ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
polygon_ Class Reference

Polygon helper used to accumulate cut-cell face geometry. More...

#include <ERF_EBPolygon.H>

Collaboration diagram for polygon_:

Public Member Functions

AMREX_GPU_HOST_DEVICE polygon_ (amrex::RealVect a_point, amrex::RealVect a_normal)
 Construct a cell-face polygon clipped by an EB plane. More...
 
AMREX_GPU_HOST_DEVICE polygon_ ()
 Construct an empty EB-boundary polygon. More...
 
AMREX_GPU_HOST_DEVICE void add_vertex (amrex::RealVect const &a_v)
 Add a unique vertex to the polygon. More...
 
AMREX_GPU_HOST_DEVICE int get_num_vertices ()
 Return the number of stored vertices. More...
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void set_area (amrex::Real const &a_area)
 Set the polygon area directly. More...
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void define ()
 Finalize polygon ordering and compute its area. More...
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE int ok () const noexcept
 Return whether the polygon has been defined with a valid area state. More...
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real area () const noexcept
 Return the polygon area. More...
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real distance (amrex::RealVect const &a_point) const noexcept
 Return the perpendicular distance from this polygon to a point. More...
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::RealVect get_centroid () const noexcept
 Return the polygon centroid from its sub-triangulation. More...
 
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::RealVect normal () const noexcept
 Return the unit normal vector of the polygon plane. More...
 
void report (int const a_id, amrex::RealVect a_v0)
 Print a diagnostic report for the polygon on CPU builds. More...
 
void debug (int const a_id)
 Print polygon vertices with a face identifier. More...
 
void debug ()
 Print polygon vertices without a face identifier. More...
 

Private Attributes

int const m_cell_face
 
amrex::RealVect const m_eb_point
 
amrex::RealVect const m_eb_normal
 
int m_defined
 
int m_num_vertices
 
amrex::Real m_area
 
int m_sorted
 
amrex::Array< amrex::RealVect, m_max_verticesm_vertices
 
amrex::GpuArray< amrex::Real, m_max_verticesm_theta
 
amrex::RealVect m_zdir
 

Static Private Attributes

static constexpr int m_max_vertices = 6
 

Detailed Description

Polygon helper used to accumulate cut-cell face geometry.

The polygon stores up to six vertices, sorts them in a local plane, and computes area, centroid, distance, and normal data used by eb_cut_cell_.

Constructor & Destructor Documentation

◆ polygon_() [1/2]

AMREX_GPU_HOST_DEVICE polygon_::polygon_ ( amrex::RealVect  a_point,
amrex::RealVect  a_normal 
)
inline

Construct a cell-face polygon clipped by an EB plane.

Parameters
a_pointPoint on the EB plane.
a_normalUnit normal for the EB plane.
31  : m_cell_face(1)
32  , m_eb_point(a_point)
33  , m_eb_normal(a_normal)
34  , m_defined(0)
35  , m_num_vertices(0)
36  , m_area(zero)
37  , m_sorted(0)
38  , m_vertices({amrex::RealVect(zero), amrex::RealVect(zero), amrex::RealVect(zero),
39  amrex::RealVect(zero), amrex::RealVect(zero), amrex::RealVect(zero)})
40  , m_zdir(zero)
41  {}
constexpr amrex::Real zero
Definition: ERF_Constants.H:8
int m_defined
Definition: ERF_EBPolygon.H:288
amrex::Real m_area
Definition: ERF_EBPolygon.H:292
amrex::Array< amrex::RealVect, m_max_vertices > m_vertices
Definition: ERF_EBPolygon.H:296
int const m_cell_face
Definition: ERF_EBPolygon.H:283
int m_sorted
Definition: ERF_EBPolygon.H:294
amrex::RealVect const m_eb_normal
Definition: ERF_EBPolygon.H:286
int m_num_vertices
Definition: ERF_EBPolygon.H:290
amrex::RealVect const m_eb_point
Definition: ERF_EBPolygon.H:285
amrex::RealVect m_zdir
Definition: ERF_EBPolygon.H:300

◆ polygon_() [2/2]

AMREX_GPU_HOST_DEVICE polygon_::polygon_ ( )
inline

Construct an empty EB-boundary polygon.

