I would like to stop my simulation after a given model variable (say, plastic strain averaged over entire domain) achieves a given threshold value. Do you know how to do it?

I'm supplying the MWE. How can I force AceFEM to stop simulation after EyPlAver achieves some threshold value, say 0.02 ?

<< AceFEM`;

  "ExamplesFiniteStrain", {"E *" -> 206.9, "\[Nu] *" -> .29, 
   "\[Sigma]y *" -> 0.45, "K *" -> 0.12924, "\[Sigma]yInf *" -> 0.715,
    "\[Delta] *" -> 16.93}];
WX = 1; WY = 1;
\[CapitalDelta]WY = 0.1;
SMTAddMesh[Polygon[{{WX, 0}, {WX, WY}, {0, WY}, {0, 0}}], "A", 
  "Q1", {10, 10}];

SMTAddEssentialBoundary[{Line[{{0, 0}, {0, WY}}], 
   1 -> 0}, {Line[{{0, 0}, {WX, 0}}], 2 -> 0}, { 
   Line[{{0, WY}, {WX, WY}}], 2 -> \[CapitalDelta]WY }];

Clear[\[Lambda]]; \[Lambda][t_] := t;

tMax = 1.; t0 = tMax/500.; \[CapitalDelta]tMin = 
 tMax/10000.; \[CapitalDelta]tMax = tMax/10.;
tolNR = 10.^-8; maxNR = 15; targetNR = 8;
SMTNextStep["t" -> t0, "\[Lambda][t]" -> \[Lambda]];
TElements = SMTFindElements["A"];
  While[step = 
     maxNR, {"Adaptive Time", 
      targetNR, \[CapitalDelta]tMin, \[CapitalDelta]tMax, tMax}], 
  If[step[[4]] === "MinBound", 
    "\[CapitalDelta]T<\!\(\*SubscriptBox[\(\[CapitalDelta]T\), \
\(min\)]\)"]; SMTStepBack[];];
   EyPl = {};
   For[i = 1, i <= Length[TElements], i++,
    AppendTo[EyPl, SMTElementPostData[TElements[[i]]][[1]][[All, 23]]]
   EyPlAver = Mean[Flatten[EyPl]];
  , If[step[[1]], SMTStepBack[];];
  SMTNextStep["\[CapitalDelta]t" -> step[[2]], 
   "\[Lambda][t]" -> \[Lambda]]
  • 1
    $\begingroup$ I didn't actually try to analyze your code, so this is just a general suggestion. You can use Return to break out of a "function". So, adding some conditional with a Return when the condition is satisfied might work. You might also be interested in Break, Throw, and Abort (and probably a few others) as ways to exit a function or loop. $\endgroup$
    – lericr
    Commented Apr 27, 2022 at 17:25

1 Answer 1


What you are looking for is an option to SMTConvergence[... , "AlternativeTarget"-> Function[...]]:

You can modify your SMTConvergence as:

SMTConvergence[tolNR, maxNR, 
{"Adaptive Time", targetNR, \[CapitalDelta]tMin, \[CapitalDelta]tMax, tMax},
  "AlternativeTarget" -> Function[{},
EyPl = Table[SMTElementPostData[i][[1, All, 23]], {i, TElements}];
EyPlAver = Mean[Flatten[EyPl]]; 
EyPlAver >=  0.02] ]

The procedure will start decreasing step size after EyPlAver > 0.02 is reached, trying to get as close to 0.02 as possible, so if you want to break at exactly 0.02 you will need very low minimum time step \CapitalDelta]tMin, otherwise it will stop once it reaches minimum step to get it as close to 0.02 as possible.

I would suggest to avoid Append since it is slow when applied many times on large lists. For even better performance and if you want a real average value, I suggest you write a task that integrates or sums this plastic deformation over element volume, then you can call SMTTask["AverageEPl"] and divide it by volume of domain or number of total entries.

If you don't care about stopping at exactly 0.02, then simple Break /Abort/ Return will be best, since you can avoid extra iterations from searching for exact value of 0.02:

 step[[3]], If[step[[1]], SMTStepBack[];,If[EyPlAver >=  0.02, Break[]]];

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.