32 {
34
35 constexpr bool debug =
false;
36
37 constexpr int numNodes = 3;
38 constexpr int numEdges = 3;
39 constexpr int refinementLevels = 1;
40
41 auto &m_field = fe_raw_ptr->mField;
42 auto fe_ptr = static_cast<Fe *>(fe_raw_ptr);
43 auto fe_handle = fe_ptr->getFEEntityHandle();
45 if (type != MBTRI) {
47 "only MBTRI is implemented");
48 }
49
50
51
52 auto set_base_quadrature = [&]() {
54 int rule =
funRule(order_row, order_col, order_data);
58 }
62 }
64 fe_ptr->gaussPts.resize(3, nb_gauss_pts, false);
66 &fe_ptr->gaussPts(0, 0), 1);
68 &fe_ptr->gaussPts(1, 0), 1);
70 &fe_ptr->gaussPts(2, 0), 1);
71 auto &data = fe_ptr->dataOnElement[
H1];
72 data->dataOnEntities[MBVERTEX][0].getN(
NOBASE).resize(nb_gauss_pts, 3,
73 false);
74 double *shape_ptr =
75 &*data->dataOnEntities[MBVERTEX][0].getN(
NOBASE).data().begin();
76 cblas_dcopy(3 * nb_gauss_pts,
QUAD_2D_TABLE[rule]->points, 1, shape_ptr,
77 1);
78 data->dataOnEntities[MBVERTEX][0].getDiffN(
NOBASE).resize(3, 2,
false);
79 std::copy(
81 data->dataOnEntities[MBVERTEX][0].getDiffN(
NOBASE).data().begin());
82
83 } else {
86 }
88 };
89
90 CHKERR set_base_quadrature();
91
93
94 auto get_edges = [&]() {
95 std::bitset<numEdges> edges;
96 for (int ee = 0; ee != numEdges; ee++) {
98 CHKERR m_field.get_moab().side_element(fe_handle, 1, ee, edge);
100 edges.set(ee);
101 } else {
102 edges.reset(ee);
103 }
104 }
105 return edges;
106 };
107
108 auto set_gauss_pts = [&](auto &ref_gauss_pts) {
110 fe_ptr->gaussPts.swap(ref_gauss_pts);
111 const size_t nb_gauss_pts = fe_ptr->gaussPts.size2();
112 auto &data = fe_ptr->dataOnElement[
H1];
113 data->dataOnEntities[MBVERTEX][0].getN(
NOBASE).resize(nb_gauss_pts, 4);
114 auto *shape_ptr =
115 data->dataOnEntities[MBVERTEX][0].getN(
NOBASE).data().data();
117 &fe_ptr->gaussPts(1, 0), nb_gauss_pts);
119 };
120
121 auto refine_quadrature = [&]() {
123
124 const int max_level = refinementLevels;
125
126 moab::Core moab_ref;
127 double base_coords[] = {0, 0, 0, 1, 0, 0, 0, 1, 0};
129 for (int nn = 0; nn != numNodes; nn++)
130 CHKERR moab_ref.create_vertex(&base_coords[3 * nn], nodes[nn]);
132 CHKERR moab_ref.create_element(MBTRI, nodes, numNodes, tri);
135 {
136 Range tris(tri, tri);
138 CHKERR m_field_ref.
get_moab().get_adjacencies(tris, 1,
true, edges,
139 moab::Interface::UNION);
142 }
143
144 auto edges = get_edges();
145
147 CHKERR moab_ref.create_meshset(MESHSET_SET, meshset);
148 for (int ee = 0; ee != numEdges; ee++) {
149 if (edges[ee]) {
151 CHKERR moab_ref.side_element(tri, 1, ee, ent);
152 CHKERR moab_ref.add_entities(meshset, &ent, 1);
153 }
154 }
155
156
157 auto *m_ref = m_field_ref.
getInterface<MeshRefinement>();
158 for (int ll = 0; ll != max_level; ll++) {
160 CHKERR moab_ref.get_entities_by_type(meshset, MBEDGE, ref_edges,
161 true);
165
168 ->getEntitiesByTypeAndRefLevel(
BitRefLevel().set(ll),
170 CHKERR m_ref->addVerticesInTheMiddleOfEdges(
174 ->updateMeshsetByEntitiesChildren(
175 meshset,
BitRefLevel().set(ll + 1), meshset, MBEDGE,
true);
176 }
177
178
181 ->getEntitiesByTypeAndRefLevel(
BitRefLevel().set(max_level),
183
187 }
188
190 int tt = 0;
191 for (Range::iterator tit = tris.begin(); tit != tris.end();
192 tit++, tt++) {
193 int num_nodes;
195 CHKERR moab_ref.get_connectivity(*tit, conn, num_nodes,
false);
196 CHKERR moab_ref.get_coords(conn, num_nodes, &ref_coords(tt, 0));
197 }
198
199 auto &data = fe_ptr->dataOnElement[
H1];
200 const size_t nb_gauss_pts = fe_ptr->gaussPts.size2();
201 MatrixDouble ref_gauss_pts(3, nb_gauss_pts * ref_coords.size1());
203 int gg = 0;
204 for (size_t tt = 0; tt != ref_coords.size1(); tt++) {
205 double *tri_coords = &ref_coords(tt, 0);
208 auto det = t_normal.
l2();
209 for (size_t ggg = 0; ggg != nb_gauss_pts; ++ggg, ++gg) {
210 for (
int dd = 0;
dd != 2;
dd++) {
211 ref_gauss_pts(dd, gg) = shape_n(ggg, 0) * tri_coords[3 * 0 +
dd] +
212 shape_n(ggg, 1) * tri_coords[3 * 1 +
dd] +
213 shape_n(ggg, 2) * tri_coords[3 * 2 +
dd];
214 }
215 ref_gauss_pts(2, gg) = fe_ptr->gaussPts(2, ggg) * det;
216 }
217 }
218
220 };
221
222 CHKERR refine_quadrature();
223 }
224
226 }
#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.
constexpr int order
Order displacement.
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)
UBlasMatrix< double > MatrixDouble
std::bitset< BITREFLEVEL_SIZE > BitRefLevel
Bit structure attached to each entity identifying to what mesh entity is attached.
auto type_from_handle(const EntityHandle h)
get type from entity handle
static auto dg_save_range(moab::Interface &moab, const std::string name, const Range r, std::vector< Tag > tags={})
#define QUAD_2D_TABLE_SIZE
#define QUAD_3D_TABLE_SIZE
static QUAD *const QUAD_2D_TABLE[]
virtual moab::Interface & get_moab()=0
Deprecated interface functions.
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.