46  : m_cell_face(0)
47  , m_eb_point(zero)
48  , m_eb_normal(zero)
49  , m_defined(0)
50  , m_num_vertices(0)
51  , m_area(zero)
52  , m_sorted(0)
53  , m_vertices({amrex::RealVect(zero), amrex::RealVect(zero), amrex::RealVect(zero),
54  amrex::RealVect(zero), amrex::RealVect(zero), amrex::RealVect(zero)})
55  , m_zdir(zero)
56  {}

Member Function Documentation

◆ add_vertex()

AMREX_GPU_HOST_DEVICE void polygon_::add_vertex ( amrex::RealVect const &  a_v)
inline

Add a unique vertex to the polygon.

Parameters
a_vVertex coordinates.
63  {
64  for ( int i(0); i<m_num_vertices; ++i) {
65  if ( amrex::almostEqual(m_vertices[i][0],a_v[0]) &&
66  amrex::almostEqual(m_vertices[i][1],a_v[1]) &&
67  amrex::almostEqual(m_vertices[i][2],a_v[2]) ) {
68  return;
69  }
70  }
71  AMREX_ASSERT( m_num_vertices < m_max_vertices );
74  }
static constexpr int m_max_vertices
Definition: ERF_EBPolygon.H:281

Referenced by eb_cut_cell_::calc_edge_intersections(), and eb_cut_cell_::set_covered_regular_cell_vertices().

Here is the caller graph for this function:

◆ area()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real polygon_::area ( ) const
inlinenoexcept

Return the polygon area.

187  {
188  AMREX_ALWAYS_ASSERT( ok() ); // <-------------------------------------- TODO remove ALWAYS
189  return m_area;
190  }
AMREX_ALWAYS_ASSERT(bx.length()[2]==khi+1)
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE int ok() const noexcept
Return whether the polygon has been defined with a valid area state.
Definition: ERF_EBPolygon.H:182

Referenced by eb_cut_cell_::areaBoun(), eb_cut_cell_::centVol(), get_centroid(), and eb_cut_cell_::volume().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ debug() [1/2]

void polygon_::debug ( )
inline

Print polygon vertices without a face identifier.

275  {
276  debug(-1);
277  }
void debug()
Print polygon vertices without a face identifier.
Definition: ERF_EBPolygon.H:275

◆ debug() [2/2]

void polygon_::debug ( int const  a_id)
inline

Print polygon vertices with a face identifier.

Parameters
a_idFace identifier used in the diagnostic output.
268  {
269  amrex::Print() << "EBPolygon: id = " << a_id << ", m_num_vertices = " << m_num_vertices << '\n';
270  for (int i(0); i<m_num_vertices; ++i) {
271  amrex::Print() << "EBPolygon: v" << i << ": " << m_vertices[i] << '\n';
272  }
273  }

◆ define()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void polygon_::define ( )
inline

Finalize polygon ordering and compute its area.

Vertices are sorted counter-clockwise in the polygon plane before area is computed by a triangle fan.

