10 #ifndef __FORMSBROKENSPACECONSTRAINTIMPL_HPP__
11 #define __FORMSBROKENSPACECONSTRAINTIMPL_HPP__
27 prev_side_fe_ptr->numeredEntFiniteElementPtr->getFEUId();
40 prev_side_fe_ptr->numeredEntFiniteElementPtr;
45 "sideFEName is different");
74 boost::shared_ptr<std::vector<BrokenBaseSideData>> broken_base_side_data);
83 template <
typename OpBase>
86 boost::shared_ptr<std::vector<BrokenBaseSideData>> broken_base_side_data)
88 brokenBaseSideData(broken_base_side_data) {}
90 template <
typename OpBase>
99 brokenBaseSideData->resize(OP::getLoopSize());
101 const auto n_in_the_loop = OP::getNinTheLoop();
102 const auto face_sense = OP::getSkeletonSense();
105 if (face_sense != -1 && face_sense != 1)
109 auto set_data = [&](
auto &side_data) {
110 side_data.getSide() = row_side;
111 side_data.getType() = row_type;
112 side_data.getSense() = face_sense;
113 side_data.getData().sEnse = row_data.
sEnse;
114 side_data.getData().sPace = row_data.
sPace;
115 side_data.getData().bAse = row_data.
bAse;
116 side_data.getData().iNdices = row_data.
iNdices;
117 side_data.getData().localIndices = row_data.
localIndices;
118 side_data.getData().dOfs = row_data.
dOfs;
120 side_data.getData().fieldData = row_data.
fieldData;
123 auto set_base = [&](
auto &side_data) {
124 auto base = side_data.getData().getBase();
125 for (
auto dd = 0;
dd != BaseDerivatives::LastDerivative; ++
dd) {
127 side_data.getData().baseFunctionsAndBaseDerivatives[
dd][base] =
128 boost::make_shared<MatrixDouble>(*base_ptr);
133 set_data((*brokenBaseSideData)[n_in_the_loop]);
134 set_base((*brokenBaseSideData)[n_in_the_loop]);
144 boost::shared_ptr<std::vector<BrokenBaseSideData>> broken_base_side_data,
145 boost::shared_ptr<MatrixDouble> flux_ptr);
155 template <
typename OpBase>
157 boost::shared_ptr<std::vector<BrokenBaseSideData>> broken_base_side_data,
158 boost::shared_ptr<MatrixDouble> flux_ptr)
159 :
OP(
NOSPACE,
OP::OPSPACE), brokenBaseSideData(broken_base_side_data),
162 template <
typename OpBase>
166 auto swap_flux = [&](
auto &side_data) { side_data.getFlux().swap(*fluxPtr); };
167 swap_flux((*brokenBaseSideData)[OP::getNinTheLoop()]);
176 boost::shared_ptr<std::vector<BrokenBaseSideData>> broken_base_side_data,
177 boost::shared_ptr<Range> ents_ptr =
nullptr)
183 const std::string row_field,
184 boost::shared_ptr<std::vector<BrokenBaseSideData>> broken_base_side_data,
185 const bool assmb_transpose,
const bool only_transpose,
186 boost::shared_ptr<Range> ents_ptr =
nullptr)
187 :
OP(row_field, row_field,
OP::OPROW, ents_ptr),
202 template <
typename OpBase>
209 if (OP::entsPtr->find(this->getFEEntityHandle()) == OP::entsPtr->end())
214 if (!brokenBaseSideData) {
219 auto do_work_rhs = [
this](
int row_side, EntityType row_type,
223 OP::nbRows = row_data.getIndices().size();
227 OP::nbIntegrationPts = OP::getGaussPts().size2();
229 OP::nbRowBaseFunctions = OP::getNbOfBaseFunctions(row_data);
231 OP::locF.resize(OP::nbRows,
false);
234 CHKERR this->iNtegrate(row_data);
237 CHKERR this->aSsemble(row_data);
241 auto do_work_lhs = [
this](
int row_side,
int col_side, EntityType row_type,
247 auto check_if_assemble_transpose = [&] {
249 if (OP::rowSide != OP::colSide || OP::rowType != OP::colType)
253 }
else if (OP::assembleTranspose) {
259 OP::rowSide = row_side;
260 OP::rowType = row_type;
261 OP::colSide = col_side;
262 OP::colType = col_type;
263 OP::nbCols = col_data.getIndices().size();
264 OP::locMat.resize(OP::nbRows, OP::nbCols,
false);
266 CHKERR this->iNtegrate(row_data, col_data);
268 CHKERR this->aSsemble(row_data, col_data, check_if_assemble_transpose());
272 switch (OP::opType) {
275 OP::nbRows = row_data.getIndices().size();
278 OP::nbIntegrationPts = OP::getGaussPts().size2();
279 OP::nbRowBaseFunctions = OP::getNbOfBaseFunctions(row_data);
284 for (
auto &bd : *brokenBaseSideData) {
287 if (bd.getData().getSpace() !=
HDIV && bd.getData().getSpace() !=
HCURL) {
289 (std::string(
"Expect Hdiv or Hcurl space but received ") +
293 if (!bd.getData().getNSharedPtr(bd.getData().getBase())) {
295 "base functions not set");
302 row_side, bd.getSide(),
305 row_type, bd.getType(),
308 row_data, bd.getData(),
318 for (
auto &bd : *brokenBaseSideData) {
319 CHKERR do_work_rhs(bd.getSide(), bd.getType(), bd.getData(),
325 (std::string(
"wrong op type ") +
333 template <
int FIELD_DIM, IntegrationType I,
typename OpBrokenBase>
336 template <
int FIELD_DIM,
typename OpBrokenBase>
343 const std::string row_field,
344 boost::shared_ptr<std::vector<BrokenBaseSideData>> broken_base_side_data,
345 const double beta,
const bool assmb_transpose,
const bool only_transpose)
346 :
OP(row_field, broken_base_side_data, assmb_transpose, only_transpose),
355 template <
int FIELD_DIM,
typename OpBase>
361 auto nb_row_dofs = row_data.
getIndices().size();
362 auto nb_col_dofs = col_data.
getIndices().size();
363 if (!nb_row_dofs || !nb_col_dofs)
369 auto t_w = this->getFTensor0IntegrationWeight();
370 auto t_normal = OpBase::getFTensor1NormalsAtGaussPts();
371 size_t nb_base_functions = col_data.
getN().size2() / 3;
376 "number of dofs not divisible by field dimension");
381 "number of dofs exceeds number of base functions");
390 for (; cc != nb_col_dofs /
FIELD_DIM; cc++) {
392 for (
auto rr = 0; rr != nb_row_dofs /
FIELD_DIM; ++rr) {
394 (t_w * t_row_base) * (t_normal(
J) * t_col_base(
J));
401 for (; cc < nb_base_functions; ++cc)
408 for (
auto rr = 0; rr != nb_row_dofs /
FIELD_DIM; ++rr) {
409 for (
auto cc = 0; cc != nb_col_dofs /
FIELD_DIM; ++cc) {
417 OP::locMat *= scalarBeta;
422 template <
int FIELD_DIM, IntegrationType I,
typename OpBase>
425 template <
int FIELD_DIM, IntegrationType I,
typename OpBase>
428 template <
int FIELD_DIM,
typename OpBrokenBase>
435 boost::shared_ptr<std::vector<BrokenBaseSideData>> broken_base_side_data,
436 boost::shared_ptr<MatrixDouble> lagrange_ptr,
const double beta)
437 :
OP(broken_base_side_data), scalarBeta(beta), lagrangePtr(lagrange_ptr) {
447 template <
int FIELD_DIM,
typename OpBase>
456 auto t_w = this->getFTensor0IntegrationWeight();
457 auto t_normal = OpBase::getFTensor1NormalsAtGaussPts();
458 auto t_lagrange = getFTensor1FromMat<FIELD_DIM>(*lagrangePtr);
461 auto nb_base_functions = row_data.
getN().size2() / 3;
464 auto t_vec = getFTensor1FromPtr<FIELD_DIM>(&*OP::locF.data().begin());
467 t_vec(
i) += (t_w * (t_row_base(
J) * t_normal(
J))) * t_lagrange(
i);
471 for (; rr < nb_base_functions; ++rr)
478 OP::locF *= scalarBeta;
483 template <
int FIELD_DIM,
typename OpBase>
490 const std::string row_field,
491 boost::shared_ptr<std::vector<BrokenBaseSideData>> broken_side_data_ptr,
494 brokenSideDataPtr(broken_side_data_ptr), scalarBeta(beta) {}
502 template <
int FIELD_DIM,
typename OpBase>
511 OP::locF.resize(row_data.
getIndices().size(),
false);
514 for (
auto &bd : *brokenSideDataPtr) {
515 auto t_w = this->getFTensor0IntegrationWeight();
516 auto t_normal = OpBase::getFTensor1NormalsAtGaussPts();
518 auto t_flux = getFTensor2FromMat<FIELD_DIM, 3>(bd.getFlux());
519 auto nb_base_functions = row_data.
getN().size2() / 3;
520 auto sense = bd.getSense();
522 auto t_vec = getFTensor1FromPtr<FIELD_DIM>(&*OP::locF.data().begin());
525 t_vec(
i) += (sense * t_w) * t_row_base * t_normal(
J) * t_flux(
i,
J);
529 for (; rr < nb_base_functions; ++rr)
537 OP::locF *= scalarBeta;
544 #endif // __FORMSBROKENSPACECONSTRAINTIMPL_HPP__