Available servo-controllers
A servo-controller is a function evaluated at every time step that rewrites the
values of the controls it owns. It is declared in drivingSystem.txt with the
Servo keyword (see Driving the boundaries), and it is what makes
stress-controlled and time-dependent loadings possible: a stress cannot
be imposed directly, because the force to apply depends on the current area of
the wall, which changes as the sample deforms.
Warning
Only one servo can be active at a time. The servo function is stored as a
single callback, so a second Servo entry silently replaces the first.
The tritri family
These servos drive a cuboidal cell made of six walls, and they all begin with the same six body numbers:
Servo tritri<Something> <idXmin> <idXmax> <idYmin> <idYmax> <idZmin> <idZmax>
<parameters...>
They install twelve controls at once, in a fixed pattern: the walls at the minimum positions are velocity-driven, and the walls at the maximum positions are force-driven.
Wall |
Control installed |
Role |
|---|---|---|
|
|
Held fixed (velocity imposed at zero), they define the origin. |
|
|
Driven by a force recomputed at every step from the target stress. |
At each step, the servo measures the current inner dimensions of the cell from the wall positions, corrected by their Minkowski radii:
and likewise for \(d_Y\) and \(d_Z\). The areas of the faces follow, \(S_X = d_Y d_Z\), \(S_Y = d_X d_Z\), \(S_Z = d_X d_Y\), and the force applied to a wall is the target stress times the corresponding area.
Note
Because the Minkowski radii are subtracted, the dimensions used are those of the free volume available to the grains, not the distance between the wall centres.
tritriIsostaticCompression (double) pressure
Isotropic compression. The same pressure is applied on the three max walls,
the three min walls staying fixed:
Servo tritriIsostaticCompression 0 1 2 3 4 5
1000
This is the standard way of preparing a dense sample: compress isotropically until the kinetic energy has dropped, then use the resulting conf-file as the initial state of the real test.
tritriBiaxialCompression (double) pressure (double) velocity
Compression along \(y\) at an imposed velocity, with a confining pressure kept constant on the lateral directions \(x\) and \(z\).
The control of the Ymax wall, installed as a force by the common pattern, is
converted back into a velocity control set to \(-v\), while the servo keeps
recomputing the lateral forces:
Servo tritriBiaxialCompression 0 1 2 3 4 5
1000 0.01
tritriCustom (int) type (double) value … (twelve values)
The general form: each of the six walls is given its own type and value, in the
order Xmin, Xmax, Ymin, Ymax, Zmin, Zmax.
|
Meaning of |
|---|---|
|
Imposed velocity of the wall. |
|
Imposed stress, converted to a force with the current wall area at every step. |
Servo tritriCustom 0 1 2 3 4 5
0 0.0
1 1000.0
0 0.0
0 -0.01
0 0.0
1 1000.0
This example holds the three min walls fixed, confines \(x\) and
\(z\) at 1000 Pa, and moves the top wall down at 0.01 m/s, which reproduces
tritriBiaxialCompression and shows how to depart from it.
Note
The values of the max walls are applied with a reversed sign, so that a
positive stress always means compression whatever the wall.
tritriLodeAngle (double) pressure (double) LodeAngle (double) sigRate
A stress path at constant Lode angle, used to explore the deviatoric plane
rather than a single triaxial path. Starting from an isotropic state at
pressure, the stress increment grows linearly in time,
\(\Delta\sigma = \dot{\sigma} t\), and is distributed over the three
directions as
with
where \(\theta_L\) is the Lode angle, in degrees, restricted to \([0°, 60°]\).
Warning
This servo has not been fully tested. It also assumes that the computation starts at \(t = 0\), since \(\Delta\sigma\) is computed from the absolute time: restarting from a conf-file at \(t \neq 0\) would resume with an already non-zero stress increment.
Shakers
Shakers impose an oscillating motion on a single body, along a given direction.
They install three velocity controls (_x_Vel_, _y_Vel_, _z_Vel_) on
that body and rewrite them at every step. The direction is normalised
automatically, so it does not need to be a unit vector.
Note
What is imposed is the velocity, taken as the exact derivative of the intended motion. The body therefore oscillates about the position it had when the shaking started, with amplitude \(A\), rather than about a position given in the file.
shaker (int) body (vec3r) dir (double) A (double) freq
Sinusoidal oscillation of amplitude \(A\) and frequency \(f\):
Servo shaker 0 0 1 0 0.001 50
triangle_shaker (int) body (vec3r) dir (double) A (double) freq
Same parameters, but the velocity is a square wave, so the displacement is a triangular wave: the body moves at the constant speed \(4Af\) and reverses twice per period. The acceleration is zero except at the reversals, which avoids the continuously varying inertial forcing of a sine.
sawtooth_shaker (int) body (vec3r) dir (double) A (double) freq (double) t_ini
triangle_shaker with a settable phase origin t_ini, so that the
oscillation can be made to start at a chosen time rather than at \(t = 0\).
This is what makes it usable after a deposition stage.
Ramps
ramp (string) type (int) body (double) valueBegin (double) valueEnd (double) tBegin (double) tEnd
Drives a single control, of any of the types listed in Driving the boundaries, along a linear ramp:
# push harder and harder between t = 0.1 s and t = 0.6 s
Servo ramp _y_For_ 3 0.0 -5000.0 0.1 0.6
This is the way to avoid the shock of a load applied abruptly at the first step.
Tip
A ramp on a material parameter rather than on a boundary is a different
mechanism: the Tempo keyword of the conf-file, described in
Format of configuration files (conf-file), which can ramp a friction coefficient or the numerical
damping over time.