2 #include "hcurl_proj_based_selector.h"
8 namespace RefinementSelectors
10 template<
typename Scalar>
11 const int HcurlProjBasedSelector<Scalar>::H2DRS_MAX_HCURL_ORDER = 6;
13 template<
typename Scalar>
15 :
ProjBasedSelector<Scalar>(cand_list, max_order, user_shapeset == nullptr ? new
HcurlShapeset() : user_shapeset, Range(), Range(0, H2DRS_MAX_HCURL_ORDER))
17 if (user_shapeset !=
nullptr)
19 this->warn(
"Warning: The user shapeset provided for the selector has to have a correct copy constructor implemented.");
20 this->warn(
"Warning: The functionality for cloning user shapeset is to be implemented yet.");
24 template<
typename Scalar>
29 template<
typename Scalar>
32 int max_element_order = (20 - element->
iro_cache) / 2 - 1;
34 max_order_ = max_element_order;
36 max_order_ = std::min(this->max_order, max_element_order);
40 template<
typename Scalar>
46 while (!done && inx_trf < H2D_TRF_NUM)
49 const Trf& trf = trfs[inx_trf];
50 std::vector<typename ProjBasedSelector<Scalar>::TrfShapeExp>& trf_svals = svals[inx_trf];
53 trf_svals.resize(max_shape_inx + 1);
56 const int num_shapes = (int)shapes.size();
57 for (
int i = 0; i < num_shapes; i++)
59 int inx_shape = shapes[i].inx;
63 shape_exp.allocate(H2D_HCFE_NUM, num_gip_points);
66 for (
int k = 0; k < num_gip_points; k++)
69 double ref_x = gip_points[k][
H2D_GIP2D_X] * trf.m[0] + trf.
t[0];
70 double ref_y = gip_points[k][
H2D_GIP2D_Y] * trf.m[1] + trf.
t[1];
73 shape_exp[H2D_HCFE_VALUE0][k] = this->shapeset->get_fn_value(inx_shape, ref_x, ref_y, 0, mode);
74 shape_exp[H2D_HCFE_VALUE1][k] = this->shapeset->get_fn_value(inx_shape, ref_x, ref_y, 1, mode);
75 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);
80 if (inx_trf == H2D_TRF_IDENTITY)
85 if (inx_trf >= num_noni_trfs)
86 inx_trf = H2D_TRF_IDENTITY;
91 throw Exceptions::Exception(
"All transformation processed but identity transformation not found.");
94 template<
typename Scalar>
98 precalc_shapes(gip_points, num_gip_points, trfs, num_noni_trfs, shapes, max_shape_inx, svals, mode);
101 const int num_shapes = (int)shapes.size();
102 for (
int i = 0; i < num_shapes; i++)
104 const int inx_shape_i = shapes[i].inx;
107 for (
int j = 0; j < i; j++)
109 const int inx_shape_j = shapes[j].inx;
112 double product = 0.0;
113 for (
int k = 0; k < num_gip_points; k++)
116 sum += svals[H2D_TRF_IDENTITY][inx_shape_i][H2D_HCFE_VALUE0][k] * svals[H2D_TRF_IDENTITY][inx_shape_j][H2D_HCFE_VALUE0][k];
117 sum += svals[H2D_TRF_IDENTITY][inx_shape_i][H2D_HCFE_VALUE1][k] * svals[H2D_TRF_IDENTITY][inx_shape_j][H2D_HCFE_VALUE1][k];
118 sum += svals[H2D_TRF_IDENTITY][inx_shape_i][H2D_HCFE_CURL][k] * svals[H2D_TRF_IDENTITY][inx_shape_j][H2D_HCFE_CURL][k];
125 while (!done && inx_trf < H2D_TRF_NUM)
128 for (
int k = 0; k < num_gip_points; k++)
130 svals[inx_trf][inx_shape_i][H2D_HCFE_VALUE0][k] -= product * svals[inx_trf][inx_shape_j][H2D_HCFE_VALUE0][k];
131 svals[inx_trf][inx_shape_i][H2D_HCFE_VALUE1][k] -= product * svals[inx_trf][inx_shape_j][H2D_HCFE_VALUE1][k];
132 svals[inx_trf][inx_shape_i][H2D_HCFE_CURL][k] -= product * svals[inx_trf][inx_shape_j][H2D_HCFE_CURL][k];
136 if (inx_trf == H2D_TRF_IDENTITY)
141 if (inx_trf >= num_noni_trfs)
142 inx_trf = H2D_TRF_IDENTITY;
147 throw Exceptions::Exception(
"All transformation processed but identity transformation not found.");
152 double norm_squared = 0.0;
153 for (
int k = 0; k < num_gip_points; k++)
156 sum += sqr(svals[H2D_TRF_IDENTITY][inx_shape_i][H2D_HCFE_VALUE0][k]);
157 sum += sqr(svals[H2D_TRF_IDENTITY][inx_shape_i][H2D_HCFE_VALUE1][k]);
158 sum += sqr(svals[H2D_TRF_IDENTITY][inx_shape_i][H2D_HCFE_CURL][k]);
161 double norm = sqrt(norm_squared);
162 if (!finite(1 / norm))
163 throw Exceptions::Exception(
"Norm (%g) is almost zero.", norm);
168 while (!done && inx_trf < H2D_TRF_NUM)
171 for (
int k = 0; k < num_gip_points; k++)
173 svals[inx_trf][inx_shape_i][H2D_HCFE_VALUE0][k] /= norm;
174 svals[inx_trf][inx_shape_i][H2D_HCFE_VALUE1][k] /= norm;
175 svals[inx_trf][inx_shape_i][H2D_HCFE_CURL][k] /= norm;
179 if (inx_trf == H2D_TRF_IDENTITY)
184 if (inx_trf >= num_noni_trfs)
185 inx_trf = H2D_TRF_IDENTITY;
190 throw Exceptions::Exception(
"All transformation processed but identity transformation not found.");
194 template<
typename Scalar>
199 rval[inx_son][H2D_HCFE_VALUE0] = malloc_with_check<Scalar>(num_gip);
200 rval[inx_son][H2D_HCFE_VALUE1] = malloc_with_check<Scalar>(num_gip);
201 rval[inx_son][H2D_HCFE_CURL] = malloc_with_check<Scalar>(num_gip);
203 memcpy(rval[inx_son][H2D_HCFE_VALUE0], rsln->
get_fn_values(0), num_gip *
sizeof(Scalar));
204 memcpy(rval[inx_son][H2D_HCFE_VALUE1], rsln->
get_fn_values(1), num_gip *
sizeof(Scalar));
209 for (
int i = 0; i < num_gip; i++)
210 rval[inx_son][H2D_HCFE_CURL][i] = d1dx[i] - d0dy[i];
213 template<
typename Scalar>
216 free_with_check(rval[inx_son][H2D_HCFE_VALUE0]);
217 free_with_check(rval[inx_son][H2D_HCFE_VALUE1]);
218 free_with_check(rval[inx_son][H2D_HCFE_CURL]);
221 template<
typename Scalar>
223 const int* shape_inx,
const int num_shapes,
ElementMode2D mode)
226 double** matrix = new_matrix<double>(num_shapes, num_shapes);
230 for (
int i = 0; i < num_shapes; i++, inx_row += num_shapes)
232 double* matrix_row = matrix[i];
233 int shape0_inx = shape_inx[i];
234 for (
int k = 0; k < num_shapes; k++)
236 int shape1_inx = shape_inx[k];
239 for (
int j = 0; j < num_gip_points; j++)
242 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) };
243 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) };
244 double d1dx0 = this->shapeset->get_value(
H2D_FEI_DX, shape0_inx, gip_x, gip_y, 1, mode);
245 double d1dx1 = this->shapeset->get_value(
H2D_FEI_DX, shape1_inx, gip_x, gip_y, 1, mode);
246 double d0dy0 = this->shapeset->get_value(
H2D_FEI_DY, shape0_inx, gip_x, gip_y, 0, mode);
247 double d0dy1 = this->shapeset->get_value(
H2D_FEI_DY, shape1_inx, gip_x, gip_y, 0, mode);
248 double curl0 = d1dx0 - d0dy0;
249 double curl1 = d1dx1 - d0dy1;
251 value += gip_points[j][
H2D_GIP2D_W] * (value0[0] * value1[0] + value0[1] * value1[1] + curl0*curl1);
254 matrix_row[k] = value;
261 template<
typename Scalar>
265 Scalar total_value = 0;
266 for (
int gip_inx = 0; gip_inx < sub_gip.
num_gip_points; gip_inx++)
269 double3 &gip_pt = sub_gip.
gip_points[gip_inx];
272 Scalar shape_value0 = sub_shape.
svals[H2D_HCFE_VALUE0][gip_inx];
273 Scalar shape_value1 = sub_shape.
svals[H2D_HCFE_VALUE1][gip_inx];
274 Scalar shape_curl = sub_shape.
svals[H2D_HCFE_CURL][gip_inx];
277 Scalar ref_value0 = sub_trf.
coef_mx * rval[son][H2D_HCFE_VALUE0][gip_inx];
278 Scalar ref_value1 = sub_trf.
coef_my * rval[son][H2D_HCFE_VALUE1][gip_inx];
280 Scalar ref_curl = coef_curl * rval[son][H2D_HCFE_CURL][gip_inx];
283 Scalar value = (shape_value0 * ref_value0)
284 + (shape_value1 * ref_value1)
285 + (shape_curl * ref_curl);
292 template<
typename Scalar>
295 double total_error_squared = 0;
297 for (
int gip_inx = 0; gip_inx < sub_gip.
num_gip_points; gip_inx++)
300 double3 &gip_pt = sub_gip.
gip_points[gip_inx];
303 Scalar proj_value0 = 0, proj_value1 = 0, proj_curl = 0;
304 for (
int i = 0; i < elem_proj.
num_shapes; i++)
307 proj_value0 += elem_proj.
shape_coeffs[i] * elem_proj.
svals[shape_inx][H2D_HCFE_VALUE0][gip_inx];
308 proj_value1 += elem_proj.
shape_coeffs[i] * elem_proj.
svals[shape_inx][H2D_HCFE_VALUE1][gip_inx];
309 proj_curl += elem_proj.
shape_coeffs[i] * elem_proj.
svals[shape_inx][H2D_HCFE_CURL][gip_inx];
314 Scalar ref_value0 = sub_trf.
coef_mx * rval[son][H2D_HCFE_VALUE0][gip_inx];
315 Scalar ref_value1 = sub_trf.
coef_my * rval[son][H2D_HCFE_VALUE1][gip_inx];
317 Scalar ref_curl = coef_curl * rval[son][H2D_HCFE_CURL][gip_inx];
320 double error_squared = sqr(proj_value0 - ref_value0)
321 + sqr(proj_value1 - ref_value1)
322 + sqr(proj_curl - ref_curl);
324 total_error_squared += gip_pt[
H2D_GIP2D_W] * error_squared;
327 return total_error_squared;
double coef_my
A coefficient that scales df/dy for each subdomain. A coefficient represents effects of a transformat...
virtual void precalc_shapes(const double3 *gip_points, const int num_gip_points, const Trf *trfs, const int num_noni_trfs, const std::vector< typename OptimumSelector< Scalar >::ShapeInx > &shapes, const int max_shape_inx, typename ProjBasedSelector< Scalar >::TrfShape &svals, ElementMode2D mode)
Calculates values of shape function at GIP for all transformations.
virtual void precalc_ref_solution(int inx_son, MeshFunction< Scalar > *rsln, Element *element, int intr_gip_order, Scalar *rval[H2D_MAX_ELEMENT_SONS][MAX_NUMBER_FUNCTION_VALUES_FOR_SELECTORS])
Returns an array of values of the reference solution at integration points.
A projection-based selector for Hcurl space.
A transform shaped function expansions.
Stores one element of a mesh.
int * shape_inxs
Used shape indices.
virtual void get_current_order_range(Element *element, int &min_order, int &max_order)
Sets OptimumSelector::current_max_order and OptimumSelector::current_min_order.
virtual void free_ref_solution_data(int inx_son, Scalar *rval[H2D_MAX_ELEMENT_SONS][MAX_NUMBER_FUNCTION_VALUES_FOR_SELECTORS])
Frees the data allocated in precalc_ref_solution.
A shape function on subdomain of an element.
Represents a function defined on a mesh.
Quad2D * get_quad_2d() const
Returns the current quadrature points.
Integration points in the reference domain of an element of a candidate.
double coef_mx
A coefficient that scales df/dx for each subdomain. A coefficient represents effects of a transformat...
virtual const Scalar * get_dx_values(int component=0) const
Returns the x partial derivative.
virtual const Scalar * get_dy_values(int component=0) const
Returns the y partial derivative.
Projection of an element of a candidate.
double3 * gip_points
Integration points and weights. The first index is an index of an integration point, the second index is defined through the enum GIP2DIndices.
A general projection-based selector.
int num_gip_points
A number of integration points.
int num_shapes
A number of used shape indices.
CandList
Predefined list of candidates.
virtual double evaluate_error_squared_subdomain(Element *sub_elem, const typename ProjBasedSelector< Scalar >::ElemGIP &sub_gip, int son, const typename ProjBasedSelector< Scalar >::ElemSubTrf &sub_trf, const typename ProjBasedSelector< Scalar >::ElemProj &elem_proj, Scalar *rval[H2D_MAX_ELEMENT_SONS][MAX_NUMBER_FUNCTION_VALUES_FOR_SELECTORS])
Evaluates an squared error of a projection of an element of a candidate onto subdomains.
Index of a function value f.
unsigned short iro_cache
Increase in integration order, see RefMap::calc_inv_ref_order()
Scalar * shape_coeffs
Coefficients of shape indices of a projection.
double2 t
The 2x2 diagonal transformation matrix.
H(curl) shapeset with Legendre bubbles and gradients of H1 functions as edges.
std::vector< TrfShapeExp > & svals
A precalculated shape-function values. Empty is not defined.
virtual Scalar evaluate_rhs_subdomain(Element *sub_elem, const typename ProjBasedSelector< Scalar >::ElemGIP &sub_gip, int son, const typename ProjBasedSelector< Scalar >::ElemSubTrf &sub_trf, const typename ProjBasedSelector< Scalar >::ElemSubShapeFunc &sub_shape, Scalar *rval[H2D_MAX_ELEMENT_SONS][MAX_NUMBER_FUNCTION_VALUES_FOR_SELECTORS])
Evaluates a value of the right-hande side in a subdomain.
TrfShapeExp & svals
Evaluate values of a shape function. If TrfShapeExp::empty(), no precalculated values are available...
A transformation from a reference domain of a subdomain to a reference domain of an element of a cand...
virtual void precalc_ortho_shapes(const double3 *gip_points, const int num_gip_points, const Trf *trfs, const int num_noni_trfs, const std::vector< typename OptimumSelector< Scalar >::ShapeInx > &shapes, const int max_shape_inx, typename ProjBasedSelector< Scalar >::TrfShape &svals, ElementMode2D mode)
Calculates values of orthogonalized shape function at GIP for all transformations.
#define H2D_MAX_ELEMENT_SONS
Macros.
virtual const Scalar * get_fn_values(int component=0) const
Returns function values.
virtual double ** build_projection_matrix(double3 *gip_points, int num_gip_points, const int *shape_inx, const int num_shapes, ElementMode2D mode)
Builds projection matrix using a given set of shapes.
HcurlProjBasedSelector(CandList cand_list=H2D_HP_ANISO, int max_order=H2DRS_DEFAULT_ORDER, HcurlShapeset *user_shapeset=nullptr)
Constructor.
#define H2DRS_DEFAULT_ORDER
A default order. Used to indicate an unkonwn order or a maximum support order.
virtual ~HcurlProjBasedSelector()
Destructor.