1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314
|
#############################################################
## ##
## Copyright (c) 2003-2017 by The University of Queensland ##
## Centre for Geoscience Computing ##
## http://earth.uq.edu.au/centre-geoscience-computing ##
## ##
## Primary Business: Brisbane, Queensland, Australia ##
## Licensed under the Open Software License version 3.0 ##
## http://www.apache.org/licenses/LICENSE-2.0 ##
## ##
#############################################################
__docformat__ = "restructuredtext en"
import esys.lsm.doc.Util
from esys.lsm.util import Vec3,BoundingBox
from esys.lsm import LsmMpi, NRotSphere, GravityPrms
__gravTutSection = \
"""
Tutorial 1: A Particle Falling Due To Gravity
==============================================
This tutorial analyses a simple model where a particle falls
due to the influence of gravity. There are no fixed objects,
and no interactions between particles, just a spherical
particle falling in space. Although the example is very simple,
it does illustrate the important basic features of running a
simulation.
The Complete Script
-------------------
The complete script for the simulation is as follows::
from esys.lsm import *
from esys.lsm.util import Vec3, BoundingBox
sim = LsmMpi(numWorkerProcesses=4, mpiDimList=[2,2,1])
sim.initVerletModel(
particleType = "NRotSphere",
gridSpacing = 2.5,
verletDist = 0.5
)
domain = BoundingBox(Vec3(-20,-20,-20), Vec3(20, 20, 20))
sim.setSpatialDomain(domain)
particle = NRotSphere(id=0, posn=Vec3(0,0,0), radius=1.0, mass=1.0)
sim.createParticle(particle)
sim.createInteractionGroup(
GravityPrms(name="earth-gravity", acceleration=Vec3(0,-9.81,0))
)
sim.setTimeStepSize(0.001)
sim.setNumTimeSteps(10000)
sim.run()
Before explaining the above statements, the command line for running
this script is demonstrated.
Executing an LSM Simulation Python Script
-----------------------------------------
If the above script is saved to the file ``GravitySim.py``, the linux/unix
command line for running the script under LAM MPI is::
$ mpiexec -machinefile hosts.txt -np 1 /absolute/path/to/lsm/mpipython GravitySim.py
where the file ``hosts.txt`` contains information about the various MPI
hosts. In its simplest form, the ``hosts.txt`` file can contain just a
single line of text::
localhost
which causes all MPI processes to be invoked on the local machine.
To execute the script, e.g. on an SGI Altix, using SGI's MPI implementation
(MPT) the command line is::
$ mpirun -up 5 -np 1 /absolute/path/to/lsm/mpipython GravitySim.py
In both these cases the initial number of MPI processes is specified
by the ``-np`` option and should always have value ``1``. The python
script is used to specifiy a number of dynamically created MPI processes
and the simulation computations are distributed across these dynamically
created processes. The MPT ``mpirun`` command requires the ``-up`` option
to specify the *MPI universe size*, which is just the number of all
MPI processes.
Analysing the Script
--------------------
Importing Packages and Modules
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
In order to use the LSM python library to run simulations, it must be
*imported* into the script. The first two lines::
from esys.lsm import *
from esys.lsm.util import Vec3, BoundingBox
achieve the import. The first statement imports a multitude
of classes and functions into the current python *namespace*
from the `esys.lsm` *package*.
The second ``import`` statement imports the two specified classes
into the the namespace: `Vec3` and `BoundingBox`. Objects of class
``Vec3`` are 3-element vectors of floating point values (representing
3D points, for example) and objects of class ``BoundingBox``
represent an axis-aligned rectangular-prism/box.
There are a number of subpackages defined within the `esys.lsm`
top-level package. Each subpackage defines classes and functions
which may be imported to provide various functionality:
`esys.lsm.benchmarks`
Defines modules and packages which in turn define simlation scripts
which are used for performance analysis.
`esys.lsm.doc`
Defines documentation-only python modules with scripting tutorials.
`esys.lsm.examples`
Defines sub-packages and modules of example simulation scripts.
`esys.lsm.geometry`
Defines modules for generating initial packings/configurations of
LSM particles and bonds.
`esys.lsm.sim`
Base classes for different types of simulations and helper classes
for running *suites* of simulations.
`esys.lsm.util`
Utility package providing basic common functionality.
`esys.lsm.vis`
Visualisation packages and modules.
Creating and Initialising the Simulation Object
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Once the LSM modules have been imported, the simulation object
is created and initialised::
sim = LsmMpi(numWorkerProcesses=4, mpiDimList=[2,2,1])
sim.initVerletModel(
particleType = "NRotSphere",
gridSpacing = 2.5,
verletDist = 0.5
)
The first statement creates an `LsmMpi` object. ``LsmMpi`` objects
provide the means to define and run LSM simulations. Here, two
arguments are provided to the ``LsmMpi`` *constructor*:
``numWorkerProcesses``
The number of MPI *worker* processes which are
dynamically created.
``mpiDimList``
A 3 element list of integers which specify a regular
axis-aligned grid decomposition of the rectangular domain. Each
domain-cell of the grid is assigned to an MPI process. The individual
MPI processes are then responsible for performing calculations on
particles which lie in their assigned cell.
The second statement, is a call to the `LsmMpi.initVerletModel` *method*
of the ``sim`` object. This method defines the type of discrete-element
particles which are to be used in the simulation and also initialises
data-structures used in the contact detection algorithm. The three arguments
are defined as follows:
``particleType``
A string defining the type of discrete-element particle. In this example,
particles are non-rotational spheres ``"NRotSphere"``.
``gridSpacing``
A regular grid of cubic cells is used to efficiently determine the
neighbouring particles of each particle. This argument defines the
length of the cubic cell sides and needs to be greater than the
maximum particle radius.
``verletDist``
This distance determines the frequency with which neighbour-lists/contacts
are updated. If any particle moves further than this distance during the
course of a simulation, then the neighbour lists (and interactions/contacts)
are updated.
Optimal values for ``gridSpacing`` and ``verletDist`` are simulation
dependent and the parameters must obey the constraint
``gridSpacing > maxRadius + verletDist``, where ``maxRadius`` is
the maximum radius of all particles. Smaller ``verletDist`` values
will lead to smaller neighbour/contact lists and faster force calculations.
However, a small ``verletDist`` value also means more frequent
recalculation of the neighbour lists.
Setting the Spatial Domain
^^^^^^^^^^^^^^^^^^^^^^^^^^
The next step in parameterising the simulation is to specify the spatial
domain over which particles are *tracked*. The LSM allows the specification
of a rectangular box as the bounding domain::
domain = BoundingBox(Vec3(-20,-20,-20), Vec3(20, 20, 20))
sim.setSpatialDomain(domain)
Here, the ``domain`` variable has been set as a `BoundingBox`
object. The ``BoundingBox`` constructor takes two `Vec3` arguments,
a minimum point (lower left back corner) ``Vec3(-20,-20,-20)``
and a maximum point (upper right front corner) ``Vec3(20, 20, 20)``.
This domain specifies a cube with side length ``40`` and centred at
the origin.
The `LsmMpi.setSpatialDomain` method is called to specify the
simulation domain. Equivently, the domain could have been set
in a single statement as follows::
sim.setSpatialDomain(BoundingBox(Vec3(-20,-20,-20), Vec3(20, 20, 20)))
Creating a Spherical Particle
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Now that the internal contact detection object and spatial domain have
been initialised, objects relating to the actual discrete element
physics can be created. First a particle is constructed within the model::
particle = NRotSphere(id=0, posn=Vec3(0,0,0), radius=1.0, mass=1.0)
sim.createParticle(particle)
The ``particle`` variable is assigned to a `NRotSphere` object and
this object is then provided as an argument to the `LsmMpi.createParticle`
method. Inside the ``sim.createParticle`` method, an identical **copy**
of the ``particle`` argument is constructed and added internally to the
``LsmMpi`` simulation ``sim`` object.
Creating the Gravity Interaction Group
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
In order to create simulations of interest, not only must the
initial particle conditions of a simulation be specified but also,
forces imparted on particles also should to be introduced.
Within the LSM scripting environment, these different types of forces
are termed *interaction groups*. Creating an interaction group within
the model specifies how discrete-element particles interact with each
other and also how they interact with other entities within the model.
Gravity is introduced into the model by creating an interaction group
as follows::
sim.createInteractionGroup(
GravityPrms(name="earth-gravity", acceleration=Vec3(0,-9.81,0))
)
The `LsmMpi.createInteractionGroup` method, of the ``sim`` object, is called
with a `GravityPrms` argument. The ``GravityPrms`` argument specifies
that a gravity interaction group is created in the model, and this gravity
group causes all particles in the model to be subjected to a *gravitational*
force with acceleration ``acceleration=Vec3(0,-9.81,0)``. All interaction
groups have an associated `InteractionPrms` subclass, and the constructors of
these ``InteractionPrms`` subclasses always have a ``name`` argument.
This ``name`` argument is used to uniquely identify an interaction group
when manipulating the group using the ``LsmMpi`` interface.
Running the Simulation
^^^^^^^^^^^^^^^^^^^^^^
To execute the time-stepping scheme for integrating the equations
of motion, the time-step size and number of time-steps are
specified before calling the `LsmMpi.run` method of the ``sim``
object::
sim.setTimeStepSize(0.000025)
sim.setNumTimeSteps(600000)
sim.run()
Instead of executing all time-steps via the ``run`` method,
individual steps may be specified in a loop as follows::
sim.setTimeStepSize(0.000025)
maxTime = 600000*sim.getTimeStepSize()
t = 0.0
while (t < maxTime):
sim.runTimeStep()
t += sim.getTimeStepSize()
Here, the `LsmMpi.runTimeStep` method is called within a
``while`` loop to execute individual time-steps. This form
of performing the integration allows the execution of arbitrary
additional code before and after each time-step.
Summary
-------
This simple gravity simulation example illustrates the basic steps
involved in all LSM simulations scripts:
1. Construct and initialise an LSM simulation object (`LsmMpi`).
2. Specify the spatial domain.
3. Create an initial configuration of particles within the model.
4. Specify inter-particle interactions and/or interactions between
particles and the environment.
5. Executing the time integration.
Of course, the purpose of running simulations is to produce data.
In this simple gravity example, neither saving data or visualisation
of particles has been covered. These topics are examined in subsequent
tutorials.
"""
__doc__ = \
esys.lsm.doc.Util.setSectionDoc("GravityTutSection",__gravTutSection) \
+ "\n:summary: A simple gravity simulation.\n"
|