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
|
#pragma once
#include<lib/serialization/Serializable.hpp>
#include<lib/base/Math.hpp>
class Cell: public Serializable{
public:
const Vector3r& getSize() const { return _size; }
void setSize(const Vector3r& s){for (int k=0;k<3;k++) hSize.col(k)*=s[k]/hSize.col(k).norm(); refHSize=hSize; postLoad(*this);}
Vector3r getSize_copy() const { return _size; }
const Vector3r& getCos() const {return _cos;}
const Matrix3r& getShearTrsf() const { return _shearTrsf; }
const Matrix3r& getUnshearTrsf() const {return _unshearTrsf;}
const double* getGlShearTrsfMatrix() const { return _glShearTrsfMatrix; }
bool hasShear() const {return _hasShear; }
private:
Matrix3r _invTrsf;
Matrix3r _trsfInc;
Matrix3r _vGradTimesPrevH;
Vector3r _size, _cos;
Vector3r _refSize;
bool _hasShear;
Matrix3r _shearTrsf, _unshearTrsf;
double _glShearTrsfMatrix[16];
void fillGlShearTrsfMatrix(double m[16]);
public:
DECLARE_LOGGER;
void integrateAndUpdate(Real dt);
Vector3r wrapShearedPt(const Vector3r& pt) const { return shearPt(wrapPt(unshearPt(pt))); }
Vector3r wrapShearedPt(const Vector3r& pt, Vector3i& period) const { return shearPt(wrapPt(unshearPt(pt),period)); }
Vector3r unshearPt(const Vector3r& pt) const { return _unshearTrsf*pt; }
Vector3r shearPt(const Vector3r& pt) const { return _shearTrsf*pt; }
Vector3r wrapPt(const Vector3r& pt) const {
Vector3r ret; for(int i=0;i<3;i++) ret[i]=wrapNum(pt[i],_size[i]); return ret;}
Vector3r wrapPt(const Vector3r& pt, Vector3i& period) const {
Vector3r ret; for(int i=0; i<3; i++){ ret[i]=wrapNum(pt[i],_size[i],period[i]); } return ret;}
static Real wrapNum(const Real& x, const Real& sz) {
Real norm=x/sz; return (norm-floor(norm))*sz;}
static Real wrapNum(const Real& x, const Real& sz, int& period) {
Real norm=x/sz; period=(int)floor(norm); return (norm-period)*sz;}
Vector3r intrShiftPos(const Vector3i& cellDist) const { return hSize*cellDist.cast<Real>(); }
Vector3r intrShiftVel(const Vector3i& cellDist) const { return _vGradTimesPrevH*cellDist.cast<Real>(); }
Vector3r bodyFluctuationVel(const Vector3r& pos, const Vector3r& vel, const Matrix3r& prevVelGrad) const { return (vel-prevVelGrad*pos); }
Matrix3r getHSize() const { return hSize; }
void setHSize(const Matrix3r& m){ hSize=refHSize=m; postLoad(*this); }
Matrix3r getTrsf() const { return trsf; }
void setTrsf(const Matrix3r& m){ trsf=m; postLoad(*this); }
Matrix3r getVelGrad() const { return velGrad; }
void setVelGrad(const Matrix3r& m){ nextVelGrad=m; velGradChanged=true;}
Matrix3r getHSize0() const { return _invTrsf*hSize; }
Vector3r getRefSize() const { Matrix3r h=getHSize0(); return Vector3r(h.col(0).norm(),h.col(1).norm(),h.col(2).norm()); }
void setRefSize(const Vector3r& s){
Matrix3r hSizeEigen3=hSize.diagonal().asDiagonal();
if(s==_size && hSize==hSizeEigen3){ LOG_WARN("Setting O.cell.refSize=O.cell.size is useless, O.trsf=Matrix3.Identity is enough now."); }
else {LOG_WARN("Setting Cell.refSize is deprecated, use Cell.setBox(...) instead.");}
setBox(s); postLoad(*this);
}
void setBox(const Vector3r& size){ setHSize(size.asDiagonal()); trsf=Matrix3r::Identity(); postLoad(*this); }
void setBox3(const Real& s0, const Real& s1, const Real& s2){ setBox(Vector3r(s0,s1,s2)); }
Real getVolume() const {return hSize.determinant();}
void postLoad(Cell&){ integrateAndUpdate(0); }
Vector3r wrapShearedPt_py(const Vector3r& pt) const { return wrapShearedPt(pt);}
Vector3r wrapPt_py(const Vector3r& pt) const { return wrapPt(pt);}
Matrix3r getDefGrad() { return trsf; }
Matrix3r getSmallStrain() { return .5*(trsf+trsf.transpose()) - Matrix3r::Identity(); }
Matrix3r getRCauchyGreenDef() { return trsf.transpose()*trsf; }
Matrix3r getLCauchyGreenDef() { return trsf*trsf.transpose(); }
Matrix3r getLagrangianStrain() { return .5*(getRCauchyGreenDef()-Matrix3r::Identity()); }
Matrix3r getEulerianAlmansiStrain() { return .5*(Matrix3r::Identity()-getLCauchyGreenDef().inverse()); }
void computePolarDecOfDefGrad(Matrix3r& R, Matrix3r& U) { Matrix_computeUnitaryPositive(trsf,&R,&U); }
boost::python::tuple getPolarDecOfDefGrad(){ Matrix3r R,U; computePolarDecOfDefGrad(R,U); return boost::python::make_tuple(R,U); }
Matrix3r getRotation() { Matrix3r R,U; computePolarDecOfDefGrad(R,U); return R; }
Matrix3r getLeftStretch() { Matrix3r R,U; computePolarDecOfDefGrad(R,U); return U; }
Matrix3r getRightStretch() { Matrix3r R,U; computePolarDecOfDefGrad(R,U); return trsf*R.transpose(); }
Vector3r getSpin() {Matrix3r R=.5*(velGrad-velGrad.transpose()); return Vector3r(-R(1,2),R(0,2),-R(0,1));}
enum { HOMO_NONE=0, HOMO_POS=1, HOMO_VEL=2, HOMO_VEL_2ND=3 };
YADE_CLASS_BASE_DOC_ATTRS_CTOR_PY(Cell,Serializable,"Parameters of periodic boundary conditions. Only applies if O.isPeriodic==True.",
((Matrix3r,trsf,Matrix3r::Identity(),,"[overridden]"))
((Matrix3r,refHSize,Matrix3r::Identity(),,"Reference cell configuration, only used with :yref:`OpenGLRenderer.dispScale`. Updated automatically when :yref:`hSize<Cell.hSize>` or :yref:`trsf<Cell.trsf>` is assigned directly; also modified by :yref:`yade.utils.setRefSe3` (called e.g. by the ``Reference`` button in the UI)."))
((Matrix3r,hSize,Matrix3r::Identity(),,"[overridden below]"))
((Matrix3r,prevHSize,Matrix3r::Identity(),Attr::readonly,":yref:`hSize<Cell.hSize>` from the previous step, used in the definition of relative velocity across periods."))
((Matrix3r,velGrad,Matrix3r::Zero(),,"[overridden below]"))
((Matrix3r,nextVelGrad,Matrix3r::Zero(),Attr::readonly,"see :yref:`Cell.velGrad`."))
((Matrix3r,prevVelGrad,Matrix3r::Zero(),Attr::readonly,"Velocity gradient in the previous step."))
((int,homoDeform,2,,"If >0, deform (:yref:`velGrad<Cell.velGrad>`) the cell homothetically by adjusting positions and velocities of bodies. The velocity change is obtained by deriving the expression v=∇v.x, where ∇v is the macroscopic velocity gradient, giving in an incremental form: Δv=Δ ∇v x + ∇v Δx. As a result, velocities are modified as soon as ``velGrad`` changes, according to the first term: Δv(t)=Δ ∇v x(t), while the 2nd term reflects a convective term: Δv'= ∇v v(t-dt/2). The second term is neglected if homoDeform=1. All terms are included if homoDeform=2 (default)"))
((bool,velGradChanged,false,Attr::readonly,"true when velGrad has been changed manually (see also :yref:`Cell.nextVelGrad`)")),
_invTrsf=Matrix3r::Identity(); integrateAndUpdate(0),
.add_property("hSize",&Cell::getHSize,&Cell::setHSize,"Base cell vectors (columns of the matrix), updated at every step from :yref:`velGrad<Cell.velGrad>` (:yref:`trsf<Cell.trsf>` accumulates applied :yref:`velGrad<Cell.velGrad>` transformations). Setting *hSize* during a simulation is not supported by most contact laws, it is only meant to be used at iteration 0 before any interactions have been created.")
.add_property("size",&Cell::getSize_copy,&Cell::setSize,"Current size of the cell, i.e. lengths of the 3 cell lateral vectors contained in :yref:`Cell.hSize` columns. Updated automatically at every step. Assigning a value will change the lengths of base vectors (see :yref:`Cell.hSize`), keeping their orientations unchanged.")
.add_property("refSize",&Cell::getRefSize,&Cell::setRefSize,"Reference size of the cell (lengths of initial cell vectors, i.e. column norms of :yref:`hSize<Cell.hSize>`).\n\n.. note::\n\t Modifying this value is deprecated, use :yref:`setBox<Cell.setBox>` instead.")
.add_property("trsf",&Cell::getTrsf,&Cell::setTrsf,"Current transformation matrix of the cell, obtained from time integration of :yref:`Cell.velGrad`.")
.add_property("velGrad",&Cell::getVelGrad,&Cell::setVelGrad,"Velocity gradient of the transformation; used in :yref:`NewtonIntegrator`. Values of :yref:`velGrad<Cell.velGrad>` accumulate in :yref:`trsf<Cell.trsf>` at every step.\n\n NOTE: changing velGrad at the beginning of a simulation loop would lead to inacurate integration for one step, as it should normaly be changed after the contact laws (but before Newton). To avoid this problem, assignment is deferred automatically. The target value typed in terminal is actually stored in :yref:`Cell.nextVelGrad` and will be applied right in time by Newton integrator. \n\n.. note::\n\t Assigning individual components of velGrad is not possible (it will not return any error but it will have no effect). Instead, you can assign to :yref:`Cell.nextVelGrad`, as in O.cell.nextVelGrad[1,2]=1.")
.def_readonly("size",&Cell::getSize_copy,"Current size of the cell, i.e. lengths of the 3 cell lateral vectors contained in :yref:`Cell.hSize` columns. Updated automatically at every step.")
.add_property("volume",&Cell::getVolume,"Current volume of the cell.")
.def("setBox",&Cell::setBox,"Set :yref:`Cell` shape to be rectangular, with dimensions along axes specified by given argument. Shorthand for assigning diagonal matrix with respective entries to :yref:`hSize<Cell.hSize>`.")
.def("setBox",&Cell::setBox3,"Set :yref:`Cell` shape to be rectangular, with dimensions along $x$, $y$, $z$ specified by arguments. Shorthand for assigning diagonal matrix with the respective entries to :yref:`hSize<Cell.hSize>`.")
.def("wrap",&Cell::wrapShearedPt_py,"Transform an arbitrary point into a point in the reference cell")
.def("unshearPt",&Cell::unshearPt,"Apply inverse shear on the point (removes skew+rot of the cell)")
.def("shearPt",&Cell::shearPt,"Apply shear (cell skew+rot) on the point")
.def("wrapPt",&Cell::wrapPt_py,"Wrap point inside the reference cell, assuming the cell has no skew+rot.")
.def("getDefGrad",&Cell::getDefGrad,"Returns deformation gradient tensor $\\mat{F}$ of the cell deformation (http://en.wikipedia.org/wiki/Finite_strain_theory)")
.def("getSmallStrain",&Cell::getSmallStrain,"Returns small strain tensor $\\mat{\\varepsilon}=\\frac{1}{2}(\\mat{F}+\\mat{F}^T)-\\mat{I}$ of the cell (http://en.wikipedia.org/wiki/Finite_strain_theory)")
.def("getRCauchyGreenDef",&Cell::getRCauchyGreenDef,"Returns right Cauchy-Green deformation tensor $\\mat{C}=\\mat{F}^T\\mat{F}$ of the cell (http://en.wikipedia.org/wiki/Finite_strain_theory)")
.def("getLCauchyGreenDef",&Cell::getLCauchyGreenDef,"Returns left Cauchy-Green deformation tensor $\\mat{b}=\\mat{F}\\mat{F}^T$ of the cell (http://en.wikipedia.org/wiki/Finite_strain_theory)")
.def("getLagrangianStrain",&Cell::getLagrangianStrain,"Returns Lagrangian strain tensor $\\mat{E}=\\frac{1}{2}(\\mat{C}-\\mat{I})=\\frac{1}{2}(\\mat{F}^T\\mat{F}-\\mat{I})=\\frac{1}{2}(\\mat{U}^2-\\mat{I})$ of the cell (http://en.wikipedia.org/wiki/Finite_strain_theory)")
.def("getEulerianAlmansiStrain",&Cell::getEulerianAlmansiStrain,"Returns Eulerian-Almansi strain tensor $\\mat{e}=\\frac{1}{2}(\\mat{I}-\\mat{b}^{-1})=\\frac{1}{2}(\\mat{I}-(\\mat{F}\\mat{F}^T)^{-1})$ of the cell (http://en.wikipedia.org/wiki/Finite_strain_theory)")
.def("getPolarDecOfDefGrad",&Cell::getPolarDecOfDefGrad,"Returns orthogonal matrix $\\mat{R}$ and symmetric positive semi-definite matrix $\\mat{U}$ as polar decomposition of deformation gradient $\\mat{F}$ of the cell ( $\\mat{F}=\\mat{RU}$ )")
.def("getRotation",&Cell::getRotation,"Returns rotation of the cell (orthogonal matrix $\\mat{R}$ from polar decomposition $\\mat{F}=\\mat{RU}$ )")
.def("getLeftStretch",&Cell::getLeftStretch,"Returns left (spatial) stretch tensor of the cell (matrix $\\mat{U}$ from polar decomposition $\\mat{F}=\\mat{RU}$ )")
.def("getRightStretch",&Cell::getRightStretch,"Returns right (material) stretch tensor of the cell (matrix $\\mat{V}$ from polar decomposition $\\mat{F}=\\mat{RU}=\\mat{VR}\\ \\rightarrow\\ \\mat{V}=\\mat{FR}^T$ )")
.def("getSpin",&Cell::getSpin,"Returns the spin defined by the skew symmetric part of :yref:`velGrad<Cell.velGrad>`")
.def_readonly("shearTrsf",&Cell::_shearTrsf,"Current skew+rot transformation (no resize)")
.def_readonly("unshearTrsf",&Cell::_unshearTrsf,"Inverse of the current skew+rot transformation (no resize)")
.add_property("hSize0",&Cell::getHSize0,"Value of untransformed hSize, with respect to current :yref:`trsf<Cell::trsf>` (computed as :yref:`trsf<Cell::trsf>` ⁻¹ × :yref:`hSize<Cell::hSize>`.")
);
};
REGISTER_SERIALIZABLE(Cell);
|