v0.8.23
DataStructures.cpp
Go to the documentation of this file.
1 /** \file DataStructures.cpp
2 \brief Implementation for Data Structures in Forces and Sources
3 
4 */
5 
6 /* This file is part of MoFEM.
7  * MoFEM is free software: you can redistribute it and/or modify it under
8  * the terms of the GNU Lesser General Public License as published by the
9  * Free Software Foundation, either version 3 of the License, or (at your
10  * option) any later version.
11  *
12  * MoFEM is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15  * License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with MoFEM. If not, see <http://www.gnu.org/licenses/>. */
19 
20 #ifdef __cplusplus
21 extern "C" {
22 #endif
23  #include <cblas.h>
24  #include <lapack_wrap.h>
25  #include <gm_rule.h>
26 #ifdef __cplusplus
27 }
28 #endif
29 
30 namespace MoFEM {
31 
33  : sEnse(0), oRder(0), bAse(NOBASE) {
34  for (int b = 0; b != LASTBASE;++b) {
35  N[b].reset(new MatrixDouble());
36  diffN[b].reset(new MatrixDouble());
37  }
38 }
39 
41  const EntityType type) {
42 
44 
45  data->dataOnEntities[MBENTITYSET].push_back(new EntData());
46 
47  switch (type) {
48  case MBENTITYSET:
49  break;
50  case MBTET:
51  data->dataOnEntities[MBVERTEX].push_back(new EntData());
52  for (int ee = 0; ee != 6; ++ee) {
53  data->dataOnEntities[MBEDGE].push_back(new EntData());
54  }
55  for (int ff = 0; ff != 4; ++ff) {
56  data->dataOnEntities[MBTRI].push_back(new EntData());
57  }
58  data->dataOnEntities[MBTET].push_back(new EntData());
59  break;
60  case MBTRI:
61  data->dataOnEntities[MBVERTEX].push_back(new EntData());
62  for (int ee = 0; ee != 3; ++ee) {
63  data->dataOnEntities[MBEDGE].push_back(new EntData());
64  }
65  data->dataOnEntities[MBTRI].push_back(new EntData());
66  break;
67  case MBEDGE:
68  data->dataOnEntities[MBVERTEX].push_back(new EntData());
69  data->dataOnEntities[MBEDGE].push_back(new EntData());
70  break;
71  case MBVERTEX:
72  data->dataOnEntities[MBVERTEX].push_back(new EntData());
73  break;
74  case MBPRISM:
75  data->dataOnEntities[MBVERTEX].push_back(new EntData());
76  for (int ee = 0; ee != 9; ++ee) {
77  data->dataOnEntities[MBEDGE].push_back(new EntData());
78  }
79  for (int qq = 0; qq != 5; ++qq) {
80  data->dataOnEntities[MBQUAD].push_back(new EntData());
81  }
82  for (int ff = 0; ff != 5; ++ff) {
83  data->dataOnEntities[MBTRI].push_back(new EntData());
84  }
85  data->dataOnEntities[MBPRISM].push_back(new EntData());
86  break;
87  default:
89  }
90 }
91 
93  constructor_data(this, type);
94 }
95 
98  for (EntityType tt = MBVERTEX; tt != MBMAXTYPE; ++tt)
99  dataOnEntities[tt].clear();
100  constructor_data(this, type);
102 }
103 
105  DerivedDataForcesAndSourcesCore *derived_data,
106  const boost::shared_ptr<DataForcesAndSourcesCore> &data_ptr) {
107 
110 
111  for (int tt = MBVERTEX; tt != MBMAXTYPE; ++tt) {
112  auto &ent_data = data_ptr->dataOnEntities[tt];
113  auto &derived_ent_data = derived_data->dataOnEntities[tt];
114  for (auto &e : ent_data) {
115  boost::shared_ptr<EntData> ent_data_ptr(data_ptr, &e);
116  derived_ent_data.push_back(new DerivedEntData(ent_data_ptr));
117  }
118  }
119 }
120 
122  const boost::shared_ptr<DataForcesAndSourcesCore> &data_ptr)
123  : DataForcesAndSourcesCore(), dataPtr(data_ptr) {
125 }
126 
130  for (EntityType tt = MBVERTEX; tt != MBMAXTYPE; ++tt)
131  dataOnEntities[tt].clear();
134 }
135 
136 std::ostream &operator<<(std::ostream &os,
138  os << "sEnse: " << e.getSense() << std::endl
139  << "oRder: " << e.getOrder() << std::endl
140  << "global indices: " << e.getIndices() << std::endl
141  << "local indices: " << e.getLocalIndices() << std::endl;
142  os.precision(2);
143  os << "fieldData: " << std::fixed << e.getFieldData() << std::endl;
144  MatrixDouble base = e.getN();
145  MatrixDouble diff_base = e.getDiffN();
146  const double eps = 1e-6;
147  for (unsigned int ii = 0; ii != base.size1(); ii++) {
148  for (unsigned int jj = 0; jj != base.size2(); jj++) {
149  if (fabs(base(ii, jj)) < eps)
150  base(ii, jj) = 0;
151  }
152  }
153  for (unsigned int ii = 0; ii != diff_base.size1(); ii++) {
154  for (unsigned int jj = 0; jj != diff_base.size2(); jj++) {
155  if (fabs(diff_base(ii, jj)) < eps)
156  diff_base(ii, jj) = 0;
157  }
158  }
159  os << "N: " << std::fixed << base << std::endl
160  << "diffN: " << std::fixed << diff_base;
161  return os;
162 }
163 
164 std::ostream &operator<<(std::ostream &os, const DataForcesAndSourcesCore &e) {
165  for (unsigned int nn = 0; nn < e.dataOnEntities[MBVERTEX].size(); nn++) {
166  os << "dataOnEntities[MBVERTEX][" << nn << "]" << std::endl
167  << e.dataOnEntities[MBVERTEX][nn] << std::endl;
168  }
169  for (unsigned int ee = 0; ee < e.dataOnEntities[MBEDGE].size(); ee++) {
170  os << "dataOnEntities[MBEDGE][" << ee << "]" << std::endl
171  << e.dataOnEntities[MBEDGE][ee] << std::endl;
172  }
173  for (unsigned int ff = 0; ff < e.dataOnEntities[MBTRI].size(); ff++) {
174  os << "dataOnEntities[MBTRI][" << ff << "] " << std::endl
175  << e.dataOnEntities[MBTRI][ff] << std::endl;
176  }
177  for (unsigned int vv = 0; vv < e.dataOnEntities[MBTET].size(); vv++) {
178  os << "dataOnEntities[MBTET][" << vv << "]" << std::endl
179  << e.dataOnEntities[MBTET][vv] << std::endl;
180  }
181  return os;
182 }
183 
184 /** \name Specializations for H1/L2 */
185 
186 /**@{*/
187 
188 template <>
190 DataForcesAndSourcesCore::EntData::getFTensor1FieldData<3>() {
191  if (dOfs[0]->getNbOfCoeffs() != 3) {
192  std::stringstream s;
193  s << "Wrong number of coefficients is " << dOfs[0]->getNbOfCoeffs();
194  s << " but you ask for tensor rank 1 dimension 3";
195  THROW_MESSAGE(s.str());
196  }
197  double *ptr = &*fieldData.data().begin();
198  return FTensor::Tensor1<FTensor::PackPtr<double *, 3>, 3>(ptr, &ptr[1],
199  &ptr[2]);
200 }
201 
202 template <>
204 DataForcesAndSourcesCore::EntData::getFTensor1FieldData<2>() {
205  if (dOfs[0]->getNbOfCoeffs() != 2) {
206  std::stringstream s;
207  s << "Wrong number of coefficients is " << dOfs[0]->getNbOfCoeffs();
208  s << " but you ask for tensor rank 1 dimension 3";
209  THROW_MESSAGE(s.str());
210  }
211  double *ptr = &*fieldData.data().begin();
212  return FTensor::Tensor1<FTensor::PackPtr<double *, 2>, 2>(ptr, &ptr[1]);
213 }
214 
215 template <>
217 DataForcesAndSourcesCore::EntData::getFTensor2FieldData<3, 3>() {
218  if (dOfs[0]->getNbOfCoeffs() != 9) {
219  std::stringstream s;
220  s << "Wrong number of coefficients is " << dOfs[0]->getNbOfCoeffs();
221  s << " but you ask for tensor rank 2 dimensions 3 by 3 so 9 coefficients "
222  "is expected";
223  THROW_MESSAGE(s.str());
224  }
225  double *ptr = &*fieldData.data().begin();
227  ptr, &ptr[1], &ptr[2], &ptr[3], &ptr[4], &ptr[5], &ptr[6], &ptr[7],
228  &ptr[8]);
229 }
230 
231 template <>
233 DataForcesAndSourcesCore::EntData::getFTensor2SymmetricFieldData<3>() {
234  if (dOfs[0]->getNbOfCoeffs() != 6) {
235  std::stringstream s;
236  s << "Wrong number of coefficients is " << dOfs[0]->getNbOfCoeffs();
237  s << " but you ask for symmetric tensor rank 2 dimensions 3 by 3 so 6 "
238  "coefficients "
239  "is expected";
240  THROW_MESSAGE(s.str());
241  }
242  double *ptr = &*fieldData.data().begin();
244  ptr, &ptr[1], &ptr[2], &ptr[3], &ptr[4], &ptr[5]);
245 }
246 
249  if (dOfs[0]->getNbOfCoeffs() != 1) {
250  std::stringstream s;
251  s << "Wrong number of coefficients is " << dOfs[0]->getNbOfCoeffs();
252  s << " but expected scalar field, tensor of rank 0";
253  THROW_MESSAGE(s.str());
254  }
256  &*fieldData.data().begin());
257 }
258 
259 template <int Tensor_Dim>
262  const FieldApproximationBase base) {
263  std::stringstream s;
264  s << "Template for tensor dimension " << Tensor_Dim << " not implemented";
265  THROW_MESSAGE(s.str());
267 }
268 
269 template <int Tensor_Dim>
272  return getFTensor1DiffN<Tensor_Dim>(bAse);
273 }
274 
275 template <int Tensor_Dim>
278  const FieldApproximationBase base, const int bb) {
279  std::stringstream s;
280  s << "Template for tensor dimension " << Tensor_Dim << " not implemented";
281  THROW_MESSAGE(s.str());
283 }
284 
285 template <int Tensor_Dim>
288  return getFTensor1DiffN<Tensor_Dim>(bAse, bb);
289 }
290 
291 /**
292  * \brief Get spatial derivative of base function tensor for dimension 3d
293  */
294 template <>
296 DataForcesAndSourcesCore::EntData::getFTensor1DiffN<3>(
297  const FieldApproximationBase base) {
298  double *ptr = &*getDiffN(base).data().begin();
299  return FTensor::Tensor1<double *, 3>(ptr, &ptr[1], &ptr[2], 3);
300 }
301 
302 /**
303  * \brief Get spatial derivative of base function tensor for dimension 3d
304  */
305 template <>
307 DataForcesAndSourcesCore::EntData::getFTensor1DiffN<3>() {
308  return getFTensor1DiffN<3>(bAse);
309 }
310 
311 /**
312  * \brief Get spatial derivative of base function tensor for dimension 3d
313  */
314 template <>
316 DataForcesAndSourcesCore::EntData::getFTensor1DiffN<3>(
317  const FieldApproximationBase base, const int bb) {
318  double *ptr = &*getDiffN(base).data().begin();
320  &ptr[3 * bb], &ptr[3 * bb + 1], &ptr[3 * bb + 2], getDiffN(base).size2());
321 }
322 
323 /**
324  * \brief Get spatial derivative of base function tensor for dimension 3d
325  */
326 template <>
328 DataForcesAndSourcesCore::EntData::getFTensor1DiffN<3>(const int bb) {
329  return getFTensor1DiffN<3>(bAse, bb);
330 }
331 
332 /**
333  * \brief Get spatial derivative of base function tensor for dimension 2d
334  */
335 template <>
337 DataForcesAndSourcesCore::EntData::getFTensor1DiffN<2>(
338  const FieldApproximationBase base) {
339  double *ptr = &*getDiffN(base).data().begin();
340  return FTensor::Tensor1<double *, 2>(ptr, &ptr[1], 2);
341 }
342 
343 /**
344  * \brief Get spatial derivative of base function tensor for dimension 2d
345  */
346 template <>
348 DataForcesAndSourcesCore::EntData::getFTensor1DiffN<2>() {
349  return getFTensor1DiffN<2>(bAse);
350 }
351 
352 /**
353  * \brief Get spatial derivative of base function tensor for dimension 3d
354  */
355 template <>
357 DataForcesAndSourcesCore::EntData::getFTensor1DiffN<2>(
358  const FieldApproximationBase base, const int bb) {
359  double *ptr = &*getDiffN(base).data().begin();
360  return FTensor::Tensor1<double *, 2>(&ptr[2 * bb], &ptr[2 * bb + 1],
361  getDiffN(base).size1());
362 }
363 
364 /**
365  * \brief Get spatial derivative of base function tensor for dimension 3d
366  */
367 template <>
369 DataForcesAndSourcesCore::EntData::getFTensor1DiffN<2>(const int bb) {
370  return getFTensor1DiffN<2>(bAse, bb);
371 }
372 
373 template <int Tensor_Dim>
376  const FieldApproximationBase base, const int gg, const int bb) {
377  std::stringstream s;
378  s << "Template for tensor dimension " << Tensor_Dim << " not implemented";
379  THROW_MESSAGE(s.str());
381 }
382 
383 /**
384  * \brief Get spatial derivative of base function tensor for dimension 3d
385  */
386 template <>
388 DataForcesAndSourcesCore::EntData::getFTensor1DiffN<3>(
389  const FieldApproximationBase base, const int gg, const int bb) {
390  double *ptr = &getDiffN(base)(gg, 3 * bb);
391  return FTensor::Tensor1<double *, 3>(ptr, &ptr[1], &ptr[2], 3);
392 }
393 
394 /**
395  * \brief Get spatial derivative of base function tensor for dimension 3d
396  */
397 template <>
399 DataForcesAndSourcesCore::EntData::getFTensor1DiffN<3>(const int gg,
400  const int bb) {
401  return getFTensor1DiffN<3>(bAse, gg, bb);
402 }
403 
404 /**
405  * \brief Get spatial derivative of base function tensor for dimension 2d
406  */
407 template <>
409 DataForcesAndSourcesCore::EntData::getFTensor1DiffN<2>(
410  const FieldApproximationBase base, const int gg, const int bb) {
411  double *ptr = &getDiffN(base)(gg, 2 * bb);
412  return FTensor::Tensor1<double *, 2>(ptr, &ptr[1], 2);
413 }
414 
415 /**
416  * \brief Get spatial derivative of base function tensor for dimension 2d
417  */
418 template <>
420 DataForcesAndSourcesCore::EntData::getFTensor1DiffN<2>(const int gg,
421  const int bb) {
422  return getFTensor1DiffN<2>(bAse, gg, bb);
423 }
424 
425 /**@}*/
426 
427 /** \name Specializations for HDiv/HCrul */
428 
429 /**@{*/
430 
431 template <int Tensor_Dim>
434  FieldApproximationBase base) {
435  std::stringstream s;
436  s << "Template for tensor dimension " << Tensor_Dim << " not implemented";
437  THROW_MESSAGE(s.str());
439 }
440 
441 template <int Tensor_Dim>
444  const int gg,
445  const int bb) {
446  std::stringstream s;
447  s << "Template for tensor dimension " << Tensor_Dim << " not implemented";
448  THROW_MESSAGE(s.str());
450 }
451 
452 template <int Tensor_Dim0, int Tensor_Dim1>
454  Tensor_Dim0, Tensor_Dim1>
456  FieldApproximationBase base) {
457  std::stringstream s;
458  s << "Template for tensor dimension " << Tensor_Dim0 << "x" << Tensor_Dim1
459  << " not implemented";
460  THROW_MESSAGE(s.str());
462 }
463 
464 template <int Tensor_Dim0, int Tensor_Dim1>
466  Tensor_Dim0, Tensor_Dim1>
468  FieldApproximationBase base, const int gg, const int bb) {
469  std::stringstream s;
470  s << "Template for tensor dimension " << Tensor_Dim0 << "x" << Tensor_Dim1
471  << " not implemented";
472  THROW_MESSAGE(s.str());
474 }
475 
476 template <>
478 DataForcesAndSourcesCore::EntData::getFTensor1N<3>(
479  FieldApproximationBase base) {
480  double *t_n_ptr = &*getN(base).data().begin();
481  return FTensor::Tensor1<FTensor::PackPtr<double *, 3>, 3>(t_n_ptr, // HVEC0
482  &t_n_ptr[HVEC1],
483  &t_n_ptr[HVEC2]);
484 }
485 
486 template <>
488 DataForcesAndSourcesCore::EntData::getFTensor1N<3>(
489  FieldApproximationBase base, const int gg, const int bb) {
490  double *t_n_ptr = &getN(base)(gg, 3 * bb);
491  return FTensor::Tensor1<FTensor::PackPtr<double *, 3>, 3>(t_n_ptr, // HVEC0
492  &t_n_ptr[HVEC1],
493  &t_n_ptr[HVEC2]);
494 }
495 
496 template <>
498 DataForcesAndSourcesCore::EntData::getFTensor2DiffN<3, 3>(
499  FieldApproximationBase base) {
500  double *t_diff_n_ptr = &*getDiffN(base).data().begin();
502  t_diff_n_ptr, &t_diff_n_ptr[HVEC0_1], &t_diff_n_ptr[HVEC0_2],
503  &t_diff_n_ptr[HVEC1_0], &t_diff_n_ptr[HVEC1_1], &t_diff_n_ptr[HVEC1_2],
504  &t_diff_n_ptr[HVEC2_0], &t_diff_n_ptr[HVEC2_1], &t_diff_n_ptr[HVEC2_2]);
505 }
506 
507 template <>
509 DataForcesAndSourcesCore::EntData::getFTensor2DiffN<3, 3>(
510  FieldApproximationBase base, const int gg, const int bb) {
511  double *t_diff_n_ptr = &getDiffN(base)(gg, 9 * bb);
513  t_diff_n_ptr, &t_diff_n_ptr[HVEC0_1], &t_diff_n_ptr[HVEC0_2],
514  &t_diff_n_ptr[HVEC1_0], &t_diff_n_ptr[HVEC1_1], &t_diff_n_ptr[HVEC1_2],
515  &t_diff_n_ptr[HVEC2_0], &t_diff_n_ptr[HVEC2_1], &t_diff_n_ptr[HVEC2_2]);
516 }
517 
518 template <>
520 DataForcesAndSourcesCore::EntData::getFTensor2DiffN<3, 2>(
521  FieldApproximationBase base) {
522  double *t_diff_n_ptr = &*getDiffN(base).data().begin();
524  t_diff_n_ptr, &t_diff_n_ptr[HVEC0_1], &t_diff_n_ptr[HVEC1_0],
525  &t_diff_n_ptr[HVEC1_1], &t_diff_n_ptr[HVEC2_0],
526  &t_diff_n_ptr[HVEC2_1]);
527 }
528 
529 template <>
531 DataForcesAndSourcesCore::EntData::getFTensor2DiffN<3, 2>(
532  FieldApproximationBase base, const int gg, const int bb) {
533  double *t_diff_n_ptr = &getDiffN(base)(gg, 6 * bb);
535  t_diff_n_ptr, &t_diff_n_ptr[HVEC0_1], &t_diff_n_ptr[HVEC1_0],
536  &t_diff_n_ptr[HVEC1_1], &t_diff_n_ptr[HVEC2_0], &t_diff_n_ptr[HVEC2_1]);
537 }
538 
539 template <int Tensor_Dim0, int Tensor_Dim1>
541  Tensor_Dim0, Tensor_Dim1>
543  std::stringstream s;
544  s << "Template for tensor dimension " << Tensor_Dim0 << ", " << Tensor_Dim1
545  << " not implemented";
546  THROW_MESSAGE(s.str());
548  Tensor_Dim0, Tensor_Dim1>();
549 }
550 
551 template <>
553 DataForcesAndSourcesCore::EntData::getFTensor2N<3, 3>(
554  FieldApproximationBase base) {
555  double *t_n_ptr = &*(getN(base).data().begin());
557 
558  &t_n_ptr[HVEC0], &t_n_ptr[HVEC1], &t_n_ptr[HVEC2],
559 
560  &t_n_ptr[3 + HVEC0], &t_n_ptr[3 + HVEC1], &t_n_ptr[3 + HVEC2],
561 
562  &t_n_ptr[6 + HVEC0], &t_n_ptr[6 + HVEC1], &t_n_ptr[6 + HVEC2]
563 
564  );
565 }
566 
567 template <int Tensor_Dim0, int Tensor_Dim1>
569  Tensor_Dim0, Tensor_Dim1>
571  const int gg, const int bb) {
572  std::stringstream s;
573  s << "Template for tensor dimension " << Tensor_Dim0 << ", " << Tensor_Dim1
574  << " not implemented";
575  THROW_MESSAGE(s.str());
577  Tensor_Dim0, Tensor_Dim1>();
578 }
579 
580 template <>
582 DataForcesAndSourcesCore::EntData::getFTensor2N<3, 3>(
583  FieldApproximationBase base, const int gg, const int bb) {
584  double *t_n_ptr = &getN(base)(gg, 9 * bb);
586 
587  &t_n_ptr[HVEC0], &t_n_ptr[HVEC1], &t_n_ptr[HVEC2],
588 
589  &t_n_ptr[3 + HVEC0], &t_n_ptr[3 + HVEC1], &t_n_ptr[3 + HVEC2],
590 
591  &t_n_ptr[6 + HVEC0], &t_n_ptr[6 + HVEC1], &t_n_ptr[6 + HVEC2]
592 
593  );
594 }
595 
596 /**@}*/
597 
598 } // namespace MoFEM
boost::shared_ptr< MatrixDouble > N[LASTBASE]
Base functions.
data structure for finite element entityIt keeps that about indices of degrees of freedom,...
DerivedDataForcesAndSourcesCore(const boost::shared_ptr< DataForcesAndSourcesCore > &data_ptr)
static void constructor_derived_data(DerivedDataForcesAndSourcesCore *derived_data, const boost::shared_ptr< DataForcesAndSourcesCore > &data_ptr)
const VectorInt & getLocalIndices() const
get local indices of dofs on entity
ublas::matrix< double, ublas::row_major, DoubleAllocator > MatrixDouble
Definition: Types.hpp:77
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
Definition: definitions.h:476
static void constructor_data(DataForcesAndSourcesCore *data, const EntityType type)
FTensor::Tensor2< FTensor::PackPtr< double *, Tensor_Dim0 *Tensor_Dim1 >, Tensor_Dim0, Tensor_Dim1 > getFTensor2DiffN()
Get derivatives of base functions for Hdiv space.
#define THROW_MESSAGE(a)
Throw MoFEM exception.
Definition: definitions.h:619
MoFEMErrorCode setElementType(const EntityType type)
virtual MoFEMErrorCode setElementType(const EntityType type)
virtual const MatrixDouble & getN(const FieldApproximationBase base) const
get base functions this return matrix (nb. of rows is equal to nb. of Gauss pts, nb....
implementation of Data Operators for Forces and Sources
Definition: Common.hpp:21
FTensor::Tensor0< FTensor::PackPtr< double *, 1 > > getFTensor0FieldData()
Resturn scalar files as a FTensor of rank 0.
boost::ptr_vector< EntData > dataOnEntities[MBMAXTYPE]
T data[Tensor_Dim]
virtual const MatrixDouble & getDiffN(const FieldApproximationBase base) const
get derivatives of base functions
std::ostream & operator<<(std::ostream &os, const DataForcesAndSourcesCore::EntData &e)
VectorDouble fieldData
Field data on entity.
FieldApproximationBase
approximation base
Definition: definitions.h:142
boost::shared_ptr< MatrixDouble > diffN[LASTBASE]
Derivatives of base functions.
const boost::shared_ptr< DataForcesAndSourcesCore > dataPtr
const VectorDouble & getFieldData() const
get dofs values
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
Definition: Exceptions.hpp:66
DataForcesAndSourcesCore::EntData EntData
ApproximationOrder getOrder() const
get approximation order
Derived ata on single entity (This is passed as argument to DataOperator::doWork)
T data[Tensor_Dim0][Tensor_Dim1]
FTensor::Tensor1< double *, Tensor_Dim > getFTensor1DiffN()
Get derivatives of base functions.
const VectorInt & getIndices() const
Get global indices of dofs on entity.
Data on single entity (This is passed as argument to DataOperator::doWork)
auto getFTensor2N()
Get base functions for Hdiv space.
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
Definition: definitions.h:406
static const double eps
std::bitset< LASTBASE > bAse
bases on element
auto getFTensor1N()
Get base functions for Hdiv space.
this class derive data form other data structure
virtual int getSense() const
get entity sense, need to calculate base functions with conforming approximation fields