Beyond subroutines in Abaqus/Exp: new keywords to make life easier
Here we are again then!? Whether you’ve stumbled on this article completely independently or have been waiting in anticipation since the first part was posted, it doesn’t really matter – I just hope you find the information contained within useful.? Also, apologies that it has taken so long to come back to this topic and finish it off: other things have just got in the way....
As alluded to then, this article is a companion to a previous post which looked at step and simulation termination strategies in Abaqus/Standard, both using user subroutines and highlighting some new keywords that facilitate this as native functionality.? In this article we’ll cover essentially the same topics – in the same format - but look at the equivalent functionality and keyword updates in Abaqus/Explicit.? Having agonised over the best way to cover this companion topic, I am going to treat this as a completely standalone article, so slight apologies that there will be a good bit of duplication to start with.
Having said all that then, our starting point is the same as last time: since its birth, Abaqus has been based on the solution of a monatomic loading history, discretised into a series of loading steps, each associated with a procedure, loads, boundary conditions etc.? In the majority of cases this is a true representation of reality (or we abstract the problem for it to be true enough) and for a defined input condition we want Abaqus to do ‘nothing more’ than calculate what the resulting response to the inputs is.
But what if you don’t actually know what the definition of the end state of the loading event looks like in advance?? Can we ask the solver to monitor the evolving solution and internally make decisions about when to terminate a step and move on?? The answer is ‘yes’ – and has been the case for a while, but involved subroutines to extract, act on and pass back solution variables from the solver.?
For both Abaqus/Standard and Abaqus/Explicit there are now ways to achieve the same thing, but without having to dust off your programming skills or install a Fortran compiler.? In the previous article we looked at some recently introduced keywords to achieve this in Abaqus/Standard and here we look at what is possible in Abaqus/Explicit.
So what kind of problem would actually benefit for the solver having the ability to autonomously terminate a step or the whole analysis??
As with the companion article, we will again use the much-simplified 3-point bend test model from the TECHNIA ‘Introduction to Abaqus’ training course, but repurposed here for Abaqus/Explicit.? Again, all the non-linearities are there: contact (with friction), geometric non-linearity and – importantly for this discussion – plasticity, simplified to a bi-linear elastic-plastic response.
The simulation consists of two Explicit, Dynamic steps, to mimic the Abaqus/Standard model from the previous article, and ‘all’ that happens mechanically is that the two lower rollers are fixed, the upper crosshead is moved downwards to bend the bar and induce plastic deformation in the first step and then the crosshead is returned to its original position in the second step to observe the elastic spring back and residual deformation of the part.
To replicate the implicit version of the model and - critically – to be able to efficiently return the crosshead to its initial position the cross head in the unloading step, the crosshead is driven under displacement control for both the loading and unloading.? I will recognise now that direct displacement control is not ideal for the explicit solver, and will cause us some minor issues later on.? However, for our purposes, where we want to compare termination strategies between an implicit and explicit solution, having a common model is more useful here than absolute accuracy (.....probably).
When we run this model we see the expected overall mechanical response and, if we plot the reaction force at the crosshead, the change in gradient of the reaction force at the crosshead due to the evolving non-linearity in the system.?
Now, clearly, the result Is quite noisy.? I have deliberately not tried to adjust this with additional damping beyond the default bulk viscosity or filtering of the history output.? The only things preventing the bar wandering off is friction at the interfaces between the components combined with a gravity load, which is enough to counteract the energy release in the elastic spring back and keep the deformed bar on the lower rollers when the crosshead is retracted and the bar is effectively unconstrained.
The take-home is that – as with the implicit version - this setup of the test is good enough for our purposes: the model solves very efficiently under displacement control in both steps and we achieve the overall mechanical response we wanted.?
So now, for this explicit version of the model, we apply the same thought experiment as we did previously: what if we look at these results and now see that maybe what we ACTUALLY want is to achieve a reaction force of, for example, -4500N in the first step to better replicate the physical test, and not just apply a fixed displacement and ‘see what happens’??
Let’s review the options we have to achieve this in Abaqus/Explicit, the same as we did previously for Abaqus/Standard.
Approach 1 – User subroutine utility XIT
Firstly, exactly as we found from the previous article, this approach doesn’t actually achieve the outcome we want.? But it is worth mentioning as it’s relatively simple, is useful in other situations where you might simply want to terminate an analysis when a particular stress/displacement/temperature/force condition is met at a location in the model within a step and sets the scene for what follows.
Secondly, I am STILL prepared to accept subroutines are a blind spot to many Abaqus users, and if you are new to this capability and need a leg-up installing the pre-requisite compilers (Windows and Linux) and linking these compilers to a particular version of Abaqus, have a look at the link below.? If that doesn’t help, just ask!
Thirdly, it is inevitable that using subroutines requires some (Fortran, in this case) programming skills and that is a subject for another day, so the thoughts that follow outline a strategy in this particular case and are not meant to be an exhaustive ‘how to’ guide and will, to a greater or lesser extent, be problem specific.
Having said all of that then, the first thing we need to do is prepare the model to allow a subroutine to interact with it, passing data between the solver and the subroutine.? In this case we’ll utilise the VUAMP subroutine, for reasons that will be more obvious later.? Some of these modifications can be achieved in Abaqus/CAE, but in this case I’ve done it by hand, and the necessary keywords edits to the basic model are shown below.
To the ‘model data’ of the input file (everything defining the model itself before the step data), we need to define an AMPLITUDE, which will be the way the analysis interacts with the VUAMP subroutine and a NSET at the location we want to define a ‘sensor’ to monitor the reaction force – in this case, the control node for the crosshead, where the displacement is applied.
Now, in the ‘step data’ for the loading step, we define a dummy CLOAD of zero force for the amplitude to operate on as we’re applying a displacement to the crosshead which follows the default RAMP definition.
And finally, also in the ‘step data’ for the loading step, create the SENSOR history output for the reaction force at the crosshead loading point in the direction the displacement is applied which will be passed to the subroutine for the conditional check.
(As an aside, defining a history output to be used as a sensor is native functionality within Abaqus/CAE though the ‘Create History Output’ dialogue in the Step Module, as shown below)
For those that have read the companion article, there is a reason why the above looks like a copy-and-paste exercise: the changes to the basic model are identical to that made to the implicit version, even though we are going to use the VUAMP subroutine (which is itself the ‘explicit version’ of the UAMP subroutine to be used with Abaqus/Standard).
So, that’s the Abaqus input file adjusted to pass useful data out to a subroutine.? We now need to create a subroutine, using the documented VUAMP template as a basis, and adding the following statements which will:
It’s worth noting that the XIT command is recognised by most subroutines – we’ve just used VUAMP conveniently here to investigate other options later on.
Assuming a Fortran compiler is installed and linked to the version of Abaqus executed, we can execute this job with the command line options:
abaqus job=<Job-name> user=<subroutine_name>.f
When the job is run, the solution proceeds as normal until reaching the first increment that the reaction force at the sensor node is of a greater magnitude than the user specified threshold value, the XIT command is executed and the analysis terminates cleanly at that point.? In Abaqus/Explicit the status file will just stop at the last output frame before the XIT command is executed ?– as far as the solver is concerned, something happened to stop it reaching the next output frame and the end of the loading history, but in this case that’s actually OK.
This is quite neat and easy to setup, but doesn’t meet our requirements in two ways:
Approach 2 – VUAMP subroutine utility lFlagsDefine(iConcludeStep)
With those limitations in mind, we can do a bit better than that with a few tweaks to our VUAMP subroutine...
The first thing to observe is that there is a handy inbuilt variable to the VUAMP subroutine that we can set, and the solver knows what to do with.? If we set:
领英推荐
So, by simply replacing the XIT command lFlagsDefine(iConcludeStep) = 1.0 in our subroutine we achieve the same outcome with functionality already built into the subroutine, not an external command.
This is also an improvement in functionality compared to XIT as only the step is terminated and the solver moves on to any subsequent steps in the loading sequence (XIT terminates the entire solution at the point that it is called).
Inevitably, there are no free lunches though.? In the second/unloading step, as the first step was terminated, the solver simply moves on to the next step as another loading event, and so the jump from a large crosshead displacement at the termination point of the loading step to zero displacement defined in the unloading step is too severe to achieve.? (As with the implicit model, we can all probably think of ways to overcome this... but let’s not spoil a good story).
However, with a few tweaks to the input file to control the displacement of the unloading step via an AMPLITUDE that we calculate in the VUAMP subroutine, by tracking the step time, total time and crosshead displacement, we can achieve a process which:
When we visualise those results, we do get what we want, but we’ve sweated a bit to get there.? Plus, getting close to the threshold value at termination point of the loading step is still a bit hit-and-miss.
Overall then, if that seems like a lot of effort with subroutines/coding to achieve what, on the face of it, seems to be a relatively simple series of solver interventions.... I would tend to agree.? Subroutines still have their place in the users toolkit, and are the only way/very useful for achieving quite detailed customisation of your simulation, but it looks like hard work here: in this simple case, it is clear we have options to easily modify our workflow to achieve a functionally similar outcome without resorting to a subroutine to do it (....but, again, let’s not let reality spoil a good story).
All of the above will look eerily similar to the previous article – in terms of both the words and the technology.? As mentioned right at the start, this is deliberate, to highlight that the approaches to this level of simulation control is well established through subroutines, and essentially common to both the implicit and explicit solvers in Abaqus.?
But this is where we deviate from the previous article as the inbuilt termination functionality in Abaqus/Explicit is accessed differently from Abaqus/Standard and we must explore a couple of alternative approaches and keywords to address some of the limitations to the step termination strategies outlined above.
Approach 3 - *EXTREME VALUE Keyword
Moving on from subroutines for this workflow in Abaqus/Explicit then, the first thing to say is that there has been keyword-only functionality lurking in the software for a long time that will allow the analysis to be terminated at some threshold point.? True, it is ‘only’ equivalent to the XIT function, and so doesn’t tick all the boxes for the workflow we’re discussing here, but *(as with XIT) it could be useful.
Essentially the idea here is that functionality exists for nodes or elements can be monitored within a step for particular variables and these values are also checked against a threshold value, using the *EXTREME NODE VALUE or *EXTREME ELEMENT VALUE keywords.?
These monitoring statements can be used in conjunction with the *EXTREME VALUE keyword to then act on the conditional statement being met: the only options on this keyword are to do nothing, or terminate the analysis at the increment after the threshold is breached.
In our case, we want to monitor reaction force in DOF 2 at the crosshead node and – for the purposes of this example, from the available options – terminate the analysis.? To do this, we need to add the following keywords into the step data for the loading step:
This works exactly as advertised, and terminates the loading step at the increment the threshold is breached, leaving us with results for the closest preceding output frame and nothing more.?
In this way, it is analogous to the XIT subroutine command – both in terms of its simplicity and limitation.? Plus, as already mentioned, this is keyword-only functionality (just to labour that point then, it’s not available to define in Abaqus/CAE, unless you count opening the keyword editor as being ‘part of the GUI’!).
So close, but still not exactly what we want.... but don’t despair - there is a solution!
Approach 4 - *FILTER Keyword
Over several releases, the *FILTER keyword has had options added to it to get closer to what we are trying to achieve with a subroutine.? Since at least v2018, the optional parameter has been available with this keyword to terminate a simulation when the value of the history data that is being monitored (for signal filtering within the history output) with this function exceeds a defined value (...sound familiar...).? From v2019, this was extended to be able to terminate the step or the whole analysis based on the limit value (...deja vu anyone?), and from v2021 the ability to create an additional output frame at the terminate point was added to be able to visualise results at the limit value, not just the last frame written as part of the overall field output definition/frequency (this is spooky!).
Now, we can define and configure the key components of this signal filter within Abaqus/CAE, but some of the other options can only be accessed by modifying the input file.? So, lets look at how we get to the functionality we need for this problem as a combination of definitions within Abaqus/CAE augmented with keyword edits.
Firstly, we need to define the basic elements of a filter in Abaqus/CAE which we then apply to the sensor history output to trigger the step termination.? From within the STEP module, we create an ‘operator’-type filter through the tools menu.? Within this filter we set up the conditional checks, as shown below, that will be applied to the sensor node later on.? For now, we’ll also check the box to terminate the analysis when the limit value of -4500 (Newtons in this case, as we will use the same sensor as before, monitoring the crosshead reaction force) is reached.
Now, with the conditional operator defined as part of this filter, we can go back to the history output which we are using as a sensor to the crosshead reaction and apply this filter to it.? The setup is identical to the history output we set up to define the sensor for the subroutine to monitor.... except now we apply the filter to the history output.
When this functionality turns up in the input deck, it all looks reassuringly familiar compared to Abaqus/CAE.? Firstly, the *FILTER keywork captures all of the relevant information we entered to define the filter and is defined within the model data section of the input deck.
Secondly, this filter is applied to the crosshead reaction force history output, we defined and used as a sensor previously.
This is all good and useful native functionality that we can define with the options available through the Abaqus/CAE interface.... but, as we’ve already said, we can do better with a few choice hand edits to the *FILTER definition in the input deck before submitting the job.? So far, we’ve specified that the analysis will terminate at the point the conditions of the filter are met, but we will now use the alternative option ‘halt=STEP’ to terminate only the loading step and allow the analysis to move on to the unloading step.? We’ll also request that an extra output frame is added to the .odb file at the exact increment the termination conditions are met.? When we do this, the *FILTER line looks like this:
With these hand edits made, as we now don’t need the subroutine, we don’t need a Fortran compiler as a prerequisite and can simply execute the job as we would any other at the command line:
abaqus job=<Job-name>
When we run this job, it does exactly what we want and expect without any other intervention:
The .sta file captures all of this information in a meaningful way (you will have to take my word for it in this case as it’s a bit too big to capture all of the relevant outputs put an image of it here).? By way of evidence, the animation of this simulation shows the cross head motion stopping at the termination point of the loading step at 4500 N of reaction force and the crosshead being retracted.
Quick side note here: I have deliberately not shown the reaction force of the unloading step - as previously mentioned, I’ve driven the crosshead with a displacement boundary condition to be consistent with the implicit model in the previous article.? This means that the abrupt termination of the loading step and instantaneous switch in the direction of crosshead motion creates a large, oscillating, perturbation force at the start of the unloading step which masks the results we want to see in the graph for the loading step (which is fine in the case, as all the deformation the bar has finished by then and we aren’t interesting in the local crosshead behaviour).
So we’ve got there.... again!? The workflow we set out to develop has been achieved efficiently with native functionality, in Abaqus/Explicit this time, and not a subroutine in sight.?
Conclusions
So what have we learnt here:
Research in Numerical Simulations for Applied Mechanics Solutions
12 个月Thanks for the interesting post. Can you explain why the curve of the second force / time diagram looks so smoothe compared the initial one?
Expert in manufacturing risk management
1 年Not sure if it was mentioned but Abaqus 2023 introduced the *STEP CONTROL keyword for implementation in the UI rather than scripting. I really could’ve used this a few years ago when working on a packaging impact project (*STEP CONTROL on ALLKE with some lower threshold value to know when the dynamic event has more-or-less stopped).
PhD. Candidate in Earthquake Engineering, Universiti Sains Malaysia
1 年I wonder if there any tutorials you recommend to achieve such this incredible simulation.
?? Follow for Simulation Ideas
1 年How difficult it would be to use thermal DOFs instead of structural DOFs to kill the job? I wonder how easy would be to make some sort of thermostat analysis with this approach ??