96  {
97 
98  AMREX_ALWAYS_ASSERT( m_defined == 0 ); // TODO ---------------------------- remove ALWAYS
99 
100  m_defined = 1;
101 
102  // We need at least 3 vertices.
103  if (m_num_vertices < 3) { return; }
104 
105  // Check to see if the vertices of the face are inside or outside of the plane.
106  // If they are outside, this face doesn't belong to the volume.
107  if ( m_cell_face ) {
108  for ( int i(0); i<m_num_vertices; ++i) {
109  if ((m_eb_normal.dotProduct(m_vertices[i] - m_eb_point)) >= zero) {
110  } else {
111  }
112  }
113  }
114 
115  // Calculate the centroid of the polygon.
116  amrex::RealVect centroid = get_centroid();
117 
118  // Shift the vertices relative to the centroid
119  amrex::Array<amrex::RealVect,m_max_vertices> vertex_cent;
120  for ( int i(0); i<m_num_vertices; ++i) {
121  vertex_cent[i] = m_vertices[i] - centroid;
122  }
123 
124  // Compute the normal vector m_zdir by cross product of two vectors in vertex_cent.
125  // Choose the vectors with the largest cross-product magnitude.
126  amrex::RealVect v_normal;
127  amrex::Real max_norm2 = -one;
128  const amrex::RealVect& vertex_cent_0 = vertex_cent[0];
129 
130  for (int i = 1; i < m_num_vertices; ++i)
131  {
132  amrex::RealVect vi = vertex_cent[i];
133  amrex::RealVect v_cross = vertex_cent_0.crossProduct(vi);
134  amrex::Real n2 = v_cross.radSquared();
135  if (n2 > max_norm2)
136  {
137  max_norm2 = n2;
138  v_normal = v_cross;
139  }
140  }
141  if (!amrex::almostEqual(max_norm2, zero))
142  {
143  v_normal /= std::sqrt(max_norm2);
144  }
145  m_zdir = v_normal;
146 
147  //
148 
149  m_theta[0] = zero;
150  for ( int i(1); i<m_num_vertices; ++i) {
151 
152  m_theta[i] = std::atan2(m_zdir.dotProduct( vertex_cent[0].crossProduct(vertex_cent[i]) ),
153  vertex_cent[0].dotProduct(vertex_cent[i]));
154 
155  m_theta[i] += ((m_theta[i] >= zero) ? zero : two*PI);
156  }
157 
158  // Sort counter clockwise based on theta.
159  for (int i(0); i<m_num_vertices; ++i) {
160  for (int j(0); j < m_num_vertices-i-1; ++j) {
161  if ( m_theta[j] > m_theta[j+1] ) {
162  amrex::Swap(m_theta[j], m_theta[j+1]);
163  amrex::Swap(m_vertices[j], m_vertices[j+1]);
164  amrex::Swap(vertex_cent[j], vertex_cent[j+1]);
165  }
166  } // j-loop
167  } // i-loop
168  m_sorted = 1;
169 
170  // Compute areas of triangles
171 
172  for (int i(0); i<m_num_vertices; ++i) {
173  int const j( (i+1 == m_num_vertices) ? 0 : i+1 );
174  amrex::RealVect vi_cross_vj = vertex_cent[i].crossProduct(vertex_cent[j]);
175  m_area += myhalf*vi_cross_vj.vectorLength();
176  }
177  AMREX_ALWAYS_ASSERT( m_area > zero ); // <------------------------------- TODO remove ALWAYS
178  } // void define
constexpr amrex::Real two
Definition: ERF_Constants.H:10
constexpr amrex::Real one
Definition: ERF_Constants.H:9
constexpr amrex::Real myhalf
Definition: ERF_Constants.H:13
constexpr amrex::Real PI
Definition: ERF_Constants.H:42
amrex::Real Real
Definition: ERF_ShocInterface.H:19
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::RealVect get_centroid() const noexcept
Return the polygon centroid from its sub-triangulation.
Definition: ERF_EBPolygon.H:205
amrex::GpuArray< amrex::Real, m_max_vertices > m_theta
Definition: ERF_EBPolygon.H:298
real(c_double), private vi
Definition: ERF_module_mp_morr_two_moment.F90:219
Here is the call graph for this function:

◆ distance()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real polygon_::distance ( amrex::RealVect const &  a_point) const
inlinenoexcept

Return the perpendicular distance from this polygon to a point.

Parameters
a_pointPoint used in the distance calculation.
197  {
198  AMREX_ALWAYS_ASSERT( m_defined == 1 ); // <--------------------------- TODO remove ALWAYS
199  amrex::RealVect x0 = a_point - m_vertices[0];
200  return amrex::Math::abs(x0.dotProduct(m_zdir));
201  }

Referenced by report(), and eb_cut_cell_::volume().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_centroid()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::RealVect polygon_::get_centroid ( ) const
inlinenoexcept

Return the polygon centroid from its sub-triangulation.

