19#include "libmesh/face_c0polygon.h"
21#include "libmesh/edge_edge2.h"
22#include "libmesh/enum_order.h"
23#include "libmesh/tensor_value.h"
33 Polygon(num_sides, num_sides, p)
41unsigned int C0Polygon::opposite_node(
const unsigned int node_in,
42 const unsigned int side_in)
const
44 const auto ns = this->n_sides();
48 libmesh_assert_less (node_in, ns);
49 libmesh_assert_less (node_in, this->
n_nodes());
50 libmesh_assert_less (side_in, this->n_sides());
53 if (node_in == side_in)
54 return (node_in + ns/2 + 1) % ns;
57 return (node_in + ns/2 - 1) % ns;
65bool C0Polygon::is_vertex(
const unsigned int libmesh_dbg_var(i))
const
72bool C0Polygon::is_edge(
const unsigned int libmesh_dbg_var(i))
const
79bool C0Polygon::is_face(
const unsigned int libmesh_dbg_var(i))
const
86bool C0Polygon::is_node_on_side(
const unsigned int n,
87 const unsigned int s)
const
89 const auto ns = this->n_sides();
90 libmesh_assert_less (s, ns);
91 libmesh_assert_less (n, this->
n_nodes());
93 return ((n % ns) == s) ||
94 ((n < ns) && ((s+1)%ns) == n);
97std::vector<unsigned int>
98C0Polygon::nodes_on_side(
const unsigned int s)
const
100 const auto ns = this->n_sides();
102 libmesh_assert_less(s, ns);
104 std::vector<unsigned int> returnval(2);
106 returnval[1] = (s+1)%ns;
111std::vector<unsigned int>
112C0Polygon::nodes_on_edge(
const unsigned int e)
const
114 return this->nodes_on_side(e);
117bool C0Polygon::has_affine_map()
const
119 const unsigned int ns = this->n_sides();
122 Real perimeter_l1 = 0;
124 perimeter_l1 += (this->point((s+1)%ns) - this->point(s)).
l1_norm();
125 const Real tol = perimeter_l1 * affine_tol;
128 const Point veci = this->point(1) - this->point(0);
129 const Point vec12 = this->point(2) - this->point(1);
133 const Real costheta = cos(theta);
134 const Real sintheta = sin(theta);
140 map(0, 1) = (vec12(0) - veci(0)*costheta)/sintheta;
141 map(1, 1) = (vec12(1) - veci(1)*costheta)/sintheta;
142 map(2, 1) = (vec12(2) - veci(2)*costheta)/sintheta;
144 libmesh_assert_less((map * this->master_point(1) -
145 (this->point(1) - this->point(0))).
l1_norm(),
147 libmesh_assert_less((map * this->master_point(2) -
148 (this->point(2) - this->point(0))).
l1_norm(),
152 if ((map * this->master_point(i) -
153 (this->point(i) - this->point(0))).l1_norm() >
162Order C0Polygon::default_order()
const
169std::unique_ptr<Elem> C0Polygon::build_side_ptr (
const unsigned int i)
171 const auto ns = this->n_sides();
172 libmesh_assert_less (i, ns);
174 std::unique_ptr<Elem> sidep = std::make_unique<Edge2>();
175 sidep->set_node(0, this->node_ptr(i));
176 sidep->set_node(1, this->node_ptr((i+1)%ns));
178 sidep->set_interior_parent(
this);
179 sidep->inherit_data_from(*
this);
186void C0Polygon::build_side_ptr (std::unique_ptr<Elem> & side,
187 const unsigned int i)
189 const auto ns = this->n_sides();
190 libmesh_assert_less (i, ns);
192 if (!side.get() || side->type() !=
EDGE2)
194 side = this->build_side_ptr(i);
198 side->inherit_data_from(*
this);
200 side->set_node(0, this->node_ptr(i));
201 side->set_node(1, this->node_ptr((i+1)%ns));
207void C0Polygon::connectivity(
const unsigned int ,
209 std::vector<dof_id_type> & )
const
211 libmesh_not_implemented();
226 libmesh_assert_equal_to (this->_triangulation.size(),
227 this->n_nodes() - 2);
229 Real double_area = 0;
230 for (
const auto & triangle : this->_triangulation)
232 Point v01 = this->point(triangle[1]) -
233 this->point(triangle[0]);
234 Point v02 = this->point(triangle[2]) -
235 this->point(triangle[0]);
239 return double_area/2;
244Point C0Polygon::true_centroid ()
const
248 return this->Elem::true_centroid();
252 libmesh_assert_equal_to (this->_triangulation.size(),
253 this->n_nodes() - 2);
255 Real double_area = 0;
256 Point double_area_weighted_centroid;
257 for (
const auto & triangle : this->_triangulation)
259 Point v01 = this->point(triangle[1]) -
260 this->point(triangle[0]);
261 Point v02 = this->point(triangle[2]) -
262 this->point(triangle[0]);
265 const Point tri_centroid = (this->point(triangle[0]) +
266 this->point(triangle[1]) +
267 this->point(triangle[2]))/3;
269 double_area += double_tri_area;
271 double_area_weighted_centroid += double_tri_area * tri_centroid;
274 return double_area_weighted_centroid / double_area;
279std::pair<unsigned short int, unsigned short int>
280C0Polygon::second_order_child_vertex (
const unsigned int )
const
282 libmesh_not_implemented();
283 return std::pair<unsigned short int, unsigned short int> (0, 0);
287void C0Polygon::permute(
unsigned int perm_num)
289 const auto ns = this->n_sides();
290 libmesh_assert_less (perm_num, ns);
297 Node * tempnode = this->node_ptr(0);
298 Elem * tempneigh = this->neighbor_ptr(0);
301 this->set_node(s, this->node_ptr((s+1)%ns));
302 this->set_neighbor(s, this->neighbor_ptr(s+1));
304 this->set_node(ns-1, tempnode);
305 this->set_neighbor(ns-1, tempneigh);
309 for (
auto & triangle : this->_triangulation)
311 triangle[i] = (triangle[i]+1)%ns;
320 const auto ns = this->n_sides();
325 swap2nodes(s, ns-1-s);
326 swap2neighbors(s, ns-2-s);
327 swap2boundarysides(s, ns-2-s, boundary_info);
328 swap2boundaryedges(s, ns-2-s, boundary_info);
334ElemType C0Polygon::side_type (
const unsigned int libmesh_dbg_var(s))
const
336 libmesh_assert_less (s, this->n_sides());
342C0Polygon::side_vertex_average_normal(
const unsigned int s)
const
344 const auto n_sides = this->n_sides();
345 libmesh_assert_less (s, n_sides);
346 libmesh_assert_equal_to(this->mapping_type(),
LAGRANGE_MAP);
347 const Point side_t = this->point((s+1) % n_sides) -
349 Point plane_normal(0, 0, 1);
354 const auto vavg = this->vertex_average();
357 const Point vi = this->point(i) - vavg;
358 const Point viplus = this->point((i+1)%n_sides) - vavg;
359 plane_normal += vi.
cross(viplus);
361 if (plane_normal.
norm_sq() > TOLERANCE)
364 plane_normal = plane_normal.
unit();
371void C0Polygon::retriangulate()
373 this->_triangulation.clear();
376 std::vector<int> remaining_nodes(this->
n_nodes());
377 std::iota(remaining_nodes.begin(), remaining_nodes.end(), 0);
379 const auto ns = this->n_sides();
381 const Point vavg = this->vertex_average();
388 const Point vi = this->point(i) - vavg;
389 const Point viplus = this->point((i+1)%ns) - vavg;
390 plane_normal += vi.
cross(viplus);
392 plane_normal = plane_normal.
unit();
397 while (remaining_nodes.size() > 2)
399 Real min_cos_angle = 1;
400 int best_vertex = -1;
403 const Point & pn = this->point(remaining_nodes[n]);
404 const Point & pnext = this->point(remaining_nodes[(n+1)%ns]);
405 const Point & pprev = this->point(remaining_nodes[(n+ns-1)%ns]);
406 const Point vprev = (pn - pprev).unit();
407 const Point vnext = (pnext - pn).unit();
409 const Real sign_check = (vprev.
cross(vnext)) * plane_normal;
413 const Real cos_angle = vprev * vnext;
414 if (cos_angle < min_cos_angle)
416 min_cos_angle = cos_angle;
423 this->_triangulation.push_back({remaining_nodes[(best_vertex+ns-1)%ns],
424 remaining_nodes[best_vertex],
425 remaining_nodes[(best_vertex+1)%ns]});
426 remaining_nodes.erase(remaining_nodes.begin()+best_vertex);
The BoundaryInfo class contains information relevant to boundary conditions including storing faces,...
C0Polygon(const unsigned int num_sides, Elem *p=nullptr)
Constructor.
This is the base class from which all geometric element types are derived.
A Node is like a Point, but with more information.
A Point defines a location in LIBMESH_DIM dimensional Real space.
The Polygon is an element in 2D with an arbitrary (but fixed) number of sides.
std::vector< std::array< int, 3 > > _triangulation
Data for a triangulation of the polygon.
This class defines a tensor in LIBMESH_DIM dimensional Real or Complex space.
TypeVector< typename CompareTypes< T, T2 >::supertype > cross(const TypeVector< T2 > &v) const
TypeVector< T > unit() const
The libMesh namespace provides an interface to certain functionality in the library.
auto l1_norm(const NumericVector< T > &vec)
auto index_range(const T &sizable)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...
IOPackage
libMesh interfaces with several different software packages for the purposes of creating,...
ElemType
Defines an enum for geometric element types.
void libmesh_ignore(const Args &...)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
IntRange< T > make_range(T beg, T end)
The 2-parameter make_range() helper function returns an IntRange<T> when both input parameters are of...
T cross_norm_sq(const TypeVector< T > &b, const TypeVector< T > &c)
Compute |b x c|^2 without creating the extra temporary produced by calling b.cross(c)....
const dof_id_type n_nodes