2D Uniaxial Tensile/compresion test¶
This notebook shows how to use the toolbox and the Argiope module to
perform a parametric simulation of a cyclic uniaxial test.
%load_ext autoreload
%matplotlib nbagg
%autoreload 2
The autoreload extension is already loaded. To reload it, use:
%reload_ext autoreload
import MechanicalTest.model_traction as model
import os, subprocess, time, local_settings, time
import matplotlib.pyplot as plt
import matplotlib as mpl
import argiope as ag
import numpy as np
#-------------------------------------------------------------------------------
# USEFUL FUNCTIONS
def create_dir(path):
try:
os.mkdir(path)
except:
pass
#-------------------------------------------------------------------------------
SETTINGS
GMSH_PATH = local_settings.GMSH_PATH
workdir = "workdir/"
outputdir = "outputs/"
label = "Trac"
template_dir = "TensileTest2D"
#-------------------------------------------------------------------------------
create_dir(workdir)
create_dir(workdir + outputdir)
Element type definition¶
def element_map(mesh):
mesh.elements.loc[mesh.elements.type.argiope == "tri3", ("type", "solver", "")] = "CPE3"
mesh.elements.loc[mesh.elements.type.argiope == "quad4", ("type", "solver", "")] = "CPE4R"
return mesh
Material¶
def material_map(mesh):
mesh.elements["materials"] = "SAMPLE_MAT"
return mesh
materials = []
materials.append(ag.materials.Hollomon(label = "SAMPLE_MAT", strain_data_points = 100,
young_modulus = 200e3,
poisson_ratio = 0.3,
hardening_exponent = 0.3,
yield_stress = 450))
Sample definition¶
Mesh generation using gmsh¶
\(L\) and \(l\) parametres are the dimension of the central part of the sample.
parts = {
"sample" :model.Sample2D(workdir = workdir,
L = 10., # length
l = 10., #width
r = 5., #radius
lcf = .2, #fine element size
lcg = 3., #coars element size
gmsh_path = GMSH_PATH,
gmsh_space = 2,
gmsh_options = "-algo delquad",
element_map = element_map,
material_map = material_map)}
Steps definition¶
Here 3 steps are implemented : * Traction * Compression * Traction
steps = [
model.Step2D_traction(name = "LOADING1",
kind = "adaptative",
control_type = "disp",
duration = 0.5,
min_frame_duration = .1,
controlled_value = .5 ),
model.Step2D_traction(name = "LOADING2",
kind = "adaptative",
control_type = "disp",
duration = 1.,
min_frame_duration = .1,
controlled_value = -.5 ),
model.Step2D_traction(name = "LOADING3",
kind = "adaptative",
control_type = "disp",
duration = 1.5,
min_frame_duration = .1,
controlled_value = 1. )
]
TracModel = model.Traction2D(label = label,
parts = parts,
steps = steps,
materials = materials,
solver = "abaqus",
solver_path = local_settings.ABAQUS_PATH,
workdir = workdir,
verbose = True)
Write the inp file for Abaqus¶
The model can be check within CAE Abaqus if needed, unsing the file>import>model>*.inp menu.
TracModel.write_input()
Mesh checking¶
i = 1
fig = plt.figure()
parts_names = parts.keys()
for name, part in parts.items():
mesh = part.mesh
patches = mesh.to_polycollection(edgecolor = "black", linewidth = .1, alpha = 1.)
stats = mesh.stats()
patches.set_array( stats.stats.max_abs_angular_deviation )
patches.set_cmap(mpl.cm.YlOrRd)
ax = fig.add_subplot(1, 1, 1)
ax.set_aspect("equal")
ax.set_xlim(mesh.nodes.coords.x.min(), mesh.nodes.coords.x.max())
ax.set_ylim(mesh.nodes.coords.y.min(), mesh.nodes.coords.y.max())
#ax.set_xlim(-6, 6)
#ax.set_ylim(-1,11)
ax.add_collection(patches)
cbar = plt.colorbar(patches, orientation = "horizontal")
cbar.set_label("Max Abs. Angular Deviation [$^o$]")
plt.xlabel("$x$")
plt.ylabel("$y$")
plt.grid('off')
plt.title(name.title())
#i+= 1
plt.show()
<IPython.core.display.Javascript object>
Run using Abaqus/Standart¶
TracModel.run_simulation()
Postprocess and save the model for further analyze¶
TracModel.postproc()
TracModel.save(workdir +label+ ".pcklz")
Re-load the case for post process within the pythonic environement¶
TracModel = ag.utils.load(workdir +label+ ".pcklz")
Ploting the results¶
Force date comming from history output¶
hist = TracModel.data["history"]
hist.head()
| RF | dtot | t | step | F | |
|---|---|---|---|---|---|
| 0 | -0.000000 | 0.000 | 0.000 | 0 | -0.000000 |
| 1 | 361.051483 | 0.005 | 0.005 | 0 | 361.051483 |
| 2 | 722.023315 | 0.010 | 0.010 | 0 | 722.023315 |
| 3 | 1082.915410 | 0.015 | 0.015 | 0 | 1082.915410 |
| 4 | 1443.727780 | 0.020 | 0.020 | 0 | 1443.727780 |
plt.figure()
for step, group in hist.groupby("step"):
plt.plot(group.dtot, group.F,'.-', label = "Step {0}".format(step))
plt.grid()
plt.legend(loc = "best")
plt.ylabel("Total force $F$, []")
plt.xlabel("Displacement, $\delta$ []")
plt.show()
<IPython.core.display.Javascript object>
Field plots¶
Check the available output fields¶
meta=TracModel.parts["sample"].mesh.fields_metadata()
meta.head(40)
| part | step_num | step_label | frame | frame_value | label | position | |
|---|---|---|---|---|---|---|---|
| 0 | I_SAMPLE | 0 | LOADING1 | 0 | 0 | PEEQ | element |
| 1 | I_SAMPLE | 0 | LOADING1 | 0 | 0 | S | element |
| 2 | I_SAMPLE | 0 | LOADING1 | 0 | 0 | Seq | element |
| 3 | I_SAMPLE | 0 | LOADING1 | 0 | 0 | U | node |
| 4 | I_SAMPLE | 0 | LOADING1 | 1 | 0.5 | PEEQ | element |
| 5 | I_SAMPLE | 0 | LOADING1 | 1 | 0.5 | S | element |
| 6 | I_SAMPLE | 0 | LOADING1 | 1 | 0.5 | Seq | element |
| 7 | I_SAMPLE | 0 | LOADING1 | 1 | 0.5 | U | node |
| 8 | I_SAMPLE | 1 | LOADING2 | 0 | 0 | PEEQ | element |
| 9 | I_SAMPLE | 1 | LOADING2 | 0 | 0 | S | element |
| 10 | I_SAMPLE | 1 | LOADING2 | 0 | 0 | Seq | element |
| 11 | I_SAMPLE | 1 | LOADING2 | 0 | 0 | U | node |
| 12 | I_SAMPLE | 1 | LOADING2 | 1 | 1 | PEEQ | element |
| 13 | I_SAMPLE | 1 | LOADING2 | 1 | 1 | S | element |
| 14 | I_SAMPLE | 1 | LOADING2 | 1 | 1 | Seq | element |
| 15 | I_SAMPLE | 1 | LOADING2 | 1 | 1 | U | node |
| 16 | I_SAMPLE | 2 | LOADING3 | 0 | 0 | PEEQ | element |
| 17 | I_SAMPLE | 2 | LOADING3 | 0 | 0 | S | element |
| 18 | I_SAMPLE | 2 | LOADING3 | 0 | 0 | Seq | element |
| 19 | I_SAMPLE | 2 | LOADING3 | 0 | 0 | U | node |
| 20 | I_SAMPLE | 2 | LOADING3 | 1 | 1.5 | PEEQ | element |
| 21 | I_SAMPLE | 2 | LOADING3 | 1 | 1.5 | S | element |
| 22 | I_SAMPLE | 2 | LOADING3 | 1 | 1.5 | Seq | element |
| 23 | I_SAMPLE | 2 | LOADING3 | 1 | 1.5 | U | node |
Plot field at nodes¶
#Frame number to plot
frame_num=1
Step_name='LOADING3'
parts = {k:part.mesh.copy() for k, part in TracModel.parts.items() }
fig = plt.figure()
ax = fig.add_subplot(1,1,1)
field_num = meta[(meta.label=='U') & (meta.frame==frame_num) & (meta.step_label==Step_name)].index[0]
disp_num = meta[(meta.label=='U') & (meta.frame==frame_num) & (meta.step_label==Step_name)].index[0]
levels = np.linspace(-.35, .35, 21)
dispMagnification = 1.
for k, mesh in parts.items():
field =mesh.fields[field_num].data.v1
disp = mesh.fields[disp_num].data
frame = mesh.fields[disp_num].frame
mesh.nodes[("coords", "x")] += dispMagnification*disp.v1
mesh.nodes[("coords", "y")] += dispMagnification*disp.v2
tri = mesh.to_triangulation()
patches = mesh.to_polycollection(facecolor='none',edgecolor = "black",linewidth = .02)
#patches.set_array(field)
patches.set_cmap(mpl.cm.jet)
g=ax.tricontourf(tri, field, levels, cmap = mpl.cm.jet, alpha = 1)
ax.add_collection(patches)
cbar = plt.colorbar(g)
cbar.set_label("$U_{2} (mm)$")
plt.title("Frame:{0}".format(frame))
ax.set_aspect("equal")
ax.set_xlim(mesh.nodes.coords.x.min(), mesh.nodes.coords.x.max())
ax.set_ylim(mesh.nodes.coords.y.min(), mesh.nodes.coords.y.max())
plt.xlabel("$x$")
plt.ylabel("$y$")
plt.show()
<IPython.core.display.Javascript object>
Plot fields at element¶
#Frame number to plot
frame_num=1
Step_name='LOADING3'
parts = {k:part.mesh.copy() for k, part in TracModel.parts.items() }
fig = plt.figure()
ax = fig.add_subplot(1,1,1)
field_num = meta[(meta.label=='PEEQ') & (meta.frame==frame_num) & (meta.step_label==Step_name)].index[0]
disp_num = meta[(meta.label=='U') & (meta.frame==frame_num) & (meta.step_label==Step_name)].index[0]
levels = np.linspace(.0, 0.03, 21)
dispMagnification = 1.
for k, mesh in parts.items():
field =mesh.fields[field_num].data.v
disp = mesh.fields[disp_num].data
frame = mesh.fields[disp_num].frame
mesh.nodes[("coords", "x")] += dispMagnification*disp.v1
mesh.nodes[("coords", "y")] += dispMagnification*disp.v2
#tri = mesh.to_triangulation()
patches = mesh.to_polycollection(edgecolor = "black",linewidth = .02)
patches.set_array(field)
patches.set_cmap(mpl.cm.jet)
cbar = plt.colorbar(patches)
cbar.set_label("$\epsilon^p_{eq} (-)$")
ax.add_collection(patches)
#g=ax.tricontourf(tri, field, levels, cmap = mpl.cm.jet, alpha = 1)
plt.title("Frame:{0}".format(frame))
ax.set_aspect("equal")
ax.set_xlim(mesh.nodes.coords.x.min(), mesh.nodes.coords.x.max())
ax.set_ylim(mesh.nodes.coords.y.min(), mesh.nodes.coords.y.max())
plt.xlabel("$x$")
plt.ylabel("$y$")
plt.show()
<IPython.core.display.Javascript object>