A Python Package to Perform and Visualise Return Mapping to Yield Surface
This package is built on an object-oriented framework. Therefore, each material defined here is an object of the class materials.
The class materials, where the general methods are defined, is available in material.py
. Material sub-classes are also defined in this file. At this moment, the subclass isotropic is provided, but extensions to anisotropic materials are expected.
The yield function associated with a material is an object of the class yield_functions, defined in yield_function.py
.
The von Mises yield criterion is defined in the sub-class vonMises, also defined in yield_function.py
. The yield criterion name is linked to the corresponding subclass through the dictionary link_name
, defined at the end of this file.
The treatment of the hardening law is similar. The class hard_laws is defined in hardening_law.py
, along with the sub-classes linear and Swift, and the linking dictionary link_name
.
Some util functions are provided in util.py
.
A python script is provided in example.py
as an example of the package usage.
Additionally, a Jupyter notebook is also available in ReturnMappingNotebook.ipynb
, with the corresponding output being provided in ReturnMappingNotebook.pdf
.
This Jupyter notebook is intended to be used for pedagogical purposes, in the framework of Computational Plasticity. The students can easily adjust the materials properties and strain/stress conditions to assess their impact on the inelastic behaviour.
A brief guide describing the usage of this package is presented in what follows.
In the first place, the module material must be imported to enable the access to the class materials and corresponding sub-classes. NumPy arrays must be employed to define stress and strain states, and Matplotlib is used to generate plots. Hence, these modules must also be imported:
import material
import numpy as np
import matplotlib.pyplot as plt
To initialise an object for an isotropic material, the Young modulus and Poisson ratio must be defined:
my_material = material.isotropic(E=<Young>, mu=<Poisson>)
The elastic matrix is initialised according to these values. By default, the accumulated plastic strain and initial stress state are set to zero.
An yield function is attached to the material through the method set_yield_function(name, list_of_properties)
.
For the von Mises yield function, the name is vonMises and the initial yield stress, sigma_y0, is the only required property:
my_material.set_yield_function('vonMises', sigma_y0=<YieldStressValue>)
A hardening law is attached to the material through the method set_hardening_law(name, list_of_properties)
.
For the linear hardening law, the name is Linear and the hardening modulus, H, must be defined:
my_material.set_hardening_law('Linear', H=<value>)
For the Swift hardening law, the name is Swift and the parameters, n and e_0, must be defined:
my_material.set_hardening_law('Swift', n=<value>, e_0=<value>)
In order to define an initial state other than null stress and accumulated plstic strain (initialised by default), the methods set_initial_stress(stress_array)
and set_initial_epbar(value)
may be employed:
my_material.set_initial_stress(stress_array)
my_material.set_initial_epbar(value)
Note that stress_array
must be a NumPy array with dimension 3x3.
These values may be recovered through
stress_initial = my_material.get_initial_stress()
epbar_initial = my_material.get_initial_epbar()
An increment of strain may be applied to the material by
my_material.apply_increment_of_strain(strain_array)
with strain_array
being a NumPy array of dimension 3x3, representing the incremental strain tensor.
The resulting stress state, obtained considering elastic behaviour, can be recovered through
stress_current = my_material.get_current_stress()
Alternatively, the current stress state may be specified through
my_material.set_current_stress(stress_array)
with stress_array
being a NumPy array of dimension 3x3, representing the specified stress tensor.
The incremental strain tensor leading to such stress state, considering elastic behaviour, can be recovered through
inc_strain = my_material.DE
If the current stress state does not comply with the yield criterion, return mapping can be performed through
my_material.return_mapping(max_iter, tolerance)
The optional arguments max_iter
and tolerance
specify the maximum number of iterations and the convergence tolerance for the iterative procedure. If not defined, the default values are 20 and 1E-8, respectively.
The elastic trial stress and current stress tensor after return mapping can be recovered through
stress_trial = my_material.get_trial_stress()
stress_current = my_material.get_current_stress()
To check the equivalent stress associated with a given stress state, the following method may be employed
sigma_equivalent = my_material.get_equiv_stress(stress_array)
To plot stress states and yield curves in the deviatoric plane, Matplotlib figure and axes must be created in the first place.
fig, ax = plt.subplots(figsize = (<size_x>,<size_y>))
The yield curve is plotted through
my_material.plot_yield_function(ax, <yield_stress>, color = <string_color>)
A specific stress state can be represented in the figure through
my_material.plot_stress_state(ax, stress_array, color = <string_color>)
The principal stress axes vectors may be included in the representation by
my_material.plot_princ_stress_axis(ax, scaling = <value>)
I suggest that the scaling value is related to the yield stress value, for instance 1.2*yield_stress
, for better visualisation.
Send me an e-mail to [email protected] if you have any question or comment. Contributions and collaborations are welcomed.
I want to express my gratitude to António Carneiro for his valuable suggestions.