16 template <
typename _Type,
typename _Xtype >
19 if(
U.size() != m_nv) {
21 problem =
" The OneD_Node_Mesh.set_node method is trying to add \n";
22 problem +=
" an DenseVector of variables of a different size to that \n";
23 problem +=
" stored at other nodal points. \n";
27 for(std::size_t var = 0; var <
U.size(); ++var) {
28 m_vars[ node * m_nv + var ] =
U[ var ];
32 template <
typename _Type,
typename _Xtype >
35 if((node >= m_X.size()) || (node < 0)) {
37 problem =
" The OneD_Node_Mesh.get_nodes_vars method is trying to access \n";
38 problem +=
" a nodal point outside of the range stored. \n";
43 for(std::size_t var = 0; var < m_nv; ++var) {
44 nodes_vars.
push_back(m_vars[ node * m_nv + var ]);
49 template <
typename _Type,
typename _Xtype >
54 template <
typename _Type,
typename _Xtype >
59 template <
typename _Type,
typename _Xtype >
67 for(std::size_t node = 0; node < m_X.size() - 1; ++node) {
68 std::size_t offset(node * m_nv + var);
70 if((m_vars[ offset ] - value) * (m_vars[ offset + m_nv ] - value) < 0.0) {
71 double deriv = (m_vars[ offset + m_nv ] - m_vars[ offset ]) / (m_X[ node + 1 ] - m_X[ node ]);
72 double x = m_X[ node ] + (value - m_vars[ offset ]) / deriv;
80 template <
typename _Type,
typename _Xtype >
85 template <
typename _Type,
typename _Xtype >
88 if(vec.
size() != m_nv * m_X.size()) {
90 problem =
"The set_vars_from_vector method has been passed a vector\n";
91 problem +=
"of a length that is of an incompatible size for this mesh object\n";
101 if(std::abs(m_X[ 0 ] - newX[ 0 ]) > 1.e-10 ||
102 std::abs(m_X[ m_X.size() - 1 ] - newX[ newX.
size() - 1 ]) > 1.e-10) {
104 problem =
" The OneD_Node_Mesh.remesh method has been called with \n";
105 problem +=
" a passed coordinate vector that has different start and/or \n";
106 problem +=
" end points from the instantiated object. \n";
110 for(std::size_t i = 0; i < newX.
size() - 1; ++i) {
111 if(newX[ i ] >= newX[ i + 1 ]) {
113 problem =
" The OneD_Node_Mesh.remesh method has been passed \n";
114 problem +=
" a non-monotonic coordinate vector. \n";
122 m_vars.resize(newX.
size() * m_nv);
126 for(std::size_t node = 1; node < newX.
size() - 1; ++node) {
128 for(std::size_t i = 0; i < m_X.size(); ++i) {
129 if((m_X[ i ] <= newX[ node ]) && (newX[ node ] < m_X[ i + 1 ])) {
131 for(std::size_t var = 0; var < m_nv; ++var) {
132 double dX = newX[ node ] - m_X[ i ];
133 double dvarsdX = (copy_of_vars[(i+1)*m_nv + var ] - copy_of_vars[ i*m_nv + var ]) / (m_X[ i + 1 ] - m_X[ i ]);
134 m_vars[ node * m_nv + var ] = copy_of_vars[ i * m_nv + var ] + dX * dvarsdX;
141 for(std::size_t var = 0; var < m_nv; ++var) {
142 m_vars[(newX.
size() - 1) * m_nv + var ] = copy_of_vars[(m_X.size() - 1) * m_nv + var ];
151 if(std::abs(m_X[ 0 ] - newX[ 0 ]) > 1.e-10 ||
152 std::abs(m_X[ m_X.size() - 1 ] - newX[ newX.
size() - 1 ]) > 1.e-10) {
154 problem =
" The OneD_Node_Mesh.remesh method has been called with \n";
155 problem +=
" a passed coordinate vector that has different start and/or \n";
156 problem +=
" end points from the instantiated object. \n";
160 for(std::size_t i = 0; i < newX.
size() - 1; ++i) {
161 if(newX[ i ] >= newX[ i + 1 ]) {
163 problem =
" The OneD_Node_Mesh.remesh method has been passed \n";
164 problem +=
" a non-monotonic coordinate vector. \n";
170 DenseVector<std::complex<double> > copy_of_vars(m_vars);
172 m_vars.resize(newX.
size() * m_nv);
176 for(std::size_t node = 1; node < newX.
size() - 1; ++node) {
178 for(std::size_t i = 0; i < m_X.size(); ++i) {
179 if((m_X[ i ] <= newX[ node ]) && (newX[ node ] < m_X[ i + 1 ])) {
181 for(std::size_t var = 0; var < m_nv; ++var) {
182 double dX = newX[ node ] - m_X[ i ];
184 std::complex<double> dvarsdX = (copy_of_vars[(i+1)*m_nv + var ] - copy_of_vars[ i*m_nv + var ]) / (m_X[ i + 1 ] - m_X[ i ]);
185 m_vars[ node * m_nv + var ] = copy_of_vars[ i * m_nv + var ] + dX * dvarsdX;
192 for(std::size_t var = 0; var < m_nv; ++var) {
193 m_vars[(newX.
size() - 1) * m_nv + var ] = copy_of_vars[(m_X.size() - 1) * m_nv + var ];
203 problem =
" The OneD_Node_Mesh.remesh method has been called with \n";
204 problem +=
" a complex data set on a complex mesh.\n";
210 for(
unsigned node = 0; node < m_X.size() - 1; ++node) {
214 if(((m_X[ node ] < x_pos) && (m_X[ node + 1 ] > x_pos))
215 || (std::abs(m_X[ node ] - x_pos) < 1.e-7) || (std::abs(m_X[ node + 1 ] - x_pos) < 1.e-7)) {
217 double delta_x(x_pos - m_X[ node ]);
223 left = get_nodes_vars(node);
224 right = get_nodes_vars(node + 1);
225 deriv = (right - left) / (m_X[ node + 1 ] - m_X[ node ]);
227 right = left + deriv * delta_x;
231 std::cout <<
"You asked for a position of " << x_pos <<
" in a range " << m_X[ 0 ] <<
" to " << m_X[ m_X.size() - 1 ] <<
"\n";
233 problem =
"You have asked the OneD_Node_Mesh class to interpolate data at\n";
234 problem +=
"a point that is outside the range covered by the mesh object.\n";
241 for(
unsigned node = 0; node < m_X.size() - 1; ++node) {
243 if((m_X[ node ] < x_pos || std::abs(m_X[ node ] - x_pos) < 1.e-7) &&
244 (m_X[ node + 1 ] > x_pos || std::abs(m_X[ node + 1 ] - x_pos) < 1.e-7)) {
246 double delta_x(x_pos - m_X[ node ]);
252 left = get_nodes_vars(node);
253 right = get_nodes_vars(node + 1);
254 deriv = (right - left) / (m_X[ node + 1 ] - m_X[ node ]);
256 right = left + deriv * delta_x;
260 std::cout <<
"You asked for a position of " << x_pos <<
" in a range " << m_X[ 0 ] <<
" to " << m_X[ m_X.size() - 1 ] <<
"\n";
262 problem =
"You have asked the OneD_Node_Mesh class to interpolate data at\n";
263 problem +=
"a point that is outside the range covered by the mesh object.\n";
270 double x_pos(pos.real());
272 std::cout <<
"WARNING: You are interpolating complex data on a complex mesh with 'get_interpolated_vars'.\n";
273 std::cout <<
" This does a simple piecewise linear interpolating assuming a single valued path. \n";
275 for(
unsigned node = 0; node < m_X.size() - 1; ++node) {
277 if((m_X[ node ].real() < x_pos || std::abs(m_X[ node ].real() - x_pos) < 1.e-7) &&
278 (m_X[ node + 1 ].real() > x_pos || std::abs(m_X[ node + 1 ].real() - x_pos) < 1.e-7)) {
282 std::complex<double> delta_z = (m_X[ node + 1 ] - m_X[ node ]) * (x_pos - m_X[ node ].real()) / (m_X[ node + 1 ].real() - m_X[ node ].real());
288 left = get_nodes_vars(node);
289 right = get_nodes_vars(node + 1);
291 deriv = (right - left) / (m_X[ node + 1 ] - m_X[ node ]);
293 right = left + deriv * delta_z;
297 std::cout <<
"You asked for a position of " << x_pos <<
" in a range " << m_X[ 0 ] <<
" to " << m_X[ m_X.size() - 1 ] <<
"\n";
299 problem =
"You have asked the OneD_Node_Mesh class to interpolate data at\n";
300 problem +=
"a point that is outside the range covered by the mesh object.\n";
301 problem +=
"Even for complex nodes we assume the path is single valued.\n";
308 problem =
" The OneD_Node_Mesh.find_roots1 method has been called with \n";
309 problem +=
" a mesh containing complex data.\n";
313 template <
typename _Type,
typename _Xtype >
318 for(std::size_t node = 0; node < m_X.size() - 1; ++node) {
319 dx = (m_X[ node + 1 ] - m_X[ node ]);
320 sum += 0.5 * dx * (m_vars[ node * m_nv + var ] + m_vars[(node+1) * m_nv + var ]);
326 template <
typename _Type,
typename _Xtype >
331 for(std::size_t node = 0; node < m_X.size() - 1; ++node) {
332 dx = std::abs(m_X[ node + 1 ] - m_X[ node ]);
333 sum += 0.5 * dx * (std::pow(std::abs(m_vars[ node * m_nv + var ]), 2)
334 + std::pow(std::abs(m_vars[(node + 1) * m_nv + var ]), 2));
337 return std::sqrt(sum);
340 template <
typename _Type,
typename _Xtype >
342 if((m_X.size()) % 2 == 0) {
344 problem =
" The OneD_Node_Mesh.Simpson_integral method is trying to run \n";
345 problem +=
" on a mesh with an even number of points. \n";
355 for(std::size_t node = 0; node < m_X.size() - 2; node += 2) {
357 x1 = m_X[ node + 1 ];
358 x2 = m_X[ node + 2 ];
359 f0 = m_vars[ node * m_nv + var ];
360 f1 = m_vars[(node+1) * m_nv + var ];
361 f2 = m_vars[(node+2) * m_nv + var ];
364 f1 * pow(x0 - x2, 2) + f0 * (x1 - x2) * (2. * x0 - 3. * x1 + x2)
365 - f2 * (x0 - x1) * (x0 - 3. * x1 + 2. * x2)
367 / (6. * (x0 - x1) * (x1 - x2));
379 std::cout <<
"[INFO] Reading OneD_Node_Mesh<double,double> data from " + filename +
"\n";
380 dump.open(filename.c_str());
381 if (dump.good() !=
true) {
383 problem =
" The OneD_Node_Mesh.read method is trying to read a \n";
384 problem +=
" file (" + filename +
") that doesn't exist.\n";
388 dump.setf(std::ios::showpoint);
389 dump.setf(std::ios::showpos);
390 dump.setf(std::ios::scientific);
391 std::size_t N = get_nnodes();
392 for (std::size_t i = 0; i < N; ++i) {
395 for (std::size_t var = 0; var < m_nv; ++var) {
398 m_vars[ i * m_nv + var ] = value;
402 if (std::fabs(x - m_X[ i ]) > 1.e-6) {
403 std::cout <<
" Read x = " << x <<
" Expected x = " << m_X[ i ] <<
"\n";
404 std::cout <<
" Absolute differences are " << fabs(x - m_X[i]) <<
"\n";
406 problem =
" The TwoD_Node_Mesh.read method is trying to read a \n";
407 problem +=
" file whose nodal points are in a different position. \n";
419 std::cout <<
"[INFO] Reading OneD_Node_Mesh<D_complex,double> data from " + filename +
"\n";
420 dump.open(filename.c_str());
421 if (dump.good() !=
true) {
423 problem =
" The OneD_Node_Mesh.read method is trying to read a \n";
424 problem +=
" file (" + filename +
") that doesn't exist.\n";
428 dump.setf(std::ios::showpoint);
429 dump.setf(std::ios::showpos);
430 dump.setf(std::ios::scientific);
431 std::size_t N = get_nnodes();
432 for (std::size_t i = 0; i < N; ++i) {
435 for (std::size_t var = 0; var < m_nv; ++var) {
436 double rValue, iValue;
437 dump >> rValue; dump >> iValue;
438 m_vars[ i * m_nv + var ] =
D_complex(rValue,iValue);
442 if (std::fabs(x - m_X[ i ]) > 1.e-6) {
443 std::cout <<
" Read x = " << x <<
" Expected x = " << m_X[ i ] <<
"\n";
444 std::cout <<
" Absolute differences are " << fabs(x - m_X[i]) <<
"\n";
446 problem =
" The TwoD_Node_Mesh.read method is trying to read a \n";
447 problem +=
" file whose nodal points are in a different position. \n";
459 std::cout <<
"[INFO] Reading OneD_Node_Mesh<D_complex, D_complex> data from " + filename +
"\n";
460 dump.open(filename.c_str());
461 if (dump.good() !=
true) {
463 problem =
" The OneD_Node_Mesh.read method is trying to read a \n";
464 problem +=
" file (" + filename +
") that doesn't exist.\n";
468 dump.setf(std::ios::showpoint);
469 dump.setf(std::ios::showpos);
470 dump.setf(std::ios::scientific);
471 std::size_t N = get_nnodes();
472 for (std::size_t i = 0; i < N; ++i) {
474 dump >> rX; dump >> iX;
476 for (std::size_t var = 0; var < m_nv; ++var) {
477 double rValue, iValue;
478 dump >> rValue; dump >> iValue;
479 m_vars[ i * m_nv + var ] =
D_complex(rValue,iValue);
483 if (std::fabs( X - m_X[ i ]) > 1.e-6) {
484 std::cout <<
" Read x = " << X <<
" Expected x = " << m_X[ i ] <<
"\n";
485 std::cout <<
" Absolute differences are " << fabs( X - m_X[i]) <<
"\n";
487 problem =
" The TwoD_Node_Mesh.read method is trying to read a \n";
488 problem +=
" file whose nodal points are in a different position. \n";
498 template <
typename _Type,
typename _Xtype >
500 std::cout <<
"Number of nodes = " << m_X.size() <<
"\n";
501 std::cout <<
"Nodal positions :\n";
504 std::cout <<
"Number of vars = " << m_nv <<
"\n";
505 std::cout <<
"Interleaved mesh data : \n";
507 std::cout <<
"Mesh dump complete\n";
513 dump.open(filename.c_str());
514 dump.precision(precision);
515 dump.setf(std::ios::showpoint);
516 dump.setf(std::ios::showpos);
517 dump.setf(std::ios::scientific);
518 for(std::size_t i = 0; i < m_X.size(); ++i) {
519 dump << m_X[ i ] <<
" ";
520 for(std::size_t var = 0; var < m_nv; ++var) {
521 dump << m_vars[ i * m_nv + var ] <<
" ";
530 dump.open(filename.c_str());
531 dump.precision(precision);
532 dump.setf(std::ios::showpoint);
533 dump.setf(std::ios::showpos);
534 dump.setf(std::ios::scientific);
535 for(std::size_t i = 0; i < m_X.size(); ++i) {
536 dump << m_X[ i ] <<
" ";
537 for(std::size_t var = 0; var < m_nv; ++var) {
538 dump << real(m_vars[ i * m_nv + var ]) <<
" " << imag(m_vars[ i * m_nv + var ]) <<
" ";
547 dump.open(filename.c_str());
548 dump.precision(precision);
549 dump.setf(std::ios::showpoint);
550 dump.setf(std::ios::showpos);
551 dump.setf(std::ios::scientific);
552 for(std::size_t i = 0; i < m_X.size(); ++i) {
553 dump << real(m_X[ i ]) <<
" " << imag(m_X[ i ]) <<
" ";
554 for(std::size_t var = 0; var < m_nv; ++var) {
555 dump << real(m_vars[ i * m_nv + var ]) <<
" " << imag(m_vars[ i * m_nv + var ]) <<
" ";
Specification for a templated DenseVector class – a dense, dynamic, vector object.
The collection of CppNoddy exceptions.
A specification for a one dimensional mesh object.
An DenseVector class – a dense vector object.
void push_back(const _Type &fill)
A pass-thru definition of push_back.
std::size_t size() const
A pass-thru definition to get the size of the vector.
An exception class to be thrown when a container of incorrect geometry used in any class/method.
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.
_Xtype squared_integral2(std::size_t var=0) const
Compute the integral of the absolute variable squared: |variable|^2.
std::size_t get_nvars() const
void set_vars_from_vector(const DenseVector< _Type > &vec)
Set the variables of this mesh from a vector.
const DenseVector< _Xtype > & nodes() const
void read(std::string filename, const bool reset=false)
Assign mesh contents using a filename.
DenseVector< _Type > get_nodes_vars(const std::size_t &node) const
Get the variables stored at A SPECIFIED node.
void dump() const
A simple method for dumping data to std::cout.
DenseVector< _Type > get_interpolated_vars(const _Xtype &pos) const
Get the variable data at an interpolated position using a first order scheme.
void set_nodes_vars(const std::size_t node, const DenseVector< _Type > &u)
Set the variables stored at A SPECIFIED node.
const DenseVector< _Type > & vars_as_vector() const
For each nodal point we push each variable into a vector in sequence.
std::size_t get_nnodes() const
_Type integral4(std::size_t var=0) const
Integrate over the domain with a Simpson rule.
DenseVector< double > find_roots1(const std::size_t &var, double value=0.0) const
Find a list of approximate locations at which a specified variable attains a given value.
_Type integral2(std::size_t var=0) const
Integrate over the domain.
void remesh1(const DenseVector< _Xtype > &z)
Interpolate this mesh data (linearly) into a new mesh with nodal points defined in the argument list.
void dump_gnu(std::string filename, int precision=10) const
A simple method for dumping data to a file for gnuplot.
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.