PS Here's a flow chart I made for myself, showing when Abaqus calls each subroutine (as far as I can work out). The black lines show sequence & blue lines show data exchange.
I have used it only for extremely simple purposes, essentially transferring node-based field variables to element-based state variables (solution-dependent variables). Here's an example (sorry that ResearchGate doesn't preserve formatting):
Thank you for taking time out and showing me some examples.
The issue I am facing is, my Young's modulus depends on 3 strains (Epsilon_11, Epsilon_22, Epsilon_12), so I have 3 field variables.
The data looks something like this : (see image 1)
I want to assign these properties to the model via the USDFLD, such that for the current strain , the equivalent Young's modulus is calculated.
I am doing this using the USDFLD : (see image 2)
I am printing out the FV1, FV2 and FV3, and they are showing the values for the strain. However, I see no difference when I run the simulation with or without the USDFLD.
How can I really know if the USDFLD is calculating the young's modulii for different combinations of the strains?
A feature I found really helpful is writing output to the .dat file produced during Abaqus runs. This is file #6, so you can output to it using WRITE(6,*) [string]. When your run finishes (or while it's running, for that matter), you can open the .dat file (plain text) and you'll see the relevant output for each increment.
Because USDFLD is called every iteration for every integration point, I would just tell it to write for one element, for example, to check what it's doing. (e.g. IF NOEL.eq.200 WRITE(6,*) 'check',KSTEP, KINC, NOEL, N_11,N_22,N_12) If you include a string like "check", you can use your text editor's find function to search for the relevant lines.
How are you telling Abaqus to derive the Young's Modulus from the field variables? *ELASTIC, DEPENDENCIES=3 ?
You'll also need to make sure you have *USER DEFINED FIELD in the material definition, to tell Abaqus to call USDFLD.
If you introduce the write statement in your USDFLD code and find that all the strains are coming up as zero, even though your previous iteration produced non-zero results, it could be because USDFLD runs at the *start* of each iteration, ie before stress analysis is done. The way around this (if you need it) would be to use URDFIL to assign the results of the previous analysis to variables that you then transfer into USDFLD via a COMMON block in your Fortran code. I can give you more details on this if you turn out to need it.
Thank you for your insight into this. The debugging technique that you mentioned is definitely handy. However, in my Field output, I have selected FV (field variables), so in my odb I can already see FV1, FV2, FV3 (my field variables) at each increment. And sure enough, at each increment, FV has the value of the nominal strain (NE) from the previous increment. At least form this, I believe that the USDFLD is assigning the Nominal Strain values to the Field variables.
What I am not sure of, however, is : I don't know if the Young's Modulii is being derived/interpolated for the calculated Field variable.
Why I say this is because according to my material definition (Engg Constant), the material gets stiffer (Young's mod increases) as the strain increases. You can see this from the figure in my previous post too.
But when I plot the deformation against time, I see that the strain is INCREASING (!!) instead of decreasing.
How are you telling Abaqus to calculate the Young's Moduli from the FVs? Do you use another subroutine to assign it, or is the field variable dependency in the material definition?
From what I read about USDFLD online and from the manual, I understood that Abaqus automatically interpolates and calculates the Young's Modulii at field variables for which it is not already defined.
That is correct, but only if you provide that information in your material definition. Could you post the material definition from your input (.inp) file? That will help us see if there's anything missing.
Here's one of mine, as an example:
*Material, name=Tissue
*Depvar
4
*User Material, constants=8
15750., 0.36, 1000., 0.36, 5., 0.45, 1., 0.4
*USER DEFINED FIELD
In this case, *User Material tells Abaqus to use the UMAT subroutine to do the stress analysis at each material point. *User defined field calls USDFLD before UMAT for each material point and each iteration. *Depvar defines the number of solution-dependent variables (state variables). It seems like you'll probably need something like:
*Material, name=[thing]
*ELASTIC, DEPENDENCIES=3 [& any other switches/settings]
Young’s modulus, Poisson’s ratio, , FV1, FV2, FV3
[repeat as many times as needed to define the behaviour, as per the Eng-Tips link you posted. What is your function defining the relationship of E to the strains?]
*USER DEFINED FIELD
(you'd replace ELASTIC with whatever material definition you need)
Note the two commas in a row, between Poisson's ratio and FVs: this is for temperature, so leaving it blank tells Abaqus to ignore it.
In my simulation, Abaqus is calculating the stresses whenever the strain (NE) reaches the values FV1, FV2, FV3, and I am hoping that it is using the interpolated values of E1, E2, E3.. etc in order to calculate the stresses.
OK, great. It looks like you're doing everything right.
To check the E values are being correctly calculated, one way would be to assign user output variables. To do that, add the following to your material definition, and then add a UVARM routine to your Fortran code.
*User Output Variables
6
UVARM can use GETVRM to access values of other variables like the field variable values at the relevant material point (USDFLD and UVARM will be called for each point for each iteration). That means you could assign UVAR(1), UVAR(2) and UVAR(3) to the E component values you should be getting from your defined relationship (assuming you can formulate that relationship via an equation), and then assign three more UVARs to the E values Abaqus is using (again using GETVRM to access their values).
Alternatively, you could define your UVARs as the difference between the value you expect and the value Abaqus assigns.
Thank you so much for that valuable input. I will definitely look into UVARM and its usage. I think its one way to find out if E's are getting calculated correctly.
I had just one (maybe two) other doubt(s) wrt this :
1. Would you happen to know whats the difference between Abaqus' USER FIELD subroutine and the current USDFLD subroutine?
2. What would happen if I used GETVRM to obtain the SDVs? As in, I see that we always set the DEPVAR as the number of field variables we have. (3 in this case). I just want to know what role do the state-dependant variables have, in a USDFLD subroutine. I hope my question isn't confusing.
Looking forward to your reply. Have a good weekend!
1. The UFIELD routine works with node-based field variables (defined by *USER FIELD in the input file), whereas USDFLD can access node-based variables, but also transfer field variables to element-based material points (also known as integration points). UFIELD is called upon each new increment (although not before the first), and USDFLD is called just before the stress analysis for each material point.
2. Actually, you shouldn't need *Depvar in your case, as *USER DEFINED FIELD tells Abaqus to use field variables, dependencies=3 tells it how to use them in calculating your parameters, and you don't make any calls to the SDVs. Depvar is only needed if you're using the state variables - SDV/STATEV.
You could equally use SDVs instead of field variables, I think, but it would be more complicated. You can access their results via GETVRM in UVARM, but you can't assign values to them or your mechanical properties there. They are passed in to USDFLD, though, as the STATEV array, but to derive your mechanical properties from them, you'd need to use a user-defined material and the UMAT routine. So I think your current approach is better.
One problem you might run into is that, with properties being defined in USDFLD, Abaqus changes the parameters for every iteration - even those that don't converge on a solution. That's why I assigned any material property changes in URDFIL, which is only called upon finalising an increment. If you run into any stability issues or strange results, that might be worth your trying too. It's a bit convoluted, though, so I'll just explain that if you need it.
PS Here's a flow chart I made for myself, showing when Abaqus calls each subroutine (as far as I can work out). The black lines show sequence & blue lines show data exchange.
The non-converging increment had never occured to me as a problem. Its definitely good to know that there's a workaround, no matter how convoluted. And the flowchart seems to be just what I needed. I will go through it slowly, lest I miss something.
Just wanted to say thank you, for providing me so much info in a week and a half, which would have taken me at least a few months to figure out on my own.
It might be challenging to navigate my not-very-annotated code, but it may be enough to get you started, if you have to go in that direction.
Essentially, I'd advise using *EL FILE to transfer your strains to the results file (.fil), which will automatically call the URDFIL routine at the end of each increment. In URDFIL, you can read those results into an array (probably 3-dimensional: number of elements x number of integration points per element x 3 strains) and share it with USDFLD using matching COMMON statements in each routine. From there, you can proceed with USDFLD as before, but you would use the common variable (it will be an array) rather than reading in the strains there, as the input for your field variables.
I won't be online much for the next couple of months, so I hope this gets things working. Feel free to ask more questions; it just might take a while for me to answer.