// Custom function to calculate drag coefficient. double integrate_over_wall(MeshFunction<double>* meshfn, int marker) { Quad2D* quad = &g_quad_2d_std; meshfn->set_quad_2d(quad); double integral = 0.0; Element* e; MeshSharedPtr mesh = meshfn->get_mesh(); for_all_active_elements(e, mesh) { for (int edge = 0; edge < e->get_nvert(); edge++) { if ((e->en[edge]->bnd) && (e->en[edge]->marker == marker)) { update_limit_table(e->get_mode()); RefMap* ru = meshfn->get_refmap(); meshfn->set_active_element(e); int eo = quad->get_edge_points(edge, quad->get_max_order(e->get_mode()), e->get_mode()); meshfn->set_quad_order(eo, H2D_FN_VAL); const double *uval = meshfn->get_fn_values(); double3* pt = quad->get_points(eo, e->get_mode()); double3* tan = ru->get_tangent(edge); for (int i = 0; i < quad->get_num_points(eo, e->get_mode()); i++) integral += pt[i][2] * uval[i] * tan[i][2]; } } } return integral * 0.5; }
int RefMap::calc_inv_ref_order() { Quad2D* quad = get_quad_2d(); int i, o, mo = quad->get_max_order(); // check first the positivity of the jacobian double3* pt = quad->get_points(mo); double2x2* m = get_inv_ref_map(mo); double* jac = get_jacobian(mo); for (i = 0; i < quad->get_num_points(mo); i++) if (jac[i] <= 0.0) error("Element #%d is concave or badly oriented.", element->id); // next, estimate the "exact" value of the typical integral int_grad_u_grad_v // (with grad_u == grad_v == (1,1)) using the maximum integration rule double exact1 = 0.0; double exact2 = 0.0; for (i = 0; i < quad->get_num_points(mo); i++, m++) { exact1 += pt[i][2] * jac[i] * (sqr((*m)[0][0] + (*m)[0][1]) + sqr((*m)[1][0] + (*m)[1][1])); exact2 += pt[i][2] / jac[i]; } // find sufficient quadrature degree for (o = 0; o < mo; o++) { pt = quad->get_points(o); m = get_inv_ref_map(o); jac = get_jacobian(o); double result1 = 0.0; double result2 = 0.0; for (i = 0; i < quad->get_num_points(o); i++, m++) { result1 += pt[i][2] * jac[i] * (sqr((*m)[0][0] + (*m)[0][1]) + sqr((*m)[1][0] + (*m)[1][1])); result2 += pt[i][2] / jac[i] ; } if ((fabs((exact1 - result1) / exact1) < 1e-8) && (fabs((exact2 - result2) / exact2) < 1e-8)) break; } if (o >= 10) { warn("Element #%d is too distorted (iro ~ %d).", element->id, o); } return o; }