1
/*************************************************************************
2
* Copyright (C) 2006 by Bruno Chareyre *
3
* bruno.chareyre@hmg.inpg.fr *
5
* This program is free software; it is licensed under the terms of the *
6
* GNU General Public License v2 or later. See file LICENSE for details. *
7
*************************************************************************/
11
#include<yade/pkg/common/BoundaryController.hpp>
12
#include<yade/core/Scene.hpp>
13
#include<yade/lib/base/Math.hpp>
15
#include<boost/array.hpp>
21
/*! \brief Controls the stress on the boundaries of a box and compute strain-like and stress-like quantities for the packing. The algorithms used have been developed initialy for simulations reported in [Chareyre2002a] and [Chareyre2005]. They have been ported to Yade in a second step and used in e.g. [Kozicki2008],[Scholtes2009b],[Jerier2010b].
24
class TriaxialStressController : public BoundaryController
28
inline const Vector3r getForce(Scene* rb, Body::id_t id){ return rb->forces.getForce(id); /* needs sync, which is done at the beginning of action */ }
30
//! internal index values for retrieving walls
31
enum {wall_left=0, wall_right, wall_bottom, wall_top, wall_back, wall_front};
32
//! real index values of walls in the Scene
34
//! Stores the value of the translation at the previous time step, stiffness, and normal
35
boost::array<Vector3r,6> previousTranslation;
36
//! The value of stiffness (updated according to stiffnessUpdateInterval)
37
vector<Real> stiffness;
40
//! The values of stresses
43
//! Value of spheres volume (solid volume)
45
//! Value of box volume
60
virtual ~TriaxialStressController();
62
virtual void action();
63
//! Regulate the stress applied on walls with flag wall_XXX_activated = true
64
void controlExternalStress(int wall, Vector3r resultantForce, State* p, Real wall_max_vel);
65
//! Regulate the mean stress by changing spheres size, WARNING : this function assumes that all dynamic bodies in the problem are spheres
66
void controlInternalStress(Real multiplier);
67
//! update the stiffness of boundary-packing interaction (sum of contacts stiffness on the boundary)
68
void updateStiffness();
69
//! Compute stresses on walls as "Vector3r stress[6]", compute meanStress, strain[3] and mean strain
70
void computeStressStrain();
71
//! Compute the mean/max unbalanced force in the assembly (normalized by mean contact force)
72
Real ComputeUnbalancedForce(bool maxUnbalanced=false);
73
///! Getter for stress in python
74
Vector3r getStress(int boundId);
76
YADE_CLASS_BASE_DOC_ATTRS_INIT_CTOR_PY(TriaxialStressController,BoundaryController,
77
"An engine maintaining constant stresses on some boundaries of a parallepipedic packing. See also :yref:`TriaxialCompressionEngine`"
78
"\n\n.. note::\n\t The algorithms used have been developed initialy for simulations reported in [Chareyre2002a]_ and [Chareyre2005]_. They have been ported to Yade in a second step and used in e.g. [Kozicki2008]_,[Scholtes2009b]_,[Jerier2010b]."
80
((unsigned int,stiffnessUpdateInterval,10,,"target strain rate (./s)"))
81
((unsigned int,radiusControlInterval,10,,""))
82
((unsigned int,computeStressStrainInterval,10,,""))
83
((Real,wallDamping,0.25,,"wallDamping coefficient - wallDamping=0 implies a (theoretical) perfect control, wallDamping=1 means no movement"))
84
((Real,thickness,-1,,"thickness of boxes (needed by some functions)"))
85
((int,wall_bottom_id,2,,"id of boundary ; coordinate 1- (default value is ok if aabbWalls are appended BEFORE spheres.)"))
86
((int,wall_top_id,3,,"id of boundary ; coordinate 1+ (default value is ok if aabbWalls are appended BEFORE spheres.)"))
87
((int,wall_left_id,0,,"id of boundary ; coordinate 0- (default value is ok if aabbWalls are appended BEFORE spheres.)"))
88
((int,wall_right_id,1,,"id of boundary ; coordinate 0+ (default value is ok if aabbWalls are appended BEFORE spheres.)"))
89
((int,wall_front_id,5,,"id of boundary ; coordinate 2+ (default value is ok if aabbWalls are appended BEFORE spheres.)"))
90
((int,wall_back_id,4,,"id of boundary ; coordinate 2- (default value is ok if aabbWalls are appended BEFORE spheres.)"))
91
((bool,wall_bottom_activated,true,,"if true, the engine is keeping stress constant on this boundary."))
92
((bool,wall_top_activated,true,,"if true, the engine is keeping stress constant on this boundary."))
93
((bool,wall_left_activated,true,,"if true, the engine is keeping stress constant on this boundary."))
94
((bool,wall_right_activated,true,,"if true, the engine is keeping stress constant on this boundary."))
95
((bool,wall_front_activated,true,,"if true, the engine is keeping stress constant on this boundary."))
96
((bool,wall_back_activated,true,,"if true, the engine is keeping stress constant on this boundary."))
97
((Real,height,0,Attr::readonly,"size of the box (1-axis) |yupdate|"))
98
((Real,width,0,Attr::readonly,"size of the box (0-axis) |yupdate|"))
99
((Real,depth,0,Attr::readonly,"size of the box (2-axis) |yupdate|"))
100
((Real,height0,0,Attr::readonly,"Reference size for strain definition. See :yref:`TriaxialStressController::height`"))
101
((Real,width0,0,Attr::readonly,"Reference size for strain definition. See :yref:`TriaxialStressController::width`"))
102
((Real,depth0,0,Attr::readonly,"Reference size for strain definition. See :yref:`TriaxialStressController::depth`"))
103
((Real,sigma_iso,0,,"prescribed confining stress (see :yref:`TriaxialStressController::isAxisymetric`)"))
104
((Real,sigma1,0,,"prescribed stress on axis 1 (see :yref:`TriaxialStressController::isAxisymetric`)"))
105
((Real,sigma2,0,,"prescribed stress on axis 2 (see :yref:`TriaxialStressController::isAxisymetric`)"))
106
((Real,sigma3,0,,"prescribed stress on axis 3 (see :yref:`TriaxialStressController::isAxisymetric`)"))
107
((bool,isAxisymetric,true,,"if true, sigma_iso is assigned to sigma1, 2 and 3 (applies at each iteration and overrides user-set values of s1,2,3)"))
108
((Real,maxMultiplier,1.001,,"max multiplier of diameters during internal compaction (initial fast increase - :yref:`TriaxialStressController::finalMaxMultiplier` is used in a second stage)"))
109
((Real,finalMaxMultiplier,1.00001,,"max multiplier of diameters during internal compaction (secondary precise adjustment - :yref:`TriaxialStressController::maxMultiplier` is used in the initial stage)"))
110
((Real,max_vel,0.001,,"Maximum allowed walls velocity [m/s]. This value superseeds the one assigned by the stress controller if the later is higher. max_vel can be set to infinity in many cases, but sometimes helps stabilizing packings. Based on this value, different maxima are computed for each axis based on the dimensions of the sample, so that if each boundary moves at its maximum velocity, the strain rate will be isotropic (see e.g. :yref:`TriaxialStressController::max_vel1`)."))
111
((Real,previousStress,0,Attr::readonly,"|yupdate|"))
112
((Real,previousMultiplier,1,Attr::readonly,"|yupdate|"))
113
((bool,internalCompaction,true,,"Switch between 'external' (walls) and 'internal' (growth of particles) compaction."))
114
((Real,meanStress,0,Attr::readonly,"Mean stress in the packing. |yupdate|"))
115
((Real,volumetricStrain,0,Attr::readonly,"Volumetric strain (see :yref:`TriaxialStressController::strain`).|yupdate|"))
116
((Real,externalWork,0,Attr::readonly,"Energy provided by boundaries.|yupdate|"))
118
/* extra initializers */
123
previousTranslation.assign(Vector3r::Zero());
124
for (int i=0; i<6; ++i){normal[i]=stress[i]=force[i]=Vector3r::Zero();stiffness[i]=0;}
125
normal[wall_bottom].y()=1;
126
normal[wall_top].y()=-1;
127
normal[wall_left].x()=1;
128
normal[wall_right].x()=-1;
129
normal[wall_front].z()=-1;
130
normal[wall_back].z()=1;
133
.def_readonly("strain",&TriaxialStressController::strain,"Current strain in a vector (exx,eyy,ezz). The values reflect true (logarithmic) strain.")
134
.def_readonly("porosity",&TriaxialStressController::porosity,"Porosity of the packing.")
135
.def_readonly("boxVolume",&TriaxialStressController::boxVolume,"Total packing volume.")
136
.def_readonly("spheresVolume",&TriaxialStressController::spheresVolume,"Total volume pf spheres.")
137
.def_readonly("max_vel1",&TriaxialStressController::max_vel1,"see :yref:`TriaxialStressController::max_vel` |ycomp|")
138
.def_readonly("max_vel2",&TriaxialStressController::max_vel2,"see :yref:`TriaxialStressController::max_vel` |ycomp|")
139
.def_readonly("max_vel3",&TriaxialStressController::max_vel3,"see :yref:`TriaxialStressController::max_vel` |ycomp|")
140
.def("stress",&TriaxialStressController::getStress,(python::arg("id")),"Return the mean stress vector acting on boundary 'id', with 'id' between 0 and 5.")
144
REGISTER_SERIALIZABLE(TriaxialStressController);