VN * IR_GVN::register_qua_vn(IR_TYPE irt, VN const* v0, VN const* v1, VN const* v2, VN const* v3) { IS_TRUE0(v0 && v1 && v2 && v3); IS_TRUE0(is_quad(irt)); VEC4 * v0_vec = (VEC4*)m_irt_vec.get(irt); if (v0_vec == NULL) { v0_vec = new VEC4(); m_vec_lst.append_tail((VEC1*)v0_vec); m_irt_vec.set(irt, (VEC2*)v0_vec); } VEC3 * v1_vec = v0_vec->get(VN_id(v0)); if (v1_vec == NULL) { v1_vec = new VEC3(); m_vec_lst.append_tail((VEC1*)v1_vec); v0_vec->set(VN_id(v0), v1_vec); } VEC2 * v2_vec = v1_vec->get(VN_id(v1)); if (v2_vec == NULL) { v2_vec = new VEC2(); m_vec_lst.append_tail((VEC1*)v2_vec); v1_vec->set(VN_id(v1), v2_vec); } VEC1 * v3_vec = v2_vec->get(VN_id(v2)); if (v3_vec == NULL) { v3_vec = new VEC1(); m_vec_lst.append_tail(v3_vec); m_vnvec_lst.append_tail(v3_vec); v2_vec->set(VN_id(v2), v3_vec); } VN * res = v3_vec->get(VN_id(v3)); if (res == NULL) { res = new_vn(); VN_type(res) = VN_OP; VN_op(res) = irt; v3_vec->set(VN_id(v3), res); } return res; }
bool IR_GVN::verify() { for (INT i = 0; i <= m_irt_vec.get_last_idx(); i++) { if (is_bin_irt((IR_TYPE)i) || i == IR_LDA) { SVECTOR<SVECTOR<VN*>*> * v0_vec = m_irt_vec.get(i); if (v0_vec == NULL) { continue; } for (INT j = 0; j <= v0_vec->get_last_idx(); j++) { SVECTOR<VN*> * v1_vec = v0_vec->get(j); if (v1_vec == NULL) { continue; } //v1_vec->clean(); } } else if (i == IR_BNOT || i == IR_LNOT || i == IR_NEG || i == IR_CVT) { SVECTOR<VN*> * v0_vec = (SVECTOR<VN*>*)m_irt_vec.get(i); if (v0_vec == NULL) { continue; } //v0_vec->clean(); } else if (is_triple((IR_TYPE)i)) { VEC3 * v0_vec = (VEC3*)m_irt_vec.get(i); if (v0_vec == NULL) { continue; } for (INT j = 0; j <= v0_vec->get_last_idx(); j++) { VEC2 * v1_vec = v0_vec->get(j); if (v1_vec == NULL) { continue; } for (INT k = 0; k <= v1_vec->get_last_idx(); k++) { VEC1 * v2_vec = v1_vec->get(k); if (v1_vec == NULL) { continue; } //v2_vec->clean(); } } } else if (is_quad((IR_TYPE)i)) { // } else { IS_TRUE0(m_irt_vec.get(i) == NULL); } } return true; }
void Element::calc_area(bool precise_for_curvature) { // First some basic arithmetics. double ax, ay, bx, by; ax = vn[1]->x - vn[0]->x; ay = vn[1]->y - vn[0]->y; bx = vn[2]->x - vn[0]->x; by = vn[2]->y - vn[0]->y; this->area = 0.5*(ax*by - ay*bx); if (is_quad()) { ax = bx; ay = by; bx = vn[3]->x - vn[0]->x; by = vn[3]->y - vn[0]->y; this->area = area + 0.5*(ax*by - ay*bx); } // Either the basic approximation is fine. if (!this->is_curved() || !precise_for_curvature) return; // Or we want to capture the curvature precisely. else { // Utility data. RefMap refmap_curv; RefMap refmap_straight; double3* tan; double x_center, y_center; this->get_center(x_center, y_center); for (unsigned char isurf = 0; isurf < this->nvert; isurf++) { // 0 - prepare data structures. int eo = g_quad_2d_std.get_edge_points(isurf, this->get_mode() == HERMES_MODE_TRIANGLE ? g_max_tri : g_max_quad, this->get_mode()); unsigned char np = g_quad_2d_std.get_num_points(eo, this->get_mode()); double* x_curv = new double[np]; double* y_curv = new double[np]; double* x_straight = new double[np]; double* y_straight = new double[np]; // 1 - get the x,y coordinates for the curved element. refmap_curv.set_active_element(this); GeomSurf<double> geometry; init_geom_surf_allocated(geometry, &refmap_curv, isurf, this->en[isurf]->marker, eo, tan); memcpy(x_curv, geometry.x, np*sizeof(double)); memcpy(y_curv, geometry.y, np*sizeof(double)); // 2. - act if there was no curvature CurvMap* cm_temp = this->cm; this->cm = nullptr; refmap_straight.set_active_element(this); init_geom_surf_allocated(geometry, &refmap_straight, isurf, this->en[isurf]->marker, eo, tan); memcpy(x_straight, geometry.x, np*sizeof(double)); memcpy(y_straight, geometry.y, np*sizeof(double)); // 3. - compare the two, get the updated area. double previous_distance; for (int i = 0; i < np; i++) { // Distance between the curved and straight edges. double distance_i = std::sqrt(std::pow(x_straight[i] - x_curv[i], 2.0) + std::pow(y_straight[i] - y_curv[i], 2.0)); // Add to- or Subtract from- the area (depends on the curvature and we shall decide based on distance from the element center). double distance_from_center_curved = std::pow(x_center - x_curv[i], 2.0) + std::pow(y_center - y_curv[i], 2.0); double distance_from_center_straight = std::pow(x_center - x_straight[i], 2.0) + std::pow(y_center - y_straight[i], 2.0); bool add = distance_from_center_curved > distance_from_center_straight; // Calculate now the area delta. // It depends on the integration point number etc. double area_delta; if (i == 0) { double distance_along_edge = std::sqrt(std::pow(x_straight[i] - this->vn[isurf]->x, 2.0) + std::pow(y_straight[i] - this->vn[isurf]->y, 2.0)); area_delta = distance_i * distance_along_edge * 0.5; } if (i > 0 && i < np - 1) { double distance_along_edge = std::sqrt(std::pow(x_straight[i] - x_straight[i - 1], 2.0) + std::pow(y_straight[i] - y_straight[i - 1], 2.0)); area_delta = 0.5*(distance_i + previous_distance) * distance_along_edge; } if (i == np - 1) { double distance_along_edge = std::sqrt(std::pow(x_straight[i] - this->vn[(isurf + 1) % this->nvert]->x, 2.0) + std::pow(y_straight[i] - this->vn[(isurf + 1) % this->nvert]->y, 2.0)); area_delta = distance_i * distance_along_edge * 0.5; } if (add) area += area_delta; else area -= area_delta; previous_distance = distance_i; } // 4. - re-add the curvature. this->cm = cm_temp; // clean up delete[] x_curv; delete[] y_curv; delete[] x_straight; delete[] y_straight; } } }