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 
101  class Sample : public Point
102  {
103  public:
104  double value = constants::missing::doubleValue;
105 
107  Sample() = default;
108 
110  Sample(double x, double y, double value)
111  : Point(x, y),
112  value(value)
113  {
114  }
115 
121  static auto ConvertToSamples(int numSamples, const double** samplesXCoordinate,
122  const double** samplesYCoordinate,
123  const double** samplesValue)
124  {
125  // Build the samples
126  std::vector<Sample> samples(numSamples);
127  for (UInt i = 0; i < samples.size(); ++i)
128  {
129  samples[i].x = (*samplesXCoordinate)[i];
130  samples[i].y = (*samplesYCoordinate)[i];
131  samples[i].value = (*samplesValue)[i];
132  }
133  return samples;
134  }
135 
137  [[nodiscard]] bool IsValid(const double missingValue = constants::missing::doubleValue) const
138  {
139  bool isInvalid = IsEqual(x, missingValue) ||
140  IsEqual(y, missingValue);
141 
142  return !isInvalid;
143  }
144  };
145 
147  static std::vector<Edge> ConvertToEdgeNodesVector(int numEdges, const int* const edge_nodes)
148  {
149  std::vector<Edge> edges(numEdges);
150 
151  int ei = 0;
152  for (auto e = 0; e < numEdges; e++)
153  {
154  edges[e].first = edge_nodes[ei];
155  ei++;
156  edges[e].second = edge_nodes[ei];
157  ei++;
158  }
159  return edges;
160  }
161 
163  static std::vector<Point> ConvertToNodesVector(int numNodes,
164  const double* const node_x,
165  const double* const node_y)
166  {
167  std::vector<Point> nodes(numNodes);
168  for (auto n = 0; n < numNodes; n++)
169  {
170  nodes[n].x = node_x[n];
171  nodes[n].y = node_y[n];
172  }
173  return nodes;
174  }
175 
177  static std::tuple<int, double*, double*> ConvertFromNodesVector(const std::vector<Point>& nodes);
178 
180  static std::vector<Point> ConvertToFaceCentersVector(int numFaces,
181  const double* const facex,
182  const double* const facey)
183  {
184  std::vector<Point> faceCenters(numFaces);
185  for (auto n = 0; n < numFaces; n++)
186  {
187  faceCenters[n].x = facex[n];
188  faceCenters[n].y = facey[n];
189  }
190  return faceCenters;
191  }
192 
194  static std::vector<std::vector<UInt>> ConvertToFaceNodesVector(int num_faces,
195  const int* const face_nodes,
196  const int* const nodes_per_face)
197  {
198  std::vector<std::vector<UInt>> result;
199  result.reserve(num_faces);
200 
201  std::vector<UInt> nodes;
202  UInt index = 0;
203  for (auto f = 0; f < num_faces; f++)
204  {
205  nodes.clear();
206  for (auto n = 0; n < nodes_per_face[f]; n++)
207  {
208  nodes.emplace_back(static_cast<UInt>(face_nodes[index]));
209  index++;
210  }
211  result.emplace_back(nodes);
212  }
213  return result;
214  }
215 
216 } // namespace meshkernel
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:121
meshkernel::IsEqual
bool IsEqual(const Point &p1, const Point &p2, const double epsilon)
Test points for equality upto a tolerance.
Definition: Point.hpp:450
meshkernel::Sample::IsValid
bool IsValid(const double missingValue=constants::missing::doubleValue) const
Determines if the sample instance has valid coordinates.
Definition: Entities.hpp:137
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::Sample
A struct describing a sample with two coordinates and a value.
Definition: Entities.hpp:101
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:39
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:110
meshkernel::Sample::value
double value
Value.
Definition: Entities.hpp:104