CppNoddy  0.92
Loading...
Searching...
No Matches
TwoD_Node_Mesh.h
Go to the documentation of this file.
1/// \file TwoD_Node_Mesh.h
2/// A specification for a two dimensional mesh object. Data
3/// is stored on a nodal mesh.
4#ifndef TWOD_NODE_MESH_H
5#define TWOD_NODE_MESH_H
6
7#include <vector>
8#include <fstream>
9
10#include <DenseVector.h>
11#include <DenseMatrix.h>
12#include <OneD_Node_Mesh.h>
13#include <Types.h>
14
15namespace CppNoddy {
16
17 /// A two dimensional mesh utility object.
18 template <typename _Type>
20 public:
21
23 {}
24
25 /// ctor
27 const std::size_t nvars) :
28 m_nx(x_nodes.size()), m_ny(y_nodes.size()), m_nv(nvars), m_X(x_nodes), m_Y(y_nodes) {
29 // we'll store the data as ( x, y, v ) -> x * ny * nv + y * nv + v
31 }
32
33 /// ctor
34 TwoD_Node_Mesh(const double left, const double right, const double bottom, const double top,
35 const std::size_t nx, const std::size_t ny, const std::size_t nvars) :
36 m_nx(nx), m_ny(ny), m_nv(nvars) {
37 {
39 const double delta = (right - left) / (m_nx - 1);
40 for(std::size_t i = 0; i < m_nx; ++i) {
41 m_X.push_back(left + delta * i);
42 }
43 }
44 {
46 const double delta = (top - bottom) / (m_ny - 1);
47 for(std::size_t i = 0; i < m_ny; ++i) {
48 m_Y.push_back(bottom + delta * i);
49 }
50 }
51 // we'll store the data as ( x, y, v ) -> x * ny * nv + y * nv + v
53 }
54
55 // ctor from a file
56 TwoD_Node_Mesh(std::string filename, const std::size_t nx, const std::size_t ny, const std::size_t nv) :
57 m_nx(nx), m_ny(ny), m_nv(nv) {
58 // need storage for the coordinates
59 m_X = DenseVector<double>(nx, 0.0);
60 m_Y = DenseVector<double>(ny, 0.0);
61 // we'll store the data as ( x, y, v ) -> x * ny * nv + y * nv + v
62 m_vars = DenseVector<_Type>(nx * ny * nv, 0.0);
63 // now read the mesh from the given filename
64 read(filename, true);
65 }
66
67 /// dtor
69 {}
70
71 /// Access operator for a nodal point that returns a vector
72 /// \param nodex The nodal index value in the first direction
73 /// \param nodey The nodal index value in the second direction
74 /// \return The vector of variables stored at the node
75 DenseVector<_Type> operator()(const std::size_t nodex, const std::size_t nodey );
76
77 /// Access operator for a nodal point/variable in the mesh
78 /// \param nodex The nodal index value in the first direction
79 /// \param nodey The nodal index value in the second direction
80 /// \param var The variable index to be accessed
81 _Type& operator()(const std::size_t nodex, const std::size_t nodey, const std::size_t var);
82
83 /// Const access operator for a nodal point/variable in the mesh
84 /// \param nodex The nodal index value in the first direction
85 /// \param nodey The nodal index value in the second direction
86 /// \param var The variable index to be accessed
87 const _Type& operator()(const std::size_t nodex, const std::size_t nodey, const std::size_t var) const;
88
89 /// Access the nodal position - as a pair.
90 /// \param nodex The x nodal position to return
91 /// \param nodey The y nodal position to return
92 /// \return The spatial position of this node as a pair
93 std::pair<double, double> coord(const std::size_t nodex, const std::size_t nodey) const;
94
95 /// Access the x-nodal (first index) position
96 /// \param nodex The x nodal index
97 /// \return The x-coordinate of the node
98 double& xcoord(const std::size_t nodex ){
99 return m_X[nodex];
100 }
101
102 /// Access the y-nodal (second index) position
103 /// \param nodex The y nodal index
104 /// \return The y-coordinate of the node
105 double& ycoord(const std::size_t nodey ){
106 return m_Y[nodey];
107 }
108
109
110 /// Set the variables stored at A SPECIFIED node
111 /// \param nodex The x nodal index to be set
112 /// \param nodey The y nodal index to be set
113 /// \param U The vector of VARIABLES to be written to this nodal point
114 void set_nodes_vars(const std::size_t nodex, const std::size_t nodey, const DenseVector<_Type>& U);
115
116 /// Get the variables stored at A SPECIFIED node -- equivalent to mesh(nodex,nodey).
117 /// \param nodex The x nodal index to be returned
118 /// \param nodey The y nodal index to be returned
119 /// \return The vector of VARIABLES stored at this nodal point
120 DenseVector<_Type> get_nodes_vars(const std::size_t nodex, const std::size_t nodey) const;
121
122 /// Get a cross section of the 2D mesh at a specified (constant) x node
123 /// \param nodex The x nodal index at which the cross section is to be taken
124 /// \return A 1D nodal mesh
125 OneD_Node_Mesh<_Type> get_xsection_at_xnode(const std::size_t nodex) const;
126
127 /// Get a cross section of the 2D mesh at a specified (constant) y node
128 /// \param nodey The y nodal index at which the cross section is to be taken
129 /// \return A 1D nodal mesh
130 OneD_Node_Mesh<_Type> get_xsection_at_ynode(const std::size_t nodey) const;
131
132 /// Get a cross section of the 2D mesh at a specified (constant) x node
133 /// \param nodex The x nodal index at which the cross section is to be taken
134 /// \return A 1D nodal mesh
136 unsigned I(0);
137 OneD_Node_Mesh<_Type> xsection(m_Y, m_nv);
138 for(unsigned i = 0; i<m_nx-1; ++i) {
139 if((m_X[i]< x) && (m_X[i+1]>x)) {
140 I=i;
141 }
142 }
143 double dx_ratio((x-m_X[I])/(m_X[I+1]-m_X[I]));
144 for(unsigned j = 0; j<m_ny; ++j) {
145 for(unsigned var = 0; var<m_nv; ++var) {
146 xsection(j,var) = this->operator()(I,j,var)+(this->operator()(I+1,j,var)-this->operator()(I,j,var))*dx_ratio;
147 }
148 }
149 return xsection;
150 }
151
152 /// Assign an element to all entries in the mesh
153 /// \param elt The element to be assigned to the mesh
154 void assign(const _Type elt);
155
156 /// Get the number of nodes in the two directions of the 2D mesh
157 /// \return A pair consisting of the number of nodes in the 2 directions
158 std::pair< std::size_t, std::size_t > get_nnodes() const;
159
160 /// Get the number of variables that are stored at each node
161 /// \return The number of variables that have data stored at
162 /// each nodal point
163 std::size_t get_nvars() const;
164
165 /// Access the vector of x-nodal positions
166 /// \return A vector of the nodal positions for this mesh
167 const DenseVector<double>& xnodes() const;
168
169 /// Access the vector of y-nodal positions
170 /// \return A vector of the nodal positions for this mesh
171 const DenseVector<double>& ynodes() const;
172
173 /// Return a matrix corresponding to each nodal point in the mesh
174 /// Each matrix element will contain a specified variable number
175 /// \param var The variable number to be accessed
176 /// \return A dense matrix of the specified variable
177 DenseMatrix<_Type> get_var_as_matrix(std::size_t var) const;
178
179 /// Interpolate this mesh data (bilinearly) into a new
180 /// mesh with nodal points defined in the argument list.
181 /// Not written to be efficient, so you probably don't want
182 /// to do any repeated calls with this method.
183 /// \param newX The x-nodal coordinates to be used in the new mesh.
184 /// \param newY The y-nodal coordinates to be used in the new mesh.
185 void remesh1(const DenseVector<double>& newX, const DenseVector<double>& newY);
186
187 /// A simple method for dumping data to std::cout
188 void dump() const;
189
190 /// A simple method for dumping data to a file
191 /// \param filename The filename to write the data to (will overwrite)
192 void dump(std::string filename) const;
193
194 /// A simple method for dumping a single variable to a file with no nodal information
195 /// \param filename The filename to write the data to (will overwrite)
196 /// \param var The index of the variable to be dumped to output
197 void dump_var(std::string filename, const unsigned var) const;
198
199 /// A simple method for reading data from a file
200 /// \param filename The filename to write the data to (will overwrite)
201 /// \param reset Will reset the nodal positions using those from the file
202 void read(std::string filename, const bool reset = false);
203
204 /// A simple method for dumping data to a file for gnuplot surface plotting
205 /// \param filename The filename to write the data to (will overwrite)
206 void dump_gnu(std::string filename) const;
207
208 /// Normalise all data in the mesh based on one variable.
209 /// \param var This var will have its peak (absolute) value as +/-unity following
210 /// the normalisation. All other variables will also be rescaled by
211 /// the same amount.
212 void normalise(const std::size_t& var);
213
214 /// Calls the vector "scale" method for the whole mesh data
215 /// \param value The value to be used in the scale operation
216 void scale(const _Type& value) {
217 m_vars.scale(value);
218 }
219
220 /// Normalise the mesh such that the real part of variable 'var'
221 /// has a real part of unity, and is then the largest real part across
222 /// the whole mesh
223 /// \param var The variable to be normalised
224 void normalise_real_part(const std::size_t& var) {
225 double maxval(max_abs_real_part(var));
226 m_vars.scale(1./maxval);
227 }
228
229 /// Find the maximum stored absolute value in the mesh for a given variable -- no interpolation is used
230 /// \param var The variable index whose maximum is being asked for
231 /// \return The value of the maximum (abs value)
232 double max_abs_real_part(unsigned var);
233
234 /// Find the maximum stored absolute value in the mesh for a given variable -- no interpolation is used
235 /// \param var The variable index whose maximum is being asked for
236 /// \return The value of the maximum (abs value)
237 double max_abs(unsigned var) {
238 double max(0.0);
239 // step through the nodes
240 for(unsigned nodex = 0; nodex < m_X.size(); ++nodex) {
241 for(unsigned nodey = 0; nodey < m_Y.size(); ++nodey) {
242 if(std::abs(m_vars[(nodex * m_ny + nodey) * m_nv + var ]) > max) {
243 max = std::abs(m_vars[(nodex * m_ny + nodey) * m_nv + var ]);
244 }
245 }
246 }
247 return max;
248 }
249
250
251 /// Get a bilinearly interpolated value at a specified point
252 /// \param x x-coordinate in the 2D mesh
253 /// \param y y-coordinate in the 2D mesh
254 /// \return A vector of bilinearly interpolated values
255 DenseVector<_Type> get_interpolated_vars(const double& x, const double& y) {
256 const double tol(1.e-10);
257 // check start and end
258 if((x < m_X[0] - tol) || (x > m_X[m_nx-1] + tol)) {
259 std::string problem;
260 problem = " The TwoD_Node_Mesh.get_interpolated_vars method has been called with \n";
261 problem += " an x coordinate that lies outside the mesh. \n";
262 throw ExceptionRuntime(problem);
263 }
264 // check start and end
265 if((y < m_Y[0] - tol) || (y > m_Y[m_ny-1] + tol)) {
266 std::string problem;
267 problem = " The TwoD_Node_Mesh.get_interpolated_vars method has been called with \n";
268 problem += " a y coordinate that lies outside the mesh. \n";
269 throw ExceptionRuntime(problem);
270 }
271 int bottom_j(-1);
272 for(unsigned j = 0; j < m_ny-1; ++j) {
273 if((y >= m_Y[j] - tol) && (y <= m_Y[j+1] + tol)) {
274 bottom_j = j;
275 }
276 //if ( abs(y-Y[j]) < tol )
277 //{
278 //bottom_j = j;
279 //}
280 //if ( abs(y-m_Y[j+1]) < tol )
281 //{
282 //bottom_j = j+1;
283 //}
284 }
285 //std::cout << y << " " << m_Y[bottom_j] << " " << m_Y[bottom_j+1] << "\n";
286 if(bottom_j == -1) {
287 std::string problem;
288 problem = " The TwoD_Node_Mesh.get_interpolated_vars method is broken.\n";
289 throw ExceptionRuntime(problem);
290 }
291 //
292 OneD_Node_Mesh<_Type> bottom_row = get_xsection_at_ynode(bottom_j);
293 OneD_Node_Mesh<_Type> top_row = get_xsection_at_ynode(bottom_j+1);
294 const double y1 = m_Y[ bottom_j ];
295 const double y2 = m_Y[ bottom_j+1 ];
296 DenseVector<_Type> result = top_row.get_interpolated_vars(x)*(y-y1)/(y2-y1)
297 + bottom_row.get_interpolated_vars(x)*(y2-y)/(y2-y1);
298 //std::cout << "x,y,interp: " << x << " " << y << " " << result[0] << "\n";
299 return result;
300 }
301
302
303 protected:
304
305 // we'll store the number of nodes
306 std::size_t m_nx, m_ny, m_nv;
307 // store x nodal points
309 // store y nodal points
311 // store the nodal values
313 };
314
315
316 template <typename _Type>
317 inline DenseVector<_Type> TwoD_Node_Mesh<_Type>::operator()(const std::size_t nodex, const std::size_t nodey ) {
318#ifdef PARANOID
319 if(nodex > m_nx - 1 || nodey > m_ny - 1) {
320 std::string problem;
321 problem = " The TwoD_Node_Mesh.operator() method is trying to \n";
322 problem += " access a nodal point that is not in the mesh. \n";
323 throw ExceptionRange(problem, m_nx, nodex, m_ny, nodey);
324 }
325#endif
326 return get_nodes_vars(nodex, nodey);
327 }
328
329
330 template <typename _Type>
331 inline _Type& TwoD_Node_Mesh<_Type>::operator()(const std::size_t nodex, const std::size_t nodey, const std::size_t var) {
332#ifdef PARANOID
333 if(nodex > m_nx - 1 || nodey > m_ny - 1) {
334 std::string problem;
335 problem = " The TwoD_Node_Mesh.operator() method is trying to \n";
336 problem += " access a nodal point that is not in the mesh. \n";
337 throw ExceptionRange(problem, m_nx, nodex, m_ny, nodey);
338 }
339 if(var > m_nv - 1) {
340 std::string problem;
341 problem = " The TwoD_Node_Mesh.operator() method is trying to \n";
342 problem += " access a variable index that is not in the mesh. \n";
343 throw ExceptionRange(problem, m_nv, var);
344 }
345#endif
346 return m_vars[(nodex * m_ny + nodey) * m_nv + var ];
347 }
348
349 template <typename _Type>
350 inline const _Type& TwoD_Node_Mesh<_Type>::operator()(const std::size_t nodex, const std::size_t nodey, const std::size_t var) const {
351#ifdef PARANOID
352 if(nodex > m_nx - 1 || nodey > m_ny - 1) {
353 std::string problem;
354 problem = " The TwoD_Node_Mesh.operator() method is trying to \n";
355 problem += " access a nodal point that is not in the mesh. \n";
356 throw ExceptionRange(problem, m_nx, nodex, m_ny, nodey);
357 }
358 if(var > m_nv - 1) {
359 std::string problem;
360 problem = " The TwoD_Node_Mesh.operator() method is trying to \n";
361 problem += " access a variable index that is not in the mesh. \n";
362 throw ExceptionRange(problem, m_nv, var);
363 }
364#endif
365 return m_vars[(nodex * m_ny + nodey) * m_nv + var ];
366 }
367
368 template <typename _Type>
369 inline std::pair<double, double> TwoD_Node_Mesh<_Type>::coord(const std::size_t nodex, const std::size_t nodey) const {
370#ifdef PARANOID
371 if(nodex > m_nx - 1 || nodey > m_ny - 1) {
372 std::string problem;
373 problem = " The TwoD_Node_Mesh.coord method is trying to \n";
374 problem += " access a nodal point that is not in the mesh. \n";
375 throw ExceptionRange(problem, m_nx, nodex, m_ny, nodey);
376 }
377#endif
378 std::pair< double, double > pos;
379 pos.first = m_X[ nodex ];
380 pos.second = m_Y[ nodey ];
381 return pos;
382 }
383
384}
385
386#endif // TWOD_NODE_MESH_H
@ U
Definition: BVPKarman.cpp:20
A matrix class that constructs a DENSE matrix as an STL Vector of DenseVectors.
Specification for a templated DenseVector class – a dense, dynamic, vector object.
A specification for a one dimensional mesh object.
Some standard typedefs.
A matrix class that constructs a DENSE matrix as a row major std::vector of DenseVectors.
Definition: DenseMatrix.h:25
An DenseVector class – a dense vector object.
Definition: DenseVector.h:34
void push_back(const _Type &fill)
A pass-thru definition of push_back.
Definition: DenseVector.h:310
void reserve(const std::size_t &n)
Reserve space for the vector.
Definition: DenseVector.h:340
std::size_t size() const
A pass-thru definition to get the size of the vector.
Definition: DenseVector.h:330
An exception to indicate that a CppNoddy container has been accessed with index/indices outside the m...
Definition: Exceptions.h:117
A generic runtime exception.
Definition: Exceptions.h:158
A one dimensional mesh utility object.
DenseVector< _Type > get_interpolated_vars(const _Xtype &pos) const
Get the variable data at an interpolated position using a first order scheme.
A two dimensional mesh utility object.
std::pair< std::size_t, std::size_t > get_nnodes() const
Get the number of nodes in the two directions of the 2D mesh.
DenseVector< double > m_Y
OneD_Node_Mesh< _Type > get_xsection_at_x1(const double x) const
Get a cross section of the 2D mesh at a specified (constant) x node.
DenseVector< _Type > m_vars
virtual ~TwoD_Node_Mesh()
dtor
DenseMatrix< _Type > get_var_as_matrix(std::size_t var) const
Return a matrix corresponding to each nodal point in the mesh Each matrix element will contain a spec...
void normalise_real_part(const std::size_t &var)
Normalise the mesh such that the real part of variable 'var' has a real part of unity,...
DenseVector< _Type > operator()(const std::size_t nodex, const std::size_t nodey)
Access operator for a nodal point that returns a vector.
TwoD_Node_Mesh(std::string filename, const std::size_t nx, const std::size_t ny, const std::size_t nv)
const DenseVector< double > & xnodes() const
Access the vector of x-nodal positions.
OneD_Node_Mesh< _Type > get_xsection_at_xnode(const std::size_t nodex) const
Get a cross section of the 2D mesh at a specified (constant) x node.
void assign(const _Type elt)
Assign an element to all entries in the mesh.
double max_abs_real_part(unsigned var)
Find the maximum stored absolute value in the mesh for a given variable – no interpolation is used.
void read(std::string filename, const bool reset=false)
A simple method for reading data from a file.
void normalise(const std::size_t &var)
Normalise all data in the mesh based on one variable.
DenseVector< _Type > get_nodes_vars(const std::size_t nodex, const std::size_t nodey) const
Get the variables stored at A SPECIFIED node – equivalent to mesh(nodex,nodey).
std::size_t get_nvars() const
Get the number of variables that are stored at each node.
const DenseVector< double > & ynodes() const
Access the vector of y-nodal positions.
void remesh1(const DenseVector< double > &newX, const DenseVector< double > &newY)
Interpolate this mesh data (bilinearly) into a new mesh with nodal points defined in the argument lis...
void dump_gnu(std::string filename) const
A simple method for dumping data to a file for gnuplot surface plotting.
double & xcoord(const std::size_t nodex)
Access the x-nodal (first index) position.
void scale(const _Type &value)
Calls the vector "scale" method for the whole mesh data.
TwoD_Node_Mesh(const DenseVector< double > &x_nodes, const DenseVector< double > &y_nodes, const std::size_t nvars)
ctor
void dump_var(std::string filename, const unsigned var) const
A simple method for dumping a single variable to a file with no nodal information.
void dump() const
A simple method for dumping data to std::cout.
double & ycoord(const std::size_t nodey)
Access the y-nodal (second index) position.
TwoD_Node_Mesh(const double left, const double right, const double bottom, const double top, const std::size_t nx, const std::size_t ny, const std::size_t nvars)
ctor
DenseVector< _Type > get_interpolated_vars(const double &x, const double &y)
Get a bilinearly interpolated value at a specified point.
OneD_Node_Mesh< _Type > get_xsection_at_ynode(const std::size_t nodey) const
Get a cross section of the 2D mesh at a specified (constant) y node.
double max_abs(unsigned var)
Find the maximum stored absolute value in the mesh for a given variable – no interpolation is used.
DenseVector< double > m_X
void set_nodes_vars(const std::size_t nodex, const std::size_t nodey, const DenseVector< _Type > &U)
Set the variables stored at A SPECIFIED node.
std::pair< double, double > coord(const std::size_t nodex, const std::size_t nodey) const
Access the nodal position - as a pair.
A collection of OO numerical routines aimed at simple (typical) applied problems in continuum mechani...

© 2012

R.E. Hewitt