MeshKernel
Entities.hpp
1 //---- GPL ---------------------------------------------------------------------
2 //
3 // Copyright (C) Stichting Deltares, 2011-2021.
4 //
5 // This program is free software: you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation version 3.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
16 //
17 // contact: delft3d.support@deltares.nl
18 // Stichting Deltares
19 // P.O. Box 177
20 // 2600 MH Delft, The Netherlands
21 //
22 // All indications and logos of, and references to, "Delft3D" and "Deltares"
23 // are registered trademarks of Stichting Deltares, and remain the property of
24 // Stichting Deltares. All rights reserved.
25 //
26 //------------------------------------------------------------------------------
27 
28 #pragma once
29 
30 #include <vector>
31 
32 #include "MeshKernel/Constants.hpp"
33 #include "MeshKernel/Definitions.hpp"
34 #include "MeshKernel/Exceptions.hpp"
35 #include "MeshKernel/Point.hpp"
36 
37 namespace meshkernel
38 {
39 
40  // to re-enable when compiling with c++20 support
41  // template <typename T>
42  // concept IsCoordinate = requires(T t)
43  //{
44  // t.x;
45  // t.y;
46  // t.IsValid
47  //};
48 
50  using Edge = std::pair<UInt, UInt>;
51 
53  static bool IsValid(const UInt value)
54  {
55  return value != constants::missing::uintValue;
56  }
57 
58  static bool IsValidEdge(const Edge& edge)
59  {
60  return IsValid(edge.first) && IsValid(edge.second);
61  }
62 
64  using EdgeFaces = std::array<UInt, 2>;
65 
67  static UInt Neighbour(const EdgeFaces& edge, const UInt elementId)
68  {
69  return edge[0] == elementId ? edge[1] : edge[0];
70  }
71 
76  UInt static OtherNodeOfEdge(const Edge& edge, UInt node)
77  {
78  return node == edge.first ? edge.second : edge.first;
79  }
80 
84  static UInt EdgeNodeIndex(const Edge& edge, UInt position)
85  {
86  if (position == 0)
87  {
88  return edge.first;
89  }
90  else if (position == 1)
91  {
92  return edge.second;
93  }
94  else
95  {
96  throw ConstraintError("Position out of bounds: {} not in [0 .. 1]", position);
97  }
98  }
99 
102  {
103  double x;
104  double y;
105  double z;
106  };
107 
109  class Sample : public Point
110  {
111  public:
112  double value = constants::missing::doubleValue;
113 
115  Sample() = default;
116 
118  Sample(double x, double y, double value)
119  : Point(x, y),
120  value(value)
121  {
122  }
123 
129  static auto ConvertToSamples(int numSamples, const double** samplesXCoordinate,
130  const double** samplesYCoordinate,
131  const double** samplesValue)
132  {
133  // Build the samples
134  std::vector<Sample> samples(numSamples);
135  for (UInt i = 0; i < samples.size(); ++i)
136  {
137  samples[i].x = (*samplesXCoordinate)[i];
138  samples[i].y = (*samplesYCoordinate)[i];
139  samples[i].value = (*samplesValue)[i];
140  }
141  return samples;
142  }
143 
145  [[nodiscard]] bool IsValid(const double missingValue = constants::missing::doubleValue) const
146  {
147  bool isInvalid = IsEqual(x, missingValue) ||
148  IsEqual(y, missingValue);
149 
150  return !isInvalid;
151  }
152  };
153 
155  static std::vector<Edge> ConvertToEdgeNodesVector(int numEdges, const int* const edge_nodes)
156  {
157  std::vector<Edge> edges(numEdges);
158 
159  int ei = 0;
160  for (auto e = 0; e < numEdges; e++)
161  {
162  edges[e].first = edge_nodes[ei];
163  ei++;
164  edges[e].second = edge_nodes[ei];
165  ei++;
166  }
167  return edges;
168  }
169 
171  static std::vector<Point> ConvertToNodesVector(int numNodes,
172  const double* const node_x,
173  const double* const node_y)
174  {
175  std::vector<Point> nodes(numNodes);
176  for (auto n = 0; n < numNodes; n++)
177  {
178  nodes[n].x = node_x[n];
179  nodes[n].y = node_y[n];
180  }
181  return nodes;
182  }
183 
185  static std::tuple<int, double*, double*> ConvertFromNodesVector(const std::vector<Point>& nodes);
186 
188  static std::vector<Point> ConvertToFaceCentersVector(int numFaces,
189  const double* const facex,
190  const double* const facey)
191  {
192  std::vector<Point> faceCenters(numFaces);
193  for (auto n = 0; n < numFaces; n++)
194  {
195  faceCenters[n].x = facex[n];
196  faceCenters[n].y = facey[n];
197  }
198  return faceCenters;
199  }
200 
202  static std::vector<std::vector<UInt>> ConvertToFaceNodesVector(int num_faces,
203  const int* const face_nodes,
204  const int* const nodes_per_face)
205  {
206  std::vector<std::vector<UInt>> result;
207  result.reserve(num_faces);
208 
209  std::vector<UInt> nodes;
210  UInt index = 0;
211  for (auto f = 0; f < num_faces; f++)
212  {
213  nodes.clear();
214  for (auto n = 0; n < nodes_per_face[f]; n++)
215  {
216  nodes.emplace_back(static_cast<UInt>(face_nodes[index]));
217  index++;
218  }
219  result.emplace_back(nodes);
220  }
221  return result;
222  }
223 
224 } // namespace meshkernel
meshkernel::Cartesian3DPoint
A struct describing the three coordinates in a cartesian projection.
Definition: Entities.hpp:101
meshkernel::Sample::ConvertToSamples
static auto ConvertToSamples(int numSamples, const double **samplesXCoordinate, const double **samplesYCoordinate, const double **samplesValue)
Convert double arrays to std::vector<Sample>
Definition: Entities.hpp:129
meshkernel::Cartesian3DPoint::y
double y
Y-coordinate.
Definition: Entities.hpp:104
meshkernel::Cartesian3DPoint::x
double x
X-coordinate.
Definition: Entities.hpp:103
meshkernel::IsEqual
bool IsEqual(const Point &p1, const Point &p2, const double epsilon)
Test points for equality upto a tolerance.
Definition: Point.hpp:451
meshkernel::Sample::IsValid
bool IsValid(const double missingValue=constants::missing::doubleValue) const
Determines if the sample instance has valid coordinates.
Definition: Entities.hpp:145
meshkernel::Point
A struct describing a point in a two-dimensional space.
Definition: Point.hpp:40
meshkernel::Point::x
double x
X-coordinate.
Definition: Point.hpp:43
meshkernel::Point::y
double y
Y-coordinate.
Definition: Point.hpp:44
meshkernel
Contains the logic of the C++ static library.
Definition: AveragingInterpolation.hpp:36
meshkernel::Cartesian3DPoint::z
double z
Z-coordinate.
Definition: Entities.hpp:105
meshkernel::Sample
A struct describing a sample with two coordinates and a value.
Definition: Entities.hpp:109
meshkernel::EdgeFaces
std::array< UInt, 2 > EdgeFaces
Contains the ID's of elements either side of an edge.
Definition: Entities.hpp:64
meshkernel::Sample::Sample
Sample()=default
Default constructor.
meshkernel::UInt
std::uint32_t UInt
Integer type used when indexing mesh graph entities.
Definition: Definitions.hpp:38
meshkernel::Edge
std::pair< UInt, UInt > Edge
Describes an edge with two indices.
Definition: Entities.hpp:50
meshkernel::Sample::Sample
Sample(double x, double y, double value)
Constructor taking coordinates and values.
Definition: Entities.hpp:118
meshkernel::Sample::value
double value
Value.
Definition: Entities.hpp:112