1 #include "proj_based_selector.h"
5 #include "discrete_problem.h"
7 #include "element_to_refine.h"
8 #include "order_permutator.h"
14 namespace RefinementSelectors
16 template<
typename Scalar>
20 OptimumSelector<Scalar>(cand_list, conv_exp, max_order, shapeset, vertex_order, edge_bubble_order),
21 warn_uniform_orders(false),
36 for(
int k = 0; k < H2DRS_MAX_ORDER + 1; k++)
44 ortho_rhs_cache.resize(max_inx + 1);
47 template<
typename Scalar>
54 for(
int k = 0; k < H2DRS_MAX_ORDER + 1; k++)
56 if(proj_matrix_cache[m][i][k] != NULL)
57 delete [] proj_matrix_cache[m][i][k];
63 delete [] cached_shape_vals_valid;
64 delete [] cached_shape_ortho_vals;
65 delete [] cached_shape_vals;
69 template<
typename Scalar>
72 error_weight_h = weight_h;
73 error_weight_p = weight_p;
74 error_weight_aniso = weight_aniso;
77 template<
typename Scalar>
80 return error_weight_h;
83 template<
typename Scalar>
84 double ProjBasedSelector<Scalar>::get_error_weight_p()
const
86 return error_weight_p;
89 template<
typename Scalar>
90 double ProjBasedSelector<Scalar>::get_error_weight_aniso()
const
92 return error_weight_aniso;
95 template<
typename Scalar>
98 template<
typename Scalar>
104 template<
typename Scalar>
108 values = new_matrix<double>(num_expansion, num_gip);
109 this->num_expansion = num_expansion;
110 this->num_gip = num_gip;
113 template<
typename Scalar>
116 return values[inx_expansion];
119 template<
typename Scalar>
120 bool ProjBasedSelector<Scalar>::TrfShapeExp::empty()
const
122 return values == NULL;
125 template<
typename Scalar>
128 bool tri = e->is_triangle();
139 double sum_err = 0.0;
140 double sum_sqr_err = 0.0;
141 int num_processed = 0;
143 for (
unsigned i = 0; i < this->
candidates.size(); i++)
146 double error_squared = 0.0;
150 case H2D_REFINEMENT_H:
155 error_squared += herr[j][order][order];
157 error_squared *= 0.25;
160 case H2D_REFINEMENT_P:
163 error_squared = perr[order][order];
168 throw Hermes::Exceptions::Exception(
"Unknown split type \"%d\" at candidate %d", c.
split, i);
174 case H2D_REFINEMENT_H:
179 error_squared += herr[j][order_h][order_v];
181 error_squared *= 0.25;
184 case H2D_REFINEMENT_ANISO_H:
185 case H2D_REFINEMENT_ANISO_V:
188 for (
int j = 0; j < 2; j++)
189 error_squared += anisoerr[(c.
split == H2D_REFINEMENT_ANISO_H) ? j : j + 2][
H2D_GET_H_ORDER(c.
p[j])][H2D_GET_V_ORDER(c.
p[j])];
190 error_squared *= 0.5;
194 case H2D_REFINEMENT_P:
197 error_squared = perr[order_h][order_v];
202 throw Hermes::Exceptions::Exception(
"Unknown split type \"%d\" at candidate %d", c.
split, i);
207 c.
error = sqrt(error_squared);
213 case H2D_REFINEMENT_ANISO_H:
216 default:
throw Hermes::Exceptions::Exception(
"Unknown split type \"%d\" at candidate %d", c.
split, i);
222 sum_err += log10(c.
error);
223 sum_sqr_err += Hermes::sqr(log10(c.
error));
228 *avg_error = sum_err / num_processed;
229 *dev_error = sqrt(sum_sqr_err/num_processed - Hermes::sqr(*avg_error));
232 template<
typename Scalar>
235 ElementMode2D mode = e->get_mode();
238 Quad2D* quad = &g_quad_2d_std;
248 Element* base_element = rsln->get_mesh()->get_element(e->
id);
251 this->info(
"Have you calculated element errors twice with solutions_for_adaptivity == true?");
285 int num_noni_trfs = 0;
286 if(mode == HERMES_MODE_TRIANGLE)
289 num_noni_trfs = H2D_TRF_TRI_NUM;
294 num_noni_trfs = H2D_TRF_QUAD_NUM;
302 #pragma omp critical (cached_shape_vals_valid)
329 Trf* sub_trfs[4] = { &trfs[0], &trfs[1], &trfs[2], &trfs[3] };
330 Hermes::vector<TrfShapeExp>* p_trf_svals[4] = { &svals[0], &svals[1], &svals[2], &svals[3] };
331 Hermes::vector<TrfShapeExp>* p_trf_ortho_svals[4] = { &ortho_svals[0], &ortho_svals[1], &ortho_svals[2], &ortho_svals[3] };
332 Scalar **sub_rval[4] = { rval[0], rval[1], rval[2], rval[3] };;
335 Scalar **sub_rval[1] = { rval[son] };
337 , 1, &base_element, &sub_trfs[son], sub_rval
338 , &p_trf_svals[son], &p_trf_ortho_svals[son]
339 , info_h, herr[son]);
344 Trf* p_trf_identity[1] = { &trfs[H2D_TRF_IDENTITY] };
345 Hermes::vector<TrfShapeExp>* p_trf_svals[1] = { &svals[H2D_TRF_IDENTITY] };
346 Hermes::vector<TrfShapeExp>* p_trf_ortho_svals[1] = { &ortho_svals[H2D_TRF_IDENTITY] };
349 Scalar **sub_rval[1] = { rval[son] };
351 , 1, &base_element->
sons[son], p_trf_identity, sub_rval
352 , p_trf_svals, p_trf_ortho_svals
353 , info_h, herr[son]);
363 const int tr[4][2] = { {0, 1}, {3, 2}, {0, 3}, {1, 2} };
364 for(
int version = 0; version < 4; version++)
366 Trf* sub_trfs[2] = { &trfs[tr[version][0]], &trfs[tr[version][1]] };
367 Element* sub_domains[2] = { base_element, base_element };
368 Scalar **sub_rval[2] = { rval[tr[version][0]], rval[tr[version][1]] };
369 Hermes::vector<TrfShapeExp>* sub_svals[2] = { &svals[tr[version][0]], &svals[tr[version][1]] };
370 Hermes::vector<TrfShapeExp>* sub_ortho_svals[2] = { &ortho_svals[tr[version][0]], &ortho_svals[tr[version][1]] };
372 , 2, sub_domains, sub_trfs, sub_rval
373 , sub_svals, sub_ortho_svals
374 , info_aniso, anisoerr[version]);
379 const int sons[4][2] = { {0, 1}, {3, 2}, {0, 3}, {1, 2} };
380 const int tr[4][2] = { {6, 7}, {6, 7}, {4, 5}, {4, 5} };
381 for(
int version = 0; version < 4; version++)
383 Trf* sub_trfs[2] = { &trfs[tr[version][0]], &trfs[tr[version][1]] };
384 Element* sub_domains[2] = { base_element->
sons[sons[version][0]], base_element->
sons[sons[version][1]] };
385 Scalar **sub_rval[2] = { rval[sons[version][0]], rval[sons[version][1]] };
386 Hermes::vector<TrfShapeExp>* sub_svals[2] = { &svals[tr[version][0]], &svals[tr[version][1]] };
387 Hermes::vector<TrfShapeExp>* sub_ortho_svals[2] = { &ortho_svals[tr[version][0]], &ortho_svals[tr[version][1]] };
389 , 2, sub_domains, sub_trfs, sub_rval
390 , sub_svals, sub_ortho_svals
391 , info_aniso, anisoerr[version]);
401 Trf* sub_trfs[4] = { &trfs[0], &trfs[1], &trfs[2], &trfs[3] };
402 Scalar **sub_rval[4] = { rval[0], rval[1], rval[2], rval[3] };
403 Hermes::vector<TrfShapeExp>* sub_svals[4] = { &svals[0], &svals[1], &svals[2], &svals[3] };
404 Hermes::vector<TrfShapeExp>* sub_ortho_svals[4] = { &ortho_svals[0], &ortho_svals[1], &ortho_svals[2], &ortho_svals[3] };
405 Element* sub_domains[4] = { base_element, base_element, base_element, base_element };
408 , 4, sub_domains, sub_trfs, sub_rval
409 , sub_svals, sub_ortho_svals
414 Trf* sub_trfs[4] = { &trfs[0], &trfs[1], &trfs[2], &trfs[3] };
415 Scalar **sub_rval[4] = { rval[0], rval[1], rval[2], rval[3] };
416 Hermes::vector<TrfShapeExp>* sub_svals[4] = { &svals[0], &svals[1], &svals[2], &svals[3] };
417 Hermes::vector<TrfShapeExp>* sub_ortho_svals[4] = { &ortho_svals[0], &ortho_svals[1], &ortho_svals[2], &ortho_svals[3] };
420 , 4, base_element->
sons, sub_trfs, sub_rval
421 , sub_svals, sub_ortho_svals
427 template<
typename Scalar>
429 , double3* gip_points,
int num_gip_points
430 ,
const int num_sub,
Element** sub_domains,
Trf** sub_trfs, Scalar*** sub_rvals
431 , Hermes::vector<TrfShapeExp>** sub_nonortho_svals, Hermes::vector<TrfShapeExp>** sub_ortho_svals
438 Scalar* right_side =
new Scalar[max_num_shapes];
439 int* shape_inxs =
new int[max_num_shapes];
440 int* indx =
new int[max_num_shapes];
441 double* d =
new double[max_num_shapes];
442 double** proj_matrix = new_matrix<double>(max_num_shapes, max_num_shapes);
444 Hermes::vector<typename OptimumSelector<Scalar>::ShapeInx>& full_shape_indices = this->
shape_indices[mode];
447 bool ortho_svals_available =
true;
448 for(
int i = 0; i < num_sub && ortho_svals_available; i++)
449 ortho_svals_available &= !sub_ortho_svals[i]->empty();
459 double sub_area_corr_coef = 1.0 / num_sub;
464 int order_h =
H2D_GET_H_ORDER(quad_order), order_v = H2D_GET_V_ORDER(quad_order);
468 unsigned int inx_shape = 0;
469 while (inx_shape < full_shape_indices.size())
474 if(num_shapes >= max_num_shapes)
475 throw Exceptions::Exception(
"more shapes than predicted, possible incosistency");
489 Hermes::vector< ValueCacheItem<Scalar> >& rhs_cache = use_ortho ? ortho_rhs_cache :
nonortho_rhs_cache;
490 Hermes::vector<TrfShapeExp>** sub_svals = use_ortho ? sub_ortho_svals : sub_nonortho_svals;
495 if(proj_matrices[order_h][order_v] == NULL)
496 proj_matrices[order_h][order_v] =
build_projection_matrix(gip_points, num_gip_points, shape_inxs, num_shapes, mode);
497 copy_matrix(proj_matrix, proj_matrices[order_h][order_v], num_shapes, num_shapes);
501 for(
int inx_sub = 0; inx_sub < num_sub; inx_sub++)
503 Element* this_sub_domain = sub_domains[inx_sub];
504 ElemSubTrf this_sub_trf = { sub_trfs[inx_sub], 1 / sub_trfs[inx_sub]->m[0], 1 / sub_trfs[inx_sub]->m[1] };
505 ElemGIP this_sub_gip = { gip_points, num_gip_points, sub_rvals[inx_sub] };
506 Hermes::vector<TrfShapeExp>& this_sub_svals = *(sub_svals[inx_sub]);
510 int shape_inx = shape_inxs[k];
515 ElemSubShapeFunc this_sub_shape = { shape_inx, this_sub_svals.empty() ? empty_sub_vals : this_sub_svals[shape_inx] };
525 right_side[k] = sub_area_corr_coef * rhs_cache_value.
get();
526 rhs_cache_value.
mark();
532 ludcmp(proj_matrix, num_shapes, indx, d);
533 lubksb<Scalar>(proj_matrix,
num_shapes, indx, right_side);
537 double error_squared = 0;
538 for(
int inx_sub = 0; inx_sub < num_sub; inx_sub++)
540 Element* this_sub_domain = sub_domains[inx_sub];
541 ElemSubTrf this_sub_trf = { sub_trfs[inx_sub], 1 / sub_trfs[inx_sub]->m[0], 1 / sub_trfs[inx_sub]->m[1] };
542 ElemGIP this_sub_gip = { gip_points, num_gip_points, sub_rvals[inx_sub] };
543 ElemProj elem_proj = { shape_inxs,
num_shapes, *(sub_svals[inx_sub]), right_side, quad_order };
547 errors_squared[order_h][order_v] = error_squared * sub_area_corr_coef;
549 while (order_perm.
next());
551 delete [] proj_matrix;
552 delete [] right_side;
553 delete [] shape_inxs;