16 #include "adapt/error_thread_calculator.h"
17 #include "discrete_problem/discrete_problem_helpers.h"
18 #include "discrete_problem/dg/multimesh_dg_neighbor_tree.h"
19 #include "neighbor_search.h"
20 #include "mesh/refmap.h"
28 template<
typename Scalar>
29 ErrorThreadCalculator<Scalar>::ErrorThreadCalculator(ErrorCalculator<Scalar>* errorCalculator) :
30 errorCalculator(errorCalculator)
32 slns = malloc_with_check<ErrorThreadCalculator<Scalar>, Solution<Scalar>*>(this->errorCalculator->component_count,
this);
33 rslns = malloc_with_check<ErrorThreadCalculator<Scalar>, Solution<Scalar>*>(this->errorCalculator->component_count,
this);
35 for (
int j = 0; j < this->errorCalculator->component_count; j++)
37 slns[j] =
static_cast<Solution<Scalar>*
>(errorCalculator->coarse_solutions[j]->clone());
38 rslns[j] =
static_cast<Solution<Scalar>*
>(errorCalculator->fine_solutions[j]->clone());
42 template<
typename Scalar>
43 ErrorThreadCalculator<Scalar>::~ErrorThreadCalculator()
48 template<
typename Scalar>
49 void ErrorThreadCalculator<Scalar>::free()
51 for (
int j = 0; j < this->errorCalculator->component_count; j++)
57 free_with_check(slns);
58 free_with_check(rslns);
61 template<
typename Scalar>
62 void ErrorThreadCalculator<Scalar>::evaluate_one_state(Traverse::State* current_state_)
64 this->current_state = current_state_;
67 for (
int i = 0; i < this->errorCalculator->component_count; i++)
69 slns[i]->set_active_element(current_state->e[i]);
70 slns[i]->set_transform(current_state->sub_idx[i]);
72 rslns[i]->set_active_element(current_state->e[this->errorCalculator->component_count + i]);
73 rslns[i]->set_transform(current_state->sub_idx[this->errorCalculator->component_count + i]);
77 int order = g_quad_2d_std.get_max_order(current_state->rep->get_mode());
80 this->evaluate_volumetric_forms(current_state, order);
83 if (current_state->isBnd && this->errorCalculator->mfsurf.size() > 0)
85 for (current_state->isurf = 0; current_state->isurf < current_state->rep->nvert; current_state->isurf++)
87 if (!current_state->bnd[current_state->isurf])
90 this->evaluate_surface_forms_one_edge(current_state, order);
95 if (this->errorCalculator->mfDG.size() > 0)
97 for (current_state->isurf = 0; current_state->isurf < current_state->rep->nvert; current_state->isurf++)
99 if (current_state->bnd[current_state->isurf])
102 ErrorThreadCalculator<Scalar>::DGErrorCalculator dGErrorCalculator(
this);
103 dGErrorCalculator.assemble_one_edge();
108 template<
typename Scalar>
109 ErrorThreadCalculator<Scalar>::DGErrorCalculator::DGErrorCalculator(ErrorThreadCalculator* errorThreadCalculator) : errorThreadCalculator(errorThreadCalculator), current_state(errorThreadCalculator->current_state)
113 template<
typename Scalar>
116 this->neighbor_searches = malloc_with_check<ErrorThreadCalculator<Scalar>::DGErrorCalculator,
NeighborSearch<Scalar>*>(this->current_state->num,
this);
121 bool* dummy_processed;
126 for (
unsigned int neighbor_i = 0; neighbor_i < num_neighbors; neighbor_i++)
127 this->assemble_one_neighbor(neighbor_i);
129 free_with_check(dummy_processed);
136 template<
typename Scalar>
140 bool DG_intra =
false;
141 for (
unsigned int i = 0; i < current_state->num; i++)
143 bool existing_ns =
false;
144 for (
int j = i - 1; j >= 0; j--)
145 if (current_state->e[i] == current_state->e[j])
147 neighbor_searches[i] = neighbor_searches[j];
154 if (i < this->errorThreadCalculator->errorCalculator->component_count)
157 ns =
new NeighborSearch<Scalar>(current_state->e[i], this->errorThreadCalculator->rslns[i - this->errorThreadCalculator->errorCalculator->component_count]->get_mesh());
160 neighbor_searches[i] = ns;
161 if (neighbor_searches[i]->set_active_edge_multimesh(current_state->isurf))
170 template<
typename Scalar>
174 for (
unsigned int i = 0; i < current_state->num; i++)
176 bool existing_ns =
false;
177 for (
int j = i - 1; j >= 0; j--)
178 if (current_state->e[i] == current_state->e[j])
184 delete this->neighbor_searches[i];
186 free_with_check(neighbor_searches);
189 template<
typename Scalar>
190 void ErrorThreadCalculator<Scalar>::DGErrorCalculator::initialize_error_and_norm_functions(NormFormDG<Scalar>* mfs, DiscontinuousFunc<Scalar>* error_func[2], DiscontinuousFunc<Scalar>* norm_func[2])
192 switch (mfs->get_function_type())
194 case CoarseSolutions:
195 error_func[0] = neighbor_searches[mfs->i]->init_ext_fn(this->errorThreadCalculator->slns[mfs->i]);
196 if (mfs->i != mfs->j)
197 error_func[1] = neighbor_searches[mfs->j]->init_ext_fn(this->errorThreadCalculator->slns[mfs->j]);
199 error_func[1] = error_func[0];
200 norm_func[0] = error_func[0];
201 norm_func[1] = error_func[1];
204 error_func[0] = neighbor_searches[mfs->i + this->errorThreadCalculator->errorCalculator->component_count]->init_ext_fn(this->errorThreadCalculator->rslns[mfs->i]);
205 if (mfs->i != mfs->j)
206 error_func[1] = neighbor_searches[mfs->j + this->errorThreadCalculator->errorCalculator->component_count]->init_ext_fn(this->errorThreadCalculator->rslns[mfs->j]);
208 error_func[1] = error_func[0];
209 norm_func[0] = error_func[0];
210 norm_func[1] = error_func[1];
212 case SolutionsDifference:
213 error_func[0] = neighbor_searches[mfs->i]->init_ext_fn(this->errorThreadCalculator->slns[mfs->i]);
214 norm_func[0] = neighbor_searches[mfs->i + this->errorThreadCalculator->errorCalculator->component_count]->init_ext_fn(this->errorThreadCalculator->rslns[mfs->i]);
215 error_func[0]->subtract(*norm_func[0]);
216 if (mfs->j != mfs->i)
218 error_func[1] = neighbor_searches[mfs->j]->init_ext_fn(this->errorThreadCalculator->slns[mfs->j]);
219 norm_func[1] = neighbor_searches[mfs->j + this->errorThreadCalculator->errorCalculator->component_count]->init_ext_fn(this->errorThreadCalculator->rslns[mfs->j]);
220 error_func[1]->subtract(*norm_func[1]);
224 error_func[1] = error_func[0];
225 norm_func[1] = norm_func[0];
231 template<
typename Scalar>
232 void ErrorThreadCalculator<Scalar>::DGErrorCalculator::assemble_one_neighbor(
unsigned int neighbor_i)
235 for (
unsigned int i = 0; i < this->current_state->num; i++)
237 NeighborSearch<Scalar>* ns = neighbor_searches[i];
238 ns->active_segment = neighbor_i;
239 ns->neighb_el = ns->neighbors[neighbor_i];
240 ns->neighbor_edge = ns->neighbor_edges[neighbor_i];
245 for (
unsigned int fns_i = 0; fns_i < this->errorThreadCalculator->errorCalculator->component_count; fns_i++)
247 NeighborSearch<Scalar>* ns = neighbor_searches[fns_i];
248 if (ns->central_transformations[neighbor_i])
249 ns->central_transformations[neighbor_i]->apply_on(this->errorThreadCalculator->slns[fns_i]);
251 ns = neighbor_searches[fns_i + this->errorThreadCalculator->errorCalculator->component_count];
252 if (ns->central_transformations[neighbor_i])
253 ns->central_transformations[neighbor_i]->apply_on(this->errorThreadCalculator->rslns[fns_i]);
262 for (
int i = 0; i < this->errorThreadCalculator->errorCalculator->component_count; i++)
264 neighbor_searches[i]->set_quad_order(order);
265 neighbor_searches[i + this->errorThreadCalculator->errorCalculator->component_count]->set_quad_order(order);
269 RefMap** refmaps = malloc_with_check<ErrorThreadCalculator<Scalar>::DGErrorCalculator, RefMap*>(this->errorThreadCalculator->errorCalculator->component_count,
this);
270 for (
int i = 0; i < this->errorThreadCalculator->errorCalculator->component_count; i++)
271 refmaps[i] = this->errorThreadCalculator->slns[i]->get_refmap();
272 this->errorThreadCalculator->n_quadrature_points = init_surface_geometry_points_allocated(refmaps, this->errorThreadCalculator->errorCalculator->component_count, order_base, current_state->isurf, current_state->rep->
marker, this->errorThreadCalculator->geometry_surf, this->errorThreadCalculator->jacobian_x_weights);
273 free_with_check(refmaps);
275 for (
unsigned short current_mfDG_i = 0; current_mfDG_i < this->errorThreadCalculator->errorCalculator->mfDG.size(); current_mfDG_i++)
277 NormFormDG<Scalar>* mfs = this->errorThreadCalculator->errorCalculator->mfDG[current_mfDG_i];
279 double*
error = &this->errorThreadCalculator->errorCalculator->errors[mfs->i][current_state->e[mfs->i]->
id];
280 double* norm = &this->errorThreadCalculator->errorCalculator->norms[mfs->i][current_state->e[mfs->i]->
id];
282 DiscontinuousFunc<Scalar>* error_func[2];
283 DiscontinuousFunc<Scalar>* norm_func[2];
285 this->initialize_error_and_norm_functions(mfs, error_func, norm_func);
287 this->errorThreadCalculator->evaluate_DG_form(mfs, error_func[mfs->i], error_func[mfs->j], norm_func[mfs->i], norm_func[mfs->j], error, norm);
290 this->errorThreadCalculator->deinitialize_error_and_norm_functions(mfs, error_func, norm_func);
295 for (
unsigned int fns_i = 0; fns_i < this->errorThreadCalculator->errorCalculator->component_count; fns_i++)
297 this->errorThreadCalculator->slns[fns_i]->set_transform(neighbor_searches[fns_i]->original_central_el_transform);
298 this->errorThreadCalculator->rslns[fns_i]->set_transform(neighbor_searches[this->errorThreadCalculator->errorCalculator->component_count + fns_i]->original_central_el_transform);
302 template<
typename Scalar>
303 template<
typename NormFormType>
304 void ErrorThreadCalculator<Scalar>::initialize_error_and_norm_functions(NormFormType* mf, Func<Scalar>* error_func[2], Func<Scalar>* norm_func[2],
int order)
306 switch (mf->get_function_type())
308 case CoarseSolutions:
309 error_func[0] =
init_fn(slns[mf->i], order);
311 error_func[1] =
init_fn(slns[mf->j], order);
313 error_func[1] = error_func[0];
314 norm_func[0] = error_func[0];
315 norm_func[1] = error_func[1];
318 error_func[0] =
init_fn(rslns[mf->i], order);
320 error_func[1] =
init_fn(rslns[mf->j], order);
322 error_func[1] = error_func[0];
323 norm_func[0] = error_func[0];
324 norm_func[1] = error_func[1];
326 case SolutionsDifference:
327 error_func[0] =
init_fn(slns[mf->i], order);
328 norm_func[0] =
init_fn(rslns[mf->i], order);
329 error_func[0]->subtract(norm_func[0]);
332 error_func[1] =
init_fn(slns[mf->j], order);
333 norm_func[1] =
init_fn(rslns[mf->j], order);
334 error_func[1]->subtract(norm_func[1]);
338 error_func[1] = error_func[0];
339 norm_func[1] = norm_func[0];
345 template<
typename Scalar>
346 template<
typename NormFormType,
typename FuncType>
347 void ErrorThreadCalculator<Scalar>::deinitialize_error_and_norm_functions(NormFormType* mf, FuncType* error_func[2], FuncType* norm_func[2])
349 switch (mf->get_function_type())
351 case CoarseSolutions:
353 delete error_func[0];
356 delete error_func[1];
359 case SolutionsDifference:
360 delete error_func[0];
364 delete error_func[1];
371 template<
typename Scalar>
372 void ErrorThreadCalculator<Scalar>::evaluate_volumetric_forms(Traverse::State* current_state,
int order)
375 RefMap** refmaps = malloc_with_check<ErrorThreadCalculator<Scalar>, RefMap*>(this->errorCalculator->component_count,
this);
376 for (
int i = 0; i < this->errorCalculator->component_count; i++)
377 refmaps[i] = slns[i]->get_refmap();
378 this->n_quadrature_points =
init_geometry_points_allocated(refmaps, this->errorCalculator->component_count, order, this->geometry_vol, this->jacobian_x_weights);
380 free_with_check(refmaps);
382 for (
unsigned short i = 0; i < this->errorCalculator->mfvol.size(); i++)
384 NormFormVol<Scalar>* form = this->errorCalculator->mfvol[i];
385 double* error = &this->errorCalculator->errors[form->i][current_state->e[form->i]->id];
386 double* norm = &this->errorCalculator->norms[form->i][current_state->e[form->i]->id];
388 Func<Scalar>* error_func[2];
389 Func<Scalar>* norm_func[2];
391 this->initialize_error_and_norm_functions(form, error_func, norm_func, order);
392 this->evaluate_volumetric_form(form, error_func[0], error_func[1], norm_func[0], norm_func[1], error, norm);
393 this->deinitialize_error_and_norm_functions(form, error_func, norm_func);
397 template<
typename Scalar>
398 void ErrorThreadCalculator<Scalar>::evaluate_surface_forms_one_edge(Traverse::State* current_state,
int order)
400 RefMap** refmaps = malloc_with_check<ErrorThreadCalculator<Scalar>, RefMap*>(this->errorCalculator->component_count,
this);
401 for (
int i = 0; i < this->errorCalculator->component_count; i++)
402 refmaps[i] = slns[i]->get_refmap();
403 this->n_quadrature_points = init_surface_geometry_points_allocated(refmaps, this->errorCalculator->component_count, order, current_state->isurf, current_state->rep->marker, this->geometry_surf, this->jacobian_x_weights);
404 free_with_check(refmaps);
406 for (
unsigned short i = 0; i < this->errorCalculator->mfsurf.size(); i++)
408 NormFormSurf<Scalar>* form = this->errorCalculator->mfsurf[i];
410 bool assemble =
false;
411 if (form->get_area() == HERMES_ANY)
415 if (this->slns[form->i])
417 Mesh::MarkersConversion::StringValid marker_to_check = this->slns[form->i]->get_mesh()->get_boundary_markers_conversion().get_user_marker(current_state->e[form->i]->en[current_state->isurf]->marker);
418 if (marker_to_check.valid)
421 if (form->get_area() == marker)
425 if (this->rslns[form->i])
427 Mesh::MarkersConversion::StringValid marker_to_check = this->rslns[form->i]->get_mesh()->get_boundary_markers_conversion().get_user_marker(current_state->e[form->i]->en[current_state->isurf]->marker);
428 if (marker_to_check.valid)
431 if (form->get_area() == marker)
440 double* error = &this->errorCalculator->errors[form->i][current_state->e[form->i]->id];
441 double* norm = &this->errorCalculator->norms[form->i][current_state->e[form->i]->id];
443 Func<Scalar>* error_func[2];
444 Func<Scalar>* norm_func[2];
446 this->initialize_error_and_norm_functions(form, error_func, norm_func, order);
447 this->evaluate_surface_form(form, error_func[0], error_func[0], norm_func[1], norm_func[1], error, norm);
448 this->deinitialize_error_and_norm_functions(form, error_func, norm_func);
452 template<
typename Scalar>
453 void ErrorThreadCalculator<Scalar>::evaluate_volumetric_form(NormFormVol<Scalar>* form, Func<Scalar>* difference_func_i, Func<Scalar>* difference_func_j, Func<Scalar>* rsln_i, Func<Scalar>* rsln_j,
double* error,
double* norm)
455 double error_value = std::abs(form->value(this->n_quadrature_points, this->jacobian_x_weights, difference_func_i, difference_func_j, &this->geometry_vol));
457 (*error) += error_value;
459 double norm_value = std::abs(form->value(this->n_quadrature_points, this->jacobian_x_weights, rsln_i, rsln_j, &this->geometry_vol));
462 (*norm) += norm_value;
465 template<
typename Scalar>
466 void ErrorThreadCalculator<Scalar>::evaluate_surface_form(NormFormSurf<Scalar>* form, Func<Scalar>* difference_func_i, Func<Scalar>* difference_func_j, Func<Scalar>* rsln_i, Func<Scalar>* rsln_j,
double* error,
double* norm)
468 double error_value = std::abs(form->value(this->n_quadrature_points, this->jacobian_x_weights, difference_func_i, difference_func_j, &this->geometry_surf));
474 (*error) += error_value;
476 double norm_value = std::abs(form->value(this->n_quadrature_points, this->jacobian_x_weights, rsln_i, rsln_j, &this->geometry_surf));
482 (*norm) += norm_value;
485 template<
typename Scalar>
486 void ErrorThreadCalculator<Scalar>::evaluate_DG_form(NormFormDG<Scalar>* form, DiscontinuousFunc<Scalar>* difference_func_i, DiscontinuousFunc<Scalar>* difference_func_j, DiscontinuousFunc<Scalar>* rsln_i, DiscontinuousFunc<Scalar>* rsln_j,
double* error,
double* norm)
488 double error_value = std::abs(form->value(this->n_quadrature_points, this->jacobian_x_weights, difference_func_i, difference_func_j, &this->geometry_surf));
494 (*error) += error_value;
496 double norm_value = std::abs(form->value(this->n_quadrature_points, this->jacobian_x_weights, rsln_i, rsln_j, &this->geometry_surf));
499 (*norm) += norm_value;
502 template HERMES_API
class ErrorThreadCalculator < double > ;
503 template HERMES_API
class ErrorThreadCalculator < std::complex<double> > ;
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...
uint64_t original_central_el_transform
Sub-element transformation of any function that comes from the.
void assemble_one_edge()
Assemble DG forms.
::xsd::cxx::tree::string< char, simple_type > string
C++ type corresponding to the string XML Schema built-in type.
This class characterizes a neighborhood of a given edge in terms of adjacent elements and provides me...
::xsd::cxx::tree::error< char > error
Error condition.
void clear_initial_sub_idx()
bool init_neighbors()
Initialize neighbors.
HERMES_API unsigned char init_geometry_points_allocated(RefMap **reference_mapping, unsigned short reference_mapping_count, int order, GeomVol< double > &geometry, double *jacobian_x_weights)