19 template <
typename _Type>
24 problem =
" The TwoD_Mapped_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_Mapped_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>
54 for(std::size_t nodey = 0; nodey < m_ny; ++nodey) {
55 xsection.
set_nodes_vars(nodey,
this -> get_nodes_vars(nodex, nodey));
60 template<
typename _Type>
63 for(std::size_t nodex = 0; nodex < m_nx; ++nodex) {
64 xsection.
set_nodes_vars(nodex,
this -> get_nodes_vars(nodex, nodey));
74 template <
typename _Type>
77 std::cout <<
"[DEBUG] Physical domain is [" << m_left <<
"," << m_right
78 <<
"] x [" << m_bottom <<
"," << m_top <<
"]\n";
79 std::cout <<
"[DEBUG] Computational domain is ["
80 << FnComp_X(m_left) <<
"," << FnComp_X(m_right)
81 <<
"] x [" << FnComp_Y(m_bottom) <<
"," << FnComp_Y(m_top) <<
"]\n";
85 double comp_left(FnComp_X(m_left));
86 double comp_right(FnComp_X(m_right));
87 const double comp_delta_x = (comp_right - comp_left) / (m_nx - 1);
88 for(std::size_t i = 0; i < m_nx; ++i) {
89 m_compX[i] = comp_left + comp_delta_x * i;
94 double comp_bottom(FnComp_Y(m_bottom));
95 double comp_top(FnComp_Y(m_top));
96 const double comp_delta_y = (comp_top - comp_bottom) / (m_ny - 1);
97 for(std::size_t j = 0; j < m_ny; ++j) {
98 m_compY[j] = comp_bottom + comp_delta_y * j;
109 for(
unsigned j = 1; j < m_ny-1; ++j) {
121 double delta = 1.e-8;
122 double correction = 1.0;
124 double newY = FnComp_Y(y + delta) - m_compY[j];
125 double oldY = FnComp_Y(y) - m_compY[j];
126 double deriv = (newY-oldY)/delta;
127 correction = -oldY/deriv;
129 }
while(fabs(correction) > 1.e-8);
137 for(
unsigned i = 1; i < m_nx-1; ++i) {
140 double delta = 1.e-8;
141 double correction = 1.0;
143 double newX = FnComp_X(x + delta) - m_compX[i];
144 double oldX = FnComp_X(x) - m_compX[i];
145 double deriv = (newX-oldX)/delta;
146 correction = -oldX/deriv;
148 }
while(fabs(correction) > 1.e-8);
154 template <
typename _Type>
156 std::pair<double,double> steps;
157 steps.first = m_compX[1]-m_compX[0];
158 steps.second = m_compY[1]-m_compY[0];
162 template <
typename _Type>
164 std::pair< std::size_t, std::size_t > nodes;
170 template <
typename _Type>
175 template <
typename _Type>
180 template <
typename _Type>
187 double maxval(max(var));
188 m_vars.scale(1./maxval);
198 for(
unsigned nodex = 0; nodex < m_X.size(); ++nodex) {
199 for(
unsigned nodey = 0; nodey < m_Y.size(); ++nodey) {
200 if(std::abs(m_vars[(nodex * m_ny + nodey) * m_nv + var ]) > max) {
201 max = std::abs(m_vars[(nodex * m_ny + nodey) * m_nv + var ]);
207 D_complex factor(m_vars[(max_nx * m_ny + max_ny) * m_nv + var ]);
209 m_vars.scale(1./factor);
215 dump.open(filename.c_str());
216 if(dump.good() !=
true) {
218 problem =
" The TwoD_Node_Mesh.read method is trying to read a \n";
219 problem +=
" file (" + filename +
") that doesn't exist.\n";
223 dump.setf(std::ios::showpoint);
224 dump.setf(std::ios::showpos);
225 dump.setf(std::ios::scientific);
226 for(std::size_t i = 0; i < m_nx; ++i) {
227 for(std::size_t j = 0; j < m_ny; ++j) {
231 for(std::size_t var = 0; var < m_nv; ++var) {
234 m_vars[(i * m_ny + j) * m_nv + var ] = value;
238 if((std::fabs(x - m_X[ i ]) > 1.e-6) || (std::fabs(y - m_Y[ j ]) > 1.e-6)) {
239 std::cout <<
" Read x = " << x <<
" Expected x = " << m_X[ i ] <<
"; Read y = " << y <<
" Expected y = " << m_Y[ j ] <<
" \n";
240 std::cout <<
" Absolute differences are " << fabs(x - m_X[i]) <<
" and " << fabs(y - m_Y[j]) <<
"\n";
242 problem =
" The TwoD_Node_Mesh.read method is trying to read a \n";
243 problem +=
" file whose nodal points are in a different position. \n";
258 dump.open(filename.c_str());
260 dump.setf(std::ios::showpoint);
261 dump.setf(std::ios::showpos);
262 dump.setf(std::ios::scientific);
266 for(std::size_t i = 0; i < m_nx; ++i) {
267 for(std::size_t j = 0; j < m_ny; ++j) {
271 for(std::size_t var = 0; var < m_nv; ++var) {
272 double value_r, value_i;
275 m_vars[(i * m_ny + j) * m_nv + var ] =
D_complex(value_r, value_i);
279 if((std::fabs(x - m_X[ i ]) > 1.e-6) || (std::fabs(y - m_Y[ j ]) > 1.e-6)) {
280 std::cout <<
" Read x = " << x <<
" Expected x = " << m_X[ i ] <<
"; Read y = " << y <<
" Expected y = " << m_Y[ j ] <<
" \n";
281 std::cout <<
" Absolute differences are " << fabs(x - m_X[i]) <<
" and " << fabs(y - m_Y[j]) <<
"\n";
283 problem =
" The TwoD_Node_Mesh.read method is trying to read a \n";
284 problem +=
" file whose nodal points are in a different position. \n";
300 dump.open(filename.c_str());
302 dump.setf(std::ios::showpoint);
303 dump.setf(std::ios::showpos);
304 dump.setf(std::ios::scientific);
306 for(std::size_t i = 0; i < m_nx; ++i) {
307 for(std::size_t j = 0; j < m_ny; ++j) {
308 dump << m_X[ i ] <<
" " << m_Y[ j ] <<
" ";
309 for(std::size_t var = 0; var < m_nv; ++var) {
310 dump << m_vars[(i * m_ny + j) * m_nv + var ] <<
" ";
322 dump.open(filename.c_str());
324 dump.setf(std::ios::showpoint);
325 dump.setf(std::ios::showpos);
326 dump.setf(std::ios::scientific);
328 for(std::size_t i = 0; i < m_nx; ++i) {
329 for(std::size_t j = 0; j < m_ny; ++j) {
330 dump << m_X[ i ] <<
" " << m_Y[ j ] <<
" ";
331 for(std::size_t var = 0; var < m_nv; ++var) {
332 dump << real(m_vars[(i * m_ny + j) * m_nv + var ]) <<
" ";
333 dump << imag(m_vars[(i * m_ny + j) * m_nv + var ]) <<
" ";
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 mapped mesh object.
A spec for a collection of utility functions.
An DenseVector class – a dense vector object.
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 (mapped) mesh utility object.
void read(std::string filename, const bool reset=false)
A simple method for reading data from a file.
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).
DenseVector< double > & xnodes()
Access the vector of x-nodal positions.
std::pair< double, double > get_comp_step_sizes() const
void init_mapping()
Sometimes a useful mapping is painful to invert analytically.
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 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< std::size_t, std::size_t > get_nnodes() const
Get the number of nodes in the two directions of the 2D mesh.
void normalise(const std::size_t &var)
Normalise all data in the mesh based on one variable.
DenseVector< double > & ynodes()
Access the vector of y-nodal positions.
std::size_t get_nvars() const
Get the number of variables that are stored at each node.
void dump_gnu(std::string filename) const
A simple method for dumping data to a file for gnuplot surface plotting.
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.
DenseVector< double > uniform_node_vector(const double &lower, const double &upper, const std::size_t &N)
Return a DENSE vector with the nodal points of a uniform mesh distributed between the upper/lower bou...
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.