205  {
206  amrex::RealVect cent(zero);
207  if (m_num_vertices==3) {
208  cent = (m_vertices[0] + m_vertices[1] + m_vertices[2]) / three;
209  } else {
210  // Loop over sub-triangles
212  for ( int i(0); i<m_num_vertices-2; ++i) {
213  amrex::RealVect const v0 (m_vertices[i+1] - m_vertices[0]);
214  amrex::RealVect const v1 (m_vertices[i+2] - m_vertices[0]);
215  amrex::RealVect v0_cross_v1 = v0.crossProduct(v1);
216  amrex::Real area_tri = myhalf * v0_cross_v1.vectorLength();
217  amrex::RealVect cent_tri = (m_vertices[0] + m_vertices[i+1] + m_vertices[i+2]) / three;
218  area += area_tri;
219  cent += area_tri * cent_tri;
220  }
221  cent = cent / area;
222  }
223  return cent;
224  }
constexpr amrex::Real three
Definition: ERF_Constants.H:11
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real area() const noexcept
Return the polygon area.
Definition: ERF_EBPolygon.H:187

Referenced by eb_cut_cell_::centBoun(), eb_cut_cell_::centVol(), define(), and report().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_num_vertices()

AMREX_GPU_HOST_DEVICE int polygon_::get_num_vertices ( )
inline

Return the number of stored vertices.

78  {
79  return m_num_vertices;
80  }

◆ normal()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::RealVect polygon_::normal ( ) const
inlinenoexcept

Return the unit normal vector of the polygon plane.

228  {
229  return m_zdir;
230  }

◆ ok()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE int polygon_::ok ( ) const
inlinenoexcept

Return whether the polygon has been defined with a valid area state.

183  { return ((m_area > zero || (m_area == zero && m_defined == 1)) ? 1 : 0); }

Referenced by area(), report(), and eb_cut_cell_::volume().

Here is the caller graph for this function:

◆ report()

void polygon_::report ( int const  a_id,
amrex::RealVect  a_v0 
)
inline

Print a diagnostic report for the polygon on CPU builds.

Parameters
a_idFace identifier used in the diagnostic output.
a_v0Reference point used to compute the reported distance.
242  {
243 
244 #ifndef AMREX_USE_GPU
245  amrex::RealVect centroid = get_centroid();
246  amrex::Print() << "Face " << a_id
247  << " -------------------------------------------\n"
248  << "\nok? " << (ok() ? "yes" : "no") << "\n\n";
249  for (int i(0); i<m_num_vertices; ++i) {
250  amrex::Print() << "v" << i << ": " << m_vertices[i] << '\n';
251  }
252  amrex::Print() << "\nvc: " << " " << centroid << "\n";
253 
254  amrex::Real const dist = distance( a_v0 );
255  // amrex::Real const vol = ok() ? m_area * dist : zero;
256 
257  amrex::Print() << "\narea: " << m_area
258  << "\ndistance: " << dist
259  << "\nvolume: " << dist*m_area
260  << "\n==================================================\n\n";
261 #endif
262  }
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real distance(amrex::RealVect const &a_point) const noexcept
Return the perpendicular distance from this polygon to a point.
Definition: ERF_EBPolygon.H:197
Here is the call graph for this function:

◆ set_area()

AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void polygon_::set_area ( amrex::Real const &  a_area)
inline

Set the polygon area directly.

Parameters
a_areaArea value assigned to the polygon.
87 { m_area = a_area; }

Referenced by eb_cut_cell_::set_regular().

Here is the caller graph for this function:

Member Data Documentation

◆ m_area

amrex::Real polygon_::m_area
private

Referenced by area(), define(), ok(), report(), and set_area().

◆ m_cell_face

int const polygon_::m_cell_face
private

Referenced by define().

◆ m_defined

int polygon_::m_defined
private

Referenced by define(), distance(), and ok().

◆ m_eb_normal

amrex::RealVect const polygon_::m_eb_normal
private

Referenced by define().

◆ m_eb_point

amrex::RealVect const polygon_::m_eb_point
private

Referenced by define().

◆ m_max_vertices

constexpr int polygon_::m_max_vertices = 6
staticconstexprprivate

Referenced by add_vertex().

◆ m_num_vertices

int polygon_::m_num_vertices
private

◆ m_sorted

int polygon_::m_sorted
private

Referenced by define().

◆ m_theta

amrex::GpuArray<amrex::Real,m_max_vertices> polygon_::m_theta
private

Referenced by define().

◆ m_vertices

amrex::Array<amrex::RealVect,m_max_vertices> polygon_::m_vertices
private

◆ m_zdir

amrex::RealVect polygon_::m_zdir
private

Referenced by define(), distance(), and normal().


The documentation for this class was generated from the following file: