370                                                           {
  372 
  373    constexpr bool debug = 
false;
 
  374 
  375    constexpr int numNodes = 4;
  376    constexpr int numEdges = 6;
  377    constexpr int refinementLevels = 4;
  378 
  379    auto &m_field = fe_raw_ptr->
mField;
 
  380    auto fe_ptr = static_cast<Fe *>(fe_raw_ptr);
  381    auto fe_handle = fe_ptr->getFEEntityHandle();
  382 
  383    auto set_base_quadrature = [&]() {
  385      int rule = 2 * order_data + 1;
  389                  "wrong dimension");
  390        }
  394        }
  396        auto &gauss_pts = fe_ptr->gaussPts;
  397        gauss_pts.resize(4, nb_gauss_pts, false);
  398        cblas_dcopy(nb_gauss_pts, &
QUAD_3D_TABLE[rule]->points[1], 4,
 
  399                    &gauss_pts(0, 0), 1);
  400        cblas_dcopy(nb_gauss_pts, &
QUAD_3D_TABLE[rule]->points[2], 4,
 
  401                    &gauss_pts(1, 0), 1);
  402        cblas_dcopy(nb_gauss_pts, &
QUAD_3D_TABLE[rule]->points[3], 4,
 
  403                    &gauss_pts(2, 0), 1);
  405                    &gauss_pts(3, 0), 1);
  406        auto &data = fe_ptr->dataOnElement[
H1];
 
  407        data->dataOnEntities[MBVERTEX][0].getN(
NOBASE).resize(nb_gauss_pts, 4,
 
  408                                                              false);
  409        double *shape_ptr =
  410            &*data->dataOnEntities[MBVERTEX][0].getN(
NOBASE).data().begin();
 
  411        cblas_dcopy(4 * nb_gauss_pts, 
QUAD_3D_TABLE[rule]->points, 1, shape_ptr,
 
  412                    1);
  413      } else {
  416      }
  418    };
  419 
  420    CHKERR set_base_quadrature();
 
  421 
  423 
  424      auto get_singular_nodes = [&]() {
  425        int num_nodes;
  427        CHKERR m_field.get_moab().get_connectivity(fe_handle, conn, num_nodes,
 
  428                                                   true);
  429        std::bitset<numNodes> singular_nodes;
  430        for (auto nn = 0; nn != numNodes; ++nn) {
  432            singular_nodes.set(nn);
  433          } else {
  434            singular_nodes.reset(nn);
  435          }
  436        }
  437        return singular_nodes;
  438      };
  439 
  440      auto get_singular_edges = [&]() {
  441        std::bitset<numEdges> singular_edges;
  442        for (int ee = 0; ee != numEdges; ee++) {
  444          CHKERR m_field.get_moab().side_element(fe_handle, 1, ee, edge);
 
  446            singular_edges.set(ee);
  447          } else {
  448            singular_edges.reset(ee);
  449          }
  450        }
  451        return singular_edges;
  452      };
  453 
  454      auto set_gauss_pts = [&](auto &ref_gauss_pts) {
  456        fe_ptr->gaussPts.swap(ref_gauss_pts);
  457        const size_t nb_gauss_pts = fe_ptr->gaussPts.size2();
  458        auto &data = fe_ptr->dataOnElement[
H1];
 
  459        data->dataOnEntities[MBVERTEX][0].getN(
NOBASE).resize(nb_gauss_pts, 4);
 
  460        double *shape_ptr =
  461            &*data->dataOnEntities[MBVERTEX][0].getN(
NOBASE).data().begin();
 
  463                          &fe_ptr->gaussPts(1, 0), &fe_ptr->gaussPts(2, 0),
  464                          nb_gauss_pts);
  466      };
  467 
  468      auto singular_nodes = get_singular_nodes();
  469      if (singular_nodes.count()) {
  470        auto it_map_ref_coords = 
mapRefCoords.find(singular_nodes.to_ulong());
 
  472          CHKERR set_gauss_pts(it_map_ref_coords->second);
 
  474        } else {
  475 
  476          auto refine_quadrature = [&]() {
  478 
  479            const int max_level = refinementLevels;
  481 
  482            moab::Core moab_ref;
  483            double base_coords[] = {0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1};
  485            for (int nn = 0; nn != 4; nn++)
  486              CHKERR moab_ref.create_vertex(&base_coords[3 * nn], nodes[nn]);
 
  487            CHKERR moab_ref.create_element(MBTET, nodes, 4, tet);
 
  490            {
  491              Range tets(tet, tet);
 
  494                  tets, 1, true, edges, moab::Interface::UNION);
  497            }
  498 
  499            Range nodes_at_front;
 
  500            for (int nn = 0; nn != numNodes; nn++) {
  501              if (singular_nodes[nn]) {
  503                CHKERR moab_ref.side_element(tet, 0, nn, ent);
 
  504                nodes_at_front.insert(ent);
  505              }
  506            }
  507 
  508            auto singular_edges = get_singular_edges();
  509 
  511            CHKERR moab_ref.create_meshset(MESHSET_SET, meshset);
 
  512            for (int ee = 0; ee != numEdges; ee++) {
  513              if (singular_edges[ee]) {
  515                CHKERR moab_ref.side_element(tet, 1, ee, ent);
 
  516                CHKERR moab_ref.add_entities(meshset, &ent, 1);
 
  517              }
  518            }
  519 
  520            
  522            for (int ll = 0; ll != max_level; ll++) {
  525                  ->getEntitiesByTypeAndRefLevel(
BitRefLevel().set(ll),
 
  527                                                 edges);
  529              CHKERR moab_ref.get_adjacencies(
 
  530                  nodes_at_front, 1, true, ref_edges, moab::Interface::UNION);
  531              ref_edges = intersect(ref_edges, edges);
  533              CHKERR moab_ref.get_entities_by_type(meshset, MBEDGE, ents, 
true);
 
  534              ref_edges = intersect(ref_edges, ents);
  537                  ->getEntitiesByTypeAndRefLevel(
  539              CHKERR m_ref->addVerticesInTheMiddleOfEdges(
 
  543                  ->updateMeshsetByEntitiesChildren(meshset,
  545                                                    meshset, MBEDGE, true);
  546            }
  547 
  548            
  551                ->getEntitiesByTypeAndRefLevel(
BitRefLevel().set(max_level),
 
  553                                               tets);
  554 
  557            }
  558 
  560            int tt = 0;
  561            for (Range::iterator tit = tets.begin(); tit != tets.end();
  562                 tit++, tt++) {
  563              int num_nodes;
  565              CHKERR moab_ref.get_connectivity(*tit, conn, num_nodes, 
false);
 
  566              CHKERR moab_ref.get_coords(conn, num_nodes, &ref_coords(tt, 0));
 
  567            }
  568 
  569            auto &data = fe_ptr->dataOnElement[
H1];
 
  570            const size_t nb_gauss_pts = fe_ptr->gaussPts.size2();
  571            MatrixDouble ref_gauss_pts(4, nb_gauss_pts * ref_coords.size1());
 
  573                data->dataOnEntities[MBVERTEX][0].getN(
NOBASE);
 
  574            int gg = 0;
  575            for (size_t tt = 0; tt != ref_coords.size1(); tt++) {
  576              double *tet_coords = &ref_coords(tt, 0);
  578              det *= 6;
  579              for (size_t ggg = 0; ggg != nb_gauss_pts; ++ggg, ++gg) {
  580                for (
int dd = 0; 
dd != 3; 
dd++) {
 
  581                  ref_gauss_pts(dd, gg) =
  582                      shape_n(ggg, 0) * tet_coords[3 * 0 + 
dd] +
 
  583                      shape_n(ggg, 1) * tet_coords[3 * 1 + 
dd] +
 
  584                      shape_n(ggg, 2) * tet_coords[3 * 2 + 
dd] +
 
  585                      shape_n(ggg, 3) * tet_coords[3 * 3 + 
dd];
 
  586                }
  587                ref_gauss_pts(3, gg) = fe_ptr->gaussPts(3, ggg) * det;
  588              }
  589            }
  590 
  591            mapRefCoords[singular_nodes.to_ulong()].swap(ref_gauss_pts);
 
  593 
  595          };
  596 
  597          CHKERR refine_quadrature();
 
  598        }
  599      }
  600    }
  601 
  603  }
#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_3D_TABLE_SIZE
static QUAD *const QUAD_3D_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.