Commit 47473538 authored by Spencer Sherwin's avatar Spencer Sherwin
Browse files

Updates tollowing from Douglas' review

parent b29802bf
///////////////////////////////////////////////////////////////////////////////
//
// File DisContField3DHomogeneous1D.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: Field definition in three-dimensions for a discontinuous
// LDG-H expansion with a homogeneous direction in 1D
//
///////////////////////////////////////////////////////////////////////////////
#ifndef NEKTAR_LIBS_MULTIREGIONS_DISCONTFIELD3DHOMO1D_H
#define NEKTAR_LIBS_MULTIREGIONS_DISCONTFIELD3DHOMO1D_H
#include <MultiRegions/MultiRegionsDeclspec.h>
#include <MultiRegions/MultiRegions.hpp>
#include <MultiRegions/ExpList3DHomogeneous1D.h>
#include <MultiRegions/ExpList2D.h>
#include <MultiRegions/AssemblyMap/AssemblyMapDG.h>
#include <SpatialDomains/Conditions.h>
#include <MultiRegions/GlobalLinSys.h>
namespace Nektar
{
namespace MultiRegions
{
class DisContField3DHomogeneous1D: public ExpList3DHomogeneous1D
{
public:
MULTI_REGIONS_EXPORT DisContField3DHomogeneous1D();
MULTI_REGIONS_EXPORT DisContField3DHomogeneous1D(
const LibUtilities::SessionReaderSharedPtr &pSession,
const LibUtilities::BasisKey &HomoBasis,
const NekDouble lhom,
const bool useFFT,
const bool dealiasing);
MULTI_REGIONS_EXPORT DisContField3DHomogeneous1D(
const LibUtilities::SessionReaderSharedPtr &pSession,
const LibUtilities::BasisKey &HomoBasis,
const NekDouble lhom,
const bool useFFT,
const bool dealiasing,
const SpatialDomains::MeshGraphSharedPtr &graph2D,
const std::string &variable);
/// Copy constructor.
MULTI_REGIONS_EXPORT DisContField3DHomogeneous1D(
const DisContField3DHomogeneous1D &In,
const bool DeclarePlanesSetCoeffPhys = true);
/// Destructor.
MULTI_REGIONS_EXPORT virtual ~DisContField3DHomogeneous1D();
MULTI_REGIONS_EXPORT void SetupBoundaryConditions(
const LibUtilities::BasisKey &HomoBasis,
const NekDouble lhom,
SpatialDomains::BoundaryConditions &bcs,
const std::string variable);
/**
* \brief This function evaluates the boundary conditions
* at a certaintime-level.
*
* Based on the boundary condition \f$g(\boldsymbol{x},t)\f$
* evaluated at a given time-level \a t, this function transforms
* the boundary conditions onto the coefficients of the
* (one-dimensional) boundary expansion.
* Depending on the type of boundary conditions, these expansion
* coefficients are calculated in different ways:
* - <b>Dirichlet boundary conditions</b><BR>
* In order to ensure global \f$C^0\f$ continuity of the
* spectral/hp approximation, the Dirichlet boundary conditions
* are projected onto the boundary expansion by means of a
* modified \f$C^0\f$ continuous Galerkin projection.
* This projection can be viewed as a collocation projection at the
* vertices, followed by an \f$L^2\f$ projection on the interior
* modes of the edges. The resulting coefficients
* \f$\boldsymbol{\hat{u}}^{\mathcal{D}}\f$ will be stored for the
* boundary expansion.
* - <b>Neumann boundary conditions</b>
* In the discrete Galerkin formulation of the problem to be
* solved, the Neumann boundary conditions appear as the set of
* surface integrals: \f[\boldsymbol{\hat{g}}=\int_{\Gamma}
* \phi^e_n(\boldsymbol{x})g(\boldsymbol{x})d(\boldsymbol{x})\quad
* \forall n \f]
* As a result, it are the coefficients \f$\boldsymbol{\hat{g}}\f$
* that will be stored in the boundary expansion
*
* \param time The time at which the boundary conditions should be
* evaluated
*/
MULTI_REGIONS_EXPORT void EvaluateBoundaryConditions(
const NekDouble time = 0.0,
const std::string varName = "");
inline const Array<OneD,const MultiRegions::ExpListSharedPtr>
&GetBndCondExpansions();
inline const Array<OneD,const SpatialDomains::
BoundaryConditionShPtr> &GetBndConditions();
inline boost::shared_ptr<ExpList> &UpdateBndCondExpansion(int i);
inline Array<OneD, SpatialDomains::BoundaryConditionShPtr>&
UpdateBndConditions();
/// \brief Set up a list of element ids and edge ids the link to the
/// boundary conditions
MULTI_REGIONS_EXPORT void GetBoundaryToElmtMap(
Array<OneD, int> &ElmtID,
Array<OneD,int> &EdgeID);
virtual void v_GetBndElmtExpansion(int i,
boost::shared_ptr<ExpList> &result);
/// This funtion extract form a vector containing a full
/// 3D-homogenous-1D field the value associated with a
/// specific boundary conditions.
/// TotField is the full field contaning all the physical values
/// BndVals is the vector where the boundary physical values are
/// stored BndID is the identifier of the boundary region
MULTI_REGIONS_EXPORT void GetBCValues(
Array<OneD, NekDouble> &BndVals,
const Array<OneD, NekDouble> &TotField,
int BndID);
/// This function calculate the inner product of two vectors
/// (V1 and V2) respect to the basis along a boundary region.
/// outarray is the inner product result multiplied by the normal to
/// the edge (specified by the BndID)
MULTI_REGIONS_EXPORT void NormVectorIProductWRTBase(
Array<OneD, const NekDouble> &V1,
Array<OneD, const NekDouble> &V2,
Array<OneD, NekDouble> &outarray,
int BndID);
/// Storage space for the boundary to element and boundary to trace
/// map. This member variable is really allocated just in case
/// a boundary expansion recasting is required at the solver level.
/// Otherwise is the 2 vectors are not filled up.
/// If is needed all the funcitons whihc require to use this map
/// do not have to recalculate it anymore.
Array<OneD, int> m_BCtoElmMap;
Array<OneD, int> m_BCtoEdgMap;
protected:
/**
* \brief An object which contains the discretised
* boundary conditions.
*
* It is an array of size equal to the number of boundary
* regions and consists of entries of the type
* MultiRegions#ExpList1D. Every entry corresponds to the
* one-dimensional spectral/hp expansion on a single
* boundary region. The values of the boundary conditions
* are stored as the coefficients of the one-dimensional
* expansion.
*/
Array<OneD, MultiRegions::ExpListSharedPtr> m_bndCondExpansions;
ExpListSharedPtr m_trace;
Array<OneD, int> m_traceBndMap;
/**
* \brief An array which contains the information about
* the boundary condition on the different boundary
* regions.
*/
Array<OneD,SpatialDomains::BoundaryConditionShPtr> m_bndConditions;
virtual void v_GetBoundaryToElmtMap(
Array<OneD,int> &ElmtID,
Array<OneD,int> &EdgeID)
{
GetBoundaryToElmtMap(ElmtID, EdgeID);
}
virtual void v_GetBCValues(
Array<OneD, NekDouble> &BndVals,
const Array<OneD, NekDouble> &TotField,
int BndID)
{
GetBCValues(BndVals, TotField, BndID);
}
virtual void v_NormVectorIProductWRTBase(
Array<OneD, const NekDouble> &V1,
Array<OneD, const NekDouble> &V2,
Array<OneD, NekDouble> &outarray,
int BndID)
{
NormVectorIProductWRTBase(V1,V2,outarray,BndID);
}
/// Set up all DG member variables and maps
MULTI_REGIONS_EXPORT void SetUpDG();
/// @todo Fix in another way considering all the planes
virtual ExpListSharedPtr &v_GetTrace()
{
return m_trace;
}
/// @todo Fix in another way considering all the planes
virtual AssemblyMapDGSharedPtr &v_GetTraceMap()
{
return m_planes[0]->GetTraceMap();
}
virtual const Array<OneD,const MultiRegions::ExpListSharedPtr>
&v_GetBndCondExpansions(void)
{
return GetBndCondExpansions();
}
virtual const
Array<OneD,const SpatialDomains::BoundaryConditionShPtr>
&v_GetBndConditions()
{
return GetBndConditions();
}
/// @todo Fix Robin BCs for homogeneous case
virtual std::map<int, RobinBCInfoSharedPtr> v_GetRobinBCInfo()
{
return std::map<int, RobinBCInfoSharedPtr>();
}
virtual void v_ExtractTracePhys(
const Array<OneD, const NekDouble> &inarray,
Array<OneD, NekDouble> &outarray);
virtual void v_ExtractTracePhys(
Array<OneD, NekDouble> &outarray);
virtual void v_GetBoundaryNormals(int i,
Array<OneD, Array<OneD, NekDouble> > &normals);
private:
// virtual functions
virtual void v_HelmSolve(
const Array<OneD, const NekDouble> &inarray,
Array<OneD, NekDouble> &outarray,
const FlagList &flags,
const StdRegions::ConstFactorMap &factors,
const StdRegions::VarCoeffMap &varcoeff,
const Array<OneD, const NekDouble> &dirForcing,
const Array<OneD, const NekDouble> &weakForcing);
virtual void v_EvaluateBoundaryConditions(
const NekDouble time = 0.0,
const std::string varName = "",
const NekDouble x2_in = NekConstants::kNekUnsetDouble,
const NekDouble x3_in = NekConstants::kNekUnsetDouble);
virtual boost::shared_ptr<ExpList> &v_UpdateBndCondExpansion(int i);
virtual Array<OneD, SpatialDomains::BoundaryConditionShPtr>
&v_UpdateBndConditions();
virtual const Array<OneD, const int> &v_GetTraceBndMap()
{
return m_traceBndMap;
}
};
typedef boost::shared_ptr<DisContField3DHomogeneous1D>
DisContField3DHomogeneous1DSharedPtr;
inline const Array<OneD,const MultiRegions::ExpListSharedPtr>
&DisContField3DHomogeneous1D::GetBndCondExpansions()
{
return m_bndCondExpansions;
}
inline const Array<OneD,const SpatialDomains::BoundaryConditionShPtr>
&DisContField3DHomogeneous1D::GetBndConditions()
{
return m_bndConditions;
}
inline MultiRegions::ExpListSharedPtr &DisContField3DHomogeneous1D::
UpdateBndCondExpansion(int i)
{
return m_bndCondExpansions[i];
}
inline Array<OneD, SpatialDomains::BoundaryConditionShPtr>
&DisContField3DHomogeneous1D::UpdateBndConditions()
{
return m_bndConditions;
}
} //end of namespace
} //end of namespace
#endif // MULTIERGIONS_DISCONTFIELD3DHOMO1D_H
......@@ -461,8 +461,7 @@ namespace Nektar
*/
void ContField1D::v_LocalToGlobal(
const Array<OneD, const NekDouble> &inarray,
Array<OneD,NekDouble> &outarray,
bool useComm)
Array<OneD,NekDouble> &outarray, bool useComm)
{
m_locToGloMap->LocalToGlobal(inarray, outarray, useComm);
}
......
......@@ -524,7 +524,9 @@ namespace Nektar
Array<OneD, NekDouble> tmp(m_locToGloMap->GetNumGlobalCoeffs());
LocalToGlobal(m_coeffs,tmp,false);
ASSERTL1(nreg < m_bndCondExpansions.num_elements(),"nreg is out or range since this many boundary regions to not exist");
ASSERTL1(nreg < m_bndCondExpansions.num_elements(),
"nreg is out or range since this many boundary "
"regions to not exist");
// Now fill in all other Dirichlet coefficients.
Array<OneD, NekDouble>& coeffs = m_bndCondExpansions[nreg]->UpdateCoeffs();
......
......@@ -1164,7 +1164,6 @@ namespace Nektar
const StdRegions::VarCoeffMap &varcoeff,
const Array<OneD, const NekDouble> &dirForcing,
const bool PhysSpaceForcing)
{
int i,n,cnt,nbndry;
int nexp = GetExpSize();
......
......@@ -293,7 +293,6 @@ namespace Nektar
{
if (n != 1 || m_transposition->GetK(n) != 0)
{
beta = 2*M_PI*(m_transposition->GetK(n))/m_lhom;
new_factors = factors;
// add in Homogeneous Fourier direction and SVV if turned on
......
......@@ -327,7 +327,6 @@ namespace Nektar
for( int i = 0; i < nqb; i++)
{
S0[i] = 0.5*(1.0-tanh(un[i]/(m_houtflow->m_U0*m_houtflow->m_delta)));
//S0[i] = 0.0; //debugging
}
// Calculate E(n,u) = ((theta+alpha2)*0.5*(u^2)n +
......@@ -354,8 +353,8 @@ namespace Nektar
// value if we want to interpret values as being the
// desired pressure value. This is now precribed from
// the velocity forcing to be consistent with the
// paper except f_b = - f_b
// paper except f_b = -f_b
// Calculate (E(n,u) + f_b).n
Array<OneD, NekDouble> En (nqb, 0.0);
for( int i = 0; i < m_bnd_dim; i++)
......@@ -421,10 +420,6 @@ namespace Nektar
// point u[i] to BDF evalauted value \hat{u}
u[i] = m_houtflow->m_outflowVelBnd[cnt][i]
[m_intSteps-1];
// For Fourier code might have needed a
// transform but since terms are linear here
// we may get away with just the mean mode
}
// Add normal velocity if weak pressure
......@@ -543,8 +538,8 @@ namespace Nektar
void Extrapolate::IProductNormVelocityOnHBC(
const Array<OneD, const Array<OneD, NekDouble> > &Vel,
Array<OneD, NekDouble> &IProdVn)
const Array<OneD, const Array<OneD, NekDouble> > &Vel,
Array<OneD, NekDouble> &IProdVn)
{
int i,n,cnt;
Array<OneD, NekDouble> IProdVnTmp;
......@@ -602,8 +597,9 @@ namespace Nektar
m_PBndExp[n]->NormVectorIProductWRTBase(velbc, IProdVnTmp);
cnt += m_PBndExp[n]->GetNcoeffs();
}
else if(m_hbcType[n] == eConvectiveOBC) // skip over conective OBC
else if(m_hbcType[n] == eConvectiveOBC)
{
// skip over convective OBC
cnt += m_PBndExp[n]->GetNcoeffs();
}
}
......@@ -729,49 +725,40 @@ namespace Nektar
// Initialise storage for outflow HOBCs
if(numOutHBCPts > 0)
{
m_houtflow = MemoryManager<HighOrderOutflow>::AllocateSharedPtr(numOutHBCPts, outHBCnumber);
m_houtflow = MemoryManager<HighOrderOutflow>::AllocateSharedPtr(numOutHBCPts, outHBCnumber, m_curl_dim, pSession);
MultiRegions::ExpListSharedPtr BndElmtExp;
m_houtflow->m_outflowVel = Array<OneD,
Array<OneD,
Array<OneD,
Array<OneD, NekDouble> > > > (outHBCnumber);
m_houtflow->m_outflowVelBnd = Array<OneD,
Array<OneD,
Array<OneD,
Array<OneD, NekDouble> > > > (outHBCnumber);
m_houtflow->m_UBndExp = Array<OneD,
Array<OneD, MultiRegions::ExpListSharedPtr> >(m_curl_dim);
// set up boundary expansions link
for (int i = 0; i < m_curl_dim; ++i)
{
m_houtflow->m_UBndExp[i] = m_fields[m_velocity[i]]->GetBndCondExpansions();
m_houtflow->m_UBndExp[i] =
m_fields[m_velocity[i]]->GetBndCondExpansions();
}
for(n = 0, cnt = 0; n < m_PBndConds.num_elements(); ++n)
{
if(boost::iequals(m_PBndConds[n]->GetUserDefined(),"HOutflow"))
{
m_houtflow->m_outflowVel[cnt] = Array<OneD,
Array<OneD,
Array<OneD, NekDouble> > > (m_curl_dim);
m_houtflow->m_outflowVel[cnt] =
Array<OneD, Array<OneD,
Array<OneD, NekDouble> > > (m_curl_dim);
m_houtflow->m_outflowVelBnd[cnt] = Array<OneD,
Array<OneD,
Array<OneD, NekDouble> > > (m_curl_dim);
m_houtflow->m_outflowVelBnd[cnt] =
Array<OneD, Array<OneD,
Array<OneD, NekDouble> > > (m_curl_dim);
m_fields[0]->GetBndElmtExpansion(n, BndElmtExp, false);
int nqb = m_PBndExp[n]->GetTotPoints();
int nq = BndElmtExp->GetTotPoints();
for(int j = 0; j < m_curl_dim; ++j)
{
m_houtflow->m_outflowVel[cnt][j] = Array<OneD,
Array<OneD, NekDouble> > (m_intSteps);
m_houtflow->m_outflowVel[cnt][j] =
Array<OneD, Array<OneD, NekDouble> > (m_intSteps);
m_houtflow->m_outflowVelBnd[cnt][j] =
Array<OneD, Array<OneD, NekDouble> > (m_intSteps);
m_houtflow->m_outflowVelBnd[cnt][j] = Array<OneD,
Array<OneD, NekDouble> > (m_intSteps);
for(int k = 0; k < m_intSteps; ++k)
{
m_houtflow->m_outflowVel[cnt][j][k] =
......@@ -838,14 +825,7 @@ namespace Nektar
}
}
}
pSession->LoadParameter("OutflowBC_theta", m_houtflow->m_obcTheta, 1.0);
pSession->LoadParameter("OutflowBC_alpha1", m_houtflow->m_obcAlpha1, 0.0);
pSession->LoadParameter("OutflowBC_alpha2", m_houtflow->m_obcAlpha2, 0.0);
pSession->LoadParameter("U0_HighOrderBC",m_houtflow->m_U0,1.0);
pSession->LoadParameter("Delta_HighOrderBC",m_houtflow->m_delta,1/20.0);
}
}
......
......@@ -278,10 +278,27 @@ namespace Nektar
struct HighOrderOutflow
{
HighOrderOutflow(const int numHOpts, const int outHBCnumber):
m_numOutHBCPts(numHOpts),
HighOrderOutflow(const int numHOpts, const int outHBCnumber,const int curldim, const LibUtilities::SessionReaderSharedPtr &pSession):
m_numOutHBCPts(numHOpts),
m_outHBCnumber(outHBCnumber)
{
m_outflowVel = Array<OneD,
Array<OneD, Array<OneD,
Array<OneD, NekDouble> > > > (outHBCnumber);
m_outflowVelBnd = Array<OneD,
Array<OneD, Array<OneD,
Array<OneD, NekDouble> > > > (outHBCnumber);
m_UBndExp = Array<OneD,
Array<OneD, MultiRegions::ExpListSharedPtr> >(curldim);
pSession->LoadParameter("OutflowBC_theta", m_obcTheta, 1.0);
pSession->LoadParameter("OutflowBC_alpha1", m_obcAlpha1, 0.0);
pSession->LoadParameter("OutflowBC_alpha2", m_obcAlpha2, 0.0);
pSession->LoadParameter("U0_HighOrderBC", m_U0,1.0);
pSession->LoadParameter("Delta_HighOrderBC", m_delta,1/20.0);
}
virtual ~HighOrderOutflow()
......
......@@ -99,11 +99,12 @@ namespace Nektar
// creation of the extrapolation object
if(m_equationType == eUnsteadyNavierStokes)
{
std::string vExtrapolation = "Standard";
std::string vExtrapolation = v_GetExtrapolateStr();
if (m_session->DefinesSolverInfo("Extrapolation"))
{
vExtrapolation = m_session->GetSolverInfo("Extrapolation");
vExtrapolation = v_GetSubSteppingExtrapolateStr(
m_session->GetSolverInfo("Extrapolation"));
}
m_extrapolation = GetExtrapolateFactory().CreateInstance(
......@@ -121,9 +122,6 @@ namespace Nektar
m_intVariables.push_back(n);
}
m_saved_aii_Dt = Array<OneD, NekDouble>(m_nConvectiveFields,
NekConstants::kNekUnsetDouble);
// Load parameters for Spectral Vanishing Viscosity
m_session->MatchSolverInfo("SpectralVanishingViscosity","True",
m_useSpecVanVisc, false);
......@@ -352,9 +350,6 @@ namespace Nektar
const NekDouble time,
const NekDouble aii_Dt)
{
// Enforcing boundary conditions on all fields
SetBoundaryConditions(time);
// Substep the pressure boundary condition if using substepping
m_extrapolation->SubStepSetPressureBCs(inarray,aii_Dt,m_kinvis);
......
......@@ -57,14 +57,13 @@ namespace Nektar
/// Name of class
static std::string className;
/// Constructor.
VelocityCorrectionScheme(const LibUtilities::SessionReaderSharedPtr& pSession);
virtual ~VelocityCorrectionScheme();
virtual void v_InitObject();
void SetUpPressureForcing(
const Array<OneD, const Array<OneD, NekDouble> > &fields,
Array<OneD, Array<OneD, NekDouble> > &Forcing,
......@@ -120,9 +119,6 @@ namespace Nektar
/// Diffusion coefficients (will be kinvis for velocities)
Array<OneD, NekDouble> m_diffCoeff;
/// Save aiiDt value to use as a trip to reset global matrix setup
Array<OneD, NekDouble> m_saved_aii_Dt;
/// Variable Coefficient map for the Laplacian which can be activated as part of SVV or otherwise
StdRegions::VarCoeffMap m_varCoeffLap;
......@@ -165,6 +161,17 @@ namespace Nektar
{
return false;
}
virtual std::string v_GetExtrapolateStr(void)
{
return "Standard";
}
virtual std::string v_GetSubSteppingExtrapolateStr(