26 for (
unsigned int node_i = 0; node_i < 2; node_i++)
40 for (
unsigned j = 0; j < e->get_nvert(); j++)
50 if (e->
vn[idx]->
id == p1)
51 e->
cm->curves[idx] = curve;
55 e->
cm->curves[idx] = curve_rev;
62 if (curve->type == ArcType)
65 ((
Arc*)toReturn)->angle = -((
Arc*)toReturn)->angle;
66 for (
int i = 0; i < toReturn->
np; i++)
68 toReturn->pt[((
Arc*)curve)->np - 1 - i][0] = ((
Arc*)curve)->pt[i][0];
69 toReturn->pt[((
Arc*)curve)->np - 1 - i][1] = ((
Arc*)curve)->pt[i][1];
70 toReturn->pt[((
Arc*)curve)->np - 1 - i][2] = ((
Arc*)curve)->pt[i][2];
79 for (
int i = 0; i < ((
Nurbs*)curve)->np; i++)
81 toReturn->
pt[((
Nurbs*)curve)->np - 1 - i][0] = ((
Nurbs*)curve)->pt[i][0];
82 toReturn->
pt[((
Nurbs*)curve)->np - 1 - i][1] = ((
Nurbs*)curve)->pt[i][1];
83 toReturn->
pt[((
Nurbs*)curve)->np - 1 - i][2] = ((
Nurbs*)curve)->pt[i][2];
86 for (
int i = 0; i < ((
Nurbs*)curve)->nk; i++)
87 toReturn->
kv[i] = ((
Nurbs*)curve)->kv[i];
88 for (
int i = ((
Nurbs*)curve)->degree + 1; i < ((
Nurbs*)curve)->nk - ((
Nurbs*)curve)->degree - 1; i++)
89 toReturn->
kv[((
Nurbs*)curve)->nk - 1 - i] = 1.0 - ((
Nurbs*)curve)->kv[i];
101 base = base->
sons[son1];
103 return base->
en[edge];
110 if (!e->is_triangle())
112 if (e->
sons[2] ==
nullptr)
114 if (edge == 0 || edge == 2) { son1 = edge >> 1;
return 1; }
115 else if (edge == 1) { son1 = 0; son2 = 1;
return 2; }
116 else { son1 = 1; son2 = 0;
return 2; }
118 else if (e->
sons[0] ==
nullptr)
120 if (edge == 1 || edge == 3) { son1 = (edge == 1) ? 3 : 2;
return 1; }
121 else if (edge == 0) { son1 = 2; son2 = 3;
return 2; }
122 else { son1 = 3; son2 = 2;
return 2; }
134 Arc* curve =
new Arc(angle);
136 *en = mesh->peek_edge_node(p1, p2);
141 throw Hermes::Exceptions::MeshLoadFailureException(
"Curve #%d: edge %d-%d does not exist.",
id, p1, p2);
147 curve->pt[0][0] = mesh->nodes[p1].x;
148 curve->pt[0][1] = mesh->nodes[p1].y;
149 curve->pt[0][2] = 1.0;
150 curve->pt[2][0] = mesh->nodes[p2].x;
151 curve->pt[2][1] = mesh->nodes[p2].y;
152 curve->pt[2][2] = 1.0;
155 double a = (180.0 - angle) / 180.0 * M_PI;
158 double x = 1.0 / std::tan(a * 0.5);
159 curve->pt[1][0] = 0.5*((curve->pt[2][0] + curve->pt[0][0]) + (curve->pt[2][1] - curve->pt[0][1]) * x);
160 curve->pt[1][1] = 0.5*((curve->pt[2][1] + curve->pt[0][1]) - (curve->pt[2][0] - curve->pt[0][0]) * x);
161 curve->pt[1][2] = Hermes::cos((M_PI - a) * 0.5);
166 MeshHashGrid::MeshHashGrid(
Mesh* mesh) : mesh_seq(mesh->get_seq())
168 mesh->calc_bounding_box();
171 double interval_len_x = (mesh->top_right_x - mesh->bottom_left_x) / GRID_SIZE;
172 double interval_len_y = (mesh->top_right_y - mesh->bottom_left_y) / GRID_SIZE;
174 intervals_x[0] = mesh->bottom_left_x;
175 intervals_y[0] = mesh->bottom_left_y;
177 for (
int i = 1; i < GRID_SIZE; i++)
179 intervals_x[i] = intervals_x[i - 1] + interval_len_x;
180 intervals_y[i] = intervals_y[i - 1] + interval_len_y;
183 intervals_x[GRID_SIZE] = mesh->top_right_x;
184 intervals_y[GRID_SIZE] = mesh->top_right_y;
186 for (
int i = 0; i < GRID_SIZE; i++)
188 for (
int j = 0; j < GRID_SIZE; j++)
190 m_grid[i][j] =
new MeshHashGridElement(intervals_x[i], intervals_y[j], intervals_x[i + 1], intervals_y[j + 1]);
197 int x_min, x_max, y_min, y_max;
198 for_all_active_elements(element, mesh)
200 elementBoundingBox(element, p1, p2);
203 while (intervals_x[x_min + 1] < p1[0])
206 x_max = GRID_SIZE - 1;
207 while (intervals_x[x_max] > p2[0])
211 while (intervals_y[y_min + 1] < p1[1])
214 y_max = GRID_SIZE - 1;
215 while (intervals_y[y_max] > p2[1])
218 assert((x_max >= x_min) && (y_max >= y_min));
220 for (
int i = x_min; i <= x_max; i++)
222 for (
int j = y_min; j <= y_max; j++)
224 assert(m_grid[i][j]->belongs(element));
225 m_grid[i][j]->insert(element);
231 MeshHashGrid::~MeshHashGrid()
233 for (
int i = 0; i < GRID_SIZE; i++)
235 for (
int j = 0; j < GRID_SIZE; j++)
242 MeshHashGridElement::MeshHashGridElement(
double lower_left_x,
double lower_left_y,
double upper_right_x,
double upper_right_y,
int depth) : lower_left_x(lower_left_x), lower_left_y(lower_left_y), upper_right_x(upper_right_x), upper_right_y(upper_right_y), m_depth(depth), m_active(true), element_count(0)
244 this->elements =
new Element*[MAX_ELEMENTS];
245 for (
int i = 0; i < 2; i++)
246 for (
int j = 0; j < 2; j++)
247 m_sons[i][j] =
nullptr;
250 MeshHashGridElement::~MeshHashGridElement()
254 for (
int i = 0; i < 2; i++)
255 for (
int j = 0; j < 2; j++)
260 bool MeshHashGridElement::belongs(Element *element)
263 MeshHashGrid::elementBoundingBox(element, p1, p2);
264 return ((p1[0] <= upper_right_x) && (p2[0] >= lower_left_x) && (p1[1] <= upper_right_y) && (p2[1] >= lower_left_y));
267 void MeshHashGridElement::insert(Element *element)
271 elements[element_count++] = element;
273 if ((element_count >= MAX_ELEMENTS) && (m_depth < MAX_DEPTH))
276 double xx[3] = { lower_left_x, (lower_left_x + upper_right_x) / 2., upper_right_x };
277 double yy[3] = { lower_left_y, (lower_left_y + upper_right_y) / 2., upper_right_y };
278 for (
int i = 0; i < 2; i++)
281 double x1 = xx[i + 1];
282 for (
int j = 0; j < 2; j++)
285 double y1 = yy[j + 1];
287 assert(m_sons[i][j] ==
nullptr);
289 m_sons[i][j] =
new MeshHashGridElement(x0, y0, x1, y1, m_depth + 1);
291 for (
int elem_i = 0; elem_i < this->element_count; elem_i++)
293 if (m_sons[i][j]->belongs(elements[elem_i]))
294 m_sons[i][j]->insert(elements[elem_i]);
305 for (
int i = 0; i < 2; i++)
307 for (
int j = 0; j < 2; j++)
309 assert(m_sons[i][j]);
310 if (m_sons[i][j]->belongs(element))
311 m_sons[i][j]->insert(element);
317 bool MeshHashGridElement::belongs(
double x,
double y)
319 return (x >= lower_left_x) && (x <= upper_right_x) && (y <= lower_left_y) && (y >= upper_right_y);
326 for (
int elem_i = 0; elem_i < this->element_count; elem_i++)
328 return elements[elem_i];
335 for (
int i = 0; i < 2; i++)
337 for (
int j = 0; j < 2; j++)
348 void MeshHashGrid::elementBoundingBox(
Element *element, double2 &p1, double2 &p2)
350 p1[0] = p2[0] = element->
vn[0]->
x;
351 p1[1] = p2[1] = element->
vn[0]->y;
353 for (
int i = 1; i < element->get_nvert(); i++)
355 double xx = element->
vn[i]->
x;
356 double yy = element->
vn[i]->y;
367 if (element->is_curved())
370 double diameter_x = p2[0] - p1[0];
374 double diameter_y = p2[1] - p1[1];
380 Element* MeshHashGrid::getElement(
double x,
double y)
383 while ((i < GRID_SIZE) && (intervals_x[i + 1] < x))
387 while ((j < GRID_SIZE) && (intervals_y[j + 1] < y))
391 if ((i >= GRID_SIZE) || (j >= GRID_SIZE))
394 return m_grid[i][j]->getElement(x, y);
397 int MeshHashGrid::get_mesh_seq()
const
399 return this->mesh_seq;
402 MarkerArea::MarkerArea(Mesh *mesh,
int marker) : mesh_seq(mesh->get_seq())
406 for_all_active_elements(elem, mesh)
408 if (elem->marker == marker)
410 elem->calc_area(
true);
416 int MarkerArea::get_mesh_seq()
const
418 return this->mesh_seq;
421 double MarkerArea::get_area()
const
double x
vertex node coordinates
unsigned char next_vert(unsigned char i) const
Helper functions to obtain the index of the next or previous vertex/edge.
static Arc * load_arc(MeshSharedPtr mesh, int id, Node **en, int p1, int p2, double angle, bool skip_check=false)
Stores one element of a mesh.
Represents a finite element mesh. Typical usage: MeshSharedPtr mesh; Hermes::Hermes2D::MeshReaderH2DX...
Hermes::Hermes2D::Element * getElement(double x, double y)
Return the Element.
Element * elem[2]
elements sharing the edge node
CurvMap * cm
curved mapping, nullptr if not curvilinear
static const unsigned char np
Arc has 3 control points.
unsigned short order
current polynomial degree of the refmap approximation
Represents one NURBS curve.
Stores one node of a mesh.
static bool is_element_on_physical_coordinates(Element *e, double x, double y, double *x_reference=nullptr, double *y_reference=nullptr)
Node * en[H2D_MAX_NUMBER_EDGES]
edge node pointers
static Curve * reverse_curve(Curve *curve)
Element * sons[H2D_MAX_ELEMENT_SONS]
son elements (up to four)
bool active
0 = active, no sons; 1 = inactive (refined), has sons
static Node * get_base_edge_node(Element *base, int edge)
For internal use.
double3 * pt
control points and their weights
Node * vn[H2D_MAX_NUMBER_VERTICES]
vertex node pointers
static int get_edge_sons(Element *e, int edge, int &son1, int &son2)
For internal use.
static void assign_curve(Node *en, Curve *curve, int p1, int p2)
For internal use.