CppNoddy  0.85
 All Classes Namespaces Files Functions Variables Typedefs Enumerator Friends Macros Groups Pages
Public Member Functions | Public Attributes | Protected Types | Protected Member Functions | Protected Attributes | List of all members
CppNoddy::TwoD_TVDLF_Mesh Class Reference

#include <TwoD_TVDLF_Mesh.h>

Public Member Functions

 TwoD_TVDLF_Mesh (const DenseVector< double > &X, const DenseVector< double > &Y, TwoD_Hyperbolic_System *ptr, fn_ptr init_ptr)
 Constructor for the Finite Volume Mesh using linear elements.
virtual ~TwoD_TVDLF_Mesh ()
 Empty desctructor.
void dump_gnu (std::string filename)
 Dump the data to a given filename in a gnuplot format.
void dump_nodes_x (std::string filename) const
 Dump the x-nodal positions to a given filename.
void dump_nodes_y (std::string filename) const
 Dump the y-nodal positions to a given filename.
void dump_data (std::string filename)
 Dump the data over the nodal positions to a given filename.
void set_limiter (const unsigned &id)
 Set the limiter type to be applied in the slope values.
double update (const double &CFL, const double &max_dt=std::numeric_limits< long double >::max())
 Update the mesh object.
void update_to (const double &CFL, const double &t_end)
 Update the mesh object to a set time level.
DenseVector< double > integrate (std::string mesh_colour="black")
 Integrate the concentration values across the entire mesh.
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.
DenseVector< double > get_point_values (const DenseVector< double > &x)
 Get the vector of unknowns at a point in the 2D mesh.
const double & get_time () const
 Get a const reference to the time value for the current mesh.
virtual void actions_before_time_step1 (const double &time_step)
 A virtual method that is run before the first time update.
virtual void actions_before_time_step2 (const double &time_step)
 A virtual method that is run before the second time update.

Public Attributes

vector_of_elts BLACK_ELTS
 An STL vector of linear elements – the black mesh.
vector_of_elts RED_ELTS
 An STL vector of linear elements – the red mesh.

Protected Types

typedef std::vector
< TwoD_TVDLF_Elt
vector_of_elts
 iterators for the vector of elements
typedef
vector_of_elts::const_iterator 
celt_iter
typedef vector_of_elts::iterator elt_iter
typedef std::vector
< TwoD_TVDLF_Elt * > 
vector_of_boundary_elts
typedef
vector_of_boundary_elts::iterator 
bdry_elt_iter
typedef void(* fn_ptr )(const double &, const double &, DenseVector< double > &)
 function pointer used in the initial conditions

Protected Member Functions

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 the other mesh that overlaps the corner specified by corner_index.
vector_of_eltsget_elts_from_colour (std::string mesh_colour)
 Given a choice of black or red mesh, return a pointer to the appropriate vector of elements.
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 calc_slopes (vector_of_elts *elt_vector)
 Use the appropriate limiter to approximate the slope in each element in the mesh.
DenseVector< double > east_diff (elt_iter e) const
 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 > north_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.
DenseVector< double > NS_diff (elt_iter e)
 Compute a finite difference approximation of the derivative in the compass direction.
DenseVector< double > EW_diff (elt_iter e)
 Compute a finite difference approximation of the derivative in the compass direction.
int sgn (double a) const
 Sign of a double.
DenseVector< double > minmod (DenseVector< double > A, DenseVector< double > B) const
 A vector version of the minmod operator.
DenseVector< double > maxmod (DenseVector< double > A, DenseVector< double > B) const
 A vector version of the maxmod operator.
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 as inflow boundary conditions in line with Levy & Tadmor (1997) and set the centre nodal value to the edge value.
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 edge_values method.

Protected Attributes

unsigned LIMITER
 Slope limiter method.
std::size_t ORDER_OF_SYSTEM
 order of the conservative system
std::size_t NX
 number of faces in the x & y directions
std::size_t NY
double MESH_TIME
 the time level of the mesh
fn_ptr p_Q_INIT
 function pointer to a funnction that defines the initial distribution

Detailed Description

Definition at line 20 of file TwoD_TVDLF_Mesh.h.

Member Typedef Documentation

typedef vector_of_boundary_elts::iterator CppNoddy::TwoD_TVDLF_Mesh::bdry_elt_iter
protected

Definition at line 29 of file TwoD_TVDLF_Mesh.h.

typedef vector_of_elts::const_iterator CppNoddy::TwoD_TVDLF_Mesh::celt_iter
protected

Definition at line 25 of file TwoD_TVDLF_Mesh.h.

typedef vector_of_elts::iterator CppNoddy::TwoD_TVDLF_Mesh::elt_iter
protected

Definition at line 26 of file TwoD_TVDLF_Mesh.h.

typedef void( * CppNoddy::TwoD_TVDLF_Mesh::fn_ptr)(const double &, const double &, DenseVector< double > &)
protected

function pointer used in the initial conditions

Definition at line 32 of file TwoD_TVDLF_Mesh.h.

Definition at line 28 of file TwoD_TVDLF_Mesh.h.

iterators for the vector of elements

Definition at line 24 of file TwoD_TVDLF_Mesh.h.

Constructor & Destructor Documentation

CppNoddy::TwoD_TVDLF_Mesh::TwoD_TVDLF_Mesh ( const DenseVector< double > &  X,
const DenseVector< double > &  Y,
TwoD_Hyperbolic_System ptr,
fn_ptr  init_ptr 
)

Constructor for the Finite Volume Mesh using linear elements.

Parameters
XA vector of nodal locations at which the element FACES will positioned
YA vector of nodal locations at which the element FACES will positioned
ptrA pointer to the hyperbolic system applied to this mesh
init_ptrA pointer to a function that defines the initial conditions

Definition at line 16 of file TwoD_TVDLF_Mesh.cpp.

References BLACK_ELTS, calc_slopes(), get_elt_iter_from_elt_iter(), LIMITER, MESH_TIME, NX, NY, ORDER_OF_SYSTEM, p_Q_INIT, RED_ELTS, CppNoddy::Example::s, and CppNoddy::DenseVector< _Type >::size().

