// Actual evaluation of volume matrix form (calculates integral) scalar FeProblem::eval_form(WeakForm::MatrixFormVol *mfv, Tuple<Solution *> u_ext, PrecalcShapeset *fu, PrecalcShapeset *fv, RefMap *ru, RefMap *rv) { // determine the integration order int inc = (fu->get_num_components() == 2) ? 1 : 0; AUTOLA_OR(Func<Ord>*, oi, wf->neq); for (int i = 0; i < wf->neq; i++) oi[i] = init_fn_ord(u_ext[i]->get_fn_order() + inc); Func<Ord>* ou = init_fn_ord(fu->get_fn_order() + inc); Func<Ord>* ov = init_fn_ord(fv->get_fn_order() + inc); ExtData<Ord>* fake_ext = init_ext_fns_ord(mfv->ext); double fake_wt = 1.0; Geom<Ord>* fake_e = init_geom_ord(); Ord o = mfv->ord(1, &fake_wt, oi, ou, ov, fake_e, fake_ext); int order = ru->get_inv_ref_order(); order += o.get_order(); limit_order_nowarn(order); for (int i = 0; i < wf->neq; i++) { oi[i]->free_ord(); delete oi[i]; } ou->free_ord(); delete ou; ov->free_ord(); delete ov; delete fake_e; fake_ext->free_ord(); delete fake_ext; // eval the form Quad2D* quad = fu->get_quad_2d(); double3* pt = quad->get_points(order); int np = quad->get_num_points(order); // init geometry and jacobian*weights if (cache_e[order] == NULL) { cache_e[order] = init_geom_vol(ru, order); double* jac = ru->get_jacobian(order); cache_jwt[order] = new double[np]; for(int i = 0; i < np; i++) cache_jwt[order][i] = pt[i][2] * jac[i]; } Geom<double>* e = cache_e[order]; double* jwt = cache_jwt[order]; // function values and values of external functions AUTOLA_OR(Func<scalar>*, prev, wf->neq); for (int i = 0; i < wf->neq; i++) prev[i] = init_fn(u_ext[i], rv, order); Func<double>* u = get_fn(fu, ru, order); Func<double>* v = get_fn(fv, rv, order); ExtData<scalar>* ext = init_ext_fns(mfv->ext, rv, order); scalar res = mfv->fn(np, jwt, prev, u, v, e, ext); for (int i = 0; i < wf->neq; i++) { prev[i]->free_fn(); delete prev[i]; } ext->free(); delete ext; return res; }
// function used to calculate L2 norm of the solution double norm_fn_l2_axisym(MeshFunction* sln, RefMap* ru) { Quad2D* quad = sln->get_quad_2d(); int o = 2 *sln->get_fn_order() + ru->get_inv_ref_order(); limit_order_nowarn(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]*sqr(uval[i])); return 2*M_PI*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); }
// Function used to calculate H1 norm of the solution. double norm_fn_h1_axisym(MeshFunction* sln, RefMap* ru) { Quad2D* quad = sln->get_quad_2d(); int o = 2 * sln->get_fn_order() + ru->get_inv_ref_order(); limit_order_nowarn(o); sln->set_quad_order(o); scalar *uval, *dudx, *dudy; uval = sln->get_fn_values(); sln->get_dx_dy_values(dudx, dudy); double* x = ru->get_phys_x(o); double result = 0.0; h1_integrate_expression(x[i] * (sqr(uval[i]) + sqr(dudx[i]) + sqr(dudy[i])) ); return 2*M_PI*result; }
// function used to calculate error in L2 norm double error_fn_l2_axisym(MeshFunction* sln1, MeshFunction* sln2, RefMap* ru, RefMap* rv) { Quad2D* quad = sln1->get_quad_2d(); int o = 2*std::max(sln1->get_fn_order(), sln2->get_fn_order()) + ru->get_inv_ref_order(); limit_order_nowarn(o); sln1->set_quad_order(o, H2D_FN_VAL); sln2->set_quad_order(o, H2D_FN_VAL); scalar *uval, *vval; uval = sln1->get_fn_values(); vval = sln2->get_fn_values(); double* x = ru->get_phys_x(o); double result = 0.0; h1_integrate_expression(x[i]*sqr(uval[i] - vval[i])); return 2*M_PI*result; }
// Function used to calculate error in H1 norm. double error_fn_h1_axisym(MeshFunction* sln1, MeshFunction* sln2, RefMap* ru, RefMap* rv) { Quad2D* quad = sln1->get_quad_2d(); int o = 2*std::max(sln1->get_fn_order(), sln2->get_fn_order()) + ru->get_inv_ref_order(); limit_order_nowarn(o); sln1->set_quad_order(o); sln2->set_quad_order(o); scalar *uval, *vval, *dudx, *dudy, *dvdx, *dvdy; uval = sln1->get_fn_values(); vval = sln2->get_fn_values(); sln1->get_dx_dy_values(dudx, dudy); sln2->get_dx_dy_values(dvdx, dvdy); double* x = ru->get_phys_x(o); double result = 0.0; h1_integrate_expression(x[i] * (sqr(uval[i] - vval[i]) + sqr(dudx[i] - dvdx[i]) + sqr(dudy[i] - dvdy[i])) ); return 2*M_PI*result; }