CppNoddy  0.92
Loading...
Searching...
No Matches
TwoD_TVDLF_Elt.cpp
Go to the documentation of this file.
1/// \file TwoD_TVDLF_Elt.cpp
2/// Implementation of an object that represents a two dimensional
3/// element for TVD LF methods.
4
5#include <vector>
6
7#include <list>
8#include <set>
9#include <algorithm>
10
12#include <TwoD_TVDLF_Elt.h>
13
14
15namespace CppNoddy {
16
17 TwoD_TVDLF_Elt::TwoD_TVDLF_Elt(double west, double east,
18 double south, double north,
20 bool flag, std::set<int> faces) {
21#ifdef DEBUG
22 std::cout << "DEBUG: Constructing a TwoD_TVDLF_Elt object over ["
23 << west << ", " << east << "] X [" << south << ", " << north << "]\n";
24#endif
25 p_system = ptr;
26 // south west corner
27 this -> WEST = west;
28 this -> SOUTH = south;
29 // lengths of the element sides
30 this -> DX = east - west;
31 this -> DY = north - south;
32 // is this an elt with an external face?
33 EXTERNAL = flag;
34 // which faces are external?
35 EXTERNAL_FACES = faces;
36 // pointers to the elements on the compass points
37 p_ELTS = std::vector<TwoD_TVDLF_Elt*>(4, this);
38 // linear reconstruction within the elt ... in 2 directions
39 SLOPE_X = DenseVector<double>(p_system -> get_order(), 0.0);
40 SLOPE_Y = DenseVector<double>(p_system -> get_order(), 0.0);
41 // the concentrations in this elt
42 Q = DenseVector<double>(p_system -> get_order(), 0.0);
43 // the corrections to be added ... built up in parts
44 DELTA_Q = DenseVector<double>(p_system -> get_order(), 0.0);
45 // no fluxes have been added to this elt
46 FLUX_FACE_DONE = std::vector<bool>(4, false);
47 }
48
50 {}
51
52 bool TwoD_TVDLF_Elt::face_is_external(const int& index) const {
53 bool found(true);
54 if(EXTERNAL_FACES.find(index) == EXTERNAL_FACES.end()) {
55 found = false;
56 }
57 return found;
58 }
59
60 bool TwoD_TVDLF_Elt::face_is_internal(const int& index) const {
61 return !face_is_external(index);
62 }
63
64 void TwoD_TVDLF_Elt::set_ptrs(const int& index, TwoD_TVDLF_Elt* ptr) {
65 p_ELTS[ index ] = ptr;
66 }
67
68 TwoD_TVDLF_Elt* TwoD_TVDLF_Elt::get_ptrs(const int& index) const {
69 return p_ELTS[ index ];
70 }
71
73 DenseVector<double> flux(p_system -> get_order(), 0.0);
74 // work out the flux into the elt
75 if(!FLUX_FACE_DONE[ 0 ]) {
77 }
78 if(!FLUX_FACE_DONE[ 1 ]) {
80 }
81 if(!FLUX_FACE_DONE[ 2 ]) {
83 }
84 if(!FLUX_FACE_DONE[ 3 ]) {
86 }
87 // evaluate the total integral over dt and divide by the area of the elt
88 DELTA_Q *= dt / (DX * DY);
89 // include the source contribution
90 DELTA_Q += get_source_contribution(dt);
91 // update the concentrations
92 Q += DELTA_Q;
93 // reset the correction to zero
94 DELTA_Q = DenseVector<double>(p_system -> get_order(), 0.0);
95 // reset the elt to having no fluxes added
96 FLUX_FACE_DONE = std::vector<bool>(4, false);
97 }
98
100 const DenseVector<double>& sw,
101 const DenseVector<double>& ne,
102 std::set< int > indices) {
103 // if any face indices are external then we ignore them
104 std::set< int > internal_indices;
105 set_difference(indices.begin(), indices.end(),
106 EXTERNAL_FACES.begin(), EXTERNAL_FACES.end(),
107 inserter(internal_indices, internal_indices.begin()));
108 // loop thru the contributions to see if it is already in there
109 std::list< contribution >::iterator c = CONT_LIST.begin();
110 bool found = false;
111 while(c != CONT_LIST.end()) {
112 if(c -> elt_ptr == ptr) {
113 found = true;
114 break;
115 } else {
116 ++c;
117 }
118 }
119 if(found) {
120 // just add face indices to the existing entry's set of faces
121 c -> face_indices.insert(internal_indices.begin(), internal_indices.end());
122 } else {
123 // we need to make a new contribution entry
124 contribution cont;
125 cont.elt_ptr = ptr;
126 cont.sw = sw;
127 cont.ne = ne;
128 cont.face_indices.insert(internal_indices.begin(), internal_indices.end());
129 // push the contribution data into a list
130 CONT_LIST.push_back(cont);
131 }
132 }
133
134 void TwoD_TVDLF_Elt::dump() const {
135 DenseVector<double> s(2, 0.0);
136 std::cout << WEST + DX / 2 << " " << SOUTH + DY / 2 << " " << get_Q(s)[0] << "\n";
137 if(EXTERNAL_FACES.find(1) != EXTERNAL_FACES.end()) {
138 std::cout << "\n";
139 }
140 }
141
143 CONT_LIST.clear();
144 }
145
147 std::list< contribution >::const_iterator c = CONT_LIST.begin();
148 // start with zero
149 DenseVector<double> sum(p_system -> get_order(), 0.0);
150 // loop over contributions
151 while(c != CONT_LIST.end()) {
152 // get integral of each
153 sum += c -> elt_ptr -> get_int_Q(c -> sw, c -> ne);
154 ++c;
155 }
156 return sum;
157 }
158
159 void TwoD_TVDLF_Elt::contributed_flux_in_west(const double &dt, DenseVector<double> &flux_in_west) {
160 DenseVector<double> flux(p_system -> get_order(), 0.0);
161 flux_in_west = DenseVector<double>(p_system -> get_order(), 0.0);
162 std::list< contribution >::iterator c = CONT_LIST.begin();
163 if(face_is_internal(3)) {
164 // loop over all contributing elements
165 while(c != CONT_LIST.end()) {
166 // true if this makes a contribution to the West face
167 if(c -> face_indices.find(3) != c -> face_indices.end()) {
168 // get the local coords in the contributing elt, but has to
169 // be at the mid-point for the y-integration
170 DenseVector<double> s_half(2, 0.0);
171 s_half[ 0 ] = c -> sw[ 0 ];
172 s_half[ 1 ] = (c -> sw[1] + c -> ne[1]) * 0.5;
173 // current concentration value at the mid-time step
174 DenseVector<double> q_half_step(c -> elt_ptr -> get_Q_Taylor_series(s_half, dt / 2));
175 // evaluate the flux at this Q value
176 c -> elt_ptr -> p_system -> flux_fn_x(c -> elt_ptr -> get_x(s_half), q_half_step, flux);
177 // the length of the elements face that this computation is over (for the y-integral)
178 const double sub_dy((c -> elt_ptr -> get_x(c -> ne) - c -> elt_ptr -> get_x(c -> sw))[1]);
179 flux_in_west += flux * sub_dy;
180 }
181 ++c;
182 }
183 // flux_in_west of this elt = flux_out_east of the elt to the west
184 p_ELTS[ 3 ] -> add_to_delta_Q(1, -flux_in_west);
185 }
186 // if we are computing the flux thru West face and it is external
187 // then we should use the user specified edge values
188 else {
189 std::list< contribution >::iterator c = CONT_LIST.begin();
190 // loop over all contributing elements
191 while(c != CONT_LIST.end()) {
192 // find any contributing elts to this external face
193 if(c -> elt_ptr -> face_is_external(3)) {
194 // get the local coords in the contributing elt, but has to
195 // be at the mid-point for the y-integration
196 DenseVector<double> s_half(2, 0.0);
197 s_half[ 0 ] = c -> sw[ 0 ];
198 s_half[ 1 ] = (c -> sw[1] + c -> ne[1]) * 0.5;
199 // global coordinate
200 const DenseVector<double> x(c -> elt_ptr -> get_x(s_half));
201 // get the concentration at the mid-time point
202 DenseVector<double> q_half_step(c -> elt_ptr -> get_Q_Taylor_series(s_half, dt / 2));
203 // at this point we have obtained the 'natural' boundary condition
204 // but we now allow the user to overwrite this using the edge_values
205 // not overwriting q_half_step means we keep the natural condition
206 p_system -> edge_values(3, x, q_half_step);
207 // evaluate the flux at this Q value
208 c -> elt_ptr -> p_system -> flux_fn_x(x, q_half_step, flux);
209 // the length of the elements face that this computation is over (for the y-integral)
210 const double sub_dy((c -> elt_ptr -> get_x(c -> ne) - c -> elt_ptr -> get_x(c -> sw))[1]);
211 flux_in_west += flux * sub_dy;
212 }
213 ++c;
214 }
215 }
216 FLUX_FACE_DONE[ 3 ] = true;
217 DELTA_Q += flux_in_west;
218 }
219
220 void TwoD_TVDLF_Elt::contributed_flux_in_south(const double &dt, DenseVector<double> &flux_in_south) {
221 DenseVector<double> flux(p_system -> get_order(), 0.0);
222 flux_in_south = DenseVector<double>(p_system -> get_order(), 0.0);
223 std::list< contribution >::iterator c = CONT_LIST.begin();
224 if(face_is_internal(0)) {
225 // loop over all contributing elements
226 while(c != CONT_LIST.end()) {
227 // true if this makes a contribution to the South face
228 if(c -> face_indices.find(0) != c -> face_indices.end()) {
229 // get the local coords in the contributing elt, but has to
230 // be at the mid-point for the x-integration
231 DenseVector<double> s_half(2, 0.0);
232 s_half[ 0 ] = (c -> sw[ 0 ] + c -> ne[ 0 ]) * 0.5;
233 s_half[ 1 ] = c -> sw[ 1 ];
234 // current concentration value at the mid-time point
235 DenseVector<double> q_half_step(c -> elt_ptr -> get_Q_Taylor_series(s_half, dt / 2));
236 // evaluate the flux at this Q value
237 c -> elt_ptr -> p_system -> flux_fn_y(c -> elt_ptr -> get_x(s_half), q_half_step, flux);
238 // the length of the elements face that this computation is over (for the x-integral)
239 const double sub_dx((c -> elt_ptr -> get_x(c -> ne) - c -> elt_ptr -> get_x(c -> sw))[0]);
240 flux_in_south += flux * sub_dx;
241 }
242 ++c;
243 }
244 // flux_in_south of this elt = flux_out_north of the elt to the south
245 p_ELTS[ 0 ] -> add_to_delta_Q(2, -flux_in_south);
246 }
247 // if we are computing the flux thru South face and it is external
248 // then we should use the user specified edge values
249 else {
250 std::list< contribution >::iterator c = CONT_LIST.begin();
251 // loop over all contributing elements
252 while(c != CONT_LIST.end()) {
253 // find any contributing elts to this external face
254 if(c -> elt_ptr -> face_is_external(0)) {
255 // get the local coords in the contributing elt, but has to
256 // be at the mid-point for the x-integration
257 DenseVector<double> s_half(2, 0.0);
258 s_half[ 0 ] = (c -> sw[ 0 ] + c -> ne[ 0 ]) * 0.5;
259 s_half[ 1 ] = c -> sw[ 1 ];
260 // global coordinate
261 const DenseVector<double> x(c -> elt_ptr -> get_x(s_half));
262 // get the concentration at the mid-time point
263 DenseVector<double> q_half_step(c -> elt_ptr -> get_Q_Taylor_series(s_half, dt / 2));
264 // at this point we have obtained the 'natural' boundary condition
265 // but we now allow the user to overwrite this using the edge_values
266 // not overwriting q_half_step means we keep the natural condition
267 p_system -> edge_values(0, x, q_half_step);
268 // evaluate the flux at this Q value
269 c -> elt_ptr -> p_system -> flux_fn_y(x, q_half_step, flux);
270 // the length of the elements face that this computation is over (for the x-integral)
271 const double sub_dx((c -> elt_ptr -> get_x(c -> ne) - c -> elt_ptr -> get_x(c -> sw))[0]);
272 flux_in_south += flux * sub_dx;
273 }
274 ++c;
275 }
276 }
277 FLUX_FACE_DONE[ 0 ] = true;
278 DELTA_Q += flux_in_south;
279 }
280
281 void TwoD_TVDLF_Elt::contributed_flux_out_east(const double &dt, DenseVector<double> &flux_out_east) {
282 DenseVector<double> flux(p_system -> get_order(), 0.0);
283 flux_out_east = DenseVector<double>(p_system -> get_order(), 0.0);
284 std::list< contribution >::iterator c = CONT_LIST.begin();
285 if(face_is_internal(1)) {
286 // loop over all contributing elements
287 while(c != CONT_LIST.end()) {
288 // true if this makes a contribution to the East face
289 if(c -> face_indices.find(1) != c -> face_indices.end()) {
290 // get the local coords in the contributing elt, but has to
291 // be at the mid-point for the y-integration
292 DenseVector<double> s_half(2, 0.0);
293 s_half[ 0 ] = c -> ne[ 0 ];
294 s_half[ 1 ] = (c -> sw[1] + c -> ne[1]) * 0.5;
295 // current concentration value at the mid-time point
296 DenseVector<double> q_half_step(c -> elt_ptr -> get_Q_Taylor_series(s_half, dt / 2));
297 // evaluate the flux at this Q value
298 c -> elt_ptr -> p_system -> flux_fn_x(c -> elt_ptr -> get_x(s_half), q_half_step, flux);
299 // the length of the elements face that this computation is over (for the y-integral)
300 const double sub_dy((c -> elt_ptr -> get_x(c -> ne) - c -> elt_ptr -> get_x(c -> sw))[1]);
301 flux_out_east += flux * sub_dy;
302 }
303 ++c;
304 }
305 // flux_out_east of this elt = flux_in_west of the elt to the west
306 p_ELTS[ 1 ] -> add_to_delta_Q(3, flux_out_east);
307 }
308 // if we are computing the flux thru East face and it is external
309 // then we should use the user specified edge values
310 else {
311 std::list< contribution >::iterator c = CONT_LIST.begin();
312 // loop over all contributing elements
313 while(c != CONT_LIST.end()) {
314 // find any contributing elts to this external face
315 if(c -> elt_ptr -> face_is_external(1)) {
316 // get the local coords in the contributing elt, but has to
317 // be at the mid-point for the y-integration
318 DenseVector<double> s_half(2, 0.0);
319 s_half[ 0 ] = c -> ne[ 0 ];
320 s_half[ 1 ] = (c -> sw[1] + c -> ne[1]) * 0.5;
321 // global coordinate
322 const DenseVector<double> x(c -> elt_ptr -> get_x(s_half));
323 // get the concentration at this point mid-time point
324 DenseVector<double> q_half_step(c -> elt_ptr -> get_Q_Taylor_series(s_half, dt / 2));
325 // at this point we have obtained the 'natural' boundary condition
326 // but we now allow the user to overwrite this using the edge_values
327 // not overwriting q_half_step means we keep the natural condition
328 p_system -> edge_values(1, x, q_half_step);
329 // evaluate the flux at this Q value
330 c -> elt_ptr -> p_system -> flux_fn_x(x, q_half_step, flux);
331 // the length of the elements face that this computation is over (for the y-integral)
332 const double sub_dy((c -> elt_ptr -> get_x(c -> ne) - c -> elt_ptr -> get_x(c -> sw))[1]);
333 flux_out_east += flux * sub_dy;
334 }
335 ++c;
336 }
337 }
338 FLUX_FACE_DONE[ 1 ] = true;
339 DELTA_Q -= flux_out_east;
340 }
341
342 void TwoD_TVDLF_Elt::contributed_flux_out_north(const double &dt, DenseVector<double> &flux_out_north) {
343 DenseVector<double> flux(p_system -> get_order(), 0.0);
344 flux_out_north = DenseVector<double>(p_system -> get_order(), 0.0);
345 std::list< contribution >::iterator c = CONT_LIST.begin();
346 if(face_is_internal(2)) {
347 // loop over all contributing elements
348 while(c != CONT_LIST.end()) {
349 // true if this makes a contribution to the North face
350 if(c -> face_indices.find(2) != c -> face_indices.end()) {
351 // get the local coords in the contributing elt, but has to
352 // be at the mid-point for the y-integration
353 DenseVector<double> s_half(2, 0.0);
354 s_half[ 0 ] = (c -> sw[ 0 ] + c -> ne[ 0 ]) * 0.5;
355 s_half[ 1 ] = c -> ne[ 1 ];
356 // current concentration value at the mid-time point
357 DenseVector<double> q_half_step(c -> elt_ptr -> get_Q_Taylor_series(s_half, dt / 2));
358 // evaluate the flux at this Q value
359 c -> elt_ptr -> p_system -> flux_fn_y(c -> elt_ptr -> get_x(s_half), q_half_step, flux);
360 // the length of the elements face that this computation is over (for the y-integral)
361 const double sub_dx((c -> elt_ptr -> get_x(c -> ne) - c -> elt_ptr -> get_x(c -> sw))[0]);
362 flux_out_north += flux * sub_dx;
363 }
364 ++c;
365 }
366 // flux_out_north of this elt = flux_in_south of the elt to the north
367 p_ELTS[ 2 ] -> add_to_delta_Q(0, flux_out_north);
368 }
369 // if we are computing the flux thru North face and it is external
370 // then we should use the user specified edge values
371 else {
372 std::list< contribution >::iterator c = CONT_LIST.begin();
373 // loop over all contributing elements
374 while(c != CONT_LIST.end()) {
375 // find any contributing elts to this external face
376 if(c -> elt_ptr -> face_is_external(2)) {
377 // get the local coords in the contributing elt, but has to
378 // be at the mid-point for the x-integration
379 DenseVector<double> s_half(2, 0.0);
380 s_half[ 0 ] = (c -> sw[ 0 ] + c -> ne[ 0 ]) * 0.5;
381 s_half[ 1 ] = c -> ne[ 1 ];
382 // global coordinate
383 const DenseVector<double> x(c -> elt_ptr -> get_x(s_half));
384 // get the concentration at this mid-time point
385 DenseVector<double> q_half_step(c -> elt_ptr -> get_Q_Taylor_series(s_half, dt / 2));
386 // at this point we have obtained the 'natural' boundary condition
387 // but we now allow the user to overwrite this using the edge_values
388 // not overwriting q_half_step means we keep the natural condition
389 p_system -> edge_values(2, x, q_half_step);
390 // evaluate the flux at this Q value
391 c -> elt_ptr -> p_system -> flux_fn_y(x, q_half_step, flux);
392 // the length of the elements face that this computation is over (for the x-integral)
393 const double sub_dx((c -> elt_ptr -> get_x(c -> ne) - c -> elt_ptr -> get_x(c -> sw))[0]);
394 flux_out_north += flux * sub_dx;
395 }
396 ++c;
397 }
398 }
399 FLUX_FACE_DONE[ 2 ] = true;
400 DELTA_Q -= flux_out_north;
401 }
402
403 void TwoD_TVDLF_Elt::add_to_delta_Q(const int& face_index, const DenseVector<double>& dq) {
404 FLUX_FACE_DONE[ face_index ] = true;
405 DELTA_Q += dq;
406 }
407
409#ifdef PARANOID
410 if((x[0] < WEST) || (x[0] > WEST + DX) || (x[1] > SOUTH + DY) || (x[1] < SOUTH)) {
411 std::string problem;
412 problem = " The TwoD_TVDLF_Elt::get_s method has been called for an element \n";
413 problem += " whose range does not bracket the given global coordinate.\n";
414 throw ExceptionRuntime(problem);
415 }
416#endif
417 DenseVector<double> s(2, 0.0);
418 s[0] = -1 + 2 * (x[0] - WEST) / DX;
419 s[1] = -1 + 2 * (x[1] - SOUTH) / DY;
420 return s;
421 }
422
424 DenseVector<double> x(2, 0.0);
425 x[ 0 ] = WEST + (s[ 0 ] + 1) * DX / 2;
426 x[ 1 ] = SOUTH + (s[ 1 ] + 1) * DY / 2;
427 return x;
428 }
429
431 DenseVector<double> x(2, 0.0);
432 x[ 0 ] = WEST + DX / 2;
433 x[ 1 ] = SOUTH + DY / 2;
434 return x;
435 }
436
438 DenseVector<double> delta(2, 0.0);
439 delta[ 0 ] = DX;
440 delta[ 1 ] = DY;
441 return delta;
442 }
443
444 double TwoD_TVDLF_Elt::get_dA() const {
445 return DX * DY;
446 }
447
449 EXTERNAL = flag;
450 }
451
453 return EXTERNAL;
454 }
455
457 return EXTERNAL_FACES;
458 }
459
461 EXTERNAL_FACES.insert(i);
462 }
463
465 EXTERNAL_FACES.erase(i);
466 }
467
469 const DenseVector<double> x(get_x(s));
470 // value of Q at the current time point
472 // evaluate the 2nd order Taylor series expansion of Q at the
473 // time step of size dt
474 //
475 // get the RHS from the eqn
476 DenseVector<double> r(p_system -> get_order(), 0.0);
477 p_system -> source_fn(x, q, r);
478 // get the Jacobian of the x-flux fn
479 DenseMatrix<double> jac(p_system -> get_order(), p_system -> get_order(), 0.0);
480 p_system -> Jac_flux_fn_x(x, q, jac);
481 r -= jac.multiply(SLOPE_X);
482 // get the Jacobian of the y-flux fn
483 p_system -> Jac_flux_fn_y(x, q, jac);
484 r -= jac.multiply(SLOPE_Y);
485 // add the correction
486 q += r * dt;
487 // the above should be equivalent to the expression below, but
488 // minimises instantiation of Jacobian matrix
489 // q += ( get_source_fn( s )
490 // - get_Jac_flux_fn_x( s ).multiply( slope_x )
491 // - get_Jac_flux_fn_y( s ).multiply( slope_y ) ) * dt;
492 return q;
493 }
494
496 const DenseVector<double> s_mid(2, 0.0);
497 // evaluate the Taylor series expansion of the unknowns at the
498 // mid time displacement point dt/2
500 DenseVector<double> R(p_system -> get_order(), 0.0);
501 // work out the source function for this mid-point in time q value
502 p_system -> source_fn(get_x(s_mid), q, R);
503 // return the contribution
504 return R * dt;
505 }
506
507
508
509}
Specification of a two dimensional linear element for use in a TVD Lax-Friedrichs scheme.
A matrix class that constructs a DENSE matrix as a row major std::vector of DenseVectors.
Definition: DenseMatrix.h:25
DenseVector< _Type > multiply(const DenseVector< _Type > &x) const
Right multiply the matrix by a DENSE vector.
An DenseVector class – a dense vector object.
Definition: DenseVector.h:34
A generic runtime exception.
Definition: Exceptions.h:158
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_ptrs(const int &index, TwoD_TVDLF_Elt *ptr)
Each element stores pointers to any adjacent elements in the four compass directions 0,...
void dump() const
Dump the details of this element.
TwoD_TVDLF_Elt(double west, double east, double south, double north, TwoD_Hyperbolic_System *ptr, bool flag=false, std::set< int > faces=std::set< int >())
Construct a linear rectangular 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.
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.
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.
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.
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.
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