CppNoddy  0.92
Loading...
Searching...
No Matches
Classes | Public Member Functions | Public Attributes | List of all members
CppNoddy::TwoD_TVDLF_Elt Class Reference

A Linear Element class. More...

#include <TwoD_TVDLF_Elt.h>

Public Member Functions

 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. More...
 
 ~TwoD_TVDLF_Elt ()
 An empty destructor. More...
 
bool face_is_external (const int &index) const
 Test to see if a face index of an element is external to the mesh. More...
 
bool face_is_internal (const int &index) const
 Test to see if a face index of an element is internal to the mesh. More...
 
void set_ptrs (const int &index, TwoD_TVDLF_Elt *ptr)
 Each element stores pointers to any adjacent elements in the four compass directions 0,1,2,3 for S,E,N,W. More...
 
TwoD_TVDLF_Eltget_ptrs (const int &index) const
 Return a pointer to an element in the given compass direction. More...
 
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. More...
 
void dump () const
 Dump the details of this element. More...
 
void clear_contributions ()
 Reset the contributions to this element. More...
 
DenseVector< double > contributed_Q () const
 Find the integral contributions to this black/red element from the corresponding contributing red/black element. More...
 
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 been added by a flux computation across the same face in an adjacent elt. More...
 
void contributed_flux_in_west (const double &dt, DenseVector< double > &flux_in_west)
 Compute the flux into this element across the western face. More...
 
void contributed_flux_in_south (const double &dt, DenseVector< double > &flux_in_south)
 Compute the flux into this element across the southern face. More...
 
void contributed_flux_out_east (const double &dt, DenseVector< double > &flux_out_east)
 Compute the flux out of this element across the eastern face. More...
 
void contributed_flux_out_north (const double &dt, DenseVector< double > &flux_out_north)
 Compute the flux out of this element across the northern face. More...
 
DenseVector< double > get_s (const DenseVector< double > &x) const
 Get the local coordinate that corresponds to a given global coordinate. More...
 
DenseVector< double > get_x (DenseVector< double > s) const
 Get the global position of a local coordinate in this element. More...
 
DenseVector< double > get_x_mid () const
 Get the global position of a central node in this element. More...
 
DenseVector< double > get_dx () const
 Get the size of the element as a vector (delta_x, delta_y). More...
 
double get_dA () const
 Get the area of the element. More...
 
void set_external_flag (bool flag)
 Set the external flag. More...
 
bool get_external_flag () const
 Get the external flag. More...
 
std::set< int > get_external_faces () const
 Get a set of indices of faces that are external. More...
 
DenseVector< double > get_Q (const DenseVector< double > &s) const
 Get the value of the 'concentration' stored in this element. More...
 
DenseVector< double > get_int_Q (const DenseVector< double > &sw, const DenseVector< double > &ne) const
 Get the integral of Q over a sub-element. More...
 
void add_external_face (const int &i)
 Add an external face to the stored stl::set. More...
 
void remove_external_face (const int &i)
 Remove an external face to the stored stl::set. More...
 
void set_Q_mid (const DenseVector< double > &value)
 Set the value of the vector 'concentration' stored in this element. More...
 
DenseVector< double > get_Q_mid () const
 Get the nodal concentration. More...
 
void set_slope_x (const DenseVector< double > &value)
 Set the x-slope vector for this element. More...
 
void set_slope_y (const DenseVector< double > &value)
 Set the y-slope vector for this element. More...
 
DenseVector< double > get_slope_x () const
 The concentration is approximated by a linear function in each element. More...
 
DenseVector< double > get_slope_y () const
 The concentration is approximated by a linear function in each element. More...
 
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 this element. More...
 
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 time step using a mid-point in time evaluation. More...
 
double get_max_dt () const
 Get the maximum allowable time step for this element by using information about the size of the element and the maximum wave speed set in the conservative system. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
DenseVector< double > get_source_fn (const DenseVector< double > &s) const
 Get the source function evaluated for the concentration value stored in this elt. More...
 

Public Attributes

TwoD_Hyperbolic_Systemp_system
 

Detailed Description

A Linear Element class.

