10#ifndef __FORMSBROKENSPACECONSTRAINTIMPL_HPP__
11#define __FORMSBROKENSPACECONSTRAINTIMPL_HPP__
45 prev_side_fe_ptr->numeredEntFiniteElementPtr->getFEUId();
58 prev_side_fe_ptr->numeredEntFiniteElementPtr;
63 "sideFEName is different");
92 boost::shared_ptr<std::vector<BrokenBaseSideData>> broken_base_side_data);
101template <
typename OpBase>
104 boost::shared_ptr<std::vector<BrokenBaseSideData>> broken_base_side_data)
106 brokenBaseSideData(broken_base_side_data) {}
108template <
typename OpBase>
117 brokenBaseSideData->resize(OP::getLoopSize());
119 const auto n_in_the_loop = OP::getNinTheLoop();
120 const auto face_sense = OP::getSkeletonSense();
123 if (face_sense != -1 && face_sense != 1)
127 auto set_data = [&](
auto &side_data) {
128 side_data.getSide() = row_side;
129 side_data.getType() = row_type;
130 side_data.getSense() = face_sense;
131 side_data.getData().sEnse = row_data.
sEnse;
132 side_data.getData().sPace = row_data.
sPace;
133 side_data.getData().bAse = row_data.
bAse;
134 side_data.getData().iNdices = row_data.
iNdices;
135 side_data.getData().localIndices = row_data.
localIndices;
136 side_data.getData().dOfs = row_data.
dOfs;
138 side_data.getData().fieldData = row_data.
fieldData;
141 auto set_base = [&](
auto &side_data) {
142 auto base = side_data.getData().getBase();
143 for (
auto dd = 0; dd != BaseDerivatives::LastDerivative; ++dd) {
144 side_data.getData().baseFunctionsAndBaseDerivatives[dd][base].reset();
146 side_data.getData().baseFunctionsAndBaseDerivatives[dd][base] =
147 boost::make_shared<MatrixDouble>(*base_ptr);
152 set_data((*brokenBaseSideData)[n_in_the_loop]);
153 set_base((*brokenBaseSideData)[n_in_the_loop]);
163 boost::shared_ptr<std::vector<BrokenBaseSideData>> broken_base_side_data,
164 boost::shared_ptr<MatrixDouble> flux_ptr);
174template <
typename OpBase>
176 boost::shared_ptr<std::vector<BrokenBaseSideData>> broken_base_side_data,
177 boost::shared_ptr<MatrixDouble> flux_ptr)
178 :
OP(
NOSPACE,
OP::OPSPACE), brokenBaseSideData(broken_base_side_data),
181template <
typename OpBase>
185 auto swap_flux = [&](
auto &side_data) { side_data.getFlux().swap(*fluxPtr); };
186 swap_flux((*brokenBaseSideData)[OP::getNinTheLoop()]);
195 boost::shared_ptr<std::vector<BrokenBaseSideData>> broken_base_side_data,
196 boost::shared_ptr<Range> ents_ptr =
nullptr)
202 const std::string row_field,
203 boost::shared_ptr<std::vector<BrokenBaseSideData>> broken_base_side_data,
204 const bool assmb_transpose,
const bool only_transpose,
205 boost::shared_ptr<Range> ents_ptr =
nullptr)
206 :
OP(row_field, row_field,
OP::OPROW, ents_ptr),
221template <
typename OpBase>
228 if (OP::entsPtr->find(this->getFEEntityHandle()) == OP::entsPtr->end())
233 if (!brokenBaseSideData) {
238 auto do_work_rhs = [
this](
int row_side, EntityType row_type,
246 OP::nbIntegrationPts = OP::getGaussPts().size2();
248 OP::nbRowBaseFunctions = OP::getNbOfBaseFunctions(row_data);
250 OP::locF.resize(OP::nbRows,
false);
253 CHKERR this->iNtegrate(row_data);
256 CHKERR this->aSsemble(row_data);
260 auto do_work_lhs = [
this](
int row_side,
int col_side, EntityType row_type,
266 auto check_if_assemble_transpose = [&] {
268 if (OP::rowSide != OP::colSide || OP::rowType != OP::colType)
272 }
else if (OP::assembleTranspose) {
278 OP::rowSide = row_side;
279 OP::rowType = row_type;
280 OP::colSide = col_side;
281 OP::colType = col_type;
282 OP::nbCols = col_data.getIndices().size();
283 OP::locMat.resize(OP::nbRows, OP::nbCols,
false);
285 CHKERR this->iNtegrate(row_data, col_data);
287 CHKERR this->aSsemble(row_data, col_data, check_if_assemble_transpose());
291 switch (OP::opType) {
297 OP::nbIntegrationPts = OP::getGaussPts().size2();
298 OP::nbRowBaseFunctions = OP::getNbOfBaseFunctions(row_data);
303 for (
auto &bd : *brokenBaseSideData) {
306 if (!bd.getData().getNSharedPtr(bd.getData().getBase())) {
308 "base functions not set");
315 row_side, bd.getSide(),
318 row_type, bd.getType(),
321 row_data, bd.getData(),
331 for (
auto &bd : *brokenBaseSideData) {
332 CHKERR do_work_rhs(bd.getSide(), bd.getType(), bd.getData(),
338 (std::string(
"wrong op type ") +
346template <
int FIELD_DIM, IntegrationType I,
typename OpBrokenBase>
349template <
int FIELD_DIM,
typename OpBrokenBase>
356 const std::string row_field,
357 boost::shared_ptr<std::vector<BrokenBaseSideData>> broken_base_side_data,
358 boost::shared_ptr<double> beta_ptr,
const bool assmb_transpose,
359 const bool only_transpose, boost::shared_ptr<Range> ents_ptr =
nullptr)
360 :
OP(row_field, broken_base_side_data, assmb_transpose, only_transpose,
362 scalarBetaPtr(beta_ptr) {}
365 const std::string row_field,
366 boost::shared_ptr<std::vector<BrokenBaseSideData>> broken_base_side_data,
367 double beta,
const bool assmb_transpose,
const bool only_transpose,
368 boost::shared_ptr<Range> ents_ptr =
nullptr)
370 boost::make_shared<
double>(beta),
371 assmb_transpose, only_transpose, ents_ptr) {}
379template <
int FIELD_DIM,
typename OpBase>
385 auto nb_row_dofs = row_data.
getIndices().size();
386 auto nb_col_dofs = col_data.
getIndices().size();
387 if (!nb_row_dofs || !nb_col_dofs)
393 auto t_w = this->getFTensor0IntegrationWeight();
394 auto t_normal = OpBase::getFTensor1NormalsAtGaussPts();
395 size_t nb_base_functions = col_data.
getN().size2() / 3;
400 "number of dofs not divisible by field dimension");
405 "number of dofs exceeds number of base functions");
414 for (; cc != nb_col_dofs /
FIELD_DIM; cc++) {
416 for (
auto rr = 0; rr != nb_row_dofs /
FIELD_DIM; ++rr) {
418 (0.5 * t_w * t_row_base) * (t_normal(
J) * t_col_base(
J));
425 for (; cc < nb_base_functions; ++cc)
432 for (
auto rr = 0; rr != nb_row_dofs /
FIELD_DIM; ++rr) {
433 for (
auto cc = 0; cc != nb_col_dofs /
FIELD_DIM; ++cc) {
442 OP::locMat *= *scalarBetaPtr;
447template <
int FIELD_DIM, IntegrationType I,
typename OpBase>
450template <
int FIELD_DIM, IntegrationType I,
typename OpBase>
453template <
int FIELD_DIM,
typename OpBrokenBase>
460 boost::shared_ptr<std::vector<BrokenBaseSideData>> broken_base_side_data,
461 boost::shared_ptr<MatrixDouble> lagrange_ptr,
462 boost::shared_ptr<double> beta_ptr,
463 boost::shared_ptr<Range> ents_ptr =
nullptr)
464 :
OP(broken_base_side_data, ents_ptr), scalarBetaPtr(beta_ptr),
465 lagrangePtr(lagrange_ptr) {}
468 boost::shared_ptr<std::vector<BrokenBaseSideData>> broken_base_side_data,
469 boost::shared_ptr<MatrixDouble> lagrange_ptr,
double beta,
470 boost::shared_ptr<Range> ents_ptr =
nullptr)
472 boost::make_shared<
double>(beta),
482template <
int FIELD_DIM,
typename OpBase>
491 auto t_w = this->getFTensor0IntegrationWeight();
492 auto t_normal = OpBase::getFTensor1NormalsAtGaussPts();
493 auto t_lagrange = getFTensor1FromMat<FIELD_DIM>(*lagrangePtr);
496 auto nb_base_functions = row_data.
getN().size2() / 3;
499 auto t_vec = getFTensor1FromPtr<FIELD_DIM>(&*OP::locF.data().begin());
502 t_vec(
i) += (0.5 * t_w * (t_row_base(
J) * t_normal(
J))) * t_lagrange(
i);
506 for (; rr < nb_base_functions; ++rr)
514 OP::locF *= *scalarBetaPtr;
519template <
int FIELD_DIM,
typename OpBase>
526 const std::string row_field,
527 boost::shared_ptr<std::vector<BrokenBaseSideData>> broken_side_data_ptr,
528 boost::shared_ptr<double> beta_ptr,
529 boost::shared_ptr<Range> ents_ptr =
nullptr)
530 :
OpBase(row_field, row_field,
OpBase::OPROW, ents_ptr),
531 brokenSideDataPtr(broken_side_data_ptr), scalarBetaPtr(beta_ptr) {}
534 const std::string row_field,
535 boost::shared_ptr<std::vector<BrokenBaseSideData>> broken_side_data_ptr,
536 double beta, boost::shared_ptr<Range> ents_ptr =
nullptr)
538 boost::make_shared<
double>(beta),
547template <
int FIELD_DIM,
typename OpBase>
556 OP::locF.resize(row_data.
getIndices().size(),
false);
559 for (
auto &bd : *brokenSideDataPtr) {
560 auto t_w = this->getFTensor0IntegrationWeight();
561 auto t_normal = OpBase::getFTensor1NormalsAtGaussPts();
563 auto t_flux = getFTensor2FromMat<FIELD_DIM, 3>(bd.getFlux());
564 auto nb_base_functions = row_data.
getN().size2() / 3;
565 auto sense = bd.getSense();
567 auto t_vec = getFTensor1FromPtr<FIELD_DIM>(&*OP::locF.data().begin());
571 (sense * 0.5 * t_w) * t_row_base * t_normal(
J) * t_flux(
i,
J);
575 for (; rr < nb_base_functions; ++rr)
584 OP::locF *= *scalarBetaPtr;
#define FTENSOR_INDEX(DIM, I)
#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 ...
#define CHK_MOAB_THROW(err, msg)
Check error code of MoAB function and throw MoFEM exception.
@ MOFEM_DATA_INCONSISTENCY
#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
FTensor::Index< 'J', DIM1 > J
const Tensor2_symmetric_Expr< const ddTensor0< T, Dim, i, j >, typename promote< T, double >::V, Dim, i, j > dd(const Tensor0< T * > &a, const Index< i, Dim > index1, const Index< j, Dim > index2, const Tensor1< int, Dim > &d_ijk, const Tensor1< double, Dim > &d_xyz)
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
implementation of Data Operators for Forces and Sources
constexpr auto field_name
OpBaseImpl< PETSC, EdgeEleOp > OpBase
EntitiesFieldData::EntData entData
Data on single entity (This is passed as argument to DataOperator::doWork)
FieldSpace sPace
Entity space.
int sEnse
Entity sense (orientation)
VectorDouble fieldData
Field data on entity.
FTensor::Tensor0< FTensor::PackPtr< double *, 1 > > getFTensor0N(const FieldApproximationBase base)
Get base function as Tensor0.
VectorInt localIndices
Local indices on entity.
VectorInt iNdices
Global indices on entity.
MatrixDouble & getN(const FieldApproximationBase base)
get base functions this return matrix (nb. of rows is equal to nb. of Gauss pts, nb....
virtual int getSense() const
Get entity sense for conforming approximation fields.
VectorFieldEntities fieldEntities
Field entities.
FTensor::Tensor1< FTensor::PackPtr< double *, Tensor_Dim >, Tensor_Dim > getFTensor1N(FieldApproximationBase base)
Get base functions for Hdiv/Hcurl spaces.
std::array< std::array< boost::shared_ptr< MatrixDouble >, LASTBASE >, LastDerivative > baseFunctionsAndBaseDerivatives
VectorDofs dOfs
DoFs on entity.
const VectorInt & getIndices() const
Get global indices of degrees of freedom on entity.
FieldApproximationBase bAse
Field approximation base.
static const char *const OpTypeNames[]
ForcesAndSourcesCore * getPtrFE() const
const FEMethod * getFEMethod() const
Return raw pointer to Finite Element Method object.
ForcesAndSourcesCore * getSidePtrFE() const
boost::shared_ptr< Range > entsPtr
Entities on which element is run.
int nbIntegrationPts
number of integration points
boost::shared_ptr< std::vector< BrokenBaseSideData > > brokenBaseSideData
MoFEMErrorCode doWork(int row_side, EntityType row_type, EntitiesFieldData::EntData &row_data)
OpBrokenBaseImpl(const std::string row_field, boost::shared_ptr< std::vector< BrokenBaseSideData > > broken_base_side_data, const bool assmb_transpose, const bool only_transpose, boost::shared_ptr< Range > ents_ptr=nullptr)
OpBrokenBaseImpl(boost::shared_ptr< std::vector< BrokenBaseSideData > > broken_base_side_data, boost::shared_ptr< Range > ents_ptr=nullptr)
Operator for broken loop side.
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
Operator for linear form, usually to calculate values on right hand side.
boost::shared_ptr< double > scalarBetaPtr
MoFEMErrorCode iNtegrate(EntitiesFieldData::EntData &row_data)
OpBrokenSpaceConstrainDFluxImpl(boost::shared_ptr< std::vector< BrokenBaseSideData > > broken_base_side_data, boost::shared_ptr< MatrixDouble > lagrange_ptr, boost::shared_ptr< double > beta_ptr, boost::shared_ptr< Range > ents_ptr=nullptr)
OpBrokenSpaceConstrainDFluxImpl(boost::shared_ptr< std::vector< BrokenBaseSideData > > broken_base_side_data, boost::shared_ptr< MatrixDouble > lagrange_ptr, double beta, boost::shared_ptr< Range > ents_ptr=nullptr)
boost::shared_ptr< MatrixDouble > lagrangePtr
OpBrokenSpaceConstrainDHybridImpl(const std::string row_field, boost::shared_ptr< std::vector< BrokenBaseSideData > > broken_side_data_ptr, boost::shared_ptr< double > beta_ptr, boost::shared_ptr< Range > ents_ptr=nullptr)
OpBrokenSpaceConstrainDHybridImpl(const std::string row_field, boost::shared_ptr< std::vector< BrokenBaseSideData > > broken_side_data_ptr, double beta, boost::shared_ptr< Range > ents_ptr=nullptr)
boost::shared_ptr< double > scalarBetaPtr
boost::shared_ptr< std::vector< BrokenBaseSideData > > brokenSideDataPtr
boost::shared_ptr< double > scalarBetaPtr
OpBrokenSpaceConstrainImpl(const std::string row_field, boost::shared_ptr< std::vector< BrokenBaseSideData > > broken_base_side_data, boost::shared_ptr< double > beta_ptr, const bool assmb_transpose, const bool only_transpose, boost::shared_ptr< Range > ents_ptr=nullptr)
MoFEMErrorCode iNtegrate(EntitiesFieldData::EntData &row_data, EntitiesFieldData::EntData &col_data)
OpBrokenSpaceConstrainImpl(const std::string row_field, boost::shared_ptr< std::vector< BrokenBaseSideData > > broken_base_side_data, double beta, const bool assmb_transpose, const bool only_transpose, boost::shared_ptr< Range > ents_ptr=nullptr)
MoFEMErrorCode doWork(int row_side, EntityType row_type, EntitiesFieldData::EntData &row_data)
boost::shared_ptr< std::vector< BrokenBaseSideData > > brokenBaseSideData
OpGetBrokenBaseSideData(const std::string field_name, boost::shared_ptr< std::vector< BrokenBaseSideData > > broken_base_side_data)
Element used to execute operators on side of the element.
const std::string sideFEName
boost::shared_ptr< E > sideFEPtr
MoFEMErrorCode doWork(int row_side, EntityType row_type, EntitiesFieldData::EntData &row_data)
OpSetFlux(boost::shared_ptr< std::vector< BrokenBaseSideData > > broken_base_side_data, boost::shared_ptr< MatrixDouble > flux_ptr)
boost::shared_ptr< std::vector< BrokenBaseSideData > > brokenBaseSideData
boost::shared_ptr< MatrixDouble > fluxPtr