4 #include "shapeset/shapeset_hc_all.h"
5 #include "element_to_refine.h"
6 #include "hcurl_proj_based_selector.h"
11 namespace RefinementSelectors
13 template<
typename Scalar>
14 const int HcurlProjBasedSelector<Scalar>::H2DRS_MAX_HCURL_ORDER = 6;
16 template<
typename Scalar>
19 , precalc_rvals_curl(NULL)
21 if(user_shapeset != NULL)
23 this->warn(
"Warning: The user shapeset provided for the selector has to have a correct copy constructor implemented.");
24 this->warn(
"Warning: The functionality for cloning user shapeset is to be implemented yet.");
28 template<
typename Scalar>
32 newSelector->
set_error_weights(this->error_weight_h, this->error_weight_p, this->error_weight_aniso);
37 template<
typename Scalar>
40 delete [] precalc_rvals_curl;
43 template<
typename Scalar>
46 this->current_max_order = this->max_order;
48 this->current_max_order = std::min(H2DRS_MAX_HCURL_ORDER, (20 - element->
iro_cache)/2 - 1);
50 this->current_max_order = std::min(this->max_order, (20 - element->
iro_cache)/2 - 1);
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_HCFE_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_HCFE_VALUE0][k] = this->shapeset->get_fn_value(inx_shape, ref_x, ref_y, 0, mode);
88 shape_exp[H2D_HCFE_VALUE1][k] = this->shapeset->get_fn_value(inx_shape, ref_x, ref_y, 1, mode);
89 shape_exp[H2D_HCFE_CURL][k] = this->shapeset->get_dx_value(inx_shape, ref_x, ref_y, 1, mode) - this->shapeset->get_dy_value(inx_shape, ref_x, ref_y, 0, mode);
94 if(inx_trf == H2D_TRF_IDENTITY)
99 if(inx_trf >= num_noni_trfs)
100 inx_trf = H2D_TRF_IDENTITY;
104 throw Exceptions::Exception(
"All transformation processed but identity transformation not found.");
107 template<
typename Scalar>
111 precalc_shapes(gip_points, num_gip_points, trfs, num_noni_trfs, shapes, max_shape_inx, svals, mode);
114 const int num_shapes = (int)shapes.size();
115 for(
int i = 0; i < num_shapes; i++)
117 const int inx_shape_i = shapes[i].inx;
120 for(
int j = 0; j < i; j++)
122 const int inx_shape_j = shapes[j].inx;
125 double product = 0.0;
126 for(
int k = 0; k < num_gip_points; k++)
129 sum += svals[H2D_TRF_IDENTITY][inx_shape_i][H2D_HCFE_VALUE0][k] * svals[H2D_TRF_IDENTITY][inx_shape_j][H2D_HCFE_VALUE0][k];
130 sum += svals[H2D_TRF_IDENTITY][inx_shape_i][H2D_HCFE_VALUE1][k] * svals[H2D_TRF_IDENTITY][inx_shape_j][H2D_HCFE_VALUE1][k];
131 sum += svals[H2D_TRF_IDENTITY][inx_shape_i][H2D_HCFE_CURL][k] * svals[H2D_TRF_IDENTITY][inx_shape_j][H2D_HCFE_CURL][k];
138 while (!done && inx_trf < H2D_TRF_NUM)
141 for(
int k = 0; k < num_gip_points; k++)
143 svals[inx_trf][inx_shape_i][H2D_HCFE_VALUE0][k] -= product * svals[inx_trf][inx_shape_j][H2D_HCFE_VALUE0][k];
144 svals[inx_trf][inx_shape_i][H2D_HCFE_VALUE1][k] -= product * svals[inx_trf][inx_shape_j][H2D_HCFE_VALUE1][k];
145 svals[inx_trf][inx_shape_i][H2D_HCFE_CURL][k] -= product * svals[inx_trf][inx_shape_j][H2D_HCFE_CURL][k];
149 if(inx_trf == H2D_TRF_IDENTITY)
154 if(inx_trf >= num_noni_trfs)
155 inx_trf = H2D_TRF_IDENTITY;
159 throw Exceptions::Exception(
"All transformation processed but identity transformation not found.");
164 double norm_squared = 0.0;
165 for(
int k = 0; k < num_gip_points; k++)
168 sum += sqr(svals[H2D_TRF_IDENTITY][inx_shape_i][H2D_HCFE_VALUE0][k]);
169 sum += sqr(svals[H2D_TRF_IDENTITY][inx_shape_i][H2D_HCFE_VALUE1][k]);
170 sum += sqr(svals[H2D_TRF_IDENTITY][inx_shape_i][H2D_HCFE_CURL][k]);
173 double norm = sqrt(norm_squared);
175 throw Exceptions::Exception(
"Norm (%g) is almost zero.", norm);
180 while (!done && inx_trf < H2D_TRF_NUM)
183 for(
int k = 0; k < num_gip_points; k++)
185 svals[inx_trf][inx_shape_i][H2D_HCFE_VALUE0][k] /= norm;
186 svals[inx_trf][inx_shape_i][H2D_HCFE_VALUE1][k] /= norm;
187 svals[inx_trf][inx_shape_i][H2D_HCFE_CURL][k] /= norm;
191 if(inx_trf == H2D_TRF_IDENTITY)
196 if(inx_trf >= num_noni_trfs)
197 inx_trf = H2D_TRF_IDENTITY;
201 throw Exceptions::Exception(
"All transformation processed but identity transformation not found.");
205 template<
typename Scalar>
211 if(precalc_rvals_curl == NULL)
215 Scalar* curl = precalc_rvals_curl[inx_son];
218 for(
int i = 0; i < num_gip; i++)
219 curl[i] = d1dx[i] - d0dy[i];
222 Scalar** rvals_son = precalc_rvals[inx_son];
225 rvals_son[H2D_HCFE_CURL] = curl;
230 template<
typename Scalar>
232 const int* shape_inx,
const int num_shapes, ElementMode2D mode)
235 double** matrix = new_matrix<double>(num_shapes, num_shapes);
239 for(
int i = 0; i < num_shapes; i++, inx_row += num_shapes)
241 double* matrix_row = matrix[i];
242 int shape0_inx = shape_inx[i];
243 for(
int k = 0; k < num_shapes; k++)
245 int shape1_inx = shape_inx[k];
248 for(
int j = 0; j < num_gip_points; j++)
251 double value0[2] = { this->shapeset->get_value(
H2D_FEI_VALUE, shape0_inx, gip_x, gip_y, 0, mode), this->shapeset->get_value(
H2D_FEI_VALUE, shape0_inx, gip_x, gip_y, 1, mode) };
252 double value1[2] = { this->shapeset->get_value(
H2D_FEI_VALUE, shape1_inx, gip_x, gip_y, 0, mode), this->shapeset->get_value(
H2D_FEI_VALUE, shape1_inx, gip_x, gip_y, 1, mode) };
253 double d1dx0 = this->shapeset->get_value(
H2D_FEI_DX, shape0_inx, gip_x, gip_y, 1, mode);
254 double d1dx1 = this->shapeset->get_value(
H2D_FEI_DX, shape1_inx, gip_x, gip_y, 1, mode);
255 double d0dy0 = this->shapeset->get_value(
H2D_FEI_DY, shape0_inx, gip_x, gip_y, 0, mode);
256 double d0dy1 = this->shapeset->get_value(
H2D_FEI_DY, shape1_inx, gip_x, gip_y, 0, mode);
257 double curl0 = d1dx0 - d0dy0;
258 double curl1 = d1dx1 - d0dy1;
260 value += gip_points[j][
H2D_GIP2D_W] * (value0[0]*value1[0] + value0[1]*value1[1] + curl0*curl1);
263 matrix_row[k] = value;
270 template<
typename Scalar>
274 Scalar total_value = 0;
278 double3 &gip_pt = sub_gip.
gip_points[gip_inx];
281 Scalar shape_value0 = sub_shape.
svals[H2D_HCFE_VALUE0][gip_inx];
282 Scalar shape_value1 = sub_shape.
svals[H2D_HCFE_VALUE1][gip_inx];
283 Scalar shape_curl = sub_shape.
svals[H2D_HCFE_CURL][gip_inx];
297 Scalar ref_value0 = sub_trf.
coef_mx * sub_gip.
rvals[H2D_HCFE_VALUE0][gip_inx];
298 Scalar ref_value1 = sub_trf.
coef_my * sub_gip.
rvals[H2D_HCFE_VALUE1][gip_inx];
299 Scalar ref_curl = coef_curl * sub_gip.
rvals[H2D_HCFE_CURL][gip_inx];
302 Scalar value = (shape_value0 * ref_value0)
303 + (shape_value1 * ref_value1)
304 + (shape_curl * ref_curl);
311 template<
typename Scalar>
314 double total_error_squared = 0;
319 double3 &gip_pt = sub_gip.
gip_points[gip_inx];
322 Scalar proj_value0 = 0, proj_value1 = 0, proj_curl = 0;
326 proj_value0 += elem_proj.
shape_coeffs[i] * elem_proj.
svals[shape_inx][H2D_HCFE_VALUE0][gip_inx];
327 proj_value1 += elem_proj.
shape_coeffs[i] * elem_proj.
svals[shape_inx][H2D_HCFE_VALUE1][gip_inx];
328 proj_curl += elem_proj.
shape_coeffs[i] * elem_proj.
svals[shape_inx][H2D_HCFE_CURL][gip_inx];
348 Scalar ref_value0 = sub_trf.
coef_mx * sub_gip.
rvals[H2D_HCFE_VALUE0][gip_inx];
349 Scalar ref_value1 = sub_trf.
coef_my * sub_gip.
rvals[H2D_HCFE_VALUE1][gip_inx];
350 Scalar ref_curl = coef_curl * sub_gip.
rvals[H2D_HCFE_CURL][gip_inx];
353 double error_squared = sqr(proj_value0 - ref_value0)
354 + sqr(proj_value1 - ref_value1)
355 + sqr(proj_curl - ref_curl);
357 total_error_squared += gip_pt[
H2D_GIP2D_W] * error_squared;
360 return total_error_squared;