int DiscreteProblemIntegrationOrderCalculator<Scalar>::calc_order_dg_matrix_form(const Hermes::vector<SpaceSharedPtr<Scalar> >& spaces, Traverse::State* current_state, MatrixFormDG<Scalar>* mfDG, RefMap** current_refmaps, Solution<Scalar>** current_u_ext, bool neighbor_supp_u, bool neighbor_supp_v, NeighborSearch<Scalar>** neighbor_searches) { NeighborSearch<Scalar>* nbs_u = neighbor_searches[mfDG->j]; unsigned int prev_size = this->rungeKutta ? this->RK_original_spaces_count : mfDG->wf->get_neq() - mfDG->u_ext_offset; // Order to return. int order = 0; DiscontinuousFunc<Hermes::Ord>** u_ext_ord = current_u_ext == nullptr ? nullptr : new DiscontinuousFunc<Hermes::Ord>*[this->rungeKutta ? this->RK_original_spaces_count : mfDG->wf->get_neq() - mfDG->u_ext_offset]; if (current_u_ext) for (int i = 0; i < prev_size; i++) if (current_u_ext[i + mfDG->u_ext_offset]) u_ext_ord[i] = init_ext_fn_ord(nbs_u, current_u_ext[i + mfDG->u_ext_offset]); else u_ext_ord[i] = new DiscontinuousFunc<Ord>(init_fn_ord(0), false, false); // Order of additional external functions. DiscontinuousFunc<Ord>** ext_ord = nullptr; Hermes::vector<MeshFunctionSharedPtr<Scalar> > ext_ord_fns = mfDG->ext.size() ? mfDG->ext.size() : mfDG->wf->ext.size(); if (ext_ord_fns.size() > 0) ext_ord = init_ext_fns_ord(ext_ord_fns, neighbor_searches); // Order of shape functions. int max_order_j = spaces[mfDG->j]->get_element_order(current_state->e[mfDG->j]->id); int max_order_i = spaces[mfDG->i]->get_element_order(current_state->e[mfDG->i]->id); if (H2D_GET_V_ORDER(max_order_i) > H2D_GET_H_ORDER(max_order_i)) max_order_i = H2D_GET_V_ORDER(max_order_i); else max_order_i = H2D_GET_H_ORDER(max_order_i); if (H2D_GET_V_ORDER(max_order_j) > H2D_GET_H_ORDER(max_order_j)) max_order_j = H2D_GET_V_ORDER(max_order_j); else max_order_j = H2D_GET_H_ORDER(max_order_j); // Order of shape functions. DiscontinuousFunc<Ord>* ou = new DiscontinuousFunc<Ord>(init_fn_ord(max_order_j), neighbor_supp_u); DiscontinuousFunc<Ord>* ov = new DiscontinuousFunc<Ord>(init_fn_ord(max_order_i), neighbor_supp_v); // Order of geometric attributes (eg. for multiplication of a solution with coordinates, normals, etc.). Geom<Hermes::Ord> tmp; double fake_wt = 1.0; // Total order of the matrix form. Ord o = mfDG->ord(1, &fake_wt, u_ext_ord, ou, ov, &tmp, ext_ord); adjust_order_to_refmaps(mfDG, order, &o, current_refmaps); // Cleanup. deinit_ext_fns_ord(mfDG, u_ext_ord, ext_ord); delete ou; delete ov; return order; }
// 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; }