Generators
Relevant module: edelweissfe.config.generators
Mesh generators are used to create meshes, using different methods.
Keyword: *generator
*modelGenerator, generator=theGeneratorType, name=myGeneratorName
multiple lines of defintion ...
multiple lines of defintion ...
multiple lines of defintion ...
boxgen - A 3D box mesh generator
Relevant module edelweissfe.generators.boxgen
A mesh generator for cuboid geometries and structured hex meshes:
__ __ __ __
/__/__/__/__/| A back
/__/__/__/__/ | | top /
/__/__/__/__/ /| | lY | /
|__|__|__|__|//| | nY elements |/
y |__|__|__|__|//| | left----/----right
| |__|__|__|__|//| V /|
|___x |__|__|__|__|//| / / |
/ |__|__|__|__|// / lZ / bottom
z |__|__|__|__|/ / nZ elements front
<----lX----->
nX elements
nSets, elSets, surface : ‘name’_left, _right, _bottom, _top, _front, _back, _all, elSets : ‘name’_centralFrontToBack, _shearBandFrontToBack, _shearBandCenterFrontToBack are automatically generated
*job, name=job, domain=3d, solver=NIST
*modelGenerator, generator=boxGen, name=gen
nX =4
nY =8
nZ =2
lX =20
lY =40
lZ =1
elType =C3D20R
Option |
Type / Default |
Description |
|---|---|---|
x0 |
float, default=0.0 |
Origin along the x axis. |
y0 |
float, default=0.0 |
Origin along the y axis. |
z0 |
float, default=0.0 |
Origin along the z axis. |
lX |
float, default=1.0 |
Length of the body along the x axis. |
lY |
float, default=1.0 |
Length of the body along the y axis. |
lZ |
float, default=1.0 |
Length of the body along the z axis. |
nX |
int, default=1 |
Number of elements along the x axis. |
nY |
int, default=1 |
Number of elements along the y axis. |
nZ |
int, default=1 |
Number of elements along the z axis. |
elType |
str (required) |
Element type. |
elProvider |
str, default=None |
Element provider. |
testfiles/marmot/BoxGen/test.inp*material, name=LinearElastic, id=myMaterial
**Isotropic
**E nu
1.8e4, 0.22
*job, name=job, domain=3d
*solver, solver=NISTParallel, name=theSolver
*modelGenerator, generator=boxGen, name=gen
nX =4
nY =8
nZ =2
lX =20
lY =40
lZ =1
elType =C3D20R
*output, type=meshdatatofile, name=meshdata
filename=myExportedMesh.inc
*modelGenerator, generator=findClosestNode, name=gen2
location='0, 0, 0'
storeIn=origin
*section, name=section1, material=myMaterial, type=solid
all
*fieldOutput
>>perNode, elSet=all, field=displacement, result=U, name=displacement
>>perElement, elSet=all, result=strain, name=strain, quadraturePoint=0:8, f(x)='np.mean(x,axis=1)'
>>perElement, elSet=all, result=stress, name=stress, quadraturePoint=0:8, f(x)='np.mean(x,axis=1)'
*output, type=ensight, name=test
>>perNode, fieldOutput=displacement
>>perElement, fieldOutput=stress
>>perElement, fieldOutput=strain
>>configuration, overwrite=yes
*step, solver=theSolver
maxInc=1e0, minInc=1e0, maxNumInc=100, maxIter=25, stepLength=1
>>dirichlet, name=x0u, nSet=gen_left, field=displacement, 1=0.
>>dirichlet, name=y0u, nSet=gen_bottom, field=displacement, 2=0.
>>dirichlet, name=z0u, nSet=gen_back, field=displacement, 3=0.
>>dirichlet, name=y1u, nSet=gen_top, field=displacement, 2=-5.
planerectquad - A 2D plane rectangular mesh generator
Relevant module edelweissfe.generators.planerectquad
A mesh generator, for rectangular geometries and structured quad meshes:
<-----l----->
nX elements
__ __ __ __
|__|__|__|__| A
|__|__|__|__| |
|__|__|__|__| | h
|__|__|__|__| | nY elements
| |__|__|__|__| |
| |__|__|__|__| V
x0|_____
y0
nSets, elSets, surface : ‘name’_top, _bottom, _left, _right, … are automatically generated
Datalines:
Option |
Type / Default |
Description |
|---|---|---|
x0 |
float, default=0.0 |
Origin along the x axis. |
y0 |
float, default=0.0 |
Origin along the y axis. |
z0 |
float, default=0.0 |
Origin along the z axis. |
l |
float, default=1.0 |
Height of the body. |
h |
float, default=1.0 |
Length of the body. |
nX |
int, default=1 |
Number of elements along the x axis. |
nY |
int, default=1 |
Number of elements along the y axis. |
nZ |
int, default=1 |
Number of elements along the z axis. |
elType |
str (required) |
Element type. |
elProvider |
str, default=None |
Element provider. |
testfiles/marmot/NodeForces/test.inp*material, name=VonMises, id=mat
210000, 0.3, 550, 1000, 200, 1400
*section, name=section1, thickness=1.0, material=mat, type=plane
all
*job, name=cps4job, domain=2d
*solver, solver=NIST, name=theSolver
*modelGenerator, generator=planeRectQuad, name=gen
x0=0, l=50
y0=0, h=100
elType=CPS4
nX=10
nY=10
*fieldOutput
>>perNode, nSet=gen_bottom, result=P, field=displacement, name=RF
>>perNode, elSet=all, field=displacement, result=U, name=displacement
*output, type=monitor
fieldOutput=RF, f(x)='mean(x[:,1])'
*output, type=ensight, name=esExport
>>perNode, fieldOutput=displacement
>>configuration, overwrite=yes
*step, solver=theSolver
maxInc=1e-1, minInc=1e-8, maxNumInc=50, maxIter=25, stepLength=100
>>dirichlet, name=bottom, nSet=gen_bottom, field=displacement, 2=0, 1=0
>>nodeforces, name=cloadTop, nSet=gen_top, field=displacement, 2=-50
*step, solver=theSolver
maxInc=1e-1, minInc=1e-8, maxNumInc=1000, maxIter=25, stepLength=100
>>nodeforces, name=cloadTop, 2=-10, f(t)=sin(t*2*pi)
*step, solver=theSolver
maxInc=1e-1, minInc=1e-8, maxNumInc=1000, maxIter=25, stepLength=100
>>nodeforces, name=cloadTop, 2=+50, f(t)=t
pipegen - A 3D pipe mesh generator
Relevant module edelweissfe.generators.pipegen
Option |
Type / Default |
Description |
|---|---|---|
x0 |
float, default=0.0 |
Origin along the x axis. |
y0 |
float, default=0.0 |
Origin along the y axis. |
z0 |
float, default=0.0 |
Origin along the z axis. |
Ro(y) |
str, default=’1.0’ |
Outer radius of the pipe as a function of height. |
Ri(y) |
str, default=’1.0’ |
Inner radius of the pipe as a function of height. |
lT |
float, default=0.5 |
Thickness of the pipe. |
lY |
float, default=1.0 |
Height of the pipe. |
phi |
float, default=360.0 |
Total angle for the pipe sector. |
nT |
int, default=1 |
Number of elements along radial direction. |
nC |
int, default=4 |
Number of elements along circumferential direction. |
nY |
int, default=4 |
Number of elements along longitudinal direction. |
exG |
bool, default=True |
Flag to place nodes on exact geometry. |
elType |
str (required) |
Element type. |
elProvider |
str, default=None |
Element provider. |
testfiles/marmot/PipeGen/test.inp*material, name=LinearElastic, id=linearelastic
2.1e4, 0.22
*job, name=c3d8job, domain=3d
*solver, solver=NIST, name=theSolver
*modelGenerator, generator=pipeGen, name=gen
nT =1
nC =8
nY =30
x0 =10
y0 =50
z0 =100
lT =10
Ro(y) =200.-0.1*y
phi =90
lY =1000
exG =False
elType =C3D20
*section, name=section1, material=linearelastic, type=solid
all
*fieldOutput
>>perNode, elSet=all, field=displacement, result=U, name=displacement
*output, type=ensight, name=test
>>perNode, fieldOutput=displacement
>>configuration, overwrite=yes
*step, solver=theSolver
maxInc=1, minInc=1e-9, maxNumInc=1000, maxIter=25, stepLength=1
>>options, name=theSolver, extrapolation=off
>>dirichlet, name=Bottom, nSet=gen_bottom, field=displacement, 1=0.0, 2=0.0, 3=.0
>>nodeforces, name=cloadTop, nSet=gen_inner, components='0.3, 0, 0.3', field=displacement
cubit - A cubit mesh generator
Relevant module edelweissfe.generators.cubit
Interface to Cubit. Generate mesh using Cubit .jou files.
Option |
Type / Default |
Description |
|---|---|---|
cubitCmd |
str, default=’cubit’ |
Cubit executable. |
jouFile |
str (required) |
Path to Cubit journal (.jou) file. |
outFile |
str, default=’mesh.inc’ |
Path to output mesh file. |
APREPROVars |
str, default=None |
APREPRO variables as comma-separated <key>=<value> pairs. |
overwrite |
bool, default=True |
Overwrite existing output files. |
runCubit |
bool, default=False |
Run Cubit GUI for debugging purposes. |
silent |
bool, default=False |
Hide Cubit output. |
elType |
str, default=None |
Specify element type for all sections. |
elTypePerBlock |
str, default=None |
Specify element type per block as comma-separated <key>=<value> pairs. |
elProvider |
str, default=None |
Element provider. |
testfiles/marmot/CubitGen/test.inp*material, name=LINEARELASTIC, id=mat1
35000, 0.2
*material, name=LINEARELASTIC, id=mat2
3000, 0.49
*modelGenerator, generator=cubit, name=gen
**cubitCmd = singularity exec <pathToImage>.smg coreform_cubit
cubitCmd = cubit
jouFile = journal.jou
APREPROVars = 'Lx=4, Ly=2, Lz=5'
elTypePerBlock = 'block1=C3D8, block2=C3D8'
silent
** runCubit = True
** overwrite = False
*section, name=section1, material=mat1, type=solid
block1
*section, name=section2, material=mat2, type=solid
block2
*job, name=set_def, domain=3d
*solver, solver=NISTParallel, name=theSolver
*fieldOutput
>>perNode, elSet=all, name=displacement, field=displacement, result=U
>>perElement, elSet=all, name=stress, result=stress, quadraturePoint=0:8, f(x)='np.mean(x,axis=1)'
>>perElement, elSet=all, name=strain, result=strain, quadraturePoint=0:8, f(x)='np.mean(x,axis=1)'
*output, type=ensight, name=esExport
>>perNode, fieldOutput=displacement
>>perElement, fieldOutput=stress
>>perElement, fieldOutput=strain
>>configuration, overwrite=yes
*step, solver=theSolver
maxInc=5e-1, minInc=1e-8, maxNumInc=1000, maxIter=25, stepLength=1
>>dirichlet, name=bot, nSet=n_bot, field=displacement, 1=0., 2=0., 3=0.
>>dirichlet, name=top, nSet=n_top, field=displacement, 1=0., 2=-1., 3=0.
findclosestnode - Find the closest node
Relevant module edelweissfe.generators.findclosestnode
Find the node closest to a given spatial position, and store it in an existing or new node set.
Option |
Type / Default |
Description |
|---|---|---|
location |
str (required) |
Query point. |
storeIn |
str (required) |
Node set to store closest node in. |
cylindergenerator - A structured hex mesh generator for cylindrical geometries
Relevant module edelweissfe.generators.cylindergenerator
A structured hex mesh generator for cylindrical geometries.
The cylinder is extruded along one of the global coordinate axes, selected
with axis (x, y or z; y by default). The cross section
(perpendicular to that axis) is meshed as an O-grid: a square core block in
the center, surrounded by nR concentric rings of quads that map the
square’s boundary radially outward onto the circle. This avoids triangles
and a singular node on the axis, so the resulting quad mesh can be extruded
into a fully hexahedral mesh. The core block’s own subdivision is chosen
automatically so its elements are similarly sized to the ring elements:
nSets, elSets, surface: ‘name’_top, _bottom, _outer, _all are automatically
generated. _top/_bottom refer to the two end faces (perpendicular to
axis), _outer to the lateral (mantle) surface at r=radius.
Additional nSets: ‘name’_centerTop/_centerBottom, the single node on the
cylinder’s axis at each end face; and, for the two global axes spanning the
cross section, ‘name’_centerLine<A>Top/_centerLine<A>Bottom, the nodes on
the diametral line parallel to axis <A> passing through the cylinder’s axis,
on the top and bottom end faces only. <A> is spelled in upper case, so the
default axis=y yields _centerLineXTop/_centerLineXBottom and
_centerLineZTop/_centerLineZBottom.
Optionally, the cylinder can be divided into sections along its length with
sectionLengths and sectionNY (one entry per section, from bottom to
top), which then replace lY and nY. Each section i (0-based) gets an
elSet and an nSet ‘name’_section<i>; the nSet includes the nodes on the
section’s end faces, which are shared with the adjacent sections. The part of
the outer surface belonging to a section is additionally available as nSet,
elSet and surface ‘name’_section<i>_outer.
Symmetry can be exploited by modeling only a half or a quarter of the
cylinder, selected with part: a half is given by one signed in-plane axis
(e.g. +x, the half with x >= x0), a quarter by two (e.g. +x-z). The
mesh is exactly the corresponding part of the full mesh. For each cutting
plane, an nSet ‘name’_symmetry<A> holds the nodes on the plane normal to
axis <A> (upper case), e.g. _symmetryX for part=+x.
Example
Generate meshes on the fly using the following syntax:
*job, name=job, domain=3d, solver=NIST
*modelGenerator, generator=cylinderGenerator, name=gen
radius =5.0
lY =10.0
nR =4
nY =8
elType =C3D8
Extruding along another axis only takes axis; lY and nY keep
their names but are then measured along that axis, and x0/y0/z0
still give the center of the bottom face:
*modelGenerator, generator=cylinderGenerator, name=gen
axis =z
z0 =-10.0
radius =5.0
lY =10.0
nR =4
nY =8
elType =C3D8
Three sections of different lengths and mesh densities:
*modelGenerator, generator=cylinderGenerator, name=gen
radius =5.0
sectionLengths ='2.0, 6.0, 2.0'
sectionNY ='4, 6, 4'
nR =4
elType =C3D8
A quarter of the cylinder, x >= 0 and z <= 0:
*modelGenerator, generator=cylinderGenerator, name=gen
radius =5.0
lY =10.0
nR =4
nY =8
part =+x-z
elType =C3D8
Option |
Type / Default |
Description |
|---|---|---|
axis |
str, default=’y’ |
Global coordinate axis the cylinder is extruded along: ‘x’, ‘y’ or ‘z’. The remaining two axes span the cross section. |
x0 |
float, default=0.0 |
Origin along the x axis: the bottom face of the cylinder if axis=’x’, the center of its cross section otherwise. |
y0 |
float, default=0.0 |
Origin along the y axis: the bottom face of the cylinder if axis=’y’, the center of its cross section otherwise. |
z0 |
float, default=0.0 |
Origin along the z axis: the bottom face of the cylinder if axis=’z’, the center of its cross section otherwise. |
radius |
float, default=1.0 |
Radius of the cylinder. |
lY |
float, default=1.0 |
Height of the cylinder, measured along ``axis`` (not necessarily the y axis). |
nR |
int, default=4 |
Number of elements along the radius, i.e., along a straight line from the center to the outer (lateral) surface. This is split automatically between the central square core block and the concentric rings surrounding it, keeping their element sizes similar. |
nY |
int, default=4 |
Number of elements along the height, i.e., along ``axis`` (not necessarily the y axis). |
sectionLengths |
str, default=None |
Lengths of the sections the cylinder is divided into along ``axis``, from bottom to top, as a comma-separated list (quoted in the input file). Replaces ``lY``; requires ``sectionNY``. |
sectionNY |
str, default=None |
Number of elements along ``axis`` per section, as a comma-separated list matching ``sectionLengths``. Replaces ``nY``. |
part |
str, default=’full’ |
Part of the cross section to model, exploiting symmetry: ‘full’, a half given by one signed in-plane axis (e.g. ‘+x’ for the half with x >= x0), or a quarter given by two (e.g. ‘+x-z’). |
coreFraction |
float, default=0.7 |
Half-width of the central square core block, as a fraction of the radius. |
curvedBoundary |
bool, default=True |
For quadratic elements only: place mid-side nodes on the outer surface exactly on the circle instead of at the straight-line midpoint. |
elType |
str (required) |
Element type. |
elProvider |
str, default=None |
Element provider. |
testfiles/marmot/CylinderGen/test.inp*material, name=LinearElastic, id=linearelastic
2.0e4, 0.2
*material, name=LinearElastic, id=soft
2.0e3, 0.2
*job, name=job, domain=3d
*solver, solver=NIST, name=theSolver
*modelGenerator, generator=cylinderGenerator, name=gen
radius =5.0
lY =10.0
nR =3
nY =5
elType =C3D20R
** second cylinder, offset from the first and divided into three sections along its length
*modelGenerator, generator=cylinderGenerator, name=gen2
x0 =15.0
radius =5.0
sectionLengths ='3.0, 4.0, 3.0'
sectionNY ='2, 3, 2'
nR =3
elType =C3D20R
** half cylinder (z <= 0), exploiting symmetry
*modelGenerator, generator=cylinderGenerator, name=gen3
x0 =30.0
radius =5.0
lY =10.0
nR =3
nY =2
part =-z
elType =C3D20R
** quarter cylinder (x >= x0, z <= 0), divided into sections, exploiting symmetry
*modelGenerator, generator=cylinderGenerator, name=gen4
x0 =45.0
radius =5.0
sectionLengths ='4.0, 6.0'
sectionNY ='1, 1'
nR =3
part =+x-z
elType =C3D8
*section, name=section1, material=linearelastic, type=solid
gen_all
gen2_section0
gen2_section2
gen3_all
gen4_all
*section, name=section2, material=soft, type=solid
gen2_section1
*fieldOutput
>>perNode, elSet=all, field=displacement, result=U, name=displacement
*output, type=ensight, name=test
>>perNode, fieldOutput=displacement
>>configuration, overwrite=yes
*step, solver=theSolver
maxInc=1.0, minInc=1.0, maxNumInc=100, maxIter=25, stepLength=1
>>dirichlet, name=fixBottom, nSet=gen_bottom, field=displacement, 1=0.0, 2=0.0, 3=0.0
>>dirichlet, name=axialTop, nSet=gen_top, field=displacement, 2=-0.05
>>distributedload, name=confinement, surface=gen_outer, magnitude=1.0, f(t)=1, type=pressure
>>dirichlet, name=fixBottom2, nSet=gen2_bottom, field=displacement, 1=0.0, 2=0.0, 3=0.0
>>dirichlet, name=axialTop2, nSet=gen2_top, field=displacement, 2=-0.05
>>distributedload, name=confinement2, surface=gen2_outer, magnitude=1.0, f(t)=1, type=pressure
>>dirichlet, name=fixBottom3, nSet=gen3_bottom, field=displacement, 1=0.0, 2=0.0, 3=0.0
>>dirichlet, name=axialTop3, nSet=gen3_top, field=displacement, 2=-0.05
>>dirichlet, name=symmetryZ3, nSet=gen3_symmetryZ, field=displacement, 3=0.0
>>distributedload, name=confinement3, surface=gen3_outer, magnitude=1.0, f(t)=1, type=pressure
>>dirichlet, name=fixBottom4, nSet=gen4_bottom, field=displacement, 1=0.0, 2=0.0, 3=0.0
>>dirichlet, name=axialTop4, nSet=gen4_top, field=displacement, 2=-0.05
>>dirichlet, name=symmetryX4, nSet=gen4_symmetryX, field=displacement, 1=0.0
>>dirichlet, name=symmetryZ4, nSet=gen4_symmetryZ, field=displacement, 3=0.0
>>distributedload, name=confinement4, surface=gen4_section1_outer, magnitude=1.0, f(t)=1, type=pressure
cuboidlatticegenerator - A cuboid lattice mesh generator
Relevant module edelweissfe.generators.cuboidlatticegenerator
A mesh generator for generating cuboid lattice structure. The following unit cell is generted and then replicated in x, y, and z direction:
+---------------+
/ +---------+ /|
/ / / / |
/ / / / |
/ +---------+ / +|
+---------------+ /||
| | + ||
| +---------+ | | ||
| | | | | +|
| | | | |/ +
| | | | + /
| | | | /
| +---------+ | /
| |/
+---------------+
After generating the unit cell mesh the microstructure generator is used to replicate the unit cell mesh in x, y, and z direction.
Example
Generate meshes on the fly using the following syntax:
*job, name=job, domain=2d, solver=NIST
*modelGenerator, generator=cuboidlatticegenerator, name=gen
lX=4
lY=8
lZ=2
nEleX=8
nEleY=16
nEleZ=4
nEleStrutX=2
nEleStrutY=4
nEleStrutZ=1
nX=3
nY=4
nZ=2
Option |
Type / Default |
Description |
|---|---|---|
lX |
float, default=1.0 |
Length of the body along the x axis. |
lY |
float, default=1.0 |
Length of the body along the y axis. |
lZ |
float, default=1.0 |
Length of the body along the z axis. |
nEleX |
int, default=1 |
Number of elements along the x axis. |
nEleY |
int, default=1 |
Number of elements along the y axis. |
nEleZ |
int, default=1 |
Number of elements along the z axis. |
nEleStrutX |
int, default=1 |
Number of in struts along the x axis. |
nEleStrutY |
int, default=1 |
Number of in struts along the y axis. |
nEleStrutZ |
int, default=1 |
Number of in struts along the z axis. |
nX |
int, default=1 |
Number of replications along the x axis. |
nY |
int, default=1 |
Number of replications along the y axis. |
nZ |
int, default=1 |
Number of replications along the z axis. |
elType |
str (required) |
Element type. |
elProvider |
str, default=None |
Element provider. |
testfiles/edelweiss-only/CuboidLatticeGenerator/test.inp*modelGenerator, generator=cuboidlatticegenerator, name=gen
lX=5
lY=5
lZ=5
nEleX=5
nEleY=5
nEleZ=5
nEleStrutX=2
nEleStrutY=2
nEleStrutZ=2
nX=1
nY=2
nZ=1
elType=C3D8TL
elProvider=edelweiss
*material, name=neohooke, id=myMaterial, provider=edelweiss
2, 10, 0.47
*section, name=section1, material=myMaterial, type=solid
all
*job, name=myJob, domain=3d
*solver, solver=NIST, name=theSolver
*modelGenerator, generator=findClosestNode, name=gen3
location='5, 15, 5'
storeIn=topRP
*step, solver=theSolver
maxInc=1, minInc=1e-3, maxNumInc=100, maxIter=25, stepLength=180
** initializematerial, name=init, elSet=all
>>dirichlet, name=1, nSet=gen_bottom, field=displacement, 1=0, 2=0, 3=0
>>dirichlet, name=4, nSet=gen_top, field=displacement, 3=0.1, 2=0, 1=0
*fieldOutput
>>perNode, name=displacement, elSet=all, field=displacement, result=U
>>perElement, name=stress, elSet=all, result=stress, quadraturePoint=0:3, f(x)='np.mean(x,axis=1)'
*output, type=ensight, name=myEnsightOutput
>>perNode, fieldOutput=displacement
>>configuration, overwrite=yes
microstructuregenerator - A unit-cell-based microstructure mesh generator
Relevant module edelweissfe.generators.microstructuregenerator
A mesh generator for generating a structure from a single unit cell mesh: The unit cell mesh must be readable by meshio (e.g., in .inp format).
*job, name=job, domain=2d, solver=NIST
*modelGenerator, generator=microstructuregenerator, name=gen
unitCellMeshFile = myUnitCellMesh.inp
nX =4
nY =8
nZ =2
Option |
Type / Default |
Description |
|---|---|---|
unitCellMeshFile |
str, default=None |
Path to the unit cell mesh file. |
nX |
int, default=1 |
Number of cells along the x axis. |
nY |
int, default=1 |
Number of cells along the y axis. |
nZ |
int, default=1 |
Number of cells along the z axis. |
elType |
str (required) |
Element type. |
elProvider |
str, default=None |
Element provider. |
testfiles/edelweiss-only/MicrostructureGenerator/test.inp*modelGenerator, generator=microstructuregenerator, name=gen
unitCellMeshFile=mesh_quadratic.inp,
nX=2,
nY=2,
nZ=1,
elType=CPE8R,
elProvider=edelweiss
*material, name=LINEARELASTIC, id=myMaterial, provider=edelweiss
100, 3
*section, name=section1, material=myMaterial, type=plane, thickness=1.0
** element set 'all' is automatically created
** we could also use the set 'theOnlyElement'
all
*job, name=mySingleElementJob, domain=2d
*solver, solver=NIST, name=theSolver
*step, solver=theSolver
maxInc=1e0, minInc=1e-1, maxNumInc=100, maxIter=25, stepLength=1
>>dirichlet, name=1, nSet=gen_top, field=displacement, 1=1, 2=0
>>dirichlet, name=2, nSet=gen_bottom, field=displacement, 1=0, 2=0
*output, type=meshdatatofile
filename=5x5mesh_quadratic.inp
*fieldOutput
** The results we are interested in
>>perElement, name=stress, elSet=all, result=stress, quadraturePoint=0:3, f(x)='np.mean(x,axis=1)'
>>perNode, name=displacement, elSet=all, field=displacement, result=U
>>perNode, name=reactionForces, nSet=gen_bottom, field=displacement, result=P, f(x)='np.sum(x[:,1])', saveHistory=True, export=RF
*output, type=ensight, name=myEnsightOutput
** For visualization in Paraview etc.
>>perNode, fieldOutput=displacement
>>perElement, fieldOutput=stress
>>configuration, overwrite=yes
discreterigidbodygenerator - A discrete rigid body from a surface mesh file
Relevant module edelweissfe.generators.discreterigidbodygenerator
A generator for discrete rigid bodies from surface mesh files (Exodus, STL, OBJ, or any other format readable by PyVista).
Loading the mesh, creating the surface/reference-point nodes, and mutating
the model are all handled here – mirroring how every other model-populating
generator in EdelweissFE/EdelweissMeshfree works – so that
DiscreteRigidBody itself
only has to deal with rigid body kinematics, not with how it is instantiated.
Option |
Type / Default |
Description |
|---|---|---|
filename |
str (required) |
The file path to the surface mesh (e.g., Exodus, STL, OBJ). |
translation |
str, default=None |
A comma-separated 3D vector to translate the mesh globally upon initialization. |
density |
float, default=None |
The (uniform) mass density of the rigid body; if given, mass and rotary inertia are computed exactly from the mesh geometry. |
mass |
float, default=None |
The total mass of the rigid body. Overrides the density-based computation. |
inertia |
str, default=None |
A comma-separated diagonal rotary inertia [Ixx, Iyy, Izz]. Overrides the density-based computation. |
rpCoordinate |
str, default=None |
A comma-separated explicit global coordinate for the reference point. Defaults to the (exact or approximate) center of mass. |
testfiles/edelweiss-only/NodeToDiscreteRigidBodyContact/test.inp*material, name=LinearElastic, id=linearelastic, provider=edelweiss
**Isotropic
**E nu
1.8e4, 0.22
*job, name=c3d8job, domain=3d
*solver, solver=NIST, name=theSolver
*modelGenerator, generator=boxGen, name=block
nX =12
nY =12
nZ =2
lX =10
lY =10
lZ =5
elProvider =edelweiss
elType =C3D8
** A cylinder (radius 5, axis along z, flat end caps) taken from
** EdelweissMeshfree's discrete rigid body contact example, translated so its
** top cap sits flush with the block's bottom (z=0) face and shifted
** off-center relative to the block's footprint -- so only part of the
** cylinder's flat cap (and, at the far corner, its rounded rim) underlies
** the block, making the contact patch asymmetric.
*modelGenerator, generator=discreteRigidBodyGenerator, name=cylinder
filename=rigid_body.exo
translation='0, -10, -11.0'
** Scoped to block_all rather than all: all also contains the rigid body's
** surface/RP nodes/elements, which cannot take a solid section.
*section, name=section1, material=linearelastic, type=solid
block_all
*constraint, type=nodeToDiscreteRigidBodyPenalty, name=contact
nSet=block_back
rigidBody=cylinder
penalty=1e8
*fieldOutput
>>perNode, elSet=all, field=displacement, name=displacement, result=U
>>perNode, rigidBody=cylinder, field=displacement, name=cylinderDisplacement, result=U
>>perNode, nSet=cylinder_rp, field=displacement, name=rpForce, result=P, f(x)=' sum ( x, axis=0 )'
*output, type=ensight, name=test
>>perNode, fieldOutput=displacement
>>perNode, fieldOutput=cylinderDisplacement
>>configuration, overwrite=yes
*output, type=monitor, name=rpForceMon
fieldOutput=rpForce
*step, solver=theSolver
maxInc=0.1, minInc=1e-9, maxNumInc=100, maxIter=25, stepLength=1
>>options, name=theSolver, extrapolation=off
>>dirichlet, name=frontFixed, nSet=block_front, field=displacement, 1=0.0, 2=0.0, 3=0.0
>>dirichlet, name=rpDisp, nSet=cylinder_rp, field=displacement, 1=0.0, 2=0.0, 3=3.00
>>dirichlet, name=rpRot, nSet=cylinder_rp, field=rotation, 1=0.15, 2=0.0, 3=0.0
executepythoncode - Script model generation using Python
Relevant module edelweissfe.generators.executepythoncode
Directly execute Python code to create the model tree.
The datalines are joined line by line and executed as Python source, with the model tree bound
to the name model.
Leading whitespace of datalines is not preserved by the input file parser, so indented blocks
(loops, conditionals, function bodies) cannot be written with plain spaces or tabs. Instead,
indent with the literal two-character sequence \t: every occurrence is replaced by a tab
character before the code is executed, so \t\t indents a line by two levels.
*modelGenerator, generator=executePythonCode, name=gen-2
from edelweissfe.sets.nodeset import NodeSet
load_nodes = []
for n in model.nodes.values():
\tif abs( n.coordinates[0] - 495 ) <= 20:
\t\tif abs( n.coordinates[1] - 81 ) <= 1e-12:
\t\t\tload_nodes.append(n)
model.nodeSets['load'] = NodeSet('load', load_nodes)
Note that \t is replaced everywhere in the code, including inside string literals.
Option |
|---|
executepythoncode declares no option schema – see its own class docstring. |
testfiles/marmot/PythonCodeModelGeneration/test.inp*modelGenerator, generator=planeRectQuad, name=gen
elType=CPS8R
nX=20
nY=20
l=100
h=100
*modelGenerator, generator=executePythonCode, name=gen-2, executeAfterManualGeneration=True
** we find all nodes at 50% of the height
from edelweissfe.sets.nodeset import NodeSet
model.nodeSets['center_horizontal'] = NodeSet('center_horizontal', [n for n in model.nodes.values()
if abs( n.coordinates[1] - 50.0 ) <= 1e-12 ])
*material, name=linearelastic, id=linearelastic
30000.0, 0.15
*section, name=section1, thickness=1.0, material=linearelastic, type=plane
all
*job, name=myJob, domain=2d
*solver, solver=NIST, name=theSolver
*fieldOutput
>>perNode, name=displacement, elSet=all, field=displacement, result=U,
>>perNode, name=RF, nSet=gen_bottom, field=displacement, result=P,
>>perElement, name=stress, elSet=all, result=stress, quadraturePoint=0:4, f(x)='mean(x, axis=1)'
>>perElement, name=strain, elSet=all, result=strain, quadraturePoint=0:4, f(x)='mean(x, axis=1)'
*output, type=monitor, name=theMonitor
fieldOutput = RF, f(x) = 'sum ( x, axis=0 )'
*output, type=ensight, name=ensightExport
>>perNode, fieldOutput=displacement
>>perElement, fieldOutput=stress
>>perElement, fieldOutput=strain
>>configuration, overwrite=yes
*step, solver=theSolver
maxInc=1e-1, minInc=1e-5, maxNumInc=1000, maxIter=25, stepLength=1
>>options, name=theSolver, extrapolation=linear
>>dirichlet, name=bottom, nSet=gen_bottom, field=displacement, 1=0.0, 2=0.0
>>dirichlet, name=load, nSet=center_horizontal, field=displacement, 1=5.0, 2=5.0
testfiles/edelweiss-only/PythonCodeModelGenerationIndented/test.inp** Four-point bending of a two-layer beam (half model), with the node and element sets for
** the load, the bearing and the soft mid-layer created by an executePythonCode generator.
** The generator's datalines are written with literal \t sequences for indentation, which
** executePythonCode converts to tabs, so nested loops and conditionals can be used.
*modelgenerator, generator=boxgen, name=gen
lX =770
lY =81
lZ =150
nX =10
nY =3
nZ =2
elProvider =edelweiss
elType =C3D20
*modelGenerator, generator=executePythonCode, name=gen-2, executeAfterManualGeneration=False
from edelweissfe.sets.nodeset import NodeSet
from edelweissfe.sets.elementset import ElementSet
def nodesOnFace(x, y, tol):
\treturn [n for n in model.nodes.values() if abs(n.coordinates[0] - x) <= tol and abs(n.coordinates[1] - y) <= 1e-12]
load_nodes = []
for n in model.nodes.values():
\tif abs( n.coordinates[0] - 495 ) <= 20:
\t\tif abs( n.coordinates[1] - 81 ) <= 1e-12:
\t\t\tload_nodes.append(n)
model.nodeSets['load'] = NodeSet('load', load_nodes)
model.nodeSets['bearing'] = NodeSet('bearing', nodesOnFace(41.25, 0, 20))
mid_elements = []
for e in model.elements.values():
\tcenter = e.getCoordinatesAtCenter()
\tif abs( center[1] - 81/2 ) <= 81/6:
\t\tmid_elements.append(e)
model.elementSets['mid-layer'] = ElementSet('mid-layer', mid_elements)
*material, name=linearelastic, id=top-bottom, provider=edelweiss
9000, 0.2
*material, name=linearelastic, id=mid, provider=edelweiss
4500, 0.2
*section, name=section1, material=top-bottom, type=solid
all
*section, name=section2, material=mid, type=solid
mid-layer
*job, name=bendingjob, domain=3d
*solver, solver=NIST, name=theSolver
*modelgenerator, generator=findclosestnode, executeAfterManualGeneration=True, name=fcn1
location='41.25,0,150', storeIn=support
*modelgenerator, generator=findclosestnode, executeAfterManualGeneration=True, name=fcn2
location='495,82.5,150', storeIn=load-rp
*constraint, type=linearizedrigidbody, name=bearing
referencePoint=support
nSet=bearing
*constraint, type=linearizedrigidbody, name=load
referencePoint=load-rp
nSet=load
*fieldOutput
>>perNode, elSet=all, field=displacement, result=U, name=displacement
>>perNode, nSet=bearing, field=displacement, result=P, name=support-force, f(x)="np.sum( x[:,1] )", saveHistory=True
*output, type=ensight, name=esExport
>>configuration, overwrite=True
>>perNode, fieldOutput=displacement
*step, solver=theSolver
maxInc=5e-1, minInc=1e-8, maxNumInc=1000, maxIter=25
>>dirichlet, name=support, nSet=support, field=displacement, 2=0
>>dirichlet, name=support-rot, nSet=support, field=rotation, 1=0, 2=0, 3=0
>>dirichlet, name=load, nSet=load-rp, field=displacement, 2=-5
>>dirichlet, name=load-rot, nSet=load-rp, field=rotation, 1=0, 2=0, 3=0
>>dirichlet, name=sym-x, nSet=gen_right, field=displacement, 1=0
>>dirichlet, name=sym-z, nSet=gen_back, field=displacement, 3=0,
surfaceElementGenerator - Contact facet elements from a *surface
Relevant module edelweissfe.generators.surfaceelementgenerator
Generates flat, geometry-only “contact facet” elements (Tria3ContactFacet / Line2ContactFacet) from an existing *surface
definition, for use as the slave or master side of node-to-deformable-surface penalty contact.
Quad faces of 3D solids are split into two Tria3 facets via a fixed diagonal. Higher-order
element faces are either reduced to their linear corner-node subset (triangulation=corner,
exact for straight-edged meshes) or triangulated including their midside nodes
(triangulation=midside, strictly more accurate for curved faces). The facets carry
face-consistent per-node tributary area shares for the pressure-weighted contact formulation;
nodalWeights selects between the facet tiling’s own consistent shares and the non-negative
weighting that best approximates a serendipity face’s consistent nodal loads. See the
contact theory documentation for the full background.
The underlying buildContactFacets() is idempotent and re-runnable, so a
MeshDependent consumer of these facets (e.g.
nodetodeformablesurfacepenalty) can regenerate them from the
current *surface definition after the source solid elements change underneath it (e.g. an AMR
refinement) as well as at setup time; the recipe is recorded in model.contactFacetRecipes.
*modelGenerator, generator=surfaceElementGenerator, name=gen
surface = mySurface
name = myContactSurface
Option |
Type / Default |
Description |
|---|---|---|
surface |
str (required) |
The name of an existing *surface definition. |
name |
str (required) |
The prefix for the generated element/node sets. |
triangulation |
str, default=’corner’ |
The facet triangulation of higher-order element faces: ‘corner’ (linear corner-node subset only; exact for straight-edged meshes) or ‘midside’ (triangulation of the full face boundary including midside nodes; strictly more accurate for curved faces). Linear element faces are unaffected by this option. |
nodalWeights |
str, default=’facetConsistent’ |
The per-node contact weighting of the generated facets: ‘facetConsistent’ (the consistent nodal loads of the flat facet tiling itself) or ‘serendipityOptimal’ (the resultant-exact, non-negative weighting that minimises the mismatch against a quadratic face’s own consistent nodal loads, by reassigning each corner node’s share to its two adjacent midside nodes – the modified shape functions of Puso, Laursen & Solberg, CMAME 2008). Reduces the spurious corner/midside load pattern on hexa20 contact surfaces by a third, at the price of corner nodes ceasing to be contact points – but NO measured benefit has been demonstrated, because a quadratic face under near-uniform pressure lifts its corner nodes off anyway, which makes their weight moot; see the contact theory documentation. Requires triangulation=’midside’; linear element faces are unaffected by this option. |
testfiles/edelweiss-only/NodeToDeformableSurfaceContact/test.inp*material, name=LinearElastic, id=linearelastic, provider=edelweiss
1.8e4, 0.3
*job, name=contactjob, domain=3d
*solver, solver=NIST, name=theSolver
*modelGenerator, generator=boxGen, name=lower
nX =3
nY =3
nZ =3
x0 =0
y0 =0
z0 =0
lX =2
lY =2
lZ =1
elProvider =edelweiss
elType =C3D8
*modelGenerator, generator=boxGen, name=upper
nX =3
nY =3
nZ =3
x0 =0.3
y0 =1.1
z0 =1.05
lX =0.6
lY =0.6
lZ =1
elProvider =edelweiss
elType =C3D8
*modelGenerator, generator=surfaceElementGenerator, name=gen1
surface = upper_back
name = slaveSurf
*modelGenerator, generator=surfaceElementGenerator, name=gen2
surface = lower_front
name = masterSurf
*section, name=section1, material=linearelastic, type=solid
lower_all
upper_all
*constraint, name=contact, type=nodeToDeformableSurfacePenalty
slaveSurface=slaveSurf_facets, masterSurface=masterSurf_facets, penalty=5e6, type=linear, searchDistance=2.0
*fieldOutput
>>perNode, elSet=lower_all, field=displacement, result=U, name=dispLower
>>perNode, elSet=upper_all, field=displacement, result=U, name=dispUpper
*output, type=ensight, name=esExport
>>perNode, fieldOutput=dispLower
>>perNode, fieldOutput=dispUpper
>>configuration, overwrite=yes
*step, solver=theSolver
maxInc=0.02, minInc=1e-6, maxNumInc=200, maxIter=25, stepLength=1
>>options, name=theSolver, extrapolation=off
>>dirichlet, name=fixLower, nSet=lower_back, field=displacement, 1=0.0, 2=0.0, 3=0.0
>>dirichlet, name=pushDown, nSet=upper_front, field=displacement, 3=-0.2
>>dirichlet, name=pinUpperXY, nSet=upper_bottomLeftBack, field=displacement, 1=0.0, 2=0.0
>>dirichlet, name=pinUpperRotZ, nSet=upper_bottomRightBack, field=displacement, 2=0.0