# AceGen incremental values of degrees of freedom

I need to operate with incremental values of my rotational degrees of freedom in my FE code. But I wish this incremental rotations to be dependent on the actual rotations, that I use as degrees of freedom.

AceGen offers nd$$[i,"da", j] as "value of the increment of the j-th nodal d.o.f in last iteration". But since I want the increment to be dependent on the rotations {Phi1,Phi2}, that are my degrees of freedom, I wrote this piece of code: First I read the nodal DOFs (first 3 dofs are displacements, I just write the relevant part here) Phi1=Array[SMSReal[nd$$[#, "at", 4]] &, 4]; Phi2=Array[SMSReal[nd$$[#, "at", 5]] &, 4];  I compute the change in the DOFs in my way and the increment from AceGen dPhi1=MapThread[#1 - #2 &, {Phi1,Array[SMSReal[nd$$[#, "ht", 1]] &, 4]}]; dPhi2=MapThread[#1 - #2 &, {Phi2,Array[SMSReal[nd[#, "ht", 2]] &, 4]}]; daPhi1=Array[SMSReal[nd$$[#, "da", 4]] &, 4]; daPhi2=Array[SMSReal[nd$$[#, "da", 5]] &, 4];


I export the nodal DOFs to the "ht" field

SMSExport[Phi1, Array[nd$$[#1, "ht", 1] &, 4]]; SMSExport[Phi2, Array[nd$$[#1, "ht", 2] &, 4]];


By exporting it to "ht" field, I should be able to access the values Phi1 and Phi2from iteration k in the next iteration k+1, so I can compute the change. I think that this should yield absolutely the same values as what the AceGen offers, but it turns out it sometimes does not.

Is the an explanation for this, or is the cause for this somewhere else in my code?

EDIT: What I mean by "it sometimes does not return the same values" is demonstrated here. I use an example of two quadrilateral elements, clamped at one side and subjected to moment load at the other. Printing the above mentioned quantities at each iteration yields:

Step/Iter=1/3  ...  Events=0 Status=0/{}
Phi1= -7.90046*10^-18 -2.19314*10^-17 -2.11643*10^-17 -8.0175*10^-18
Phi2= 0.0333223 0.0666529 0.0666529 0.0333223

dPhi1= 0. -0.0000137898 -0.0000137898 0.
dPhi2= 0. -8.17552*10^-16 -1.10177*10^-15 0.

daPhi1= -0.0000110787 -0.0000137898 -0.0000137898 -0.0000110787
daPhi2= 7.3362*10^-16 8.17552*10^-16 1.10177*10^-15 6.23152*10^-16


Given the values of Phi1 and Phi2 in Step/Iter=1/2, the values from "da" field are correct.

• I am struggling to understand your question, could you please update it with a more self-contained minimal working example? Also, I have noticed that you talk about DOF increment "da" but your code calls history field "ht". Could you please check if that is correct? – Pinti Jul 19 '19 at 7:28
• I edited the question, so it is explained in more detail. Hopefully now you see where the problem is? – marko Jul 19 '19 at 8:58
• Hm, I am still not sure if I really understand your question. Are you sure you want to calculate values between iterations and not steps? I think your procedure of exporting to nodal history field "ht" doesn't work because its value is updated for each step not iteration. That could explain why it "works" in second iteration but not further. – Pinti Jul 19 '19 at 11:09
• I am sure that what I need is values between iterations, not steps. The nodal history field nd$$[i, "ht", j]" is by definition "current state of the j-th history dependent real type variable in the i-th node". It should be updated every time that SMSExport[ ] function is called. In my case this should happen at every iteration. The proof that this is actually happens for some values is that some of the values for d_Phi and da_Phi are identical, while for some, the d_Phi is equal to 0. Also, the difference is present in all the iterations (except the first and the converged one) – marko Jul 19 '19 at 11:30 • Unfortunately I am out of ideas how to achieve your goal. Maybe try to export to some other nodal data field, like nd$$[i,"Data",j]. As a side comment, I am confused by your use of illegal Mathematica syntax for variable name with underscore d_Phi1. It could be worth to fix this to avoid confusing other readers, what do you think? – Pinti Jul 19 '19 at 11:45

I did try to replicate your issue but for my code I get the same values throng both approaches for computing the increment.

Here the simple element:

<< AceGen;
SMSInitialize["Truss", "Environment" -> "AceFEM",
"Mode" -> "Prototype"];
SMSTemplate["SMSTopology" -> "C1", "SMSDOFGlobal" -> 3,
"SMSDefaultIntegrationCode" -> 0,
"SMSDomainDataNames" -> {"Emod", "\[Nu]", "A"},
"SMSDefaultData" -> {21000, 0.3, 1}, "SMSNoTimeStorage" -> 1];
SMSStandardModule["Tangent and residual"];
{Emod, \[Nu], A} \[RightTee]
SMSReal[{es$$["Data", 1], es$$["Data", 2], es$$["Data", 3]}]; \[DoubleStruckCapitalX]IO \[RightTee] Table[SMSReal[nd$$[i, "X", j]], {i, 2}, {j, 3}];
\[DoubleStruckU]IO \[RightTee]
Table[SMSReal[nd$$[i, "at", j]], {i, 2}, {j, 3}]; DOFVector = Flatten[\[DoubleStruckU]IO]; SMSPrint["Iteration: ", SMSInteger[idata$$["Iteration"]]];
SMSPrint["Current     DOF-> at: ", SMSReal[nd$$[2, "at", 1]]]; SMSPrint["Previous DOF-> ap: ", SMSReal[nd$$[2, "ap", 1]]];
SMSPrint["Incremental DOF-> da: ", SMSReal[nd$$[2, "da", 1]]]; SMSPrint["at - ht(updated last iter): ", SMSReal[nd$$[2, "at", 1]] - SMSReal[ed$$["ht", 1]]]; SMSExport[SMSReal[nd$$[2, "at", 1]], ed$$["ht", 1]]; Le \[DoubleRightTee] SMSSqrt[(\[DoubleStruckCapitalX]IO[[ 1]] - \[DoubleStruckCapitalX]IO[[ 2]]).(\[DoubleStruckCapitalX]IO[[ 1]] - \[DoubleStruckCapitalX]IO[])]; \[DoubleStruckT] \[DoubleRightTee] (\[DoubleStruckCapitalX]IO[[ 2]] - \[DoubleStruckCapitalX]IO[])/Le; Grad\[DoubleStruckU] \[DoubleRightTee] (\[DoubleStruckU]IO[[ 2]].\[DoubleStruckT] - \[DoubleStruckU]IO[[ 1]].\[DoubleStruckT])/2; \[DoubleStruckCapitalE] \[DoubleRightTee] 1/2 (Grad\[DoubleStruckU] + Grad\[DoubleStruckU] + Grad\[DoubleStruckU]^2); \[CapitalPi] \[DoubleRightTee] 1/2 Emod \[DoubleStruckCapitalE]^2; \[DoubleStruckCapitalR]e \[DoubleRightTee] A Le SMSD[\[CapitalPi], DOFVector]; \[DoubleStruckCapitalK]e \[DoubleRightTee] SMSD[\[DoubleStruckCapitalR]e, DOFVector]; SMSExport[\[DoubleStruckCapitalR]e, p$$]; SMSExport[\
\[DoubleStruckCapitalK]e, s$$]; SMSWrite[];  And the simple test case: << AceFEM; F = 100; L = 10; A = 1; Emod = 1000; SMTInputData["Threads" -> 1]; SMTAddDomain["\[CapitalOmega]", "Truss", {"Emod" -> Emod, "A" -> A}]; SMTAddMesh[Line[{{0, 0, 0}, {L, 0, 0}}], "\[CapitalOmega]", "C1", 1]; SMTAddEssentialBoundary["X" == 0 &, 1 -> 0, 2 -> 0, 3 -> 0]; SMTAddNaturalBoundary["X" == L &, 1 -> F]; SMTAnalysis[]; Print["---Next Step---", SMTNextStep[1, 1];]; Print["Residual: ", SMTNewtonIteration[]] Print["Residual: ", SMTNewtonIteration[]] Print["Residual: ", SMTNewtonIteration[]] Print["Residual: ", SMTNewtonIteration[]] Print["---Next Step---", SMTNextStep[1, 1];]; Print["Residual: ", SMTNewtonIteration[]] Print["Residual: ", SMTNewtonIteration[]] Print["Residual: ", SMTNewtonIteration[]] Print["Residual: ", SMTNewtonIteration[]]  Can you tell the difference to what you did ? • The difference is in the field that I was exporting values to. You are using ed$$ field, which is unique for each element, I was using nd$$ field. As I found out while debugging the code, nd$$ field is updated already during the solution phase, for each element consecutively. So for my 2 element example, the nodes that were common to both elements, had data from previous iteration for the first element, but for the second element the data in these nodes was already taken as the one computed for the first element. So the solution to my problem is to export to ed` field. – marko Jul 22 '19 at 6:14