Definition at line 19 of file TwoD_TVDLF_Elt.h.

Constructor & Destructor Documentation

◆ TwoD_TVDLF_Elt()

CppNoddy::TwoD_TVDLF_Elt::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.

Parameters
westThe western face location
eastThe eastern face location
southThe western face location
northThe eastern face location
ptrA pointer to the hyperbolic system
flagA boolean indicator to specify an elt with an external face
facesA set of indices of the external faces

Definition at line 17 of file TwoD_TVDLF_Elt.cpp.

20 {
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 }
TwoD_Hyperbolic_System * p_system

References p_system.

◆ ~TwoD_TVDLF_Elt()

CppNoddy::TwoD_TVDLF_Elt::~TwoD_TVDLF_Elt ( )

An empty destructor.

Definition at line 49 of file TwoD_TVDLF_Elt.cpp.

50 {}

Member Function Documentation

◆ add_contribution()

void CppNoddy::TwoD_TVDLF_Elt::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.

Parameters
ptrA pointer to the element that contributes to this one
swThe SW local coordinate in the contributory element
neThe NE local coordinate in the contributory element
indicesA set of indices of faces that this element contributes to

Definition at line 99 of file TwoD_TVDLF_Elt.cpp.

102 {
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 }

◆ add_external_face()

void CppNoddy::TwoD_TVDLF_Elt::add_external_face ( const int &  i)

Add an external face to the stored stl::set.

Parameters
iThe index of the external face 0,1,2,3 for S,E,N,W.

Definition at line 460 of file TwoD_TVDLF_Elt.cpp.

460 {
461 EXTERNAL_FACES.insert(i);
462 }

◆ add_flux_contributions()

void CppNoddy::TwoD_TVDLF_Elt::add_flux_contributions ( const double &  dt)

Adds the contribution of each face's flux to the correction for this element unless it has already been added by a flux computation across the same face in an adjacent elt.

Parameters
dtThe time step over which the flux is to be computed

Definition at line 72 of file TwoD_TVDLF_Elt.cpp.

72 {
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 }
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 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_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.
void contributed_flux_in_south(const double &dt, DenseVector< double > &flux_in_south)
Compute the flux into this element across the southern face.

References contributed_flux_in_south(), contributed_flux_in_west(), contributed_flux_out_east(), contributed_flux_out_north(), get_source_contribution(), and p_system.

◆ clear_contributions()

void CppNoddy::TwoD_TVDLF_Elt::clear_contributions ( )

Reset the contributions to this element.

Definition at line 142 of file TwoD_TVDLF_Elt.cpp.

142 {
143 CONT_LIST.clear();
144 }

◆ contributed_flux_in_south()

void CppNoddy::TwoD_TVDLF_Elt::contributed_flux_in_south ( const double &  dt,
DenseVector< double > &  flux_in_south 
)

Compute the flux into this element across the southern face.

Parameters
dtThe time step over which the flux is to be computed
flux_in_southA vector flux that is overwritten by this method and returned containing the appropriate flux values.

Definition at line 220 of file TwoD_TVDLF_Elt.cpp.

220 {
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 }
DenseVector< double > get_x(DenseVector< double > s) const
Get the global position of a local coordinate in this element.
bool face_is_external(const int &index) const
Test to see if a face index of an element is external to the mesh.
bool face_is_internal(const int &index) const
Test to see if a face index of an element is internal to the mesh.
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...

References face_is_external(), face_is_internal(), get_Q_Taylor_series(), get_x(), and p_system.

Referenced by add_flux_contributions().

◆ contributed_flux_in_west()

void CppNoddy::TwoD_TVDLF_Elt::contributed_flux_in_west ( const double &  dt,
DenseVector< double > &  flux_in_west 
)

Compute the flux into this element across the western face.

Parameters
dtThe time step over which the flux is to be computed
flux_in_westA vector flux that is overwritten by this method and returned containing the appropriate flux values.

Definition at line 159 of file TwoD_TVDLF_Elt.cpp.

159 {
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 }

References face_is_external(), face_is_internal(), get_Q_Taylor_series(), get_x(), and p_system.

Referenced by add_flux_contributions().

◆ contributed_flux_out_east()

void CppNoddy::TwoD_TVDLF_Elt::contributed_flux_out_east ( const double &  dt,
DenseVector< double > &  flux_out_east 
)

Compute the flux out of this element across the eastern face.

Parameters
dtThe time step over which the flux is to be computed
flux_out_eastA vector flux that is overwritten by this method and returned containing the appropriate flux values.

Definition at line 281 of file TwoD_TVDLF_Elt.cpp.

281 {
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 }

References face_is_external(), face_is_internal(), get_Q_Taylor_series(), get_x(), and p_system.

Referenced by add_flux_contributions().

◆ contributed_flux_out_north()

void CppNoddy::TwoD_TVDLF_Elt::contributed_flux_out_north ( const double &  dt,
DenseVector< double > &  flux_out_north 
)

Compute the flux out of this element across the northern face.

Parameters
dtThe time step over which the flux is to be computed
flux_out_northA vector flux that is overwritten by this method and returned containing the appropriate flux values.

Definition at line 342 of file TwoD_TVDLF_Elt.cpp.

342 {
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 }

References face_is_external(), face_is_internal(), get_Q_Taylor_series(), get_x(), and p_system.

Referenced by add_flux_contributions().

◆ contributed_Q()

DenseVector< double > CppNoddy::TwoD_TVDLF_Elt::contributed_Q ( ) const

Find the integral contributions to this black/red element from the corresponding contributing red/black element.

Returns
The integrated value of all components

Definition at line 146 of file TwoD_TVDLF_Elt.cpp.

146 {
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 }
DenseVector< double > get_int_Q(const DenseVector< double > &sw, const DenseVector< double > &ne) const
Get the integral of Q over a sub-element.

References get_int_Q(), and p_system.

◆ dump()

void CppNoddy::TwoD_TVDLF_Elt::dump ( ) const

Dump the details of this element.

Definition at line 134 of file TwoD_TVDLF_Elt.cpp.

134 {
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 }
DenseVector< double > get_Q(const DenseVector< double > &s) const
Get the value of the 'concentration' stored in this element.
double s
relative rotation rate

References get_Q().

◆ face_is_external()

bool CppNoddy::TwoD_TVDLF_Elt::face_is_external ( const int &  index) const

Test to see if a face index of an element is external to the mesh.

Parameters
indexThe face index to test (0,1,2,3) for (S,E,N,W)
Returns
True if the face is external to the mesh.

Definition at line 52 of file TwoD_TVDLF_Elt.cpp.

52 {
53 bool found(true);
54 if(EXTERNAL_FACES.find(index) == EXTERNAL_FACES.end()) {
55 found = false;
56 }
57 return found;
58 }

Referenced by contributed_flux_in_south(), contributed_flux_in_west(), contributed_flux_out_east(), contributed_flux_out_north(), and face_is_internal().

◆ face_is_internal()

bool CppNoddy::TwoD_TVDLF_Elt::face_is_internal ( const int &  index) const

Test to see if a face index of an element is internal to the mesh.

Parameters
indexThe face index to test (0,1,2,3) for (S,E,N,W)
Returns
True if the face is internal to the mesh.

Definition at line 60 of file TwoD_TVDLF_Elt.cpp.

60 {
61 return !face_is_external(index);
62 }

References face_is_external().

Referenced by contributed_flux_in_south(), contributed_flux_in_west(), contributed_flux_out_east(), and contributed_flux_out_north().

◆ get_dA()

double CppNoddy::TwoD_TVDLF_Elt::get_dA ( ) const

Get the area of the element.

Returns
The area of the element

Definition at line 444 of file TwoD_TVDLF_Elt.cpp.

444 {
445 return DX * DY;
446 }

◆ get_dx()

DenseVector< double > CppNoddy::TwoD_TVDLF_Elt::get_dx ( ) const

Get the size of the element as a vector (delta_x, delta_y).

Returns
The separation of the rectangles faces (delta_x, delta_y)

Definition at line 437 of file TwoD_TVDLF_Elt.cpp.

