15 boost::make_shared<EntitiesFieldData>(MBENTITYSET),
16 boost::make_shared<EntitiesFieldData>(MBENTITYSET),
17 boost::make_shared<EntitiesFieldData>(MBENTITYSET),
18 boost::make_shared<EntitiesFieldData>(MBENTITYSET),
19 boost::make_shared<EntitiesFieldData>(MBENTITYSET)
25 boost::make_shared<EntitiesFieldData>(MBENTITYSET),
26 boost::make_shared<EntitiesFieldData>(MBENTITYSET),
27 boost::make_shared<EntitiesFieldData>(MBENTITYSET),
28 boost::make_shared<EntitiesFieldData>(MBENTITYSET),
29 boost::make_shared<EntitiesFieldData>(MBENTITYSET)
35 boost::make_shared<DerivedEntitiesFieldData>(dataOnMaster[
NOFIELD]),
36 boost::make_shared<DerivedEntitiesFieldData>(dataOnMaster[
H1]),
37 boost::make_shared<DerivedEntitiesFieldData>(dataOnMaster[
HCURL]),
38 boost::make_shared<DerivedEntitiesFieldData>(dataOnMaster[
HDIV]),
39 boost::make_shared<DerivedEntitiesFieldData>(dataOnMaster[
L2])
45 boost::make_shared<DerivedEntitiesFieldData>(dataOnSlave[
NOFIELD]),
46 boost::make_shared<DerivedEntitiesFieldData>(dataOnSlave[
H1]),
47 boost::make_shared<DerivedEntitiesFieldData>(dataOnSlave[
HCURL]),
48 boost::make_shared<DerivedEntitiesFieldData>(dataOnSlave[
HDIV]),
49 boost::make_shared<DerivedEntitiesFieldData>(dataOnSlave[
L2])
52 dataH1Master(*dataOnMaster[
H1].get()),
53 dataH1Slave(*dataOnSlave[
H1].get()),
54 dataNoFieldSlave(*dataOnSlave[
NOFIELD].get()),
55 dataNoFieldMaster(*dataOnMaster[
NOFIELD].get()),
56 dataHcurlMaster(*dataOnMaster[
HCURL].get()),
57 dataHcurlSlave(*dataOnSlave[
HCURL].get()),
58 dataHdivMaster(*dataOnMaster[
HDIV].get()),
59 dataL2Master(*dataOnMaster[
L2].get()),
60 dataHdivSlave(*dataOnSlave[
HDIV].get()),
61 dataL2Slave(*dataOnSlave[
L2].get()), opContravariantTransform() {
63 getUserPolynomialBase() =
64 boost::shared_ptr<BaseFunction>(
new TriPolynomialBase());
67 dataOnMaster[
H1]->setElementType(MBTRI);
68 derivedDataOnMaster[
H1]->setElementType(MBTRI);
69 dataOnSlave[
H1]->setElementType(MBTRI);
70 derivedDataOnSlave[
H1]->setElementType(MBTRI);
72 dataOnMaster[
HDIV]->setElementType(MBTRI);
73 derivedDataOnMaster[
HDIV]->setElementType(MBTRI);
74 dataOnSlave[
HDIV]->setElementType(MBTRI);
75 derivedDataOnSlave[
HDIV]->setElementType(MBTRI);
77 dataOnMaster[
NOFIELD]->dataOnEntities[MBENTITYSET].push_back(
79 dataOnSlave[
NOFIELD]->dataOnEntities[MBENTITYSET].push_back(
82 derivedDataOnMaster[
NOFIELD]->dataOnEntities[MBENTITYSET].push_back(
84 derivedDataOnSlave[
NOFIELD]->dataOnEntities[MBENTITYSET].push_back(
88 "Problem with creation data on element");
123 double *shape_ptr_master =
126 shape_ptr_master, 1);
127 double *shape_ptr_slave =
151 auto get_coord_and_normal = [&]() {
156 coords.resize(num_nodes * 3,
false);
172 &vec_double(
r + 0), &vec_double(
r + 1), &vec_double(
r + 2));
175 auto t_coords_master = get_vec_ptr(
coords);
176 auto t_coords_slave = get_vec_ptr(
coords, 9);
177 auto t_normal_master = get_vec_ptr(
normal);
178 auto t_normal_slave = get_vec_ptr(
normal, 3);
187 &diff_ptr[0], &diff_ptr[1]);
195 for (
int nn = 0; nn != 3; ++nn) {
196 t_t1_master(
i) += t_coords_master(
i) * t_diff(N0);
197 t_t1_slave(
i) += t_coords_slave(
i) * t_diff(N0);
203 aRea[0] = sqrt(t_normal_master(
i) * t_normal_master(
i)) / 2.;
204 aRea[1] = sqrt(t_normal_slave(
i) * t_normal_slave(
i)) / 2.;
213 CHKERR get_coord_and_normal();
227 CHKERR getEntitySense<MBEDGE>(data_curl);
228 CHKERR getEntityDataOrder<MBEDGE>(data_curl,
HCURL);
229 CHKERR getEntitySense<MBTRI>(data_curl);
230 CHKERR getEntityDataOrder<MBTRI>(data_curl,
HCURL);
235 CHKERR getEntitySense<MBTRI>(data_div);
236 CHKERR getEntityDataOrder<MBTRI>(data_div,
HDIV);
244 CHKERR getEntitySense<MBTRI>(data_l2);
245 CHKERR getEntityDataOrder<MBTRI>(data_l2,
L2);
251 for (EntityType
t = MBVERTEX;
t != MBMAXTYPE; ++
t) {
252 data.spacesOnEntities[
t].reset();
253 data.basesOnEntities[
t].reset();
256 data.basesOnSpaces[s].reset();
265 if (shift != 0 && shift != 6) {
267 "Wrong shift for contact prism element");
270 data.
bAse = copy_data.bAse;
271 for (
auto t : {MBVERTEX, MBEDGE, MBTRI}) {
278 for (
int ii = 0; ii != 3; ++ii) {
280 copy_data.dataOnEntities[MBEDGE][ii + shift].getSense();
282 copy_data.dataOnEntities[MBEDGE][ii + shift].getOrder();
287 copy_data.dataOnEntities[MBTRI][3].getSense();
289 copy_data.dataOnEntities[MBTRI][3].getOrder();
292 copy_data.dataOnEntities[MBTRI][4].getSense();
294 copy_data.dataOnEntities[MBTRI][4].getOrder();
304 if (shift != 3 && shift != 4) {
306 "Wrong shift for contact prism element");
309 data.
bAse = copy_data.bAse;
311 for (
auto t : {MBVERTEX, MBTRI}) {
317 auto &cpy_ent_dat = copy_data.dataOnEntities[MBTRI][shift];
319 ent_dat.getBase() = cpy_ent_dat.getBase();
320 ent_dat.getSpace() = cpy_ent_dat.getSpace();
321 ent_dat.getSense() = ent_dat.getSense();
322 ent_dat.getOrder() = cpy_ent_dat.getOrder();
335 int rule =
getRule(order_row, order_col, order_data);
347 "Number of Gauss Points at Master triangle is different than slave");
364 CHKERR Tools::shapeFunMBTRI<1>(
378 for (
int dd = 0;
dd < 3;
dd++) {
462 "Not yet implemented");
466 "Not yet implemented");
471 "Not yet implemented");
485 constexpr std::array<UserDataOperator::OpType, 2> types{
487 std::array<std::string, 2> last_eval_field_name{std::string(), std::string()};
492 for (; oit != hi_oit; oit++) {
499 switch (oit->sPace) {
510 "Not implemented for this space", oit->sPace);
515 dataOnSlave[oit->sPace]->resetFieldDependentData();
525 boost::shared_ptr<EntitiesFieldData> op_master_data[2];
526 boost::shared_ptr<EntitiesFieldData> op_slave_data[2];
528 for (
int ss = 0; ss != 2; ss++) {
531 !ss ? oit->rowFieldName : oit->colFieldName;
540 if ((oit->getNumeredEntFiniteElementPtr()->getBitFieldIdData() &
544 "no data field < %s > on finite element < %s >",
547 if (oit->getOpType() & types[ss] ||
562 "Not implemented for this space", space);
571 boost::weak_ptr<EntityCacheNumeredDofs>
572 operator()(boost::shared_ptr<FieldEntity> &e) {
573 return e->entityCacheRowDofs;
579 MBPRISM, Extractor());
582 boost::weak_ptr<EntityCacheNumeredDofs>
583 operator()(boost::shared_ptr<FieldEntity> &e) {
584 return e->entityCacheColDofs;
589 MBPRISM, Extractor());
599 auto get_indices = [&](
auto &master,
auto &slave,
auto &ents,
603 master.dataOnEntities[MBVERTEX][0].getIndices(),
604 master.dataOnEntities[MBVERTEX][0].getLocalIndices(),
605 slave.dataOnEntities[MBVERTEX][0].getIndices(),
606 slave.dataOnEntities[MBVERTEX][0].getLocalIndices(), ex);
614 slave_data.dataOnEntities[MBVERTEX][0].getFieldData(),
616 slave_data.dataOnEntities[MBVERTEX][0].getFieldDofs(),
618 slave_data.dataOnEntities[MBVERTEX][0].getFieldEntities(),
620 slave_data.dataOnEntities[MBVERTEX][0].getSpace(),
622 slave_data.dataOnEntities[MBVERTEX][0].getBase());
628 boost::weak_ptr<EntityCacheNumeredDofs>
629 operator()(boost::shared_ptr<FieldEntity> &e) {
630 return e->entityCacheRowDofs;
634 CHKERR get_indices(*op_master_data[ss], *op_slave_data[ss],
638 boost::weak_ptr<EntityCacheNumeredDofs>
639 operator()(boost::shared_ptr<FieldEntity> &e) {
640 return e->entityCacheColDofs;
644 CHKERR get_indices(*op_master_data[ss], *op_slave_data[ss],
648 CHKERR get_data(*op_master_data[ss], *op_slave_data[ss]);
673 "Not implemented for this space", space);
684 type = cast_oit->getFaceType();
692 "Wrong combination of FaceType and OpType, OPROW or OPCOL "
693 "combined with face-face OpType");
700 "Wrong combination of FaceType and OpType, OPROWCOL "
701 "combined with face-face OpType");
706 "Face type is not set");
719 CHKERR oit->opRhs(*op_master_data[0],
false);
727 CHKERR oit->opRhs(*op_slave_data[0],
false);
735 CHKERR oit->opRhs(*op_master_data[1],
false);
743 CHKERR oit->opRhs(*op_slave_data[1],
false);
751 CHKERR oit->opLhs(*op_master_data[0], *op_master_data[1]);
759 CHKERR oit->opLhs(*op_master_data[0], *op_slave_data[1]);
767 CHKERR oit->opLhs(*op_slave_data[0], *op_master_data[1]);
775 CHKERR oit->opLhs(*op_slave_data[0], *op_slave_data[1]);
786 const std::string &
field_name,
const EntityType type_lo,
787 const EntityType type_hi)
const {
790 auto reset_data = [type_lo, type_hi](
auto &data) {
791 for (EntityType
t = type_lo;
t != type_hi; ++
t) {
792 for (
auto &dat : data.dataOnEntities[
t]) {
796 dat.getFieldData().resize(0,
false);
797 dat.getFieldDofs().resize(0,
false);
798 dat.getFieldEntities().resize(0,
false);
802 reset_data(master_data);
803 reset_data(slave_data);
809 auto lo = std::lower_bound(field_ents.begin(), field_ents.end(), lo_uid,
811 if (lo != field_ents.end()) {
814 auto hi = std::upper_bound(lo, field_ents.end(), hi_uid,
cmp_uid_hi);
816 for (
auto it = lo; it != hi; ++it)
817 if (
auto e = it->lock()) {
819 auto get_data = [&](
auto &data,
auto type,
auto side) {
820 auto &dat = data.dataOnEntities[
type][side];
821 auto &ent_field_dofs = dat.getFieldDofs();
822 auto &ent_field_data = dat.getFieldData();
823 dat.getFieldEntities().resize(1,
false);
824 dat.getFieldEntities()[0] = e.get();
825 dat.getBase() = e->getApproxBase();
826 dat.getSpace() = e->getSpace();
827 const int ent_order = e->getMaxOrder();
829 dat.getOrder() > ent_order ? dat.getOrder() : ent_order;
830 const auto dof_ent_field_data = e->getEntFieldData();
831 const int nb_dofs_on_ent = e->getNbDofsOnEnt();
832 ent_field_data.resize(nb_dofs_on_ent,
false);
833 noalias(ent_field_data) = e->getEntFieldData();
834 ent_field_dofs.resize(nb_dofs_on_ent,
false);
835 std::fill(ent_field_dofs.begin(), ent_field_dofs.end(),
nullptr);
836 if (
auto cache = e->entityCacheDataDofs.lock()) {
837 for (
auto dit = cache->loHi[0]; dit != cache->loHi[1]; ++dit) {
838 ent_field_dofs[(*dit)->getEntDofIdx()] =
844 const EntityType
type = e->getEntType();
845 const int side = e->getSideNumberPtr()->side_number;
851 get_data(master_data,
type, side);
853 get_data(slave_data,
type, side - 6);
859 get_data(master_data,
type, 0);
861 get_data(slave_data,
type, 0);
866 "Entity type not implemented (FIXME)");
869 const int brother_side = e->getSideNumberPtr()->brother_side_number;
870 if (brother_side != -1)
872 "Case with brother side not implemented (FIXME)");
893 auto set_zero = [](
auto &nodes_data,
auto &nodes_dofs,
auto &field_entities) {
894 nodes_data.resize(0,
false);
895 nodes_dofs.resize(0,
false);
896 field_entities.resize(0,
false);
898 set_zero(master_nodes_data, master_nodes_dofs, master_field_entities);
899 set_zero(slave_nodes_data, slave_nodes_dofs, slave_field_entities);
904 auto bit_number = (*field_it)->getBitNumber();
905 const int nb_dofs_on_vert = (*field_it)->getNbOfCoeffs();
906 master_space = slave_space = (*field_it)->getSpace();
907 master_base = slave_base = (*field_it)->getApproxBase();
911 bit_number, get_id_for_min_type<MBVERTEX>());
912 auto lo = std::lower_bound(field_ents.begin(), field_ents.end(), lo_uid,
914 if (lo != field_ents.end()) {
916 bit_number, get_id_for_max_type<MBVERTEX>());
917 auto hi = std::upper_bound(lo, field_ents.end(), hi_uid,
cmp_uid_hi);
921 for (
auto it = lo; it != hi; ++it) {
922 if (
auto e = it->lock()) {
923 nb_dofs += e->getEntFieldData().size();
929 auto init_set = [&](
auto &nodes_data,
auto &nodes_dofs,
930 auto &field_entities) {
931 constexpr
int num_nodes = 3;
932 const int max_nb_dofs = nb_dofs_on_vert * num_nodes;
933 nodes_data.resize(max_nb_dofs,
false);
934 nodes_dofs.resize(max_nb_dofs,
false);
935 field_entities.resize(num_nodes,
false);
937 fill(nodes_dofs.begin(), nodes_dofs.end(),
nullptr);
938 fill(field_entities.begin(), field_entities.end(),
nullptr);
941 init_set(master_nodes_data, master_nodes_dofs, master_field_entities);
942 init_set(slave_nodes_data, slave_nodes_dofs, slave_field_entities);
944 for (
auto it = lo; it != hi; ++it) {
945 if (
auto e = it->lock()) {
947 const auto &sn = e->getSideNumberPtr();
948 int side = sn->side_number;
950 auto set_data = [&](
auto &nodes_data,
auto &nodes_dofs,
951 auto &field_entities,
int side,
int pos) {
952 field_entities[side] = e.get();
953 if (
auto cache = e->entityCacheDataDofs.lock()) {
954 for (
auto dit = cache->loHi[0]; dit != cache->loHi[1];
956 const auto dof_idx = (*dit)->getEntDofIdx();
957 nodes_data[pos + dof_idx] = (*dit)->getFieldData();
958 nodes_dofs[pos + dof_idx] =
965 set_data(master_nodes_data, master_nodes_dofs,
966 master_field_entities, side, side * nb_dofs_on_vert);
968 set_data(slave_nodes_data, slave_nodes_dofs,
969 slave_field_entities, (side - 3),
970 (side - 3) * nb_dofs_on_vert);
972 const int brother_side = sn->brother_side_number;
973 if (brother_side != -1)
975 "Not implemented (FIXME please)");
986 template <
typename EXTRACTOR>
990 const EntityType type_lo,
const EntityType type_hi,
991 EXTRACTOR &&extractor)
const {
994 auto clear_data = [type_lo, type_hi](
auto &data) {
995 for (EntityType
t = type_lo;
t != type_hi; ++
t) {
996 for (
auto &
d : data.dataOnEntities[
t]) {
997 d.getIndices().resize(0,
false);
998 d.getLocalIndices().resize(0,
false);
1003 clear_data(master_data);
1004 clear_data(slave_data);
1009 auto lo = std::lower_bound(ents_field.begin(), ents_field.end(), lo_uid,
1011 if (lo != ents_field.end()) {
1014 auto hi = std::upper_bound(lo, ents_field.end(), hi_uid,
cmp_uid_hi);
1017 std::vector<boost::weak_ptr<FieldEntity>> brother_ents_vec;
1019 for (
auto it = lo; it != hi; ++it)
1020 if (
auto e = it->lock()) {
1022 const EntityType
type = e->getEntType();
1023 const int side = e->getSideNumberPtr()->side_number;
1024 const int brother_side = e->getSideNumberPtr()->brother_side_number;
1025 if (brother_side != -1)
1027 "Not implemented case");
1029 auto get_indices = [&](
auto &data,
const auto type,
const auto side) {
1030 if (
auto cache = extractor(e).lock()) {
1031 for (
auto dit = cache->loHi[0]; dit != cache->loHi[1]; ++dit) {
1032 auto &dof = (**dit);
1033 auto &dat = data.dataOnEntities[
type][side];
1034 auto &ent_field_indices = dat.getIndices();
1035 auto &ent_field_local_indices = dat.getLocalIndices();
1036 if (ent_field_indices.empty()) {
1037 const int nb_dofs_on_ent = dof.getNbDofsOnEnt();
1038 ent_field_indices.resize(nb_dofs_on_ent,
false);
1039 ent_field_local_indices.resize(nb_dofs_on_ent,
false);
1040 std::fill(ent_field_indices.data().begin(),
1041 ent_field_indices.data().end(), -1);
1042 std::fill(ent_field_local_indices.data().begin(),
1043 ent_field_local_indices.data().end(), -1);
1045 const int idx = dof.getEntDofIdx();
1046 ent_field_indices[idx] = dof.getPetscGlobalDofIdx();
1047 ent_field_local_indices[idx] = dof.getPetscLocalDofIdx();
1056 get_indices(master_data,
type, side);
1058 get_indices(slave_data,
type, side - 6);
1064 get_indices(master_data,
type, 0);
1066 get_indices(slave_data,
type, 0);
1071 "Entity type not implemented");
1080 template <
typename EXTRACTOR>
1085 EXTRACTOR &&extractor)
const {
1088 master_nodes_indices.resize(0,
false);
1089 master_local_nodes_indices.resize(0,
false);
1090 slave_nodes_indices.resize(0,
false);
1091 slave_local_nodes_indices.resize(0,
false);
1096 auto bit_number = (*field_it)->getBitNumber();
1097 const int nb_dofs_on_vert = (*field_it)->getNbOfCoeffs();
1100 bit_number, get_id_for_min_type<MBVERTEX>());
1101 auto lo = std::lower_bound(ents_field.begin(), ents_field.end(), lo_uid,
1103 if (lo != ents_field.end()) {
1105 bit_number, get_id_for_max_type<MBVERTEX>());
1106 auto hi = std::upper_bound(lo, ents_field.end(), hi_uid,
cmp_uid_hi);
1110 for (
auto it = lo; it != hi; ++it) {
1111 if (
auto e = it->lock()) {
1112 if (
auto cache = extractor(e).lock()) {
1113 nb_dofs += std::distance(cache->loHi[0], cache->loHi[1]);
1120 constexpr
int num_nodes = 3;
1121 const int max_nb_dofs = nb_dofs_on_vert * num_nodes;
1123 auto set_vec_size = [&](
auto &nodes_indices,
1124 auto &local_nodes_indices) {
1125 nodes_indices.resize(max_nb_dofs,
false);
1126 local_nodes_indices.resize(max_nb_dofs,
false);
1127 std::fill(nodes_indices.begin(), nodes_indices.end(), -1);
1128 std::fill(local_nodes_indices.begin(), local_nodes_indices.end(),
1132 set_vec_size(master_nodes_indices, master_local_nodes_indices);
1133 set_vec_size(slave_nodes_indices, slave_local_nodes_indices);
1135 for (
auto it = lo; it != hi; ++it) {
1136 if (
auto e = it->lock()) {
1138 const int side = e->getSideNumberPtr()->side_number;
1139 const int brother_side =
1140 e->getSideNumberPtr()->brother_side_number;
1141 if (brother_side != -1)
1143 "Not implemented case");
1145 auto get_indices = [&](
auto &nodes_indices,
1146 auto &local_nodes_indices,
1148 if (
auto cache = extractor(e).lock()) {
1149 for (
auto dit = cache->loHi[0]; dit != cache->loHi[1];
1151 const int idx = (*dit)->getPetscGlobalDofIdx();
1152 const int local_idx = (*dit)->getPetscLocalDofIdx();
1154 side * nb_dofs_on_vert + (*dit)->getDofCoeffIdx();
1155 nodes_indices[pos] = idx;
1156 local_nodes_indices[pos] = local_idx;
1162 get_indices(master_nodes_indices, master_local_nodes_indices,
1165 get_indices(slave_nodes_indices, slave_local_nodes_indices,
1182 const string fe_name,
1184 const int side_type,
const EntityHandle ent_for_side) {
1185 return loopSide(fe_name, &fe_method, side_type, ent_for_side);