G+Smo  24.08.0
Geometry + Simulation Modules
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
gsElasticityFunctions.hpp
Go to the documentation of this file.
1 
16 #pragma once
17 
19 #include <gsCore/gsFuncData.h>
21 
22 namespace gismo
23 {
24 
25 template <class T>
27 {
28  result.setZero(targetDim(),outputCols(u.cols()));
29  // evaluating the fields
31  mdGeo.points = u;
32  m_geometry->patch(m_patch).computeMap(mdGeo);
33  gsMapData<T> mdDisp(NEED_DERIV);
34  mdDisp.points = u;
35  m_displacement->patch(m_patch).computeMap(mdDisp);
36  // define temporary matrices here for efficieny
37  gsMatrix<T> I = gsMatrix<T>::Identity(m_dim,m_dim);
38  gsMatrix<T> sigma,eps,dispGrad;
39  // material parameters
40  T YM = m_options.getReal("YoungsModulus");
41  T PR = m_options.getReal("PoissonsRatio");
42  T lambda = YM * PR / ( ( 1. + PR ) * ( 1. - 2. * PR ) );
43  T mu = YM / ( 2. * ( 1. + PR ) );
44 
45  for (index_t q = 0; q < u.cols(); ++q)
46  {
47  // linear strain tensor eps = (gradU+gradU^T)/2
48  if (mdGeo.jacobian(q).determinant() <= 0)
49  gsInfo << "Invalid domain parametrization: J = " << mdGeo.jacobian(q).determinant() <<
50  " at point (" << u.col(q).transpose() << ") of patch " << m_patch << std::endl;
51  if (abs(mdGeo.jacobian(q).determinant()) > 1e-20)
52  dispGrad = mdDisp.jacobian(q)*(mdGeo.jacobian(q).cramerInverse());
53  else
54  dispGrad = gsMatrix<T>::Zero(m_dim,m_dim);
55  eps = (dispGrad + dispGrad.transpose())/2;
56  // Cauchy stress tensor
57  sigma = lambda*eps.trace()*I + 2*mu*eps;
58  saveStress(sigma,result,q);
59  }
60 }
61 
62 template <class T>
64 {
65  result.setZero(targetDim(),outputCols(u.cols()));
66  // evaluating the fields
68  mdGeo.points = u;
69  m_geometry->patch(m_patch).computeMap(mdGeo);
70  gsMapData<T> mdDisp(NEED_DERIV);
71  mdDisp.points = u;
72  m_displacement->patch(m_patch).computeMap(mdDisp);
73  // define temporary matrices here for efficieny
74  gsMatrix<T> I = gsMatrix<T>::Identity(m_dim,m_dim);
75  gsMatrix<T> S,sigma,F,C,E;
76  // material parameters
77  T YM = m_options.getReal("YoungsModulus");
78  T PR = m_options.getReal("PoissonsRatio");
79  T lambda = YM * PR / ( ( 1. + PR ) * ( 1. - 2. * PR ) );
80  T mu = YM / ( 2. * ( 1. + PR ) );
81 
82  for (index_t q = 0; q < u.cols(); ++q)
83  {
84  // deformation gradient F = I + gradU*gradGeo^-1
85  if (mdGeo.jacobian(q).determinant() <= 0)
86  gsInfo << "Invalid domain parametrization: J = " << mdGeo.jacobian(q).determinant() <<
87  " at point (" << u.col(q).transpose() << ") of patch " << m_patch << std::endl;
88  if (abs(mdGeo.jacobian(q).determinant()) > 1e-20)
89  F = I + mdDisp.jacobian(q)*(mdGeo.jacobian(q).cramerInverse());
90  else
91  F = I;
92  T J = F.determinant();
93  if (J <= 0)
94  gsInfo << "Invalid displacement field: J = " << J <<
95  " at point (" << u.col(q).transpose() << ") of patch " << m_patch << std::endl;
96  // Second Piola-Kirchhoff stress tensor
97  if (material_law::law(m_options.getInt("MaterialLaw")) == material_law::saint_venant_kirchhoff)
98  {
99  // Green-Lagrange strain tensor E = 0.5(F^T*F-I)
100  E = (F.transpose() * F - I)/2;
101  S = lambda*E.trace()*I + 2*mu*E;
102  }
103  if (material_law::law(m_options.getInt("MaterialLaw")) == material_law::neo_hooke_ln)
104  {
105  // Right Cauchy Green strain, C = F'*F
106  C = F.transpose() * F;
107  S = (lambda*log(J)-mu)*(C.cramerInverse()) + mu*I;
108  }
109  if (material_law::law(m_options.getInt("MaterialLaw")) == material_law::neo_hooke_quad)
110  {
111  // Right Cauchy Green strain, C = F'*F
112  C = F.transpose() * F;
113  S = (lambda*(J*J-1)/2-mu)*(C.cramerInverse()) + mu*I;
114  }
115  // transformation to Cauchy stress
116  sigma = F*S*F.transpose()/J;
117  saveStress(sigma,result,q);
118  }
119 }
120 
121 template <class T>
122 void gsCauchyStressFunction<T>::mixedLinearElastic(const gsMatrix<T> & u, gsMatrix<T> & result) const
123 {
124  result.setZero(targetDim(),outputCols(u.cols()));
125  // evaluating the fields
126  gsMapData<T> mdGeo(NEED_GRAD_TRANSFORM);
127  mdGeo.points = u;
128  m_geometry->patch(m_patch).computeMap(mdGeo);
129  gsMapData<T> mdDisp(NEED_DERIV);
130  mdDisp.points = u;
131  m_displacement->patch(m_patch).computeMap(mdDisp);
132  gsMatrix<T> presVals;
133  m_pressure->patch(m_patch).eval_into(u,presVals);
134  // define temporary matrices here for efficieny
135  gsMatrix<T> I = gsMatrix<T>::Identity(m_dim,m_dim);
136  gsMatrix<T> sigma,eps,dispGrad;
137  // material parameters
138  T YM = m_options.getReal("YoungsModulus");
139  T PR = m_options.getReal("PoissonsRatio");
140  T mu = YM / ( 2. * ( 1. + PR ) );
141 
142  for (index_t q = 0; q < u.cols(); ++q)
143  {
144  // linear strain tensor eps = (gradU+gradU^T)/2
145  if (mdGeo.jacobian(q).determinant() <= 0)
146  gsInfo << "Invalid domain parametrization: J = " << mdGeo.jacobian(q).determinant() <<
147  " at point (" << u.col(q).transpose() << ") of patch " << m_patch << std::endl;
148  if (abs(mdGeo.jacobian(q).determinant()) > 1e-20)
149  dispGrad = mdDisp.jacobian(q)*(mdGeo.jacobian(q).cramerInverse());
150  else
151  dispGrad = gsMatrix<T>::Zero(m_dim,m_dim);
152  eps = (dispGrad + dispGrad.transpose())/2;
153  // Cauchy stress tensor
154  sigma = presVals.at(q)*I + 2*mu*eps;
155  saveStress(sigma,result,q);
156  }
157 }
158 
159 template <class T>
160 void gsCauchyStressFunction<T>::mixedNonLinearElastic(const gsMatrix<T> & u, gsMatrix<T> & result) const
161 {
162  result.setZero(targetDim(),outputCols(u.cols()));
163  // evaluating the fields
164  gsMapData<T> mdGeo(NEED_GRAD_TRANSFORM);
165  mdGeo.points = u;
166  m_geometry->patch(m_patch).computeMap(mdGeo);
167  gsMapData<T> mdDisp(NEED_DERIV);
168  mdDisp.points = u;
169  m_displacement->patch(m_patch).computeMap(mdDisp);
170  gsMatrix<T> presVals;
171  m_pressure->patch(m_patch).eval_into(u,presVals);
172  // define temporary matrices here for efficieny
173  gsMatrix<T> I = gsMatrix<T>::Identity(m_dim,m_dim);
174  gsMatrix<T> S,sigma,F,C,E;
175  // material parameters
176  T YM = m_options.getReal("YoungsModulus");
177  T PR = m_options.getReal("PoissonsRatio");
178  T mu = YM / ( 2. * ( 1. + PR ) );
179 
180  for (index_t q = 0; q < u.cols(); ++q)
181  {
182  if (mdGeo.jacobian(q).determinant() <= 0)
183  gsInfo << "Invalid domain parametrization: J = " << mdGeo.jacobian(q).determinant() <<
184  " at point (" << u.col(q).transpose() << ") of patch " << m_patch << std::endl;
185  // deformation gradient F = I + gradU*gradGeo^-1
186  if (abs(mdGeo.jacobian(q).determinant()) > 1e-20)
187  F = I + mdDisp.jacobian(q)*(mdGeo.jacobian(q).cramerInverse());
188  else
189  F = I;
190  T J = F.determinant();
191  if (J <= 0)
192  gsInfo << "Invalid displacement field: J = " << J <<
193  " at point (" << u.col(q).transpose() << ") of patch " << m_patch << std::endl;
194  // Second Piola-Kirchhoff stress tensor
195  C = F.transpose() * F;
196  S = (presVals.at(q)-mu)*(C.cramerInverse()) + mu*I;
197  // transformation to Cauchy stress
198  sigma = F*S*F.transpose()/J;
199  saveStress(sigma,result,q);
200  }
201 }
202 
203 template <class T>
205 {
206  switch (m_type)
207  {
208  case stress_components::von_mises :
209  {
210  if (m_geometry->parDim() == 2)
211  result(0,q) = sqrt( S(0,0)*S(0,0) + S(1,1)*S(1,1) - S(0,0)*S(1,1) + 3*S(0,1)*S(0,1) );
212  if (m_geometry->parDim() == 3)
213  result(0,q) = sqrt(0.5*( pow(S(0,0)-S(1,1),2) + pow(S(0,0)-S(2,2),2) + pow(S(1,1)-S(2,2),2) +
214  6 * (pow(S(0,1),2) + pow(S(0,2),2) + pow(S(1,2),2) ) ) );
215  return;
216  }
217  case stress_components::all_2D_vector : result(0,q) = S(0,0); result(1,q) = S(1,1); result(2,q) = S(0,1); return;
218  case stress_components::all_2D_matrix : result.middleCols(q*2,2) = S; return;
219  case stress_components::normal_3D_vector : result(0,q) = S(0,0); result(1,q) = S(1,1); result(2,q) = S(2,2); return;
220  case stress_components::shear_3D_vector : result(0,q) = S(0,1); result(1,q) = S(0,2); result(2,q) = S(1,2); return;
221  case stress_components::all_3D_matrix : result.middleCols(q*3,3) = S; return;
222  }
223 }
224 
225 
226 template <class T>
227 void gsDetFunction<T>::eval_into(const gsMatrix<T> & u, gsMatrix<T> & result) const
228 {
229  result.resize(1,u.cols());
230 
231  gsMapData<T> mappingData;
232  mappingData.points = u;
233  mappingData.flags = NEED_DERIV;
234  m_geo.patch(m_patch).computeMap(mappingData);
235 
236  for (index_t i = 0; i < u.cols(); ++i)
237  result(0,i) = mappingData.jacobian(i).determinant();
238 }
239 
240 template <class T>
241 void gsFsiLoad<T>::eval_into(const gsMatrix<T> & u, gsMatrix<T> & result) const
242 {
243  result.setZero(targetDim(),u.cols());
244  // mapping points back to the parameter space via the reference configuration
245  gsMatrix<T> paramPoints;
246  m_geo.patch(m_patchGeo).invertPoints(u,paramPoints);
247  // evaluate reference geometry mapping at the param points
248  // NEED_GRAD_TRANSFORM for velocity gradients transformation from parametric to reference domain
250  mdGeo.points = paramPoints;
251  m_geo.patch(m_patchGeo).computeMap(mdGeo);
252  // evaluate velocity at the param points
253  // NEED_DERIV for velocity gradients
254  gsMapData<T> mdVel(NEED_DERIV);
255  mdVel.points = paramPoints;
256  m_vel.patch(m_patchVP).computeMap(mdVel);
257  // evaluate pressure at the quad points
258  gsMatrix<T> pressureValues;
259  m_pres.patch(m_patchVP).eval_into(paramPoints,pressureValues);
260  // evaluate ALE dispacement at the param points
261  // NEED_DERIV for gradients
262  gsMapData<T> mdALE(NEED_DERIV);
263  mdALE.points = paramPoints;
264  m_ale.patch(m_patchGeo).computeMap(mdALE);
265 
266  gsMatrix<T> I = gsMatrix<T>::Identity(targetDim(),targetDim());
267  for (index_t p = 0; p < paramPoints.cols(); ++p)
268  {
269  // transform velocity gradients from parametric to reference
270  gsMatrix<T> physGradVel = mdVel.jacobian(p)*(mdGeo.jacobian(p).cramerInverse());
271  // ALE jacobian (identity + physical displacement gradient)
272  gsMatrix<T> physJacALE = I + mdALE.jacobian(p)*(mdGeo.jacobian(p).cramerInverse());
273  // inverse ALE jacobian
274  gsMatrix<T> invJacALE = physJacALE.cramerInverse();
275  // ALE stress tensor
276  gsMatrix<T> sigma = pressureValues.at(p)*I
277  - m_density*m_viscosity*(physGradVel*invJacALE +
278  invJacALE.transpose()*physGradVel.transpose());
279  // stress tensor pull back
280  gsMatrix<T> sigmaALE = physJacALE.determinant()*sigma*(invJacALE.transpose());
281 
282  // normal length is the local measure
283  gsVector<T> normal;
284  outerNormal(mdGeo,p,m_sideGeo,normal);
285  result.col(p) = sigmaALE * normal / normal.norm();
286  }
287 }
288 
289 } // namespace gismo ends
Compute Cauchy stresses for a previously computed/defined displacement field. Can be pushed into gsPi...
Definition: gsElasticityFunctions.h:29
Provides generic assembler routines.
Gradient of the object.
Definition: gsForwardDeclarations.h:73
S = lambda*ln(J)*C^-1 + mu*(I-C^-1)
Definition: gsBaseUtils.h:134
the gsMapData is a cache of pre-computed function (map) values.
Definition: gsFuncData.h:324
#define index_t
Definition: gsConfig.h:32
return von Mises stress as a scala
Definition: gsBaseUtils.h:114
sigma = 2*mu*eps + lambda*tr(eps)*I
Definition: gsBaseUtils.h:132
Provides useful classes derived from gsFunction which can be used for visualization or coupling...
T at(index_t i) const
Returns the i-th element of the vectorization of the matrix.
Definition: gsMatrix.h:211
#define gsInfo
Definition: gsDebug.h:43
void linearElastic(const gsMatrix< T > &u, gsMatrix< T > &result) const
computation routines for different material laws
Definition: gsElasticityFunctions.hpp:26
law
Definition: gsBaseUtils.h:128
virtual void eval_into(const gsMatrix< T > &u, gsMatrix< T > &result) const
Each column of the input matrix (u) corresponds to one evaluation point. Each column of the output ma...
Definition: gsElasticityFunctions.hpp:227
void saveStress(const gsMatrix< T > &S, gsMatrix< T > &result, index_t q) const
save components of the stress tensor to the output matrix according to the m_type ...
Definition: gsElasticityFunctions.hpp:204
virtual void eval_into(const gsMatrix< T > &u, gsMatrix< T > &result) const
Each column of the input matrix (u) corresponds to one evaluation point. Each column of the output ma...
Definition: gsElasticityFunctions.hpp:241
return all components of the 2D stress tensor as a 2x2 matrix
Definition: gsBaseUtils.h:117
EIGEN_STRONG_INLINE abs_expr< E > abs(const E &u)
Absolute value.
Definition: gsExpressions.h:4486
gsMatrix< T > points
input (parametric) points
Definition: gsFuncData.h:348
Gradient transformation matrix.
Definition: gsForwardDeclarations.h:77
Definition: gsBaseUtils.h:119
S = 2*mu*E + lambda*tr(E)*I.
Definition: gsBaseUtils.h:133
Definition: gsBaseUtils.h:116
This object is a cache for computed values from an evaluator.
Definition: gsBaseUtils.h:121