Caluclate face material force and normal pressure at gauss points.
Reconstruct the full gradient \(U=\nabla u\) on a surface from the symmetric part and the surface gradient.
Procedure (pointwise on S): 1) Normalize the normal \(\mathbf n=\mathbf N/\|\mathbf N\|\). 2) Form the residual \(R=\varepsilon-\operatorname{sym}(u^\Gamma)\), where \(\operatorname{sym}(A)=\tfrac12(A+A^\top)\). 3) Recover the normal directional derivative (a vector) \(\mathbf v=\partial_{\mathbf n}u=2R\mathbf n-(\mathbf n^\top R\,\mathbf
n)\,\mathbf n\). 4) Assemble the full gradient \(U = u^\Gamma + \mathbf
v\otimes \mathbf n\).
4212 {
4214
4227
4228 const auto nb_gauss_pts = getGaussPts().size2();
4230 dataAtPts->faceMaterialForceAtPts, nb_gauss_pts);
4231 dataAtPts->normalPressureAtPts.resize(nb_gauss_pts,
false);
4232 if (getNinTheLoop() == 0) {
4233 dataAtPts->faceMaterialForceAtPts.clear();
4235 }
4236 auto loop_size = getLoopSize();
4237 if (loop_size == 1) {
4238 auto numebered_fe_ptr = getSidePtrFE()->numeredEntFiniteElementPtr;
4239 auto pstatus = numebered_fe_ptr->getPStatus();
4240 if (pstatus & (PSTATUS_SHARED | PSTATUS_MULTISHARED)) {
4241 loop_size = 2;
4242 }
4243 }
4244
4246
4247 auto t_normal = getFTensor1NormalsAtGaussPts();
4248 auto t_T =
dataAtPts->getFTensorFaceMaterialForce(
4249 nb_gauss_pts);
4250 auto t_p =
4252 auto t_P =
dataAtPts->getFTensorApproxP(nb_gauss_pts);
4253 auto t_u_gamma =
dataAtPts->getFTensorSmallHybridDisp(nb_gauss_pts);
4254 auto t_grad_u_gamma =
dataAtPts->getFTensorGradHybridDisp(nb_gauss_pts);
4255 auto t_strain =
dataAtPts->getFTensorLogStretch(nb_gauss_pts);
4256 auto t_omega =
dataAtPts->getFTensorRotAxis(nb_gauss_pts);
4257
4263
4264 auto next = [&]() {
4265 ++t_normal;
4266 ++t_P;
4267
4268 ++t_omega;
4269 ++t_u_gamma;
4270 ++t_grad_u_gamma;
4271 ++t_strain;
4272 ++t_T;
4273 ++t_p;
4274 };
4275
4278 for (auto gg = 0; gg != getGaussPts().size2(); ++gg) {
4279 t_N(
I) = t_normal(
I);
4281
4284 t_grad_u(
i,
j) = t_R(
i,
j) + t_strain(
i,
j);
4285
4286 t_T(
I) += t_N(
J) * (t_grad_u(
i,
I) * t_P(
i,
J)) / loop_size;
4287
4288
4289 t_T(
I) -= t_N(
I) * ((t_strain(
i,
K) * t_P(
i,
K)) / 2.) / loop_size;
4290
4292 (t_N(
J) * ((
t_kd(
i,
I) + t_grad_u_gamma(
i,
I)) * t_P(
i,
J))) /
4293 loop_size;
4294
4295 next();
4296 }
4297 break;
4299 for (auto gg = 0; gg != getGaussPts().size2(); ++gg) {
4300
4301
4302 t_N(
I) = t_normal(
I);
4304
4305
4307 t_strain(
i,
j) - 0.5 * (t_grad_u_gamma(
i,
j) + t_grad_u_gamma(
j,
i));
4308
4309
4311 t_grad_u_gamma(
i,
J) +
4312 (2 * t_R(
i,
K) * t_N(
K) - (t_R(
k,
L) * t_N(
k) * t_N(
L)) * t_N(
i)) *
4314
4315 t_T(
I) += t_N(
J) * (t_grad_u(
i,
I) * t_P(
i,
J)) / loop_size;
4316
4317
4318 t_T(
I) -= t_N(
I) * ((t_strain(
i,
K) * t_P(
i,
K)) / 2.) / loop_size;
4319
4320
4322 (t_N(
J) * ((
t_kd(
i,
I) + t_grad_u_gamma(
i,
I)) * t_P(
i,
J))) /
4323 loop_size;
4324
4325 next();
4326 }
4327 break;
4328
4329 default:
4331 "Grffith energy release "
4332 "selector not implemented");
4333 };
4334
4335#ifndef NDEBUG
4336 auto side_fe_ptr = getSidePtrFE();
4337 auto side_fe_mi_ptr = side_fe_ptr->numeredEntFiniteElementPtr;
4338 auto pstatus = side_fe_mi_ptr->getPStatus();
4339 if (pstatus) {
4340 auto owner = side_fe_mi_ptr->getOwnerProc();
4342 << "OpFaceSideMaterialForce: owner proc is not 0, owner proc: " << owner
4343 << " " << getPtrFE()->mField.get_comm_rank() << " n in the loop "
4344 << getNinTheLoop() << " loop size " << getLoopSize();
4345 }
4346#endif
4347
4349}
#define FTENSOR_INDEX(DIM, I)
Kronecker Delta class symmetric.
Tensor1< T, Tensor_Dim > normalize()
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define MOFEM_LOG(channel, severity)
Log.
FTensor::Index< 'i', SPACE_DIM > i
const double n
refractive index of diffusive medium
FTensor::Index< 'J', DIM1 > J
FTensor::Index< 'l', 3 > l
FTensor::Index< 'j', 3 > j
FTensor::Index< 'k', 3 > k
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
DataLayoutTraits< DataLayout::GaussByCoeffs > DL
decltype(GetFTensor1FromMatImpl< Tensor_Dim, S, DL, M >::get(std::declval< M & >(), 0, 0)) GetFTensor1FromMatType
static auto getFTensor0FromVec(V &data)
Get tensor rank 0 (scalar) form data vector.
constexpr IntegrationType I
FTensor::Index< 'm', 3 > m
static enum EnergyReleaseSelector energyReleaseSelector