634                                                           {
  636 
  637    constexpr bool debug = 
false;
 
  638 
  639    constexpr int numNodes = 3;
  640    constexpr int numEdges = 3;
  641    constexpr int refinementLevels = 4;
  642 
  643    auto &m_field = fe_raw_ptr->
mField;
 
  644    auto fe_ptr = static_cast<Fe *>(fe_raw_ptr);
  645    auto fe_handle = fe_ptr->getFEEntityHandle();
  646 
  647    auto set_base_quadrature = [&]() {
  649      int rule = 
funRule(order_data);
 
  653        }
  657        }
  659        fe_ptr->gaussPts.resize(3, nb_gauss_pts, false);
  660        cblas_dcopy(nb_gauss_pts, &
QUAD_2D_TABLE[rule]->points[1], 3,
 
  661                    &fe_ptr->gaussPts(0, 0), 1);
  662        cblas_dcopy(nb_gauss_pts, &
QUAD_2D_TABLE[rule]->points[2], 3,
 
  663                    &fe_ptr->gaussPts(1, 0), 1);
  665                    &fe_ptr->gaussPts(2, 0), 1);
  666        auto &data = fe_ptr->dataOnElement[
H1];
 
  667        data->dataOnEntities[MBVERTEX][0].getN(
NOBASE).resize(nb_gauss_pts, 3,
 
  668                                                              false);
  669        double *shape_ptr =
  670            &*data->dataOnEntities[MBVERTEX][0].getN(
NOBASE).data().begin();
 
  671        cblas_dcopy(3 * nb_gauss_pts, 
QUAD_2D_TABLE[rule]->points, 1, shape_ptr,
 
  672                    1);
  673        data->dataOnEntities[MBVERTEX][0].getDiffN(
NOBASE).resize(3, 2, 
false);
 
  674        std::copy(
  676            data->dataOnEntities[MBVERTEX][0].getDiffN(
NOBASE).data().begin());
 
  677 
  678      } else {
  681      }
  683    };
  684 
  685    CHKERR set_base_quadrature();
 
  686 
  688 
  689      auto get_singular_nodes = [&]() {
  690        int num_nodes;
  692        CHKERR m_field.get_moab().get_connectivity(fe_handle, conn, num_nodes,
 
  693                                                   true);
  694        std::bitset<numNodes> singular_nodes;
  695        for (auto nn = 0; nn != numNodes; ++nn) {
  697            singular_nodes.set(nn);
  698          } else {
  699            singular_nodes.reset(nn);
  700          }
  701        }
  702        return singular_nodes;
  703      };
  704 
  705      auto get_singular_edges = [&]() {
  706        std::bitset<numEdges> singular_edges;
  707        for (int ee = 0; ee != numEdges; ee++) {
  709          CHKERR m_field.get_moab().side_element(fe_handle, 1, ee, edge);
 
  711            singular_edges.set(ee);
  712          } else {
  713            singular_edges.reset(ee);
  714          }
  715        }
  716        return singular_edges;
  717      };
  718 
  719      auto set_gauss_pts = [&](auto &ref_gauss_pts) {
  721        fe_ptr->gaussPts.swap(ref_gauss_pts);
  722        const size_t nb_gauss_pts = fe_ptr->gaussPts.size2();
  723        auto &data = fe_ptr->dataOnElement[
H1];
 
  724        data->dataOnEntities[MBVERTEX][0].getN(
NOBASE).resize(nb_gauss_pts, 4);
 
  725        double *shape_ptr =
  726            &*data->dataOnEntities[MBVERTEX][0].getN(
NOBASE).data().begin();
 
  728                          &fe_ptr->gaussPts(1, 0), nb_gauss_pts);
  730      };
  731 
  732      auto singular_nodes = get_singular_nodes();
  733      if (singular_nodes.count()) {
  734        auto it_map_ref_coords = 
mapRefCoords.find(singular_nodes.to_ulong());
 
  736          CHKERR set_gauss_pts(it_map_ref_coords->second);
 
  738        } else {
  739 
  740          auto refine_quadrature = [&]() {
  742 
  743            const int max_level = refinementLevels;
  744 
  745            moab::Core moab_ref;
  746            double base_coords[] = {0, 0, 0, 1, 0, 0, 0, 1, 0};
  748            for (int nn = 0; nn != numNodes; nn++)
  749              CHKERR moab_ref.create_vertex(&base_coords[3 * nn], nodes[nn]);
 
  751            CHKERR moab_ref.create_element(MBTRI, nodes, numNodes, tri);
 
  754            {
  755              Range tris(tri, tri);
 
  758                  tris, 1, true, edges, moab::Interface::UNION);
  761            }
  762 
  763            Range nodes_at_front;
 
  764            for (int nn = 0; nn != numNodes; nn++) {
  765              if (singular_nodes[nn]) {
  767                CHKERR moab_ref.side_element(tri, 0, nn, ent);
 
  768                nodes_at_front.insert(ent);
  769              }
  770            }
  771 
  772            auto singular_edges = get_singular_edges();
  773 
  775            CHKERR moab_ref.create_meshset(MESHSET_SET, meshset);
 
  776            for (int ee = 0; ee != numEdges; ee++) {
  777              if (singular_edges[ee]) {
  779                CHKERR moab_ref.side_element(tri, 1, ee, ent);
 
  780                CHKERR moab_ref.add_entities(meshset, &ent, 1);
 
  781              }
  782            }
  783 
  784            
  786            for (int ll = 0; ll != max_level; ll++) {
  789                  ->getEntitiesByTypeAndRefLevel(
BitRefLevel().set(ll),
 
  791                                                 edges);
  793              CHKERR moab_ref.get_adjacencies(
 
  794                  nodes_at_front, 1, true, ref_edges, moab::Interface::UNION);
  795              ref_edges = intersect(ref_edges, edges);
  797              CHKERR moab_ref.get_entities_by_type(meshset, MBEDGE, ents, 
true);
 
  798              ref_edges = intersect(ref_edges, ents);
  801                  ->getEntitiesByTypeAndRefLevel(
  803              CHKERR m_ref->addVerticesInTheMiddleOfEdges(
 
  807                  ->updateMeshsetByEntitiesChildren(meshset,
  809                                                    meshset, MBEDGE, true);
  810            }
  811 
  812            
  815                ->getEntitiesByTypeAndRefLevel(
BitRefLevel().set(max_level),
 
  817                                               tris);
  818 
  822            }
  823 
  825            int tt = 0;
  826            for (Range::iterator tit = tris.begin(); tit != tris.end();
  827                 tit++, tt++) {
  828              int num_nodes;
  830              CHKERR moab_ref.get_connectivity(*tit, conn, num_nodes, 
false);
 
  831              CHKERR moab_ref.get_coords(conn, num_nodes, &ref_coords(tt, 0));
 
  832            }
  833 
  834            auto &data = fe_ptr->dataOnElement[
H1];
 
  835            const size_t nb_gauss_pts = fe_ptr->gaussPts.size2();
  836            MatrixDouble ref_gauss_pts(3, nb_gauss_pts * ref_coords.size1());
 
  838                data->dataOnEntities[MBVERTEX][0].getN(
NOBASE);
 
  839            int gg = 0;
  840            for (size_t tt = 0; tt != ref_coords.size1(); tt++) {
  841              double *tri_coords = &ref_coords(tt, 0);
  844              auto det = t_normal.
l2();
 
  845              for (size_t ggg = 0; ggg != nb_gauss_pts; ++ggg, ++gg) {
  846                for (
int dd = 0; 
dd != 2; 
dd++) {
 
  847                  ref_gauss_pts(dd, gg) =
  848                      shape_n(ggg, 0) * tri_coords[3 * 0 + 
dd] +
 
  849                      shape_n(ggg, 1) * tri_coords[3 * 1 + 
dd] +
 
  850                      shape_n(ggg, 2) * tri_coords[3 * 2 + 
dd];
 
  851                }
  852                ref_gauss_pts(2, gg) = fe_ptr->gaussPts(2, ggg) * det;
  853              }
  854            }
  855 
  856            mapRefCoords[singular_nodes.to_ulong()].swap(ref_gauss_pts);
 
  858 
  860          };
  861 
  862          CHKERR refine_quadrature();
 
  863        }
  864      }
  865    }
  866 
  868  }
#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 ...
@ MOFEM_DATA_INCONSISTENCY
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
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)
std::bitset< BITREFLEVEL_SIZE > BitRefLevel
Bit structure attached to each entity identifying to what mesh entity is attached.
#define QUAD_2D_TABLE_SIZE
#define QUAD_3D_TABLE_SIZE
static QUAD *const QUAD_2D_TABLE[]
static PetscBool setSingularity
static std::map< long int, MatrixDouble > mapRefCoords
virtual moab::Interface & get_moab()=0
Deprecated interface functions.
Mesh refinement interface.
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.