15 #include "kelly_type_adapt.h"
21 static const int H2D_DG_INNER_EDGE_INT = -1234567;
22 static const std::string H2D_DG_INNER_EDGE =
"-1234567";
24 template<
typename Scalar>
28 template<
typename Scalar>
31 this->set_area(H2D_DG_INNER_EDGE);
34 template<
typename Scalar>
36 bool ignore_visited_segments_,
37 Hermes::vector<const InterfaceEstimatorScalingFunction*> interface_scaling_fns_,
38 Hermes::vector<ProjNormType > norms_)
39 :
Adapt<Scalar>(spaces_, norms_)
41 error_estimators_surf.reserve(this->
num);
44 if(interface_scaling_fns_.size() == 0)
46 interface_scaling_fns_.reserve(this->
num);
47 for (
int i = 0; i < this->
num; i++)
55 element_markers_conversion = spaces_[0]->get_mesh()->element_markers_conversion;
56 boundary_markers_conversion = spaces_[0]->get_mesh()->boundary_markers_conversion;
59 template<
typename Scalar>
61 bool ignore_visited_segments_,
64 :
Adapt<Scalar>(space_, norm_)
66 if(interface_scaling_fn_ == NULL)
76 element_markers_conversion = space_->get_mesh()->element_markers_conversion;
77 boundary_markers_conversion = space_->get_mesh()->boundary_markers_conversion;
80 template<
typename Scalar>
83 Hermes::vector<RefinementSelectors::Selector<Scalar> *> refinement_selectors;
85 for (
int i = 0; i < this->num; i++)
86 refinement_selectors.push_back(&selector);
91 template<
typename Scalar>
94 if(form->
i < 0 || form->
i >= this->num)
95 throw Exceptions::ValueException(
"component number", form->
i, 0, this->num);
98 this->error_estimators_vol.push_back(form);
101 template<
typename Scalar>
104 if(form->
i < 0 || form->
i >= this->num)
105 throw Exceptions::ValueException(
"component number", form->
i, 0, this->num);
108 this->error_estimators_surf.push_back(form);
111 template<
typename Scalar>
113 Hermes::vector<double>* component_errors,
114 unsigned int error_flags)
116 if(slns.size() != this->num)
117 throw Hermes::Exceptions::LengthException(0, slns.size(), this->num);
121 for (
int i = 0; i < this->num; i++)
123 this->sln[i] = slns[i];
124 this->sln[i]->set_quad_2d(&g_quad_2d_std);
127 this->have_coarse_solutions =
true;
129 const Mesh** meshes =
new const Mesh*[this->num];
132 this->num_act_elems = 0;
133 for (
int i = 0; i < this->num; i++)
135 meshes[i] = (this->sln[i]->get_mesh());
136 fns[i] = (this->sln[i]);
141 if(this->errors[i] != NULL)
delete [] this->errors[i];
142 this->errors[i] =
new double[max];
143 memset(this->errors[i], 0,
sizeof(
double) * max);
146 double total_norm = 0.0;
148 bool calc_norm =
false;
152 double *norms = NULL;
155 norms =
new double[this->num];
156 memset(norms, 0, this->num *
sizeof(
double));
159 double *errors_components =
new double[this->num];
160 memset(errors_components, 0, this->num *
sizeof(
double));
161 this->errors_squared_sum = 0.0;
162 double total_error = 0.0;
171 if(ignore_visited_segments)
173 for (
int i = 0; i < this->num; i++)
176 for_all_active_elements(e, meshes[i])
182 trav.begin(this->num, meshes, fns);
183 while ((ee = trav.get_next_state()) != NULL)
190 surf_pos[0].
marker = ee->rep->en[0]->marker;
191 surf_pos[1].
marker = ee->rep->en[1]->marker;
192 surf_pos[2].
marker = ee->rep->en[2]->marker;
193 surf_pos[3].
marker = ee->rep->en[3]->marker;
201 for (
int i = 0; i < this->num; i++)
207 update_limit_table(ee->e[i]->get_mode());
209 RefMap *rm = this->sln[i]->get_refmap();
214 for (
unsigned int iest = 0; iest < error_estimators_vol.size(); iest++)
219 if(error_estimators_vol[iest]->i != i)
222 if(error_estimators_vol[iest]->area != HERMES_ANY)
223 if(!element_markers_conversion.get_internal_marker(error_estimators_vol[iest]->area).valid || element_markers_conversion.get_internal_marker(error_estimators_vol[iest]->area).marker != ee->e[i]->marker)
226 err += eval_volumetric_estimator(error_estimators_vol[iest], rm);
230 for (
unsigned int iest = 0; iest < error_estimators_surf.size(); iest++)
232 if(error_estimators_surf[iest]->i != i)
235 for (
int isurf = 0; isurf < ee->e[i]->get_nvert(); isurf++)
239 if(error_estimators_surf[iest]->area != HERMES_ANY)
241 if(!boundary_markers_conversion.get_internal_marker(error_estimators_surf[iest]->area).valid)
243 int imarker = boundary_markers_conversion.get_internal_marker(error_estimators_surf[iest]->area).marker;
245 if(imarker == H2D_DG_INNER_EDGE_INT)
247 if(imarker != surf_pos[isurf].marker)
251 err += eval_boundary_estimator(error_estimators_surf[iest], rm, &surf_pos[isurf]);
255 if(error_estimators_surf[iest]->area != H2D_DG_INNER_EDGE)
261 LightArray<NeighborSearch<Scalar>*> neighbor_searches(5);
262 unsigned int num_neighbors = 0;
267 unsigned int min_dg_mesh_seq = 0;
268 for(
unsigned int j = 0; j < this->spaces.size(); j++)
269 if(this->spaces[j]->get_mesh()->get_seq() < min_dg_mesh_seq || j == 0)
270 min_dg_mesh_seq = this->spaces[j]->get_mesh()->get_seq();
272 ns_index = meshes[i]->
get_seq() - min_dg_mesh_seq;
275 this->dp.init_neighbors(neighbor_searches, ee, min_dg_mesh_seq);
279 this->dp.build_multimesh_tree(root, neighbor_searches);
286 for(
unsigned int j = 0; j < neighbor_searches.get_size(); j++)
288 if(neighbor_searches.present(j))
291 this->dp.update_neighbor_search(ns, root);
292 if(num_neighbors == 0)
293 num_neighbors = ns->n_neighbors;
294 if(ns->n_neighbors != num_neighbors)
295 throw Hermes::Exceptions::Exception(
"Num_neighbors of different NeighborSearches not matching in KellyTypeAdapt<Scalar>::calc_err_internal.");
301 for (
unsigned int neighbor = 0; neighbor < num_neighbors; neighbor++)
303 if(ignore_visited_segments)
305 bool processed =
true;
306 for(
unsigned int j = 0; j < neighbor_searches.get_size(); j++)
307 if(neighbor_searches.present(j))
308 if(!neighbor_searches.get(j)->neighbors.at(neighbor)->visited)
314 if(processed)
continue;
320 for(
unsigned int j = 0; j < neighbor_searches.get_size(); j++)
322 if(neighbor_searches.present(j))
324 neighbor_searches.get(j)->active_segment = neighbor;
325 neighbor_searches.get(j)->neighb_el = neighbor_searches.get(j)->neighbors[neighbor];
326 neighbor_searches.get(j)->neighbor_edge = neighbor_searches.get(j)->neighbor_edges[neighbor];
333 for(
unsigned int fns_i = 0; fns_i < this->num; fns_i++)
336 if(ns->central_transformations.present(neighbor))
337 ns->central_transformations.get(neighbor)->apply_on(fns[fns_i]);
341 rm->force_transform(this->sln[i]->get_transform(), this->sln[i]->get_ctm());
345 double central_err = 0.5 * eval_interface_estimator(error_estimators_surf[iest],
346 rm, &surf_pos[isurf], neighbor_searches,
348 double neighb_err = central_err;
352 if(use_aposteriori_interface_scaling && interface_scaling_fns[i])
353 if(!element_markers_conversion.get_user_marker(ee->e[i]->marker).valid)
354 throw Hermes::Exceptions::Exception(
"Marker not valid.");
356 central_err *= interface_scaling_fns[i]->value(ee->e[i]->get_diameter(), element_markers_conversion.get_user_marker(ee->e[i]->marker).marker);
360 if(ignore_visited_segments)
362 Element *neighb = neighbor_searches.get(ns_index)->neighb_el;
366 if(use_aposteriori_interface_scaling && interface_scaling_fns[i])
367 if(!element_markers_conversion.get_user_marker(neighb->
marker).valid)
368 throw Hermes::Exceptions::Exception(
"Marker not valid.");
370 neighb_err *= interface_scaling_fns[i]->value(neighb->
get_diameter(), element_markers_conversion.get_user_marker(neighb->
marker).marker);
372 errors_components[i] += central_err + neighb_err;
373 total_error += central_err + neighb_err;
374 this->errors[i][ee->e[i]->id] += central_err;
375 this->errors[i][neighb->
id] += neighb_err;
383 for(
unsigned int fns_i = 0; fns_i < this->num; fns_i++)
384 fns[fns_i]->set_transform(neighbor_searches.get(meshes[fns_i]->
get_seq() - min_dg_mesh_seq)->original_central_el_transform);
386 rm->
set_transform(neighbor_searches.get(ns_index)->original_central_el_transform);
397 for(
unsigned int j = 0; j < neighbor_searches.get_size(); j++)
398 if(neighbor_searches.present(j))
399 delete neighbor_searches.get(j);
408 double nrm = eval_solution_norm(this->norm_form[i][i], rm, this->sln[i]);
413 errors_components[i] += err;
415 this->errors[i][ee->e[i]->id] += err;
417 ee->e[i]->visited =
true;
423 if(component_errors != NULL)
425 component_errors->clear();
426 for (
int i = 0; i < this->num; i++)
429 component_errors->push_back(sqrt(errors_components[i]));
431 component_errors->push_back(sqrt(errors_components[i]/norms[i]));
434 throw Hermes::Exceptions::Exception(
"Unknown total error type (0x%x).", error_flags & this->HERMES_TOTAL_ERROR_MASK);
441 this->error_time = this->accumulated();
446 for (
int i = 0; i < this->num; i++)
449 for_all_active_elements(e, meshes[i])
450 this->errors[i][e->
id] /= norms[i];
454 this->errors_squared_sum = total_error;
460 this->errors_squared_sum /= total_norm;
463 this->fill_regular_queue(meshes);
464 this->have_errors =
true;
468 delete [] errors_components;
472 return sqrt(total_error);
474 return sqrt(total_error / total_norm);
477 throw Hermes::Exceptions::Exception(
"Unknown total error type (0x%x).", error_flags & this->HERMES_TOTAL_ERROR_MASK);
482 template<
typename Scalar>
490 double fake_wt = 1.0;
492 Hermes::Ord o = form->
ord(1, &fake_wt, NULL, ou, ou, fake_e, NULL);
494 order += o.get_order();
497 if(sol && sol->
get_type() == HERMES_EXACT)
513 double* jwt =
new double[np];
514 for(
int i = 0; i < np; i++)
515 jwt[i] = pt[i][2] * jac[i];
519 Scalar res = form->
value(np, jwt, NULL, u, u, e, NULL);
525 return std::abs(res);
528 template<
typename Scalar>
536 for (
int i = 0; i < this->num; i++)
537 oi[i] =
init_fn_ord(this->sln[i]->get_fn_order() + inc);
541 for (
int i = 0; i < err_est_form->
ext.size(); i++)
542 fake_ext_fn[i] =
init_fn_ord(err_est_form->
ext[i]->get_fn_order());
544 double fake_wt = 1.0;
546 Hermes::Ord o = err_est_form->
ord(1, &fake_wt, oi, oi[err_est_form->
i], fake_e, fake_ext_fn);
548 order += o.get_order();
553 for (
int i = 0; i < this->num; i++)
563 for(
int i = 0; i < err_est_form->
ext.size(); i++)
564 fake_ext_fn[i]->free_ord();
565 delete [] fake_ext_fn;
575 double* jwt =
new double[np];
576 for(
int i = 0; i < np; i++)
577 jwt[i] = pt[i][2] * jac[i];
582 for (
int i = 0; i < this->num; i++)
583 ui[i] =
init_fn(this->sln[i], order);
586 for (
unsigned i = 0; i < err_est_form->
ext.size(); i++)
588 if(err_est_form->
ext[i] != NULL)
589 ext_fn[i] =
init_fn(err_est_form->
ext[i], order);
594 Scalar res = volumetric_scaling_const * err_est_form->
value(np, jwt, ui, ui[err_est_form->
i], e, ext_fn);
596 for (
int i = 0; i < this->num; i++)
606 for(
int i = 0; i < err_est_form->
ext.size(); i++)
607 fake_ext_fn[i]->free_fn();
608 delete [] fake_ext_fn;
615 return std::abs(res);
618 template<
typename Scalar>
625 for (
int i = 0; i < this->num; i++)
630 for (
int i = 0; i < err_est_form->
ext.size(); i++)
631 fake_ext_fn[i] =
init_fn_ord(err_est_form->
ext[i]->get_fn_order());
633 double fake_wt = 1.0;
635 Hermes::Ord o = err_est_form->
ord(1, &fake_wt, oi, oi[err_est_form->
i], fake_e, fake_ext_fn);
637 order += o.get_order();
642 for (
int i = 0; i < this->num; i++)
651 for(
int i = 0; i < err_est_form->
ext.size(); i++)
652 fake_ext_fn[i]->free_ord();
653 delete [] fake_ext_fn;
656 Quad2D* quad = this->sln[err_est_form->
i]->
get_quad_2d();
664 double* jwt =
new double[np];
665 for(
int i = 0; i < np; i++)
666 jwt[i] = pt[i][2] * tan[i][2];
669 Func<Scalar>** ui =
new Func<Scalar>*[this->num];
670 for (
int i = 0; i < this->num; i++)
671 ui[i] =
init_fn(this->sln[i], eo);
673 Func<Scalar>** ext_fn =
new Func<Scalar>*[err_est_form->
ext.size()];
674 for (
unsigned i = 0; i < err_est_form->
ext.size(); i++)
676 if(err_est_form->
ext[i] != NULL)
677 ext_fn[i] =
init_fn(err_est_form->
ext[i], order);
682 Scalar res = boundary_scaling_const *
683 err_est_form->
value(np, jwt, ui, ui[err_est_form->
i], e, ext_fn);
685 for (
int i = 0; i < this->num; i++)
693 for(
int i = 0; i < err_est_form->
ext.size(); i++)
694 fake_ext_fn[i]->free_fn();
695 delete [] fake_ext_fn;
702 return std::abs(0.5*res);
707 template<
typename Scalar>
708 double KellyTypeAdapt<Scalar>::eval_interface_estimator(
typename KellyTypeAdapt<Scalar>::ErrorEstimatorForm* err_est_form,
709 RefMap *rm, SurfPos* surf_pos,
710 LightArray<NeighborSearch<Scalar>*>& neighbor_searches,
713 NeighborSearch<Scalar>* nbs = neighbor_searches.get(neighbor_index);
714 Hermes::vector<MeshFunction<Scalar>*> slns;
715 for (
int i = 0; i < this->num; i++)
716 slns.push_back(this->sln[i]);
719 Func<Hermes::Ord>** fake_ext_fns =
new Func<Hermes::Ord>*[err_est_form->ext.size()];
720 for (
unsigned int j = 0; j < err_est_form->ext.size(); j++)
722 int inc = (err_est_form->ext[j]->get_num_components() == 2) ? 1 : 0;
723 int central_order = err_est_form->ext[j]->get_edge_fn_order(neighbor_searches.get(err_est_form->ext[j]->get_mesh()->get_seq())->active_edge) + inc;
724 int neighbor_order = err_est_form->ext[j]->get_edge_fn_order(neighbor_searches.get(err_est_form->ext[j]->get_mesh()->get_seq())->neighbor_edge.local_num_of_edge) + inc;
725 fake_ext_fns[j] =
new DiscontinuousFunc<Hermes::Ord>(
init_fn_ord(central_order),
init_fn_ord(neighbor_order));
729 Geom<Hermes::Ord>* fake_e =
new InterfaceGeom<Hermes::Ord>(
init_geom_ord(), nbs->neighb_el->marker, nbs->neighb_el->
id, Hermes::Ord(nbs->neighb_el->get_diameter()));
730 double fake_wt = 1.0;
731 Hermes::Ord o = err_est_form->ord(1, &fake_wt, fake_ext_fns, fake_ext_fns[err_est_form->i], fake_e, NULL);
733 int order = rm->get_inv_ref_order();
734 order += o.get_order();
736 limit_order(order, rm->get_active_element()->get_mode());
739 for (
int i = 0; i < this->num; i++)
741 fake_ext_fns[i]->free_ord();
742 delete fake_ext_fns[i];
744 delete [] fake_ext_fns;
751 Quad2D* quad = this->sln[err_est_form->i]->
get_quad_2d();
752 int eo = quad->get_edge_points(surf_pos->surf_num, order, rm->get_active_element()->get_mode());
753 int np = quad->get_num_points(eo, rm->get_active_element()->get_mode());
754 double3* pt = quad->get_points(eo, rm->get_active_element()->get_mode());
758 double* jwt =
new double[np];
759 for(
int i = 0; i < np; i++)
760 jwt[i] = pt[i][2] * tan[i][2];
762 Geom<double>* e =
new InterfaceGeom<double>(
init_geom_surf(rm, surf_pos->surf_num, surf_pos->marker, eo, tan),
763 nbs->neighb_el->marker,
765 nbs->neighb_el->get_diameter());
768 Func<Scalar>** ui = this->dp.init_ext_fns(slns, neighbor_searches, order, 0);
770 Scalar res = interface_scaling_const *
771 err_est_form->value(np, jwt, ui, ui[err_est_form->i], e, NULL);
775 for(
unsigned int i = 0; i < slns.size(); i++)
785 return std::abs(0.5*res);
791 template HERMES_API
class KellyTypeAdapt<double>;
792 template HERMES_API
class KellyTypeAdapt<std::complex<double> >;
793 template HERMES_API
class BasicKellyAdapt<double>;
794 template HERMES_API
class BasicKellyAdapt<std::complex<double> >;