20 #include "limit_order.h"
22 #include "discrete_problem.h"
26 #include "refinement_selectors/optimum_selector.h"
33 template<
typename Scalar>
35 Hermes::vector<ProjNormType> proj_norms) :
39 have_coarse_solutions(false),
40 have_reference_solutions(false)
43 if(proj_norms.size() > 0 &&
spaces.size() != proj_norms.size())
44 throw Exceptions::LengthException(1, 2,
spaces.size(), proj_norms.size());
49 if((this->
num <= 0) || (this->
num > H2D_MAX_COMPONENTS))
throw Exceptions::ValueException(
"components", this->
num, 0, H2D_MAX_COMPONENTS);
53 memset(
sln, 0,
sizeof(
sln));
55 own_forms =
new bool*[H2D_MAX_COMPONENTS];
56 for(
int i = 0; i < H2D_MAX_COMPONENTS; i++)
58 own_forms[i] =
new bool[H2D_MAX_COMPONENTS];
59 memset(own_forms[i], 0, H2D_MAX_COMPONENTS *
sizeof(
bool));
64 if(proj_norms.size() == 0)
66 for (
int i = 0; i < this->
num; i++)
68 switch (
spaces[i]->get_type())
70 case HERMES_H1_SPACE: proj_norms.push_back(HERMES_H1_NORM);
break;
71 case HERMES_HCURL_SPACE: proj_norms.push_back(HERMES_HCURL_NORM);
break;
72 case HERMES_HDIV_SPACE: proj_norms.push_back(HERMES_HDIV_NORM);
break;
73 case HERMES_L2_SPACE: proj_norms.push_back(HERMES_L2_NORM);
break;
74 default:
throw Hermes::Exceptions::Exception(
"Unknown space type in Adapt<Scalar>::Adapt().");
80 for (
int i = 0; i < this->
num; i++)
81 for (
int j = 0; j < this->
num; j++)
87 for (
int i = 0; i < this->
num; i++)
91 own_forms[i][i] =
true;
95 template<
typename Scalar>
97 spaces(Hermes::vector<
Space<Scalar>*>()),
100 have_coarse_solutions(false),
101 have_reference_solutions(false)
103 if(space == NULL)
throw Exceptions::NullException(1);
110 memset(
sln, 0,
sizeof(
sln));
112 own_forms =
new bool*[H2D_MAX_COMPONENTS];
113 for(
int i = 0; i < H2D_MAX_COMPONENTS; i++)
115 own_forms[i] =
new bool[H2D_MAX_COMPONENTS];
116 memset(own_forms[i], 0, H2D_MAX_COMPONENTS *
sizeof(
bool));
121 if(proj_norm == HERMES_UNSET_NORM)
125 case HERMES_H1_SPACE: proj_norm = HERMES_H1_NORM;
break;
126 case HERMES_HCURL_SPACE: proj_norm = HERMES_HCURL_NORM;
break;
127 case HERMES_HDIV_SPACE: proj_norm = HERMES_HDIV_NORM;
break;
128 case HERMES_L2_SPACE: proj_norm = HERMES_L2_NORM;
break;
129 default:
throw Hermes::Exceptions::Exception(
"Unknown space type in Adapt<Scalar>::Adapt().");
134 error_form[0][0] =
new MatrixFormVolError(0, 0, proj_norm);
136 own_forms[0][0] =
true;
139 template<
typename Scalar>
142 for (
int i = 0; i < this->num; i++)
145 for (
int i = 0; i < this->num; i++)
146 for (
int j = 0; j < this->num; j++)
147 if(error_form[i][j] != NULL && own_forms[i][j])
149 delete error_form[i][j];
150 own_forms[i][j] =
false;
153 for(
int i = 0; i < H2D_MAX_COMPONENTS; i++)
154 delete [] own_forms[i];
157 template<
typename Scalar>
159 int regularize,
double to_be_processed)
163 this->caughtException = NULL;
166 throw Exceptions::Exception(
"element errors have to be calculated first, call Adapt<Scalar>::calc_err_est().");
168 if(refinement_selectors.empty())
169 throw Exceptions::NullException(1);
170 if(spaces.size() != refinement_selectors.size())
171 throw Exceptions::LengthException(1, refinement_selectors.size(), spaces.size());
175 Mesh* meshes[H2D_MAX_COMPONENTS];
176 for (
int j = 0; j < this->num; j++)
178 meshes[j] = this->spaces[j]->get_mesh();
181 rsln[j]->set_quad_2d(&g_quad_2d_std);
182 rsln[j]->enable_transform(
false);
184 if(meshes[j]->get_max_element_id() > max_id)
189 int** idx =
new int*[max_id];
190 for(
int i = 0; i < max_id; i++)
191 idx[i] =
new int[num];
194 for(
int j = 0; j < max_id; j++)
195 for(
int l = 0; l < this->num; l++)
198 double err0_squared = 1000.0;
199 double processed_error_squared = 0.0;
201 std::vector<ElementToRefine> elem_inx_to_proc;
202 elem_inx_to_proc.reserve(num_act_elems);
205 double error_squared_threshold = -1;
206 int num_ignored_elem = 0;
207 int num_not_changed = 0;
208 int num_priority_elem = 0;
211 Hermes::vector<int> ids;
212 Hermes::vector<int> components;
213 Hermes::vector<int> current_orders;
214 bool first_regular_element =
true;
215 bool error_level_reached =
false;
217 for(
int inx_regular_element = 0; inx_regular_element < num_act_elems || !priority_queue.empty();)
222 if(priority_queue.empty())
224 id = regular_queue[inx_regular_element].id;
225 comp = regular_queue[inx_regular_element].comp;
226 inx_regular_element++;
229 double err_squared = errors[comp][
id];
231 if(first_regular_element)
233 error_squared_threshold = thr * err_squared;
234 first_regular_element =
false;
240 if((strat == 0) && (processed_error_squared > sqrt(thr) * errors_squared_sum)
241 && fabs((err_squared - err0_squared)/err0_squared) > 1e-3)
242 error_level_reached =
true;
246 if((strat == 1) && (err_squared < error_squared_threshold))
247 error_level_reached =
true;
249 if((strat == 2) && (err_squared < thr))
250 error_level_reached =
true;
252 if((strat == 3) && ((err_squared < error_squared_threshold) || (processed_error_squared > 1.5 * to_be_processed)))
253 error_level_reached =
true;
256 if(!error_level_reached)
258 err0_squared = err_squared;
259 processed_error_squared += err_squared;
261 components.push_back(comp);
262 current_orders.push_back(this->spaces[comp]->get_element_order(
id));
263 spaces[comp]->edata[
id].changed_in_last_adaptation =
true;
266 if(priority_queue.empty())
272 id = priority_queue.front().id;
273 comp = priority_queue.front().comp;
274 priority_queue.pop();
278 components.push_back(comp);
279 current_orders.push_back(this->spaces[comp]->get_element_order(
id));
280 spaces[comp]->edata[
id].changed_in_last_adaptation =
true;
286 this->warn(
"None of the elements selected for refinement was refined. Adaptivity step successful, returning 'true'.");
293 for(
unsigned int i = 0; i <
Hermes2DApi.get_integral_param_value(Hermes::Hermes2D::numThreads); i++)
296 for (
unsigned int j = 0; j < refinement_selectors.size(); j++)
299 global_refinement_selectors[i][j] = refinement_selectors[j];
302 global_refinement_selectors[i][j] = refinement_selectors[j]->
clone();
318 for(
unsigned int i = 0; i <
Hermes2DApi.get_integral_param_value(Hermes::Hermes2D::numThreads); i++)
321 for (
int j = 0; j < this->num; j++)
329 this->info(
"Adaptivity: data preparation duration: %f s.", this->last());
332 Hermes::vector<int> numberOfCandidates;
340 int num_threads_used =
Hermes2DApi.get_integral_param_value(Hermes::Hermes2D::numThreads);
341 #pragma omp parallel shared(ids, components, elem_inx_to_proc, meshes, current_orders) private(current_refinement_selectors, current_rslns, id_to_refine) num_threads(num_threads_used)
343 #pragma omp for schedule(dynamic, CHUNKSIZE)
344 for(id_to_refine = 0; id_to_refine < ids.size(); id_to_refine++)
348 current_refinement_selectors = global_refinement_selectors[omp_get_thread_num()];
349 current_rslns = rslns[omp_get_thread_num()];
355 bool refined = current_refinement_selectors[components[id_to_refine]]->
select_refinement(meshes[components[id_to_refine]]->get_element(ids[id_to_refine]), current_orders[id_to_refine], current_rslns[components[id_to_refine]], elem_ref);
357 #pragma omp critical (number_of_candidates)
364 #pragma omp critical (elem_inx_to_proc)
366 idx[ids[id_to_refine]][components[id_to_refine]] = (int)elem_inx_to_proc.size();
367 elem_inx_to_proc.push_back(elem_ref);
370 catch(Hermes::Exceptions::Exception&
exception)
372 if(this->caughtException == NULL)
373 this->caughtException = exception.clone();
377 if(this->caughtException == NULL)
378 this->caughtException =
new Hermes::Exceptions::Exception(exception.what());
383 if(this->caughtException == NULL)
385 int averageNumberOfCandidates = 0;
386 for(
int i = 0; i < numberOfCandidates.size(); i++)
387 averageNumberOfCandidates += numberOfCandidates[i];
388 averageNumberOfCandidates = averageNumberOfCandidates / numberOfCandidates.size();
390 this->info(
"Adaptivity: total number of refined Elements: %i.", ids.size());
391 this->info(
"Adaptivity: average number of candidates per refined Element: %i.", averageNumberOfCandidates);
395 this->info(
"Adaptivity: refinement selection duration: %f s.", this->last());
397 if(this->caughtException == NULL)
398 fix_shared_mesh_refinements(meshes, elem_inx_to_proc, idx, global_refinement_selectors);
403 for (
unsigned int j = 0; j < refinement_selectors.size(); j++)
404 delete global_refinement_selectors[i][j];
405 delete [] global_refinement_selectors[i];
407 delete [] global_refinement_selectors;
409 for(
unsigned int i = 0; i <
Hermes2DApi.get_integral_param_value(Hermes::Hermes2D::numThreads); i++)
413 for (
unsigned int j = 0; j < this->num; j++)
421 for(
int i = 0; i < max_id; i++)
425 if(this->caughtException != NULL)
426 throw *(this->caughtException);
429 apply_refinements(elem_inx_to_proc);
432 homogenize_shared_mesh_orders(meshes);
440 this->warn(
"Total mesh regularization is not supported in adaptivity. 1-irregular mesh is used instead.");
442 for (
int i = 0; i < this->num; i++)
446 this->spaces[i]->distribute_orders(meshes[i], parents);
451 for (
int j = 0; j < this->num; j++)
453 rsln[j]->enable_transform(
true);
456 last_refinements.swap(elem_inx_to_proc);
463 for(
unsigned int i = 0; i < this->spaces.size(); i++)
464 this->spaces[i]->assign_dofs();
466 for (
int i = 0; i < this->num; i++)
468 for_all_active_elements(e, this->spaces[i]->get_mesh())
469 this->spaces[i]->edata[e->
id].changed_in_last_adaptation =
false;
470 for(id_to_refine = 0; id_to_refine < ids.size(); id_to_refine++)
471 this->spaces[i]->edata[ids[id_to_refine]].changed_in_last_adaptation =
false;
477 template<
typename Scalar>
482 template<
typename Scalar>
488 template<
typename Scalar>
493 template<
typename Scalar>
494 template<
typename TestFunctionDomain,
typename SolFunctionDomain>
498 SolFunctionDomain result = SolFunctionDomain(0);
499 for (
int i = 0; i < n; i++)
500 result += wt[i] * (u->
val[i] * conj(v->
val[i]));
504 template<
typename Scalar>
505 template<
typename TestFunctionDomain,
typename SolFunctionDomain>
509 SolFunctionDomain result = SolFunctionDomain(0);
510 for (
int i = 0; i < n; i++)
511 result += wt[i] * (u->
val[i] * conj(v->
val[i]) + u->dx[i] * conj(v->dx[i])
512 + u->
dy[i] * conj(v->
dy[i]));
516 template<
typename Scalar>
517 template<
typename TestFunctionDomain,
typename SolFunctionDomain>
519 Func<SolFunctionDomain> *v, Geom<TestFunctionDomain> *e, Func<SolFunctionDomain> **ext)
521 SolFunctionDomain result = SolFunctionDomain(0);
522 for (
int i = 0; i < n; i++)
523 result += wt[i] * (u->dx[i] * conj(v->dx[i]) + u->dy[i] * conj(v->dy[i]));
527 template<
typename Scalar>
528 template<
typename TestFunctionDomain,
typename SolFunctionDomain>
530 Func<SolFunctionDomain> *v, Geom<TestFunctionDomain> *e, Func<SolFunctionDomain> **ext)
532 throw Hermes::Exceptions::Exception(
"hdiv error form not implemented yet in hdiv.h.");
535 SolFunctionDomain result = SolFunctionDomain(0);
536 for (
int i = 0; i < n; i++)
537 result += wt[i] * (u->curl[i] * conj(v->curl[i]) +
538 u->val0[i] * conj(v->val0[i]) + u->val1[i] * conj(v->val1[i]));
542 template<
typename Scalar>
543 template<
typename TestFunctionDomain,
typename SolFunctionDomain>
545 Func<SolFunctionDomain> *v, Geom<TestFunctionDomain> *e, Func<SolFunctionDomain> **ext)
547 SolFunctionDomain result = SolFunctionDomain(0);
548 for (
int i = 0; i < n; i++)
549 result += wt[i] * (u->curl[i] * conj(v->curl[i]) +
550 u->val0[i] * conj(v->val0[i]) + u->val1[i] * conj(v->val1[i]));
554 template<
typename Scalar>
559 switch (projNormType)
562 return l2_error_form<double, Scalar>(n, wt, u_ext, u, v, e, ext);
564 return h1_error_form<double, Scalar>(n, wt, u_ext, u, v, e, ext);
565 case HERMES_H1_SEMINORM:
566 return h1_error_semi_form<double, Scalar>(n, wt, u_ext, u, v, e, ext);
567 case HERMES_HCURL_NORM:
568 return hcurl_error_form<double, Scalar>(n, wt, u_ext, u, v, e, ext);
569 case HERMES_HDIV_NORM:
570 return hdiv_error_form<double, Scalar>(n, wt, u_ext, u, v, e, ext);
572 throw Hermes::Exceptions::Exception(
"Unknown projection type");
577 template<
typename Scalar>
582 switch (projNormType)
585 return l2_error_form<Hermes::Ord, Hermes::Ord>(n, wt, u_ext, u, v, e, ext);
587 return h1_error_form<Hermes::Ord, Hermes::Ord>(n, wt, u_ext, u, v, e, ext);
588 case HERMES_H1_SEMINORM:
589 return h1_error_semi_form<Hermes::Ord, Hermes::Ord>(n, wt, u_ext, u, v, e, ext);
590 case HERMES_HCURL_NORM:
591 return hcurl_error_form<Hermes::Ord, Hermes::Ord>(n, wt, u_ext, u, v, e, ext);
592 case HERMES_HDIV_NORM:
593 return hdiv_error_form<Hermes::Ord, Hermes::Ord>(n, wt, u_ext, u, v, e, ext);
595 throw Hermes::Exceptions::Exception(
"Unknown projection type");
596 return Hermes::Ord();
600 template<
typename Scalar>
602 unsigned int error_flags)
606 throw Exceptions::LengthException(1, 1,
num);
607 double result =
calc_err_internal(sln, rsln, NULL, solutions_for_adapt, error_flags);
609 this->info(
"Adaptivity: error estimate calculation duration: %f s.", this->last());
613 template<
typename Scalar>
615 Hermes::vector<double>* component_errors,
bool solutions_for_adapt,
616 unsigned int error_flags)
619 if(slns.size() !=
num)
620 throw Exceptions::LengthException(1, slns.size(),
num);
621 if(rslns.size() !=
num)
622 throw Exceptions::LengthException(2, rslns.size(),
num);
623 double result =
calc_err_internal(slns, rslns, component_errors, solutions_for_adapt, error_flags);
625 this->info(
"Adaptivity: error estimate calculation duration: %f s.", this->last());
629 template<
typename Scalar>
631 unsigned int error_flags)
635 throw Exceptions::LengthException(1, 1,
num);
643 double result =
calc_err_internal(sln, &ref_sln_local, NULL, solutions_for_adapt, error_flags);
647 this->info(
"Adaptivity: exact error calculation duration: %f s.", this->last());
651 template<
typename Scalar>
653 Hermes::vector<double>* component_errors,
bool solutions_for_adapt,
654 unsigned int error_flags)
657 if(slns.size() !=
num)
658 throw Exceptions::LengthException(1, slns.size(),
num);
659 if(rslns.size() !=
num)
660 throw Exceptions::LengthException(2, rslns.size(),
num);
663 Hermes::vector<Solution<Scalar>*> ref_slns_local;
664 for(
unsigned int i = 0; i <
num; i++)
670 ref_spaces[i] = ref_space_creator.create_ref_space();
672 ogProjection.
project_global(ref_space_creator.create_ref_space(), rslns[i], ref_slns_local.back());
674 double result =
calc_err_internal(slns, ref_slns_local, component_errors, solutions_for_adapt, error_flags);
675 for(
unsigned int i = 0; i <
num; i++)
677 delete ref_spaces[i];
678 delete ref_meshes[i];
680 delete [] ref_meshes;
681 delete [] ref_spaces;
683 this->info(
"Adaptivity: exact error calculation duration: %f s.", this->last());
687 template<
typename Scalar>
689 int regularize,
double to_be_processed)
691 if(refinement_selector==NULL)
692 throw Exceptions::NullException(1);
693 Hermes::vector<RefinementSelectors::Selector<Scalar> *> refinement_selectors;
694 refinement_selectors.push_back(refinement_selector);
695 return adapt(refinement_selectors, thr, strat, regularize, to_be_processed);
698 template<
typename Scalar>
702 int num_elem_to_proc = elems_to_refine.size();
706 for(
int inx = 0; inx < num_elem_to_proc; inx++)
708 current_refinement_selectors = refinement_selectors[omp_get_thread_num()];
710 int current_quad_order = this->
spaces[elem_ref.comp]->get_element_order(elem_ref.id);
714 int selected_refinement = elem_ref.split;
715 for (
int j = 0; j < this->
num; j++)
717 if(selected_refinement == H2D_REFINEMENT_H)
break;
718 if(j != elem_ref.comp && meshes[j] == meshes[elem_ref.comp]) {
719 int ii = idx[elem_ref.id][j];
722 if(elem_ref_ii.split != selected_refinement && elem_ref_ii.split != H2D_REFINEMENT_P) {
723 if((elem_ref_ii.split == H2D_REFINEMENT_ANISO_H || elem_ref_ii.split == H2D_REFINEMENT_ANISO_V) && selected_refinement == H2D_REFINEMENT_P)
724 selected_refinement = elem_ref_ii.split;
726 selected_refinement = H2D_REFINEMENT_H;
733 if(selected_refinement != H2D_REFINEMENT_P)
736 const int* suggested_orders = NULL;
737 if(selected_refinement == H2D_REFINEMENT_H)
738 suggested_orders = elem_ref.q;
741 for (
int j = 0; j < this->
num; j++)
743 if(j != elem_ref.comp && meshes[j] == meshes[elem_ref.comp]) {
745 if(elem_ref.split != selected_refinement)
747 elem_ref.split = selected_refinement;
748 current_refinement_selectors[j]->
generate_shared_mesh_orders(current_elem, current_quad_order, elem_ref.split, elem_ref.p, suggested_orders);
752 int ii = idx[elem_ref.id][j];
756 if(elem_ref_ii.split != selected_refinement)
758 elem_ref_ii.split = selected_refinement;
759 current_refinement_selectors[j]->
generate_shared_mesh_orders(current_elem, current_quad_order, elem_ref_ii.split, elem_ref_ii.p, suggested_orders);
765 elem_ref_new.split = selected_refinement;
766 current_refinement_selectors[j]->
generate_shared_mesh_orders(current_elem, current_quad_order, elem_ref_new.split, elem_ref_new.p, suggested_orders);
767 elems_to_refine.push_back(elem_ref_new);
775 template<
typename Scalar>
779 throw Exceptions::Exception(
"element errors have to be calculated first, call Adapt<Scalar>::calc_err_est().");
783 template<
typename Scalar>
789 template<
typename Scalar>
793 for (
int i = 0; i < this->
num; i++)
795 for_all_active_elements(e, meshes[i])
797 int current_quad_order = this->
spaces[i]->get_element_order(e->
id);
798 int current_order_h =
H2D_GET_H_ORDER(current_quad_order), current_order_v = H2D_GET_V_ORDER(current_quad_order);
800 for (
int j = 0; j < this->
num; j++)
801 if((j != i) && (meshes[j] == meshes[i]))
803 int quad_order = this->
spaces[j]->get_element_order(e->
id);
804 current_order_h = std::max(current_order_h,
H2D_GET_H_ORDER(quad_order));
805 current_order_v = std::max(current_order_v, H2D_GET_V_ORDER(quad_order));
808 this->
spaces[i]->set_element_order_internal(e->
id, H2D_MAKE_QUAD_ORDER(current_order_h, current_order_v));
813 template<
typename Scalar>
819 template<
typename Scalar>
822 for (std::vector<ElementToRefine>::const_iterator elem_ref = elems_to_refine.begin();
823 elem_ref != elems_to_refine.end(); elem_ref++)
827 template<
typename Scalar>
831 Mesh* mesh = space->get_mesh();
836 if(elem_ref.split == H2D_REFINEMENT_P)
839 space->
edata[elem_ref.id].changed_in_last_adaptation =
true;
841 else if(elem_ref.split == H2D_REFINEMENT_H)
845 for (
int j = 0; j < 4; j++)
848 space->
edata[e->
sons[j]->
id].changed_in_last_adaptation =
true;
855 for (
int j = 0; j < 2; j++)
858 space->
edata[e->
sons[ (elem_ref.split == 1) ? j : j + 2 ]->
id].changed_in_last_adaptation =
true;
863 template<
typename Scalar>
866 if(form->i < 0 || form->i >= this->num)
867 throw Exceptions::ValueException(
"component number", form->i, 0, this->num);
868 if(form->j < 0 || form->j >= this->num)
869 throw Exceptions::ValueException(
"component number", form->j, 0, this->num);
873 if(own_forms[i][j] &&
error_form[i][j] != NULL)
877 own_forms[i][j] =
false;
880 template<
typename Scalar>
886 template<
typename Scalar>
887 void Adapt<Scalar>::set_norm_form(
int i,
int j,
typename Adapt<Scalar>::MatrixFormVolError* form)
889 if(form->i < 0 || form->i >= this->num)
890 throw Exceptions::ValueException(
"component number", form->i, 0, this->num);
891 if(form->j < 0 || form->j >= this->num)
892 throw Exceptions::ValueException(
"component number", form->j, 0, this->num);
897 template<
typename Scalar>
898 void Adapt<Scalar>::set_norm_form(
typename Adapt<Scalar>::MatrixFormVolError* form)
900 set_norm_form(0, 0, form);
903 template<
typename Scalar>
908 RefMap *rv1 = sln1->get_refmap();
909 RefMap *rv2 = sln2->get_refmap();
910 RefMap *rrv1 = rsln1->get_refmap();
911 RefMap *rrv2 = rsln2->get_refmap();
918 double fake_wt = 1.0;
920 Hermes::Ord o = form->
ord(1, &fake_wt, NULL, ou, ov, fake_e, NULL);
922 order += o.get_order();
945 double* jwt =
new double[np];
946 for(
int i = 0; i < np; i++)
947 jwt[i] = pt[i][2] * jac[i];
958 Scalar res = form->
value(np, jwt, NULL, err1, err2, e, NULL);
967 return std::abs(res);
970 template<
typename Scalar>
974 RefMap *rrv1 = rsln1->get_refmap();
975 RefMap *rrv2 = rsln2->get_refmap();
982 double fake_wt = 1.0;
984 Hermes::Ord o = form->
ord(1, &fake_wt, NULL, ou, ov, fake_e, NULL);
986 order += o.get_order();
1009 double* jwt =
new double[np];
1010 for(
int i = 0; i < np; i++)
1011 jwt[i] = pt[i][2] * jac[i];
1017 Scalar res = form->
value(np, jwt, NULL, v1, v2, e, NULL);
1019 e->
free();
delete e;
1024 return std::abs(res);
1027 template<
typename Scalar>
1029 Hermes::vector<double>* component_errors,
bool solutions_for_adapt,
unsigned int error_flags)
1033 bool compatible_meshes =
true;
1034 for (
int space_i = 0; space_i < this->
num; space_i++)
1037 for_all_active_elements(e, slns[space_i]->get_mesh())
1039 Element* e_ref = rslns[space_i]->get_mesh()->get_element(e->
id);
1042 compatible_meshes =
false;
1047 if(e_ref->
sons[0] == NULL || e_ref->
sons[2] == NULL)
1049 compatible_meshes =
false;
1054 compatible_meshes =
false;
1061 if(!compatible_meshes)
1062 throw Exceptions::Exception(
"Reference space not created by an isotropic (p-, h-, or hp-) refinement from the coarse space.");
1064 if(slns.size() != this->
num)
1065 throw Exceptions::LengthException(0, slns.size(), this->
num);
1070 for (i = 0; i < this->
num; i++)
1072 slns_original[i] = this->
sln[i];
1073 this->
sln[i] = slns[i];
1074 sln[i]->set_quad_2d(&g_quad_2d_std);
1076 for (i = 0; i < this->
num; i++)
1078 rslns_original[i] = this->
rsln[i];
1079 this->
rsln[i] = rslns[i];
1080 rsln[i]->set_quad_2d(&g_quad_2d_std);
1091 for (i = 0; i <
num; i++)
1093 meshes[i] =
sln[i]->get_mesh();
1094 meshes[i +
num] =
rsln[i]->get_mesh();
1101 if(solutions_for_adapt)
1104 errors[i] =
new double[max];
1105 memset(
errors[i], 0,
sizeof(
double) * max);
1109 double total_norm = 0.0;
1110 double *norms =
new double[
num];
1111 memset(norms, 0, num *
sizeof(
double));
1112 double *errors_components =
new double[
num];
1113 memset(errors_components, 0, num *
sizeof(
double));
1115 double total_error = 0.0;
1118 Traverse::State * ee;
1119 trav.begin(2 * num, meshes, tr);
1120 while ((ee = trav.get_next_state()) != NULL)
1122 for (i = 0; i <
num; i++)
1124 for (j = 0; j <
num; j++)
1135 errors_components[i] += err;
1136 if(solutions_for_adapt)
1137 this->
errors[i][ee->e[i]->id] += err;
1145 if(component_errors != NULL)
1147 component_errors->clear();
1148 for (
int i = 0; i <
num; i++)
1151 component_errors->push_back(sqrt(errors_components[i]));
1153 component_errors->push_back(sqrt(errors_components[i]/norms[i]));
1156 throw Hermes::Exceptions::Exception(
"Unknown total error type (0x%x).", error_flags & HERMES_TOTAL_ERROR_MASK);
1163 if(solutions_for_adapt)
1167 for (
int i = 0; i < this->
num; i++)
1170 for_all_active_elements(e, meshes[i])
1187 if(solutions_for_adapt)
1194 for (i = 0; i < this->
num; i++)
1196 this->
sln[i] = slns_original[i];
1197 this->
rsln[i] = rslns_original[i];
1204 delete [] errors_components;
1208 return sqrt(total_error);
1210 return sqrt(total_error / total_norm);
1213 throw Hermes::Exceptions::Exception(
"Unknown total error type (0x%x).", error_flags & HERMES_TOTAL_ERROR_MASK);
1218 template<
typename Scalar>
1220 Hermes::vector<double>* component_errors,
bool solutions_for_adapt,
1221 unsigned int error_flags)
1223 Hermes::vector<Solution<Scalar>*> slns;
1224 slns.push_back(sln);
1225 Hermes::vector<Solution<Scalar>*> rslns;
1226 rslns.push_back(rsln);
1227 return calc_err_internal(slns, rslns, component_errors, solutions_for_adapt, error_flags);
1230 template<
typename Scalar>
1235 template<
typename Scalar>
1236 bool Adapt<Scalar>::CompareElements::operator()(
const ElementReference& e1,
const ElementReference& e2)
const
1238 return errors[e1.comp][e1.id] > errors[e2.comp][e2.id];
1241 template<
typename Scalar>
1245 regular_queue.clear();
1246 if(num_act_elems < (
int)regular_queue.capacity())
1248 Hermes::vector<ElementReference> empty_refs;
1249 regular_queue.swap(empty_refs);
1250 regular_queue.reserve(num_act_elems);
1255 typename Hermes::vector<ElementReference>::iterator elem_info = regular_queue.begin();
1256 for (
int i = 0; i < this->num; i++)
1258 for_all_active_elements(e, meshes[i])
1264 std::sort(regular_queue.begin(), regular_queue.end(), CompareElements(errors));