v0.15.0
Loading...
Searching...
No Matches
Public Member Functions | Private Attributes | List of all members
OpCalculateRotationAndSpatialGradient Struct Reference

#include "users_modules/eshelbian_plasticity/src/EshelbianOperators.hpp"

Inheritance diagram for OpCalculateRotationAndSpatialGradient:
[legend]
Collaboration diagram for OpCalculateRotationAndSpatialGradient:
[legend]

Public Member Functions

 OpCalculateRotationAndSpatialGradient (boost::shared_ptr< DataAtIntegrationPts > data_ptr, double alpha_omega=0)
 
MoFEMErrorCode doWork (int side, EntityType type, EntData &data)
 Operator for linear form, usually to calculate values on right hand side.
 
- Public Member Functions inherited from MoFEM::VolumeElementForcesAndSourcesCore::UserDataOperator
int getNumNodes ()
 get element number of nodes
 
const EntityHandlegetConn ()
 get element connectivity
 
double getVolume () const
 element volume (linear geometry)
 
doublegetVolume ()
 element volume (linear geometry)
 
FTensor::Tensor2< double *, 3, 3 > & getJac ()
 get element Jacobian
 
FTensor::Tensor2< double *, 3, 3 > & getInvJac ()
 get element inverse Jacobian
 
VectorDoublegetCoords ()
 nodal coordinates
 
VolumeElementForcesAndSourcesCoregetVolumeFE () const
 return pointer to Generic Volume Finite Element object
 
- Public Member Functions inherited from MoFEM::ForcesAndSourcesCore::UserDataOperator
 UserDataOperator (const FieldSpace space, const char type=OPSPACE, const bool symm=true)
 Constructor for operators working on finite element spaces.
 
 UserDataOperator (const std::string field_name, const char type, const bool symm=true)
 Constructor for operators working on a single field.
 
 UserDataOperator (const std::string row_field_name, const std::string col_field_name, const char type, const bool symm=true)
 Constructor for operators working on two fields (bilinear forms)
 
boost::shared_ptr< const NumeredEntFiniteElementgetNumeredEntFiniteElementPtr () const
 Return raw pointer to NumeredEntFiniteElement.
 
EntityHandle getFEEntityHandle () const
 Return finite element entity handle.
 
int getFEDim () const
 Get dimension of finite element.
 
EntityType getFEType () const
 Get dimension of finite element.
 
boost::weak_ptr< SideNumbergetSideNumberPtr (const int side_number, const EntityType type)
 Get the side number pointer.
 
EntityHandle getSideEntity (const int side_number, const EntityType type)
 Get the side entity.
 
int getNumberOfNodesOnElement () const
 Get the number of nodes on finite element.
 
MoFEMErrorCode getProblemRowIndices (const std::string filed_name, const EntityType type, const int side, VectorInt &indices) const
 Get row indices.
 
MoFEMErrorCode getProblemColIndices (const std::string filed_name, const EntityType type, const int side, VectorInt &indices) const
 Get col indices.
 
const FEMethodgetFEMethod () const
 Return raw pointer to Finite Element Method object.
 
int getOpType () const
 Get operator types.
 
void setOpType (const OpType type)
 Set operator type.
 
void addOpType (const OpType type)
 Add operator type.
 
int getNinTheLoop () const
 get number of finite element in the loop
 
int getLoopSize () const
 get size of elements in the loop
 
std::string getFEName () const
 Get name of the element.
 
ForcesAndSourcesCoregetPtrFE () const
 
ForcesAndSourcesCoregetSidePtrFE () const
 
ForcesAndSourcesCoregetRefinePtrFE () const
 
const PetscData::SwitchesgetDataCtx () const
 
const KspMethod::KSPContext getKSPCtx () const
 
const SnesMethod::SNESContext getSNESCtx () const
 
const TSMethod::TSContext getTSCtx () const
 
Vec getKSPf () const
 
Mat getKSPA () const
 
Mat getKSPB () const
 
Vec getSNESf () const
 
Vec getSNESx () const
 
Mat getSNESA () const
 
Mat getSNESB () const
 
Vec getTSu () const
 
Vec getTSu_t () const
 
Vec getTSu_tt () const
 
Vec getTSf () const
 
Mat getTSA () const
 
Mat getTSB () const
 
int getTSstep () const
 
double getTStime () const
 
double getTStimeStep () const
 
double getTSa () const
 
double getTSaa () const
 
MatrixDoublegetGaussPts ()
 matrix of integration (Gauss) points for Volume Element
 
auto getFTensor0IntegrationWeight ()
 Get integration weights.
 
MatrixDoublegetCoordsAtGaussPts ()
 Gauss points and weight, matrix (nb. of points x 3)
 
auto getFTensor1CoordsAtGaussPts ()
 Get coordinates at integration points assuming linear geometry.
 
double getMeasure () const
 get measure of element
 
doublegetMeasure ()
 get measure of element
 
MoFEM::InterfacegetMField ()
 
moab::Interface & getMoab ()
 
MoFEMErrorCode loopSide (const string &fe_name, ForcesAndSourcesCore *side_fe, const size_t dim, const EntityHandle ent_for_side=0, boost::shared_ptr< Range > fe_range=nullptr, const int verb=QUIET, const LogManager::SeverityLevel sev=Sev::noisy, AdjCache *adj_cache=nullptr)
 User calls this function to loop over elements on the side of face. This function calls finite element with its operator to do calculations.
 
MoFEMErrorCode loopThis (const string &fe_name, ForcesAndSourcesCore *this_fe, const int verb=QUIET, const LogManager::SeverityLevel sev=Sev::noisy)
 User calls this function to loop over the same element using a different set of integration points. This function calls finite element with its operator to do calculations.
 
