19 #include "discrete_problem/dg/discrete_problem_dg_assembler.h"
20 #include "discrete_problem/discrete_problem_thread_assembler.h"
28 static const std::string H2D_DG_INNER_EDGE =
"-1234567";
30 template<
typename Scalar>
31 unsigned int DiscreteProblemDGAssembler<Scalar>::dg_order = 20;
33 template<
typename Scalar>
35 : pss(threadAssembler->pss),
36 refmaps(threadAssembler->refmaps),
37 u_ext(threadAssembler->u_ext),
38 fns(threadAssembler->fns),
39 wf(threadAssembler->wf),
40 spaces_size(threadAssembler->spaces_size),
41 nonlinear(threadAssembler->nonlinear),
42 current_mat(threadAssembler->current_mat),
43 current_rhs(threadAssembler->current_rhs),
44 current_state(nullptr),
45 selectiveAssembler(threadAssembler->selectiveAssembler),
49 this->DG_matrix_forms_present =
false;
50 this->DG_vector_forms_present =
false;
53 if (!this->wf->mfDG.empty())
54 this->DG_matrix_forms_present =
true;
56 if (!this->wf->vfDG.empty())
57 this->DG_vector_forms_present =
true;
60 if (DG_matrix_forms_present)
62 npss = malloc_with_check<PrecalcShapesetAssembling*>(spaces_size);
63 nrefmaps = malloc_with_check<RefMap*>(spaces_size);
65 for (
unsigned int j = 0; j < spaces_size; j++)
68 nrefmaps[j] =
new RefMap();
71 this->als = threadAssembler->als;
74 template<
typename Scalar>
77 return neighbor_searches[index + wf->get_neq()];
80 template<
typename Scalar>
83 if (DG_matrix_forms_present)
85 for (
unsigned int j = 0; j < spaces_size; j++)
90 free_with_check(npss);
91 free_with_check(nrefmaps);
95 template<
typename Scalar>
98 this->current_state = current_state_;
101 for (
int i = 0; i < this->current_state->rep->nvert; i++)
103 this->num_neighbors =
new unsigned int[this->current_state->rep->nvert];
104 processed =
new bool*[current_state->rep->nvert];
106 if (DG_matrix_forms_present)
108 for (
unsigned int i = 0; i < spaces_size; i++)
110 npss[i]->set_quad_2d(&g_quad_2d_std);
111 nrefmaps[i]->set_quad_2d(&g_quad_2d_std);
116 template<
typename Scalar>
119 #pragma omp critical (DG)
121 for (
unsigned int i = 0; i < current_state->num; i++)
122 current_state->e[i]->visited =
true;
124 for (current_state->isurf = 0; current_state->isurf < current_state->rep->nvert; current_state->isurf++)
126 if (!current_state->bnd[current_state->isurf])
129 if (!init_neighbors(neighbor_searches[current_state->isurf], current_state))
136 for (current_state->isurf = 0; current_state->isurf < current_state->rep->nvert; current_state->isurf++)
138 if (!current_state->bnd[current_state->isurf])
140 #ifdef DEBUG_DG_ASSEMBLING
143 for (
unsigned int neighbor_i = 0; neighbor_i < num_neighbors[current_state->isurf]; neighbor_i++)
145 if (!DG_vector_forms_present && processed[current_state->isurf][neighbor_i])
149 wf->set_active_DG_state(current_state->e, current_state->isurf);
151 assemble_one_neighbor(processed[current_state->isurf][neighbor_i], neighbor_i, neighbor_searches[current_state->isurf]);
154 deinit_neighbors(neighbor_searches[current_state->isurf], current_state);
157 processed[current_state->isurf] =
nullptr;
162 template<
typename Scalar>
165 for (
int i = 0; i < this->current_state->rep->nvert; i++)
167 free_with_check(neighbor_searches[i]);
168 free_with_check(processed[i]);
170 free_with_check(neighbor_searches);
171 free_with_check(num_neighbors);
172 free_with_check(processed);
175 template<
typename Scalar>
180 template<
typename Scalar>
181 void DiscreteProblemDGAssembler<Scalar>::assemble_one_neighbor(
bool edge_processed,
unsigned int neighbor_i, NeighborSearch<Scalar>** current_neighbor_searches)
184 for (
unsigned int i = 0; i < this->current_state->num; i++)
186 NeighborSearch<Scalar>* ns = current_neighbor_searches[i];
187 ns->active_segment = neighbor_i;
188 ns->neighb_el = ns->neighbors[neighbor_i];
189 ns->neighbor_edge = ns->neighbor_edges[neighbor_i];
194 for (
unsigned int fns_i = 0; fns_i < current_state->num; fns_i++)
196 NeighborSearch<Scalar>* ns = current_neighbor_searches[fns_i];
197 if (neighbor_i < ns->central_transformations_alloc_size && ns->central_transformations[neighbor_i])
198 ns->central_transformations[neighbor_i]->apply_on(fns[fns_i]);
202 if (current_mat && DG_matrix_forms_present && !edge_processed)
204 for (
unsigned int idx_i = 0; idx_i < spaces_size; idx_i++)
206 NeighborSearch<Scalar>* ns = current_neighbor_searches[idx_i];
207 npss[idx_i]->set_active_element((*ns->get_neighbors())[neighbor_i]);
208 if (neighbor_i < ns->neighbor_transformations_alloc_size && ns->neighbor_transformations[neighbor_i])
209 ns->neighbor_transformations[neighbor_i]->apply_on(npss[idx_i]);
214 for (
unsigned int i = 0; i < spaces_size; i++)
216 refmaps[i]->force_transform(pss[i]->get_transform(), pss[i]->get_ctm());
219 if (current_mat && DG_matrix_forms_present && !edge_processed)
221 nrefmaps[i]->set_active_element(npss[i]->get_active_element());
222 nrefmaps[i]->force_transform(npss[i]->get_transform(), npss[i]->get_ctm());
228 typename NeighborSearch<Scalar>::ExtendedShapeset** ext_asmlist =
new typename NeighborSearch<Scalar>::ExtendedShapeset*[this->spaces_size];
229 int n_quadrature_points;
230 GeomSurf<double>* geometry = malloc_with_check<GeomSurf<double>>(this->spaces_size);
231 double** jacobian_x_weights = malloc_with_check<double*>(this->spaces_size);
232 InterfaceGeom<double>** e = malloc_with_check<InterfaceGeom<double>*>(this->spaces_size);
233 DiscontinuousFunc<double>*** testFunctions = malloc_with_check<DiscontinuousFunc<double>**>(this->spaces_size);
236 int order = DiscreteProblemDGAssembler<Scalar>::dg_order;
237 int order_base = DiscreteProblemDGAssembler<Scalar>::dg_order;
238 for (
unsigned int i = 0; i < this->spaces_size; i++)
240 if (!current_state->e[i])
242 current_neighbor_searches[i]->set_quad_order(order);
244 jacobian_x_weights[i] =
new double[refmaps[i]->get_quad_2d()->get_num_points(order_base, current_state->e[i]->get_mode())];
245 n_quadrature_points = init_surface_geometry_points_allocated(refmaps, this->spaces_size, order_base, current_state->isurf, current_state->rep->marker, geometry[i], jacobian_x_weights[i]);
246 e[i] =
new InterfaceGeom<double>(&geometry[i], current_neighbor_searches[i]->central_el, current_neighbor_searches[i]->neighb_el);
248 if (current_mat && DG_matrix_forms_present && !edge_processed)
250 ext_asmlist[i] = current_neighbor_searches[i]->create_extended_asmlist(spaces[i], &als[i]);
251 testFunctions[i] = malloc_with_check<DiscontinuousFunc<double>*>(ext_asmlist[i]->cnt);
252 for (
int func_i = 0; func_i < ext_asmlist[i]->cnt; func_i++)
254 if (ext_asmlist[i]->dof[func_i] < 0)
258 if (ext_asmlist[i]->has_support_on_neighbor(func_i))
260 npss[i]->set_active_shape(ext_asmlist[i]->neighbor_al->idx[func_i - ext_asmlist[i]->central_al->cnt]);
261 testFunctions[i][func_i] =
new DiscontinuousFunc<double>(
init_fn(npss[i], nrefmaps[i], current_neighbor_searches[i]->get_quad_eo(
true)),
true, current_neighbor_searches[i]->neighbor_edge.orientation);
265 pss[i]->set_active_shape(ext_asmlist[i]->central_al->idx[func_i]);
266 testFunctions[i][func_i] =
new DiscontinuousFunc<double>(
init_fn(pss[i], refmaps[i], current_neighbor_searches[i]->get_quad_eo(
false)),
false, current_neighbor_searches[i]->neighbor_edge.orientation);
272 DiscontinuousFunc<Scalar>** ext = init_ext_fns(wf->ext, current_neighbor_searches, order);
274 DiscontinuousFunc<Scalar>** u_ext_func = malloc_with_check<DiscontinuousFunc<Scalar>*>(this->spaces_size);
279 for (
int u_ext_func_i = 0; u_ext_func_i < this->spaces_size; u_ext_func_i++)
280 if (u_ext[u_ext_func_i])
282 current_neighbor_searches[u_ext_func_i]->set_quad_order(order);
283 u_ext_func[u_ext_func_i] = current_neighbor_searches[u_ext_func_i]->init_ext_fn(u_ext[u_ext_func_i]);
286 u_ext_func[u_ext_func_i] =
nullptr;
289 for (
int u_ext_func_i = 0; u_ext_func_i < this->spaces_size; u_ext_func_i++)
290 u_ext_func[u_ext_func_i] =
nullptr;
293 if (current_mat && DG_matrix_forms_present && !edge_processed)
295 for (
unsigned short current_mfsurf_i = 0; current_mfsurf_i < wf->mfDG.size(); current_mfsurf_i++)
297 if (!this->selectiveAssembler->form_to_be_assembled((MatrixForm<Scalar>*)wf->mfDG[current_mfsurf_i], current_state))
300 MatrixFormDG<Scalar>* mfs = wf->mfDG[current_mfsurf_i];
306 bool support_neigh_u, support_neigh_v;
307 typename NeighborSearch<Scalar>::ExtendedShapeset* ext_asmlist_u = ext_asmlist[n];
308 typename NeighborSearch<Scalar>::ExtendedShapeset* ext_asmlist_v = ext_asmlist[m];
310 for (
int i = 0; i < ext_asmlist_v->cnt; i++)
312 if (ext_asmlist_v->dof[i] < 0)
315 support_neigh_v = ext_asmlist_v->has_support_on_neighbor(i);
317 for (
int j = 0; j < ext_asmlist_u->cnt; j++)
319 if (ext_asmlist_u->dof[j] >= 0)
322 DiscontinuousFunc<double>* u = testFunctions[n][j];
323 DiscontinuousFunc<double>* v = testFunctions[m][i];
325 Scalar res = mfs->value(n_quadrature_points, jacobian_x_weights[n], u_ext_func, u, v, e[n], ext) * mfs->scaling_factor;
327 support_neigh_u = ext_asmlist_u->has_support_on_neighbor(j);
329 Scalar val = 0.5 * res * (support_neigh_u ? ext_asmlist_u->neighbor_al->coef[j - ext_asmlist_u->central_al->cnt] : ext_asmlist_u->central_al->coef[j])
330 * (support_neigh_v ? ext_asmlist_v->neighbor_al->coef[i - ext_asmlist_v->central_al->cnt] : ext_asmlist_v->central_al->coef[i]);
332 local_stiffness_matrix[i * 2 * H2D_MAX_LOCAL_BASIS_SIZE + j] = val;
337 current_mat->add(ext_asmlist_v->cnt, ext_asmlist_u->cnt, this->local_stiffness_matrix, ext_asmlist_v->dof, ext_asmlist_u->dof, H2D_MAX_LOCAL_BASIS_SIZE * 2);
341 for (
int i = 0; i < this->spaces_size; i++)
343 for (
int func_i = 0; func_i < ext_asmlist[i]->cnt; func_i++)
345 if (ext_asmlist[i]->dof[func_i] < 0)
347 delete testFunctions[i][func_i];
349 delete ext_asmlist[i];
350 free_with_check(testFunctions[i]);
353 free_with_check(testFunctions);
354 free_with_check(ext_asmlist);
356 if (current_rhs && DG_vector_forms_present)
358 for (
unsigned int ww = 0; ww < wf->vfDG.size(); ww++)
360 VectorFormDG<Scalar>* vfs = wf->vfDG[ww];
361 if (vfs->areas[0] != H2D_DG_INNER_EDGE)
366 if (!this->selectiveAssembler->form_to_be_assembled((VectorForm<Scalar>*)vfs, current_state))
369 NeighborSearch<Scalar>* current_neighbor_searches_v = current_neighbor_searches[n];
372 for (
unsigned int dof_i = 0; dof_i < als[n].cnt; dof_i++)
374 if (als[n].dof[dof_i] < 0)
376 pss[n]->set_active_shape(als[n].idx[dof_i]);
378 Func<double>* v =
init_fn(pss[n], refmaps[n], current_neighbor_searches_v->get_quad_eo());
380 current_rhs->
add(als[n].dof[dof_i], 0.5 * vfs->value(n_quadrature_points, jacobian_x_weights[n], u_ext_func, v, e[n], ext) * vfs->scaling_factor * als[n].coef[dof_i]);
388 for (
unsigned int i = 0; i < wf->ext.size(); i++)
399 for (
int u_ext_i = 0; u_ext_i < this->spaces_size; u_ext_i++)
402 delete u_ext_func[u_ext_i];
409 for (
int i = 0; i < this->spaces_size; i++)
411 if (this->spaces[i]->get_type() != HERMES_L2_SPACE)
413 delete[] jacobian_x_weights[i];
417 free_with_check(geometry);
418 free_with_check(jacobian_x_weights);
423 for (
unsigned int fns_i = 0; fns_i < current_state->num; fns_i++)
425 fns[fns_i]->set_transform(current_neighbor_searches[fns_i]->original_central_el_transform);
429 for (
unsigned int i = 0; i < spaces_size; i++)
430 refmaps[i]->force_transform(pss[i]->get_transform(), pss[i]->get_ctm());
433 template<
typename Scalar>
434 void DiscreteProblemDGAssembler<Scalar>::deinit_assembling_one_neighbor()
438 template<
typename Scalar>
439 DiscontinuousFunc<Scalar>** DiscreteProblemDGAssembler<Scalar>::init_ext_fns(std::vector<MeshFunctionSharedPtr<Scalar> > ext,
440 NeighborSearch<Scalar>** current_neighbor_searches,
int order)
442 DiscontinuousFunc<Scalar>** ext_fns =
new DiscontinuousFunc<Scalar>*[ext.size()];
443 for (
unsigned int j = 0; j < ext.size(); j++)
445 NeighborSearch<Scalar>* ns = get_neighbor_search_ext(this->wf, current_neighbor_searches, j);
446 ns->set_quad_order(order);
447 ext_fns[j] = ns->init_ext_fn(ext[j].
get());
453 template<
typename Scalar>
454 bool DiscreteProblemDGAssembler<Scalar>::init_neighbors(NeighborSearch<Scalar>** current_neighbor_searches, Traverse::State* current_state)
457 bool DG_intra =
false;
458 for (
unsigned int i = 0; i < current_state->num; i++)
460 bool existing_ns =
false;
461 for (
int j = i - 1; j >= 0; j--)
462 if (current_state->e[i] == current_state->e[j])
464 current_neighbor_searches[i] = current_neighbor_searches[j];
470 NeighborSearch<Scalar>* ns =
new NeighborSearch<Scalar>(current_state->e[i], this->meshes[i]);
471 ns->original_central_el_transform = current_state->sub_idx[i];
472 current_neighbor_searches[i] = ns;
473 if (current_neighbor_searches[i]->set_active_edge_multimesh(current_state->isurf) && (i >= this->spaces_size || spaces[i]->get_type() == HERMES_L2_SPACE))
475 current_neighbor_searches[i]->clear_initial_sub_idx();
482 template<
typename Scalar>
483 void DiscreteProblemDGAssembler<Scalar>::deinit_neighbors(NeighborSearch<Scalar>** current_neighbor_searches, Traverse::State* current_state)
485 for (
unsigned int i = 0; i < current_state->num; i++)
487 bool existing_ns =
false;
488 for (
int j = i - 1; j >= 0; j--)
489 if (current_state->e[i] == current_state->e[j])
495 delete current_neighbor_searches[i];
499 #ifdef DEBUG_DG_ASSEMBLING
500 template<
typename Scalar>
501 void DiscreteProblemDGAssembler<Scalar>::debug()
503 #pragma omp critical (debug_DG)
506 if (DEBUG_DG_ASSEMBLING_ELEMENT != -1)
508 for (
unsigned int i = 0; i < this->current_state->num; i++)
509 if (neighbor_searches[current_state->isurf][i]->
central_el->
id == DEBUG_DG_ASSEMBLING_ELEMENT)
516 if (DEBUG_DG_ASSEMBLING_ISURF != -1)
517 if (current_state->isurf != DEBUG_DG_ASSEMBLING_ISURF)
523 for (
unsigned int i = 0; i < this->current_state->num; i++)
525 NeighborSearch<Scalar>* ns = neighbor_searches[current_state->isurf][i];
526 std::cout <<
"The " << ++
id <<
"-th Neighbor search: " << ns->n_neighbors <<
" neighbors." << std::endl;
527 std::cout <<
"\tCentral element: " << ns->central_el->id <<
", Isurf: " << current_state->isurf <<
", Original sub_idx: " << ns->original_central_el_transform << std::endl;
528 for (
int j = 0; j < ns->n_neighbors; j++)
530 std::cout <<
'\t' <<
"The " << j <<
"-th neighbor element: " << ns->neighbors[j]->id << std::endl;
531 if (ns->central_transformations[j])
533 std::cout <<
'\t' <<
"Central transformations: " << std::endl;
534 for (
int k = 0; k < ns->central_transformations[j]->num_levels; k++)
535 std::cout <<
'\t' <<
'\t' << ns->central_transformations[j]->transf[k] << std::endl;
537 if (ns->neighbor_transformations[j])
539 std::cout <<
'\t' <<
"Neighbor transformations: " << std::endl;
540 for (
int k = 0; k < ns->neighbor_transformations[j]->num_levels; k++)
541 std::cout <<
'\t' <<
'\t' << ns->neighbor_transformations[j]->transf[k] << std::endl;
550 template class HERMES_API DiscreteProblemDGAssembler < double > ;
551 template class HERMES_API DiscreteProblemDGAssembler < std::complex<double> > ;
PrecalcShapeset variant for fast assembling.
~DiscreteProblemDGAssembler()
Destructor.
Element * central_el
Central (currently assembled) element.
Used to pass the instances of Space around.
static void process_edge(NeighborSearch< Scalar > **neighbor_searches, unsigned char num_neighbor_searches, unsigned int &num_neighbors, bool *&processed)
The main method, for the passed neighbor searches, it will process all multi-mesh neighbor consolidat...
HERMES_API Func< double > * init_fn(PrecalcShapeset *fu, RefMap *rm, const int order)
Init the shape function for the evaluation of the volumetric/surface integral (transformation of valu...
void add(Func< double > *func)
Calculate this += func for each function expations and each integration point.
void deinit_assembling_one_state()
Deinitialize assembling for a state.
void assemble_one_state()
Assemble DG forms.
::xsd::cxx::tree::string< char, simple_type > string
C++ type corresponding to the string XML Schema built-in type.
This class is a one-thread (non-DG) assembly worker.
Represents the reference mapping.
void init_assembling_one_state(Traverse::State *current_state_)
Initialize assembling for a state.
This class characterizes a neighborhood of a given edge in terms of adjacent elements and provides me...