16 #include "discrete_problem/discrete_problem.h"
17 #include "discrete_problem/dg/discrete_problem_dg_assembler.h"
18 #include "function/exact_solution.h"
20 #include "quadrature/limit_order.h"
21 #include "mesh/traverse.h"
22 #include "space/space.h"
23 #include "shapeset/precalc.h"
24 #include "mesh/refmap.h"
25 #include "function/solution.h"
26 #include "neighbor_search.h"
37 static GeomVol<Hermes::Ord> geom_order_vol;
38 static GeomSurf<Hermes::Ord> geom_order_surf;
39 static InterfaceGeom<Hermes::Ord> geom_order_interface;
72 template<
typename Scalar>
74 selectiveAssembler(selectiveAssembler),
75 current_state(
nullptr),
80 template<
typename Scalar>
84 if (current_wf->global_integration_order_set)
85 return current_wf->global_integration_order;
93 Func<Hermes::Ord>** ext_func = this->init_ext_orders(current_wf->ext, current_wf->u_ext_fn, u_ext_func);
95 for (
unsigned short current_mfvol_i = 0; current_mfvol_i < current_wf->mfvol.size(); current_mfvol_i++)
100 current_mfvol->wf = current_wf.get();
101 int orderTemp = calc_order_matrix_form(spaces, current_mfvol, current_refmaps, ext_func, u_ext_func);
102 if (order < orderTemp)
106 for (
unsigned short current_vfvol_i = 0; current_vfvol_i < current_wf->vfvol.size(); current_vfvol_i++)
111 current_vfvol->wf = current_wf.get();
112 int orderTemp = calc_order_vector_form(spaces, current_vfvol, current_refmaps, ext_func, u_ext_func);
113 if (order < orderTemp)
118 if (current_state->isBnd && (current_wf->mfsurf.size() > 0 || current_wf->vfsurf.size() > 0))
120 for (current_state->isurf = 0; current_state->isurf < current_state->rep->nvert; current_state->isurf++)
122 if (!current_state->bnd[current_state->isurf])
129 Func<Hermes::Ord>** ext_funcSurf = this->init_ext_orders(current_wf->ext, current_wf->u_ext_fn, u_ext_func);
131 for (
unsigned short current_mfsurf_i = 0; current_mfsurf_i < current_wf->mfsurf.size(); current_mfsurf_i++)
136 current_mfsurf->wf = current_wf.get();
137 int orderTemp = calc_order_matrix_form(spaces, current_mfsurf, current_refmaps, ext_funcSurf, u_ext_funcSurf);
138 if (order < orderTemp)
142 for (
unsigned short current_vfsurf_i = 0; current_vfsurf_i < current_wf->vfsurf.size(); current_vfsurf_i++)
148 current_vfsurf->wf = current_wf.get();
149 int orderTemp = calc_order_vector_form(spaces, current_vfsurf, current_refmaps, ext_funcSurf, u_ext_funcSurf);
150 if (order < orderTemp)
155 this->deinit_u_ext_orders(u_ext_funcSurf);
158 this->deinit_ext_orders(ext_funcSurf);
163 this->deinit_u_ext_orders(u_ext_func);
166 this->deinit_ext_orders(ext_func);
171 template<
typename Scalar>
172 template<
typename MatrixFormType>
179 if (form->ext.size() > 0)
180 local_ext = this->init_ext_orders(form->ext, (form->u_ext_fn.size() > 0 ? form->u_ext_fn : form->wf->u_ext_fn), u_ext);
183 int max_order_j = spaces[form->j]->get_element_order(current_state->e[form->j]->id);
184 int max_order_i = spaces[form->i]->get_element_order(current_state->e[form->i]->id);
186 max_order_i = H2D_GET_V_ORDER(max_order_i);
190 max_order_j = H2D_GET_V_ORDER(max_order_j);
194 for (
unsigned int k = 0; k < current_state->rep->nvert; k++)
196 int eo = spaces[form->i]->get_edge_order(current_state->e[form->i], k);
197 if (eo > max_order_i)
199 eo = spaces[form->j]->get_edge_order(current_state->e[form->j], k);
200 if (eo > max_order_j)
204 Func<Hermes::Ord>* ou = &func_order[max_order_j + (spaces[form->j]->shapeset->num_components > 1 ? 1 : 0)];
205 Func<Hermes::Ord>* ov = &func_order[max_order_i + (spaces[form->i]->shapeset->num_components > 1 ? 1 : 0)];
210 o = (
dynamic_cast<MatrixFormVol<Scalar>*
>(form))->ord(1, &wt_order, u_ext, ou, ov, &geom_order_vol, local_ext);
212 o = (
dynamic_cast<MatrixFormSurf<Scalar>*
>(form))->ord(1, &wt_order, u_ext, ou, ov, &geom_order_surf, local_ext);
214 adjust_order_to_refmaps(form, order, &o, current_refmaps);
217 if (form->ext.size() > 0)
218 this->deinit_ext_orders(local_ext);
223 template<
typename Scalar>
224 template<
typename VectorFormType>
231 if (form->ext.size() > 0)
232 local_ext = this->init_ext_orders(form->ext, (form->u_ext_fn.size() > 0 ? form->u_ext_fn : form->wf->u_ext_fn), u_ext);
235 int max_order_i = spaces[form->i]->get_element_order(current_state->e[form->i]->id);
237 max_order_i = H2D_GET_V_ORDER(max_order_i);
241 for (
unsigned int k = 0; k < current_state->rep->nvert; k++)
243 int eo = spaces[form->i]->get_edge_order(current_state->e[form->i], k);
244 if (eo > max_order_i)
247 Func<Hermes::Ord>* ov = &func_order[max_order_i + (spaces[form->i]->shapeset->num_components > 1 ? 1 : 0)];
252 o = (
dynamic_cast<VectorFormVol<Scalar>*
>(form))->ord(1, &wt_order, u_ext, ov, &geom_order_vol, local_ext);
254 o = (
dynamic_cast<VectorFormSurf<Scalar>*
>(form))->ord(1, &wt_order, u_ext, ov, &geom_order_surf, local_ext);
256 adjust_order_to_refmaps(form, order, &o, current_refmaps);
259 if (form->ext.size() > 0)
260 this->deinit_ext_orders(local_ext);
265 template<
typename Scalar>
269 bool surface_form = (this->current_state->isurf > -1);
274 for (
int i = 0; i < this->selectiveAssembler->
spaces_size; i++)
276 assert(this->u_ext[i]);
278 if (this->u_ext[i]->get_active_element())
281 u_ext_func[i] = &func_order[this->u_ext[i]->get_edge_fn_order(this->current_state->isurf) + (this->u_ext[i]->get_num_components() > 1 ? 1 : 0)];
283 u_ext_func[i] = &func_order[this->u_ext[i]->get_fn_order() + (this->u_ext[i]->get_num_components() > 1 ? 1 : 0)];
286 u_ext_func[i] = &func_order[0];
293 template<
typename Scalar>
296 free_with_check(u_ext_func);
299 template<
typename Scalar>
302 int ext_size = ext.size();
303 int u_ext_fns_size = u_ext_fns.size();
307 bool surface_form = (this->current_state->isurf > -1);
309 if (ext_size > 0 || u_ext_fns_size > 0)
311 ext_func = malloc_with_check<Func<Hermes::Ord>*>(ext_size + u_ext_fns_size);
312 for (
unsigned short ext_i = 0; ext_i < ext.size(); ext_i++)
316 if (ext[ext_i]->get_active_element())
319 ext_func[u_ext_fns_size + ext_i] = &func_order[ext[ext_i]->get_edge_fn_order(this->current_state->isurf) + (ext[ext_i]->get_num_components() > 1 ? 1 : 0)];
321 ext_func[u_ext_fns_size + ext_i] = &func_order[ext[ext_i]->get_fn_order() + (ext[ext_i]->get_num_components() > 1 ? 1 : 0)];
324 ext_func[u_ext_fns_size + ext_i] =
nullptr;
327 ext_func[u_ext_fns_size + ext_i] =
nullptr;
330 for (
int ext_i = 0; ext_i < u_ext_fns_size; ext_i++)
332 if (u_ext_fns[ext_i])
334 ext_func[ext_i] = &func_order[0];
335 u_ext_fns[ext_i]->ord(ext_func + u_ext_fns_size, u_ext_func, ext_func[ext_i]);
338 ext_func[ext_i] =
nullptr;
345 template<
typename Scalar>
348 free_with_check(ext_func);
351 template<
typename Scalar>
355 int coordinate = form->i;
357 order += o->get_order();
358 limit_order(order, current_refmaps[coordinate]->get_active_element()->get_mode());
361 template<
typename Scalar>
364 int inc = (fu->get_num_components() == 2) ? 1 : 0;
365 int central_order = fu->get_edge_fn_order(ns->active_edge) + inc;
366 int neighbor_order = fu->get_edge_fn_order(ns->neighbor_edge.local_num_of_edge) + inc;
370 template<
typename Scalar>
375 for (
unsigned int j = 0; j < ext.size(); j++)
381 template<
typename Scalar>
382 template<
typename FormType>
385 unsigned int prev_size = oi ? (this->rungeKutta ? this->RK_original_spaces_count : form->wf->get_neq() - form->
u_ext_offset) : 0;
389 for (
int i = 0; i < prev_size; i++)
394 int ext_size = form->
ext.size() ? form->
ext.size() : form->wf->ext.size();
395 int u_ext_fn_size = form->u_ext_fn.size() ? form->u_ext_fn.size() : form->wf->u_ext_fn.size();
398 for (
int i = 0; i < ext_size + u_ext_fn_size; i++)
404 template<
typename Scalar>
409 unsigned short prev_size = this->rungeKutta ? this->RK_original_spaces_count : mfDG->wf->get_neq() - mfDG->
u_ext_offset;
417 for (
unsigned short i = 0; i < prev_size; i++)
419 u_ext_ord[i] = init_ext_fn_ord(nbs_u, current_u_ext[i + mfDG->
u_ext_offset]);
425 std::vector<MeshFunctionSharedPtr<Scalar> > ext_ord_fns = mfDG->
ext.size() ? mfDG->
ext : mfDG->wf->ext;
426 if (ext_ord_fns.size() > 0)
427 ext_ord = init_ext_fns_ord(ext_ord_fns, neighbor_searches);
430 int max_order_j = spaces[mfDG->j]->get_element_order(current_state->e[mfDG->j]->
id);
431 int max_order_i = spaces[mfDG->i]->get_element_order(current_state->e[mfDG->i]->
id);
433 max_order_i = H2D_GET_V_ORDER(max_order_i);
437 max_order_j = H2D_GET_V_ORDER(max_order_j);
448 Ord o = mfDG->ord(1, &wt_order, u_ext_ord, ou, ov, &geom_order_interface, ext_ord);
450 adjust_order_to_refmaps(mfDG, order, &o, current_refmaps);
453 deinit_ext_fns_ord(mfDG, u_ext_ord, ext_ord);
461 template<
typename Scalar>
466 unsigned short prev_size = this->rungeKutta ? this->RK_original_spaces_count : vfDG->wf->get_neq() - vfDG->
u_ext_offset;
474 for (
unsigned short i = 0; i < prev_size; i++)
476 u_ext_ord[i] = init_ext_fn_ord(nbs_u, current_u_ext[i + vfDG->
u_ext_offset]);
482 std::vector<MeshFunctionSharedPtr<Scalar> > ext_ord_fns = vfDG->
ext.size() ? vfDG->
ext : vfDG->wf->ext;
483 if (ext_ord_fns.size() > 0)
484 ext_ord = init_ext_fns_ord(ext_ord_fns, neighbor_searches);
487 int max_order_i = spaces[vfDG->i]->get_element_order(current_state->e[vfDG->i]->
id);
489 max_order_i = H2D_GET_V_ORDER(max_order_i);
497 Ord o = vfDG->ord(1, &wt_order, u_ext_ord, ov, &geom_order_interface, ext_ord);
499 adjust_order_to_refmaps(vfDG, order, &o, current_refmaps);
502 deinit_ext_fns_ord(vfDG, u_ext_ord, ext_ord);
double wt_order
"Fake" integration weight for order calculation.
This class represents a function with jump discontinuity on an interface of two elements.
Provides capabilities to (re-)assemble a matrix / vector only where necessary. See also Solver::keep_...
Used to pass the instances of Space around.
Common definitions for Hermes2D.
int get_inv_ref_order() const
Returns the increase in the integration order due to the reference map.
#define H2D_GET_H_ORDER(encoded_order)
Macros for combining quad horizontal and vertical encoded_orders.
Represents the reference mapping.
Provides methods of integration order calculation.
This class characterizes a neighborhood of a given edge in terms of adjacent elements and provides me...
Represents the solution of a PDE.
bool form_to_be_assembled(MatrixForm< Scalar > *form, Traverse::State *current_state)
Decides if the form will be assembled on this State.
unsigned int spaces_size
Spaces.