CppNoddy  0.92
Loading...
Searching...
No Matches
TwoD_TVDLF_Elt.h
Go to the documentation of this file.
1/// \file TwoD_TVDLF_Elt.h
2/// Specification of a two dimensional linear element for
3/// use in a TVD Lax-Friedrichs scheme.
4
5#ifndef TWOD_TVDLF_ELT_H
6#define TWOD_TVDLF_ELT_H
7
8#include <list>
9#include <set>
10#include <algorithm>
11
13
14//#define DEBUG
15
16namespace CppNoddy {
17
18 /// A Linear Element class.
20
21 typedef std::vector<TwoD_TVDLF_Elt> vector_of_elts;
22 typedef vector_of_elts::const_iterator celt_iter;
23 typedef vector_of_elts::iterator elt_iter;
24
25 /// A contributory element's data in the projection scheme.
26 struct contribution {
27 TwoD_TVDLF_Elt* elt_ptr;
29 std::set< int > face_indices;
30 };
31
32 public:
33
34 /// Construct a linear rectangular element
35 /// \param west The western face location
36 /// \param east The eastern face location
37 /// \param south The western face location
38 /// \param north The eastern face location
39 /// \param ptr A pointer to the hyperbolic system
40 /// \param flag A boolean indicator to specify an elt with an external face
41 /// \param faces A set of indices of the external faces
42 TwoD_TVDLF_Elt(double west, double east,
43 double south, double north,
45 bool flag = false, std::set<int> faces = std::set<int>());
46
47 /// An empty destructor
49
50 /// Test to see if a face index of an element is external to the mesh.
51 /// \param index The face index to test (0,1,2,3) for (S,E,N,W)
52 /// \return True if the face is external to the mesh.
53 bool face_is_external(const int& index) const;
54
55 /// Test to see if a face index of an element is internal to the mesh.
56 /// \param index The face index to test (0,1,2,3) for (S,E,N,W)
57 /// \return True if the face is internal to the mesh.
58 bool face_is_internal(const int& index) const;
59
60 /// Each element stores pointers to any adjacent elements in the
61 /// four compass directions 0,1,2,3 for S,E,N,W
62 /// \param index The index of the direction to set the pointer for
63 /// \param ptr A pointer to the element in the chosen direction
64 void set_ptrs(const int& index, TwoD_TVDLF_Elt* ptr);
65
66 /// Return a pointer to an element in the given compass direction
67 /// \param index The appropriate index of the direction 0,1,2,3 for
68 /// S,E,N,W
69 /// \return The pointer to the element
70 TwoD_TVDLF_Elt* get_ptrs(const int& index) const;
71
72 /// Add a contribution to this element from another element.
73 /// \param ptr A pointer to the element that contributes to this one
74 /// \param sw The SW local coordinate in the contributory element
75 /// \param ne The NE local coordinate in the contributory element
76 /// \param indices A set of indices of faces that this element contributes to
78 const DenseVector<double>& sw,
79 const DenseVector<double>& ne,
80 std::set< int > indices);
81
82 /// Dump the details of this element.
83 void dump() const;
84
85 /// Reset the contributions to this element.
87
88 /// Find the integral contributions to this black/red element from the
89 /// corresponding contributing red/black element.
90 /// \return The integrated value of all components
92
93 /// Adds the contribution of each face's flux to the correction
94 /// for this element unless it has already been added by a flux
95 /// computation across the same face in an adjacent elt.
96 /// \param dt The time step over which the flux is to be computed
97 void add_flux_contributions(const double& dt);
98
99 /// Compute the flux into this element across the western face.
100 /// \param dt The time step over which the flux is to be computed
101 /// \param flux_in_west A vector flux that is overwritten by this method
102 /// and returned containing the appropriate flux values.
103 void contributed_flux_in_west(const double &dt, DenseVector<double> &flux_in_west);
104
105 /// Compute the flux into this element across the southern face.
106 /// \param dt The time step over which the flux is to be computed
107 /// \param flux_in_south A vector flux that is overwritten by this method
108 /// and returned containing the appropriate flux values.
109 void contributed_flux_in_south(const double &dt, DenseVector<double> &flux_in_south);
110
111 /// Compute the flux out of this element across the eastern face.
112 /// \param dt The time step over which the flux is to be computed
113 /// \param flux_out_east A vector flux that is overwritten by this method
114 /// and returned containing the appropriate flux values.
115 void contributed_flux_out_east(const double &dt, DenseVector<double> &flux_out_east);
116
117 /// Compute the flux out of this element across the northern face.
118 /// \param dt The time step over which the flux is to be computed
119 /// \param flux_out_north A vector flux that is overwritten by this method
120 /// and returned containing the appropriate flux values.
121 void contributed_flux_out_north(const double &dt, DenseVector<double> &flux_out_north);
122
123 /// Get the local coordinate that corresponds to a given global coordinate.
124 /// If the global coordinate is outside this element, an exception is thrown.
125 /// \param x The global coordinate
126 /// \return The local coordinate
128
129 /// Get the global position of a local coordinate in this element.
130 /// \param s The local coordinate
131 /// \return The global position
133
134 /// Get the global position of a central node in this element.
135 /// \return The global position of the central node
137
138 /// Get the size of the element as a vector (delta_x, delta_y).
139 /// \return The separation of the rectangles faces (delta_x, delta_y)
141
142 /// Get the area of the element
143 /// \return The area of the element
144 double get_dA() const;
145
146 /// Set the external flag.
147 /// \param flag is the value to set
148 void set_external_flag(bool flag);
149
150 /// Get the external flag.
151 /// \return The value of the flag (true if this is an elt with an external face)
152 bool get_external_flag() const;
153
154 /// Get a set of indices of faces that are external
155 /// \return A set of integers (0,1,2,3 for south, east, north, west)
156 /// indicating which faces are external.
157 std::set<int> get_external_faces() const;
158
159 /// Get the value of the 'concentration' stored in this element.
160 /// \param s The local coordinate in the elt at which Q is requested
161 /// \return The concentration value of the elt for each component
163
164 /// Get the integral of Q over a sub-element
165 /// \param sw A vector containing the SW local coordinates
166 /// \param ne A vector containing the NE local coordinates
167 /// \return The integral of the concentration over the local range
169
170 /// Add an external face to the stored stl::set.
171 /// \param i The index of the external face 0,1,2,3 for S,E,N,W.
172 void add_external_face(const int& i);
173
174 /// Remove an external face to the stored stl::set.
175 /// \param i The index of the external face 0,1,2,3 for S,E,N,W.
176 void remove_external_face(const int& i);
177
178 /// Set the value of the vector 'concentration' stored in this
179 /// element. To second order, this is the value of the
180 /// concentration at the mid-point of the element.
181 /// \param value The vector value to be assigned to the
182 /// concentration member data Q
183 void set_Q_mid(const DenseVector<double>& value);
184
185 /// Get the nodal concentration
186 /// \return The concentration at the central node
188
189 /// Set the x-slope vector for this element.
190 /// \param value The slope vector to be set
191 void set_slope_x(const DenseVector<double>& value);
192
193 /// Set the y-slope vector for this element.
194 /// \param value The slope vector to be set
195 void set_slope_y(const DenseVector<double>& value);
196
197 /// The concentration is approximated by a linear function
198 /// in each element. The slope of this function in the x-direction
199 /// is found through this method.
200 /// \return The value of the 'slope_x' member data
202
203 /// The concentration is approximated by a linear function
204 /// in each element. The slope of this function in the y-direction
205 /// is found through this method.
206 /// \return The value of the 'slope_x' member data
208
209 /// Get the Taylor series expansion of the concentration
210 /// for a given time step and local coordinate for this element
211 /// \param s The local coordinate
212 /// \param dt The time step
213 DenseVector<double> get_Q_Taylor_series(const DenseVector<double> &s, const double &dt) const;
214
215 /// Evaluate the contribution to this element by the hyperbolic
216 /// system's source function over a given time step using a
217 /// mid-point in time evaluation.
218 /// \param dt The time step over which source function is to be integrated
219 /// \return The total contribution
220 DenseVector<double> get_source_contribution(const double &dt) const;
221
222 /// Get the maximum allowable time step for this element by using
223 /// information about the size of the element and the maximum wave
224 /// speed set in the conservative system. The time step is guranteed
225 /// to satisfy the CFL < 0.5 constraint in the two principle directions.
226 /// \return The maximum time step for this element
227 double get_max_dt() const;
228
229 /// Get the flux function in the x direction evaluated for
230 /// the concentration value stored in this elt.
231 /// \param s The local vector coordinate at which to evaluate
232 /// \return The flux function vector
234 DenseVector<double> f(p_system -> get_order(), 0.0);
235 p_system -> flux_fn_x(get_x(s), get_Q(s), f);
236 return f;
237 }
238
239 /// Get the flux function in the y direction evaluated for
240 /// the concentration value stored in this elt.
241 /// \param s The local vector coordinate at which to evaluate
242 /// \return The flux function vector
244 DenseVector<double> g(p_system -> get_order(), 0.0);
245 p_system -> flux_fn_y(get_x(s), get_Q(s), g);
246 return g;
247 }
248
249 /// Get the Jacobian of the x flux function evaluated for the
250 /// concentration value stored in this elt.
251 /// \param s The local coordinate at which to evaluate
252 /// \return The Jacobian matrix
254 DenseMatrix<double> J(p_system -> get_order(), p_system -> get_order(), 0.0);
255 p_system -> Jac_flux_fn_x(get_x(s), get_Q(s), J);
256 return J;
257 }
258
259 /// Get the Jacobian of the y flux function evaluated for the
260 /// concentration value stored in this elt.
261 /// \param s The local coordinate at which to evaluate
262 /// \return The Jacobian matrix
264 DenseMatrix<double> J(p_system -> get_order(), p_system -> get_order(), 0.0);
265 p_system -> Jac_flux_fn_y(get_x(s), get_Q(s), J);
266 return J;
267 }
268
269
270 /// Get the source function evaluated for the
271 /// concentration value stored in this elt
272 /// \param s The local coordinate at which to evaluate
273 /// \return The source function value
275 DenseVector<double> r(p_system -> get_order(), 0.0);
276 p_system -> source_fn(get_x(s), get_Q(s), r);
277 return r;
278 }
279
280
282
283 private:
284
285 /// Since any face is common to at least two elements this
286 /// is a private method that allows any element to set a
287 /// flux contribution in another (adjacent) elt.
288 /// \param face_index The index (0,1,2,3) of the face that this
289 /// contribution is for
290 /// \param dq The contribution to be made
291 void add_to_delta_Q(const int& face_index, const DenseVector<double>& dq);
292
293 /// a list of elts that contribute to this one
294 std::list< contribution > CONT_LIST;
295 /// the concentration at the center of this elt
297 /// the 2 slopes for this elt
298 DenseVector<double> SLOPE_X;
299 DenseVector<double> SLOPE_Y;
300 /// keep track of the flux into the elt so far
301 DenseVector<double> DELTA_Q;
302 /// the global coordinates of the 4 faces
303 double SOUTH, WEST;
304 /// elt sizes
305 double DX, DY;
306 /// a vector of iterators to neighbouring elts
307 std::vector< TwoD_TVDLF_Elt* > p_ELTS;
308 /// a set of indices of external faces
309 std::set<int> EXTERNAL_FACES;
310 /// a vector of booleans that are set when a face's flux contribution has
311 /// been computed
312 std::vector<bool> FLUX_FACE_DONE;
313 /// a boolean to indicate that this elt has external faces
314 bool EXTERNAL;
315
316 };
317
318 // used too many times for inlining apparently
320 return Q + (SLOPE_X * s[ 0 ] * DX
321 + SLOPE_Y * s[ 1 ] * DY) / 2;
322 }
323
325 Q = value;
326 }
327
329 return Q;
330 }
331
333 SLOPE_X = value;
334 }
335
337 SLOPE_Y = value;
338 }
339
341 return SLOPE_X;
342 }
343
345 return SLOPE_Y;
346 }
347
349 const double sub_dx(DX * (s_ne[ 0 ] - s_sw[ 0 ]) / 2);
350 const double sub_dy(DY * (s_ne[ 1 ] - s_sw[ 1 ]) / 2);
351 return get_Q((s_ne + s_sw) / 2) * sub_dx * sub_dy;
352 }
353
354 inline double TwoD_TVDLF_Elt::get_max_dt() const {
355 DenseVector<double> c(2, 0.0);
356 DenseVector<double> s(2, 0.0);
357 p_system -> max_charac_speed(get_x(s), get_Q_mid(), c);
358 return std::min(DX / c[ 0 ], DY / c[ 1 ]);
359 }
360
361} // CppNoddy namespace
362
363#endif // TwoD_TVDLF_Elt_H
@ f
Definition: BVPBerman.cpp:15
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
A class to represent a two-dimensional hyperbolic system of equations.
A Linear Element class.
void set_external_flag(bool flag)
Set the external flag.
void clear_contributions()
Reset the contributions to this element.
void set_slope_x(const DenseVector< double > &value)
Set the x-slope vector for this element.
void set_ptrs(const int &index, TwoD_TVDLF_Elt *ptr)
Each element stores pointers to any adjacent elements in the four compass directions 0,...
double get_max_dt() const
Get the maximum allowable time step for this element by using information about the size of the eleme...
DenseVector< double > get_source_fn(const DenseVector< double > &s) const
Get the source function evaluated for the concentration value stored in this elt.
void dump() const
Dump the details of this element.
DenseVector< double > get_flux_fn_y(const DenseVector< double > &s) const
Get the flux function in the y direction evaluated for the concentration value stored in this elt.
DenseVector< double > get_slope_x() const
The concentration is approximated by a linear function in each element.
DenseVector< double > get_x(DenseVector< double > s) const
Get the global position of a local coordinate in this element.
double get_dA() const
Get the area of the element.
DenseVector< double > get_Q_mid() const
Get the nodal concentration.
DenseVector< double > get_flux_fn_x(const DenseVector< double > &s) const
Get the flux function in the x direction evaluated for the concentration value stored in this elt.
void add_external_face(const int &i)
Add an external face to the stored stl::set.
DenseVector< double > get_Q(const DenseVector< double > &s) const
Get the value of the 'concentration' stored in this element.
DenseMatrix< double > get_Jac_flux_fn_x(const DenseVector< double > &s) const
Get the Jacobian of the x flux function evaluated for the concentration value stored in this elt.
bool get_external_flag() const
Get the external flag.
bool face_is_external(const int &index) const
Test to see if a face index of an element is external to the mesh.
DenseVector< double > get_slope_y() const
The concentration is approximated by a linear function in each element.
TwoD_Hyperbolic_System * p_system
bool face_is_internal(const int &index) const
Test to see if a face index of an element is internal to the mesh.
void contributed_flux_out_north(const double &dt, DenseVector< double > &flux_out_north)
Compute the flux out of this element across the northern face.
void add_contribution(TwoD_TVDLF_Elt *ptr, const DenseVector< double > &sw, const DenseVector< double > &ne, std::set< int > indices)
Add a contribution to this element from another element.
void set_Q_mid(const DenseVector< double > &value)
Set the value of the vector 'concentration' stored in this element.
void set_slope_y(const DenseVector< double > &value)
Set the y-slope vector for this element.
DenseVector< double > get_dx() const
Get the size of the element as a vector (delta_x, delta_y).
void contributed_flux_in_west(const double &dt, DenseVector< double > &flux_in_west)
Compute the flux into this element across the western face.
DenseVector< double > get_x_mid() const
Get the global position of a central node in this element.
void add_flux_contributions(const double &dt)
Adds the contribution of each face's flux to the correction for this element unless it has already be...
DenseVector< double > get_source_contribution(const double &dt) const
Evaluate the contribution to this element by the hyperbolic system's source function over a given tim...
void contributed_flux_out_east(const double &dt, DenseVector< double > &flux_out_east)
Compute the flux out of this element across the eastern face.
std::set< int > get_external_faces() const
Get a set of indices of faces that are external.
void remove_external_face(const int &i)
Remove an external face to the stored stl::set.
DenseVector< double > get_s(const DenseVector< double > &x) const
Get the local coordinate that corresponds to a given global coordinate.
~TwoD_TVDLF_Elt()
An empty destructor.
DenseMatrix< double > get_Jac_flux_fn_y(const DenseVector< double > &s) const
Get the Jacobian of the y flux function evaluated for the concentration value stored in this elt.
void contributed_flux_in_south(const double &dt, DenseVector< double > &flux_in_south)
Compute the flux into this element across the southern face.
DenseVector< double > get_int_Q(const DenseVector< double > &sw, const DenseVector< double > &ne) const
Get the integral of Q over a sub-element.
DenseVector< double > contributed_Q() const
Find the integral contributions to this black/red element from the corresponding contributing red/bla...
DenseVector< double > get_Q_Taylor_series(const DenseVector< double > &s, const double &dt) const
Get the Taylor series expansion of the concentration for a given time step and local coordinate for t...
TwoD_TVDLF_Elt * get_ptrs(const int &index) const
Return a pointer to an element in the given compass direction.
A collection of OO numerical routines aimed at simple (typical) applied problems in continuum mechani...

© 2012

R.E. Hewitt