MoFEMErrorCode loopParent (const string &fe_name, ForcesAndSourcesCore *parent_fe, const int verb=QUIET, const LogManager::SeverityLevel sev=Sev::noisy)
 User calls this function to loop over parent elements. This function calls finite element with its operator to do calculations.
 
MoFEMErrorCode loopChildren (const string &fe_name, ForcesAndSourcesCore *child_fe, const int verb=QUIET, const LogManager::SeverityLevel sev=Sev::noisy)
 User calls this function to loop over parent elements. This function calls finite element with its operator to do calculations.
 
MoFEMErrorCode loopRange (const string &fe_name, ForcesAndSourcesCore *range_fe, boost::shared_ptr< Range > fe_range, const int verb=QUIET, const LogManager::SeverityLevel sev=Sev::noisy)
 Iterate over range of elements.
 
- Public Member Functions inherited from MoFEM::DataOperator
 DataOperator (const bool symm=true)
 
virtual ~DataOperator ()=default
 
virtual MoFEMErrorCode doWork (int row_side, int col_side, EntityType row_type, EntityType col_type, EntitiesFieldData::EntData &row_data, EntitiesFieldData::EntData &col_data)
 Operator for bi-linear form, usually to calculate values on left hand side.
 
virtual MoFEMErrorCode opLhs (EntitiesFieldData &row_data, EntitiesFieldData &col_data)
 
virtual MoFEMErrorCode opRhs (EntitiesFieldData &data, const bool error_if_no_base=false)
 
bool getSymm () const
 Get if operator uses symmetry of DOFs or not.
 
void setSymm ()
 set if operator is executed taking in account symmetry
 
void unSetSymm ()
 unset if operator is executed for non symmetric problem
 

Private Attributes

boost::shared_ptr< DataAtIntegrationPtsdataAtPts
 data at integration pts
 
double alphaOmega
 

Additional Inherited Members

- Public Types inherited from MoFEM::ForcesAndSourcesCore::UserDataOperator
enum  OpType {
  OPROW = 1 << 0 , OPCOL = 1 << 1 , OPROWCOL = 1 << 2 , OPSPACE = 1 << 3 ,
  OPLAST = 1 << 3
}
 Controls loop over entities on element. More...
 
using AdjCache = std::map< EntityHandle, std::vector< boost::weak_ptr< NumeredEntFiniteElement > > >
 
- Public Types inherited from MoFEM::DataOperator
using DoWorkLhsHookFunType = boost::function< MoFEMErrorCode(DataOperator *op_ptr, int row_side, int col_side, EntityType row_type, EntityType col_type, EntitiesFieldData::EntData &row_data, EntitiesFieldData::EntData &col_data)>
 
using DoWorkRhsHookFunType = boost::function< MoFEMErrorCode(DataOperator *op_ptr, int side, EntityType type, EntitiesFieldData::EntData &data)>
 
- Public Attributes inherited from MoFEM::ForcesAndSourcesCore::UserDataOperator
char opType
 
std::string rowFieldName
 
std::string colFieldName
 
FieldSpace sPace
 
- Public Attributes inherited from MoFEM::DataOperator
DoWorkLhsHookFunType doWorkLhsHook
 
DoWorkRhsHookFunType doWorkRhsHook
 
bool sYmm
 If true assume that matrix is symmetric structure.
 
std::array< bool, MBMAXTYPE > doEntities
 If true operator is executed for entity.
 
booldoVertices
 \deprectaed If false skip vertices
 
booldoEdges
 \deprectaed If false skip edges
 
booldoQuads
 \deprectaed
 
booldoTris
 \deprectaed
 
booldoTets
 \deprectaed
 
booldoPrisms
 \deprectaed
 
- Static Public Attributes inherited from MoFEM::ForcesAndSourcesCore::UserDataOperator
static const char *const OpTypeNames []
 
- Protected Member Functions inherited from MoFEM::VolumeElementForcesAndSourcesCore::UserDataOperator
MoFEMErrorCode setPtrFE (ForcesAndSourcesCore *ptr)
 
- Protected Attributes inherited from MoFEM::ForcesAndSourcesCore::UserDataOperator
ForcesAndSourcesCoreptrFE
 

Detailed Description

Examples
mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianPlasticity.cpp.

Definition at line 282 of file EshelbianOperators.hpp.

Constructor & Destructor Documentation

◆ OpCalculateRotationAndSpatialGradient()

OpCalculateRotationAndSpatialGradient::OpCalculateRotationAndSpatialGradient ( boost::shared_ptr< DataAtIntegrationPts data_ptr,
double  alpha_omega = 0 
)
inline

Definition at line 284 of file EshelbianOperators.hpp.

287 alphaOmega(alpha_omega) {}
@ NOSPACE
Definition definitions.h:83
VolumeElementForcesAndSourcesCore::UserDataOperator VolUserDataOperator
@ OPSPACE
operator do Work is execute on space data
boost::shared_ptr< DataAtIntegrationPts > dataAtPts
data at integration pts

Member Function Documentation

◆ doWork()

MoFEMErrorCode OpCalculateRotationAndSpatialGradient::doWork ( int  side,
EntityType  type,
EntData data 
)
virtual

Operator for linear form, usually to calculate values on right hand side.

Reimplemented from MoFEM::DataOperator.

Examples
mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianOperators.cpp.

Definition at line 63 of file EshelbianOperators.cpp.