437 {
438 DenseVector<double> delta(2, 0.0);
439 delta[ 0 ] = DX;
440 delta[ 1 ] = DY;
441 return delta;
442 }
const double delta(0.5)

◆ get_external_faces()

std::set< int > CppNoddy::TwoD_TVDLF_Elt::get_external_faces ( ) const

Get a set of indices of faces that are external.

Returns
A set of integers (0,1,2,3 for south, east, north, west) indicating which faces are external.

Definition at line 456 of file TwoD_TVDLF_Elt.cpp.

456 {
457 return EXTERNAL_FACES;
458 }

◆ get_external_flag()

bool CppNoddy::TwoD_TVDLF_Elt::get_external_flag ( ) const

Get the external flag.

Returns
The value of the flag (true if this is an elt with an external face)

Definition at line 452 of file TwoD_TVDLF_Elt.cpp.

452 {
453 return EXTERNAL;
454 }

◆ get_flux_fn_x()

DenseVector< double > CppNoddy::TwoD_TVDLF_Elt::get_flux_fn_x ( const DenseVector< double > &  s) const
inline

Get the flux function in the x direction evaluated for the concentration value stored in this elt.

Parameters
sThe local vector coordinate at which to evaluate
Returns
The flux function vector

Definition at line 233 of file TwoD_TVDLF_Elt.h.

233 {
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 }
@ f
Definition: BVPBerman.cpp:15

References f, get_Q(), get_x(), and p_system.

◆ get_flux_fn_y()

DenseVector< double > CppNoddy::TwoD_TVDLF_Elt::get_flux_fn_y ( const DenseVector< double > &  s) const
inline

Get the flux function in the y direction evaluated for the concentration value stored in this elt.

Parameters
sThe local vector coordinate at which to evaluate
Returns
The flux function vector

Definition at line 243 of file TwoD_TVDLF_Elt.h.

243 {
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 }
double g(1.0)
gravitational acceleration

References get_Q(), get_x(), and p_system.

◆ get_int_Q()

DenseVector< double > CppNoddy::TwoD_TVDLF_Elt::get_int_Q ( const DenseVector< double > &  sw,
const DenseVector< double > &  ne 
) const
inline

Get the integral of Q over a sub-element.

Parameters
swA vector containing the SW local coordinates
neA vector containing the NE local coordinates
Returns
The integral of the concentration over the local range

Definition at line 348 of file TwoD_TVDLF_Elt.h.

348 {
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 }

References get_Q().

Referenced by contributed_Q().

◆ get_Jac_flux_fn_x()

DenseMatrix< double > CppNoddy::TwoD_TVDLF_Elt::get_Jac_flux_fn_x ( const DenseVector< double > &  s) const
inline

Get the Jacobian of the x flux function evaluated for the concentration value stored in this elt.

Parameters
sThe local coordinate at which to evaluate
Returns
The Jacobian matrix

Definition at line 253 of file TwoD_TVDLF_Elt.h.

253 {
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 }

References get_Q(), get_x(), and p_system.

◆ get_Jac_flux_fn_y()

DenseMatrix< double > CppNoddy::TwoD_TVDLF_Elt::get_Jac_flux_fn_y ( const DenseVector< double > &  s) const
inline

Get the Jacobian of the y flux function evaluated for the concentration value stored in this elt.

Parameters
sThe local coordinate at which to evaluate
Returns
The Jacobian matrix

Definition at line 263 of file TwoD_TVDLF_Elt.h.

263 {
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 }

References get_Q(), get_x(), and p_system.

◆ get_max_dt()

double CppNoddy::TwoD_TVDLF_Elt::get_max_dt ( ) const
inline

Get the maximum allowable time step for this element by using information about the size of the element and the maximum wave speed set in the conservative system.

The time step is guranteed to satisfy the CFL < 0.5 constraint in the two principle directions.

Returns
The maximum time step for this element

Definition at line 354 of file TwoD_TVDLF_Elt.h.

354 {
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 }
DenseVector< double > get_Q_mid() const
Get the nodal concentration.

References get_Q_mid(), get_x(), and p_system.

◆ get_ptrs()

TwoD_TVDLF_Elt * CppNoddy::TwoD_TVDLF_Elt::get_ptrs ( const int &  index) const

