598 constexpr
bool debug =
false;
600 constexpr
int numNodes = 3;
601 constexpr
int numEdges = 3;
602 constexpr
int refinementLevels = 4;
604 auto &m_field = fe_raw_ptr->
mField;
605 auto fe_ptr =
static_cast<Fe *
>(fe_raw_ptr);
606 auto fe_handle = fe_ptr->getFEEntityHandle();
608 auto set_base_quadrature = [&]() {
610 int rule = 2 * (order_data + 1);
620 fe_ptr->gaussPts.resize(3, nb_gauss_pts,
false);
621 cblas_dcopy(nb_gauss_pts, &
QUAD_2D_TABLE[rule]->points[1], 3,
622 &fe_ptr->gaussPts(0, 0), 1);
623 cblas_dcopy(nb_gauss_pts, &
QUAD_2D_TABLE[rule]->points[2], 3,
624 &fe_ptr->gaussPts(1, 0), 1);
626 &fe_ptr->gaussPts(2, 0), 1);
627 auto &data = fe_ptr->dataOnElement[
H1];
628 data->dataOnEntities[MBVERTEX][0].getN(
NOBASE).resize(nb_gauss_pts, 3,
631 &*data->dataOnEntities[MBVERTEX][0].getN(
NOBASE).data().begin();
632 cblas_dcopy(3 * nb_gauss_pts,
QUAD_2D_TABLE[rule]->points, 1, shape_ptr,
634 data->dataOnEntities[MBVERTEX][0].getDiffN(
NOBASE).resize(3, 2,
false);
636 Tools::diffShapeFunMBTRI.begin(), Tools::diffShapeFunMBTRI.end(),
637 data->dataOnEntities[MBVERTEX][0].getDiffN(
NOBASE).data().begin());
646 CHKERR set_base_quadrature();
650 auto get_singular_nodes = [&]() {
653 CHKERR m_field.get_moab().get_connectivity(fe_handle, conn, num_nodes,
655 std::bitset<numNodes> singular_nodes;
656 for (
auto nn = 0; nn != numNodes; ++nn) {
658 singular_nodes.set(nn);
660 singular_nodes.reset(nn);
663 return singular_nodes;
666 auto get_singular_edges = [&]() {
667 std::bitset<numEdges> singular_edges;
668 for (
int ee = 0; ee != numEdges; ee++) {
670 CHKERR m_field.get_moab().side_element(fe_handle, 1, ee, edge);
672 singular_edges.set(ee);
674 singular_edges.reset(ee);
677 return singular_edges;
680 auto set_gauss_pts = [&](
auto &ref_gauss_pts) {
682 fe_ptr->gaussPts.swap(ref_gauss_pts);
683 const size_t nb_gauss_pts = fe_ptr->gaussPts.size2();
684 auto &data = fe_ptr->dataOnElement[
H1];
685 data->dataOnEntities[MBVERTEX][0].getN(
NOBASE).resize(nb_gauss_pts, 4);
687 &*data->dataOnEntities[MBVERTEX][0].getN(
NOBASE).data().begin();
689 &fe_ptr->gaussPts(1, 0), nb_gauss_pts);
693 auto singular_nodes = get_singular_nodes();
694 if (singular_nodes.count()) {
695 auto it_map_ref_coords =
mapRefCoords.find(singular_nodes.to_ulong());
697 CHKERR set_gauss_pts(it_map_ref_coords->second);
701 auto refine_quadrature = [&]() {
704 const int max_level = refinementLevels;
707 double base_coords[] = {0, 0, 0, 1, 0, 0, 0, 1, 0};
709 for (
int nn = 0; nn != numNodes; nn++)
710 CHKERR moab_ref.create_vertex(&base_coords[3 * nn], nodes[nn]);
712 CHKERR moab_ref.create_element(MBTRI, nodes, numNodes, tri);
716 Range tris(tri, tri);
719 tris, 1,
true, edges, moab::Interface::UNION);
724 Range nodes_at_front;
725 for (
int nn = 0; nn != numNodes; nn++) {
726 if (singular_nodes[nn]) {
728 CHKERR moab_ref.side_element(tri, 0, nn, ent);
729 nodes_at_front.insert(ent);
733 auto singular_edges = get_singular_edges();
736 CHKERR moab_ref.create_meshset(MESHSET_SET, meshset);
737 for (
int ee = 0; ee != numEdges; ee++) {
738 if (singular_edges[ee]) {
740 CHKERR moab_ref.side_element(tri, 1, ee, ent);
741 CHKERR moab_ref.add_entities(meshset, &ent, 1);
747 for (
int ll = 0; ll != max_level; ll++) {
750 ->getEntitiesByTypeAndRefLevel(
BitRefLevel().set(ll),
754 CHKERR moab_ref.get_adjacencies(
755 nodes_at_front, 1,
true, ref_edges, moab::Interface::UNION);
756 ref_edges = intersect(ref_edges, edges);
758 CHKERR moab_ref.get_entities_by_type(meshset, MBEDGE, ents,
true);
759 ref_edges = intersect(ref_edges, ents);
762 ->getEntitiesByTypeAndRefLevel(
764 CHKERR m_ref->addVerticesInTheMiddleOfEdges(
768 ->updateMeshsetByEntitiesChildren(meshset,
770 meshset, MBEDGE,
true);
776 ->getEntitiesByTypeAndRefLevel(
BitRefLevel().set(max_level),
787 for (Range::iterator tit = tris.begin(); tit != tris.end();
791 CHKERR moab_ref.get_connectivity(*tit, conn, num_nodes,
false);
792 CHKERR moab_ref.get_coords(conn, num_nodes, &ref_coords(tt, 0));
795 auto &data = fe_ptr->dataOnElement[
H1];
796 const size_t nb_gauss_pts = fe_ptr->gaussPts.size2();
797 MatrixDouble ref_gauss_pts(3, nb_gauss_pts * ref_coords.size1());
799 data->dataOnEntities[MBVERTEX][0].getN(
NOBASE);
801 for (
size_t tt = 0; tt != ref_coords.size1(); tt++) {
802 double *tri_coords = &ref_coords(tt, 0);
804 CHKERR Tools::getTriNormal(tri_coords, &t_normal(0));
805 auto det = t_normal.
l2();
806 for (
size_t ggg = 0; ggg != nb_gauss_pts; ++ggg, ++gg) {
807 for (
int dd = 0;
dd != 2;
dd++) {
808 ref_gauss_pts(
dd, gg) =
809 shape_n(ggg, 0) * tri_coords[3 * 0 +
dd] +
810 shape_n(ggg, 1) * tri_coords[3 * 1 +
dd] +
811 shape_n(ggg, 2) * tri_coords[3 * 2 +
dd];
813 ref_gauss_pts(2, gg) = fe_ptr->gaussPts(2, ggg) * det;
817 mapRefCoords[singular_nodes.to_ulong()].swap(ref_gauss_pts);
823 CHKERR refine_quadrature();