Commit 2477c58d authored by Dave Moxey's avatar Dave Moxey

Merge branch 'feature/CFS-filters' into 'master'

Extend AeroForces filter to compressible flows

See merge request nektar/nektar!815
parents 982d929a 149c6a86
......@@ -16,6 +16,7 @@ v5.0.0
- Add ARPACK thirdparty build capabilities (!828)
- Added native support for csv files in addititon to pts (!760, !835, !906)
- Utilize LAPACK_DIR env variable to find the native blas/lapack install (!827)
- Extend AeroForces filter to compressible flows (!815)
- Remove StdExpansion use from MultiRegion (use Expansions instead). (!831)
- Move steady state check and CFL output from solvers to SolverUtils (!832)
- Remove DG advection implementation from EquationSystem (!832)
......
......@@ -24,7 +24,7 @@ SET(SOLVER_UTILS_SOURCES
Filters/FilterAverageFields.cpp
Filters/FilterCheckpoint.cpp
Filters/FilterEnergy1D.cpp
Filters/FilterEnergyBase.cpp
Filters/FilterEnergy.cpp
Filters/FilterHistoryPoints.cpp
Filters/FilterModalEnergy.cpp
Filters/FilterMovingAverage.cpp
......@@ -68,7 +68,7 @@ SET(SOLVER_UTILS_HEADERS
Filters/FilterAverageFields.h
Filters/FilterCheckpoint.h
Filters/FilterEnergy1D.h
Filters/FilterEnergyBase.h
Filters/FilterEnergy.h
Filters/FilterHistoryPoints.h
Filters/FilterModalEnergy.h
Filters/FilterMovingAverage.h
......
......@@ -1139,7 +1139,7 @@ namespace Nektar
variables[i] = m_boundaryConditions->GetVariable(i);
}
v_ExtraFldOutput(fieldcoeffs, variables);
ExtraFldOutput(fieldcoeffs, variables);
WriteFld(outname, m_fields[0], fieldcoeffs, variables);
}
......
......@@ -128,7 +128,11 @@ class Interpolator;
}
/// Get pressure field if available
SOLVER_UTILS_EXPORT MultiRegions::ExpListSharedPtr GetPressure();
SOLVER_UTILS_EXPORT MultiRegions::ExpListSharedPtr GetPressure();
SOLVER_UTILS_EXPORT inline void ExtraFldOutput(
std::vector<Array<OneD, NekDouble> > &fieldcoeffs,
std::vector<std::string> &variables);
/// Print a summary of parameters and solver characteristics.
SOLVER_UTILS_EXPORT inline void PrintSummary(std::ostream &out);
......@@ -567,7 +571,21 @@ class Interpolator;
{
return v_GetPressure();
}
/**
* Append the coefficients and name of variables with solver specific
* extra variables
*
* @param fieldcoeffs Vector with coefficients
* @param variables Vector with name of variables
*/
inline void EquationSystem::ExtraFldOutput(
std::vector<Array<OneD, NekDouble> > &fieldcoeffs,
std::vector<std::string> &variables)
{
v_ExtraFldOutput(fieldcoeffs, variables);
}
/**
* Prints a summary of variables and problem parameters.
*
......
......@@ -46,8 +46,10 @@ FilterFactory& GetFilterFactory()
}
Filter::Filter(const LibUtilities::SessionReaderSharedPtr& pSession) :
m_session(pSession)
Filter::Filter(const LibUtilities::SessionReaderSharedPtr &pSession,
const std::weak_ptr<EquationSystem> &pEquation) :
m_session(pSession),
m_equ(pEquation)
{
}
......
......@@ -48,6 +48,7 @@ namespace Nektar
namespace SolverUtils
{
class Filter;
class EquationSystem;
/// A shared pointer to a Driver object
typedef std::shared_ptr<Filter> FilterSharedPtr;
......@@ -57,6 +58,7 @@ typedef std::shared_ptr<Filter> FilterSharedPtr;
typedef LibUtilities::NekFactory<
std::string, Filter,
const LibUtilities::SessionReaderSharedPtr&,
const std::weak_ptr<EquationSystem>&,
const std::map<std::string, std::string>&
> FilterFactory;
SOLVER_UTILS_EXPORT FilterFactory& GetFilterFactory();
......@@ -66,7 +68,8 @@ class Filter
public:
typedef std::map<std::string, std::string> ParamMap;
SOLVER_UTILS_EXPORT Filter(
const LibUtilities::SessionReaderSharedPtr& pSession);
const LibUtilities::SessionReaderSharedPtr &pSession,
const std::weak_ptr<EquationSystem> &pEquation);
SOLVER_UTILS_EXPORT virtual ~Filter();
SOLVER_UTILS_EXPORT inline void Initialise(
......@@ -81,7 +84,8 @@ public:
SOLVER_UTILS_EXPORT inline bool IsTimeDependent();
protected:
LibUtilities::SessionReaderSharedPtr m_session;
LibUtilities::SessionReaderSharedPtr m_session;
const std::weak_ptr<EquationSystem> m_equ;
virtual void v_Initialise(
const Array<OneD, const MultiRegions::ExpListSharedPtr> &pFields,
......
......@@ -52,11 +52,11 @@ public:
/// Creates an instance of this class
static FilterSharedPtr create(
const LibUtilities::SessionReaderSharedPtr &pSession,
const std::map<std::string, std::string> &pParams)
const std::weak_ptr<EquationSystem> &pEquation,
const std::map<std::string, std::string> &pParams)
{
FilterSharedPtr p = MemoryManager<FilterAeroForces>::
AllocateSharedPtr(pSession, pParams);
//p->InitObject();
AllocateSharedPtr(pSession, pEquation, pParams);
return p;
}
......@@ -65,14 +65,15 @@ public:
SOLVER_UTILS_EXPORT FilterAeroForces(
const LibUtilities::SessionReaderSharedPtr &pSession,
const std::map<std::string, std::string> &pParams);
const std::weak_ptr<EquationSystem> &pEquation,
const std::map<std::string, std::string> &pParams);
SOLVER_UTILS_EXPORT virtual ~FilterAeroForces();
SOLVER_UTILS_EXPORT void GetForces(
const Array<OneD, const MultiRegions::ExpListSharedPtr> &pFields,
Array<OneD, NekDouble> &Aeroforces,
const NekDouble &time);
const Array<OneD, const MultiRegions::ExpListSharedPtr> &pFields,
Array<OneD, NekDouble> &Aeroforces,
const NekDouble &time);
protected:
virtual void v_Initialise(
......@@ -117,7 +118,7 @@ private:
Array<OneD, Array<OneD, NekDouble> > m_Ftplane;
NekDouble m_lastTime;
GlobalMapping::MappingSharedPtr m_mapping;
GlobalMapping::MappingSharedPtr m_mapping;
void CalculateForces(
const Array<OneD, const MultiRegions::ExpListSharedPtr> &pFields,
......
......@@ -45,9 +45,22 @@ std::string FilterAverageFields::className =
FilterAverageFields::FilterAverageFields(
const LibUtilities::SessionReaderSharedPtr &pSession,
const std::weak_ptr<EquationSystem> &pEquation,
const ParamMap &pParams)
: FilterFieldConvert(pSession, pParams)
: FilterFieldConvert(pSession, pEquation, pParams)
{
// Load sampling frequency
auto it = pParams.find("SampleFrequency");
if (it == pParams.end())
{
m_sampleFrequency = 1;
}
else
{
LibUtilities::Equation equ(
m_session->GetExpressionEvaluator(), it->second);
m_sampleFrequency = round(equ.Evaluate());
}
}
FilterAverageFields::~FilterAverageFields()
......@@ -56,12 +69,13 @@ FilterAverageFields::~FilterAverageFields()
void FilterAverageFields::v_ProcessSample(
const Array<OneD, const MultiRegions::ExpListSharedPtr> &pFields,
std::vector<Array<OneD, NekDouble> > &fieldcoeffs,
const NekDouble &time)
{
for(int n = 0; n < pFields.num_elements(); ++n)
for(int n = 0; n < m_outFields.size(); ++n)
{
Vmath::Vadd(m_outFields[n].num_elements(),
pFields[n]->GetCoeffs(),
fieldcoeffs[n],
1,
m_outFields[n],
1,
......
......@@ -50,10 +50,11 @@ public:
/// Creates an instance of this class
static FilterSharedPtr create(
const LibUtilities::SessionReaderSharedPtr &pSession,
const std::map<std::string, std::string> &pParams)
const std::weak_ptr<EquationSystem> &pEquation,
const std::map<std::string, std::string> &pParams)
{
FilterSharedPtr p = MemoryManager<FilterAverageFields>
::AllocateSharedPtr(pSession, pParams);
::AllocateSharedPtr(pSession, pEquation, pParams);
return p;
}
......@@ -62,12 +63,14 @@ public:
SOLVER_UTILS_EXPORT FilterAverageFields(
const LibUtilities::SessionReaderSharedPtr &pSession,
const std::weak_ptr<EquationSystem> &pEquation,
const ParamMap &pParams);
SOLVER_UTILS_EXPORT virtual ~FilterAverageFields();
protected:
virtual void v_ProcessSample(
const Array<OneD, const MultiRegions::ExpListSharedPtr> &pFields,
std::vector<Array<OneD, NekDouble> > &fieldcoeffs,
const NekDouble &time);
virtual void v_PrepareOutput(
const Array<OneD, const MultiRegions::ExpListSharedPtr> &pFields,
......
......@@ -45,8 +45,9 @@ std::string FilterCheckpoint::className =
FilterCheckpoint::FilterCheckpoint(
const LibUtilities::SessionReaderSharedPtr &pSession,
const std::weak_ptr<EquationSystem> &pEquation,
const ParamMap &pParams) :
Filter(pSession)
Filter(pSession, pEquation)
{
// OutputFile
auto it = pParams.find("OutputFile");
......
......@@ -50,10 +50,11 @@ public:
/// Creates an instance of this class
static FilterSharedPtr create(
const LibUtilities::SessionReaderSharedPtr &pSession,
const std::map<std::string, std::string> &pParams) {
const std::weak_ptr<EquationSystem> &pEquation,
const std::map<std::string, std::string> &pParams)
{
FilterSharedPtr p = MemoryManager<FilterCheckpoint>
::AllocateSharedPtr(pSession, pParams);
//p->InitObject();
::AllocateSharedPtr(pSession, pEquation, pParams);
return p;
}
......@@ -62,6 +63,7 @@ public:
SOLVER_UTILS_EXPORT FilterCheckpoint(
const LibUtilities::SessionReaderSharedPtr &pSession,
const std::weak_ptr<EquationSystem> &pEquation,
const ParamMap &pParams);
SOLVER_UTILS_EXPORT virtual ~FilterCheckpoint();
......
///////////////////////////////////////////////////////////////////////////////
//
// File FilterEnergyBase.cpp
// File FilterEnergy.cpp
//
// For more information, please see: http://www.nektar.info
//
......@@ -35,7 +35,8 @@
#include <iomanip>
#include <SolverUtils/Filters/FilterEnergyBase.h>
#include <SolverUtils/Filters/FilterEnergy.h>
#include <SolverUtils/Filters/FilterInterfaces.hpp>
using namespace std;
......@@ -43,15 +44,17 @@ namespace Nektar
{
namespace SolverUtils
{
FilterEnergyBase::FilterEnergyBase(
std::string FilterEnergy::className = SolverUtils::GetFilterFactory().
RegisterCreatorFunction("Energy", FilterEnergy::create);
FilterEnergy::FilterEnergy(
const LibUtilities::SessionReaderSharedPtr &pSession,
const ParamMap &pParams,
const bool pConstDensity)
: Filter (pSession),
const std::weak_ptr<EquationSystem> &pEquation,
const ParamMap &pParams)
: Filter (pSession, pEquation),
m_index (-1),
m_homogeneous (false),
m_planes (),
m_constDensity(pConstDensity)
m_planes ()
{
std::string outName;
......@@ -90,12 +93,12 @@ FilterEnergyBase::FilterEnergyBase(
m_outputFrequency = round(equ.Evaluate());
}
FilterEnergyBase::~FilterEnergyBase()
FilterEnergy::~FilterEnergy()
{
}
void FilterEnergyBase::v_Initialise(
void FilterEnergy::v_Initialise(
const Array<OneD, const MultiRegions::ExpListSharedPtr> &pFields,
const NekDouble &time)
{
......@@ -134,7 +137,7 @@ void FilterEnergyBase::v_Initialise(
v_Update(pFields, time);
}
void FilterEnergyBase::v_Update(
void FilterEnergy::v_Update(
const Array<OneD, const MultiRegions::ExpListSharedPtr> &pFields,
const NekDouble &time)
{
......@@ -147,16 +150,33 @@ void FilterEnergyBase::v_Update(
return;
}
// Lock equation system pointer
auto equ = m_equ.lock();
ASSERTL0(equ, "Weak pointer expired");
auto fluidEqu = std::dynamic_pointer_cast<FluidInterface>(equ);
ASSERTL0(fluidEqu, "Energy filter is incompatible with this solver.");
// Store physical values in an array
Array<OneD, Array<OneD, NekDouble> > physfields(pFields.num_elements());
for(i = 0; i < pFields.num_elements(); ++i)
{
physfields[i] = pFields[i]->GetPhys();
}
// Calculate kinetic energy.
NekDouble Ek = 0.0;
Array<OneD, NekDouble> tmp(nPoints, 0.0);
Array<OneD, NekDouble> density;
Array<OneD, Array<OneD, NekDouble> > u(3);
for (i = 0; i < 3; ++i)
{
u[i] = Array<OneD, NekDouble>(nPoints);
}
fluidEqu->GetVelocity(physfields, u);
v_GetVelocity(pFields, i, u[i]);
for (i = 0; i < 3; ++i)
{
if (m_homogeneous && pFields[i]->GetWaveSpace())
{
pFields[i]->HomogeneousBwdTrans(u[i], u[i]);
......@@ -165,9 +185,11 @@ void FilterEnergyBase::v_Update(
Vmath::Vvtvp(nPoints, u[i], 1, u[i], 1, tmp, 1, tmp, 1);
}
if (!m_constDensity)
if (!fluidEqu->HasConstantDensity())
{
Vmath::Vmul(nPoints, v_GetDensity(pFields), 1, tmp, 1, tmp, 1);
density = Array<OneD, NekDouble>(nPoints);
fluidEqu->GetDensity(physfields, density);
Vmath::Vmul(nPoints, density, 1, tmp, 1, tmp, 1);
}
if (m_homogeneous)
......@@ -216,9 +238,9 @@ void FilterEnergyBase::v_Update(
Vmath::Vvtvp(nPoints, tmp2, 1, tmp2, 1, tmp, 1, tmp, 1);
}
if (!m_constDensity)
if (!fluidEqu->HasConstantDensity())
{
Vmath::Vmul(nPoints, v_GetDensity(pFields), 1, tmp, 1, tmp, 1);
Vmath::Vmul(nPoints, density, 1, tmp, 1, tmp, 1);
}
if (m_homogeneous)
......@@ -243,31 +265,17 @@ void FilterEnergyBase::v_Update(
}
}
void FilterEnergyBase::v_Finalise(
void FilterEnergy::v_Finalise(
const Array<OneD, const MultiRegions::ExpListSharedPtr> &pFields,
const NekDouble &time)
{
m_outFile.close();
}
bool FilterEnergyBase::v_IsTimeDependent()
bool FilterEnergy::v_IsTimeDependent()
{
return true;
}
void FilterEnergyBase::v_GetVelocity(
const Array<OneD, const MultiRegions::ExpListSharedPtr> &pFields,
const int i,
Array<OneD, NekDouble> &velocity)
{
ASSERTL0(false, "Needs to implemented by subclass");
}
Array<OneD, NekDouble> FilterEnergyBase::v_GetDensity(
const Array<OneD, const MultiRegions::ExpListSharedPtr> &pFields)
{
ASSERTL0(false, "Needs to implemented by subclass");
return Array<OneD, NekDouble>();
}
}
}
......@@ -33,8 +33,8 @@
//
///////////////////////////////////////////////////////////////////////////////
#ifndef NEKTAR_SOLVERUTILS_FILTERS_FILTERENERGYBASE_H
#define NEKTAR_SOLVERUTILS_FILTERS_FILTERENERGYBASE_H
#ifndef NEKTAR_SOLVERUTILS_FILTERS_FILTERENERGY_H
#define NEKTAR_SOLVERUTILS_FILTERS_FILTERENERGY_H
#include <SolverUtils/Filters/Filter.h>
......@@ -42,14 +42,28 @@ namespace Nektar
{
namespace SolverUtils
{
class FilterEnergyBase : public Filter
class FilterEnergy : public Filter
{
public:
SOLVER_UTILS_EXPORT FilterEnergyBase(
/// Creates an instance of this class
static SolverUtils::FilterSharedPtr create(
const LibUtilities::SessionReaderSharedPtr &pSession,
const std::weak_ptr<SolverUtils::EquationSystem> &pEquation,
const ParamMap &pParams)
{
SolverUtils::FilterSharedPtr p = MemoryManager<FilterEnergy>
::AllocateSharedPtr(pSession, pEquation, pParams);
return p;
}
///Name of the class
static std::string className;
SOLVER_UTILS_EXPORT FilterEnergy(
const LibUtilities::SessionReaderSharedPtr &pSession,
const ParamMap &pParams,
const bool pConstDensity = true);
SOLVER_UTILS_EXPORT ~FilterEnergyBase();
const std::weak_ptr<EquationSystem> &pEquation,
const ParamMap &pParams);
SOLVER_UTILS_EXPORT ~FilterEnergy();
protected:
SOLVER_UTILS_EXPORT virtual void v_Initialise(
......@@ -63,13 +77,6 @@ protected:
const NekDouble &time);
SOLVER_UTILS_EXPORT virtual bool v_IsTimeDependent();
SOLVER_UTILS_EXPORT virtual void v_GetVelocity(
const Array<OneD, const MultiRegions::ExpListSharedPtr> &pField,
const int i,
Array<OneD, NekDouble> &velocity);
SOLVER_UTILS_EXPORT virtual Array<OneD, NekDouble> v_GetDensity(
const Array<OneD, const MultiRegions::ExpListSharedPtr> &pFld);
private:
unsigned int m_index;
unsigned int m_outputFrequency;
......@@ -79,7 +86,6 @@ private:
NekDouble m_area;
LibUtilities::CommSharedPtr m_comm;
Array<OneD, unsigned int> m_planes;
bool m_constDensity;
};
}
}
......
......@@ -53,8 +53,9 @@ std::string FilterEnergy1D::className = GetFilterFactory().
*/
FilterEnergy1D::FilterEnergy1D(
const LibUtilities::SessionReaderSharedPtr &pSession,
const std::weak_ptr<EquationSystem> &pEquation,
const ParamMap &pParams) :
Filter(pSession),
Filter(pSession, pEquation),
m_index(0)
{
ASSERTL0(pSession->GetComm()->GetSize() == 1,
......
......@@ -58,9 +58,11 @@ public:
/// Creates an instance of this class
static FilterSharedPtr create(
const LibUtilities::SessionReaderSharedPtr &pSession,
const std::map<std::string, std::string> &pParams) {
const std::weak_ptr<EquationSystem> &pEquation,
const std::map<std::string, std::string> &pParams)
{
FilterSharedPtr p = MemoryManager<FilterEnergy1D>
::AllocateSharedPtr(pSession, pParams);
::AllocateSharedPtr(pSession, pEquation, pParams);
return p;
}
......@@ -69,6 +71,7 @@ public:
SOLVER_UTILS_EXPORT FilterEnergy1D(
const LibUtilities::SessionReaderSharedPtr &pSession,
const std::weak_ptr<EquationSystem> &pEquation,
const ParamMap &pParams);
SOLVER_UTILS_EXPORT ~FilterEnergy1D();
......
......@@ -47,8 +47,9 @@ std::string FilterFieldConvert::className =
FilterFieldConvert::FilterFieldConvert(
const LibUtilities::SessionReaderSharedPtr &pSession,
const std::weak_ptr<EquationSystem> &pEquation,
const ParamMap &pParams)
: Filter(pSession)
: Filter(pSession, pEquation)
{
// OutputFile
auto it = pParams.find("OutputFile");
......@@ -94,19 +95,6 @@ FilterFieldConvert::FilterFieldConvert(
}
}
// SampleFrequency
it = pParams.find("SampleFrequency");
if (it == pParams.end())
{
m_sampleFrequency = 1;
}
else
{
LibUtilities::Equation equ(
m_session->GetExpressionEvaluator(), it->second);
m_sampleFrequency = round(equ.Evaluate());
}
// OutputFrequency
it = pParams.find("OutputFrequency");
if (it == pParams.end())
......@@ -120,6 +108,10 @@ FilterFieldConvert::FilterFieldConvert(
m_outputFrequency = round(equ.Evaluate());
}
// The base class can use SampleFrequency = OutputFrequency
// (Derived classes need to override this if needed)
m_sampleFrequency = m_outputFrequency;
m_numSamples = 0;
m_index = 0;
m_outputIndex = 0;
......@@ -168,13 +160,14 @@ void FilterFieldConvert::v_Initialise(
// m_variables need to be filled by a derived class
m_outFields.resize(m_variables.size());
int nfield;
for (int n = 0; n < m_variables.size(); ++n)
{
// if n >= pFields.num_elements() assum we have used n=0 field
nfield = (n < pFields.num_elements())? n: 0;
m_outFields[n] = Array<OneD, NekDouble>(pFields[nfield]->GetNcoeffs(), 0.0);
m_outFields[n] =
Array<OneD, NekDouble>(pFields[nfield]->GetNcoeffs(), 0.0);
}
m_fieldMetaData["InitialTime"] = boost::lexical_cast<std::string>(time);
......@@ -258,6 +251,17 @@ void FilterFieldConvert::v_FillVariablesName(
{
m_variables[n] = pFields[n]->GetSession()->GetVariable(n);
}
// Need to create a dummy coeffs vector to get extra variables names...
vector<Array<OneD, NekDouble> > coeffs(nfield);
for (int n = 0; n < nfield; ++n)
{
coeffs[n] = pFields[n]->GetCoeffs();
}
// Get extra variables
auto equ = m_equ.lock();
ASSERTL0(equ, "Weak pointer expired");
equ->ExtraFldOutput(coeffs, m_variables);
}
void FilterFieldConvert::v_Update(
......@@ -270,8 +274,20 @@ void FilterFieldConvert::v_Update(
return;
}
// Append extra fields
int nfield = pFields.num_elements();
vector<Array<OneD, NekDouble> > coeffs(nfield);
for (int n = 0; n < nfield; ++n)
{
coeffs[n] = pFields[n]->GetCoeffs();
}
vector<std::string> variables = m_variables;
auto equ = m_equ.lock();
ASSERTL0(equ, "Weak pointer expired");
equ->ExtraFldOutput(coeffs, variables);
m_numSamples++;
v_ProcessSample(pFields, time);
v_ProcessSample(pFields, coeffs, time);
if (m_index % m_outputFrequency == 0)
{
......@@ -290,14 +306,15 @@ void FilterFieldConvert::v_Finalise(
OutputField(pFields);
}
void FilterFieldConvert::v_PrepareOutput(
const Array<OneD, const MultiRegions::ExpListSharedPtr> &pFields,
const NekDouble &time)
void FilterFieldConvert::v_ProcessSample(
const Array<OneD, const MultiRegions::ExpListSharedPtr> &pFields,
std::vector<Array<OneD, NekDouble> > &fieldcoeffs,
const NekDouble &time)
{
for(int n = 0; n < pFields.num_elements(); ++n)
for(int n = 0; n < m_outFields.size(); ++n)
{
Vmath::Vcopy(m_outFields[n].num_elements(),
pFields[n]->GetCoeffs(),
fieldcoeffs[n],
1,
m_outFields[n],
1);
......
......@@ -54,10 +54,11 @@ public:
/// Creates an instance of this class
static FilterSharedPtr create(
const LibUtilities::SessionReaderSharedPtr &pSession,
const std::weak_ptr<EquationSystem> &pEquation,
const std::map<std::string, std::string> &pParams)
{
FilterSharedPtr p = MemoryManager<FilterFieldConvert>
::AllocateSharedPtr(pSession, pParams);
::AllocateSharedPtr(pSession, pEquation, pParams);
return p;
}
......@@ -66,6 +67,7 @@ public:
SOLVER_UTILS_EXPORT FilterFieldConvert(
const LibUtilities::SessionReaderSharedPtr &pSession,
const std::weak_ptr<EquationSystem> &pEquation,
const ParamMap &pParams);
SOLVER_UTILS_EXPORT virtual ~FilterFieldConvert();
......@@ -82,14 +84,15 @@ protected:
const Array<OneD, const MultiRegions::ExpListSharedPtr> &pFields,
const NekDouble &time);
SOLVER_UTILS_EXPORT virtual void v_ProcessSample(
const Array<OneD, const MultiRegions::ExpListSharedPtr> &pFields,
std::vector<Array<OneD, NekDouble> > &fieldcoeffs,
const NekDouble &time);
SOLVER_UTILS_EXPORT virtual void v_PrepareOutput(
const Array<OneD, const MultiRegions::ExpListSharedPtr> &pFields,
const NekDouble &time)
{
// Do nothing by default
}
SOLVER_UTILS_EXPORT virtual void v_PrepareOutput(
const Array<OneD, const MultiRegions::ExpListSharedPtr> &pFields,
const NekDouble &time);
SOLVER_UTILS_EXPORT virtual NekDouble v_GetScale()