{
#ifdef DEBUG
std::cout << "DEBUG: Starting construction of a TwoD_TVDLF_Mesh object. \n";
#endif
MESH_TIME = 0.0;
NX = X.size();
NY = Y.size();
if ( std::min( NX - 1, NY - 1 ) <= 1 )
{
std::string problem;
problem = " The TwoD_TVDLF_Mesh object is trying to construct itself \n";
problem += " with just one element in one of the directions! \n";
throw ExceptionRuntime( problem );
}
#ifdef DEBUG
std::cout << "DEBUG: configuration of the black mesh \n";
#endif
// reserve appropriate space to avoid re-allocation later
BLACK_ELTS.reserve( ( NX - 1 ) * ( NY - 1 ) );
RED_ELTS.reserve( NX * NY );
// set up the fn ptr to the initial conditions fn
p_Q_INIT = init_ptr;
// default limiter
LIMITER = 0;
// store the order of the conservative system here for simplicity
ORDER_OF_SYSTEM = ptr -> get_order();
// face index of edges
std::set<int> faces_s;
faces_s.insert( 0 );
std::set<int> faces_e;
faces_e.insert( 1 );
std::set<int> faces_n;
faces_n.insert( 2 );
std::set<int> faces_w;
faces_w.insert( 3 );
// face indices of corners
std::set<int> faces_se( faces_s );
faces_se.insert( 1 );
std::set<int> faces_ne( faces_n );
faces_ne.insert( 1 );
std::set<int> faces_nw( faces_n );
faces_nw.insert( 3 );
std::set<int> faces_sw( faces_s );
faces_sw.insert( 3 );
// set up the black elements
{
// southern row
BLACK_ELTS.push_back( TwoD_TVDLF_Elt( X[0], X[1], Y[0], Y[1], ptr, true, faces_sw ) );
for ( std::size_t i = 1; i <= NX - 3; ++i )
{
BLACK_ELTS.push_back( TwoD_TVDLF_Elt( X[i], X[i+1], Y[0], Y[1], ptr, true, faces_s ) );
}
BLACK_ELTS.push_back( TwoD_TVDLF_Elt( X[NX-2], X[NX-1], Y[0], Y[1], ptr, true, faces_se ) );
// interior elts
for ( std::size_t j = 1; j <= NY - 3; ++j )
{
BLACK_ELTS.push_back( TwoD_TVDLF_Elt( X[0], X[1], Y[j], Y[j+1], ptr, true, faces_w ) );
for ( std::size_t i = 1; i <= NX - 3; ++i )
{
BLACK_ELTS.push_back( TwoD_TVDLF_Elt( X[i], X[i+1], Y[j], Y[j+1], ptr ) );
}
BLACK_ELTS.push_back( TwoD_TVDLF_Elt( X[NX-2], X[NX-1], Y[j], Y[j+1], ptr, true, faces_e ) );
}
// northern row
BLACK_ELTS.push_back( TwoD_TVDLF_Elt( X[0], X[1], Y[NY-2], Y[NY-1], ptr, true, faces_nw ) );
for ( std::size_t i = 1; i <= NX - 3; ++i )
{
BLACK_ELTS.push_back( TwoD_TVDLF_Elt( X[i], X[i+1], Y[NY-2], Y[NY-1], ptr, true, faces_n ) );
}
BLACK_ELTS.push_back( TwoD_TVDLF_Elt( X[NX-2], X[NX-1], Y[NY-2], Y[NY-1], ptr, true, faces_ne ) );
}
#ifdef DEBUG
std::cout << "DEBUG: configuration of the red mesh \n";
#endif
// set up the red elements
{
// southern row
RED_ELTS.push_back( TwoD_TVDLF_Elt( X[0], ( X[1] + X[0] ) / 2, Y[0], ( Y[0] + Y[1] ) / 2, ptr, true, faces_sw ) );
for ( std::size_t i = 1; i <= NX - 2; ++i )
{
RED_ELTS.push_back( TwoD_TVDLF_Elt( ( X[i-1] + X[i] ) / 2, ( X[i] + X[i+1] ) / 2, Y[0], ( Y[0] + Y[1] ) / 2, ptr, true, faces_s ) );
}
RED_ELTS.push_back( TwoD_TVDLF_Elt( ( X[NX-2] + X[NX-1] ) / 2, X[NX-1], Y[0], ( Y[0] + Y[1] ) / 2, ptr, true, faces_se ) );
// interior elts
for ( std::size_t j = 1; j <= NY - 2; ++j )
{
RED_ELTS.push_back( TwoD_TVDLF_Elt( X[0], ( X[1] + X[0] ) / 2, ( Y[j-1] + Y[j] ) / 2, ( Y[j] + Y[j+1] ) / 2, ptr, true, faces_w ) );
for ( std::size_t i = 1; i <= NX - 2; ++i )
{
RED_ELTS.push_back( TwoD_TVDLF_Elt( ( X[i-1] + X[i] ) / 2, ( X[i] + X[i+1] ) / 2, ( Y[j-1] + Y[j] ) / 2, ( Y[j] + Y[j+1] ) / 2, ptr ) );
}
RED_ELTS.push_back( TwoD_TVDLF_Elt( ( X[NX-2] + X[NX-1] ) / 2, X[NX-1], ( Y[j-1] + Y[j] ) / 2, ( Y[j] + Y[j+1] ) / 2, ptr, true, faces_e ) );
}
// northern row
RED_ELTS.push_back( TwoD_TVDLF_Elt( X[0], ( X[1] + X[0] ) / 2, ( Y[NY-2] + Y[NY-1] ) / 2, Y[NY-1], ptr, true, faces_nw ) );
for ( std::size_t i = 1; i <= NX - 2; ++i )
{
RED_ELTS.push_back( TwoD_TVDLF_Elt( ( X[i-1] + X[i] ) / 2, ( X[i] + X[i+1] ) / 2, ( Y[NY-2] + Y[NY-1] ) / 2, Y[NY-1], ptr, true, faces_n ) );
}
RED_ELTS.push_back( TwoD_TVDLF_Elt( ( X[NX-2] + X[NX-1] ) / 2, X[NX-1], ( Y[NY-2] + Y[NY-1] ) / 2, Y[NY-1], ptr, true, faces_ne ) );
}
#ifdef DEBUG
std::cout << "DEBUG: computing black to red projection \n";
#endif
// Now we need to pre-compute the mesh projection from black-red-black.
// Each element needs to know which element in the other mesh contributes
// to it in the projection scheme. It also needs to know which of its faces
// the element contributes to in the flux computation.
// We assume the constructor is not required to be efficient & just brute
// force it here rather than working out all the index mappings by hand.
//
// loop through all the black elts
elt_iter eb = BLACK_ELTS.begin();
while ( eb != BLACK_ELTS.end() )
{
// local coordinates of the corners
DenseVector<double> ne( 2, 1.0 );
DenseVector<double> sw( -ne );
DenseVector<double> se( 2, 1.0 );
se[ 1 ] = -1.0;
DenseVector<double> nw( -se );
// global coordinates of the corners
DenseVector<double> bx_sw = eb -> get_x( sw );
DenseVector<double> bx_ne = eb -> get_x( ne );
DenseVector<double> bx_nw = eb -> get_x( nw );
DenseVector<double> bx_se = eb -> get_x( se );
// get an iterator to the red elt that contains each corner
// & add it as a contribution
//
// nw corner
{
//elt_iter er = get_elt_iter_from_x( bx_nw, "red" );
elt_iter er = get_elt_iter_from_elt_iter( eb, "red", 3 );
DenseVector<double> s = er -> get_s( bx_nw );
DenseVector<double> s1( 2, 0.0 );
s1[ 0 ] = s[ 0 ];
s1[ 1 ] = -1.0;
DenseVector<double> s2( 2, 0.0 );
s2[ 0 ] = 1.0;
s2[ 1 ] = s[ 1 ];
eb -> add_contribution( &( *er ), s1, s2, faces_nw );
}
// sw corner
{
//elt_iter er = get_elt_iter_from_x( bx_sw, "red" );
elt_iter er = get_elt_iter_from_elt_iter( eb, "red", 0 );
DenseVector<double> s = er -> get_s( bx_sw );
DenseVector<double> s1( 2, 0.0 );
s1[ 0 ] = s[ 0 ];
s1[ 1 ] = s[ 1 ];
DenseVector<double> s2( 2, 0.0 );
s2[ 0 ] = 1.0;
s2[ 1 ] = 1.0;
eb -> add_contribution( &( *er ), s1, s2, faces_sw );
}
// ne corner
{
//elt_iter er = get_elt_iter_from_x( bx_ne, "red" );
elt_iter er = get_elt_iter_from_elt_iter( eb, "red", 2 );
DenseVector<double> s = er -> get_s( bx_ne );
DenseVector<double> s1( 2, 0.0 );
s1[ 0 ] = -1.0;
s1[ 1 ] = -1.0;
DenseVector<double> s2( 2, 0.0 );
s2[ 0 ] = s[ 0 ];
s2[ 1 ] = s[ 1 ];
eb -> add_contribution( &( *er ), s1, s2, faces_ne );
}
// se corner
{
//elt_iter er = get_elt_iter_from_x( bx_se, "red" );
elt_iter er = get_elt_iter_from_elt_iter( eb, "red", 1 );
DenseVector<double> s = er -> get_s( bx_se );
DenseVector<double> s1( 2, 0.0 );
s1[ 0 ] = -1.0;
s1[ 1 ] = s[ 1 ];
DenseVector<double> s2( 2, 0.0 );
s2[ 0 ] = s[ 0 ];
s2[ 1 ] = 1.0;
eb -> add_contribution( &( *er ), s1, s2, faces_se );
}
++eb;
}
#ifdef DEBUG
std::cout << "DEBUG: computing red to black projection \n";
#endif
// now we need to set up the projection from red to black elts.
// it's a little more tricky here as we have to avoid the external nodes.
elt_iter er = RED_ELTS.begin();
while ( er != RED_ELTS.end() )
{
// local coordinates of the corners
DenseVector<double> ne( 2, 1.0 );
DenseVector<double> sw( -ne );
DenseVector<double> se( 2, 1.0 );
se[ 1 ] = -1.0;
DenseVector<double> nw( -se );
// global coordinates of the corners
DenseVector<double> bx_sw = er -> get_x( sw );
DenseVector<double> bx_ne = er -> get_x( ne );
DenseVector<double> bx_nw = er -> get_x( nw );
DenseVector<double> bx_se = er -> get_x( se );
//
std::set<int> external = er -> get_external_faces();
if ( ( external.find( 2 ) == external.end() ) &&
( external.find( 3 ) == external.end() ) )
{
// nw corner is internal
//elt_iter eb = get_elt_iter_from_x( bx_nw, "black" );
elt_iter eb = get_elt_iter_from_elt_iter( er, "black", 3 );
DenseVector<double> s = eb -> get_s( bx_nw );
DenseVector<double> s1( 2, 0.0 );
s1[ 0 ] = s[ 0 ];
s1[ 1 ] = -1.0;
DenseVector<double> s2( 2, 0.0 );
s2[ 0 ] = 1.0;
s2[ 1 ] = s[ 1 ];
er -> add_contribution( &( *eb ), s1, s2, faces_nw );
}
if ( ( external.find( 0 ) == external.end() ) &&
( external.find( 3 ) == external.end() ) )
{
// sw corner is internal
//elt_iter eb = get_elt_iter_from_x( bx_sw, "black" );
elt_iter eb = get_elt_iter_from_elt_iter( er, "black", 0 );
DenseVector<double> s = eb -> get_s( bx_sw );
DenseVector<double> s1( 2, 0.0 );
s1[ 0 ] = s[ 0 ];
s1[ 1 ] = s[ 1 ];
DenseVector<double> s2( 2, 0.0 );
s2[ 0 ] = 1.0;
s2[ 1 ] = 1.0;
er -> add_contribution( &( *eb ), s1, s2, faces_sw );
}
if ( ( external.find( 1 ) == external.end() ) &&
( external.find( 2 ) == external.end() ) )
{
// ne corner is internal
//elt_iter eb = get_elt_iter_from_x( bx_ne, "black" );
elt_iter eb = get_elt_iter_from_elt_iter( er, "black", 2 );
DenseVector<double> s = eb -> get_s( bx_ne );
DenseVector<double> s1( 2, 0.0 );
s1[ 0 ] = -1.0;
s1[ 1 ] = -1.0;
DenseVector<double> s2( 2, 0.0 );
s2[ 0 ] = s[ 0 ];
s2[ 1 ] = s[ 1 ];
er -> add_contribution( &( *eb ), s1, s2, faces_ne );
}
if ( ( external.find( 0 ) == external.end() ) &&
( external.find( 1 ) == external.end() ) )
{
// se corner is internal
//elt_iter eb = get_elt_iter_from_x( bx_se, "black" );
elt_iter eb = get_elt_iter_from_elt_iter( er, "black", 1 );
DenseVector<double> s = eb -> get_s( bx_se );
DenseVector<double> s1( 2, 0.0 );
s1[ 0 ] = -1.0;
s1[ 1 ] = s[ 1 ];
DenseVector<double> s2( 2, 0.0 );
s2[ 0 ] = s[ 0 ];
s2[ 1 ] = 1.0;
er -> add_contribution( &( *eb ), s1, s2, faces_se );
}
++er;
}
#ifdef DEBUG
std::cout << "DEBUG: setting up pointers to NESW elts in black mesh\n";
#endif
// we need to set the pointers to neighbouring elts in both meshes
eb = BLACK_ELTS.begin();
while ( eb != BLACK_ELTS.end() )
{
// the offset for computing N & S elts is no. of faces minus one
const std::size_t offset( NX - 1 );
// get a set of external faces
std::set< int > faces( eb -> get_external_faces() );
if ( eb -> face_is_internal( 0 ) )
{
// southern face is internal
eb -> set_ptrs( 0, &( *eb ) - offset );
}
if ( eb -> face_is_internal( 1 ) )
{
// eastern face is internal
eb -> set_ptrs( 1, &( *eb ) + 1 );
}
if ( eb -> face_is_internal( 2 ) )
{
// northern face is internal
eb -> set_ptrs( 2, &( *eb ) + offset );
}
if ( eb -> face_is_internal( 3 ) )
{
// western face is internal
eb -> set_ptrs( 3, &( *eb ) - 1 );
}
++eb;
}
#ifdef DEBUG
std::cout << "DEBUG: setting up pointers to NESW elts in red mesh\n";
#endif
// we need to set the pointers to neighbouring elts in both meshes
er = RED_ELTS.begin();
while ( er != RED_ELTS.end() )
{
// the offset for computing N & S elts is no. of faces
// as the red mesh has an extra elt per row
const std::size_t offset( NX );
// get a set of external faces
std::set< int > faces( er -> get_external_faces() );
if ( er -> face_is_internal( 0 ) )
{
// southern face is internal
er -> set_ptrs( 0, &( *er ) - offset );
}
if ( er -> face_is_internal( 1 ) )
{
// eastern face is internal
er -> set_ptrs( 1, &( *er ) + 1 );
}
if ( er -> face_is_internal( 2 ) )
{
// northern face is internal
er -> set_ptrs( 2, &( *er ) + offset );
}
if ( er -> face_is_internal( 3 ) )
{
// western face is internal
er -> set_ptrs( 3, &( *er ) - 1 );
}
++er;
}
#ifdef DEBUG
std::cout << "DEBUG: initialising the black mesh \n";
#endif
// now all that remains is to initialise the starting (black) mesh
eb = BLACK_ELTS.begin();
while ( eb != BLACK_ELTS.end() )
{
DenseVector<double> s( 2, 0.0 );
// compute to the east
s[ 0 ] = 1.0;
s[ 1 ] = 0.0;
DenseVector<double> xe( eb -> get_x( s ) );
DenseVector<double> Qe( ORDER_OF_SYSTEM, 0.0 );
p_Q_INIT( xe[0], xe[1], Qe );
// compute to the west
s[ 0 ] = -1.0;
s[ 1 ] = 0.0;
DenseVector<double> xw( eb -> get_x( s ) );
DenseVector<double> Qw( ORDER_OF_SYSTEM, 0.0 );
p_Q_INIT( xw[0], xw[1], Qw );
// compute to the north
s[ 0 ] = 0.0;
s[ 1 ] = 1.0;
DenseVector<double> xn( eb -> get_x( s ) );
DenseVector<double> Qn( ORDER_OF_SYSTEM, 0.0 );
p_Q_INIT( xn[0], xn[1], Qn );
// compute to the north
s[ 0 ] = 0.0;
s[ 1 ] = -1.0;
DenseVector<double> xs( eb -> get_x( s ) );
DenseVector<double> Qs( ORDER_OF_SYSTEM, 0.0 );
p_Q_INIT( xs[0], xs[1], Qs );
// difference for the slopes
eb -> set_slope_x( ( Qe - Qw ) / ( xe[0] - xw[0] ) );
eb -> set_slope_y( ( Qn - Qs ) / ( xn[1] - xs[1] ) );
// set the mid value
eb -> set_Q_mid( ( Qe + Qw + Qn + Qs ) / 4 );
++eb;
}
#ifdef DEBUG
std::cout << "DEBUG: mesh constructor complete \n";
#endif
// now all that remains is to initialise the starting (black) mesh
eb = BLACK_ELTS.begin();
while ( eb != BLACK_ELTS.end() )
{
DenseVector<double> x( 2, 0.0 );
DenseVector<double> s( 2, 0.0 );
x = eb -> get_x( s );
DenseVector<double> Q( ORDER_OF_SYSTEM, 0.0 );
p_Q_INIT( x[0], x[1], Q );
eb -> set_Q_mid( Q );
++eb;
}
}
CppNoddy::TwoD_TVDLF_Mesh::~TwoD_TVDLF_Mesh ( )
virtual

Empty desctructor.

Definition at line 430 of file TwoD_TVDLF_Mesh.cpp.

{}

Member Function Documentation

virtual void CppNoddy::TwoD_TVDLF_Mesh::actions_before_time_step1 ( const double &  time_step)
inlinevirtual

A virtual method that is run before the first time update.

For user-custom problems.

Parameters
time_stepThe time step size that is about to be taken

Definition at line 112 of file TwoD_TVDLF_Mesh.h.

Referenced by update().

{
// Empty by default. If you want to take actions before the time
// step then you need to inherit from this basic mesh and implement
// this method.
}
virtual void CppNoddy::TwoD_TVDLF_Mesh::actions_before_time_step2 ( const double &  time_step)
inlinevirtual

A virtual method that is run before the second time update.

For user-custom problems.

Parameters
time_stepThe time step size that is about to be taken

Definition at line 122 of file TwoD_TVDLF_Mesh.h.

Referenced by update().

{
// Empty by default. If you want to take actions before the time
// step then you need to inherit from this basic mesh and implement
// this method.
}
void CppNoddy::TwoD_TVDLF_Mesh::boundary_diff ( elt_iter  e,
const int &  face_index,
DenseVector< double > &  diff 
) const
protected

Given an element iterator and the local coordinate this will return zero for any components specified as inflow boundary conditions in line with Levy & Tadmor (1997) and set the centre nodal value to the edge value.

Parameters
eElement iterator
face_indexThe index of the face that is on a boundary
diffA vector of derivatives

Definition at line 1008 of file TwoD_TVDLF_Mesh.cpp.

References ORDER_OF_SYSTEM.

Referenced by east_diff(), EW_diff(), north_diff(), NS_diff(), south_diff(), and west_diff().

{
DenseVector<double> se( 2, 0.0 );
// get the appropriate local coordinate for the mid point on the edge
switch ( face_index )
{
case 0:
// south
se[ 0 ] = 0.0;
se[ 1 ] = -1.0;
break;
case 1:
// east
se[ 0 ] = 1.0;
se[ 1 ] = 0.0;
break;
case 2:
// north
se[ 0 ] = 0.0;
se[ 1 ] = 1.0;
break;
case 3:
// west
se[ 0 ] = -1.0;
se[ 1 ] = 0.0;
break;
}
// for the edge value
DenseVector<double> Q( e -> get_Q( se ) );
// look at the user-defined BCs for any defined Dirichlet conditions
std::vector<bool> inflow = e -> p_system -> edge_values( face_index, e -> get_x( se ), Q );
// the default is a zero slope in accordance with Levy & Tadmor (1997)
DenseVector<double> sigma_n( ORDER_OF_SYSTEM, 0.0 );
// allow the user to override the zero slope
e -> p_system -> edge_slopes( face_index, e -> get_x( se ), sigma_n );
// use edge values for inflow conditions
for ( std::size_t i = 0; i < ORDER_OF_SYSTEM; ++i )
{
if ( inflow[ i ] == true )
{
// set a zero slope as per Levy & Tadmor (1997)?
diff[ i ] = sigma_n[ i ];// ( Qe[ i ] - Qm[ i ] ) / delta;
//std::cout << face_index << " " << diff[ i ] << "\n";
}
}
}
void CppNoddy::TwoD_TVDLF_Mesh::calc_slopes ( vector_of_elts elt_vector)
protected

Use the appropriate limiter to approximate the slope in each element in the mesh.

The slopes will be sent down to the element objects and then onto the face objects.

Parameters
elt_vectorThe vector of elements to set the slope for

superbee

Definition at line 760 of file TwoD_TVDLF_Mesh.cpp.

References east_diff(), EW_diff(), LIMITER, maxmod(), minmod(), north_diff(), NS_diff(), ORDER_OF_SYSTEM, set_boundary_Q(), south_diff(), and west_diff().

Referenced by TwoD_TVDLF_Mesh(), and update().

{
set_boundary_Q( elt_vector );
elt_iter e( elt_vector -> begin() );
DenseVector<double> slope_east( ORDER_OF_SYSTEM, 0.0 );
DenseVector<double> slope_west( ORDER_OF_SYSTEM, 0.0 );
DenseVector<double> slope_north( ORDER_OF_SYSTEM, 0.0 );
DenseVector<double> slope_south( ORDER_OF_SYSTEM, 0.0 );
switch ( LIMITER )
{
case 0:
// minmod
while ( e != elt_vector -> end() )
{
slope_east = east_diff( e );
slope_west = west_diff( e );
slope_south = south_diff( e );
slope_north = north_diff( e );
e -> set_slope_x( minmod( slope_east, slope_west ) );
e -> set_slope_y( minmod( slope_north, slope_south ) );
++e;
}
break;
case 1:
// MC
while ( e != elt_vector -> end() )
{
slope_east = east_diff( e );
slope_west = west_diff( e );
DenseVector<double> slope_ew( EW_diff( e ) );
slope_south = south_diff( e );
slope_north = north_diff( e );
DenseVector<double> slope_ns( NS_diff( e ) );
const DenseVector<double> temp_x( minmod( slope_east * 2, slope_west * 2 ) );
const DenseVector<double> slope_x( minmod( temp_x, slope_ew ) );
const DenseVector<double> temp_y( minmod( slope_north * 2, slope_south * 2 ) );
const DenseVector<double> slope_y( minmod( temp_y, slope_ns ) );
e -> set_slope_x( slope_x );
e -> set_slope_y( slope_y );
++e;
}
case 2:
/// superbee
while ( e != elt_vector -> end() )
{
slope_east = east_diff( e );
slope_west = west_diff( e );
slope_south = south_diff( e );
slope_north = north_diff( e );
const DenseVector<double> slope_x = maxmod(
minmod( slope_east, slope_west * 2. ),
minmod( slope_east * 2., slope_west )
);
e -> set_slope_x( slope_x );
const DenseVector<double> slope_y = maxmod(
minmod( slope_north, slope_south * 2. ),
minmod( slope_north * 2., slope_south )
);
e -> set_slope_y( slope_y );
++e;
}
break;
default:
std::string problem;
problem = " The TwoD_TVDLF_Mesh object has an unrecognised 'LIMITER' identifier. \n";
throw ExceptionRuntime( problem );
}
}
void CppNoddy::TwoD_TVDLF_Mesh::dump_data ( std::string  filename)

