Hermes2D  3.0
discrete_problem_dg_assembler.cpp
1 //#define DEBUG_DG_ASSEMBLING
2 //#define DEBUG_DG_ASSEMBLING_ELEMENT 44
3 //#define DEBUG_DG_ASSEMBLING_ISURF 3
4 // This file is part of Hermes2D.
5 //
6 // Hermes2D is free software: you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation, either version 2 of the License, or
9 // (at your option) any later version.
10 //
11 // Hermes2D is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with Hermes2D. If not, see <http://www.gnu.org/licenses/>.
18 
19 #include "discrete_problem/dg/discrete_problem_dg_assembler.h"
20 #include "discrete_problem/discrete_problem_thread_assembler.h"
21 
23 
24 namespace Hermes
25 {
26  namespace Hermes2D
27  {
28  static const std::string H2D_DG_INNER_EDGE = "-1234567";
29 
30  template<typename Scalar>
31  unsigned int DiscreteProblemDGAssembler<Scalar>::dg_order = 20;
32 
33  template<typename Scalar>
34  DiscreteProblemDGAssembler<Scalar>::DiscreteProblemDGAssembler(DiscreteProblemThreadAssembler<Scalar>* threadAssembler, const std::vector<SpaceSharedPtr<Scalar> > spaces, std::vector<MeshSharedPtr>& meshes)
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),
46  spaces(spaces),
47  meshes(meshes)
48  {
49  this->DG_matrix_forms_present = false;
50  this->DG_vector_forms_present = false;
51  if (this->wf)
52  {
53  if (!this->wf->mfDG.empty())
54  this->DG_matrix_forms_present = true;
55 
56  if (!this->wf->vfDG.empty())
57  this->DG_vector_forms_present = true;
58  }
59 
60  if (DG_matrix_forms_present)
61  {
62  npss = malloc_with_check<PrecalcShapesetAssembling*>(spaces_size);
63  nrefmaps = malloc_with_check<RefMap*>(spaces_size);
64 
65  for (unsigned int j = 0; j < spaces_size; j++)
66  {
67  npss[j] = new PrecalcShapesetAssembling(spaces[j]->shapeset);
68  nrefmaps[j] = new RefMap();
69  }
70  }
71  this->als = threadAssembler->als;
72  }
73 
74  template<typename Scalar>
76  {
77  return neighbor_searches[index + wf->get_neq()];
78  }
79 
80  template<typename Scalar>
82  {
83  if (DG_matrix_forms_present)
84  {
85  for (unsigned int j = 0; j < spaces_size; j++)
86  {
87  delete npss[j];
88  delete nrefmaps[j];
89  }
90  free_with_check(npss);
91  free_with_check(nrefmaps);
92  }
93  }
94 
95  template<typename Scalar>
97  {
98  this->current_state = current_state_;
99 
100  this->neighbor_searches = new NeighborSearch<Scalar>**[this->current_state->rep->nvert];
101  for (int i = 0; i < this->current_state->rep->nvert; i++)
102  this->neighbor_searches[i] = new NeighborSearch<Scalar>*[this->current_state->num];
103  this->num_neighbors = new unsigned int[this->current_state->rep->nvert];
104  processed = new bool*[current_state->rep->nvert];
105 
106  if (DG_matrix_forms_present)
107  {
108  for (unsigned int i = 0; i < spaces_size; i++)
109  {
110  npss[i]->set_quad_2d(&g_quad_2d_std);
111  nrefmaps[i]->set_quad_2d(&g_quad_2d_std);
112  }
113  }
114  }
115 
116  template<typename Scalar>
118  {
119 #pragma omp critical (DG)
120  {
121  for (unsigned int i = 0; i < current_state->num; i++)
122  current_state->e[i]->visited = true;
123 
124  for (current_state->isurf = 0; current_state->isurf < current_state->rep->nvert; current_state->isurf++)
125  {
126  if (!current_state->bnd[current_state->isurf])
127  {
128  // If this edge is an inter-element one on all meshes.
129  if (!init_neighbors(neighbor_searches[current_state->isurf], current_state))
130  continue;
131 
132  // Create a multimesh tree;
133  MultimeshDGNeighborTree<Scalar>::process_edge(neighbor_searches[current_state->isurf], this->current_state->num, this->num_neighbors[current_state->isurf], this->processed[current_state->isurf]);
134  }
135  }
136  for (current_state->isurf = 0; current_state->isurf < current_state->rep->nvert; current_state->isurf++)
137  {
138  if (!current_state->bnd[current_state->isurf])
139  {
140 #ifdef DEBUG_DG_ASSEMBLING
141  debug();
142 #endif
143  for (unsigned int neighbor_i = 0; neighbor_i < num_neighbors[current_state->isurf]; neighbor_i++)
144  {
145  if (!DG_vector_forms_present && processed[current_state->isurf][neighbor_i])
146  continue;
147 
148  // DG-inner-edge-wise parameters for WeakForm.
149  wf->set_active_DG_state(current_state->e, current_state->isurf);
150 
151  assemble_one_neighbor(processed[current_state->isurf][neighbor_i], neighbor_i, neighbor_searches[current_state->isurf]);
152  }
153 
154  deinit_neighbors(neighbor_searches[current_state->isurf], current_state);
155  }
156  else
157  processed[current_state->isurf] = nullptr;
158  }
159  }
160  }
161 
162  template<typename Scalar>
164  {
165  for (int i = 0; i < this->current_state->rep->nvert; i++)
166  {
167  free_with_check(neighbor_searches[i]);
168  free_with_check(processed[i]);
169  }
170  free_with_check(neighbor_searches);
171  free_with_check(num_neighbors);
172  free_with_check(processed);
173  }
174 
175  template<typename Scalar>
177  {
178  }
179 
180  template<typename Scalar>
181  void DiscreteProblemDGAssembler<Scalar>::assemble_one_neighbor(bool edge_processed, unsigned int neighbor_i, NeighborSearch<Scalar>** current_neighbor_searches)
182  {
183  // Set the active segment in all NeighborSearches
184  for (unsigned int i = 0; i < this->current_state->num; i++)
185  {
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];
190  }
191 
192  // Push all the necessary transformations to all functions of this stage.
193  // The important thing is that the transformations to the current subelement are already there.
194  for (unsigned int fns_i = 0; fns_i < current_state->num; fns_i++)
195  {
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]);
199  }
200 
201  // For neighbor psss.
202  if (current_mat && DG_matrix_forms_present && !edge_processed)
203  {
204  for (unsigned int idx_i = 0; idx_i < spaces_size; idx_i++)
205  {
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]);
210  }
211  }
212 
213  // Also push the transformations to the refmaps.
214  for (unsigned int i = 0; i < spaces_size; i++)
215  {
216  refmaps[i]->force_transform(pss[i]->get_transform(), pss[i]->get_ctm());
217 
218  // Neighbor.
219  if (current_mat && DG_matrix_forms_present && !edge_processed)
220  {
221  nrefmaps[i]->set_active_element(npss[i]->get_active_element());
222  nrefmaps[i]->force_transform(npss[i]->get_transform(), npss[i]->get_ctm());
223  }
224  }
225 
226  /***/
227  // The computation takes place here.
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);
234 
235  // Create the extended shapeset on the union of the central element and its current neighbor.
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++)
239  {
240  if (!current_state->e[i])
241  continue;
242  current_neighbor_searches[i]->set_quad_order(order);
243  order_base = 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);
247 
248  if (current_mat && DG_matrix_forms_present && !edge_processed)
249  {
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++)
253  {
254  if (ext_asmlist[i]->dof[func_i] < 0)
255  continue;
256 
257  // Choose the correct shapeset for the test function.
258  if (ext_asmlist[i]->has_support_on_neighbor(func_i))
259  {
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);
262  }
263  else
264  {
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);
267  }
268  }
269  }
270  }
271 
272  DiscontinuousFunc<Scalar>** ext = init_ext_fns(wf->ext, current_neighbor_searches, order);
273 
274  DiscontinuousFunc<Scalar>** u_ext_func = malloc_with_check<DiscontinuousFunc<Scalar>*>(this->spaces_size);
275  if (this->nonlinear)
276  {
277  if (u_ext)
278  {
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])
281  {
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]);
284  }
285  else
286  u_ext_func[u_ext_func_i] = nullptr;
287  }
288  else
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;
291  }
292 
293  if (current_mat && DG_matrix_forms_present && !edge_processed)
294  {
295  for (unsigned short current_mfsurf_i = 0; current_mfsurf_i < wf->mfDG.size(); current_mfsurf_i++)
296  {
297  if (!this->selectiveAssembler->form_to_be_assembled((MatrixForm<Scalar>*)wf->mfDG[current_mfsurf_i], current_state))
298  continue;
299 
300  MatrixFormDG<Scalar>* mfs = wf->mfDG[current_mfsurf_i];
301 
302  int m = mfs->i;
303  int n = mfs->j;
304 
305  // Precalc shapeset and refmaps used for the evaluation.
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];
309 
310  for (int i = 0; i < ext_asmlist_v->cnt; i++)
311  {
312  if (ext_asmlist_v->dof[i] < 0)
313  continue;
314 
315  support_neigh_v = ext_asmlist_v->has_support_on_neighbor(i);
316 
317  for (int j = 0; j < ext_asmlist_u->cnt; j++)
318  {
319  if (ext_asmlist_u->dof[j] >= 0)
320  {
321  // Values of the previous Newton iteration, shape functions and external functions in quadrature points.
322  DiscontinuousFunc<double>* u = testFunctions[n][j];
323  DiscontinuousFunc<double>* v = testFunctions[m][i];
324 
325  Scalar res = mfs->value(n_quadrature_points, jacobian_x_weights[n], u_ext_func, u, v, e[n], ext) * mfs->scaling_factor;
326 
327  support_neigh_u = ext_asmlist_u->has_support_on_neighbor(j);
328 
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]);
331 
332  local_stiffness_matrix[i * 2 * H2D_MAX_LOCAL_BASIS_SIZE + j] = val;
333  }
334  }
335  }
336 
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);
338  }
339  }
340 
341  for (int i = 0; i < this->spaces_size; i++)
342  {
343  for (int func_i = 0; func_i < ext_asmlist[i]->cnt; func_i++)
344  {
345  if (ext_asmlist[i]->dof[func_i] < 0)
346  continue;
347  delete testFunctions[i][func_i];
348  }
349  delete ext_asmlist[i];
350  free_with_check(testFunctions[i]);
351  }
352 
353  free_with_check(testFunctions);
354  free_with_check(ext_asmlist);
355 
356  if (current_rhs && DG_vector_forms_present)
357  {
358  for (unsigned int ww = 0; ww < wf->vfDG.size(); ww++)
359  {
360  VectorFormDG<Scalar>* vfs = wf->vfDG[ww];
361  if (vfs->areas[0] != H2D_DG_INNER_EDGE)
362  continue;
363 
364  int n = vfs->i;
365 
366  if (!this->selectiveAssembler->form_to_be_assembled((VectorForm<Scalar>*)vfs, current_state))
367  continue;
368 
369  NeighborSearch<Scalar>* current_neighbor_searches_v = current_neighbor_searches[n];
370 
371  // Here we use the standard pss, possibly just transformed by NeighborSearch.
372  for (unsigned int dof_i = 0; dof_i < als[n].cnt; dof_i++)
373  {
374  if (als[n].dof[dof_i] < 0)
375  continue;
376  pss[n]->set_active_shape(als[n].idx[dof_i]);
377 
378  Func<double>* v = init_fn(pss[n], refmaps[n], current_neighbor_searches_v->get_quad_eo());
379 
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]);
381  delete v;
382  }
383  }
384  }
385 
386  if (ext)
387  {
388  for (unsigned int i = 0; i < wf->ext.size(); i++)
389  {
390  delete ext[i];
391  }
392  delete[] ext;
393  }
394 
395  if (this->nonlinear)
396  {
397  if (u_ext)
398  {
399  for (int u_ext_i = 0; u_ext_i < this->spaces_size; u_ext_i++)
400  if (u_ext[u_ext_i])
401  {
402  delete u_ext_func[u_ext_i];
403  }
404  }
405  }
406 
407  delete[] u_ext_func;
408 
409  for (int i = 0; i < this->spaces_size; i++)
410  {
411  if (this->spaces[i]->get_type() != HERMES_L2_SPACE)
412  continue;
413  delete[] jacobian_x_weights[i];
414  delete e[i];
415  }
416 
417  free_with_check(geometry);
418  free_with_check(jacobian_x_weights);
419  free_with_check(e);
420 
421  // This is just cleaning after ourselves.
422  // Clear the transformations from the RefMaps and all functions.
423  for (unsigned int fns_i = 0; fns_i < current_state->num; fns_i++)
424  {
425  fns[fns_i]->set_transform(current_neighbor_searches[fns_i]->original_central_el_transform);
426  }
427 
428  // Also clear the transformations from the slave psss and refmaps.
429  for (unsigned int i = 0; i < spaces_size; i++)
430  refmaps[i]->force_transform(pss[i]->get_transform(), pss[i]->get_ctm());
431  }
432 
433  template<typename Scalar>
434  void DiscreteProblemDGAssembler<Scalar>::deinit_assembling_one_neighbor()
435  {
436  }
437 
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)
441  {
442  DiscontinuousFunc<Scalar>** ext_fns = new DiscontinuousFunc<Scalar>*[ext.size()];
443  for (unsigned int j = 0; j < ext.size(); j++)
444  {
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());
448  }
449 
450  return ext_fns;
451  }
452 
453  template<typename Scalar>
454  bool DiscreteProblemDGAssembler<Scalar>::init_neighbors(NeighborSearch<Scalar>** current_neighbor_searches, Traverse::State* current_state)
455  {
456  // Initialize the NeighborSearches.
457  bool DG_intra = false;
458  for (unsigned int i = 0; i < current_state->num; i++)
459  {
460  bool existing_ns = false;
461  for (int j = i - 1; j >= 0; j--)
462  if (current_state->e[i] == current_state->e[j])
463  {
464  current_neighbor_searches[i] = current_neighbor_searches[j];
465  existing_ns = true;
466  break;
467  }
468  if (!existing_ns)
469  {
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))
474  DG_intra = true;
475  current_neighbor_searches[i]->clear_initial_sub_idx();
476  }
477  }
478 
479  return DG_intra;
480  }
481 
482  template<typename Scalar>
483  void DiscreteProblemDGAssembler<Scalar>::deinit_neighbors(NeighborSearch<Scalar>** current_neighbor_searches, Traverse::State* current_state)
484  {
485  for (unsigned int i = 0; i < current_state->num; i++)
486  {
487  bool existing_ns = false;
488  for (int j = i - 1; j >= 0; j--)
489  if (current_state->e[i] == current_state->e[j])
490  {
491  existing_ns = true;
492  break;
493  }
494  if (!existing_ns)
495  delete current_neighbor_searches[i];
496  }
497  }
498 
499 #ifdef DEBUG_DG_ASSEMBLING
500  template<typename Scalar>
501  void DiscreteProblemDGAssembler<Scalar>::debug()
502  {
503 #pragma omp critical (debug_DG)
504  {
505  bool pass = true;
506  if (DEBUG_DG_ASSEMBLING_ELEMENT != -1)
507  {
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)
510  pass = false;
511  }
512  else
513  pass = false;
514 
515  if (!pass)
516  if (DEBUG_DG_ASSEMBLING_ISURF != -1)
517  if (current_state->isurf != DEBUG_DG_ASSEMBLING_ISURF)
518  pass = true;
519 
520  if (!pass)
521  {
522  int id = 0;
523  for (unsigned int i = 0; i < this->current_state->num; i++)
524  {
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++)
529  {
530  std::cout << '\t' << "The " << j << "-th neighbor element: " << ns->neighbors[j]->id << std::endl;
531  if (ns->central_transformations[j])
532  {
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;
536  }
537  if (ns->neighbor_transformations[j])
538  {
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;
542  }
543  }
544  }
545  }
546  }
547  }
548 #endif
549 
550  template class HERMES_API DiscreteProblemDGAssembler < double > ;
551  template class HERMES_API DiscreteProblemDGAssembler < std::complex<double> > ;
552  }
553 }
PrecalcShapeset variant for fast assembling.
Definition: precalc.h:109
Definition: adapt.h:24
int id
element id number
Definition: element.h:112
Element * central_el
Central (currently assembled) element.
Used to pass the instances of Space around.
Definition: space.h:34
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...
Definition: forms.cpp:469
Used to pass the instances of WeakForm around.
Definition: weakform.h:55
void add(Func< double > *func)
Calculate this += func for each function expations and each integration point.
Definition: forms.cpp:122
void deinit_assembling_one_state()
Deinitialize assembling for a state.
::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.
Definition: refmap.h:40
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...