FEAP User Forum
FEAP => Programming => Topic started by: simd on February 12, 2020, 10:03:17 AM
-
Dear all,
I'm trying to save an user array so that it can be accessed from the restart file invoked by the RESTart command.
My idea was to do it with an user macro, as given below. It seems to properly read the values (I'm getting the correct value in each element) when (urest.eq.1), but when I'm checking whether it has properly written it to the save file (urest.eq.2), I'm getting as an output just "Writing crack 0 in el 0". Do you maybe know what is the problem with my macro? Do I perhaps have to give the exact location before starting to write the data to the ios? Is it a problem that I made a loop over all elements, when in reality the allocation was made just in the user element module elmt10.f that is called under material 3 and 4 (and another user element is used for materials 1 and 2)?
c$Id:$
subroutine umacr3(lct,ctl)
c * * F E A P * * A Finite Element Analysis Program
c.... Copyright (c) 1984-2014: Regents of the University of California
c All rights reserved
c-----[--.----+----.----+----.-----------------------------------------]
c Modification log Date (dd/mm/year)
c Original version 01/11/2006
c 1. Remove 'prt' from argument list 09/07/2009
c-----[--.----+----.----+----.-----------------------------------------]
c Purpose: User interface for adding solution command language
c instructions.
c Inputs:
c lct - Command character parameters
c ctl(3) - Command numerical parameters
c Outputs:
c N.B. Users are responsible for command actions. See
c programmers manual for example.
c-----[--.----+----.----+----.-----------------------------------------]
implicit none
include 'iofile.h'
include 'iodata.h' ! ios
include 'umac1.h' ! uct
include 'pointer.h' ! up
include 'comblk.h' ! hr, mr
include 'cdata.h' ! nen, numnp, numel
include 'eldata.h' ! n, ma
logical pcomp
integer i
character lct*15
real*8 ctl(3)
save
c Set command word
if(pcomp(uct,'mac3',4)) then ! Usual form
uct = 'hres' ! Specify 'name'
elseif(urest.eq.1) then ! Read restart data
do i = 1,numel
if(up(1).ne.0) then
read(ios) hr(up(1) + i-1)
end if
end do
write(*,*) 'Reading crack', hr(up(1) + i-1), 'in el', i
elseif(urest.eq.2) then ! Write restart data
do i=1,numel
if(up(1).ne.0) then
write(ios) hr(up(1) + i-1)
end if
end do
write(*,*) 'Writing crack', hr(up(1) + i-1), 'in el', i
else ! Perform user operation
endif
end
The array is defined in ualloc.f as:
data (names(i),i=1,list)/
& 'CRACK'/
In the user subroutine elmt10.f I allocate it as:
! Allocate memory for crack
setvar = ualloc(1,'CRACK',numel,2)
if(.not.setvar) then
write(*,*) 'UALLOC ERROR - CRACK'
endif
(for isw=1)
I initialize it and later update as:
crack = hr(up(1)+(n-1))
(for isw=3 or 6)
I would be grateful for any advice.
-
Could it be because your write statement is outside of the loop?
-
Dear Prof. Govindjee,
thank you for your reply. Yes, I should have put it into the loop while checking.
I have checked it again and the problem is that when I'm checking directly inside the element subroutine, the variable takes the correct value in a particular element, but that value is not properly stored in the restart file (it's always zero). When I'm reading from the restart file I also get zeros in all elements, even though the value should change to 1 in some elements after a particular time step. Shall I maybe make some changes in restrt.f?
-
crack = hr(up(1)+(n-1))
sets crack not hr*(up(1) ....). If you want to store data in the array that you have allocated, you have to do it the other way around:
hr(up(1)+(n-1)) = ...
-
Dear Professor,
yes, I have done it in this manner in my element subroutine. I have also changed it in the macro routine, but it didn't help.
-
Your file looks like it should work if all the data is there. I would suggest also do one write/read like
write(ios) (hr(up(1)+i),i=0,numel-1)
at the same time put an mprint(hr(up(1)),1,numel,1,'UMAC3_ARRAY') after the read and writesjj
I would suggest this to monitor what is happening. There could be a bug in how the restart is working for user data as you are using it. It may not be used very often.
Also, please tell us what version of FEAP you are using. Is it 8.4?
-
I ran a test on the restart using the attached files. It seems to work fine. Note the need to tell what restart file you are using, in this case the file 1.
I used FEAP ver8.5
-
Dear Prof. Taylor,
thank you very much for your help. I have changed the macro as you have suggested, but still the value is not properly saved and read after the restart (it is always zero).
if(up(1).ne.0) then
write(ios) (hr(up(1)+i),i=0,numel-1)
call mprint(hr(up(1)),1,numel,1,'UMACR3_ARRAY')
end if
I am using FEAP ver 8.4.
As for the small example that you have attached, it works fine also for me.
-
If the module I gave you works then you may not have problems not associated with the user module and the problem is elsewhere.
You should insert writes to screen where you do the restart save and the restart read. If you have the values when you write but not when you read it will provide additional information on where to look. If you do not write the values correctly then the problem is elsewhere.
-
Can you verify that the example I gave:
1. Sets write values to 1.0, outputs and does save.
2. sets values to 2.0 and outputs
3. Does restart and outputs original values of 1.0
This would verify that the save/restart is working in a single run.
You should also verify that if you quit the analysis and then do the second problem with the restart it also works
-
It would be nice to have an option for the restart/save feature, which handles all user arrays (ualloc.f) like it is done for FEAP arrays (palloc.f).
-
Feap only saves selected np(*) arrays that are allocated on a SAVE for later RESTart. It is possible to add a feature to poll all allocated arrays and pick the up(*) ones to save, but then there may be cases where that is not wanted too.
I would guess there is no perfect solution for all cases?
Current save/restart operations are preformed in 'restrt.f' in ./program -- is there something you would suggest to add that would be flexible?
-
Dear Prof. Taylor,
with your help I managed to solve my problem. Thank you very much again!
I'm using the values from array up(1) in another macro routine as well and there it also seems to import the correct value and properly detect the change in the values after restart.
I'm attaching the corrected macro routine for restart in case someone else finds it helpful.
-
Feap only saves selected np(*) arrays that are allocated on a SAVE for later RESTart. It is possible to add a feature to poll all allocated arrays and pick the up(*) ones to save, but then there may be cases where that is not wanted too.
I would guess there is no perfect solution for all cases?
Current save/restart operations are preformed in 'restrt.f' in ./program -- is there something you would suggest to add that would be flexible?
It would be helpful to extend ralloc.f and walloc.f to work also with user-arrays. To call these subroutines in user macros reduces the necessary code.
Really great would be a new subroutine, which takes a list of up()-indices, a list of integers and a list of real values to write and read the restart file. In this case, the developer of user macros do not need to be familiar with restart files and explanation in the user manual can be short too.
-
The first suggestion should be quite easy to implement as
setvar = u_ralloc( nd, 'UNAME', ios)
and
setvar = u_walloc( nd, 'UNAME', len, type, ios)
where type is 1 for integer and 2 for real justa s now.
I am not clear on what is suggested in the other part -- maybe an example can help to see what the benefit could be?