2 #include "h1_proj_based_selector.h"
8 namespace RefinementSelectors
10 template<
typename Scalar>
14 if (user_shapeset !=
nullptr)
16 this->warn(
"Warn: The user shapeset provided for the selector has to have a correct copy constructor implemented.");
17 this->warn(
"Warning: The functionality for cloning user shapeset is to be implemented yet.");
21 template<
typename Scalar>
24 if (!this->user_shapeset)
25 delete this->shapeset;
28 template<
typename Scalar>
31 int max_element_order = (20 - element->
iro_cache) / 2 - 1;
33 max_order_ = max_element_order;
35 max_order_ = std::min(this->max_order, max_element_order);
39 template<
typename Scalar>
45 while (!done && inx_trf < H2D_TRF_NUM)
48 const Trf& trf = trfs[inx_trf];
49 std::vector<typename ProjBasedSelector<Scalar>::TrfShapeExp>& trf_svals = svals[inx_trf];
52 trf_svals.resize(max_shape_inx + 1);
55 const int num_shapes = (int)shapes.size();
56 for (
int i = 0; i < num_shapes; i++)
58 int inx_shape = shapes[i].inx;
62 shape_exp.allocate(H2D_H1FE_NUM, num_gip_points);
65 for (
int k = 0; k < num_gip_points; k++)
68 double ref_x = gip_points[k][
H2D_GIP2D_X] * trf.m[0] + trf.
t[0];
69 double ref_y = gip_points[k][
H2D_GIP2D_Y] * trf.m[1] + trf.
t[1];
72 shape_exp[H2D_H1FE_VALUE][k] = this->shapeset->get_fn_value(inx_shape, ref_x, ref_y, 0, mode);
73 shape_exp[H2D_H1FE_DX][k] = this->shapeset->get_dx_value(inx_shape, ref_x, ref_y, 0, mode);
74 shape_exp[H2D_H1FE_DY][k] = this->shapeset->get_dy_value(inx_shape, ref_x, ref_y, 0, mode);
79 if (inx_trf == H2D_TRF_IDENTITY)
84 if (inx_trf >= num_noni_trfs)
85 inx_trf = H2D_TRF_IDENTITY;
90 throw Exceptions::Exception(
"All transformation processed but identity transformation not found.");
93 template<
typename Scalar>
97 precalc_shapes(gip_points, num_gip_points, trfs, num_noni_trfs, shapes, max_shape_inx, svals, mode);
100 const int num_shapes = (int)shapes.size();
101 for (
int i = 0; i < num_shapes; i++)
103 const int inx_shape_i = shapes[i].inx;
106 for (
int j = 0; j < i; j++)
108 const int inx_shape_j = shapes[j].inx;
111 double product = 0.0;
112 for (
int k = 0; k < num_gip_points; k++)
115 sum += svals[H2D_TRF_IDENTITY][inx_shape_i][H2D_H1FE_VALUE][k] * svals[H2D_TRF_IDENTITY][inx_shape_j][H2D_H1FE_VALUE][k];
116 sum += svals[H2D_TRF_IDENTITY][inx_shape_i][H2D_H1FE_DX][k] * svals[H2D_TRF_IDENTITY][inx_shape_j][H2D_H1FE_DX][k];
117 sum += svals[H2D_TRF_IDENTITY][inx_shape_i][H2D_H1FE_DY][k] * svals[H2D_TRF_IDENTITY][inx_shape_j][H2D_H1FE_DY][k];
124 while (!done && inx_trf < H2D_TRF_NUM)
127 for (
int k = 0; k < num_gip_points; k++)
129 svals[inx_trf][inx_shape_i][H2D_H1FE_VALUE][k] -= product * svals[inx_trf][inx_shape_j][H2D_H1FE_VALUE][k];
130 svals[inx_trf][inx_shape_i][H2D_H1FE_DX][k] -= product * svals[inx_trf][inx_shape_j][H2D_H1FE_DX][k];
131 svals[inx_trf][inx_shape_i][H2D_H1FE_DY][k] -= product * svals[inx_trf][inx_shape_j][H2D_H1FE_DY][k];
135 if (inx_trf == H2D_TRF_IDENTITY)
140 if (inx_trf >= num_noni_trfs)
141 inx_trf = H2D_TRF_IDENTITY;
146 throw Exceptions::Exception(
"All transformation processed but identity transformation not found.");
151 double norm_squared = 0.0;
152 for (
int k = 0; k < num_gip_points; k++)
155 sum += sqr(svals[H2D_TRF_IDENTITY][inx_shape_i][H2D_H1FE_VALUE][k]);
156 sum += sqr(svals[H2D_TRF_IDENTITY][inx_shape_i][H2D_H1FE_DX][k]);
157 sum += sqr(svals[H2D_TRF_IDENTITY][inx_shape_i][H2D_H1FE_DY][k]);
160 double norm = sqrt(norm_squared);
161 if (!finite(1 / norm))
162 throw Exceptions::Exception(
"Norm (%g) is almost zero.", norm);
167 while (!done && inx_trf < H2D_TRF_NUM)
170 for (
int k = 0; k < num_gip_points; k++)
172 svals[inx_trf][inx_shape_i][H2D_H1FE_VALUE][k] /= norm;
173 svals[inx_trf][inx_shape_i][H2D_H1FE_DX][k] /= norm;
174 svals[inx_trf][inx_shape_i][H2D_H1FE_DY][k] /= norm;
178 if (inx_trf == H2D_TRF_IDENTITY)
183 if (inx_trf >= num_noni_trfs)
184 inx_trf = H2D_TRF_IDENTITY;
189 throw Exceptions::Exception(
"All transformation processed but identity transformation not found.");
193 template<
typename Scalar>
198 rval[inx_son][H2D_H1FE_VALUE] = malloc_with_check<Scalar>(num_gip);
199 rval[inx_son][H2D_H1FE_DX] = malloc_with_check<Scalar>(num_gip);
200 rval[inx_son][H2D_H1FE_DY] = malloc_with_check<Scalar>(num_gip);
202 memcpy(rval[inx_son][H2D_H1FE_VALUE], rsln->
get_fn_values(0), num_gip *
sizeof(Scalar));
203 memcpy(rval[inx_son][H2D_H1FE_DX], rsln->
get_dx_values(0), num_gip *
sizeof(Scalar));
204 memcpy(rval[inx_son][H2D_H1FE_DY], rsln->
get_dy_values(0), num_gip *
sizeof(Scalar));
207 template<
typename Scalar>
210 free_with_check(rval[inx_son][H2D_H1FE_VALUE]);
211 free_with_check(rval[inx_son][H2D_H1FE_DX]);
212 free_with_check(rval[inx_son][H2D_H1FE_DY]);
215 template<
typename Scalar>
217 const int* shape_inx,
const int num_shapes,
ElementMode2D mode)
220 double** matrix = new_matrix<double>(num_shapes, num_shapes);
224 for (
int i = 0; i < num_shapes; i++, inx_row += num_shapes)
226 double* matrix_row = matrix[i];
227 int shape0_inx = shape_inx[i];
228 for (
int k = 0; k < num_shapes; k++)
230 int shape1_inx = shape_inx[k];
233 for (
int j = 0; j < num_gip_points; j++)
236 double value0 = this->shapeset->get_value(
H2D_FEI_VALUE, shape0_inx, gip_x, gip_y, 0, mode);
237 double value1 = this->shapeset->get_value(
H2D_FEI_VALUE, shape1_inx, gip_x, gip_y, 0, mode);
238 double dx0 = this->shapeset->get_value(
H2D_FEI_DX, shape0_inx, gip_x, gip_y, 0, mode);
239 double dx1 = this->shapeset->get_value(
H2D_FEI_DX, shape1_inx, gip_x, gip_y, 0, mode);
240 double dy0 = this->shapeset->get_value(
H2D_FEI_DY, shape0_inx, gip_x, gip_y, 0, mode);
241 double dy1 = this->shapeset->get_value(
H2D_FEI_DY, shape1_inx, gip_x, gip_y, 0, mode);
243 value += gip_points[j][
H2D_GIP2D_W] * (value0*value1 + dx0*dx1 + dy0*dy1);
245 matrix_row[k] = value;
252 template<
typename Scalar>
255 Scalar total_value = 0;
256 for (
int gip_inx = 0; gip_inx < sub_gip.
num_gip_points; gip_inx++)
258 double3 &gip_pt = sub_gip.
gip_points[gip_inx];
261 double shape_value[H2D_H1FE_NUM] = { 0, 0, 0 };
262 shape_value[H2D_H1FE_VALUE] = sub_shape.
svals[H2D_H1FE_VALUE][gip_inx];
263 shape_value[H2D_H1FE_DX] = sub_shape.
svals[H2D_H1FE_DX][gip_inx];
264 shape_value[H2D_H1FE_DY] = sub_shape.
svals[H2D_H1FE_DY][gip_inx];
267 Scalar ref_value[H2D_H1FE_NUM];
268 ref_value[H2D_H1FE_VALUE] = rval[son][H2D_H1FE_VALUE][gip_inx];
269 ref_value[H2D_H1FE_DX] = sub_trf.
coef_mx * rval[son][H2D_H1FE_DX][gip_inx];
270 ref_value[H2D_H1FE_DY] = sub_trf.
coef_my * rval[son][H2D_H1FE_DY][gip_inx];
273 Scalar value = (shape_value[H2D_H1FE_VALUE] * ref_value[H2D_H1FE_VALUE])
274 + (shape_value[H2D_H1FE_DX] * ref_value[H2D_H1FE_DX])
275 + (shape_value[H2D_H1FE_DY] * ref_value[H2D_H1FE_DY]);
282 template<
typename Scalar>
285 double total_error_squared = 0;
286 for (
int gip_inx = 0; gip_inx < sub_gip.
num_gip_points; gip_inx++)
288 double3 &gip_pt = sub_gip.
gip_points[gip_inx];
291 Scalar proj_value[H2D_H1FE_NUM] = { 0, 0, 0 };
292 for (
int i = 0; i < elem_proj.
num_shapes; i++)
295 proj_value[H2D_H1FE_VALUE] += elem_proj.
shape_coeffs[i] * elem_proj.
svals[shape_inx][H2D_H1FE_VALUE][gip_inx];
296 proj_value[H2D_H1FE_DX] += elem_proj.
shape_coeffs[i] * elem_proj.
svals[shape_inx][H2D_H1FE_DX][gip_inx];
297 proj_value[H2D_H1FE_DY] += elem_proj.
shape_coeffs[i] * elem_proj.
svals[shape_inx][H2D_H1FE_DY][gip_inx];
303 ref_value[H2D_H1FE_VALUE] = rval[son][H2D_H1FE_VALUE][gip_inx];
304 ref_value[H2D_H1FE_DX] = sub_trf.
coef_mx * rval[son][H2D_H1FE_DX][gip_inx];
305 ref_value[H2D_H1FE_DY] = sub_trf.
coef_my * rval[son][H2D_H1FE_DY][gip_inx];
308 double error_squared = sqr(proj_value[H2D_H1FE_VALUE] - ref_value[H2D_H1FE_VALUE])
309 + sqr(proj_value[H2D_H1FE_DX] - ref_value[H2D_H1FE_DX])
310 + sqr(proj_value[H2D_H1FE_DY] - ref_value[H2D_H1FE_DY]);
312 total_error_squared += gip_pt[
H2D_GIP2D_W] * error_squared;
316 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_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.
A transform shaped function expansions.
Stores one element of a mesh.
int * shape_inxs
Used shape indices.
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.
#define H2DRS_MAX_ORDER
A maximum order suported by refinement selectors.
Shape functions based on integrated Jacobi polynomials.
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.
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.
Integration points in the reference domain of an element of a candidate.
A projection-based selector for H1 space.
double coef_mx
A coefficient that scales df/dx for each subdomain. A coefficient represents effects of a transformat...
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.
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.
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.
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.
std::vector< TrfShapeExp > & svals
A precalculated shape-function values. Empty is not defined.
TrfShapeExp & svals
Evaluate values of a shape function. If TrfShapeExp::empty(), no precalculated values are available...
~H1ProjBasedSelector()
Destructor.
A transformation from a reference domain of a subdomain to a reference domain of an element of a cand...
H1ProjBasedSelector(CandList cand_list=H2D_HP_ANISO, int max_order=H2DRS_DEFAULT_ORDER, H1Shapeset *user_shapeset=nullptr)
Constructor.
virtual void get_current_order_range(Element *element, int &min_order, int &max_order)
Sets OptimumSelector::current_max_order and OptimumSelector::current_min_order.
#define H2D_MAX_ELEMENT_SONS
Macros.
virtual const Scalar * get_fn_values(int component=0) const
Returns function values.
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.
#define H2DRS_DEFAULT_ORDER
A default order. Used to indicate an unkonwn order or a maximum support order.
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.