Commit bc340bb8 authored by Dave Moxey's avatar Dave Moxey
Browse files

Merge branch 'feature/MoveAdvectionClass' into 'master'

Feature/move advection class

This MR concerns a restructuring of the handling of advection objects:
- Advection terms in IncNavierStokesSolver now derive from the SolverUtils Advection base class
- A new AdvectionSystem holds the Advection term at Driver level and sits between UnsteadySystem and a specific solvers EquationSystems (to allow Advection objects to be manipulated at Driver level)
- Moved instantiation of the extrapolation terms to the most derived classes in IncNavierStokesSolver. Previously m_fields needed to be initialised (through a call to UnsteadySystem::v_InitObject()), the m_pressure pointer set, and then the extrapolation term initialised through calling IncNavierStokes::v_InitObject(). However, this now also calls UnsteadySystem::v_InitObject resulting in m_fields being initialised twice and m_pressure and m_fields[m_nConvectiveFields] being different.
- Some tidying up of the advection term code.

A similar structure can be adopted for the diffusion terms. The AdvectionSystem class therefore inherits UnsteadySystem virtually to allow this to be implemented.

See merge request !408
parents 0ba33b73 88080de7
......@@ -37,52 +37,93 @@
namespace Nektar
{
namespace SolverUtils
namespace SolverUtils
{
/**
* @returns The advection factory.
*/
AdvectionFactory& GetAdvectionFactory()
{
typedef Loki::SingletonHolder<AdvectionFactory,
Loki::CreateUsingNew,
Loki::NoDestroy > Type;
return Type::Instance();
}
/**
* @param pSession Session configuration data.
* @param pFields Array of ExpList objects.
*/
void Advection::InitObject(
const LibUtilities::SessionReaderSharedPtr pSession,
Array<OneD, MultiRegions::ExpListSharedPtr> pFields)
{
v_InitObject(pSession, pFields);
}
/**
* @param nConvectiveFields Number of velocity components.
* @param pFields Expansion lists for scalar fields.
* @param pAdvVel Advection velocity.
* @param pInarray Scalar data to advect.
* @param pOutarray Advected scalar data.
* @param pTime Simulation time.
*/
void Advection::Advect(
const int nConvectiveFields,
const Array<OneD, MultiRegions::ExpListSharedPtr> &pFields,
const Array<OneD, Array<OneD, NekDouble> > &pAdvVel,
const Array<OneD, Array<OneD, NekDouble> > &pInarray,
Array<OneD, Array<OneD, NekDouble> > &pOutarray,
const NekDouble &pTime)
{
v_Advect(nConvectiveFields, pFields, pAdvVel, pInarray, pOutarray, pTime);
}
/**
* This function should be overridden in derived classes to initialise the
* specific advection data members. However, this base class function should
* be called as the first statement of the overridden function to ensure the
* base class is correctly initialised in order.
*
* @param pSession Session information.
* @param pFields Expansion lists for scalar fields.
*/
void Advection::v_InitObject(
const LibUtilities::SessionReaderSharedPtr pSession,
Array<OneD, MultiRegions::ExpListSharedPtr> pFields)
{
m_spaceDim = pFields[0]->GetCoordim(0);
if (pSession->DefinesSolverInfo("HOMOGENEOUS"))
{
AdvectionFactory& GetAdvectionFactory()
std::string HomoStr = pSession->GetSolverInfo("HOMOGENEOUS");
if (HomoStr == "HOMOGENEOUS1D" || HomoStr == "Homogeneous1D" ||
HomoStr == "1D" || HomoStr == "Homo1D")
{
typedef Loki::SingletonHolder<AdvectionFactory,
Loki::CreateUsingNew,
Loki::NoDestroy > Type;
return Type::Instance();
m_spaceDim++;
}
void Advection::InitObject(
const LibUtilities::SessionReaderSharedPtr pSession,
Array<OneD, MultiRegions::ExpListSharedPtr> pFields)
else
{
v_InitObject(pSession, pFields);
ASSERTL0(false, "Only 1D homogeneous dimension supported.");
}
}
}
void Advection::Advect(
const int nConvectiveFields,
const Array<OneD, MultiRegions::ExpListSharedPtr> &fields,
const Array<OneD, Array<OneD, NekDouble> > &advVel,
const Array<OneD, Array<OneD, NekDouble> > &inarray,
Array<OneD, Array<OneD, NekDouble> > &outarray)
{
v_Advect(nConvectiveFields, fields, advVel, inarray, outarray);
}
void Advection::v_InitObject(
const LibUtilities::SessionReaderSharedPtr pSession,
Array<OneD, MultiRegions::ExpListSharedPtr> pFields)
{
m_spaceDim = pFields[0]->GetCoordim(0);
/**
*
*/
void Advection::v_SetBaseFlow(
const Array<OneD, Array<OneD, NekDouble> > &inarray)
{
ASSERTL0(false,
"A baseflow is not appropriate for this advection type.");
}
if (pSession->DefinesSolverInfo("HOMOGENEOUS"))
{
std::string HomoStr = pSession->GetSolverInfo("HOMOGENEOUS");
if (HomoStr == "HOMOGENEOUS1D" || HomoStr == "Homogeneous1D" ||
HomoStr == "1D" || HomoStr == "Homo1D")
{
m_spaceDim++;
}
else
{
ASSERTL0(false, "Only 1D homogeneous dimension supported.");
}
}
}
}
}
}
......@@ -47,101 +47,125 @@
namespace Nektar
{
namespace SolverUtils
namespace SolverUtils
{
/// Defines a callback function which evaluates the flux vector \f$ F(u)
/// \f$ in a conservative advection of the form \f$ \nabla\cdot F(u)
/// \f$.
typedef boost::function<void (
const Array<OneD, Array<OneD, NekDouble> >&,
Array<OneD, Array<OneD, Array<OneD, NekDouble> > >&)>
AdvectionFluxVecCB;
/**
* @brief An abstract base class encapsulating the concept of advection
* of a vector field.
*
* Subclasses override the Advection::v_InitObject function to
* initialise the object and the Advection::v_Advect function to
* evaluate the advection of the vector field.
*/
class Advection
{
public:
/// Interface function to initialise the advection object.
SOLVER_UTILS_EXPORT void InitObject(
LibUtilities::SessionReaderSharedPtr pSession,
Array<OneD, MultiRegions::ExpListSharedPtr> pFields);
/// Interface function to advect the vector field.
SOLVER_UTILS_EXPORT void Advect(
const int nConvectiveFields,
const Array<OneD, MultiRegions::ExpListSharedPtr> &fields,
const Array<OneD, Array<OneD, NekDouble> > &advVel,
const Array<OneD, Array<OneD, NekDouble> > &inarray,
Array<OneD, Array<OneD, NekDouble> > &outarray,
const NekDouble &time);
/**
* @brief Set the flux vector callback function.
*
* This routine is a utility function to avoid the explicit use of
* boost::bind. A function and object can be passed to this function
* instead.
*/
template<typename FuncPointerT, typename ObjectPointerT>
void SetFluxVector(FuncPointerT func, ObjectPointerT obj)
{
m_fluxVector = boost::bind(func, obj, _1, _2);
}
/**
* @brief Set a Riemann solver object for this advection object.
*
* @param riemann The RiemannSolver object.
*/
inline void SetRiemannSolver(RiemannSolverSharedPtr riemann)
{
m_riemann = riemann;
}
/**
* @brief Set the flux vector callback function.
*
* @param fluxVector The callback function to override.
*/
inline void SetFluxVector(AdvectionFluxVecCB fluxVector)
{
/// Defines a callback function which evaluates the flux vector \f$ F(u)
/// \f$ in a conservative advection of the form \f$ \nabla\cdot F(u)
/// \f$.
typedef boost::function<void (
const Array<OneD, Array<OneD, NekDouble> >&,
Array<OneD, Array<OneD, Array<OneD, NekDouble> > >&)>
AdvectionFluxVecCB;
/**
* @brief An abstract base class encapsulating the concept of advection
* of a vector field.
*
* Subclasses override the Advection::v_InitObject function to
* initialise the object and the Advection::v_Advect function to
* evaluate the advection of the vector field.
*/
class Advection
{
public:
SOLVER_UTILS_EXPORT void InitObject(
LibUtilities::SessionReaderSharedPtr pSession,
Array<OneD, MultiRegions::ExpListSharedPtr> pFields);
SOLVER_UTILS_EXPORT void Advect(
const int nConvectiveFields,
const Array<OneD, MultiRegions::ExpListSharedPtr> &fields,
const Array<OneD, Array<OneD, NekDouble> > &advVel,
const Array<OneD, Array<OneD, NekDouble> > &inarray,
Array<OneD, Array<OneD, NekDouble> > &outarray);
/**
* @brief Set the flux vector callback function.
*
* This routine is a utility function to avoid the explicit use of
* boost::bind. A function and object can be passed to this function
* instead.
*/
template<typename FuncPointerT, typename ObjectPointerT>
void SetFluxVector(FuncPointerT func, ObjectPointerT obj)
{
m_fluxVector = boost::bind(func, obj, _1, _2);
}
/**
* @brief Set a Riemann solver object for this advection object.
*
* @param riemann The RiemannSolver object.
*/
inline void SetRiemannSolver(RiemannSolverSharedPtr riemann)
{
m_riemann = riemann;
}
/**
* @brief Set the flux vector callback function.
*
* @param fluxVector The callback function to override.
*/
inline void SetFluxVector(AdvectionFluxVecCB fluxVector)
{
m_fluxVector = fluxVector;
}
protected:
virtual void v_InitObject(
LibUtilities::SessionReaderSharedPtr pSession,
Array<OneD, MultiRegions::ExpListSharedPtr> pFields);
virtual void v_Advect(
const int nConvectiveFields,
const Array<OneD, MultiRegions::ExpListSharedPtr> &fields,
const Array<OneD, Array<OneD, NekDouble> > &advVel,
const Array<OneD, Array<OneD, NekDouble> > &inarray,
Array<OneD, Array<OneD, NekDouble> > &outarray)=0;
/// Callback function to the flux vector (set when advection is in
/// conservative form).
AdvectionFluxVecCB m_fluxVector;
/// Riemann solver for DG-type schemes.
RiemannSolverSharedPtr m_riemann;
/// Storage for space dimension. Used for homogeneous extension.
int m_spaceDim;
};
/// A shared pointer to an Advection object.
typedef boost::shared_ptr<Advection> AdvectionSharedPtr;
/// Datatype of the NekFactory used to instantiate classes derived
/// from the Advection class.
typedef LibUtilities::NekFactory<std::string, Advection,
std::string> AdvectionFactory;
SOLVER_UTILS_EXPORT AdvectionFactory& GetAdvectionFactory();
m_fluxVector = fluxVector;
}
/**
* @brief Set the base flow used for linearised advection objects.
*
* @param inarray Vector to use as baseflow
*/
inline void SetBaseFlow(const Array<OneD, Array<OneD, NekDouble> >& inarray)
{
v_SetBaseFlow(inarray);
}
protected:
/// Callback function to the flux vector (set when advection is in
/// conservative form).
AdvectionFluxVecCB m_fluxVector;
/// Riemann solver for DG-type schemes.
RiemannSolverSharedPtr m_riemann;
/// Storage for space dimension. Used for homogeneous extension.
int m_spaceDim;
/// Initialises the advection object.
SOLVER_UTILS_EXPORT virtual void v_InitObject(
LibUtilities::SessionReaderSharedPtr pSession,
Array<OneD, MultiRegions::ExpListSharedPtr> pFields);
/// Advects a vector field.
SOLVER_UTILS_EXPORT virtual void v_Advect(
const int nConvectiveFields,
const Array<OneD, MultiRegions::ExpListSharedPtr> &fields,
const Array<OneD, Array<OneD, NekDouble> > &advVel,
const Array<OneD, Array<OneD, NekDouble> > &inarray,
Array<OneD, Array<OneD, NekDouble> > &outarray,
const NekDouble &time)=0;
/// Overrides the base flow used during linearised advection
SOLVER_UTILS_EXPORT virtual void v_SetBaseFlow(
const Array<OneD, Array<OneD, NekDouble> > &inarray);
};
/// A shared pointer to an Advection object.
typedef boost::shared_ptr<Advection> AdvectionSharedPtr;
/// Datatype of the NekFactory used to instantiate classes derived
/// from the Advection class.
typedef LibUtilities::NekFactory<std::string, Advection,
std::string> AdvectionFactory;
/// Gets the factory for initialising advection objects.
SOLVER_UTILS_EXPORT AdvectionFactory& GetAdvectionFactory();
}
}
#endif
......@@ -191,7 +191,8 @@ namespace Nektar
const Array<OneD, MultiRegions::ExpListSharedPtr> &fields,
const Array<OneD, Array<OneD, NekDouble> > &advVel,
const Array<OneD, Array<OneD, NekDouble> > &inarray,
Array<OneD, Array<OneD, NekDouble> > &outarray)
Array<OneD, Array<OneD, NekDouble> > &outarray,
const NekDouble &time)
{
Array<OneD, NekDouble> tmp(m_numPoints), tmp2;
int nVel = advVel.num_elements();
......@@ -226,7 +227,7 @@ namespace Nektar
// Compute advection term for this plane.
m_planeAdv->Advect(nConvectiveFields, m_fieldsPlane,
m_advVelPlane, m_inarrayPlane,
m_outarrayPlane);
m_outarrayPlane, time);
}
// Calculate Fourier derivative and add to final result.
......
......@@ -73,7 +73,7 @@ namespace Nektar
Array<OneD, Array<OneD, NekDouble> > m_advVelPlane;
Array<OneD, Array<OneD, Array<OneD, Array<OneD, NekDouble> > > >
m_fluxVecPlane;
virtual void v_InitObject(
LibUtilities::SessionReaderSharedPtr pSession,
Array<OneD, MultiRegions::ExpListSharedPtr> pFields);
......@@ -83,7 +83,8 @@ namespace Nektar
const Array<OneD, MultiRegions::ExpListSharedPtr> &fields,
const Array<OneD, Array<OneD, NekDouble> > &advVel,
const Array<OneD, Array<OneD, NekDouble> > &inarray,
Array<OneD, Array<OneD, NekDouble> > &outarray);
Array<OneD, Array<OneD, NekDouble> > &outarray,
const NekDouble &time);
private:
void ModifiedFluxVector(
......
......@@ -799,7 +799,8 @@ namespace Nektar
const Array<OneD, MultiRegions::ExpListSharedPtr> &fields,
const Array<OneD, Array<OneD, NekDouble> > &advVel,
const Array<OneD, Array<OneD, NekDouble> > &inarray,
Array<OneD, Array<OneD, NekDouble> > &outarray)
Array<OneD, Array<OneD, NekDouble> > &outarray,
const NekDouble &time)
{
int i, j, n;
int phys_offset;
......
......@@ -87,7 +87,8 @@ namespace Nektar
const Array<OneD, MultiRegions::ExpListSharedPtr> &fields,
const Array<OneD, Array<OneD, NekDouble> > &advVel,
const Array<OneD, Array<OneD, NekDouble> > &inarray,
Array<OneD, Array<OneD, NekDouble> > &outarray);
Array<OneD, Array<OneD, NekDouble> > &outarray,
const NekDouble &time);
virtual void v_SetupMetrics(
LibUtilities::SessionReaderSharedPtr pSession,
......
......@@ -67,7 +67,8 @@ namespace Nektar
const Array<OneD, MultiRegions::ExpListSharedPtr> &fields,
const Array<OneD, Array<OneD, NekDouble> > &advVel,
const Array<OneD, Array<OneD, NekDouble> > &inarray,
Array<OneD, Array<OneD, NekDouble> > &outarray)
Array<OneD, Array<OneD, NekDouble> > &outarray,
const NekDouble &time)
{
int nDim = advVel.num_elements();
int nPointsTot = fields[0]->GetNpoints();
......
......@@ -64,7 +64,8 @@ namespace Nektar
const Array<OneD, MultiRegions::ExpListSharedPtr> &fields,
const Array<OneD, Array<OneD, NekDouble> > &advVel,
const Array<OneD, Array<OneD, NekDouble> > &inarray,
Array<OneD, Array<OneD, NekDouble> > &outarray);
Array<OneD, Array<OneD, NekDouble> > &outarray,
const NekDouble &time);
};
}
}
......
......@@ -78,7 +78,8 @@ namespace Nektar
const Array<OneD, MultiRegions::ExpListSharedPtr> &fields,
const Array<OneD, Array<OneD, NekDouble> > &advVel,
const Array<OneD, Array<OneD, NekDouble> > &inarray,
Array<OneD, Array<OneD, NekDouble> > &outarray)
Array<OneD, Array<OneD, NekDouble> > &outarray,
const NekDouble &time)
{
int nDim = fields[0]->GetCoordim(0);
int nPointsTot = fields[0]->GetTotPoints();
......
......@@ -64,7 +64,8 @@ namespace Nektar
const Array<OneD, MultiRegions::ExpListSharedPtr> &fields,
const Array<OneD, Array<OneD, NekDouble> > &advVel,
const Array<OneD, Array<OneD, NekDouble> > &inarray,
Array<OneD, Array<OneD, NekDouble> > &outarray);
Array<OneD, Array<OneD, NekDouble> > &outarray,
const NekDouble &time);
};
}
}
......
///////////////////////////////////////////////////////////////////////////////
//
// File: AdvectionSystem.cpp
//
// For more information, please see: http://www.nektar.info
//
// The MIT License
//
// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
// Department of Aeronautics, Imperial College London (UK), and Scientific
// Computing and Imaging Institute, University of Utah (USA).
//
// License for the specific language governing rights and limitations under
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
// Description: Base class for advection-based equation systems.
//
///////////////////////////////////////////////////////////////////////////////
#include <SolverUtils/AdvectionSystem.h>
namespace Nektar {
namespace SolverUtils {
/**
*
*/
AdvectionSystem::AdvectionSystem(
const LibUtilities::SessionReaderSharedPtr& pSession)
: UnsteadySystem(pSession)
{
}
/**
*
*/
AdvectionSystem::~AdvectionSystem()
{
}
/**
*
*/
void AdvectionSystem::v_InitObject()
{
UnsteadySystem::v_InitObject();
}
}
}
///////////////////////////////////////////////////////////////////////////////
//
// File AdvectionSystem.h
//
// For more information, please see: http://www.nektar.info
//
// The MIT License
//
// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
// Department of Aeronautics, Imperial College London (UK), and Scientific
// Computing and Imaging Institute, University of Utah (USA).
//
// License for the specific language governing rights and limitations under
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
// Description: Advection system
//
///////////////////////////////////////////////////////////////////////////////
#ifndef NEKTAR_SOLVERUTILS_ADVECTIONSYSTEM_H
#define NEKTAR_SOLVERUTILS_ADVECTIONSYSTEM_H
#include <SolverUtils/UnsteadySystem.h>
#include <SolverUtils/Advection/Advection.h>
namespace Nektar {
namespace SolverUtils {
/// A base class for PDEs which include an advection component
class AdvectionSystem: virtual public UnsteadySystem
{
public:
SOLVER_UTILS_EXPORT AdvectionSystem(
const LibUtilities::SessionReaderSharedPtr &pSession);
SOLVER_UTILS_EXPORT virtual ~AdvectionSystem();
SOLVER_UTILS_EXPORT virtual void v_InitObject();
/// Returns the advection object held by this instance.
AdvectionSharedPtr GetAdvObject()
{
return m_advObject;
}
protected:
/// Advection term
SolverUtils::AdvectionSharedPtr m_advObject;
};
/// Shared pointer to an AdvectionSystem class