// 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; }
// 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 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]; } }
scalar HcurlOrthoHP::eval_error(biform_val_t bi_fn, biform_ord_t bi_ord, MeshFunction *sln1, MeshFunction *sln2, MeshFunction *rsln1, MeshFunction *rsln2, RefMap *rv1, RefMap *rv2, RefMap *rrv1, RefMap *rrv2) { // determine the integration order int inc = (rsln1->get_num_components() == 2) ? 1 : 0; Func<Ord>* ou = init_fn_ord(rsln1->get_fn_order() + inc); Func<Ord>* ov = init_fn_ord(rsln2->get_fn_order() + inc); double fake_wt = 1.0; Geom<Ord>* fake_e = init_geom_ord(); Ord o = bi_ord(1, &fake_wt, ou, ov, fake_e, NULL); int order = rrv1->get_inv_ref_order(); order += o.get_order(); limit_order(order); ou->free_ord(); delete ou; ov->free_ord(); delete ov; delete fake_e; // eval the form Quad2D* quad = sln1->get_quad_2d(); double3* pt = quad->get_points(order); int np = quad->get_num_points(order); // init geometry and jacobian*weights Geom<double>* e = init_geom_vol(rrv1, order); double* jac = rrv1->get_jacobian(order); double* jwt = new double[np]; for(int i = 0; i < np; i++) jwt[i] = pt[i][2] * jac[i]; // function values and values of external functions Func<scalar>* err1 = init_fn(sln1, rv1, order); Func<scalar>* err2 = init_fn(sln2, rv2, order); Func<scalar>* v1 = init_fn(rsln1, rrv1, order); Func<scalar>* v2 = init_fn(rsln2, rrv2, order); for (int i = 0; i < np; i++) { err1->val0[i] = err1->val0[i] - v1->val0[i]; err1->val1[i] = err1->val1[i] - v1->val1[i]; err1->curl[i] = err1->curl[i] - v1->curl[i]; err2->val0[i] = err2->val0[i] - v2->val0[i]; err2->val1[i] = err2->val1[i] - v2->val1[i]; err2->curl[i] = err2->curl[i] - v2->curl[i]; } scalar res = bi_fn(np, jwt, err1, err2, e, NULL); e->free(); delete e; delete [] jwt; err1->free_fn(); delete err1; err2->free_fn(); delete err2; v1->free_fn(); delete v1; v2->free_fn(); delete v2; return res; }
double KellyTypeAdapt::eval_boundary_estimator(KellyTypeAdapt::ErrorEstimatorForm* err_est_form, RefMap *rm, SurfPos* surf_pos) { // determine the integration order int inc = (this->sln[err_est_form->i]->get_num_components() == 2) ? 1 : 0; Func<Ord>** oi = new Func<Ord>* [num]; for (int i = 0; i < num; i++) oi[i] = init_fn_ord(this->sln[i]->get_edge_fn_order(surf_pos->surf_num) + inc); // Order of additional external functions. ExtData<Ord>* fake_ext = dp.init_ext_fns_ord(err_est_form->ext, surf_pos->surf_num); double fake_wt = 1.0; Geom<Ord>* fake_e = init_geom_ord(); Ord o = err_est_form->ord(1, &fake_wt, oi, oi[err_est_form->i], fake_e, fake_ext); int order = rm->get_inv_ref_order(); order += o.get_order(); limit_order(order); // Clean up. for (int i = 0; i < this->num; i++) if (oi[i] != NULL) { oi[i]->free_ord(); delete oi[i]; } delete [] oi; delete fake_e; delete fake_ext; // eval the form Quad2D* quad = this->sln[err_est_form->i]->get_quad_2d(); int eo = quad->get_edge_points(surf_pos->surf_num, order); double3* pt = quad->get_points(eo); int np = quad->get_num_points(eo); // init geometry and jacobian*weights Geom<double>* e = init_geom_surf(rm, surf_pos, eo); double3* tan = rm->get_tangent(surf_pos->surf_num, eo); double* jwt = new double[np]; for(int i = 0; i < np; i++) jwt[i] = pt[i][2] * tan[i][2]; // function values Func<scalar>** ui = new Func<scalar>* [num]; for (int i = 0; i < num; i++) ui[i] = init_fn(this->sln[i], eo); ExtData<scalar>* ext = dp.init_ext_fns(err_est_form->ext, rm, eo); scalar res = boundary_scaling_const * err_est_form->value(np, jwt, ui, ui[err_est_form->i], e, ext); for (int i = 0; i < this->num; i++) if (ui[i] != NULL) { ui[i]->free_fn(); delete ui[i]; } delete [] ui; if (ext != NULL) { ext->free(); delete ext; } e->free(); delete e; delete [] jwt; return std::abs(0.5*res); // Edges are parameterized from 0 to 1 while integration weights // are defined in (-1, 1). Thus multiplying with 0.5 to correct // the weights. }
double KellyTypeAdapt::eval_volumetric_estimator(KellyTypeAdapt::ErrorEstimatorForm* err_est_form, RefMap *rm) { // determine the integration order int inc = (this->sln[err_est_form->i]->get_num_components() == 2) ? 1 : 0; Func<Ord>** oi = new Func<Ord>* [num]; for (int i = 0; i < num; i++) oi[i] = init_fn_ord(this->sln[i]->get_fn_order() + inc); // Order of additional external functions. ExtData<Ord>* fake_ext = dp.init_ext_fns_ord(err_est_form->ext); double fake_wt = 1.0; Geom<Ord>* fake_e = init_geom_ord(); Ord o = err_est_form->ord(1, &fake_wt, oi, oi[err_est_form->i], fake_e, fake_ext); int order = rm->get_inv_ref_order(); order += o.get_order(); limit_order(order); // Clean up. for (int i = 0; i < this->num; i++) if (oi[i] != NULL) { oi[i]->free_ord(); delete oi[i]; } delete [] oi; delete fake_e; delete fake_ext; // eval the form Quad2D* quad = this->sln[err_est_form->i]->get_quad_2d(); double3* pt = quad->get_points(order); int np = quad->get_num_points(order); // init geometry and jacobian*weights Geom<double>* e = init_geom_vol(rm, order); double* jac = rm->get_jacobian(order); double* jwt = new double[np]; for(int i = 0; i < np; i++) jwt[i] = pt[i][2] * jac[i]; // function values Func<scalar>** ui = new Func<scalar>* [num]; for (int i = 0; i < num; i++) ui[i] = init_fn(this->sln[i], order); ExtData<scalar>* ext = dp.init_ext_fns(err_est_form->ext, rm, order); scalar res = volumetric_scaling_const * err_est_form->value(np, jwt, ui, ui[err_est_form->i], e, ext); for (int i = 0; i < this->num; i++) if (ui[i] != NULL) { ui[i]->free_fn(); delete ui[i]; } delete [] ui; if (ext != NULL) { ext->free(); delete ext; } e->free(); delete e; delete [] jwt; return std::abs(res); }
void DiscreteProblemIntegrationOrderCalculator<Scalar>::adjust_order_to_refmaps(Form<Scalar> *form, int& order, Hermes::Ord* o, RefMap** current_refmaps) { // Increase due to reference map. int coordinate = form->i; order = current_refmaps[coordinate]->get_inv_ref_order(); order += o->get_order(); limit_order(order, current_refmaps[coordinate]->get_active_element()->get_mode()); }
// same as int_grad_u_grad_v but now fu is a solution inline double int_grad_u_grad_v_II(RealFunction* fu, RealFunction* fv, RefMap* ru, RefMap* rv) { Quad2D* quad = fu->get_quad_2d(); int o = fu->get_fn_order() + fv->get_fn_order() + ru->get_inv_ref_order(); limit_order(o); fu->set_quad_order(o); fv->set_quad_order(o); double *dudx, *dudy, *dvdx, *dvdy; fu->get_dx_dy_values(dudx, dudy); // 'u' solution => derivatives already transformed to physical element fv->get_dx_dy_values(dvdx, dvdy); double result = 0.0; h1_integrate_dd_expression(dudx[i] * t_dvdx + dudy[i] * t_dvdy); return result; }
double KellyTypeAdapt::eval_solution_norm(Adapt::MatrixFormVolError* form, RefMap *rm, MeshFunction* sln) { // determine the integration order int inc = (sln->get_num_components() == 2) ? 1 : 0; Func<Ord>* ou = init_fn_ord(sln->get_fn_order() + inc); double fake_wt = 1.0; Geom<Ord>* fake_e = init_geom_ord(); Ord o = form->ord(1, &fake_wt, NULL, ou, ou, fake_e, NULL); int order = rm->get_inv_ref_order(); order += o.get_order(); Solution *sol = static_cast<Solution *>(sln); if(sol && sol->get_type() == HERMES_EXACT) { limit_order_nowarn(order); } else { limit_order(order); } ou->free_ord(); delete ou; delete fake_e; // eval the form Quad2D* quad = sln->get_quad_2d(); double3* pt = quad->get_points(order); int np = quad->get_num_points(order); // init geometry and jacobian*weights Geom<double>* e = init_geom_vol(rm, order); double* jac = rm->get_jacobian(order); double* jwt = new double[np]; for(int i = 0; i < np; i++) jwt[i] = pt[i][2] * jac[i]; // function values Func<scalar>* u = init_fn(sln, order); scalar res = form->value(np, jwt, NULL, u, u, e, NULL); e->free(); delete e; delete [] jwt; u->free_fn(); delete u; return std::abs(res); }
inline double int_u_dvdy_w(RealFunction* fu, RealFunction* fv, RealFunction* fw, RefMap* ru, RefMap* rv, RefMap* rw) // assumes that 'v' is a solution { Quad2D* quad = fu->get_quad_2d(); int o = fu->get_fn_order() + fv->get_fn_order() + fw->get_fn_order() + ru->get_inv_ref_order(); limit_order(o); fu->set_quad_order(o, FN_VAL); fv->set_quad_order(o); fw->set_quad_order(o, FN_VAL); double* uval = fu->get_fn_values(); double* wval = fw->get_fn_values(); double *dvdx, *dvdy; fv->get_dx_dy_values(dvdx, dvdy); // 'v' solution => derivatives already transformed to physical element double result = 0.0; h1_integrate_dd_expression(uval[i] * dvdy[i] * wval[i]); return result; }
// custom integral inline scalar int_fn_e_f(double (*fn)(int, double, double), RealFunction* fe, RealFunction* ff, RefMap* re, RefMap* rf) { Quad2D* quad = re->get_quad_2d(); int o = fe->get_fn_order() + ff->get_fn_order() + 2 + re->get_inv_ref_order(); limit_order(o); fe->set_quad_order(o, FN_VAL); ff->set_quad_order(o, FN_VAL); int marker = re->get_active_element()->marker; double* x = re->get_phys_x(o); double* y = re->get_phys_y(o); double *e0 = fe->get_fn_values(0), *e1 = fe->get_fn_values(1); double *f0 = ff->get_fn_values(0), *f1 = ff->get_fn_values(1); scalar c; scalar result = 0.0; hcurl_integrate_jac_expression(( c = fn(marker, x[i], y[i]), c * (((*me)[0][0]*e0[i] + (*me)[0][1]*e1[i]) * ((*mf)[0][0]*f0[i] + (*mf)[0][1]*f1[i]) + ((*me)[1][0]*e0[i] + (*me)[1][1]*e1[i]) * ((*mf)[1][0]*f0[i] + (*mf)[1][1]*f1[i])))); return result; }
// same as int_w_nabla_u_v() but now 'u' is a solution inline double int_w_nabla_u_v_II(RealFunction* w1, RealFunction* w2, RealFunction* fu, RealFunction* fv, RefMap* ru, RefMap* rv) { Quad2D* quad = fu->get_quad_2d(); int o = fu->get_fn_order() + fv->get_fn_order() + w1->get_fn_order() + ru->get_inv_ref_order(); limit_order(o); w1->set_quad_order(o, FN_VAL); w2->set_quad_order(o, FN_VAL); fu->set_quad_order(o); fv->set_quad_order(o, FN_VAL); double *dudx, *dudy; fu->get_dx_dy_values(dudx, dudy); // 'u' solution => derivatives already transformed to physical element double* vval = fv->get_fn_values(); double* w1val = w1->get_fn_values(); double* w2val = w2->get_fn_values(); double result = 0.0; h1_integrate_dd_expression((w1val[i] * dudx[i] + w2val[i] * dudy[i]) * vval[i]); return result; }
// 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++; }
double KellyTypeAdapt::eval_interface_estimator(KellyTypeAdapt::ErrorEstimatorForm* err_est_form, RefMap *rm, SurfPos* surf_pos, LightArray<NeighborSearch*>& neighbor_searches, int neighbor_index) { NeighborSearch* nbs = neighbor_searches.get(neighbor_index); Hermes::vector<MeshFunction*> slns; for (int i = 0; i < num; i++) slns.push_back(this->sln[i]); // Determine integration order. ExtData<Ord>* fake_ui = dp.init_ext_fns_ord(slns, neighbor_searches); // Order of additional external functions. // ExtData<Ord>* fake_ext = dp.init_ext_fns_ord(err_est_form->ext, nbs); // Order of geometric attributes (eg. for multiplication of a solution with coordinates, normals, etc.). Geom<Ord>* fake_e = new InterfaceGeom<Ord>(init_geom_ord(), nbs->neighb_el->marker, nbs->neighb_el->id, nbs->neighb_el->get_diameter()); double fake_wt = 1.0; Ord o = err_est_form->ord(1, &fake_wt, fake_ui->fn, fake_ui->fn[err_est_form->i], fake_e, NULL); int order = rm->get_inv_ref_order(); order += o.get_order(); limit_order(order); // Clean up. if (fake_ui != NULL) { for (int i = 0; i < num; i++) delete fake_ui->fn[i]; fake_ui->free_ord(); delete fake_ui; } delete fake_e; //delete fake_ext; Quad2D* quad = this->sln[err_est_form->i]->get_quad_2d(); int eo = quad->get_edge_points(surf_pos->surf_num, order); int np = quad->get_num_points(eo); double3* pt = quad->get_points(eo); // Init geometry and jacobian*weights (do not use the NeighborSearch caching mechanism). double3* tan = rm->get_tangent(surf_pos->surf_num, eo); double* jwt = new double[np]; for(int i = 0; i < np; i++) jwt[i] = pt[i][2] * tan[i][2]; Geom<double>* e = new InterfaceGeom<double>(init_geom_surf(rm, surf_pos, eo), nbs->neighb_el->marker, nbs->neighb_el->id, nbs->neighb_el->get_diameter()); // function values ExtData<scalar>* ui = dp.init_ext_fns(slns, neighbor_searches, order); //ExtData<scalar>* ext = dp.init_ext_fns(err_est_form->ext, nbs); scalar res = interface_scaling_const * err_est_form->value(np, jwt, ui->fn, ui->fn[err_est_form->i], e, NULL); if (ui != NULL) { ui->free(); delete ui; } //if (ext != NULL) { ext->free(); delete ext; } e->free(); delete e; delete [] jwt; return std::abs(0.5*res); // Edges are parameterized from 0 to 1 while integration weights // are defined in (-1, 1). Thus multiplying with 0.5 to correct // the weights. }