APIs act as a bridge between two programs, so it's important to understand the philosophy
behind PyMAPDL if we hope to build reliable and insightful Python engineering apps with
the MAPDL solver.
In this video, we'll discuss How APDL commands are implemented and used
in the python environment.
What are the advantages of calling MAPDL pythonically.
How to obtain output from PyMAPDL.
Finally, we will setup and solve a simple 2-D plane strain model in PyMAPDL and execute
it in batch to automate mesh convergence study.
Let’s get started!
The PyMAPDL commands are Pythonic statements that act as a wrapper for APDL commands.
When these commands are issued in Python, PyMAPDL passes them to the MAPDL instance,
executes the commands and returns the output to Python.
Each APDL command has been translated to the Python format where APDL arguments are passed
as keyword arguments.
For instance, the APDL command ESEL,s,TYPE,,1 is translated to mapdl.esel(‘s’, ‘type’,
vmin=1) in PyMAPDL.
Unlike APDL, in PyMAPDL one must issue full command name and not just first 4 characters.
For example, mapdl.aglu() is not recognized, instead use mapdl.aglue().
It’s also important to note that PyMAPDL commands are Pythonic statements, therefore
they’re case sensitive.
APDL Commands that start with / and * have those characters removed.
Here, ‘/PREP7’ is written as ‘mapdl.prep7()’ and ‘*GET’ is written as ‘mapdl.get()’.
In cases where removing a slash or star will cause a conflict with other commands, such
as in SOLU & /SOLU and VGET & *VGET, a prefix “slash” or “star” is added to the
pythonic statement.
For example, ‘SOLU’ is written as ‘mapdl.solu()’ and ‘/SOLU’ is written as ‘mapdl.slashsolu()’.
Similarly, VGET and *VGET are translated to mapdl.vget() and mapdl.starvget().
At any given time, one can issue help(mapdl.comandname) in the Python terminal to pull up the command
reference.
When it comes to post-processing, there’s a special class ‘ansys.mapdl.core.post.postprocessing’
implemented in PyMAPDL.
While both /POST1 and /POST26 APDL commands are supported in PyMAPDL, it may be advantageous
to use this class in the Python environment.
For instance, one can extract data from results directly to NumPy arrays for further processing.
PyMAPDL also provides a way of translating existing APDL scripts into pythonic format
using ‘convert_script()’.
One can also convert a block of APDL commands using ‘convert_apdl_block()’.
PyMAPDL allows us to integrate APDL in a true programming environment with a powerful ecosystem.
Pythonic datatypes can be passed as both arguments and parameters to APDL, so integration with
other Pythonic modules is easier.
We can also iterate over a range, strings, lists, etc., using loops in Python.
In addition to this, we can setup a FE model as a callable function, so it can be automated
or integrated into engineering workflows.
This can be very helpful in developing vertical apps and in design optimization workflows.
Since the whole program is developed using Python statements, one can use PEP8, which
is a style guide for Python codes, and write beautiful and readable codes making it easy
to maintain and distribute to wider users.
When we call MAPDL from Python, the MAPDL program is running in the background, and
one can access the solver output dynamically within Python.
The solver output can either be printed to screen or written to a separate text file
using these commands.
Since Python and MAPDL are both executing different sets of commands, errors and warnings
may arise from both the programs.
In PyMAPDL, all errors and warnings are handled pythonically.
When errors are encountered, a traceback is provided, indicating which line in the code
triggered it.
If the error arises from MAPDL, then the corresponding error message is also provided.
Warnings arising from MAPDL are also handled pythonically.
An important situation to note, however, is the default PyMAPDL behavior when a command
is ignored.
For instance, if a command is issued under the wrong processor, MAPDL ignores the command
and issues a warning, but this is treated as an error in PyMAPDL and immediately kills
the instance.
Fortunately, this behavior can be changed by setting mapdl.allow_ignore = True if needed,
so please keep this in mind when developing programs.
Most MAPDL commands have been translated to Python format.
However, there are a few commands that are either unsupported or are not applicable to
PyMAPDL.
PyMAPDL is an interactive session so the commands that are implemented for batch mode of processing
are not supported.
Using these commands would not cause PyMAPDL to exit; instead, they are ignored.
Some APDL commands are not translated in PyMAPDL, as equivalent functionality is already available
in Python.
For example, one can use while and for-loops in place of *DO and *DOWHILE commands and
use if-elif-else statement in place of *IF, *ELSEIF, *ELSE commands.
Note that issuing these APDL commands will return an error and immediately kill the MAPDL
instance.
With this knowledge, now let’s proceed to a workshop.
Workshop: Imagine a long, steel pipe containing a pressurized
fluid.
The internal pressure exerted on the pipe causes deformation and stresses to develop
in the pipe, and it may be important to understand these quantities, especially if we do not
want the pipe to burst or, with cyclic loading, to fail due to fatigue.
In this workshop, we will perform a stress analysis of such a pipe with the main output
being the peak equivalent stress and nodal displacements developed due to the internal
pressure.
Due to the symmetry in the geometry and loading, we will model only one quadrant of the geometry
with a 2D plane strain formulation, which is useful for structures are very long in
a given direction.
From a modelling standpoint, the geometry of the pipe is defined by inner and outer
radii, and material of the pipe is assumed to be linear elastic.
We fix one end of the pipe in the X direction and another in the Y direction.
We apply a pressure load on the inner edge of the pipe to account for the internal pressure.
We’ll also perform a mesh convergence study to ensure that the results are reasonably
independent of the mesh density.
To do this, we’ll run a series of simulations with increasing mesh density and monitor the
maximum stress developed in the part with respect to the number of DOFs.
Once we have achieved mesh convergence, we’ll use the result from the finest mesh to report
the stresses and displacements developed in the pipe.
To do this, we will use PyMAPDL in setting up the FE model as a Python function and use
this function to run a series of simulations in a loop and incorporate the mesh convergence
study into our stress analysis.
=== workshop recording=== We’ll start by importing all the necessary
libraries in Python.
In this workshop, in addition to PyMAPDL, we plan on using NumPy for working with stress
data and Matplotlib for plotting mesh convergence behaviour.
After we import the libraries, let’s launch a local instance of MAPDL.
Now, we’re ready to setup the FE model.
Let us start by identifying the input parameters for this model.
The material constants Youngs modulus and Poisson’s ratio, geometric parameters inner
and outer radii, pressure load, and the element size are the inputs for this function.
Using these as input parameters, we setup the rest of the model using all MAPDL commands
in their pythonic format.
After we solve the model, we use the post-processing class to extract equivalent stresses as a
NumPy array and save its maximum value to a variable max_eqv_stress.
Similarly, we save all node numbers to another NumPy array and save the size of this array
to a variable num_dof that represents the number of DOFs.
Finally, we return the two variables num_dof and max_eqv_stress as output for this function.
So, we now have the FE model setup such that running this function with user inputs provides
these two quantities as outputs.
Note that all other simulation data generated by MAPDL is still available but only these
two variables are extracted and saved to the Python database.
Now, we can proceed to perform a mesh convergence study.
First, we assign values to all the input parameters.
The inner and outer radii of the pipe are set to 175 mm and 200 mm respectively.
We set the pressure load to be 100 MPa.
In this example, we assume that the pipe is made of structural steel, so we define Young’s
modulus of 200,000 MPa and Poisson’s ratio of 0.3.
Next, define two empty lists to store the mesh convergence parameters.
For element sizes, we define a NumPy array of 20 elements that are evenly spaced in log
space.
We use log scale since mesh convergence is typically expected to be logarithmic.
Now, we loop over this array and execute the function each time using the inputs defined
earlier while changing the element size.
We save results from each run and append them into the empty arrays that we defined earlier.
Once all the runs are executed, we can plot the mesh convergence parameters on a semi-log
plot.
We can see that the maximum equivalent stress is converging to a value over log-space.
With this, we can now confidently report the stresses and displacements from the last analysis
that are reasonably independent of the mesh density.
We now plot the final mesh used, the normalized nodal displacements, and the equivalent stresses
in the pipe.
With that, we complete the learning objectives of this workshop.
In this video, we learnt how to write APDL commands in Pythonic format and work in the
Python environment.
We also used this to setup an FE model and perform stress analysis, along with mesh convergence
study.
This concludes the video, and we'll continue our learning in the next video.
The End