19 template <
typename _Type>
24 problem =
" The TwoD_Node_Mesh.set_nodes_vars method is trying to use a \n";
25 problem +=
" vector that has more entries than variables stored in the mesh. \n";
30 std::size_t offset((nodex * m_ny + nodey) * m_nv);
31 for(std::size_t var = 0; var < m_nv; ++var) {
32 m_vars[ offset++ ] =
U[ var ];
36 template <
typename _Type>
39 if(nodex > m_nx - 1 || nodey > m_ny - 1) {
41 problem =
" The TwoD_Node_Mesh.get_nodes_vars method is trying to \n";
42 problem +=
" access a nodal point that is not in the mesh. \n";
51 template <
typename _Type>
53 m_vars.assign(m_nx * m_ny * m_nv, elt);
56 template <
typename _Type>
58 std::pair< std::size_t, std::size_t > nodes;
64 template <
typename _Type>
69 template <
typename _Type>
74 template <
typename _Type>
79 template <
typename _Type>
84 problem =
" The TwoD_Node_Mesh.get_var_as_matrix method is trying to use a \n";
85 problem +=
" variable index bigger than the number of variables in the mesh. \n";
90 for(std::size_t i = 0; i < m_nx; ++i) {
91 for(std::size_t j = 0; j < m_ny; ++j) {
92 temp(i, j) = m_vars[(i * m_ny + j) * m_nv + var ];
98 template<
typename _Type>
102 if(std::abs(m_X[ 0 ] - newX[ 0 ]) > 1.e-10 ||
103 std::abs(m_X[ m_X.size() - 1 ] - newX[ newX.
size() - 1 ]) > 1.e-10) {
105 problem =
" The TwoD_Node_Mesh.remesh1 method has been called with \n";
106 problem +=
" a passed X coordinate vector that has different start and/or \n";
107 problem +=
" end points from the instantiated object. \n";
111 for(std::size_t i = 0; i < newX.
size() - 1; ++i) {
112 if(newX[ i ] >= newX[ i + 1 ]) {
114 problem =
" The TwoD_Node_Mesh.remesh1 method has been passed \n";
115 problem +=
" a non-monotonic X coordinate vector. \n";
121 if(std::abs(m_Y[ 0 ] - newY[ 0 ]) > 1.e-10 ||
122 std::abs(m_Y[ m_Y.size() - 1 ] - newY[ newY.
size() - 1 ]) > 1.e-10) {
124 problem =
" The TwoD_Node_Mesh.remesh1 method has been called with \n";
125 problem +=
" a passed Y coordinate vector that has different start and/or \n";
126 problem +=
" end points from the instantiated object. \n";
130 for(std::size_t i = 0; i < newY.
size() - 1; ++i) {
131 if(newY[ i ] >= newY[ i + 1 ]) {
133 problem =
" The TwoD_Node_Mesh.remesh1 method has been passed \n";
134 problem +=
" a non-monotonic Y coordinate vector. \n";
146 std::size_t xnode(0);
148 for(
unsigned var = 0; var < m_nv; ++var) {
149 newvars[(xnode * newY.
size() + 0) * m_nv + var ] = get_nodes_vars(0, 0)[ var ];
151 for(std::size_t ynode = 1; ynode < newY.
size() - 1; ++ynode) {
152 std::size_t left_i(0);
153 std::size_t below_j(0);
156 for(std::size_t j = 0; j < m_Y.size() - 1; ++j) {
157 if((m_Y[ j ] <= newY[ ynode ]) && (newY[ ynode ] < m_Y[ j + 1 ])) {
159 deltaY = newY[ ynode ] - m_Y[ j ];
162 DenseVector<_Type> dvarsdY = (get_nodes_vars(left_i, below_j + 1) - get_nodes_vars(left_i, below_j))
163 / (coord(left_i, below_j + 1).second - coord(left_i, below_j).second);
164 DenseVector<_Type> interpolated_vars = get_nodes_vars(left_i, below_j) + dvarsdY * deltaY;
165 for(
unsigned var = 0; var < m_nv; ++var) {
166 newvars[(xnode * newY.
size() + ynode) * m_nv + var ] = interpolated_vars[ var ];
170 for(
unsigned var = 0; var < m_nv; ++var) {
171 newvars[(xnode * newY.
size() + newY.
size() - 1) * m_nv + var ] = get_nodes_vars(0, m_ny - 1)[ var ];
176 std::size_t xnode(newX.
size() - 1);
178 for(
unsigned var = 0; var < m_nv; ++var) {
179 newvars[(xnode * newY.
size() + 0) * m_nv + var ] = get_nodes_vars(m_nx - 1, 0)[ var ];
181 for(std::size_t ynode = 1; ynode < newY.
size() - 1; ++ynode) {
182 std::size_t left_i(m_X.size() - 1);
183 std::size_t below_j(0);
186 for(std::size_t j = 0; j < m_Y.size() - 1; ++j) {
187 if((m_Y[ j ] <= newY[ ynode ]) && (newY[ ynode ] < m_Y[ j + 1 ])) {
189 deltaY = newY[ ynode ] - m_Y[ j ];
192 DenseVector<_Type> dvarsdY = (get_nodes_vars(left_i, below_j + 1) - get_nodes_vars(left_i, below_j))
193 / (coord(left_i, below_j + 1).second - coord(left_i, below_j).second);
194 DenseVector<_Type> interpolated_vars = get_nodes_vars(left_i, below_j) + dvarsdY * deltaY;
195 for(
unsigned var = 0; var < m_nv; ++var) {
196 newvars[(xnode * newY.
size() + ynode) * m_nv + var ] = interpolated_vars[ var ];
200 for(
unsigned var = 0; var < m_nv; ++var) {
201 newvars[(xnode * newY.
size() + newY.
size() - 1) * m_nv + var ] = get_nodes_vars(m_nx - 1, m_ny - 1)[ var ];
206 std::size_t ynode(0);
207 for(std::size_t xnode = 1; xnode < newX.
size() - 1; ++xnode) {
208 std::size_t left_i(0);
209 std::size_t below_j(0);
212 for(std::size_t i = 0; i < m_X.size() - 1; ++i) {
213 if((m_X[ i ] <= newX[ xnode ]) && (newX[ xnode ] < m_X[ i + 1 ])) {
215 deltaX = newX[ xnode ] - m_X[ i ];
218 DenseVector<_Type> dvarsdX = (get_nodes_vars(left_i + 1, below_j) - get_nodes_vars(left_i, below_j))
219 / (coord(left_i + 1, below_j).first - coord(left_i, below_j).first);
220 DenseVector<_Type> interpolated_vars = get_nodes_vars(left_i, below_j) + dvarsdX * deltaX;
221 for(
unsigned var = 0; var < m_nv; ++var) {
222 newvars[(xnode * newY.
size() + ynode) * m_nv + var ] = interpolated_vars[ var ];
228 std::size_t ynode(newY.
size() - 1);
229 for(std::size_t xnode = 1; xnode < newX.
size() - 1; ++xnode) {
230 std::size_t left_i(0);
231 std::size_t below_j(m_Y.size() - 1);
234 for(std::size_t i = 0; i < m_X.size() - 1; ++i) {
235 if((m_X[ i ] <= newX[ xnode ]) && (newX[ xnode ] < m_X[ i + 1 ])) {
237 deltaX = newX[ xnode ] - m_X[ i ];
240 DenseVector<_Type> dvarsdX = (get_nodes_vars(left_i + 1, below_j) - get_nodes_vars(left_i, below_j))
241 / (coord(left_i + 1, below_j).first - coord(left_i, below_j).first);
242 DenseVector<_Type> interpolated_vars = get_nodes_vars(left_i, below_j) + dvarsdX * deltaX;
243 for(
unsigned var = 0; var < m_nv; ++var) {
244 newvars[(xnode * newY.
size() + ynode) * m_nv + var ] = interpolated_vars[ var ];
249 for(std::size_t xnode = 1; xnode < newX.
size() - 1; ++xnode) {
250 for(std::size_t ynode = 1; ynode < newY.
size() - 1; ++ynode) {
251 std::size_t left_i(0);
252 std::size_t below_j(0);
254 for(std::size_t i = 0; i < m_X.size() - 1; ++i) {
255 if((m_X[ i ] <= newX[ xnode ]) && (newX[ xnode ] < m_X[ i + 1 ])) {
260 for(std::size_t j = 0; j < m_Y.size() - 1; ++j) {
261 if((m_Y[ j ] <= newY[ ynode ]) && (newY[ ynode ] < m_Y[ j + 1 ])) {
265 DenseVector<_Type> dvarsdX = (get_nodes_vars(left_i + 1, below_j) - get_nodes_vars(left_i, below_j))
266 / (coord(left_i + 1, below_j).first - coord(left_i, below_j).first);
267 DenseVector<_Type> dvarsdY = (get_nodes_vars(left_i, below_j + 1) - get_nodes_vars(left_i, below_j))
268 / (coord(left_i, below_j + 1).second - coord(left_i, below_j).second);
271 (get_nodes_vars(left_i, below_j) * (coord(left_i + 1, below_j).first - newX[ xnode ])
272 + get_nodes_vars(left_i + 1, below_j) * (newX[ xnode ] - coord(left_i, below_j).first)) /
273 (coord(left_i + 1, below_j).first - coord(left_i, below_j).first);
276 (get_nodes_vars(left_i, below_j + 1) * (coord(left_i + 1, below_j + 1).first - newX[ xnode ])
277 + get_nodes_vars(left_i + 1, below_j + 1) * (newX[ xnode ] - coord(left_i, below_j + 1).first)) /
278 (coord(left_i + 1, below_j + 1).first - coord(left_i, below_j + 1).first);
281 (interpolated_vars_bottom * (coord(left_i, below_j + 1).second - newY[ ynode ])
282 + interpolated_vars_top * (newY[ ynode ] - coord(left_i, below_j).second)) /
283 (coord(left_i, below_j + 1).second - coord(left_i, below_j).second);
285 for(
unsigned var = 0; var < m_nv; ++var) {
286 newvars[(xnode * newY.
size() + ynode) * m_nv + var ] = interpolated_vars[ var ];
298 template<
typename _Type>
301 for(std::size_t nodey = 0; nodey < m_ny; ++nodey) {
302 xsection.
set_nodes_vars(nodey,
this -> get_nodes_vars(nodex, nodey));
307 template<
typename _Type>
310 for(std::size_t nodex = 0; nodex < m_nx; ++nodex) {
311 xsection.
set_nodes_vars(nodex,
this -> get_nodes_vars(nodex, nodey));
317 template <
typename _Type>
319 for(std::size_t var = 0; var < m_nv; ++var) {
320 std::cout <<
"Variable : " << var <<
"\n";
321 std::cout <<
" x = ";
322 for(std::size_t i = 0; i < m_nx; ++i) {
323 std::cout << m_X[ i ] <<
", ";
327 for(std::size_t j = 0; j < m_ny; ++j) {
328 std::cout <<
" y = " << m_Y[ j ] <<
"\n";
329 for(std::size_t i = 0; i < m_nx; ++i) {
330 std::cout << m_vars[(i * m_ny + j) * m_nv + var ] <<
", ";
340 double maxval(max_abs(var));
341 m_vars.scale(1./maxval);
350 for(
unsigned nodex = 0; nodex < m_X.size(); ++nodex) {
351 for(
unsigned nodey = 0; nodey < m_Y.size(); ++nodey) {
352 if(std::abs(m_vars[(nodex * m_ny + nodey) * m_nv + var ]) > max) {
353 max = std::abs(m_vars[(nodex * m_ny + nodey) * m_nv + var ]);
359 D_complex factor(m_vars[(max_nx * m_ny + max_ny) * m_nv + var ]);
360 std::cout <<
"[DEBUG] Normalise factor = " << factor <<
"\n";
361 m_vars.scale(1./factor);
377 for(
unsigned nodex = 0; nodex < m_X.size(); ++nodex) {
378 for(
unsigned nodey = 0; nodey < m_Y.size(); ++nodey) {
379 if(std::abs(m_vars[(nodex * m_ny + nodey) * m_nv + var ].real()) > max) {
380 max = std::abs(m_vars[(nodex * m_ny + nodey) * m_nv + var ].real());
392 problem =
" The TwoD_Node_Mesh.max_abs_real_part method has been called for \n";
393 problem +=
" a mesh with element type of double (rather than D_complex).";
403 dump.open(filename.c_str());
405 dump.setf(std::ios::showpoint);
406 dump.setf(std::ios::showpos);
407 dump.setf(std::ios::scientific);
409 for(std::size_t i = 0; i < m_nx; ++i) {
410 for(std::size_t j = 0; j < m_ny; ++j) {
411 dump << m_X[ i ] <<
" " << m_Y[ j ] <<
" ";
412 for(std::size_t var = 0; var < m_nv; ++var) {
413 dump << m_vars[(i * m_ny + j) * m_nv + var ] <<
" ";
425 dump.open(filename.c_str());
427 dump.setf(std::ios::showpoint);
428 dump.setf(std::ios::showpos);
429 dump.setf(std::ios::scientific);
431 for(std::size_t i = 0; i < m_nx; ++i) {
432 for(std::size_t j = 0; j < m_ny; ++j) {
433 dump << m_X[ i ] <<
" " << m_Y[ j ] <<
" ";
434 for(std::size_t var = 0; var < m_nv; ++var) {
435 dump << real(m_vars[(i * m_ny + j) * m_nv + var ]) <<
" ";
436 dump << imag(m_vars[(i * m_ny + j) * m_nv + var ]) <<
" ";
445 template<
typename _Type>
448 dump.open(filename.c_str());
450 dump.setf(std::ios::showpoint);
451 dump.setf(std::ios::showpos);
452 dump.setf(std::ios::scientific);
453 for(std::size_t i = 0; i < m_nx; ++i) {
454 for(std::size_t j = 0; j < m_ny; ++j) {
455 dump << m_vars[(i * m_ny + j) * m_nv + var ] <<
"\n";
460 template<
typename _Type>
463 dump.open(filename.c_str());
465 dump.setf(std::ios::showpoint);
466 dump.setf(std::ios::showpos);
467 dump.setf(std::ios::scientific);
470 for(std::size_t i = 0; i < m_nx; ++i) {
471 for(std::size_t j = 0; j < m_ny; ++j) {
472 dump << m_X[ i ] <<
" " << m_Y[ j ] <<
" ";
473 for(std::size_t var = 0; var < m_nv; ++var) {
474 dump << m_vars[(i * m_ny + j) * m_nv + var ] <<
" ";
484 dump.open(filename.c_str());
485 if(dump.good() !=
true) {
487 problem =
" The TwoD_Node_Mesh.read method is trying to read a \n";
488 problem +=
" file (" + filename +
") that doesn't exist.\n";
492 dump.setf(std::ios::showpoint);
493 dump.setf(std::ios::showpos);
494 dump.setf(std::ios::scientific);
495 for(std::size_t i = 0; i < m_nx; ++i) {
496 for(std::size_t j = 0; j < m_ny; ++j) {
500 for(std::size_t var = 0; var < m_nv; ++var) {
503 m_vars[(i * m_ny + j) * m_nv + var ] = value;
507 if((std::fabs(x - m_X[ i ]) > 1.e-6) || (std::fabs(y - m_Y[ j ]) > 1.e-6)) {
508 std::cout <<
" Read x = " << x <<
" Expected x = " << m_X[ i ] <<
"; Read y = " << y <<
" Expected y = " << m_Y[ j ] <<
" \n";
509 std::cout <<
" Absolute differences are " << fabs(x - m_X[i]) <<
" and " << fabs(y - m_Y[j]) <<
"\n";
511 problem =
" The TwoD_Node_Mesh.read method is trying to read a \n";
512 problem +=
" file whose nodal points are in a different position. \n";
527 dump.open(filename.c_str());
529 dump.setf(std::ios::showpoint);
530 dump.setf(std::ios::showpos);
531 dump.setf(std::ios::scientific);
535 for(std::size_t i = 0; i < m_nx; ++i) {
536 for(std::size_t j = 0; j < m_ny; ++j) {
540 for(std::size_t var = 0; var < m_nv; ++var) {
541 double value_r, value_i;
544 m_vars[(i * m_ny + j) * m_nv + var ] =
D_complex(value_r, value_i);
548 if((std::fabs(x - m_X[ i ]) > 1.e-6) || (std::fabs(y - m_Y[ j ]) > 1.e-6)) {
549 std::cout <<
" Read x = " << x <<
" Expected x = " << m_X[ i ] <<
"; Read y = " << y <<
" Expected y = " << m_Y[ j ] <<
" \n";
550 std::cout <<
" Absolute differences are " << fabs(x - m_X[i]) <<
" and " << fabs(y - m_Y[j]) <<
"\n";
552 problem =
" The TwoD_Node_Mesh.read method is trying to read a \n";
553 problem +=
" file whose nodal points are in a different position. \n";
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.
The collection of CppNoddy exceptions.
A specification for a two dimensional mesh object.
A spec for a collection of utility functions.
A matrix class that constructs a DENSE matrix as a row major std::vector of DenseVectors.
An DenseVector class – a dense vector object.
std::size_t size() const
A pass-thru definition to get the size of the vector.
An exception to indicate that a CppNoddy container has been accessed with index/indices outside the m...
A generic runtime exception.
A one dimensional mesh utility object.
void set_nodes_vars(const std::size_t node, const DenseVector< _Type > &u)
Set the variables stored at A SPECIFIED node.
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.
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...
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.
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.
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.
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::string stringify(const int &val)
Return an integer value as a string - useful for file naming.
A collection of OO numerical routines aimed at simple (typical) applied problems in continuum mechani...
std::complex< double > D_complex
A complex double precision number using std::complex.