19 #include "algebra/dense_matrix_operations.h"
27 double* Shapeset::calculate_constrained_edge_combination(
unsigned short order,
unsigned short part,
unsigned short ori,
ElementMode2D mode)
34 assert((order - ebias) >= 0);
37 unsigned short i, j, n;
40 for (n = 2; n <= part; n <<= 1)
44 double hi = -((double)part * n2 - 1.0);
45 double lo = -((double)(part + 1) * n2 - 1.0);
47 unsigned short idx[16];
49 for (i = 0; i <= order; i++)
50 idx[i] = get_edge_index(0, ori, i, mode);
54 double f_lo = 0.0, f_hi = 0.0;
57 f_lo = get_value(0, idx[order], lo, -1.0, 0, mode);
58 f_hi = get_value(0, idx[order], hi, -1.0, 0, mode);
68 n = order + 1 - ebias;
69 unsigned short space_type = this->get_space_type();
70 unsigned short component = (space_type == HERMES_HDIV_SPACE) ? 1 : 0;
71 double** a = new_matrix<double>(n, n);
72 double* b = malloc_with_check<double>(n);
73 for (i = 0; i < n; i++)
76 unsigned short o = (ebias == 0) ? order + 1 : order;
77 double p = cos((i + 1) * M_PI / o);
78 double r = (p + 1.0) * 0.5;
82 for (j = 0; j < n; j++)
83 a[i][j] = get_value(0, idx[j + ebias], p, -1.0, component, mode);
86 b[i] = c * get_value(0, idx[order], lo*s + hi*r, -1.0, component, mode) - f_lo*s - f_hi*r;
91 unsigned short* iperm = malloc_with_check<unsigned short>(n);
92 ludcmp(a, n, iperm, &d);
93 lubksb(a, n, iperm, b);
96 free_with_check(iperm);
97 free_with_check(a,
true);
102 double* Shapeset::get_constrained_edge_combination(
unsigned short order,
unsigned short part,
unsigned short ori,
unsigned short& nitems,
ElementMode2D mode)
104 unsigned short index = 2 * ((max_order + 1 - ebias)*part + (order - ebias)) + ori;
107 if (!this->comb_table)
111 if (!this->comb_table)
114 while (table_size <= index)
116 comb_table = calloc_with_check<double*>(table_size,
true);
120 else if (index >= table_size)
125 unsigned short old_size = table_size;
126 while (index >= table_size)
130 comb_table = realloc_with_check<double*>(comb_table, table_size);
131 memset(comb_table + old_size, 0, (table_size - old_size) *
sizeof(
double*));
136 if (!comb_table[index])
140 if (!comb_table[index])
143 comb_table[index] = calculate_constrained_edge_combination(order, part, ori, mode);
148 nitems = order + 1 - ebias;
149 return comb_table[index];
152 void Shapeset::free_constrained_edge_combinations()
156 for (
int i = 0; i < table_size; i++)
157 free_with_check(comb_table[i]);
159 free_with_check(comb_table,
true);
163 double Shapeset::get_constrained_value(
int n,
int index,
double x,
double y,
unsigned short component,
ElementMode2D mode)
167 unsigned short part = (unsigned)index >> 7;
168 unsigned short order = (index >> 3) & 15;
169 unsigned short edge = (index >> 1) & 3;
170 unsigned short ori = index & 1;
172 unsigned short i, nc;
173 double sum, *comb = get_constrained_edge_combination(order, part, ori, nc, mode);
176 shape_fn_t* table = shape_table[n][mode][component];
177 for (i = 0; i < nc; i++)
178 sum += comb[i] * table[get_edge_index(edge, ori, i + ebias, mode)](x, y);
183 Shapeset::~Shapeset() { free_constrained_edge_combinations(); }
185 unsigned short Shapeset::get_max_order()
const
190 unsigned short Shapeset::get_min_order()
const
195 unsigned char Shapeset::get_num_components()
const {
return num_components; }
200 if (mode == HERMES_MODE_TRIANGLE)
205 return vertex_indices[mode][vertex];
208 short Shapeset::get_edge_index(
unsigned char edge,
unsigned short ori,
unsigned short order,
ElementMode2D mode)
const
211 if (mode == HERMES_MODE_TRIANGLE)
215 assert(order >= 0 && order <= max_order);
216 assert(ori == 0 || ori == 1);
218 return edge_indices[mode][edge][2 * order + ori];
221 short* Shapeset::get_bubble_indices(
unsigned short order,
ElementMode2D mode)
const
225 assert(H2D_GET_V_ORDER(order) >= 0 && H2D_GET_V_ORDER(order) <= max_order);
227 unsigned short index = order;
228 if (mode == HERMES_MODE_QUAD)
229 index = H2D_MAKE_QUAD_ORDER(H2D_GET_V_ORDER(order),
H2D_GET_H_ORDER(order));
230 return bubble_indices[mode][index];
233 unsigned short Shapeset::get_num_bubbles(
unsigned short order,
ElementMode2D mode)
const
237 assert(H2D_GET_V_ORDER(order) >= 0 && H2D_GET_V_ORDER(order) <= max_order);
239 return bubble_count[mode][order];
242 int Shapeset::get_constrained_edge_index(
unsigned char edge,
unsigned short order,
unsigned short ori,
unsigned short part,
ElementMode2D mode)
const
245 if (mode == HERMES_MODE_TRIANGLE)
249 assert(order >= 0 && order <= max_order);
251 assert(order <= H2D_ORDER_MASK);
253 return -1 - ((part << 7) + (order << 3) + (edge << 1) + ori);
259 return index_to_order[mode][index];
261 else return ((-1 - index) >> 3) & 15;
264 double Shapeset::get_value(
int n,
int index,
double x,
double y,
unsigned short component,
ElementMode2D mode)
267 return shape_table[n][mode][component][index](x, y);
269 return get_constrained_value(n, index, x, y, component, mode);
272 double Shapeset::get_fn_value(
int index,
double x,
double y,
unsigned short component,
ElementMode2D mode)
275 return get_value(0, index, x, y, component, mode);
277 return shape_table[0][mode][component][index](x, y);
279 double Shapeset::get_dx_value(
int index,
double x,
double y,
unsigned short component,
ElementMode2D mode)
282 return get_value(1, index, x, y, component, mode);
284 return shape_table[1][mode][component][index](x, y);
286 double Shapeset::get_dy_value(
int index,
double x,
double y,
unsigned short component,
ElementMode2D mode)
289 return get_value(2, index, x, y, component, mode);
291 return shape_table[2][mode][component][index](x, y);
294 double Shapeset::get_fn_value_0_tri(
int index,
double x,
double y)
297 return get_value(0, index, x, y, 0, HERMES_MODE_TRIANGLE);
299 return shape_table[0][HERMES_MODE_TRIANGLE][0][index](x, y);
301 double Shapeset::get_dx_value_0_tri(
int index,
double x,
double y)
304 return get_value(1, index, x, y, 0, HERMES_MODE_TRIANGLE);
306 return shape_table[1][HERMES_MODE_TRIANGLE][0][index](x, y);
308 double Shapeset::get_dy_value_0_tri(
int index,
double x,
double y)
311 return get_value(2, index, x, y, 0, HERMES_MODE_TRIANGLE);
313 return shape_table[2][HERMES_MODE_TRIANGLE][0][index](x, y);
316 double Shapeset::get_fn_value_0_quad(
int index,
double x,
double y)
319 return get_value(0, index, x, y, 0, HERMES_MODE_QUAD);
321 return shape_table[0][HERMES_MODE_QUAD][0][index](x, y);
323 double Shapeset::get_dx_value_0_quad(
int index,
double x,
double y)
326 return get_value(1, index, x, y, 0, HERMES_MODE_QUAD);
328 return shape_table[1][HERMES_MODE_QUAD][0][index](x, y);
330 double Shapeset::get_dy_value_0_quad(
int index,
double x,
double y)
333 return get_value(2, index, x, y, 0, HERMES_MODE_QUAD);
335 return shape_table[2][HERMES_MODE_QUAD][0][index](x, y);
338 double Shapeset::get_dxx_value(
int index,
double x,
double y,
unsigned short component,
ElementMode2D mode)
341 return get_value(3, index, x, y, component, mode);
343 return shape_table[3][mode][component][index](x, y);
345 double Shapeset::get_dyy_value(
int index,
double x,
double y,
unsigned short component,
ElementMode2D mode)
348 return get_value(4, index, x, y, component, mode);
350 return shape_table[4][mode][component][index](x, y);
352 double Shapeset::get_dxy_value(
int index,
double x,
double y,
unsigned short component,
ElementMode2D mode)
355 return get_value(5, index, x, y, component, mode);
357 return shape_table[5][mode][component][index](x, y);
362 return &ref_vert[mode][vertex];
Common definitions for Hermes2D.
#define H2D_GET_H_ORDER(encoded_order)
Macros for combining quad horizontal and vertical encoded_orders.