Return a pointer to an element in the given compass direction.

Parameters
indexThe appropriate index of the direction 0,1,2,3 for S,E,N,W
Returns
The pointer to the element

Definition at line 68 of file TwoD_TVDLF_Elt.cpp.

68 {
69 return p_ELTS[ index ];
70 }

◆ get_Q()

DenseVector< double > CppNoddy::TwoD_TVDLF_Elt::get_Q ( const DenseVector< double > &  s) const
inline

Get the value of the 'concentration' stored in this element.

Parameters
sThe local coordinate in the elt at which Q is requested
Returns
The concentration value of the elt for each component

Definition at line 319 of file TwoD_TVDLF_Elt.h.

319 {
320 return Q + (SLOPE_X * s[ 0 ] * DX
321 + SLOPE_Y * s[ 1 ] * DY) / 2;
322 }

Referenced by dump(), get_flux_fn_x(), get_flux_fn_y(), get_int_Q(), get_Jac_flux_fn_x(), get_Jac_flux_fn_y(), get_Q_Taylor_series(), and get_source_fn().

◆ get_Q_mid()

DenseVector< double > CppNoddy::TwoD_TVDLF_Elt::get_Q_mid ( ) const
inline

Get the nodal concentration.

Returns
The concentration at the central node

Definition at line 328 of file TwoD_TVDLF_Elt.h.

328 {
329 return Q;
330 }

Referenced by get_max_dt().

◆ get_Q_Taylor_series()

DenseVector< double > CppNoddy::TwoD_TVDLF_Elt::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 this element.

Parameters
sThe local coordinate
dtThe time step

Definition at line 468 of file TwoD_TVDLF_Elt.cpp.

468 {
469 const DenseVector<double> x(get_x(s));
470 // value of Q at the current time point
471 DenseVector<double> q(get_Q(s));
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 }
double source_fn(const std::pair< double, double > &coord)

References get_Q(), get_x(), CppNoddy::DenseMatrix< _Type >::multiply(), and p_system.

Referenced by contributed_flux_in_south(), contributed_flux_in_west(), contributed_flux_out_east(), contributed_flux_out_north(), and get_source_contribution().

◆ get_s()

DenseVector< double > CppNoddy::TwoD_TVDLF_Elt::get_s ( const DenseVector< double > &  x) const

Get the local coordinate that corresponds to a given global coordinate.

If the global coordinate is outside this element, an exception is thrown.

Parameters
xThe global coordinate
Returns
The local coordinate

Definition at line 408 of file TwoD_TVDLF_Elt.cpp.

408 {
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 }

◆ get_slope_x()

DenseVector< double > CppNoddy::TwoD_TVDLF_Elt::get_slope_x ( ) const
inline

The concentration is approximated by a linear function in each element.

The slope of this function in the x-direction is found through this method.

Returns
The value of the 'slope_x' member data

Definition at line 340 of file TwoD_TVDLF_Elt.h.

340 {
341 return SLOPE_X;
342 }

◆ get_slope_y()

DenseVector< double > CppNoddy::TwoD_TVDLF_Elt::get_slope_y ( ) const
inline

The concentration is approximated by a linear function in each element.

The slope of this function in the y-direction is found through this method.

Returns
The value of the 'slope_x' member data

Definition at line 344 of file TwoD_TVDLF_Elt.h.

344 {
345 return SLOPE_Y;
346 }

◆ get_source_contribution()

DenseVector< double > CppNoddy::TwoD_TVDLF_Elt::get_source_contribution ( const double &  dt) const

Evaluate the contribution to this element by the hyperbolic system's source function over a given time step using a mid-point in time evaluation.

Parameters
dtThe time step over which source function is to be integrated
Returns
The total contribution

Definition at line 495 of file TwoD_TVDLF_Elt.cpp.

495 {
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
499 DenseVector<double> q(get_Q_Taylor_series(s_mid, 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 }

References get_Q_Taylor_series(), get_x(), and p_system.

Referenced by add_flux_contributions().

◆ get_source_fn()

DenseVector< double > CppNoddy::TwoD_TVDLF_Elt::get_source_fn ( const DenseVector< double > &  s) const
inline

Get the source function evaluated for the concentration value stored in this elt.

Parameters
sThe local coordinate at which to evaluate
Returns
The source function value

Definition at line 274 of file TwoD_TVDLF_Elt.h.

274 {
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 }

References get_Q(), get_x(), and p_system.

◆ get_x()

DenseVector< double > CppNoddy::TwoD_TVDLF_Elt::get_x ( DenseVector< double >  s) const

Get the global position of a local coordinate in this element.

Parameters
sThe local coordinate
Returns
The global position

Definition at line 423 of file TwoD_TVDLF_Elt.cpp.

423 {
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 }

Referenced by contributed_flux_in_south(), contributed_flux_in_west(), contributed_flux_out_east(), contributed_flux_out_north(), get_flux_fn_x(), get_flux_fn_y(), get_Jac_flux_fn_x(), get_Jac_flux_fn_y(), get_max_dt(), get_Q_Taylor_series(), get_source_contribution(), and get_source_fn().

◆ get_x_mid()

DenseVector< double > CppNoddy::TwoD_TVDLF_Elt::get_x_mid ( ) const

Get the global position of a central node in this element.

Returns
The global position of the central node

Definition at line 430 of file TwoD_TVDLF_Elt.cpp.

430 {
431 DenseVector<double> x(2, 0.0);
432 x[ 0 ] = WEST + DX / 2;
433 x[ 1 ] = SOUTH + DY / 2;
434 return x;
435 }

◆ remove_external_face()

void CppNoddy::TwoD_TVDLF_Elt::remove_external_face ( const int &  i)

Remove an external face to the stored stl::set.

Parameters
iThe index of the external face 0,1,2,3 for S,E,N,W.

Definition at line 464 of file TwoD_TVDLF_Elt.cpp.

464 {
465 EXTERNAL_FACES.erase(i);
466 }

◆ set_external_flag()

void CppNoddy::TwoD_TVDLF_Elt::set_external_flag ( bool  flag)

Set the external flag.

Parameters
flagis the value to set

Definition at line 448 of file TwoD_TVDLF_Elt.cpp.

448 {
449 EXTERNAL = flag;
450 }

◆ set_ptrs()

void CppNoddy::TwoD_TVDLF_Elt::set_ptrs ( const int &  index,
TwoD_TVDLF_Elt ptr 
)

Each element stores pointers to any adjacent elements in the four compass directions 0,1,2,3 for S,E,N,W.

Parameters
indexThe index of the direction to set the pointer for
ptrA pointer to the element in the chosen direction

Definition at line 64 of file TwoD_TVDLF_Elt.cpp.

64 {
65 p_ELTS[ index ] = ptr;
66 }

◆ set_Q_mid()

void CppNoddy::TwoD_TVDLF_Elt::set_Q_mid ( const DenseVector< double > &  value)
inline

Set the value of the vector 'concentration' stored in this element.

To second order, this is the value of the concentration at the mid-point of the element.

Parameters
valueThe vector value to be assigned to the concentration member data Q

Definition at line 324 of file TwoD_TVDLF_Elt.h.

324 {
325 Q = value;
326 }

◆ set_slope_x()

void CppNoddy::TwoD_TVDLF_Elt::set_slope_x ( const DenseVector< double > &  value)
inline

Set the x-slope vector for this element.

Parameters
valueThe slope vector to be set

Definition at line 332 of file TwoD_TVDLF_Elt.h.

332 {
333 SLOPE_X = value;
334 }

◆ set_slope_y()

void CppNoddy::TwoD_TVDLF_Elt::set_slope_y ( const DenseVector< double > &  value)
inline

Set the y-slope vector for this element.

Parameters
valueThe slope vector to be set

Definition at line 336 of file TwoD_TVDLF_Elt.h.

336 {
337 SLOPE_Y = value;
338 }

Member Data Documentation

◆ p_system

TwoD_Hyperbolic_System* CppNoddy::TwoD_TVDLF_Elt::p_system

The documentation for this class was generated from the following files:

© 2012

R.E. Hewitt