Dump the data over the nodal positions to a given filename.

Parameters
filenameThe filename to be generated

Definition at line 501 of file TwoD_TVDLF_Mesh.cpp.

References BLACK_ELTS, ORDER_OF_SYSTEM, and CppNoddy::Example::s.

Referenced by main().

{
std::ofstream dump;
dump.open( filename.c_str() );
dump.precision( 6 );
DenseVector<double> s( 2, 0.0 );
{
e = BLACK_ELTS.begin();
while ( e != BLACK_ELTS.end() )
{
for ( std::size_t i = 0; i < ORDER_OF_SYSTEM; ++i )
{
dump << e -> get_Q( s )[i] << " ";
}
for ( std::size_t i = 0; i < ORDER_OF_SYSTEM; ++i )
{
dump << e -> get_slope_x()[i] << " ";
}
for ( std::size_t i = 0; i < ORDER_OF_SYSTEM; ++i )
{
dump << e -> get_slope_y()[i] << " ";
}
dump << "\n";
++e;
}
}
dump.close();
}
void CppNoddy::TwoD_TVDLF_Mesh::dump_gnu ( std::string  filename)

Dump the data to a given filename in a gnuplot format.

Parameters
filenameThe filename to be generated

Definition at line 433 of file TwoD_TVDLF_Mesh.cpp.

References BLACK_ELTS, ORDER_OF_SYSTEM, and CppNoddy::Example::s.

Referenced by main().

{
std::ofstream dump;
dump.open( filename.c_str() );
dump.precision( 6 );
DenseVector<double> s( 2, 0.0 );
{
elt_iter e( BLACK_ELTS.begin() );
while ( e != BLACK_ELTS.end() )
{
dump << e -> get_x( s )[0] << " " << e -> get_x( s )[1] << " ";
for ( std::size_t i = 0; i < ORDER_OF_SYSTEM; ++i )
{
dump << e -> get_Q( s )[i] << " ";
}
for ( std::size_t i = 0; i < ORDER_OF_SYSTEM; ++i )
{
dump << e -> get_slope_x()[i] << " ";
}
for ( std::size_t i = 0; i < ORDER_OF_SYSTEM; ++i )
{
dump << e -> get_slope_y()[i] << " ";
}
dump << "\n";
if ( e -> face_is_external( 1 ) )
dump << "\n";
++e;
}
}
dump.close();
}
void CppNoddy::TwoD_TVDLF_Mesh::dump_nodes_x ( std::string  filename) const

Dump the x-nodal positions to a given filename.

This method only applies to regular structured meshes.

Parameters
filenameThe filename to be generated

Definition at line 465 of file TwoD_TVDLF_Mesh.cpp.

References BLACK_ELTS, NX, and CppNoddy::Example::s.

Referenced by main().

{
std::ofstream dump;
dump.open( filename.c_str() );
dump.precision( 6 );
DenseVector<double> s( 2, 0.0 );
{
e = BLACK_ELTS.begin();
for ( unsigned i = 0; i < NX - 1; ++i )
{
dump << e -> get_x( s )[0] << "\n";
++e;
}
}
dump.close();
}
void CppNoddy::TwoD_TVDLF_Mesh::dump_nodes_y ( std::string  filename) const

Dump the y-nodal positions to a given filename.

This method only applies to regular structured meshes.

Parameters
filenameThe filename to be generated

Definition at line 483 of file TwoD_TVDLF_Mesh.cpp.

References BLACK_ELTS, NX, NY, and CppNoddy::Example::s.

Referenced by main().

{
std::ofstream dump;
dump.open( filename.c_str() );
dump.precision( 6 );
DenseVector<double> s( 2, 0.0 );
{
e = BLACK_ELTS.begin();
for ( unsigned i = 0; i < NY - 1; ++i )
{
dump << e -> get_x( s )[1] << "\n";
e += NX - 1;
}
}
dump.close();
}
DenseVector< double > CppNoddy::TwoD_TVDLF_Mesh::east_diff ( elt_iter  e) const
protected

Compute a finite difference approximation of the derivative in the compass direction.

Parameters
eThe iterator to the element that we want the derivative for
Returns
The spatial derivative of the vector system

Definition at line 829 of file TwoD_TVDLF_Mesh.cpp.

References boundary_diff(), ORDER_OF_SYSTEM, and west_diff().

Referenced by calc_slopes(), EW_diff(), and west_diff().

{
DenseVector<double> diff( ORDER_OF_SYSTEM, 0.0 );
std::set< int > faces( e -> get_external_faces() );
const int face_index( 1 );
if ( e -> face_is_external( face_index ) )
{
// interior difference
diff = west_diff( e );
boundary_diff( e, face_index, diff );
}
else
{
// We're not on an edge, so we can difference
elt_iter j( e -> get_ptrs( face_index ) );
diff = ( j -> get_Q_mid() - e -> get_Q_mid() )
/ ( j -> get_x_mid()[0] - e -> get_x_mid()[0] );
}
return diff;
}
DenseVector< double > CppNoddy::TwoD_TVDLF_Mesh::EW_diff ( elt_iter  e)
protected

Compute a finite difference approximation of the derivative in the compass direction.

Parameters
eThe iterator to the element that we want the derivative for
Returns
The spatial derivative of the vector system

Definition at line 941 of file TwoD_TVDLF_Mesh.cpp.

References boundary_diff(), east_diff(), ORDER_OF_SYSTEM, and west_diff().

Referenced by calc_slopes().

{
DenseVector<double> diff( ORDER_OF_SYSTEM, 0.0 );
std::set< int > faces( e -> get_external_faces() );
if ( e -> face_is_external( 1 ) )
{
// interior difference
diff = west_diff( e );
boundary_diff( e, 1, diff );
}
else
if ( e -> face_is_external( 3 ) )
{
// interior difference
diff = east_diff( e );
boundary_diff( e, 3, diff );
}
else
{
// We're not on an edge, so we can difference
elt_iter jE( e -> get_ptrs( 1 ) );
elt_iter jW( e -> get_ptrs( 3 ) );
diff = ( jE -> get_Q_mid() - jW -> get_Q_mid() )
/ ( jE -> get_x_mid()[0] - jW -> get_x_mid()[0] );
}
return diff;
}
elt_iter CppNoddy::TwoD_TVDLF_Mesh::get_elt_iter_from_elt_iter ( elt_iter  e,
std::string  target_colour,
int  corner_index 
)
inlineprotected

Given an element in the INITIAL STRUCTURED MESH, this method will return an iterator to an element in the other mesh that overlaps the corner specified by corner_index.

Parameters
eAn element iterator to the source element
target_colourThe colour of the target mesh, ie. NOT the one that iterator 'e' is in
corner_indexThe index of the corner to be considered 0,1,2,3 for SW, SE, NE, NW.

Definition at line 143 of file TwoD_TVDLF_Mesh.h.

References BLACK_ELTS, m, NX, NY, and RED_ELTS.

Referenced by TwoD_TVDLF_Mesh().

{
// for corners SW,SE,NE,NW:
// black (i,j) -> red (i,j),(i+1,j),(i+1,j+1),(i,j+1)
// => j*Bx+i -> j*Rx+i etc
// red (i,j) -> black (i-1,j-1),(i,j-1),(i,j),(i-1,j)
// => j*Rx+i -> (j-1)*Bx+i-1 etc
//dimensions of the Black (Bx times By) & Red (Rx times Ry) meshes
//
vector_of_elts* target_elts( NULL );
int k( 0 );
int Bx( NX - 1 );
int By( NY - 1 );
int Rx( NX );
int Ry( NY );
//
if ( target_colour == "red" )
{
int offset( e - BLACK_ELTS.begin() );
target_elts = &RED_ELTS;
int i, j, l, m;
//std::cout << " offset = " << offset << "\n";
i = offset % Bx;
j = ( offset - i ) / Bx;
switch ( corner_index )
{
case 0:
l = i;
m = j;
break;
case 1:
l = i + 1;
m = j;
break;
case 2:
l = i + 1;
m = j + 1;
break;
case 3:
l = i;
m = j + 1;
break;
default:
l = 0;
m = 0;
assert( false );
}
// dont return outside the mesh
//std::cout << source_colour << " " << i << "," << j << " -> " << l << "," << m <<"\n";
l = std::min( l, Rx );
l = std::max( l, 0 );
m = std::min( m, Ry );
m = std::max( m, 0 );
k = m * Rx + l;
//std::cout << source_colour << " " << i << "," << j << " -> " << l << "," << m <<"\n";
//std::cout << "--\n";
}
else
if ( target_colour == "black" )
{
int offset( e - RED_ELTS.begin() );
target_elts = &BLACK_ELTS;
int i, j, l, m;
i = offset % Rx;
j = ( offset - i ) / Rx;
switch ( corner_index )
{
case 0:
l = i - 1;
m = j - 1;
break;
case 1:
l = i;
m = j - 1;
break;
case 2:
l = i;
m = j;
break;
case 3:
l = i - 1;
m = j;
break;
default:
l = 0;
m = 0;
assert( false );
}
// dont return outside the mesh
l = std::min( l, Bx );
l = std::max( l, 0 );
m = std::min( m, By );
m = std::max( m, 0 );
k = m * Bx + l;
}
else
{
// throw
}
return target_elts -> begin() + k;
}
std::vector< TwoD_TVDLF_Elt >::iterator CppNoddy::TwoD_TVDLF_Mesh::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.

Because the elts are stored in a vector, and are logically in a rectangular grid, we first hunt for the column, then the appropriate row.

Parameters
xA vector global coordinate
mesh_colourA string identifier of the mesh to be searched
Returns
A pointer to the element containing the global coordinate

Definition at line 666 of file TwoD_TVDLF_Mesh.cpp.

References get_elts_from_colour(), and get_number_elts_in_x().

Referenced by get_point_values().

{
elt_iter found_elt;
vector_of_elts* elts( get_elts_from_colour( mesh_colour ) );
std::size_t Mx( get_number_elts_in_x( mesh_colour ) );
elt_iter e = elts -> begin();
while ( e != elts -> end() )
{
// local coordinates of the NE and SW corners
DenseVector<double> ne( 2, 1.0 );
DenseVector<double> sw( -ne );
double west = e -> get_x( sw )[ 0 ];
double east = e -> get_x( ne )[ 0 ];
if ( ( x[ 0 ] >= west ) && ( x[ 0 ] <= east ) )
{
break;
}
++e;
}
while ( true )
{
// local coordinates of the NE and SW corners
DenseVector<double> ne( 2, 1.0 );
DenseVector<double> sw( -ne );
double south = e -> get_x( sw )[ 1 ];
double north = e -> get_x( ne )[ 1 ];
if ( ( x[ 1 ] >= south ) && ( x[ 1 ] <= north ) )
{
break;
}
if ( e + Mx < elts -> end() )
{
e += Mx;
}
else
{
// if we are here, then we're looking for a point outside the mesh
std::string problem;
problem = "The TwoD_TVDLF_Mesh::get_elt_iter_from_x method has been called\n";
problem += "for a position that is outside the boundaries of the mesh.\n";
throw ExceptionRuntime( problem );
}
}
// if we get to here, then we've found the elt.
return e;
}
std::vector< TwoD_TVDLF_Elt > * CppNoddy::TwoD_TVDLF_Mesh::get_elts_from_colour ( std::string  mesh_colour)
protected

Given a choice of black or red mesh, return a pointer to the appropriate vector of elements.

Parameters
mesh_colourA mesh identifier (black or red)
Returns
A pointer to a std::vector of elements

Definition at line 716 of file TwoD_TVDLF_Mesh.cpp.

References BLACK_ELTS, and RED_ELTS.

Referenced by get_elt_iter_from_x(), and integrate().

{
if ( mesh_colour == "black" )
{
elts = &BLACK_ELTS;
}
else
if ( mesh_colour == "red" )
{
elts = &RED_ELTS;
}
else
{
std::string problem;
problem = " The TwoD_TVDLF_Mesh object has been passed an unrecognised mesh identifier. \n";
problem += " valid options are 'black' or 'red'.\n";
throw ExceptionRuntime( problem );
}
return elts;
}
std::size_t CppNoddy::TwoD_TVDLF_Mesh::get_number_elts_in_x ( std::string  mesh_colour)
protected

Given a choice of black or red mesh, return the number of elements in the x-direction.

Parameters
mesh_colourA mesh identifier (black or red)
Returns
The number of elts in the x-direction

Definition at line 738 of file TwoD_TVDLF_Mesh.cpp.

References NX.

Referenced by get_elt_iter_from_x().

{
std::size_t N;
if ( mesh_colour == "black" )
{
N = NX - 1;
}
else
if ( mesh_colour == "red" )
{
N = NX;
}
else
{
std::string problem;
problem = " The TwoD_TVDLF_Mesh object has been passed an unrecognised mesh identifier. \n";
problem += " valid options are 'black' or 'red'.\n";
throw ExceptionRuntime( problem );
}
return N;
}
DenseVector< double > CppNoddy::TwoD_TVDLF_Mesh::get_point_values ( const DenseVector< double > &  x)

Get the vector of unknowns at a point in the 2D mesh.

Parameters
xThe global coordinate at which to return the values
Returns
The vector of unknowns

Definition at line 531 of file TwoD_TVDLF_Mesh.cpp.

References get_elt_iter_from_x(), and CppNoddy::Example::s.

Referenced by main().

{
DenseVector<double> s( e-> get_s( x ) );
return e -> get_Q( s );
}
const double & CppNoddy::TwoD_TVDLF_Mesh::get_time ( ) const

Get a const reference to the time value for the current mesh.

Returns
time The time level at which the data in the mesh applies.

Definition at line 646 of file TwoD_TVDLF_Mesh.cpp.

References MESH_TIME.

Referenced by main().

{
return MESH_TIME;
}
DenseVector< double > CppNoddy::TwoD_TVDLF_Mesh::integrate ( std::string  mesh_colour = "black")

Integrate the concentration values across the entire mesh.

Parameters
mesh_colourThe identifier of which mesh to integrate over
Returns
The vector value of the integral

Definition at line 651 of file TwoD_TVDLF_Mesh.cpp.

References get_elts_from_colour(), and ORDER_OF_SYSTEM.

{
vector_of_elts* elts( get_elts_from_colour( mesh_colour ) );
elt_iter e = elts -> begin();
DenseVector<double> I( ORDER_OF_SYSTEM, 0.0 );
while ( e != elts -> end() )
{
const DenseVector<double> sw( 2, -1.0 );
const DenseVector<double> ne( 2, 1.0 );
I += e -> get_int_Q( sw, ne );
++e;
}
return I;
}
DenseVector< double > CppNoddy::TwoD_TVDLF_Mesh::maxmod ( DenseVector< double >  A,
DenseVector< double >  B 
) const
protected

A vector version of the maxmod operator.

Parameters
AA vector to compare
BA vector to compare
Returns
A component-wise maxmod vector, i.e., each component of the returned vector is the maxmod of the components of A & B.

Definition at line 997 of file TwoD_TVDLF_Mesh.cpp.

References CppNoddy::DenseVector< _Type >::push_back(), sgn(), and CppNoddy::DenseVector< _Type >::size().

Referenced by calc_slopes().

{
DenseVector<double> MM;
for ( std::size_t i = 0; i < A.size(); ++i )
{
MM.push_back( 0.5 * ( sgn( A[i] ) + sgn( B[i] ) )
* std::max( std::abs( A[i] ), std::abs( B[i] ) ) );
}
return MM;
}
DenseVector< double > CppNoddy::TwoD_TVDLF_Mesh::minmod ( DenseVector< double >  A,
DenseVector< double >  B 
) const
protected

A vector version of the minmod operator.

Parameters
AA vector to compare
BA vector to compare
Returns
A component-wise minmod vector, i.e., each component of the returned vector is the minmod of the components of A & B.

Definition at line 986 of file TwoD_TVDLF_Mesh.cpp.

References CppNoddy::DenseVector< _Type >::push_back(), sgn(), and CppNoddy::DenseVector< _Type >::size().

Referenced by calc_slopes().

{
DenseVector<double> MM;
for ( std::size_t i = 0; i < A.size(); ++i )
{
MM.push_back( 0.5 * ( sgn( A[i] ) + sgn( B[i] ) )
* std::min( std::abs( A[i] ), std::abs( B[i] ) ) );
}
return MM;
}
DenseVector< double > CppNoddy::TwoD_TVDLF_Mesh::north_diff ( elt_iter  e) const
protected

Compute a finite difference approximation of the derivative in the compass direction.

Parameters
eThe iterator to the element that we want the derivative for
Returns
The spatial derivative of the vector system

Definition at line 871 of file TwoD_TVDLF_Mesh.cpp.

References boundary_diff(), ORDER_OF_SYSTEM, and south_diff().

Referenced by calc_slopes(), NS_diff(), and south_diff().

{
DenseVector<double> diff( ORDER_OF_SYSTEM, 0.0 );
std::set< int > faces( e -> get_external_faces() );
const int face_index( 2 );
if ( e -> face_is_external( face_index ) )
{
// interior difference
diff = south_diff( e );
boundary_diff( e, face_index, diff );
}
else
{
// We're not on an edge, so we can difference
elt_iter j( e -> get_ptrs( face_index ) );
diff = ( j -> get_Q_mid() - e -> get_Q_mid() )
/ ( j -> get_x_mid()[1] - e -> get_x_mid()[1] );
}
return diff;
}
DenseVector< double > CppNoddy::TwoD_TVDLF_Mesh::NS_diff ( elt_iter  e)
protected

Compute a finite difference approximation of the derivative in the compass direction.

Parameters
eThe iterator to the element that we want the derivative for
Returns
The spatial derivative of the vector system

Definition at line 913 of file TwoD_TVDLF_Mesh.cpp.

References boundary_diff(), north_diff(), ORDER_OF_SYSTEM, and south_diff().

Referenced by calc_slopes().

{
DenseVector<double> diff( ORDER_OF_SYSTEM, 0.0 );
std::set< int > faces( e -> get_external_faces() );
if ( e -> face_is_external( 0 ) )
{
// interior difference
diff = north_diff( e );
boundary_diff( e, 0, diff );
}
else
if ( e -> face_is_external( 2 ) )
{
// interior difference
diff = south_diff( e );
boundary_diff( e, 2, diff );
}
else
{
// We're not on an edge, so we can difference
elt_iter jS( e -> get_ptrs( 0 ) );
elt_iter jN( e -> get_ptrs( 2 ) );
diff = ( jN -> get_Q_mid() - jS -> get_Q_mid() )
/ ( jN -> get_x_mid()[1] - jS -> get_x_mid()[1] );
}
return diff;
}
void CppNoddy::TwoD_TVDLF_Mesh::set_boundary_Q ( vector_of_elts elts)
inlineprotected

Loops over all boundary elements and sets the Q values in each one to be the value specified by the edge_values method.

Parameters
eltsA vector of elements in the mesh

Definition at line 332 of file TwoD_TVDLF_Mesh.h.

References ORDER_OF_SYSTEM, and CppNoddy::Example::s.

Referenced by calc_slopes().

{
// loop over all elts
elt_iter e( elts -> begin() );
while ( e != elts -> end() )
{
// find the external elts that are on the boundary
if ( e -> get_external_flag() )
{
std::set<int> faces( e -> get_external_faces() );
std::set<int>::iterator i( faces.begin() );
// loop through all external faces (there are 2 on corner elts)
while ( i != faces.end() )
{
int face( *i );
// local coordinate at which to impose the BC
DenseVector<double> s( 2, 0.0 );
switch ( face )
{
case 0:
s[ 0 ] = 0.0;
s[ 1 ] = -1.0;
break;
case 1:
s[ 0 ] = 1.0;
s[ 1 ] = 0.0;
break;
case 2:
s[ 0 ] = 0.0;
s[ 1 ] = 1.0;
break;
case 3:
s[ 0 ] = -1.0;
s[ 1 ] = 0.0;
break;
}
// get the current edge data
DenseVector<double> Qe( e -> get_Q( s ) );
//// initialise the normal slope vector
// DenseVector<double> sigma_n( ORDER_OF_SYSTEM, 0.0 );
// get the user specified edge values
std::vector<bool> inflow = e -> p_system -> edge_values( face, e -> get_x( s ), Qe ); //, sigma_n );
// get the mid-element nodal data
DenseVector<double> Qm( e -> get_Q_mid() );
for ( std::size_t j = 0; j < ORDER_OF_SYSTEM; ++j )
{
if ( inflow[ j ] == true )
{
// only change components that are inflow
Qm[ j ] = Qe[ j ];
}
}
e -> set_Q_mid( Qm );
++i;
}
}
++e;
}
}
void CppNoddy::TwoD_TVDLF_Mesh::set_limiter ( const unsigned &  id)

Set the limiter type to be applied in the slope values.

Parameters
idThe identifier of the limiter.

Definition at line 538 of file TwoD_TVDLF_Mesh.cpp.

References LIMITER.

Referenced by main().

{
LIMITER = id;
}
int CppNoddy::TwoD_TVDLF_Mesh::sgn ( double  a) const
protected

Sign of a double.

Parameters
aThe value to return the sign of
Returns
The sign of the value

Definition at line 969 of file TwoD_TVDLF_Mesh.cpp.

Referenced by maxmod(), and minmod().

{
if ( a > 0.0 )
{
return 1;
}
else
if ( a < 0.0 )
{
return -1;
}
else
{
return 0;
}
}
DenseVector< double > CppNoddy::TwoD_TVDLF_Mesh::south_diff ( elt_iter  e) const
protected

Compute a finite difference approximation of the derivative in the compass direction.

Parameters
eThe iterator to the element that we want the derivative for
Returns
The spatial derivative of the vector system

