Commit f57dfa9d authored by Chris Cantwell's avatar Chris Cantwell

Merge branch 'fix/Stability3D' into 'master'

Tidy linearised advection and fix full 3D

This MR simplifies the logic of `LinearisedAdvection::v_Advect`, reducing the dependency on the dimension and handling all components in a single loop. In doing so, I think this fixes the full 3D case, which was not working. Also, the gradient of the base flow is now computed in a separate function and stored in `m_gradBase`, avoiding the need to recompute this every time-step for steady base flows.

The adjoint advection is now derived from LinearisedAdvection, eliminating a lot of duplicate code. It only needs to redefine v_Advect, which now follows a similar structure to the new implementation from LinearisedAdvection.

See merge request !708
parents 41212019 8d010c7f
......@@ -47,6 +47,7 @@ v4.4.0
**IncNavierStokesSolver:**
- Add ability to simulate additional scalar fields (!624)
- Improve performance when using homogeneous dealiasing (!622)
- Fix linearised advection for full 3D cases (!708)
**FieldConvert:**
- Allow equi-spaced output for 1D and 2DH1D fields (!613)
......
......@@ -125,7 +125,8 @@ void Advection::v_InitObject(
*
*/
void Advection::v_SetBaseFlow(
const Array<OneD, Array<OneD, NekDouble> > &inarray)
const Array<OneD, Array<OneD, NekDouble> > &inarray,
const Array<OneD, MultiRegions::ExpListSharedPtr> &fields)
{
ASSERTL0(false,
"A baseflow is not appropriate for this advection type.");
......
......@@ -123,9 +123,11 @@ public:
*
* @param inarray Vector to use as baseflow
*/
inline void SetBaseFlow(const Array<OneD, Array<OneD, NekDouble> >& inarray)
inline void SetBaseFlow(
const Array<OneD, Array<OneD, NekDouble> >& inarray,
const Array<OneD, MultiRegions::ExpListSharedPtr> &fields)
{
v_SetBaseFlow(inarray);
v_SetBaseFlow(inarray, fields);
}
protected:
......@@ -155,7 +157,8 @@ protected:
/// Overrides the base flow used during linearised advection
SOLVER_UTILS_EXPORT virtual void v_SetBaseFlow(
const Array<OneD, Array<OneD, NekDouble> > &inarray);
const Array<OneD, Array<OneD, NekDouble> > &inarray,
const Array<OneD, MultiRegions::ExpListSharedPtr> &fields);
};
/// A shared pointer to an Advection object.
......
......@@ -226,7 +226,7 @@ void DriverSteadyState::v_Execute(ostream &out)
m_equ[m_nequ - 1]->Checkpoint_BaseFlow(m_Check_BaseFlow);
m_Check_BaseFlow++;
A->GetAdvObject()->SetBaseFlow(q0);
A->GetAdvObject()->SetBaseFlow(q0,m_equ[0]->UpdateFields());
DriverModifiedArnoldi::v_Execute(out);
if (m_comm->GetRank() == 0)
......@@ -262,7 +262,7 @@ void DriverSteadyState::v_Execute(ostream &out)
m_equ[m_nequ - 1]->Checkpoint_BaseFlow(m_Check_BaseFlow);
m_Check_BaseFlow++;
A->GetAdvObject()->SetBaseFlow(q0);
A->GetAdvObject()->SetBaseFlow(q0,m_equ[0]->UpdateFields());
DriverModifiedArnoldi::v_Execute(out);
if (m_comm->GetRank() == 0)
......
......@@ -36,148 +36,43 @@
#ifndef NEKTAR_SOLVERS_ADJOINTADVECTION_H
#define NEKTAR_SOLVERS_ADJOINTADVECTION_H
#include <SolverUtils/Advection/Advection.h>
#include <LibUtilities/FFT/NektarFFT.h>
#include <IncNavierStokesSolver/AdvectionTerms/LinearisedAdvection.h>
namespace Nektar
{
/// Advection for the adjoint form of the linearised Navier-Stokes equations
class AdjointAdvection: public SolverUtils::Advection
class AdjointAdvection: public LinearisedAdvection
{
enum FloquetMatType
{
eForwardsCoeff,
eForwardsPhys
};
/// A map between matrix keys and their associated block matrices.
typedef std::map< FloquetMatType, DNekBlkMatSharedPtr> FloquetBlockMatrixMap;
/// A shared pointer to a BlockMatrixMap.
typedef boost::shared_ptr<FloquetBlockMatrixMap> FloquetBlockMatrixMapShPtr;
public:
friend class MemoryManager<AdjointAdvection>;
/// Creates an instance of this class
static SolverUtils::AdvectionSharedPtr create(std::string) {
return MemoryManager<AdjointAdvection>::AllocateSharedPtr();
}
/// Name of class
static std::string className;
protected:
LibUtilities::SessionReaderSharedPtr m_session;
MultiRegions::ProjectionType m_projectionType;
int m_spacedim;
int m_expdim;
/// Storage for base flow
Array<OneD, Array<OneD, NekDouble> > m_baseflow;
//number of slices
int m_slices;
//period length
NekDouble m_period;
//interpolation vector
Array<OneD, Array<OneD, NekDouble> > m_interp;
//auxiliary variables
LibUtilities::NektarFFTSharedPtr m_FFT;
Array<OneD,NekDouble> m_tmpIN;
Array<OneD,NekDouble> m_tmpOUT;
bool m_useFFTW;
/// flag to determine if use single mode or not
bool m_SingleMode;
/// flag to determine if use half mode or not
bool m_HalfMode;
/// flag to determine if use multiple mode or not
bool m_MultipleModes;
bool m_homogen_dealiasing;
MultiRegions::CoeffState m_CoeffState;
DNekBlkMatSharedPtr GetFloquetBlockMatrix(
FloquetMatType mattype,
bool UseContCoeffs = false) const;
DNekBlkMatSharedPtr GenFloquetBlockMatrix(
FloquetMatType mattype,
bool UseContCoeffs = false) const;
FloquetBlockMatrixMapShPtr m_FloquetBlockMat;
AdjointAdvection();
virtual ~AdjointAdvection();
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,
const NekDouble &time,
const Array<OneD, Array<OneD, NekDouble> > &pFwd = NullNekDoubleArrayofArray,
const Array<OneD, Array<OneD, NekDouble> > &pBwd = NullNekDoubleArrayofArray);
virtual void v_SetBaseFlow(
const Array<OneD, Array<OneD, NekDouble> > &inarray);
void UpdateBase(
const NekDouble m_slices,
const Array<OneD, const NekDouble> &inarray,
Array<OneD, NekDouble> &outarray,
const NekDouble m_time,
const NekDouble m_period);
void DFT(
const std::string file,
Array<OneD, MultiRegions::ExpListSharedPtr> &pFields,
const NekDouble m_slices);
/// Import Base flow
void ImportFldBase(
std::string pInfile,
Array<OneD, MultiRegions::ExpListSharedPtr> &pFields,
int slice);
private:
///Parameter for homogeneous expansions
enum HomogeneousType
{
eHomogeneous1D,
eHomogeneous2D,
eHomogeneous3D,
eNotHomogeneous
};
/// flag to determine if use or not the FFT for transformations
bool m_useFFT;
enum HomogeneousType m_HomogeneousType;
NekDouble m_LhomX; ///< physical length in X direction (if homogeneous)
NekDouble m_LhomY; ///< physical length in Y direction (if homogeneous)
NekDouble m_LhomZ; ///< physical length in Z direction (if homogeneous)
int m_npointsX; ///< number of points in X direction (if homogeneous)
int m_npointsY; ///< number of points in Y direction (if homogeneous)
int m_npointsZ; ///< number of points in Z direction (if homogeneous)
int m_HomoDirec; ///< number of homogenous directions
int m_NumMode; ///< Mode to use in case of single mode analysis
SpatialDomains::BoundaryConditionsSharedPtr m_boundaryConditions;
public:
friend class MemoryManager<AdjointAdvection>;
/// Creates an instance of this class
static SolverUtils::AdvectionSharedPtr create(std::string)
{
return MemoryManager<AdjointAdvection>::AllocateSharedPtr();
}
/// Name of class
static std::string className;
protected:
AdjointAdvection();
virtual ~AdjointAdvection();
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,
const Array<OneD, Array<OneD, NekDouble> > &pFwd =
NullNekDoubleArrayofArray,
const Array<OneD, Array<OneD, NekDouble> > &pBwd =
NullNekDoubleArrayofArray);
};
}
......
......@@ -43,7 +43,6 @@
namespace Nektar
{
class LinearisedAdvection: public SolverUtils::Advection
{
enum FloquetMatType
......@@ -62,7 +61,8 @@ public:
friend class MemoryManager<LinearisedAdvection>;
/// Creates an instance of this class
static SolverUtils::AdvectionSharedPtr create(std::string) {
static SolverUtils::AdvectionSharedPtr create(std::string)
{
return MemoryManager<LinearisedAdvection>::AllocateSharedPtr();
}
/// Name of class
......@@ -76,6 +76,7 @@ protected:
/// Storage for base flow
Array<OneD, Array<OneD, NekDouble> > m_baseflow;
Array<OneD, Array<OneD, NekDouble> > m_gradBase;
/// number of slices
int m_slices;
......@@ -123,7 +124,8 @@ protected:
const Array<OneD, Array<OneD, NekDouble> > &pBwd = NullNekDoubleArrayofArray);
virtual void v_SetBaseFlow(
const Array<OneD, Array<OneD, NekDouble> > &inarray);
const Array<OneD, Array<OneD, NekDouble> > &inarray,
const Array<OneD, MultiRegions::ExpListSharedPtr> &fields);
void UpdateBase(
const NekDouble m_slices,
......@@ -132,6 +134,10 @@ protected:
const NekDouble m_time,
const NekDouble m_period);
void UpdateGradBase(
const int var,
const MultiRegions::ExpListSharedPtr &field);
void DFT(
const std::string file,
Array<OneD, MultiRegions::ExpListSharedPtr> &pFields,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment