G+Smo  25.01.0
Geometry + Simulation Modules
 
Loading...
Searching...
No Matches
gsElasticityFunctions.hpp
Go to the documentation of this file.
1
16#pragma once
17
19#include <gsCore/gsFuncData.h>
21
22namespace gismo
23{
24
25template <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);
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
62template <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);
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
121template <class T>
122void 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
159template <class T>
160void 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
203template <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
226template <class T>
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
240template <class T>
241void 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
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
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:30
void linearElastic(const gsMatrix< T > &u, gsMatrix< T > &result) const
computation routines for different material laws
Definition gsElasticityFunctions.hpp:26
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:227
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
the gsMapData is a cache of pre-computed function (map) values.
Definition gsFuncData.h:349
gsMatrix< T > points
input (parametric) points
Definition gsFuncData.h:372
A matrix with arbitrary coefficient type and fixed or dynamic size.
Definition gsMatrix.h:41
T at(index_t i) const
Returns the i-th element of the vectorization of the matrix.
Definition gsMatrix.h:211
A vector with arbitrary coefficient type and fixed or dynamic size.
Definition gsVector.h:37
Provides generic assembler routines.
#define index_t
Definition gsConfig.h:32
#define gsInfo
Definition gsDebug.h:43
Provides useful classes derived from gsFunction which can be used for visualization or coupling.
This object is a cache for computed values from an evaluator.
EIGEN_STRONG_INLINE abs_expr< E > abs(const E &u)
Absolute value.
Definition gsExpressions.h:4486
The G+Smo namespace, containing all definitions for the library.
@ NEED_DERIV
Gradient of the object.
Definition gsForwardDeclarations.h:73
@ NEED_GRAD_TRANSFORM
Gradient transformation matrix.
Definition gsForwardDeclarations.h:77
law
Definition gsBaseUtils.h:129
@ neo_hooke_quad
S = lambda*ln(J)*C^-1 + mu*(I-C^-1)
Definition gsBaseUtils.h:134
@ neo_hooke_ln
S = 2*mu*E + lambda*tr(E)*I.
Definition gsBaseUtils.h:133
@ saint_venant_kirchhoff
sigma = 2*mu*eps + lambda*tr(eps)*I
Definition gsBaseUtils.h:132
@ normal_3D_vector
return all components of the 2D stress tensor as a 2x2 matrix
Definition gsBaseUtils.h:117
@ shear_3D_vector
Definition gsBaseUtils.h:119
@ all_3D_matrix
Definition gsBaseUtils.h:121
@ all_2D_vector
return von Mises stress as a scala
Definition gsBaseUtils.h:114
@ all_2D_matrix
Definition gsBaseUtils.h:116