4 #include "shapeset/shapeset_l2_all.h"
5 #include "element_to_refine.h"
6 #include "l2_proj_based_selector.h"
11 namespace RefinementSelectors
13 template<
typename Scalar>
14 const int L2ProjBasedSelector<Scalar>::H2DRS_MAX_L2_ORDER =
H2DRS_MAX_ORDER;
16 template<
typename Scalar>
20 if(user_shapeset != NULL)
22 this->warn(
"Warning: The user shapeset provided for the selector has to have a correct copy constructor implemented.");
23 this->warn(
"Warning: The functionality for cloning user shapeset is to be implemented yet.");
27 template<
typename Scalar>
30 if(!this->user_shapeset)
31 delete this->shapeset;
34 template<
typename Scalar>
38 newSelector->
set_error_weights(this->error_weight_h, this->error_weight_p, this->error_weight_aniso);
43 template<
typename Scalar>
46 this->current_max_order = this->max_order;
48 this->current_max_order = (20 - element->
iro_cache)/2 - 2;
50 this->current_max_order = std::min(this->current_max_order, (20 - element->
iro_cache)/2 - 2);
51 this->current_min_order = 0;
54 template<
typename Scalar>
60 while (!done && inx_trf < H2D_TRF_NUM)
63 const Trf& trf = trfs[inx_trf];
64 Hermes::vector<typename ProjBasedSelector<Scalar>::TrfShapeExp>& trf_svals = svals[inx_trf];
67 trf_svals.resize(max_shape_inx + 1);
70 const int num_shapes = (int)shapes.size();
71 for(
int i = 0; i < num_shapes; i++)
73 int inx_shape = shapes[i].inx;
77 shape_exp.allocate(H2D_L2FE_NUM, num_gip_points);
80 for(
int k = 0; k < num_gip_points; k++)
83 double ref_x = gip_points[k][
H2D_GIP2D_X] * trf.m[0] + trf.
t[0];
84 double ref_y = gip_points[k][
H2D_GIP2D_Y] * trf.m[1] + trf.
t[1];
87 shape_exp[H2D_L2FE_VALUE][k] = this->shapeset->get_fn_value(inx_shape, ref_x, ref_y, 0, mode);
92 if(inx_trf == H2D_TRF_IDENTITY)
97 if(inx_trf >= num_noni_trfs)
98 inx_trf = H2D_TRF_IDENTITY;
102 throw Exceptions::Exception(
"All transformation processed but identity transformation not found.");
105 template<
typename Scalar>
108 int order_h =
H2D_GET_H_ORDER(quad_order), order_v = H2D_GET_V_ORDER(quad_order);
109 int max_p_order_h =
H2D_GET_H_ORDER(max_p_quad_order), max_p_order_v = H2D_GET_V_ORDER(max_p_quad_order);
110 int max_ha_order_h =
H2D_GET_H_ORDER(max_ha_quad_order), max_ha_order_v = H2D_GET_V_ORDER(max_ha_quad_order);
111 bool tri = e->is_triangle();
114 this->candidates.clear();
121 int start_quad_order = quad_order;
123 switch(this->cand_list)
126 case H2D_H_ANISO: last_quad_order = start_quad_order;
break;
131 this->append_candidates_split(quad_order, last_quad_order, H2D_REFINEMENT_P, tri || iso_p);
135 int start_order_h = std::max(this->current_min_order, (order_h + 1) / 2), start_order_v = std::max(this->current_min_order, (order_v + 1) / 2);
136 start_quad_order = H2D_MAKE_QUAD_ORDER(start_order_h, start_order_v);
138 switch(this->cand_list)
142 last_quad_order = start_quad_order = quad_order;
break;
148 this->append_candidates_split(start_quad_order, last_quad_order, H2D_REFINEMENT_H, tri || iso_p);
155 int start_quad_order_hz = H2D_MAKE_QUAD_ORDER(order_h, std::max(this->current_min_order, (order_v + 1) / 2));
157 int start_quad_order_vt = H2D_MAKE_QUAD_ORDER(std::max(this->current_min_order, (order_h + 1) / 2), order_v);
159 switch(this->cand_list)
162 last_quad_order_hz = start_quad_order_hz = quad_order;
163 last_quad_order_vt = start_quad_order_vt = quad_order;
168 int order = std::min(
H2D_GET_H_ORDER(start_quad_order_hz), H2D_GET_V_ORDER(start_quad_order_hz));
169 start_quad_order_hz = H2D_MAKE_QUAD_ORDER(order, order);
170 order = std::min(
H2D_GET_H_ORDER(start_quad_order_vt), H2D_GET_V_ORDER(start_quad_order_vt));
171 start_quad_order_vt = H2D_MAKE_QUAD_ORDER(order, order);
173 order = std::min(
H2D_GET_H_ORDER(last_quad_order_hz), H2D_GET_V_ORDER(last_quad_order_hz));
174 last_quad_order_hz = H2D_MAKE_QUAD_ORDER(order, order);
175 order = std::min(
H2D_GET_H_ORDER(last_quad_order_vt), H2D_GET_V_ORDER(last_quad_order_vt));
176 last_quad_order_vt = H2D_MAKE_QUAD_ORDER(order, order);
178 this->append_candidates_split(start_quad_order_hz, last_quad_order_hz, H2D_REFINEMENT_ANISO_H, iso_p);
179 this->append_candidates_split(start_quad_order_vt, last_quad_order_vt, H2D_REFINEMENT_ANISO_V, iso_p);
183 template<
typename Scalar>
187 precalc_shapes(gip_points, num_gip_points, trfs, num_noni_trfs, shapes, max_shape_inx, svals, mode);
190 const int num_shapes = (int)shapes.size();
191 for(
int i = 0; i < num_shapes; i++)
193 const int inx_shape_i = shapes[i].inx;
196 for(
int j = 0; j < i; j++)
198 const int inx_shape_j = shapes[j].inx;
201 double product = 0.0;
202 for(
int k = 0; k < num_gip_points; k++)
205 sum += svals[H2D_TRF_IDENTITY][inx_shape_i][H2D_L2FE_VALUE][k] * svals[H2D_TRF_IDENTITY][inx_shape_j][H2D_L2FE_VALUE][k];
212 while (!done && inx_trf < H2D_TRF_NUM)
215 for(
int k = 0; k < num_gip_points; k++)
217 svals[inx_trf][inx_shape_i][H2D_L2FE_VALUE][k] -= product * svals[inx_trf][inx_shape_j][H2D_L2FE_VALUE][k];
221 if(inx_trf == H2D_TRF_IDENTITY)
226 if(inx_trf >= num_noni_trfs)
227 inx_trf = H2D_TRF_IDENTITY;
232 throw Exceptions::Exception(
"All transformation processed but identity transformation not found.");
237 double norm_squared = 0.0;
238 for(
int k = 0; k < num_gip_points; k++)
241 sum += sqr(svals[H2D_TRF_IDENTITY][inx_shape_i][H2D_L2FE_VALUE][k]);
244 double norm = sqrt(norm_squared);
246 throw Exceptions::Exception(
"Norm (%g) is almost zero.", norm);
251 while (!done && inx_trf < H2D_TRF_NUM)
254 for(
int k = 0; k < num_gip_points; k++)
256 svals[inx_trf][inx_shape_i][H2D_L2FE_VALUE][k] /= norm;
260 if(inx_trf == H2D_TRF_IDENTITY)
265 if(inx_trf >= num_noni_trfs)
266 inx_trf = H2D_TRF_IDENTITY;
271 throw Exceptions::Exception(
"All transformation processed but identity transformation not found.");
275 template<
typename Scalar>
279 Scalar** rvals_son = precalc_rvals[inx_son];
285 template<
typename Scalar>
287 const int* shape_inx,
const int num_shapes, ElementMode2D mode)
290 double** matrix = new_matrix<double>(num_shapes, num_shapes);
294 for(
int i = 0; i < num_shapes; i++, inx_row += num_shapes)
296 double* matrix_row = matrix[i];
297 int shape0_inx = shape_inx[i];
298 for(
int k = 0; k < num_shapes; k++)
300 int shape1_inx = shape_inx[k];
303 for(
int j = 0; j < num_gip_points; j++)
306 double value0 = this->shapeset->get_value(
H2D_FEI_VALUE, shape0_inx, gip_x, gip_y, 0, mode);
307 double value1 = this->shapeset->get_value(
H2D_FEI_VALUE, shape1_inx, gip_x, gip_y, 0, mode);
309 value += gip_points[j][
H2D_GIP2D_W] * (value0*value1);
312 matrix_row[k] = value;
319 template<
typename Scalar>
322 Scalar total_value = 0;
326 double3 &gip_pt = sub_gip.
gip_points[gip_inx];
329 double shape_value = sub_shape.
svals[H2D_L2FE_VALUE][gip_inx];
340 ref_value = sub_gip.
rvals[H2D_L2FE_VALUE][gip_inx];
343 Scalar value = (shape_value * ref_value);
350 template<
typename Scalar>
353 double total_error_squared = 0;
357 double3 &gip_pt = sub_gip.
gip_points[gip_inx];
360 Scalar proj_value = 0;
364 proj_value += elem_proj.
shape_coeffs[i] * elem_proj.
svals[shape_inx][H2D_L2FE_VALUE][gip_inx];
368 Scalar ref_value = sub_gip.
rvals[H2D_L2FE_VALUE][gip_inx];
371 double error_squared = sqr(proj_value - ref_value);
373 total_error_squared += gip_pt[
H2D_GIP2D_W] * error_squared;
375 return total_error_squared;