65 {
67
68 auto ts_ctx = getTSCtx();
69 int nb_integration_pts = getGaussPts().size2();
70
71 // space size indices
79
80 // sym size indices
82
83 auto t_L = symm_L_tensor();
84
85 dataAtPts->hAtPts.resize(9, nb_integration_pts, false);
86 dataAtPts->hdOmegaAtPts.resize(9 * 3, nb_integration_pts, false);
87 dataAtPts->hdLogStretchAtPts.resize(9 * 6, nb_integration_pts, false);
88
89 dataAtPts->leviKirchhoffAtPts.resize(3, nb_integration_pts, false);
90 dataAtPts->leviKirchhoffdOmegaAtPts.resize(9, nb_integration_pts, false);
91 dataAtPts->leviKirchhoffdLogStreatchAtPts.resize(3 * size_symm,
92 nb_integration_pts, false);
93 dataAtPts->leviKirchhoffPAtPts.resize(9 * 3, nb_integration_pts, false);
94
95 dataAtPts->adjointPdstretchAtPts.resize(9, nb_integration_pts, false);
96 dataAtPts->adjointPdUAtPts.resize(size_symm, nb_integration_pts, false);
97 dataAtPts->adjointPdUdPAtPts.resize(9 * size_symm, nb_integration_pts, false);
98 dataAtPts->adjointPdUdOmegaAtPts.resize(3 * size_symm, nb_integration_pts,
99 false);
100 dataAtPts->rotMatAtPts.resize(9, nb_integration_pts, false);
101 dataAtPts->stretchTensorAtPts.resize(6, nb_integration_pts, false);
102 dataAtPts->diffStretchTensorAtPts.resize(36, nb_integration_pts, false);
103 dataAtPts->eigenVals.resize(3, nb_integration_pts, false);
104 dataAtPts->eigenVecs.resize(9, nb_integration_pts, false);
105 dataAtPts->nbUniq.resize(nb_integration_pts, false);
106 dataAtPts->eigenValsC.resize(3, nb_integration_pts, false);
107 dataAtPts->eigenVecsC.resize(9, nb_integration_pts, false);
108 dataAtPts->nbUniqC.resize(nb_integration_pts, false);
109
110 dataAtPts->logStretch2H1AtPts.resize(6, nb_integration_pts, false);
111 dataAtPts->logStretchTotalTensorAtPts.resize(6, nb_integration_pts, false);
112
113 dataAtPts->internalStressAtPts.resize(9, nb_integration_pts, false);
114 dataAtPts->internalStressAtPts.clear();
115
116 // Calculated values
117 auto t_h = getFTensor2FromMat<3, 3>(dataAtPts->hAtPts);
118 auto t_h_domega = getFTensor3FromMat<3, 3, 3>(dataAtPts->hdOmegaAtPts);
119 auto t_h_dlog_u =
120 getFTensor3FromMat<3, 3, size_symm>(dataAtPts->hdLogStretchAtPts);
121 auto t_levi_kirchhoff = getFTensor1FromMat<3>(dataAtPts->leviKirchhoffAtPts);
122 auto t_levi_kirchhoff_domega =
123 getFTensor2FromMat<3, 3>(dataAtPts->leviKirchhoffdOmegaAtPts);
124 auto t_levi_kirchhoff_dstreach = getFTensor2FromMat<3, size_symm>(
125 dataAtPts->leviKirchhoffdLogStreatchAtPts);
126 auto t_levi_kirchhoff_dP =
127 getFTensor3FromMat<3, 3, 3>(dataAtPts->leviKirchhoffPAtPts);
128 auto t_approx_P_adjoint__dstretch =
129 getFTensor2FromMat<3, 3>(dataAtPts->adjointPdstretchAtPts);
130 auto t_approx_P_adjoint_log_du =
131 getFTensor1FromMat<size_symm>(dataAtPts->adjointPdUAtPts);
132 auto t_approx_P_adjoint_log_du_dP =
133 getFTensor3FromMat<3, 3, size_symm>(dataAtPts->adjointPdUdPAtPts);
134 auto t_approx_P_adjoint_log_du_domega =
135 getFTensor2FromMat<3, size_symm>(dataAtPts->adjointPdUdOmegaAtPts);
136 auto t_R = getFTensor2FromMat<3, 3>(dataAtPts->rotMatAtPts);
137 auto t_u = getFTensor2SymmetricFromMat<3>(dataAtPts->stretchTensorAtPts);
138 auto t_diff_u =
139 getFTensor4DdgFromMat<3, 3, 1>(dataAtPts->diffStretchTensorAtPts);
140 auto t_eigen_vals = getFTensor1FromMat<3>(dataAtPts->eigenVals);
141 auto t_eigen_vecs = getFTensor2FromMat<3, 3>(dataAtPts->eigenVecs);
142 auto &nbUniq = dataAtPts->nbUniq;
143 auto t_nb_uniq =
144 FTensor::Tensor0<FTensor::PackPtr<int *, 1>>(nbUniq.data().data());
145 auto t_eigen_vals_C = getFTensor1FromMat<3>(dataAtPts->eigenValsC);
146 auto t_eigen_vecs_C = getFTensor2FromMat<3, 3>(dataAtPts->eigenVecsC);
147 auto &nbUniqC = dataAtPts->nbUniqC;
148 auto t_nb_uniq_C =
149 FTensor::Tensor0<FTensor::PackPtr<int *, 1>>(nbUniqC.data().data());
150
151 auto t_log_stretch_total =
152 getFTensor2SymmetricFromMat<3>(dataAtPts->logStretchTotalTensorAtPts);
153 auto t_log_u2_h1 =
154 getFTensor2SymmetricFromMat<3>(dataAtPts->logStretch2H1AtPts);
155
156 // Field values
157 auto t_grad_h1 = getFTensor2FromMat<3, 3>(dataAtPts->wGradH1AtPts);
158 auto t_omega = getFTensor1FromMat<3>(dataAtPts->rotAxisAtPts);
159 auto t_approx_P = getFTensor2FromMat<3, 3>(dataAtPts->approxPAtPts);
160 auto t_log_u =
161 getFTensor2SymmetricFromMat<3>(dataAtPts->logStretchTensorAtPts);
162
163 auto next = [&]() {
164 // calculated values
165 ++t_h;
166 ++t_h_domega;
167 ++t_h_dlog_u;
168 ++t_levi_kirchhoff;
169 ++t_levi_kirchhoff_domega;
170 ++t_levi_kirchhoff_dstreach;
171 ++t_levi_kirchhoff_dP;
172 ++t_approx_P_adjoint__dstretch;
173 ++t_approx_P_adjoint_log_du;
174 ++t_approx_P_adjoint_log_du_dP;
175 ++t_approx_P_adjoint_log_du_domega;
176 ++t_R;
177 ++t_u;
178 ++t_diff_u;
179 ++t_eigen_vals;
180 ++t_eigen_vecs;
181 ++t_nb_uniq;
182 ++t_eigen_vals_C;
183 ++t_eigen_vecs_C;
184 ++t_nb_uniq_C;
185 ++t_log_u2_h1;
186 ++t_log_stretch_total;
187 // field values
188 ++t_omega;
189 ++t_grad_h1;
190 ++t_approx_P;
191 ++t_log_u;
192 };
193
196
197 auto bound_eig = [&](auto &eig) {
199 const auto zero = std::exp(std::numeric_limits<double>::min_exponent);
200 const auto large = std::exp(std::numeric_limits<double>::max_exponent);
201 for (int ii = 0; ii != 3; ++ii) {
202 eig(ii) = std::min(std::max(zero, eig(ii)), large);
203 }
205 };
206
207 auto calculate_log_stretch = [&]() {
210 eigen_vec(i, j) = t_log_u(i, j);
211 if (computeEigenValuesSymmetric(eigen_vec, eig) != MB_SUCCESS) {
212 MOFEM_LOG("SELF", Sev::error) << "Failed to compute eigen values";
213 }
214 // CHKERR bound_eig(eig);
215 // rare case when two eigen values are equal
216 t_nb_uniq = get_uniq_nb<3>(&eig(0));
217 if (t_nb_uniq < 3) {
218 sort_eigen_vals(eig, eigen_vec);
219 }
220 t_eigen_vals(i) = eig(i);
221 t_eigen_vecs(i, j) = eigen_vec(i, j);
222 t_u(i, j) =
223 EigenMatrix::getMat(t_eigen_vals, t_eigen_vecs, EshelbianCore::f)(i, j);
224 auto get_t_diff_u = [&]() {
225 return EigenMatrix::getDiffMat(t_eigen_vals, t_eigen_vecs,
227 t_nb_uniq);
228 };
229 t_diff_u(i, j, k, l) = get_t_diff_u()(i, j, k, l);
231 t_Ldiff_u(i, j, L) = t_diff_u(i, j, m, n) * t_L(m, n, L);
232 return t_Ldiff_u;
233 };
234
235 auto calculate_total_stretch = [&](auto &t_h1) {
236 if (EshelbianCore::gradApproximator == NO_H1_CONFIGURATION) {
237
238 t_log_u2_h1(i, j) = 0;
239 t_log_stretch_total(i, j) = t_log_u(i, j);
240
243 t_R_h1(i, j) = t_kd(i, j);
244 t_inv_u_h1(i, j) = t_symm_kd(i, j);
245
246 return std::make_pair(t_R_h1, t_inv_u_h1);
247
248 } else {
249
252
254 t_C_h1(i, j) = t_h1(k, i) * t_h1(k, j);
255 eigen_vec(i, j) = t_C_h1(i, j);
256 if (computeEigenValuesSymmetric(eigen_vec, eig) != MB_SUCCESS) {
257 MOFEM_LOG("SELF", Sev::error) << "Failed to compute eigen values";
258 }
259 // rare case when two eigen values are equal
260 t_nb_uniq_C = get_uniq_nb<3>(&eig(0));
261 if (t_nb_uniq_C < 3) {
262 sort_eigen_vals(eig, eigen_vec);
263 }
264 if (EshelbianCore::stretchSelector >= StretchSelector::LOG) {
265 CHKERR bound_eig(eig);
266 }
267 t_eigen_vals_C(i) = eig(i);
268 t_eigen_vecs_C(i, j) = eigen_vec(i, j);
269
270 t_log_u2_h1(i, j) =
271 EigenMatrix::getMat(eig, eigen_vec, EshelbianCore::inv_f)(i, j);
272 t_log_stretch_total(i, j) = t_log_u2_h1(i, j) / 2 + t_log_u(i, j);
273
274 auto f_inv_sqrt = [](auto e) { return 1. / std::sqrt(e); };
276 t_inv_u_h1(i, j) = EigenMatrix::getMat(eig, eigen_vec, f_inv_sqrt)(i, j);
278 t_R_h1(i, j) = t_h1(i, o) * t_inv_u_h1(o, j);
279
280 return std::make_pair(t_R_h1, t_inv_u_h1);
281 }
282 };
283
284 auto no_h1_loop = [&]() {
286
288 case LARGE_ROT:
289 break;
290 case SMALL_ROT:
291 break;
292 default:
293 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
294 "rotSelector should be large");
295 };
296
297 for (int gg = 0; gg != nb_integration_pts; ++gg) {
298
300
302 t_h1(i, j) = t_kd(i, j);
303
304 // calculate streach
305 auto t_Ldiff_u = calculate_log_stretch();
306
307 // calculate total stretch
308 auto [t_R_h1, t_inv_u_h1] = calculate_total_stretch(t_h1);
309
314
316
317 // rotation
319 case LARGE_ROT:
320 t_R(i, j) = LieGroups::SO3::exp(t_omega, t_omega.l2())(i, j);
321 t_diff_R(i, j, k) =
322 LieGroups::SO3::diffExp(t_omega, t_omega.l2())(i, j, k);
323 // left
324 t_diff_Rr(i, j, l) = t_R(i, k) * levi_civita(k, j, l);
325 t_diff_diff_Rr(i, j, l, m) = t_diff_R(i, k, m) * levi_civita(k, j, l);
326 // right
327 t_diff_Rl(i, j, l) = levi_civita(i, k, l) * t_R(k, j);
328 t_diff_diff_Rl(i, j, l, m) = levi_civita(i, k, l) * t_diff_R(k, j, m);
329 break;
330
331 default:
332 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
333 "rotationSelector not handled");
334 }
335
336 constexpr double half_r = 1 / 2.;
337 constexpr double half_l = 1 / 2.;
338
339 // calculate gradient
340 t_h(i, k) = t_R(i, l) * t_u(l, k);
341
342 // Adjoint stress
343 t_approx_P_adjoint__dstretch(l, k) =
344 (t_R(i, l) * t_approx_P(i, k) + t_R(i, k) * t_approx_P(i, l));
345 t_approx_P_adjoint__dstretch(l, k) /= 2.;
346
347 t_approx_P_adjoint_log_du(L) =
348 (t_approx_P_adjoint__dstretch(l, k) * t_Ldiff_u(l, k, L) +
349 t_approx_P_adjoint__dstretch(k, l) * t_Ldiff_u(l, k, L) +
350 t_approx_P_adjoint__dstretch(l, k) * t_Ldiff_u(k, l, L) +
351 t_approx_P_adjoint__dstretch(k, l) * t_Ldiff_u(k, l, L)) /
352 4.;
353
354 // Kirchhoff stress
355 t_levi_kirchhoff(m) =
356
357 half_r * (t_diff_Rr(i, l, m) * (t_u(l, k) * t_approx_P(i, k)) +
358 t_diff_Rr(i, k, m) * (t_u(l, k) * t_approx_P(i, l)))
359
360 +
361
362 half_l * (t_diff_Rl(i, l, m) * (t_u(l, k) * t_approx_P(i, k)) +
363 t_diff_Rl(i, k, m) * (t_u(l, k) * t_approx_P(i, l)));
364 t_levi_kirchhoff(m) /= 2.;
365
367
368 if (EshelbianCore::symmetrySelector == SYMMETRIC) {
369 t_h_domega(i, k, m) = half_r * (t_diff_Rr(i, l, m) * t_u(l, k))
370
371 +
372
373 half_l * (t_diff_Rl(i, l, m) * t_u(l, k));
374 } else {
375 t_h_domega(i, k, m) = t_diff_R(i, l, m) * t_u(l, k);
376 }
377
378 t_h_dlog_u(i, k, L) = t_R(i, l) * t_Ldiff_u(l, k, L);
379
380 t_approx_P_adjoint_log_du_dP(i, k, L) =
381 t_R(i, l) * (t_Ldiff_u(l, k, L) + t_Ldiff_u(k, l, L)) / 2.;
382
383 if (EshelbianCore::symmetrySelector == SYMMETRIC) {
385 t_A(k, l, m) = t_diff_Rr(i, l, m) * t_approx_P(i, k) +
386 t_diff_Rr(i, k, m) * t_approx_P(i, l);
387 t_A(k, l, m) /= 2.;
389 t_B(k, l, m) = t_diff_Rl(i, l, m) * t_approx_P(i, k) +
390 t_diff_Rl(i, k, m) * t_approx_P(i, l);
391 t_B(k, l, m) /= 2.;
392
393 t_approx_P_adjoint_log_du_domega(m, L) =
394 half_r * (t_A(k, l, m) *
395 (t_Ldiff_u(k, l, L) + t_Ldiff_u(k, l, L)) / 2) +
396 half_l * (t_B(k, l, m) *
397 (t_Ldiff_u(k, l, L) + t_Ldiff_u(k, l, L)) / 2);
398 } else {
400 t_A(k, l, m) = t_diff_R(i, l, m) * t_approx_P(i, k);
401 t_approx_P_adjoint_log_du_domega(m, L) =
402 t_A(k, l, m) * t_Ldiff_u(k, l, L);
403 }
404
405 t_levi_kirchhoff_dstreach(m, L) =
406 half_r *
407 (t_diff_Rr(i, l, m) * (t_Ldiff_u(l, k, L) * t_approx_P(i, k)))
408
409 +
410
411 half_l *
412 (t_diff_Rl(i, l, m) * (t_Ldiff_u(l, k, L) * t_approx_P(i, k)));
413
414 t_levi_kirchhoff_dP(m, i, k) =
415 half_r * t_diff_Rr(i, l, m) * (t_u(l, k))
416
417 +
418
419 half_l * t_diff_Rl(i, l, m) * (t_u(l, k));
420
421 t_levi_kirchhoff_domega(m, n) =
422 half_r *
423 (t_diff_diff_Rr(i, l, m, n) * (t_u(l, k) * t_approx_P(i, k)) +
424 t_diff_diff_Rr(i, k, m, n) * (t_u(l, k) * t_approx_P(i, l)))
425
426 +
427
428 half_l *
429 (t_diff_diff_Rl(i, l, m, n) * (t_u(l, k) * t_approx_P(i, k)) +
430 t_diff_diff_Rl(i, k, m, n) * (t_u(l, k) * t_approx_P(i, l)));
431 t_levi_kirchhoff_domega(m, n) /= 2.;
432 }
433
434 next();
435 }
436
438 };
439
440 auto large_loop = [&]() {
442
444 case LARGE_ROT:
445 break;
446 case SMALL_ROT:
447 break;
448 default:
449 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
450 "rotSelector should be large");
451 };
452
453 for (int gg = 0; gg != nb_integration_pts; ++gg) {
454
456
460 t_h1(i, j) = t_kd(i, j);
461 break;
462 case LARGE_ROT:
463 t_h1(i, j) = t_grad_h1(i, j) + t_kd(i, j);
464 break;
465 default:
466 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
467 "gradApproximator not handled");
468 };
469
470 // calculate streach
471 auto t_Ldiff_u = calculate_log_stretch();
472 // calculate total stretch
473 auto [t_R_h1, t_inv_u_h1] = calculate_total_stretch(t_h1);
474
476 t_h_u(l, k) = t_u(l, o) * t_h1(o, k);
478 t_Ldiff_h_u(l, k, L) = t_Ldiff_u(l, o, L) * t_h1(o, k);
479
484
486
487 // rotation
489 case LARGE_ROT:
490 t_R(i, j) = LieGroups::SO3::exp(t_omega, t_omega.l2())(i, j);
491 t_diff_R(i, j, k) =
492 LieGroups::SO3::diffExp(t_omega, t_omega.l2())(i, j, k);
493 // left
494 t_diff_Rr(i, j, l) = t_R(i, k) * levi_civita(k, j, l);
495 t_diff_diff_Rr(i, j, l, m) = t_diff_R(i, k, m) * levi_civita(k, j, l);
496 // right
497 t_diff_Rl(i, j, l) = levi_civita(i, k, l) * t_R(k, j);
498 t_diff_diff_Rl(i, j, l, m) = levi_civita(i, k, l) * t_diff_R(k, j, m);
499 break;
500 case SMALL_ROT:
501 t_R(i, k) = t_kd(i, k) + levi_civita(i, k, l) * t_omega(l);
502 t_diff_R(i, j, k) = levi_civita(i, j, k);
503 // left
504 t_diff_Rr(i, j, l) = levi_civita(i, j, l);
505 t_diff_diff_Rr(i, j, l, m) = 0;
506 // right
507 t_diff_Rl(i, j, l) = levi_civita(i, j, l);
508 t_diff_diff_Rl(i, j, l, m) = 0;
509 break;
510
511 default:
512 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
513 "rotationSelector not handled");
514 }
515
516 constexpr double half_r = 1 / 2.;
517 constexpr double half_l = 1 / 2.;
518
519 // calculate gradient
520 t_h(i, k) = t_R(i, l) * t_h_u(l, k);
521
522 // Adjoint stress
523 t_approx_P_adjoint__dstretch(l, o) =
524 (t_R(i, l) * t_approx_P(i, k)) * t_h1(o, k);
525 t_approx_P_adjoint_log_du(L) =
526 t_approx_P_adjoint__dstretch(l, o) * t_Ldiff_u(l, o, L);
527
528 // Kirchhoff stress
529 t_levi_kirchhoff(m) =
530
531 half_r * ((t_diff_Rr(i, l, m) * (t_h_u(l, k)) * t_approx_P(i, k)))
532
533 +
534
535 half_l * ((t_diff_Rl(i, l, m) * (t_h_u(l, k)) * t_approx_P(i, k)));
536
538
539 if (EshelbianCore::symmetrySelector == SYMMETRIC) {
540 t_h_domega(i, k, m) = half_r * (t_diff_Rr(i, l, m) * t_h_u(l, k))
541
542 +
543
544 half_l * (t_diff_Rl(i, l, m) * t_h_u(l, k));
545 } else {
546 t_h_domega(i, k, m) = t_diff_R(i, l, m) * t_h_u(l, k);
547 }
548
549 t_h_dlog_u(i, k, L) = t_R(i, l) * t_Ldiff_h_u(l, k, L);
550
551 t_approx_P_adjoint_log_du_dP(i, k, L) =
552 t_R(i, l) * t_Ldiff_h_u(l, k, L);
553
554 if (EshelbianCore::symmetrySelector == SYMMETRIC) {
556 t_A(m, L, i, k) = t_diff_Rr(i, l, m) * t_Ldiff_h_u(l, k, L);
558 t_B(m, L, i, k) = t_diff_Rl(i, l, m) * t_Ldiff_h_u(l, k, L);
559
560 t_approx_P_adjoint_log_du_domega(m, L) =
561 half_r * (t_A(m, L, i, k) * t_approx_P(i, k))
562
563 +
564
565 half_l * (t_B(m, L, i, k) * t_approx_P(i, k));
566 } else {
568 t_A(m, L, i, k) = t_diff_R(i, l, m) * t_Ldiff_h_u(l, k, L);
569 t_approx_P_adjoint_log_du_domega(m, L) =
570 t_A(m, L, i, k) * t_approx_P(i, k);
571 }
572
573 t_levi_kirchhoff_dstreach(m, L) =
574 half_r *
575 (t_diff_Rr(i, l, m) * (t_Ldiff_h_u(l, k, L) * t_approx_P(i, k)))
576
577 +
578
579 half_l * (t_diff_Rl(i, l, m) *
580 (t_Ldiff_h_u(l, k, L) * t_approx_P(i, k)));
581
582 t_levi_kirchhoff_dP(m, i, k) =
583
584 half_r * (t_diff_Rr(i, l, m) * t_h_u(l, k))
585
586 +
587
588 half_l * (t_diff_Rl(i, l, m) * t_h_u(l, k));
589
590 t_levi_kirchhoff_domega(m, n) =
591 half_r *
592 (t_diff_diff_Rr(i, l, m, n) * (t_h_u(l, k) * t_approx_P(i, k)))
593
594 +
595
596 half_l *
597 (t_diff_diff_Rl(i, l, m, n) * (t_h_u(l, k) * t_approx_P(i, k)));
598 }
599
600 next();
601 }
602
604 };
605
606 auto moderate_loop = [&]() {
608
610 case LARGE_ROT:
611 break;
612 case SMALL_ROT:
613 break;
614 default:
615 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
616 "rotSelector should be large");
617 };
618
619 for (int gg = 0; gg != nb_integration_pts; ++gg) {
620
622
625 case MODERATE_ROT:
626 t_h1(i, j) = t_grad_h1(i, j) + t_kd(i, j);
627 break;
628 default:
629 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
630 "gradApproximator not handled");
631 };
632
633 // calculate streach
634 auto t_Ldiff_u = calculate_log_stretch();
635 // calculate total stretch
636 auto [t_R_h1, t_inv_u_h1] = calculate_total_stretch(t_h1);
637
639 t_h_u(l, k) = (t_symm_kd(l, o) + t_log_u(l, o)) * t_h1(o, k);
641 t_L_h(l, k, L) = t_L(l, o, L) * t_h1(o, k);
642
647
649
650 // rotation
652 case LARGE_ROT:
653 t_R(i, j) = LieGroups::SO3::exp(t_omega, t_omega.l2())(i, j);
654 t_diff_R(i, j, k) =
655 LieGroups::SO3::diffExp(t_omega, t_omega.l2())(i, j, k);
656 // left
657 t_diff_Rr(i, j, l) = t_R(i, k) * levi_civita(k, j, l);
658 t_diff_diff_Rr(i, j, l, m) = t_diff_R(i, k, m) * levi_civita(k, j, l);
659 // right
660 t_diff_Rl(i, j, l) = levi_civita(i, k, l) * t_R(k, j);
661 t_diff_diff_Rl(i, j, l, m) = levi_civita(i, k, l) * t_diff_R(k, j, m);
662 break;
663 case SMALL_ROT:
664 t_R(i, k) = t_kd(i, k) + levi_civita(i, k, l) * t_omega(l);
665 t_diff_R(i, j, l) = levi_civita(i, j, l);
666 // left
667 t_diff_Rr(i, j, l) = levi_civita(i, j, l);
668 t_diff_diff_Rr(i, j, l, m) = 0;
669 // right
670 t_diff_Rl(i, j, l) = levi_civita(i, j, l);
671 t_diff_diff_Rl(i, j, l, m) = 0;
672 break;
673
674 default:
675 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
676 "rotationSelector not handled");
677 }
678
679 constexpr double half_r = 1 / 2.;
680 constexpr double half_l = 1 / 2.;
681
682 // calculate gradient
683 t_h(i, k) = t_R(i, l) * t_h_u(l, k);
684
685 // Adjoint stress
686 t_approx_P_adjoint__dstretch(l, o) =
687 (t_R(i, l) * t_approx_P(i, k)) * t_h1(o, k);
688
689 t_approx_P_adjoint_log_du(L) =
690 t_approx_P_adjoint__dstretch(l, o) * t_L(l, o, L);
691
692 // Kirchhoff stress
693 t_levi_kirchhoff(m) =
694
695 half_r * ((t_diff_Rr(i, l, m) * (t_h_u(l, k)) * t_approx_P(i, k)))
696
697 +
698
699 half_l * ((t_diff_Rl(i, l, m) * (t_h_u(l, k)) * t_approx_P(i, k)));
700
702
703 if (EshelbianCore::symmetrySelector == SYMMETRIC) {
704 t_h_domega(i, k, m) = half_r * (t_diff_Rr(i, l, m) * t_h_u(l, k))
705
706 +
707
708 half_l * (t_diff_Rl(i, l, m) * t_h_u(l, k));
709 } else {
710 t_h_domega(i, k, m) = t_diff_R(i, l, m) * t_h_u(l, k);
711 }
712
713 t_h_dlog_u(i, k, L) = t_R(i, l) * t_L_h(l, k, L);
714
715 t_approx_P_adjoint_log_du_dP(i, k, L) = t_R(i, l) * t_L_h(l, k, L);
716
717 if (EshelbianCore::symmetrySelector == SYMMETRIC) {
719 t_A(m, L, i, k) = t_diff_Rr(i, l, m) * t_L_h(l, k, L);
721 t_B(m, L, i, k) = t_diff_Rl(i, l, m) * t_L_h(l, k, L);
722 t_approx_P_adjoint_log_du_domega(m, L) =
723 half_r * (t_A(m, L, i, k) * t_approx_P(i, k))
724
725 +
726
727 half_l * (t_B(m, L, i, k) * t_approx_P(i, k));
728 } else {
730 t_A(m, L, i, k) = t_diff_R(i, l, m) * t_L_h(l, k, L);
731 t_approx_P_adjoint_log_du_domega(m, L) =
732 t_A(m, L, i, k) * t_approx_P(i, k);
733 }
734
735 t_levi_kirchhoff_dstreach(m, L) =
736 half_r * (t_diff_Rr(i, l, m) * (t_L_h(l, k, L) * t_approx_P(i, k)))
737
738 +
739
740 half_l * (t_diff_Rl(i, l, m) * (t_L_h(l, k, L) * t_approx_P(i, k)));
741
742 t_levi_kirchhoff_dP(m, i, k) =
743
744 half_r * (t_diff_Rr(i, l, m) * t_h_u(l, k))
745
746 +
747
748 half_l * (t_diff_Rl(i, l, m) * t_h_u(l, k));
749
750 t_levi_kirchhoff_domega(m, n) =
751 half_r *
752 (t_diff_diff_Rr(i, l, m, n) * (t_h_u(l, k) * t_approx_P(i, k)))
753
754 +
755
756 half_l *
757 (t_diff_diff_Rl(i, l, m, n) * (t_h_u(l, k) * t_approx_P(i, k)));
758 }
759
760 next();
761 }
762
764 };
765
766 auto small_loop = [&]() {
769 case SMALL_ROT:
770 break;
771 default:
772 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
773 "rotSelector should be small");
774 };
775
776 for (int gg = 0; gg != nb_integration_pts; ++gg) {
777
780 case SMALL_ROT:
781 t_h1(i, j) = t_kd(i, j);
782 break;
783 default:
784 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
785 "gradApproximator not handled");
786 };
787
788 // calculate streach
790
791 if (EshelbianCore::stretchSelector > LINEAR) {
792 t_Ldiff_u(i, j, L) = calculate_log_stretch()(i, j, L);
793 } else {
794 t_u(i, j) = t_symm_kd(i, j) + t_log_u(i, j);
795 t_Ldiff_u(i, j, L) = t_L(i, j, L);
796 }
797 t_log_u2_h1(i, j) = 0;
798 t_log_stretch_total(i, j) = t_log_u(i, j);
799
801 t_h(i, j) = levi_civita(i, j, k) * t_omega(k) + t_u(i, j);
802
803 t_h_domega(i, j, k) = levi_civita(i, j, k);
804 t_h_dlog_u(i, j, L) = t_Ldiff_u(i, j, L);
805
806 // Adjoint stress
807 t_approx_P_adjoint__dstretch(i, j) = t_approx_P(i, j);
808 t_approx_P_adjoint_log_du(L) =
809 t_approx_P_adjoint__dstretch(i, j) * t_Ldiff_u(i, j, L);
810 t_approx_P_adjoint_log_du_dP(i, j, L) = t_Ldiff_u(i, j, L);
811 t_approx_P_adjoint_log_du_domega(m, L) = 0;
812
813 // Kirchhoff stress
814 t_levi_kirchhoff(k) = levi_civita(i, j, k) * t_approx_P(i, j);
815 t_levi_kirchhoff_dstreach(m, L) = 0;
816 t_levi_kirchhoff_dP(k, i, j) = levi_civita(i, j, k);
817 t_levi_kirchhoff_domega(m, n) = 0;
818
819 next();
820 }
821
823 };
824
827 CHKERR no_h1_loop();
828 break;
829 case LARGE_ROT:
830 CHKERR large_loop();
832 break;
833 case MODERATE_ROT:
834 CHKERR moderate_loop();
836 break;
837 case SMALL_ROT:
838 CHKERR small_loop();
840 break;
841 default:
842 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
843 "gradApproximator not handled");
844 break;
845 };
846
848}
#define FTENSOR_INDEX(DIM, I)
constexpr int SPACE_DIM
[Define dimension]
Kronecker Delta class symmetric.
Kronecker Delta class.
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
@ MOFEM_DATA_INCONSISTENCY
Definition definitions.h:31
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
constexpr auto t_kd
#define MOFEM_LOG(channel, severity)
Log.
FTensor::Index< 'i', SPACE_DIM > i
const double n
refractive index of diffusive medium
MoFEM::TsCtx * ts_ctx
FTensor::Index< 'l', 3 > l
FTensor::Index< 'j', 3 > j
FTensor::Index< 'k', 3 > k
auto getMat(A &&t_val, B &&t_vec, Fun< double > f)
Get the Mat object.
auto getDiffMat(A &&t_val, B &&t_vec, Fun< double > f, Fun< double > d_f, const int nb)
Get the Diff Mat object.
constexpr std::enable_if<(Dim0<=2 &&Dim1<=2), Tensor2_Expr< Levi_Civita< T >, T, Dim0, Dim1, i, j > >::type levi_civita(const Index< i, Dim0 > &, const Index< j, Dim1 > &)
levi_civita functions to make for easy adhoc use
auto sort_eigen_vals(FTensor::Tensor1< double, DIM > &eig, FTensor::Tensor2< double, DIM, DIM > &eigen_vec)
Definition HenckyOps.hpp:41
MoFEMErrorCode computeEigenValuesSymmetric(const MatrixDouble &mat, VectorDouble &eig, MatrixDouble &eigen_vec)
compute eigenvalues of a symmetric matrix using lapack dsyev
auto symm_L_tensor(FTensor::Number< DIM >)
FTensor::Index< 'm', 3 > m
static enum StretchSelector stretchSelector
static enum RotSelector rotSelector
static enum RotSelector gradApproximator
static enum SymmetrySelector symmetrySelector
static boost::function< double(const double)> f
static boost::function< double(const double)> d_f
static boost::function< double(const double)> inv_f
static auto diffExp(A &&t_w_vee, B &&theta)
Definition Lie.hpp:79
static auto exp(A &&t_w_vee, B &&theta)
Definition Lie.hpp:48
MatrixDouble & getGaussPts()
matrix of integration (Gauss) points for Volume Element
@ CTX_TSSETIJACOBIAN
Setting up implicit Jacobian.
constexpr auto size_symm
Definition plastic.cpp:42

Member Data Documentation

◆ alphaOmega

double OpCalculateRotationAndSpatialGradient::alphaOmega
private

Definition at line 293 of file EshelbianOperators.hpp.

◆ dataAtPts

boost::shared_ptr<DataAtIntegrationPts> OpCalculateRotationAndSpatialGradient::dataAtPts
private

data at integration pts

Definition at line 292 of file EshelbianOperators.hpp.


The documentation for this struct was generated from the following files: