184 {
186 (void)side;
188 (void)data;
189
190 auto mat_ops_data =
physicsPtr->matOpsDataPtr;
191 if (!mat_ops_data)
193 "Mat core material data is not allocated");
194
195 const int nb_integration_pts = getGaussPts().size2();
196 if (nb_integration_pts <= 0)
198 "Mat core energy operator has no integration points");
199
200 auto mat_grad_ptr = mat_ops_data->getCommonDataPtr("grad");
201 auto mat_F_ptr = mat_ops_data->getActiveDataPtr("F");
202 auto mat_energy_ptr =
physicsPtr->getEnergyDensityPtr();
203 if (!mat_grad_ptr || !mat_F_ptr || !mat_energy_ptr)
205 "Mat core energy evaluation has incomplete material data");
206 if (mat_grad_ptr->size1() != nb_integration_pts ||
209 "Mat core energy gradient data has size %zu x %zu; expected %d "
210 "x %d",
211 mat_grad_ptr->size1(), mat_grad_ptr->size2(), nb_integration_pts,
213
215 mat_energy_ptr->resize(1, 1, false);
216
217 const auto get_material_tag = [&]() {
219 for (
const auto &tag_range_pair : *
physicsPtr->tagVsRangePtr) {
220 if (tag_range_pair.second.find(getFEEntityHandle()) !=
221 tag_range_pair.second.end())
222 return tag_range_pair.first;
223 }
224 }
225#ifndef NDEBUG
228 "ADOL-C tag not found " +
230#endif
232 };
233
234 const int material_tag = get_material_tag();
235 auto *fe_ptr =
const_cast<FEMethod *
>(getFEMethod());
236 if (!fe_ptr)
238 "Mat core energy operator has no finite-element method");
239 const EntityHandle ent = fe_ptr->getFEEntityHandle();
240 if (!ent)
242 "Mat core energy operator has no finite-element entity");
243
244 using GaussLayout = DataLayoutTraits<DataLayout::GaussByCoeffs>;
245 auto get_grad_at_pts = MatrixSizeHelper<
247 GaussLayout>::get(*mat_grad_ptr, nb_integration_pts);
248
251 auto t_grad_at_pts = get_grad_at_pts();
252 dataAtPts->energyAtPts.resize(nb_integration_pts,
false);
253 auto t_energy_at_pts = getFTensor0FromVec(
dataAtPts->energyAtPts);
254
255 for (int gg = 0; gg != nb_integration_pts; ++gg) {
256 auto t_F =
257 getFTensor2FromPtr<SPACE_DIM, SPACE_DIM>(mat_F_ptr->data().data());
258 t_F(
i,
J) = t_grad_at_pts(
i,
J);
261
263 const double energy_density = t_energy;
264 if (!std::isfinite(energy_density))
265 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_FP,
266 "Mat core returned non-finite energy density at point %d on "
267 "entity %lu",
268 gg, static_cast<unsigned long>(ent));
269 t_energy_at_pts = energy_density;
270
271 ++t_grad_at_pts;
272 ++t_energy_at_pts;
273 }
274
277 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_FP,
278 "Mat core accumulated energy is non-finite before integration");
279 const double element_measure = getMeasure();
280 if (!std::isfinite(element_measure) || element_measure < 0.)
281 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_FP,
282 "Mat core element measure is invalid: %.16g", element_measure);
283
284 auto t_w = getFTensor0IntegrationWeight();
285 auto t_energy_at_pts_integral = getFTensor0FromVec(
dataAtPts->energyAtPts);
286 auto t_plasticF =
dataAtPts->getFTensorPlasticF(nb_integration_pts);
287 double local_energy = 0;
288 for (int gg = 0; gg != nb_integration_pts; ++gg) {
289 const double weight = t_w;
290 const double energy_density = t_energy_at_pts_integral;
292 if (!std::isfinite(weight) || !std::isfinite(det_plasticF) ||
293 det_plasticF <= 0.)
294 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_FP,
295 "Invalid Mat core energy quadrature data at point %d on "
296 "entity %lu",
297 gg, static_cast<unsigned long>(ent));
298 local_energy += weight * det_plasticF * energy_density;
299
300 ++t_w;
301 ++t_energy_at_pts_integral;
302 ++t_plasticF;
303 }
304
305 const double element_energy = element_measure * local_energy;
306 const double accumulated_energy =
308 if (!std::isfinite(element_energy) || !std::isfinite(accumulated_energy))
309 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_FP,
310 "Mat core integrated energy is non-finite on entity %lu",
311 static_cast<unsigned long>(ent));
313 }
314
316}
#define FTENSOR_INDEX(DIM, I)
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
@ MOFEM_OPERATION_UNSUCCESSFUL
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
FTensor::Index< 'i', SPACE_DIM > i
FTensor::Index< 'J', DIM1 > J
auto getFTensor0FromMat(M &data)
Get tensor rank 0 (scalar) form data vector.
decltype(GetFTensor2FromMatImpl< Tensor_Dim0, Tensor_Dim1, S, DL, M >::get(std::declval< M & >(), 0, 0)) GetFTensor2FromMatType
MoFEMErrorCode determinantTensor3by3(T1 &t, T2 &det)
Calculate determinant 3 by 3.