File: simple-scene.py

package info (click to toggle)
yade 2025.2.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 33,308 kB
  • sloc: cpp: 93,298; python: 50,409; sh: 577; makefile: 162
file content (92 lines) | stat: -rw-r--r-- 4,549 bytes parent folder | download | duplicates (2)
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
# -*- encoding=utf-8 -*-

## Omega is the super-class that orchestrates the whole program.
## It holds the entire simulation (MetaBody), takes care of loading/saving,
## starting/stopping the simulation, loads plugins and more.

o = Omega()  # for advaned folks: this creates default MetaBody as well

## Engines are called consecutively at each iteration. Their order matters.
##
## Some of them work by themselves (GlobalEngine, PartialEngine - the difference of these two is unimportant).
##
## MetaEngines act as dispatchers and based on the type of objects they operate on, different EngineUnits are called.
o.engines = [
        ## Resets forces and momenta the act on bodies
        ForceResetter(),
        ## associates bounding volume - in this case, AxisAlignedBoundingBox (Aabb) - to each body.
        ## Using bounding boxes created, find possible body collisions.
        ## These possible collisions are inserted in O.interactions container (Scene::interactions in c++).
        InsertionSortCollider([
                Bo1_Sphere_Aabb(),
                Bo1_Box_Aabb(),
        ]),
        InteractionLoop(
                ## Decide whether the potential collisions are real; if so, create geometry information about each potential collision.
                ## Here, the decision about which EngineUnit to use depends on types of _both_ bodies.
                ## Note that there is no EngineUnit for box-box collision. They are not implemented.
                [Ig2_Sphere_Sphere_ScGeom(), Ig2_Box_Sphere_ScGeom()],
                ## Create physical information about the interaction.
                ## This may consist in deriving contact rigidity from elastic moduli of each body, for example.
                ## The purpose is that the contact may be "solved" without reference to related bodies,
                ## only with the information contained in contact geometry and physics.
                [Ip2_FrictMat_FrictMat_FrictPhys()],
                ## "Solver" of the contact, also called (consitutive) law.
                ## Based on the information in interaction physics and geometry, it applies corresponding forces on bodies in interaction.
                [Law2_ScGeom_FrictPhys_CundallStrack()]
        ),
        ## Apply gravity: all bodies will have gravity applied on them.
        ## Note the engine parameter 'gravity', a vector that gives the acceleration.
        ## Forces acting on bodies are damped to artificially increase energy dissipation in simulation.
        ## (In this model, the restitution coefficient of interaction is 1, which is not realistic.)
        ## This MetaEngine acts on all PhysicalActions and selects the right EngineUnit base on type of the PhysicalAction.
        #
        # note that following 4 engines (till the end) can be replaced by an optimized monolithic version:
        NewtonIntegrator(damping=0.1, gravity=[0, 0, -9.81])
]

## The yade.utils module contains some handy functions, like yade.utils.box and yade.utils.sphere.
## After this import, they will be accessible as utils.box and utils.sphere.
### UPDATE: utils is loaded automatically, no longer need to import
#from yade import utils

## create bodies in the simulation: one box in the origin and one floating above it.
##
## The box:
## * extents: half-size of the box. [.5,.5,.5] is unit cube
## * center: position of the center of the box
## * dynamic: it is not dynamic, i.e. will not move during simulation, even if forces are applied to it

o.bodies.append(box(center=[0, 0, 0], extents=[.5, .5, .5], color=[0, 0, 1], fixed=True))

## The sphere
##
## * First two arguments are radius and center, respectively. They are used as "positional arguments" here:
## python will deduce based on where they are what they mean.
##
## It could also be written without using sphere - see gui/py/utils.py for the code of the sphere function
o.bodies.append(sphere([0, 0, 2], 1, color=[0, 1, 0]))

## Estimate timestep from p-wave speed and multiply it by safety factor of .2
o.dt = .01 * PWaveTimeStep()

## Save the scene to file, so that it can be loaded later. Supported extension are: .xml, .xml.gz, .xml.bz2.
o.save('/tmp/a.xml.bz2')
#o.run(100000); o.wait(); print o.iter/o.realtime,'iterations/sec'


def onBodySelect(id):
	print("Selected:", id)
	highlightNone()
	for i in O.interactions.withBody(id):
		O.bodies[i.id2 if i.id1 == id else i.id1].shape.highlight = True
		print(i.id1, i.id2, i.phys, i.geom)


try:
	from yade import qt
	qt.View()
	qt.Controller()
except ImportError:
	pass
O.run(20000)