//------------------------------------------------------------------------------ // Compute marked boundary length // double CalculateBoundaryLength(Mesh* mesh, int bdryMarker) { // Variables declaration. Element* e; double length = 0; RefMap rm; rm.set_quad_2d(&g_quad_2d_std); Quad2D * quad = rm.get_quad_2d(); int points_location; double3* points; int np; double3* tangents; // Loop through all boundary faces of all active elements. for_all_active_elements(e, mesh) { for(int edge = 0; edge < e->nvert; ++edge) { if ((e->en[edge]->bnd) && (e->en[edge]->marker == bdryMarker)) { rm.set_active_element(e); points_location = quad->get_edge_points(edge); points = quad->get_points(points_location); np = quad->get_num_points(points_location); tangents = rm.get_tangent(edge, points_location); for(int i = 0; i < np; i++) { // Weights sum up to two on every edge, therefore the division by two must be present. length += 0.5 * points[i][2] * tangents[i][2]; } } } } return length; } // end of CalculateBoundaryLength()
void Orderizer::process_space(SpaceSharedPtr<Scalar> space, bool show_edge_orders) { // sanity check if (space == nullptr) throw Hermes::Exceptions::Exception("Space is nullptr in Orderizer:process_space()."); if (!space->is_up_to_date()) throw Hermes::Exceptions::Exception("The space is not up to date."); MeshSharedPtr mesh = space->get_mesh(); // Reallocate. this->reallocate(mesh); RefMap refmap; int oo, o[6]; // make a mesh illustrating the distribution of polynomial orders over the space Element* e; for_all_active_elements(e, mesh) { oo = o[4] = o[5] = space->get_element_order(e->id); if (show_edge_orders) for (unsigned int k = 0; k < e->get_nvert(); k++) o[k] = space->get_edge_order(e, k); else if (e->is_curved()) { if (e->is_triangle()) for (unsigned int k = 0; k < e->get_nvert(); k++) o[k] = oo; else for (unsigned int k = 0; k < e->get_nvert(); k++) o[k] = H2D_GET_H_ORDER(oo); } double3* pt; int np; double* x; double* y; if (show_edge_orders || e->is_curved()) { refmap.set_quad_2d(&quad_ord); refmap.set_active_element(e); x = refmap.get_phys_x(1); y = refmap.get_phys_y(1); pt = quad_ord.get_points(1, e->get_mode()); np = quad_ord.get_num_points(1, e->get_mode()); } else { refmap.set_quad_2d(&quad_ord_simple); refmap.set_active_element(e); x = refmap.get_phys_x(1); y = refmap.get_phys_y(1); pt = quad_ord_simple.get_points(1, e->get_mode()); np = quad_ord_simple.get_num_points(1, e->get_mode()); } int id[80]; assert(np <= 80); int mode = e->get_mode(); if (e->is_quad()) { o[4] = H2D_GET_H_ORDER(oo); o[5] = H2D_GET_V_ORDER(oo); } if (show_edge_orders || e->is_curved()) { make_vert(lvert[label_count], x[0], y[0], o[4]); for (int i = 1; i < np; i++) make_vert(id[i - 1], x[i], y[i], o[(int)pt[i][2]]); for (int i = 0; i < num_elem[mode][1]; i++) this->add_triangle(id[ord_elem[mode][1][i][0]], id[ord_elem[mode][1][i][1]], id[ord_elem[mode][1][i][2]], e->marker); for (int i = 0; i < num_edge[mode][1]; i++) { if (e->en[ord_edge[mode][1][i][2]]->bnd || (y[ord_edge[mode][1][i][0] + 1] < y[ord_edge[mode][1][i][1] + 1]) || ((y[ord_edge[mode][1][i][0] + 1] == y[ord_edge[mode][1][i][1] + 1]) && (x[ord_edge[mode][1][i][0] + 1] < x[ord_edge[mode][1][i][1] + 1]))) { add_edge(id[ord_edge[mode][1][i][0]], id[ord_edge[mode][1][i][1]], e->en[ord_edge[mode][1][i][2]]->marker); } } } else { make_vert(lvert[label_count], x[0], y[0], o[4]); for (int i = 1; i < np; i++) make_vert(id[i - 1], x[i], y[i], o[(int)pt[i][2]]); for (int i = 0; i < num_elem_simple[mode][1]; i++) this->add_triangle(id[ord_elem_simple[mode][1][i][0]], id[ord_elem_simple[mode][1][i][1]], id[ord_elem_simple[mode][1][i][2]], e->marker); for (int i = 0; i < num_edge_simple[mode][1]; i++) add_edge(id[ord_edge_simple[mode][1][i][0]], id[ord_edge_simple[mode][1][i][1]], e->en[ord_edge_simple[mode][1][i][2]]->marker); } double xmin = 1e100, ymin = 1e100, xmax = -1e100, ymax = -1e100; for (unsigned int k = 0; k < e->get_nvert(); k++) { if (e->vn[k]->x < xmin) xmin = e->vn[k]->x; if (e->vn[k]->x > xmax) xmax = e->vn[k]->x; if (e->vn[k]->y < ymin) ymin = e->vn[k]->y; if (e->vn[k]->y > ymax) ymax = e->vn[k]->y; } lbox[label_count][0] = xmax - xmin; lbox[label_count][1] = ymax - ymin; ltext[label_count++] = labels[o[4]][o[5]]; }
void Orderizer::process_solution(Space* space) { // sanity check if (space == NULL) error("Space is NULL in Orderizer:process_solution()."); if (!space->is_up_to_date()) error("The space is not up to date."); int type = 1; nv = nt = ne = nl = 0; del_slot = -1; // estimate the required number of vertices and triangles Mesh* mesh = space->get_mesh(); if (mesh == NULL) { error("Mesh is NULL in Orderizer:process_solution()."); } int nn = mesh->get_num_active_elements(); int ev = 77 * nn, et = 64 * nn, ee = 16 * nn, el = nn + 10; // reuse or allocate vertex, triangle and edge arrays lin_init_array(verts, double3, cv, ev); lin_init_array(tris, int3, ct, et); lin_init_array(edges, int3, ce, ee); lin_init_array(lvert, int, cl1, el); lin_init_array(ltext, char*, cl2, el); lin_init_array(lbox, double2, cl3, el); info = NULL; int oo, o[6]; RefMap refmap; refmap.set_quad_2d(&quad_ord); // make a mesh illustrating the distribution of polynomial orders over the space Element* e; for_all_active_elements(e, mesh) { oo = o[4] = o[5] = space->get_element_order(e->id); for (unsigned int k = 0; k < e->nvert; k++) o[k] = space->get_edge_order(e, k); refmap.set_active_element(e); double* x = refmap.get_phys_x(type); double* y = refmap.get_phys_y(type); double3* pt = quad_ord.get_points(type); int np = quad_ord.get_num_points(type); int id[80]; assert(np <= 80); #define make_vert(index, x, y, val) \ { (index) = add_vertex(); \ verts[index][0] = (x); \ verts[index][1] = (y); \ verts[index][2] = (val); } int mode = e->get_mode(); if (e->is_quad()) { o[4] = H2D_GET_H_ORDER(oo); o[5] = H2D_GET_V_ORDER(oo); } make_vert(lvert[nl], x[0], y[0], o[4]); for (int i = 1; i < np; i++) make_vert(id[i-1], x[i], y[i], o[(int) pt[i][2]]); for (int i = 0; i < num_elem[mode][type]; i++) add_triangle(id[ord_elem[mode][type][i][0]], id[ord_elem[mode][type][i][1]], id[ord_elem[mode][type][i][2]]); for (int i = 0; i < num_edge[mode][type]; i++) { if (e->en[ord_edge[mode][type][i][2]]->bnd || (y[ord_edge[mode][type][i][0] + 1] < y[ord_edge[mode][type][i][1] + 1]) || ((y[ord_edge[mode][type][i][0] + 1] == y[ord_edge[mode][type][i][1] + 1]) && (x[ord_edge[mode][type][i][0] + 1] < x[ord_edge[mode][type][i][1] + 1]))) { add_edge(id[ord_edge[mode][type][i][0]], id[ord_edge[mode][type][i][1]], 0); } } double xmin = 1e100, ymin = 1e100, xmax = -1e100, ymax = -1e100; for (unsigned int k = 0; k < e->nvert; k++) { if (e->vn[k]->x < xmin) xmin = e->vn[k]->x; if (e->vn[k]->x > xmax) xmax = e->vn[k]->x; if (e->vn[k]->y < ymin) ymin = e->vn[k]->y; if (e->vn[k]->y > ymax) ymax = e->vn[k]->y; } lbox[nl][0] = xmax - xmin; lbox[nl][1] = ymax - ymin; ltext[nl++] = labels[o[4]][o[5]]; }