/// Calculates the absolute error between sln1 and sln2 using function fn double calc_error(double (*fn)(MeshFunction*, MeshFunction*, int, QuadPt3D*), MeshFunction *sln1, MeshFunction *sln2) { _F_ Mesh *meshes[2] = { sln1->get_mesh(), sln2->get_mesh() }; Transformable *tr[2] = { sln1, sln2 }; Traverse trav; trav.begin(2, meshes, tr); double error = 0.0; Element **ee; while ((ee = trav.get_next_state(NULL, NULL)) != NULL) { ElementMode3D mode = ee[0]->get_mode(); RefMap *ru = sln1->get_refmap(); Ord3 order = max(sln1->get_fn_order(), sln2->get_fn_order()) + ru->get_inv_ref_order(); order.limit(); Quad3D *quad = get_quadrature(mode); int np = quad->get_num_points(order); QuadPt3D *pt = quad->get_points(order); error += fn(sln1, sln2, np, pt); } trav.finish(); return error > H3D_TINY ? sqrt(error) : error; // do not ruin the precision by taking the sqrt }
// Integral over the active core. double integrate(MeshFunction* sln, int marker) { Quad2D* quad = &g_quad_2d_std; sln->set_quad_2d(quad); double integral = 0.0; Element* e; Mesh* mesh = sln->get_mesh(); for_all_active_elements(e, mesh) { if (e->marker == marker) { update_limit_table(e->get_mode()); sln->set_active_element(e); RefMap* ru = sln->get_refmap(); int o = sln->get_fn_order() + ru->get_inv_ref_order(); limit_order(o); sln->set_quad_order(o, H2D_FN_VAL); scalar *uval = sln->get_fn_values(); double* x = ru->get_phys_x(o); double result = 0.0; h1_integrate_expression(x[i] * uval[i]); integral += result; } } return 2.0 * M_PI * integral; }
// Calculates maximum of a given function, including its coordinates. Extremum get_peak(MeshFunction *sln) { Quad2D* quad = &g_quad_2d_std; sln->set_quad_2d(quad); Element* e; Mesh* mesh = sln->get_mesh(); scalar peak = 0.0; double pos_x = 0.0; double pos_y = 0.0; for_all_active_elements(e, mesh) { update_limit_table(e->get_mode()); sln->set_active_element(e); RefMap* ru = sln->get_refmap(); int o = sln->get_fn_order() + ru->get_inv_ref_order(); limit_order(o); sln->set_quad_order(o, H2D_FN_VAL); scalar *uval = sln->get_fn_values(); int np = quad->get_num_points(o); double* x = ru->get_phys_x(o); double* y = ru->get_phys_y(o); for (int i = 0; i < np; i++) if (uval[i] > peak) { peak = uval[i]; pos_x = x[i]; pos_y = y[i]; } }
// Integral over the active core. double integrate(MeshFunction<double>* sln, std::string area) { Quad2D* quad = &g_quad_2d_std; sln->set_quad_2d(quad); double integral = 0.0; Element* e; Mesh* mesh = const_cast<Mesh*>(sln->get_mesh()); int marker = mesh->get_element_markers_conversion().get_internal_marker(area).marker; for_all_active_elements(e, mesh) { if (e->marker == marker) { update_limit_table(e->get_mode()); sln->set_active_element(e); RefMap* ru = sln->get_refmap(); int o = sln->get_fn_order() + ru->get_inv_ref_order(); limit_order(o, e->get_mode()); sln->set_quad_order(o, H2D_FN_VAL); double *uval = sln->get_fn_values(); double* x = ru->get_phys_x(o); double result = 0.0; h1_integrate_expression(x[i] * uval[i]); integral += result; } } return 2.0 * M_PI * integral; }
/// Calculates the norm of sln using function fn double calc_norm(double (*fn)(MeshFunction*, int, QuadPt3D*), MeshFunction *sln) { _F_ double norm = 0.0; Mesh *mesh = sln->get_mesh(); FOR_ALL_ACTIVE_ELEMENTS(eid, mesh) { Element *e = mesh->elements[eid]; sln->set_active_element(e); RefMap *ru = sln->get_refmap(); order3_t o = sln->get_fn_order() + ru->get_inv_ref_order(); o.limit(); Quad3D *quad = get_quadrature(e->get_mode()); int np = quad->get_num_points(o); QuadPt3D *pt = quad->get_points(o); norm += fn(sln, np, pt); }
/// Calculates the norm of sln using function fn double calc_norm(double (*fn)(MeshFunction*, int, QuadPt3D*), MeshFunction *sln) { _F_ double norm = 0.0; Mesh *mesh = sln->get_mesh(); for(std::map<unsigned int, Element*>::iterator it = mesh->elements.begin(); it != mesh->elements.end(); it++) if (it->second->used && it->second->active) { Element *e = mesh->elements[it->first]; sln->set_active_element(e); RefMap *ru = sln->get_refmap(); Ord3 o = sln->get_fn_order() + ru->get_inv_ref_order(); o.limit(); Quad3D *quad = get_quadrature(e->get_mode()); int np = quad->get_num_points(o); QuadPt3D *pt = quad->get_points(o); norm += fn(sln, np, pt); } return norm > H3D_TINY ? sqrt(norm) : norm; // do not ruin the precision by taking the sqrt }
/// Calculate number of negative solution values. int get_num_of_neg(MeshFunction *sln) { Quad2D* quad = &g_quad_2d_std; sln->set_quad_2d(quad); Element* e; Mesh* mesh = sln->get_mesh(); int n = 0; for_all_active_elements(e, mesh) { update_limit_table(e->get_mode()); sln->set_active_element(e); RefMap* ru = sln->get_refmap(); int o = sln->get_fn_order() + ru->get_inv_ref_order(); limit_order(o); sln->set_quad_order(o, H2D_FN_VAL); scalar *uval = sln->get_fn_values(); int np = quad->get_num_points(o); for (int i = 0; i < np; i++) if (uval[i] < -1e-12) n++; }