CppNoddy  0.92
Loading...
Searching...
No Matches
TwoD_TVDLF_Mesh.h
Go to the documentation of this file.
1/// \file TwoD_TVDLF_Mesh.h
2/// Specification of an object that represents a two dimensional
3/// mesh for TVD LF methods.
4
5#ifndef TWOD_TVDLF_MESH_H
6#define TWOD_TVDLF_MESH_H
7
8#include <vector>
9#include <fstream>
10#include <limits>
11#include <cassert>
12
13#include <Types.h>
14#include <TwoD_TVDLF_Elt.h>
16
17namespace CppNoddy {
18
20 protected:
21 /// iterators for the vector of elements
22 typedef std::vector<TwoD_TVDLF_Elt> vector_of_elts;
23 typedef vector_of_elts::const_iterator celt_iter;
24 typedef vector_of_elts::iterator elt_iter;
25
26 typedef std::vector<TwoD_TVDLF_Elt*> vector_of_boundary_elts;
27 typedef vector_of_boundary_elts::iterator bdry_elt_iter;
28
29 /// function pointer used in the initial conditions
30 typedef void (*fn_ptr)(const double&, const double&, DenseVector<double>&);
31
32 public:
33
34 /// Constructor for the Finite Volume Mesh using linear elements
35 /// \param X A vector of nodal locations at which the element
36 /// FACES will positioned
37 /// \param Y A vector of nodal locations at which the element
38 /// FACES will positioned
39 /// \param ptr A pointer to the hyperbolic system applied to this mesh
40 /// \param init_ptr A pointer to a function that defines the initial conditions
43 fn_ptr init_ptr);
44
45 /// Empty desctructor
46 virtual ~TwoD_TVDLF_Mesh();
47
48 /// Dump the data to a given filename in a gnuplot format
49 /// \param filename The filename to be generated
50 void dump_gnu(std::string filename);
51
52 /// Dump the x-nodal positions to a given filename.
53 /// This method only applies to regular structured meshes.
54 /// \param filename The filename to be generated
55 void dump_nodes_x(std::string filename) const;
56
57 /// Dump the y-nodal positions to a given filename.
58 /// This method only applies to regular structured meshes.
59 /// \param filename The filename to be generated
60 void dump_nodes_y(std::string filename) const;
61
62 /// Dump the data over the nodal positions to a given filename.
63 /// \param filename The filename to be generated
64 void dump_data(std::string filename);
65
66 /// Set the limiter type to be applied in the slope values.
67 /// \param id The identifier of the limiter.
68 void set_limiter(const unsigned& id);
69
70 /// Update the mesh object. A time step is chosen based upon
71 /// the CFL constraint.
72 /// \param CFL The CFL constraint for the timestep (e.g. 0.49)
73 /// \param max_dt A maximum timestep to be taken irrespective of the CFL value
74 /// \return The total timestep that was taken
75 double update(const double& CFL, const double& max_dt = std::numeric_limits<long double>::max());
76
77 /// Update the mesh object to a set time level. A time step is chosen based upon
78 /// the CFL constraint.
79 /// \param CFL The CFL constraint for the timestep (e.g. 0.49)
80 /// \param t_end The target end time.
81 void update_to(const double& CFL, const double& t_end);
82
83 /// Integrate the concentration values across the entire mesh.
84 /// \param mesh_colour The identifier of which mesh to integrate over
85 /// \return The vector value of the integral
86 DenseVector<double> integrate(std::string mesh_colour = "black");
87
88 /// Given a global coordinate, return a pointer to the elt that contains
89 /// that point. Because the elts are stored in a vector, and are logically
90 /// in a rectangular grid, we first hunt for the column, then the appropriate
91 /// row.
92 /// \param x A vector global coordinate
93 /// \param mesh_colour A string identifier of the mesh to be searched
94 /// \return A pointer to the element containing the global coordinate
95 elt_iter get_elt_iter_from_x(const DenseVector<double>& x, std::string mesh_colour = "black");
96
97
98 /// Get the vector of unknowns at a point in the 2D mesh.
99 /// \param x The global coordinate at which to return the values
100 /// \return The vector of unknowns
102
103 /// Get a const reference to the time value for the current mesh.
104 /// \return time The time level at which the data in the mesh applies.
105 const double& get_time() const;
106
107 /// A virtual method that is run before the first time update.
108 /// For user-custom problems.
109 /// \param time_step The time step size that is about to be taken
110 virtual void actions_before_time_step1(const double& time_step) {
111 // Empty by default. If you want to take actions before the time
112 // step then you need to inherit from this basic mesh and implement
113 // this method.
114 }
115
116 /// A virtual method that is run before the second time update.
117 /// For user-custom problems.
118 /// \param time_step The time step size that is about to be taken
119 virtual void actions_before_time_step2(const double& time_step) {
120 // Empty by default. If you want to take actions before the time
121 // step then you need to inherit from this basic mesh and implement
122 // this method.
123 }
124
125 /// An STL vector of linear elements -- the black mesh
127 /// An STL vector of linear elements -- the red mesh
129
130 protected:
131
132 /// Given an element in the INITIAL STRUCTURED MESH, this
133 /// method will return an iterator to an element in the other mesh
134 /// that overlaps the corner specified by corner_index.
135 /// \param e An element iterator to the source element
136 /// \param target_colour The colour of the target mesh, ie. NOT the one that iterator 'e' is in
137 /// \param corner_index The index of the corner to be considered
138 /// 0,1,2,3 for SW, SE, NE, NW.
140 std::string target_colour,
141 int corner_index) {
142 // for corners SW,SE,NE,NW:
143 // black (i,j) -> red (i,j),(i+1,j),(i+1,j+1),(i,j+1)
144 // => j*Bx+i -> j*Rx+i etc
145 // red (i,j) -> black (i-1,j-1),(i,j-1),(i,j),(i-1,j)
146 // => j*Rx+i -> (j-1)*Bx+i-1 etc
147 //dimensions of the Black (Bx times By) & Red (Rx times Ry) meshes
148 //
149 vector_of_elts* target_elts(NULL);
150 int k(0);
151 int Bx(NX - 1);
152 int By(NY - 1);
153 int Rx(NX);
154 int Ry(NY);
155 //
156 if(target_colour == "red") {
157 int offset(e - BLACK_ELTS.begin());
158 target_elts = &RED_ELTS;
159 int i, j, l, m;
160 //std::cout << " offset = " << offset << "\n";
161 i = offset % Bx;
162 j = (offset - i) / Bx;
163 switch(corner_index) {
164 case 0:
165 l = i;
166 m = j;
167 break;
168 case 1:
169 l = i + 1;
170 m = j;
171 break;
172 case 2:
173 l = i + 1;
174 m = j + 1;
175 break;
176 case 3:
177 l = i;
178 m = j + 1;
179 break;
180 default:
181 l = 0;
182 m = 0;
183 assert(false);
184 }
185 // dont return outside the mesh
186 //std::cout << source_colour << " " << i << "," << j << " -> " << l << "," << m <<"\n";
187 l = std::min(l, Rx);
188 l = std::max(l, 0);
189 m = std::min(m, Ry);
190 m = std::max(m, 0);
191 k = m * Rx + l;
192 //std::cout << source_colour << " " << i << "," << j << " -> " << l << "," << m <<"\n";
193 //std::cout << "--\n";
194 } else if(target_colour == "black") {
195 int offset(e - RED_ELTS.begin());
196 target_elts = &BLACK_ELTS;
197 int i, j, l, m;
198 i = offset % Rx;
199 j = (offset - i) / Rx;
200 switch(corner_index) {
201 case 0:
202 l = i - 1;
203 m = j - 1;
204 break;
205 case 1:
206 l = i;
207 m = j - 1;
208 break;
209 case 2:
210 l = i;
211 m = j;
212 break;
213 case 3:
214 l = i - 1;
215 m = j;
216 break;
217 default:
218 l = 0;
219 m = 0;
220 assert(false);
221 }
222 // dont return outside the mesh
223 l = std::min(l, Bx);
224 l = std::max(l, 0);
225 m = std::min(m, By);
226 m = std::max(m, 0);
227 k = m * Bx + l;
228 } else {
229 // throw
230 }
231 return target_elts -> begin() + k;
232 }
233
234 /// Given a choice of black or red mesh, return a pointer
235 /// to the appropriate vector of elements.
236 /// \param mesh_colour A mesh identifier (black or red)
237 /// \return A pointer to a std::vector of elements
238 vector_of_elts* get_elts_from_colour(std::string mesh_colour);
239
240 /// Given a choice of black or red mesh, return the number
241 /// of elements in the x-direction.
242 /// \param mesh_colour A mesh identifier (black or red)
243 /// \return The number of elts in the x-direction
244 std::size_t get_number_elts_in_x(std::string mesh_colour);
245
246 /// Use the appropriate limiter to approximate the slope in each
247 /// element in the mesh. The slopes will be sent down to the element
248 /// objects and then onto the face objects.
249 /// \param elt_vector The vector of elements to set the slope for
250 void calc_slopes(vector_of_elts* elt_vector);
251
252 /// Compute a finite difference approximation of the derivative in the
253 /// compass direction.
254 /// \param e The iterator to the element that we want the derivative for
255 /// \return The spatial derivative of the vector system
257
258 /// Compute a finite difference approximation of the derivative in the
259 /// compass direction.
260 /// \param e The iterator to the element that we want the derivative for
261 /// \return The spatial derivative of the vector system
263
264 /// Compute a finite difference approximation of the derivative in the
265 /// compass direction.
266 /// \param e The iterator to the element that we want the derivative for
267 /// \return The spatial derivative of the vector system
269
270 /// Compute a finite difference approximation of the derivative in the
271 /// compass direction.
272 /// \param e The iterator to the element that we want the derivative for
273 /// \return The spatial derivative of the vector system
275
276 /// Compute a finite difference approximation of the derivative in the
277 /// compass direction.
278 /// \param e The iterator to the element that we want the derivative for
279 /// \return The spatial derivative of the vector system
281
282 /// Compute a finite difference approximation of the derivative in the
283 /// compass direction.
284 /// \param e The iterator to the element that we want the derivative for
285 /// \return The spatial derivative of the vector system
287
288 /// Sign of a double.
289 /// \param a The value to return the sign of
290 /// \return The sign of the value
291 int sgn(double a) const;
292
293 /// A vector version of the minmod operator
294 /// \param A A vector to compare
295 /// \param B A vector to compare
296 /// \return A component-wise minmod vector, i.e., each component
297 /// of the returned vector is the minmod of the components of A & B.
299
300 /// A vector version of the maxmod operator
301 /// \param A A vector to compare
302 /// \param B A vector to compare
303 /// \return A component-wise maxmod vector, i.e., each component
304 /// of the returned vector is the maxmod of the components of A & B.
306
307 /// Given an element iterator and the local coordinate this
308 /// will return zero for any components specified as inflow
309 /// boundary conditions in line with Levy & Tadmor (1997) and
310 /// set the centre nodal value to the edge value.
311 /// \param e Element iterator
312 /// \param face_index The index of the face that is on a boundary
313 /// \param diff A vector of derivatives
314 void boundary_diff(elt_iter e, const int& face_index, DenseVector<double>& diff) const;
315
316 /// Loops over all boundary elements and sets the Q values in each
317 /// one to be the value specified by the edge_values method.
318 /// \param elts A vector of elements in the mesh
320 // loop over all elts
321 elt_iter e(elts -> begin());
322 while(e != elts -> end()) {
323 // find the external elts that are on the boundary
324 if(e -> get_external_flag()) {
325 std::set<int> faces(e -> get_external_faces());
326 std::set<int>::iterator i(faces.begin());
327 // loop through all external faces (there are 2 on corner elts)
328 while(i != faces.end()) {
329 int face(*i);
330 // local coordinate at which to impose the BC
331 DenseVector<double> s(2, 0.0);
332 switch(face) {
333 case 0:
334 s[ 0 ] = 0.0;
335 s[ 1 ] = -1.0;
336 break;
337 case 1:
338 s[ 0 ] = 1.0;
339 s[ 1 ] = 0.0;
340 break;
341 case 2:
342 s[ 0 ] = 0.0;
343 s[ 1 ] = 1.0;
344 break;
345 case 3:
346 s[ 0 ] = -1.0;
347 s[ 1 ] = 0.0;
348 break;
349 }
350 // get the current edge data
351 DenseVector<double> Qe(e -> get_Q(s));
352 //// initialise the normal slope vector
353 // DenseVector<double> sigma_n( ORDER_OF_SYSTEM, 0.0 );
354 // get the user specified edge values
355 std::vector<bool> inflow = e -> p_system -> edge_values(face, e -> get_x(s), Qe); //, sigma_n );
356 // get the mid-element nodal data
357 DenseVector<double> Qm(e -> get_Q_mid());
358 for(std::size_t j = 0; j < ORDER_OF_SYSTEM; ++j) {
359 if(inflow[ j ] == true) {
360 // only change components that are inflow
361 Qm[ j ] = Qe[ j ];
362 }
363 }
364 e -> set_Q_mid(Qm);
365 ++i;
366 }
367 }
368 ++e;
369 }
370 }
371
372 /// Slope limiter method
373 unsigned LIMITER;
374 /// order of the conservative system
375 std::size_t ORDER_OF_SYSTEM;
376 /// number of faces in the x & y directions
377 std::size_t NX, NY;
378 /// the time level of the mesh
379 double MESH_TIME;
380 /// function pointer to a funnction that defines the initial distribution
382
383 };
384
385}
386
387#endif // end OneD_TVDLF_Mesh_H
Specification of a two dimensional linear element for use in a TVD Lax-Friedrichs scheme.
Some standard typedefs.
An DenseVector class – a dense vector object.
Definition: DenseVector.h:34
A class to represent a two-dimensional hyperbolic system of equations.
vector_of_elts * get_elts_from_colour(std::string mesh_colour)
Given a choice of black or red mesh, return a pointer to the appropriate vector of elements.
vector_of_elts RED_ELTS
An STL vector of linear elements – the red mesh.
virtual void actions_before_time_step1(const double &time_step)
A virtual method that is run before the first time update.
DenseVector< double > get_point_values(const DenseVector< double > &x)
Get the vector of unknowns at a point in the 2D mesh.
std::size_t get_number_elts_in_x(std::string mesh_colour)
Given a choice of black or red mesh, return the number of elements in the x-direction.
void dump_gnu(std::string filename)
Dump the data to a given filename in a gnuplot format.
DenseVector< double > minmod(DenseVector< double > A, DenseVector< double > B) const
A vector version of the minmod operator.
void calc_slopes(vector_of_elts *elt_vector)
Use the appropriate limiter to approximate the slope in each element in the mesh.
vector_of_boundary_elts::iterator bdry_elt_iter
DenseVector< double > integrate(std::string mesh_colour="black")
Integrate the concentration values across the entire mesh.
void update_to(const double &CFL, const double &t_end)
Update the mesh object to a set time level.
unsigned LIMITER
Slope limiter method.
DenseVector< double > EW_diff(elt_iter e)
Compute a finite difference approximation of the derivative in the compass direction.
DenseVector< double > west_diff(elt_iter e) const
Compute a finite difference approximation of the derivative in the compass direction.
DenseVector< double > east_diff(elt_iter e) const
Compute a finite difference approximation of the derivative in the compass direction.
DenseVector< double > south_diff(elt_iter e) const
Compute a finite difference approximation of the derivative in the compass direction.
void(* fn_ptr)(const double &, const double &, DenseVector< double > &)
function pointer used in the initial conditions
void dump_data(std::string filename)
Dump the data over the nodal positions to a given filename.
void boundary_diff(elt_iter e, const int &face_index, DenseVector< double > &diff) const
Given an element iterator and the local coordinate this will return zero for any components specified...
vector_of_elts BLACK_ELTS
An STL vector of linear elements – the black mesh.
elt_iter get_elt_iter_from_elt_iter(elt_iter e, std::string target_colour, int corner_index)
Given an element in the INITIAL STRUCTURED MESH, this method will return an iterator to an element in...
std::vector< TwoD_TVDLF_Elt * > vector_of_boundary_elts
fn_ptr p_Q_INIT
function pointer to a funnction that defines the initial distribution
std::size_t ORDER_OF_SYSTEM
order of the conservative system
int sgn(double a) const
Sign of a double.
void set_boundary_Q(vector_of_elts *elts)
Loops over all boundary elements and sets the Q values in each one to be the value specified by the e...
const double & get_time() const
Get a const reference to the time value for the current mesh.
vector_of_elts::const_iterator celt_iter
void dump_nodes_y(std::string filename) const
Dump the y-nodal positions to a given filename.
double update(const double &CFL, const double &max_dt=std::numeric_limits< long double >::max())
Update the mesh object.
DenseVector< double > NS_diff(elt_iter e)
Compute a finite difference approximation of the derivative in the compass direction.
DenseVector< double > maxmod(DenseVector< double > A, DenseVector< double > B) const
A vector version of the maxmod operator.
void dump_nodes_x(std::string filename) const
Dump the x-nodal positions to a given filename.
std::size_t NX
number of faces in the x & y directions
DenseVector< double > north_diff(elt_iter e) const
Compute a finite difference approximation of the derivative in the compass direction.
virtual ~TwoD_TVDLF_Mesh()
Empty desctructor.
void set_limiter(const unsigned &id)
Set the limiter type to be applied in the slope values.
double MESH_TIME
the time level of the mesh
virtual void actions_before_time_step2(const double &time_step)
A virtual method that is run before the second time update.
vector_of_elts::iterator elt_iter
std::vector< TwoD_TVDLF_Elt > vector_of_elts
iterators for the vector of elements
elt_iter get_elt_iter_from_x(const DenseVector< double > &x, std::string mesh_colour="black")
Given a global coordinate, return a pointer to the elt that contains that point.
A collection of OO numerical routines aimed at simple (typical) applied problems in continuum mechani...

© 2012

R.E. Hewitt