G+Smo  24.08.0
Geometry + Simulation Modules
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
gsVisitorMixedNonLinearElasticity.h
Go to the documentation of this file.
1 
16 #pragma once
17 
19 #include <gsElasticity/gsBasePde.h>
20 
22 #include <gsCore/gsFuncData.h>
23 
24 namespace gismo
25 {
26 
27 template <class T>
28 class gsVisitorMixedNonLinearElasticity
29 {
30 public:
31  gsVisitorMixedNonLinearElasticity(const gsPde<T> & pde_, const gsMultiPatch<T> & displacement_,
32  const gsMultiPatch<T> & pressure_)
33  : pde_ptr(static_cast<const gsBasePde<T>*>(&pde_)),
34  displacement(displacement_),
35  pressure(pressure_){}
36 
37  void initialize(const gsBasisRefs<T> & basisRefs,
38  const index_t patchIndex,
39  const gsOptionList & options,
40  gsQuadRule<T> & rule)
41  {
42  // parametric dimension of the first displacement component
43  dim = basisRefs.front().dim();
44  // a quadrature rule is defined by the basis for the first velocity component.
45  // the same rule is used for the presure
46  rule = gsQuadrature::get(basisRefs.front(), options);
47  // saving necessary info
48  patch = patchIndex;
49  T YM = options.getReal("YoungsModulus");
50  T PR = options.getReal("PoissonsRatio");
51  lambda_inv = ( 1. + PR ) * ( 1. - 2. * PR ) / YM / PR ;
52  mu = YM / ( 2. * ( 1. + PR ) );
53  forceScaling = options.getReal("ForceScaling");
54  I = gsMatrix<T>::Identity(dim,dim);
55  // resize containers for global indices
56  globalIndices.resize(dim+1);
57  blockNumbers.resize(dim+1);
58  }
59 
60  inline void evaluate(const gsBasisRefs<T> & basisRefs,
61  const gsGeometry<T> & geo,
62  const gsMatrix<T> & quNodes)
63  {
64  // store quadrature points of the element for geometry evaluation
65  md.points = quNodes;
66  // NEED_VALUE to get points in the physical domain for evaluation of the RHS
67  // NEED_MEASURE to get the Jacobian determinant values for integration
68  // NEED_GRAD_TRANSFORM to get the Jacobian matrix to transform gradient from the parametric to physical domain
70  // Compute image of the quadrature points plus gradient, jacobian and other necessary data
71  geo.computeMap(md);
72  // find local indices of the displacement and pressure basis functions active on the element
73  basisRefs.front().active_into(quNodes.col(0),localIndicesDisp);
74  N_D = localIndicesDisp.rows();
75  basisRefs.back().active_into(quNodes.col(0), localIndicesPres);
76  N_P = localIndicesPres.rows();
77  // Evaluate displacement basis functions and their derivatives on the element
78  basisRefs.front().evalAllDers_into(quNodes,1,basisValuesDisp);
79  // Evaluate pressure basis functions on the element
80  basisRefs.back().eval_into(quNodes,basisValuesPres);
81  // Evaluate right-hand side at the image of the quadrature points
82  pde_ptr->rhs()->eval_into(md.values[0],forceValues);
83  // store quadrature points of the element for displacement evaluation
84  mdDisplacement.points = quNodes;
85  // NEED_DERIV to compute deformation gradient
86  mdDisplacement.flags = NEED_DERIV;
87  // evaluate displacement gradient
88  displacement.patch(patch).computeMap(mdDisplacement);
89  // evaluate pressure; we use eval_into instead of another gsMapData object
90  // because it easier for simple value evaluation
91  pressure.patch(patch).eval_into(quNodes,pressureValues);
92  }
93 
94  inline void assemble(gsDomainIterator<T> & element,
95  const gsVector<T> & quWeights)
96  {
97  // Initialize local matrix/rhs // A | B^T
98  localMat.setZero(dim*N_D + N_P, dim*N_D + N_P); // --|-- matrix structure
99  localRhs.setZero(dim*N_D + N_P,1); // B | C
100  // Loop over the quadrature nodes
101  for (index_t q = 0; q < quWeights.rows(); ++q)
102  {
103  // Multiply quadrature weight by the geometry measure
104  const T weight = quWeights[q] * md.measure(q);
105  // Compute physical gradients of basis functions at q as a dim x numActiveFunction matrix
106  transformGradients(md,q,basisValuesDisp[1],physGradDisp);
107  // physical jacobian of displacemnt du/dx = du/dxi * dxi/dx
108  physDispJac = mdDisplacement.jacobian(q)*(md.jacobian(q).cramerInverse());
109  // deformation gradient F = I + du/dx
110  F = I + physDispJac;
111  // deformation jacobian J = det(F)
112  T J = F.determinant();
113  // Right Cauchy Green strain, C = F'*F
114  RCG = F.transpose() * F;
115  // logarithmic neo-Hooke
116  GISMO_ENSURE(J>0,"Invalid configuration: J < 0");
117  RCGinv = RCG.cramerInverse();
118  // Second Piola-Kirchhoff stress tensor
119  S = (pressureValues.at(q)-mu)*RCGinv + mu*I;
120  // elasticity tensor
121  symmetricIdentityTensor<T>(C,RCGinv);
122  C *= mu-pressureValues.at(q);
123  // Matrix A and reisdual: loop over displacement basis functions
124  for (index_t i = 0; i < N_D; i++)
125  {
126  setB<T>(B_i,F,physGradDisp.col(i));
127  materialTangentTemp = B_i.transpose() * C;
128  // Geometric tangent K_tg_geo = gradB_i^T * S * gradB_j;
129  geometricTangentTemp = S * physGradDisp.col(i);
130  // A-matrix
131  for (index_t j = 0; j < N_D; j++)
132  {
133  setB<T>(B_j,F,physGradDisp.col(j));
134  materialTangent = materialTangentTemp * B_j;
135  T geometricTangent = geometricTangentTemp.transpose() * physGradDisp.col(j);
136  // K_tg = K_tg_mat + I*K_tg_geo;
137  for (short_t d = 0; d < dim; ++d)
138  materialTangent(d,d) += geometricTangent;
139 
140  for (short_t di = 0; di < dim; ++di)
141  for (short_t dj = 0; dj < dim; ++dj)
142  localMat(di*N_D+i, dj*N_D+j) += weight * materialTangent(di,dj);
143  }
144 
145  // Second Piola-Kirchhoff stress tensor as vector
146  voigtStress<T>(Svec,S);
147  // rhs = -r = force - B*Svec,
148  localResidual = B_i.transpose() * Svec;
149  for (short_t d = 0; d < dim; d++)
150  localRhs(d*N_D+i) -= weight * localResidual(d);
151  }
152  // B-matrix
153  divV = F.cramerInverse().transpose() * physGradDisp;
154  for (short_t d = 0; d < dim; ++d)
155  {
156  block = weight*basisValuesPres.col(q)*divV.row(d);
157  localMat.block(dim*N_D,d*N_D,N_P,N_D) += block.block(0,0,N_P,N_D);
158  localMat.block(d*N_D,dim*N_D,N_D,N_P) += block.transpose().block(0,0,N_D,N_P);
159  }
160  // C-matrix
161  if (abs(lambda_inv) > 0)
162  localMat.block(dim*N_D,dim*N_D,N_P,N_P) -=
163  (weight*lambda_inv*basisValuesPres.col(q)*basisValuesPres.col(q).transpose()).block(0,0,N_P,N_P);
164  // rhs: constraint residual
165  localRhs.middleRows(dim*N_D,N_P) += weight*basisValuesPres.col(q)*(lambda_inv*pressureValues.at(q)-log(J));
166  // rhs: force
167  for (short_t d = 0; d < dim; ++d)
168  localRhs.middleRows(d*N_D,N_D).noalias() += weight * forceScaling * forceValues(d,q) * basisValuesDisp[0].col(q) ;
169  }
170  }
171 
172  inline void localToGlobal(const int patchIndex,
173  const std::vector<gsMatrix<T> > & eliminatedDofs,
174  gsSparseSystem<T> & system)
175  {
176  // computes global indices for displacement components
177  for (short_t d = 0; d < dim; ++d)
178  {
179  system.mapColIndices(localIndicesDisp,patchIndex,globalIndices[d],d);
180  blockNumbers.at(d) = d;
181  }
182  // computes global indices for pressure
183  system.mapColIndices(localIndicesPres, patchIndex, globalIndices[dim], dim);
184  blockNumbers.at(dim) = dim;
185  // push to global system
186  system.pushToRhs(localRhs,globalIndices,blockNumbers);
187  system.pushToMatrix(localMat,globalIndices,eliminatedDofs,blockNumbers,blockNumbers);
188  }
189 
190 protected:
191  // problem info
192  short_t dim;
193  const gsBasePde<T> * pde_ptr;
194  index_t patch; // current patch
195  // Lame coefficients and force scaling factor
196  T lambda_inv, mu, forceScaling;
197  // geometry mapping
198  gsMapData<T> md;
199  // local components of the global linear system
200  gsMatrix<T> localMat;
201  gsMatrix<T> localRhs;
202  // local indices (at the current patch) of basis functions active at the current element
203  gsMatrix<index_t> localIndicesDisp;
204  gsMatrix<index_t> localIndicesPres;
205  // number of displacement and pressure basis functions active at the current element
206  index_t N_D, N_P;
207  // values and derivatives of displacement basis functions at quadrature points at the current element
208  // values are stored as a N_D x numQuadPoints matrix; not sure about derivatives, must be smth like N_D*dim x numQuadPoints
209  std::vector<gsMatrix<T> > basisValuesDisp;
210  // values of pressure basis functions active at the current element;
211  // stores as a N_P x numQuadPoints matrix
212  gsMatrix<T> basisValuesPres;
213  // RHS values at quadrature points at the current element; stored as a dim x numQuadPoints matrix
214  gsMatrix<T> forceValues;
215  // current displacement field
216  const gsMultiPatch<T> & displacement;
217  // evaluation data of the current displacement field
218  gsMapData<T> mdDisplacement;
219  // current pressure field
220  const gsMultiPatch<T> & pressure;
221  // evaluation data of the current pressure field stored as a 1 x numQuadPoints matrix
222  gsMatrix<T> pressureValues;
223 
224  // all temporary matrices defined here for efficiency
225  gsMatrix<T> C, Ctemp, physGradDisp, physDispJac, F, RCG, E, S, RCGinv, B_i, materialTangentTemp, B_j, materialTangent, divV, block, I;
226  gsVector<T> geometricTangentTemp, Svec, localResidual;
227  // containers for global indices
228  std::vector< gsMatrix<index_t> > globalIndices;
229  gsVector<index_t> blockNumbers;
230 };
231 
232 } // namespace gismo
Gradient of the object.
Definition: gsForwardDeclarations.h:73
#define short_t
Definition: gsConfig.h:35
#define index_t
Definition: gsConfig.h:32
#define GISMO_ENSURE(cond, message)
Definition: gsDebug.h:102
static gsQuadRule< T > get(const gsBasis< T > &basis, const gsOptionList &options, short_t fixDir=-1)
Constructs a quadrature rule based on input options.
Definition: gsQuadrature.h:48
Creates a variety of quadrature rules.
IMHO, a useless class, but it is necessary to use the gsAssembler class. Contains proper information ...
The density of the measure pull back.
Definition: gsForwardDeclarations.h:76
Tensor operations for elasticity.
Value of the object.
Definition: gsForwardDeclarations.h:72
EIGEN_STRONG_INLINE abs_expr< E > abs(const E &u)
Absolute value.
Definition: gsExpressions.h:4486
Gradient transformation matrix.
Definition: gsForwardDeclarations.h:77
This object is a cache for computed values from an evaluator.