Commit b17fd625 authored by Chris Cantwell's avatar Chris Cantwell

Merge branch 'feature/filterenergy1d' into 'master'

Add 1D energy filter

This MR adds a simple filter to output the orthogonal coefficients of one-dimensional expansion list.

See merge request !457
parents fa4ca62a aa5bb19a
......@@ -203,6 +203,42 @@ which produces a field file \inlsh{threshold\_max.fld}.
Performs the same function as the \inltt{ThresholdMax} filter but records the
time at which the threshold variable drops below a prescribed value.
\subsection{One-dimensional energy}
This filter is designed to output the energy spectrum of one-dimensional
elements. It transforms the solution field at each timestep into a orthogonal
basis defined by the functions
\[
\psi_p(\xi) = L_p(\xi)
\]
where $L_p$ is the $p$-th Legendre polynomial. This can be used to show the
presence of, for example, oscillations in the underlying field due to numerical
instability. The resulting output is written into a file called
\inltt{session.eny} by default. The following parameters are supported:
\begin{center}
\begin{tabularx}{0.99\textwidth}{lllX}
\toprule
\textbf{Option name} & \textbf{Required} & \textbf{Default} &
\textbf{Description} \\
\midrule
\inltt{OutputFile} & \xmark & \inltt{session} &
Prefix of the output filename to which the energy spectrum is written.\\
\inltt{OutputFrequency} & \xmark & 1 &
Number of timesteps after which output is written.\\
\bottomrule
\end{tabularx}
\end{center}
An example syntax is given below:
\begin{lstlisting}[style=XMLStyle,gobble=2]
<FILTER TYPE="Energy1D">
<PARAM NAME="OutputFile">EnergyFile</PARAM>
<PARAM NAME="OutputFrequency">10</PARAM>
</FILTER>
\end{lstlisting}
\subsection{Modal energy}
\begin{notebox}
......
......@@ -22,6 +22,7 @@ SET(SOLVER_UTILS_SOURCES
Filters/FilterAeroForces.cpp
Filters/FilterAverageFields.cpp
Filters/FilterCheckpoint.cpp
Filters/FilterEnergy1D.cpp
Filters/FilterEnergyBase.cpp
Filters/FilterHistoryPoints.cpp
Filters/FilterModalEnergy.cpp
......@@ -63,6 +64,7 @@ SET(SOLVER_UTILS_HEADERS
Filters/FilterAeroForces.h
Filters/FilterAverageFields.h
Filters/FilterCheckpoint.h
Filters/FilterEnergy1D.h
Filters/FilterEnergyBase.h
Filters/FilterHistoryPoints.h
Filters/FilterModalEnergy.h
......
///////////////////////////////////////////////////////////////////////////////
//
// File FilterEnergy1D.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: Outputs orthogonal expansion of 1D elements.
//
///////////////////////////////////////////////////////////////////////////////
#include <LibUtilities/Foundations/InterpCoeff.h>
#include <SolverUtils/Filters/FilterEnergy1D.h>
namespace Nektar
{
namespace SolverUtils
{
std::string FilterEnergy1D::className = GetFilterFactory().
RegisterCreatorFunction("Energy1D", FilterEnergy1D::create);
/**
* @brief Set up filter with output file and frequency parameters.
*
* @param pSession Current session.
* @param pParams Map of parameters defined in XML file.
*/
FilterEnergy1D::FilterEnergy1D(
const LibUtilities::SessionReaderSharedPtr &pSession,
const std::map<std::string, std::string> &pParams) :
Filter(pSession),
m_index(0)
{
std::string outName;
if (pParams.find("OutputFile") == pParams.end())
{
outName = m_session->GetSessionName();
}
else
{
ASSERTL0(!(pParams.find("OutputFile")->second.empty()),
"Missing parameter 'OutputFile'.");
outName = pParams.find("OutputFile")->second;
}
if (pParams.find("OutputFrequency") == pParams.end())
{
m_outputFrequency = 1;
}
else
{
m_outputFrequency =
atoi(pParams.find("OutputFrequency")->second.c_str());
}
outName += ".eny";
ASSERTL0(pSession->GetComm()->GetSize() == 1,
"The 1D energy filter currently only works in serial.");
m_out.open(outName.c_str());
}
/**
* @brief Destructor.
*/
FilterEnergy1D::~FilterEnergy1D()
{
}
/**
* @brief Initialize filter.
*/
void FilterEnergy1D::v_Initialise(
const Array<OneD, const MultiRegions::ExpListSharedPtr> &pFields,
const NekDouble &time)
{
ASSERTL0(pFields[0]->GetExp(0)->GetNumBases() == 1,
"The Energy 1D filter is only valid in 1D.");
}
/**
* @brief Update filter output with the current timestep's orthogonal
* coefficients.
*/
void FilterEnergy1D::v_Update(
const Array<OneD, const MultiRegions::ExpListSharedPtr> &pFields,
const NekDouble &time)
{
// Only output every m_outputFrequency
if ((m_index++) % m_outputFrequency)
{
return;
}
int nElmt = pFields[0]->GetExpSize();
// Loop over all elements
m_out << "##" << endl;
m_out << "## Time = " << time << endl;
m_out << "##" << endl;
for (int i = 0; i < nElmt; ++i)
{
// Figure out number of modes in this expansion.
LocalRegions::ExpansionSharedPtr exp = pFields[0]->GetExp(i);
int nModes = exp->GetBasis(0)->GetNumModes();
// Set uo basis key for orthogonal basis
LibUtilities::BasisType btype = LibUtilities::eOrtho_A;
LibUtilities::BasisKey bkeyOrth(
btype, nModes, exp->GetBasis(0)->GetPointsKey());
// Get basis key for existing expansion
LibUtilities::BasisKey bkey(
exp->GetBasis(0)->GetBasisType(),
exp->GetBasis(0)->GetNumModes(),
exp->GetBasis(0)->GetPointsKey());
// Find coeffs for this element in the list of all coefficients
Array<OneD, NekDouble> coeffs =
pFields[0]->GetCoeffs() + pFields[0]->GetCoeff_Offset(i);
// Storage for orthogonal coefficients
Array<OneD, NekDouble> coeffsOrth(nModes);
// Project from coeffs -> orthogonal coeffs
LibUtilities::InterpCoeff1D(bkey, coeffs, bkeyOrth, coeffsOrth);
// Write coeffs to file
m_out << "# Element " << i << " (ID "
<< exp->GetGeom()->GetGlobalID() << ")" << endl;
for (int j = 0; j < nModes; ++j)
{
m_out << coeffsOrth[j] << endl;
}
}
m_out << endl;
}
void FilterEnergy1D::v_Finalise(
const Array<OneD, const MultiRegions::ExpListSharedPtr> &pFields,
const NekDouble &time)
{
m_out.close();
}
bool FilterEnergy1D::v_IsTimeDependent()
{
return true;
}
}
}
///////////////////////////////////////////////////////////////////////////////
//
// File FilterEnergy1D.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: Outputs orthogonal expansion of 1D elements.
//
///////////////////////////////////////////////////////////////////////////////
#ifndef NEKTAR_SOLVERUTILS_FILTERS_FILTERENERGY1D_H
#define NEKTAR_SOLVERUTILS_FILTERS_FILTERENERGY1D_H
#include <SolverUtils/Filters/Filter.h>
namespace Nektar
{
namespace SolverUtils
{
/**
* @brief Filter for one-dimensional energy spectrum.
*
* This filter transforms the coefficients of each element into an
* orthogonal basis and outputs these coefficients at each timestep. It
* can be used to, for example, detect high-order oscillations in the
* solution field.
*/
class FilterEnergy1D : public Filter
{
public:
friend class MemoryManager<FilterEnergy1D>;
/// Creates an instance of this class
static FilterSharedPtr create(
const LibUtilities::SessionReaderSharedPtr &pSession,
const std::map<std::string, std::string> &pParams) {
FilterSharedPtr p = MemoryManager<FilterEnergy1D>
::AllocateSharedPtr(pSession, pParams);
return p;
}
///Name of the class
static std::string className;
SOLVER_UTILS_EXPORT FilterEnergy1D(
const LibUtilities::SessionReaderSharedPtr &pSession,
const std::map<std::string, std::string> &pParams);
SOLVER_UTILS_EXPORT ~FilterEnergy1D();
protected:
virtual void v_Initialise(
const Array<OneD, const MultiRegions::ExpListSharedPtr> &pField,
const NekDouble &time);
virtual void v_Update(
const Array<OneD, const MultiRegions::ExpListSharedPtr> &pField,
const NekDouble &time);
virtual void v_Finalise(
const Array<OneD, const MultiRegions::ExpListSharedPtr> &pField,
const NekDouble &time);
virtual bool v_IsTimeDependent();
private:
/// Output file.
ofstream m_out;
/// Output frequency.
unsigned int m_outputFrequency;
/// Current index counter.
unsigned int m_index;
};
}
}
#endif
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