Definition at line 892 of file TwoD_TVDLF_Mesh.cpp.

References boundary_diff(), north_diff(), and ORDER_OF_SYSTEM.

Referenced by calc_slopes(), north_diff(), and NS_diff().

{
DenseVector<double> diff( ORDER_OF_SYSTEM, 0.0 );
std::set< int > faces( e -> get_external_faces() );
const int face_index( 0 );
if ( e -> face_is_external( face_index ) )
{
// interior difference
diff = north_diff( e );
boundary_diff( e, face_index, diff );
}
else
{
// We're not on an edge, so we can difference
elt_iter j( e -> get_ptrs( face_index ) );
diff = ( e -> get_Q_mid() - j -> get_Q_mid() )
/ ( e -> get_x_mid()[1] - j -> get_x_mid()[1] );
}
return diff;
}
double CppNoddy::TwoD_TVDLF_Mesh::update ( const double &  CFL,
const double &  max_dt = std::numeric_limits<long double>::max() 
)

Update the mesh object.

A time step is chosen based upon the CFL constraint.

Parameters
CFLThe CFL constraint for the timestep (e.g. 0.49)
max_dtA maximum timestep to be taken irrespective of the CFL value
Returns
The total timestep that was taken

Definition at line 543 of file TwoD_TVDLF_Mesh.cpp.

References actions_before_time_step1(), actions_before_time_step2(), BLACK_ELTS, calc_slopes(), MESH_TIME, and RED_ELTS.

Referenced by main(), and update_to().

{
// integrate the black mesh data onto the red mesh
{
elt_iter e = RED_ELTS.begin();
while ( e != RED_ELTS.end() )
{
e -> set_Q_mid( e -> contributed_Q() / e -> get_dA() );
++e;
}
}
// determine the first time step from the CFL constraint
double first_dt;
{
elt_iter e = BLACK_ELTS.begin();
first_dt = e -> get_max_dt();
++e;
while ( e != BLACK_ELTS.end() )
{
first_dt = std::min( first_dt, e -> get_max_dt() );
++e;
}
first_dt *= CFL;
}
if ( first_dt > max_dt / 2 )
{
first_dt = max_dt / 2;
}
// do the time step
{
elt_iter e = RED_ELTS.begin();
while ( e != RED_ELTS.end() )
{
// add to the corrections
e -> add_flux_contributions( first_dt );
++e;
}
}
MESH_TIME += first_dt;
// integrate the red mesh data onto the black mesh
{
elt_iter e = BLACK_ELTS.begin();
while ( e != BLACK_ELTS.end() )
{
e -> set_Q_mid( e -> contributed_Q() / e -> get_dA() );
++e;
}
}
// determine the first time step from the CFL constraint
double second_dt;
{
elt_iter e = RED_ELTS.begin();
second_dt = e -> get_max_dt();
++e;
while ( e != RED_ELTS.end() )
{
second_dt = std::min( second_dt, e -> get_max_dt() );
++e;
}
second_dt *= CFL;
}
if ( first_dt + second_dt > max_dt )
{
second_dt = max_dt - first_dt;
}
// do the time step
{
elt_iter e = BLACK_ELTS.begin();
while ( e != BLACK_ELTS.end() )
{
// add to the corrections
e -> add_flux_contributions( second_dt );
++e;
}
}
MESH_TIME += second_dt;
//std::cout << " currently at " << MESH_TIME << "\n";
return first_dt + second_dt;
}
void CppNoddy::TwoD_TVDLF_Mesh::update_to ( const double &  CFL,
const double &  t_end 
)

Update the mesh object to a set time level.

A time step is chosen based upon the CFL constraint.

Parameters
CFLThe CFL constraint for the timestep (e.g. 0.49)
t_endThe target end time.

Definition at line 636 of file TwoD_TVDLF_Mesh.cpp.

References MESH_TIME, and update().

{
do
{
std::cout << " computing to " << t_end << "\n";
update( CFL, std::abs( t_end - MESH_TIME ) );
}
while ( MESH_TIME < t_end );
}
DenseVector< double > CppNoddy::TwoD_TVDLF_Mesh::west_diff ( elt_iter  e) const
protected

Compute a finite difference approximation of the derivative in the compass direction.

Parameters
eThe iterator to the element that we want the derivative for
Returns
The spatial derivative of the vector system

Definition at line 850 of file TwoD_TVDLF_Mesh.cpp.

References boundary_diff(), east_diff(), and ORDER_OF_SYSTEM.

Referenced by calc_slopes(), east_diff(), and EW_diff().

{
DenseVector<double> diff( ORDER_OF_SYSTEM, 0.0 );
std::set< int > faces( e -> get_external_faces() );
const int face_index( 3 );
if ( e -> face_is_external( face_index ) )
{
// interior difference
diff = east_diff( e );
boundary_diff( e, face_index, diff );
}
else
{
// We're not on an edge, so we can difference
elt_iter j( e -> get_ptrs( face_index ) );
diff = ( e -> get_Q_mid() - j -> get_Q_mid() )
/ ( e -> get_x_mid()[0] - j -> get_x_mid()[0] );
}
return diff;
}

Member Data Documentation

vector_of_elts CppNoddy::TwoD_TVDLF_Mesh::BLACK_ELTS

An STL vector of linear elements – the black mesh.

Definition at line 130 of file TwoD_TVDLF_Mesh.h.

Referenced by dump_data(), dump_gnu(), dump_nodes_x(), dump_nodes_y(), get_elt_iter_from_elt_iter(), get_elts_from_colour(), TwoD_TVDLF_Mesh(), and update().

unsigned CppNoddy::TwoD_TVDLF_Mesh::LIMITER
protected

Slope limiter method.

Definition at line 393 of file TwoD_TVDLF_Mesh.h.

Referenced by calc_slopes(), set_limiter(), and TwoD_TVDLF_Mesh().

double CppNoddy::TwoD_TVDLF_Mesh::MESH_TIME
protected

the time level of the mesh

Definition at line 399 of file TwoD_TVDLF_Mesh.h.

Referenced by get_time(), TwoD_TVDLF_Mesh(), update(), and update_to().

std::size_t CppNoddy::TwoD_TVDLF_Mesh::NX
protected

number of faces in the x & y directions

Definition at line 397 of file TwoD_TVDLF_Mesh.h.

Referenced by dump_nodes_x(), dump_nodes_y(), get_elt_iter_from_elt_iter(), get_number_elts_in_x(), and TwoD_TVDLF_Mesh().

std::size_t CppNoddy::TwoD_TVDLF_Mesh::NY
protected

Definition at line 397 of file TwoD_TVDLF_Mesh.h.

Referenced by dump_nodes_y(), get_elt_iter_from_elt_iter(), and TwoD_TVDLF_Mesh().

std::size_t CppNoddy::TwoD_TVDLF_Mesh::ORDER_OF_SYSTEM
protected
fn_ptr CppNoddy::TwoD_TVDLF_Mesh::p_Q_INIT
protected

function pointer to a funnction that defines the initial distribution

Definition at line 401 of file TwoD_TVDLF_Mesh.h.

Referenced by TwoD_TVDLF_Mesh().

vector_of_elts CppNoddy::TwoD_TVDLF_Mesh::RED_ELTS

An STL vector of linear elements – the red mesh.

Definition at line 132 of file TwoD_TVDLF_Mesh.h.

Referenced by get_elt_iter_from_elt_iter(), get_elts_from_colour(), TwoD_TVDLF_Mesh(), and update().


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

© 2012

R.E. Hewitt