v0.16.3
Loading...
Searching...
No Matches
L2Rotation.hpp
Go to the documentation of this file.
1#ifndef ESHELBIAN_L2_ROTATION_HPP
2#define ESHELBIAN_L2_ROTATION_HPP
3
4namespace EshelbianPlasticity {
5
6/** Decompose a tetrahedral L2 vector into its constant and higher modes.
7 * The core evaluator owns total-field interpolation and vector/DM lookup.
8 * Used before rotation kinematics; the same linear split applies to directions.
9 */
13 using DL = DataLayoutTraits<DataLayout::GaussByCoeffs>;
14
15 OpCalculateL2RotationValues(const std::string &field, MatrixPtr total,
16 MatrixPtr constant, MatrixPtr higher,
17 SmartPetscObj<Vec> vector = {})
18 : OpBase(field, std::move(total), vector, MBTET),
19 constantPtr(std::move(constant)), higherPtr(std::move(higher)) {}
20
21 MoFEMErrorCode doWork(int side, EntityType type, EntData &data) override {
24 if (type != MBTET)
26 const int points = getGaussPts().size2();
27 auto a = MatrixSizeHelper<GetFTensor1FromMatType<3, -1, DL>, DL>::size(
28 *constantPtr, points)();
29 auto q = MatrixSizeHelper<GetFTensor1FromMatType<3, -1, DL>, DL>::size(
30 *higherPtr, points)();
31 constantPtr->clear();
32 higherPtr->clear();
33 const int dofs = data.getFieldData().size();
34 if (!dofs || !points)
36 if (dofs < 3 || dofs % 3)
37 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
38 "L2 rotation requires a complete constant vector block");
40 FTENSOR_INDEX(3, i);
41 if (dataVec) {
42 // The core base retains the evaluated vector coefficients after restoring
43 // field data. Reuse them so constant and total values share one lookup.
44 auto coefficients = getFTensor1FromPtr<3>(&dotVector[0]);
45 c0(i) = coefficients(i);
46 } else {
47 auto coefficients = data.getFTensor1FieldData<3>();
48 c0(i) = coefficients(i);
49 }
50 const double phi0 = data.getN()(0, 0);
51#ifndef NDEBUG
52 if (!std::isfinite(phi0) || phi0 == 0.)
53 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
54 "Invalid constant L2 rotation basis");
55 for (int gg = 0; gg != points; ++gg)
56 if (std::abs(data.getN()(gg, 0) - phi0) > 1.e-13)
57 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
58 "First L2 rotation basis must be constant");
59#endif
60 auto total = MatrixSizeHelper<GetFTensor1FromMatType<3, -1, DL>, DL>::get(
61 *dataPtr, points)();
62 for (int gg = 0; gg != points; ++gg) {
63 a(i) = phi0 * c0(i);
64 q(i) = total(i) - a(i);
65 ++a;
66 ++q;
67 ++total;
68 }
70 }
71
72private:
74};
75
76/** Assemble a rotation covector with different constant/higher test modes.
77 * Used for tangent-state and incremental-adjoint loads; the form base owns
78 * local sizing and global assembly, including ghost contribution handling.
79 */
80template <AssemblyType Assembly>
82 : FormsIntegrators<VolUserDataOperator>::template Assembly<
83 Assembly>::OpBase {
84 using OpBase = typename FormsIntegrators<
85 VolUserDataOperator>::template Assembly<Assembly>::OpBase;
86 using DL = DataLayoutTraits<DataLayout::GaussByCoeffs>;
87 OpAssembleL2RotationLoad(const std::string &field, MatrixPtr constant,
88 MatrixPtr higher)
89 : OpBase(field, VolUserDataOperator::OPROW),
90 constantPtr(std::move(constant)), higherPtr(std::move(higher)) {}
91 MoFEMErrorCode iNtegrate(EntData &row_data) override {
93 FTENSOR_INDEX(3, i);
94 using View = GetFTensor1FromMatType<3, -1, DL>;
95 auto values = std::array{MatrixSizeHelper<View, DL>::get(
97 MatrixSizeHelper<View, DL>::get(
99 auto basis = row_data.getFTensor0N();
100 auto weight = OpBase::getFTensor0IntegrationWeight();
101 for (int gg = 0; gg != OpBase::nbIntegrationPts; ++gg) {
102 const double alpha = weight * OpBase::getMeasure();
103 auto f = OpBase::template getNf<3>();
104 int rr = 0;
105 for (; rr != OpBase::nbRows / 3; ++rr) {
106 f(i) += (alpha * basis) * values[rr ? 1 : 0](i);
107 ++f;
108 ++basis;
109 }
110 for (; rr != OpBase::nbRowBaseFunctions; ++rr)
111 ++basis;
112 ++values[0];
113 ++values[1];
114 ++weight;
115 }
117 }
119};
120
121} // namespace EshelbianPlasticity
122#endif
std::string type
boost::shared_ptr< DataAtIntegrationPts > data
SmartPetscObj< Vec > values
PetscInt size
#define FTENSOR_INDEX(DIM, I)
constexpr double a
#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.
FTensor::Index< 'i', SPACE_DIM > i
boost::shared_ptr< MatrixDouble > MatrixPtr
double q
typename FormsIntegrators< VolUserDataOperator >::template Assembly< Assembly >::OpBase OpBase
OpAssembleL2RotationLoad(const std::string &field, MatrixPtr constant, MatrixPtr higher)
MoFEMErrorCode iNtegrate(EntData &row_data) override
DataLayoutTraits< DataLayout::GaussByCoeffs > DL
OpCalculateL2RotationValues(const std::string &field, MatrixPtr total, MatrixPtr constant, MatrixPtr higher, SmartPetscObj< Vec > vector={})
MoFEMErrorCode doWork(int side, EntityType type, EntData &data) override
Operator for linear form, usually to calculate values on right hand side.
DataLayoutTraits< DataLayout::GaussByCoeffs > DL
Data on single entity (This is passed as argument to DataOperator::doWork)
FTensor::Tensor0< FTensor::PackPtr< double *, 1 > > getFTensor0N(const FieldApproximationBase base)
Get base function as Tensor0.
MatrixDouble & getGaussPts()
matrix of integration (Gauss) points for Volume Element
int nbRows
number of dofs on rows
int nbIntegrationPts
number of integration points
int nbRowBaseFunctions
number or row base functions
Calculate field values for tensor field rank 1, i.e. vector field.
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
calculate values of vector field at integration points