v0.16.3
Loading...
Searching...
No Matches
MatAxisymmetric.hpp
Go to the documentation of this file.
1#ifndef MAT_AXISYMMETRIC_HPP
2#define MAT_AXISYMMETRIC_HPP
3
4namespace MatOps {
5
9 boost::shared_ptr<MatrixDouble> disp_ptr,
10 boost::shared_ptr<MatrixDouble> grad_ptr,
11 boost::shared_ptr<MatrixDouble> axisymmetric_grad_ptr)
13 dispPtr(disp_ptr), gradPtr(grad_ptr),
14 axisymmetricGradPtr(axisymmetric_grad_ptr) {}
15
16 MoFEMErrorCode doWork(int, EntityType, EntData &) {
18 const int nb_gauss_pts = getGaussPts().size2();
20 auto t_disp = MatrixSizeHelper<GetFTensor1FromMatType<2, -1, DL>, DL>::get(
21 *dispPtr, nb_gauss_pts)();
22 auto t_grad =
24 *gradPtr, nb_gauss_pts)();
25 auto t_axisymmetric_grad =
27 *axisymmetricGradPtr, nb_gauss_pts)();
28 auto t_coords = getFTensor1CoordsAtGaussPts();
29 FTENSOR_INDEX(2, j);
30 FTENSOR_INDEX(2, I);
31 FTENSOR_INDEX(3, i);
32 FTENSOR_INDEX(3, J);
35 for (int gg = 0; gg != nb_gauss_pts; ++gg) {
36 const double radius = t_coords(0);
37 if (radius <= 0)
38 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
39 "Axisymmetric integration point is on or below the axis");
40 t_axisymmetric_grad(i, J) = 0;
41 t_axisymmetric_grad(j, I) = t_grad(j, I);
42 t_axisymmetric_grad(N2, N2) = t_disp(N0) / radius;
43 ++t_disp;
44 ++t_grad;
45 ++t_axisymmetric_grad;
46 ++t_coords;
47 }
49 }
50
51private:
52 boost::shared_ptr<MatrixDouble> dispPtr;
53 boost::shared_ptr<MatrixDouble> gradPtr;
54 boost::shared_ptr<MatrixDouble> axisymmetricGradPtr;
55};
56
58 boost::shared_ptr<MatrixDouble> inPlaneStress =
59 boost::make_shared<MatrixDouble>();
60 boost::shared_ptr<MatrixDouble> inPlaneTangent =
61 boost::make_shared<MatrixDouble>();
62};
63
67 boost::shared_ptr<MatrixDouble> stress_ptr,
68 boost::shared_ptr<AxisymmetricAssemblyData> data_ptr)
70 stressPtr(stress_ptr), dataPtr(data_ptr) {}
71
72 MoFEMErrorCode doWork(int, EntityType, EntData &) {
74 const int nb_gauss_pts = getGaussPts().size2();
76 auto t_stress =
78 *stressPtr, nb_gauss_pts)();
79 auto t_in_plane_stress =
81 *dataPtr->inPlaneStress, nb_gauss_pts)();
82 FTENSOR_INDEX(2, i);
83 FTENSOR_INDEX(2, J);
84 for (int gg = 0; gg != nb_gauss_pts; ++gg) {
85 t_in_plane_stress(i, J) = t_stress(i, J);
86 ++t_stress;
87 ++t_in_plane_stress;
88 }
90 }
91
92private:
93 boost::shared_ptr<MatrixDouble> stressPtr;
94 boost::shared_ptr<AxisymmetricAssemblyData> dataPtr;
95};
96
100 boost::shared_ptr<MatrixDouble> tangent_ptr,
101 boost::shared_ptr<AxisymmetricAssemblyData> data_ptr)
103 tangentPtr(tangent_ptr), dataPtr(data_ptr) {}
104
105 MoFEMErrorCode doWork(int, EntityType, EntData &) {
107 const int nb_gauss_pts = getGaussPts().size2();
109 auto t_tangent =
110 MatrixSizeHelper<GetFTensor4FromMatType<3, 3, 3, 3, -1, DL>, DL>::get(
111 *tangentPtr, nb_gauss_pts)();
112 auto t_in_plane_tangent =
113 MatrixSizeHelper<GetFTensor4FromMatType<2, 2, 2, 2, -1, DL>, DL>::size(
114 *dataPtr->inPlaneTangent, nb_gauss_pts)();
115 FTENSOR_INDEX(2, i);
116 FTENSOR_INDEX(2, J);
117 FTENSOR_INDEX(2, k);
118 FTENSOR_INDEX(2, L);
119 for (int gg = 0; gg != nb_gauss_pts; ++gg) {
120 t_in_plane_tangent(i, J, k, L) = t_tangent(i, J, k, L);
121 ++t_tangent;
122 ++t_in_plane_tangent;
123 }
125 }
126
127private:
128 boost::shared_ptr<MatrixDouble> tangentPtr;
129 boost::shared_ptr<AxisymmetricAssemblyData> dataPtr;
130};
131
132template <AssemblyType A, typename DomainEleOp>
134 typename FormsIntegrators<DomainEleOp>::template Assembly<A>::OpBase;
135
136template <AssemblyType A, typename DomainEleOp>
137struct OpAxisymmetricRhs : public OpAxisymmetricBase<A, DomainEleOp> {
139
140 OpAxisymmetricRhs(const std::string field_name,
141 boost::shared_ptr<MatrixDouble> full_stress_ptr)
143 fullStressPtr(full_stress_ptr) {}
144
145protected:
146 boost::shared_ptr<MatrixDouble> fullStressPtr;
147
148 MoFEMErrorCode iNtegrate(EntData &row_data) override {
151 auto t_full_stress =
154 auto t_w = OpBase::getFTensor0IntegrationWeight();
155 auto t_row_base = row_data.getFTensor0N();
158 for (int gg = 0; gg != OpBase::nbIntegrationPts; ++gg) {
159 auto t_nf = OpBase::template getNf<2>();
160 const double alpha = 2 * M_PI * t_w * OpBase::getMeasure();
161 int rr = 0;
162 for (; rr != OpBase::nbRows / 2; ++rr) {
163 t_nf(N0) += alpha * t_row_base * t_full_stress(N2, N2);
164 ++t_nf;
165 ++t_row_base;
166 }
167 for (; rr < OpBase::nbRowBaseFunctions; ++rr)
168 ++t_row_base;
169 ++t_full_stress;
170 ++t_w;
171 }
173 }
174};
175
176template <AssemblyType A, typename DomainEleOp>
177struct OpAxisymmetricLhs : public OpAxisymmetricBase<A, DomainEleOp> {
179
180 OpAxisymmetricLhs(const std::string field_name,
181 boost::shared_ptr<MatrixDouble> full_tangent_ptr)
183 fullTangentPtr(full_tangent_ptr) {}
184
185protected:
186 boost::shared_ptr<MatrixDouble> fullTangentPtr;
187
188 MoFEMErrorCode iNtegrate(EntData &row_data, EntData &col_data) override {
191 auto t_D =
192 MatrixSizeHelper<GetFTensor4FromMatType<3, 3, 3, 3, -1, DL>, DL>::get(
194 auto t_w = OpBase::getFTensor0IntegrationWeight();
195 auto t_coords = OpBase::getFTensor1CoordsAtGaussPts();
196 auto t_row_base = row_data.getFTensor0N();
197 auto t_row_diff = row_data.getFTensor1DiffN<2>();
198 FTENSOR_INDEX(3, i);
199 FTENSOR_INDEX(3, J);
200 FTENSOR_INDEX(3, k);
201 FTENSOR_INDEX(3, L);
202 FTENSOR_INDEX(2, j);
203 FTENSOR_INDEX(2, I);
204 FTENSOR_INDEX(2, l);
208 t_hoop(i, J) = 0;
209 t_hoop(N2, N2) = 1;
210 for (int gg = 0; gg != OpBase::nbIntegrationPts; ++gg) {
211 const double radius = t_coords(0);
212 const double alpha = 2 * M_PI * t_w * OpBase::getMeasure();
213 int rr = 0;
214 for (; rr != OpBase::nbRows / 2; ++rr) {
215 auto t_m = OpBase::template getLocMat<2>(2 * rr);
216 auto t_col_base = col_data.getFTensor0N(gg, 0);
217 auto t_col_diff = col_data.getFTensor1DiffN<2>(gg, 0);
218 for (int cc = 0; cc != OpBase::nbCols / 2; ++cc) {
219 t_m(j, N0) += alpha * t_col_base * t_row_diff(I) *
220 (t_D(j, I, k, L) * t_hoop(k, L));
221 t_m(N0, l) += alpha * t_row_base * t_hoop(i, J) *
222 (t_D(i, J, l, I) * t_col_diff(I));
223 t_m(N0, N0) += alpha * t_row_base * t_col_base / radius *
224 t_hoop(i, J) *
225 (t_D(i, J, k, L) * t_hoop(k, L));
226 ++t_m;
227 ++t_col_base;
228 ++t_col_diff;
229 }
230 ++t_row_base;
231 ++t_row_diff;
232 }
233 for (; rr < OpBase::nbRowBaseFunctions; ++rr) {
234 ++t_row_base;
235 ++t_row_diff;
236 }
237 ++t_D;
238 ++t_w;
239 ++t_coords;
240 }
242 }
243};
244
245} // namespace MatOps
246
247#endif // MAT_AXISYMMETRIC_HPP
#define FTENSOR_INDEX(DIM, I)
@ NOSPACE
Definition definitions.h:83
#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()
FTensor::Index< 'i', SPACE_DIM > i
FTensor::Index< 'J', DIM1 > J
Definition level_set.cpp:30
FTensor::Index< 'l', 3 > l
FTensor::Index< 'j', 3 > j
FTensor::Index< 'k', 3 > k
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
decltype(GetFTensor4FromMatImpl< Tensor_Dim0, Tensor_Dim1, Tensor_Dim2, Tensor_Dim3, S, DL, M >::get(std::declval< M & >(), 0, 0)) GetFTensor4FromMatType
decltype(GetFTensor1FromMatImpl< Tensor_Dim, S, DL, M >::get(std::declval< M & >(), 0, 0)) GetFTensor1FromMatType
decltype(GetFTensor2FromMatImpl< Tensor_Dim0, Tensor_Dim1, S, DL, M >::get(std::declval< M & >(), 0, 0)) GetFTensor2FromMatType
constexpr IntegrationType I
constexpr auto field_name
boost::shared_ptr< MatrixDouble > inPlaneStress
boost::shared_ptr< MatrixDouble > inPlaneTangent
OpAxisymmetricLhs(const std::string field_name, boost::shared_ptr< MatrixDouble > full_tangent_ptr)
OpAxisymmetricBase< A, DomainEleOp > OpBase
boost::shared_ptr< MatrixDouble > fullTangentPtr
MoFEMErrorCode iNtegrate(EntData &row_data, EntData &col_data) override
MoFEMErrorCode iNtegrate(EntData &row_data) override
OpAxisymmetricBase< A, DomainEleOp > OpBase
OpAxisymmetricRhs(const std::string field_name, boost::shared_ptr< MatrixDouble > full_stress_ptr)
boost::shared_ptr< MatrixDouble > fullStressPtr
boost::shared_ptr< MatrixDouble > dispPtr
boost::shared_ptr< MatrixDouble > gradPtr
MoFEMErrorCode doWork(int, EntityType, EntData &)
Operator for linear form, usually to calculate values on right hand side.
boost::shared_ptr< MatrixDouble > axisymmetricGradPtr
OpCalculateAxisymmetricGradient(boost::shared_ptr< MatrixDouble > disp_ptr, boost::shared_ptr< MatrixDouble > grad_ptr, boost::shared_ptr< MatrixDouble > axisymmetric_grad_ptr)
boost::shared_ptr< AxisymmetricAssemblyData > dataPtr
MoFEMErrorCode doWork(int, EntityType, EntData &)
Operator for linear form, usually to calculate values on right hand side.
OpCalculateAxisymmetricStress(boost::shared_ptr< MatrixDouble > stress_ptr, boost::shared_ptr< AxisymmetricAssemblyData > data_ptr)
boost::shared_ptr< MatrixDouble > stressPtr
MoFEMErrorCode doWork(int, EntityType, EntData &)
Operator for linear form, usually to calculate values on right hand side.
OpCalculateAxisymmetricTangent(boost::shared_ptr< MatrixDouble > tangent_ptr, boost::shared_ptr< AxisymmetricAssemblyData > data_ptr)
boost::shared_ptr< MatrixDouble > tangentPtr
boost::shared_ptr< AxisymmetricAssemblyData > dataPtr
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.
auto getFTensor1DiffN(const FieldApproximationBase base)
Get derivatives of base functions.
auto getFTensor1CoordsAtGaussPts()
Get coordinates at integration points assuming linear geometry.
@ OPSPACE
operator do Work is execute on space data
MatrixDouble & getGaussPts()
matrix of integration (Gauss) points for Volume Element
structure to get information from mofem into EntitiesFieldData
int nbRows
number of dofs on rows
int nbIntegrationPts
number of integration points
int nbCols
number if dof on column
int nbRowBaseFunctions
number or row base functions