v0.16.0
Loading...
Searching...
No Matches
NormsOperators.cpp
Go to the documentation of this file.
1/** \file NormsOperators.cpp
2
3\brief User data operators for calculating norms and differences between
4fields
5
6*/
7
8namespace MoFEM {
9
11 boost::shared_ptr<VectorDouble> data_ptr, SmartPetscObj<Vec> data_vec,
12 const int index, boost::shared_ptr<VectorDouble> diff_data_ptr,
13 boost::shared_ptr<Range> ent_ptr)
16 dataPtr(data_ptr), dataVec(data_vec), iNdex(index),
17 diffDataPtr(diff_data_ptr), entsPtr(ent_ptr) {
18 if (!dataPtr)
19 THROW_MESSAGE("Pointer is not set");
20 if (!diffDataPtr)
22}
23
27
28 // check if entity is in the range
29 if (entsPtr) {
30 if (entsPtr->find(this->getFEEntityHandle()) == entsPtr->end())
32 }
33
34 // calculate the difference between data pointers and save them in diffDataPtr
35 if (dataPtr != diffDataPtr)
37
38 // get number of integration points
39 const auto nb_integration_points = getGaussPts().size2();
40 // get element volume
41 const double vol = getMeasure();
42 // get integration weights
44 // get values
45 auto t_data = getFTensor0FromVec(*diffDataPtr);
46 // initialise double to store norm values
47 double norm_on_element = 0.;
48 // loop over integration points
49 for (int gg = 0; gg != nb_integration_points; gg++) {
50 // add to element norm
51 norm_on_element += t_w * t_data * t_data;
52 // move to another integration weight
53 ++t_w;
54 // move to another data values
55 ++t_data;
56 }
57 // scale with volume of the element
58 norm_on_element *= vol;
59 // add to dataVec at iNdex position
60 CHKERR VecSetValue(dataVec, iNdex, norm_on_element, ADD_VALUES);
61
63}
64
65template <int DIM>
67 boost::shared_ptr<MatrixDouble> data_ptr, SmartPetscObj<Vec> data_vec,
68 const int index, boost::shared_ptr<MatrixDouble> diff_data_ptr,
69 boost::shared_ptr<Range> ent_ptr)
72 dataPtr(data_ptr), dataVec(data_vec), iNdex(index),
73 diffDataPtr(diff_data_ptr), entsPtr(ent_ptr) {
74 if (!dataPtr)
75 THROW_MESSAGE("Pointer is not set");
76 if (!diffDataPtr)
78}
79
80template <int DIM>
85
86 // check if entity is in the range
87 if (entsPtr) {
88 if (entsPtr->find(this->getFEEntityHandle()) == entsPtr->end())
90 }
91
92 // calculate the difference between data pointers and save them in diffDataPtr
93 if (dataPtr != diffDataPtr)
94 *diffDataPtr -= *dataPtr;
95
96 // Declare FTensor index
97 FTensor::Index<'i', DIM> i;
98 // get number of integration points
99 const auto nb_integration_points = getGaussPts().size2();
100 // get element volume
101 const double vol = getMeasure();
102 // get integration weights
103 auto t_w = getFTensor0IntegrationWeight();
104 // get vector values
105#ifndef NDEBUG
106 if (diffDataPtr->size2() != DIM)
107 THROW_MESSAGE("OpCalcNormL2Tensor1: wrong number of matrix columns");
108#endif
109 auto t_data = getFTensor1FromPtr<DIM, DIM>(diffDataPtr->data().data());
110 // initialise double to store norm values
111 double norm_on_element = 0.;
112 // loop over integration points
113 for (int gg = 0; gg != nb_integration_points; ++gg) {
114 // add to element norm
115 norm_on_element += t_w * (t_data(i) * t_data(i));
116 // move to another integration weight
117 ++t_w;
118 // move to another data values
119 ++t_data;
120 }
121 // scale with volume of the element
122 norm_on_element *= vol;
123 // add to dataVec at iNdex position
124 CHKERR VecSetValue(dataVec, iNdex, norm_on_element, ADD_VALUES);
125
127}
128
129template <int DIM_1, int DIM_2>
131 boost::shared_ptr<MatrixDouble> data_ptr, SmartPetscObj<Vec> data_vec,
132 const int index, boost::shared_ptr<MatrixDouble> diff_data_ptr,
133 boost::shared_ptr<Range> ent_ptr)
136 dataPtr(data_ptr), dataVec(data_vec), iNdex(index),
137 diffDataPtr(diff_data_ptr), entsPtr(ent_ptr) {
138 if (!dataPtr)
139 THROW_MESSAGE("Pointer is not set");
140 if (!diffDataPtr)
142}
143
144template <int DIM_1, int DIM_2>
149
150 // check if entity is in the range
151 if (entsPtr) {
152 if (entsPtr->find(this->getFEEntityHandle()) == entsPtr->end())
154 }
155
156 // calculate the difference between data pointers and save them in diffDataPtr
157 if (dataPtr != diffDataPtr)
158 *diffDataPtr -= *dataPtr;
159
160 // Declare FTensor index
161 FTensor::Index<'i', DIM_1> i;
162 FTensor::Index<'j', DIM_2> j;
163 // get number of integration points
164 const auto nb_integration_points = getGaussPts().size2();
165 // get element volume
166 const double vol = getMeasure();
167 // get integration weights
168 auto t_w = getFTensor0IntegrationWeight();
169 // get vector values
170 auto t_data = getFTensor2FromMat<DIM_1, DIM_2>(*diffDataPtr);
171 // initialise double to store norm values
172 double norm_on_element = 0.;
173 // loop over integration points
174 for (int gg = 0; gg != nb_integration_points; gg++) {
175 // add to element norm
176 norm_on_element += t_w * (t_data(i, j) * t_data(i, j));
177 // move to another integration weight
178 ++t_w;
179 // move to another data values
180 ++t_data;
181 }
182 // scale with volume of the element
183 norm_on_element *= vol;
184 // add to dataVec at iNdex position
185 CHKERR VecSetValue(dataVec, iNdex, norm_on_element, ADD_VALUES);
186
188}
189
191 boost::shared_ptr<VectorDouble> data_ptr, ScalarFun scalar_function)
194 dataPtr(data_ptr), sFunc(scalar_function) {}
195
199
200 // get number of integration points
201 const int nb_integration_pts = getGaussPts().size2();
202 // resize dataPtr to store values at integration points
203 dataPtr->resize(nb_integration_pts);
204 // get values
205 auto t_val = getFTensor0FromVec(*dataPtr);
206
207 // get coordinates at integration point
208 auto t_coords = getFTensor1CoordsAtGaussPts();
209 // loop over integration points
210 for (int gg = 0; gg != nb_integration_pts; ++gg) {
211 // set value at integration point to value of scalar function at the
212 // coordinates
213 t_val = sFunc(t_coords(0), t_coords(1), t_coords(2));
214 // move to another value
215 ++t_val;
216 // move to another coordinates
217 ++t_coords;
218 }
219
221}
222
223template <int SPACE_DIM, int BASE_DIM>
225 boost::shared_ptr<MatrixDouble> data_ptr, VectorFunc vector_function)
228 dataPtr(data_ptr), vFunc(vector_function) {}
229
230template <int SPACE_DIM, int BASE_DIM>
232 int side, EntityType type, EntitiesFieldData::EntData &data) {
234
235 // Declare FTensor index set to space dimension
237 // get number of integration points
238 const int nb_integration_pts = getGaussPts().size2();
239 // resize dataPtr to store values at integration points
241 auto get_values_at_pts =
243 *dataPtr, nb_integration_pts);
244 dataPtr->clear();
245 // get values
246 auto t_val = get_values_at_pts();
247
248 // get coordinates at integration point
249 auto t_coords = getFTensor1CoordsAtGaussPts();
250 // loop over integration points
251 for (int gg = 0; gg != nb_integration_pts; ++gg) {
252 // get function values of vector function at the coordinates
253 auto func_val = vFunc(t_coords(0), t_coords(1), t_coords(2));
254 // translate function values to tensor
255 auto t_func_val = getFTensor1FromArray<SPACE_DIM, SPACE_DIM>(func_val);
256 // set values at integration point to function values at the coordinates
257 t_val(i) = t_func_val(i);
258
259 // move to another value
260 ++t_val;
261 // move to another coordinates
262 ++t_coords;
263 }
264
266}
267
268template struct OpCalcNormL2Tensor1<2>;
269template struct OpCalcNormL2Tensor1<3>;
270template struct OpCalcNormL2Tensor2<2, 2>;
271template struct OpCalcNormL2Tensor2<3, 3>;
272template struct OpGetTensor1fromFunc<2, 2>;
273template struct OpGetTensor1fromFunc<2, 3>;
274template struct OpGetTensor1fromFunc<3, 3>;
275
276} // namespace MoFEM
std::string type
constexpr int SPACE_DIM
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
@ NOSPACE
Definition definitions.h:83
#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 CHKERR
Inline error check.
#define THROW_MESSAGE(msg)
Throw MoFEM exception.
constexpr int BASE_DIM
boost::function< double(const double, const double, const double)> ScalarFun
Scalar function type.
FTensor::Index< 'i', SPACE_DIM > i
FTensor::Index< 'j', 3 > j
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
implementation of Data Operators for Forces and Sources
Definition Common.hpp:10
boost::function< VectorDouble(const double, const double, const double)> VectorFunc
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.
Data on single entity (This is passed as argument to DataOperator::doWork)
auto getFTensor1CoordsAtGaussPts()
Get coordinates at integration points assuming linear geometry.
auto getFTensor0IntegrationWeight()
Get integration weights.
double getMeasure() const
get measure of element
MatrixDouble & getGaussPts()
matrix of integration (Gauss) points for Volume Element
structure to get information from mofem into EntitiesFieldData
boost::shared_ptr< VectorDouble > dataPtr
boost::shared_ptr< VectorDouble > diffDataPtr
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
calculate norm of scalar values at integration points
OpCalcNormL2Tensor0(boost::shared_ptr< VectorDouble > data_ptr, SmartPetscObj< Vec > data_vec, const int index, boost::shared_ptr< VectorDouble > diff_data_ptr=nullptr, boost::shared_ptr< Range > ent_ptr=nullptr)
SmartPetscObj< Vec > dataVec
boost::shared_ptr< Range > entsPtr
Get norm of input MatrixDouble for Tensor1.
boost::shared_ptr< MatrixDouble > diffDataPtr
OpCalcNormL2Tensor1(boost::shared_ptr< MatrixDouble > data_ptr, SmartPetscObj< Vec > data_vec, const int index, boost::shared_ptr< MatrixDouble > diff_data_ptr=nullptr, boost::shared_ptr< Range > ent_ptr=nullptr)
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
calculate norm of vector values at integration points
boost::shared_ptr< MatrixDouble > dataPtr
Get norm of input MatrixDouble for Tensor2.
OpCalcNormL2Tensor2(boost::shared_ptr< MatrixDouble > data_ptr, SmartPetscObj< Vec > data_vec, const int index, boost::shared_ptr< MatrixDouble > diff_data_ptr=nullptr, boost::shared_ptr< Range > ent_ptr=nullptr)
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
calculate norm of tensor values at integration points
boost::shared_ptr< MatrixDouble > diffDataPtr
boost::shared_ptr< MatrixDouble > dataPtr
OpGetTensor0fromFunc(boost::shared_ptr< VectorDouble > data_ptr, ScalarFun scalar_function)
boost::shared_ptr< VectorDouble > dataPtr
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
calculate values of scalar function at integration points
OpGetTensor1fromFunc(boost::shared_ptr< MatrixDouble > data_ptr, VectorFunc vector_function)
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
calculate values of vector function at integration points
intrusive_ptr for managing petsc objects