Philosophy¶
The point of the preprocessor is the generation of a simulation case. It allows to define an avatar of a body (a numerical model) in a self content way so that LMGC90’s software will have all needed data to simulate its behaviour. Furthermore, within the preprocessor it is possible to copy, translate or rotate any avatar or container of avatars.
Model and Material definition¶
Models are necessary to define which physics is considered. Material contains physical parameters necessary to simulate a model.
Example:
mod = model(name='rigid', physics='MECAx', element='Rxx2D', dimension=2)
mat = material(name='TDURx', materialType='RIGID', density=1000.)
mut = material(name='TMOUx', materialType='RIGID', density=100.)
Avatar definition¶
An avatar
is first defined by its geometrical discretization:
- a set of nodes: center of inertia for a rigid body, nodes of the mesh for a meshed body (see
node
), - a list of geometrical elements connected to nodes. A rigid model is defined by only one element attached to its only node (center of inertia).
Example:
disk = avatar(dimension=2)
no = node(coor=numpy.array([0.,0.1]),number=1) )
disk.addNode( no )
disk.addBulk( rigid2d() )
Once the nodes and elements are defined for an avatar, groups of element must be defined. There is always at least
one group called ‘all’ which contained all the elements. This notion of group is inherited from the mesh manipulation
and appears for rigid avatars for consistency’s sake. Thus the avatar.defineGroups
method should always
be called.
Modeling properties are then defined:
- list of bulk elements: element with a given material and a model (see
bulk
), - list of contactors: a basic shape attached to some geometrical
element such as the center of gravity for a rigid object or a patch
of linear/surfacic elements for a deformable one (see
contactor
), - initial or driven values of degrees of freedom may be defined.
Example:

Disk creation:
import numpy
radius = 0.1
disk = avatar(dimension=2)
disk.addNode( node(coor=numpy.array([0.,0.1]),number=1) )
disk.addBulk( rigid2d() )
disk.defineGroups()
disk.defineModel(model=mod)
disk.defineMaterial(material=mut)
disk.addContactors(shape='DISKx', color='BLUEx', byrd=radius)
disk.computeRigidProperties()
Foundation creation:
floor = avatar(dimension=2)
floor.addNode( node(coor=numpy.array([0.,-0.05]),number=1) )
floor.addBulk( rigid2d() )
floor.defineGroups()
floor.defineModel(model=mod)
floor.defineMaterial(material=mat)
floor.addContactors(shape='JONCx', color='BLUEx', axe1=1., axe2=0.05)
floor.computeRigidProperties()
Floor boundary condition:
floor.imposeDrivenDof(component=[1,2,3],dofty='vlocy')
Note that for rigids (as other models), the
avatar.defineGroups
method must be called in order to be
able to add model, material, contactors, etc.
When a rigid body defined without giving precision on volume or
inertia, a call to avatar.computeRigidProperties
is also
necessary once the model and material are defined.
Some basic features, like imposing initial or driven values of degrees of freedom, can be applied to a set of
nodes thanks to their group name. To impose initial values to degrees of freeedom of an avatar use: avatar.imposeInitValue
.
To impose driven degrees of freedom of an avatar use: avatar.imposeDrivenDof
Containers¶
Since several model, material, avatar, etc need to be defined some storage mechanism are necessary.
Instead of using Python list of objects pre-lmgc built-in containers
are defined. Available containers are: models
, materials
, avatars
.
Some containers are also hidden in an avatar: nodes
, bulks
and contactors
.
Example:
mods = models()
mods.addModel(mod)
#
mats = materials()
mats+=mat
mats.addMaterial(mut)
#
bodies = avatars()
bodies.addAvatar(disk)
bodies+=floor
Basic operations¶
The methods avatar.translate
and avatar.rotate
allow to translate and
rotate respectively an avatar. To duplicate an avatar, be sure to use deep copy and not shallow copy.
The translation and rotation can be applied to a whole container of avatars
.
Example:

Column creation:
import copy
nb_disks = 10
column = avatars()
for i in range(nb_disks):
new_disk = copy.deepcopy(disk)
new_disk.translate(dy=i*2.*radius)
column.addAvatar(new_disk)

Columns creation and adding to avatar container:
bodies = avatars()
nb_columns = 3
for i in range(nb_columns):
new_column = copy.deepcopy(column)
new_column.translate(dx=i*2.*radius)
for body in new_column:
bodies.addAvatar(body)

Adding floor an rotating it:
bodies.addAvatar(floor)
bodies.rotate(description='axis', center=numpy.array([1.,-0.05]), axis=[0.,0.,1.], alpha=-math.pi/6.)
See this file
for the complete generation script.
The example shows how to generate a simple 2D rigid case. This small set of functions allows a lot
of things already. But it becomes boring to always have to redefine some common behaviours when generating
a lot of samples. That is why some common operations are already implemented using those basic features.