Commit fd5fa274 authored by David Moxey's avatar David Moxey

Tidy up linear space preconditioner option to use either PETSc or Xxt

parent f882c192
......@@ -11,6 +11,7 @@ IF( NEKTAR_USE_PETSC )
ELSE (THIRDPARTY_BUILD_PETSC)
INCLUDE (FindPETSc)
MESSAGE(STATUS "Found PETSc: ${PETSC_LIBRARIES}")
ADD_DEFINITIONS(-DNEKTAR_USING_PETSC)
ENDIF (THIRDPARTY_BUILD_PETSC)
ENDIF( NEKTAR_USE_PETSC )
......
......@@ -309,7 +309,8 @@ namespace Nektar
m_solnType = solnTypeOld;
ASSERTL1(m_solnType==eDirectMultiLevelStaticCond
||m_solnType==eIterativeMultiLevelStaticCond
||m_solnType==eXxtMultiLevelStaticCond,
||m_solnType==eXxtMultiLevelStaticCond
||m_solnType==ePETScMultiLevelStaticCond,
"This method should only be called for in "
"case of multi-level static condensation.");
m_staticCondLevel = newLevel;
......@@ -639,7 +640,8 @@ namespace Nektar
return result;
}
boost::shared_ptr<AssemblyMap> AssemblyMap::v_XxtLinearSpaceMap(const ExpList &locexp)
boost::shared_ptr<AssemblyMap> AssemblyMap::v_LinearSpaceMap(
const ExpList &locexp, GlobalSysSolnType solnType)
{
ASSERTL0(false, "Not defined for this sub class");
static boost::shared_ptr<AssemblyMap> result;
......@@ -802,9 +804,9 @@ namespace Nektar
return v_GetExtraDirEdges();
}
boost::shared_ptr<AssemblyMap> AssemblyMap::XxtLinearSpaceMap(const ExpList &locexp)
boost::shared_ptr<AssemblyMap> AssemblyMap::LinearSpaceMap(const ExpList &locexp, GlobalSysSolnType solnType)
{
return v_XxtLinearSpaceMap(locexp);
return v_LinearSpaceMap(locexp, solnType);
}
int AssemblyMap::GetLocalToGlobalBndMap(const int i) const
......@@ -1210,7 +1212,6 @@ namespace Nektar
= m_session->GetComm()->GetRowComm();
bool isRoot = vRowComm->GetRank() == 0;
int n = vRowComm->GetSize();
int p = vRowComm->GetRank();
int i;
// Determine number of global degrees of freedom.
......
......@@ -257,7 +257,7 @@ namespace Nektar
MULTI_REGIONS_EXPORT const Array<OneD, const int>&
GetExtraDirEdges();
MULTI_REGIONS_EXPORT boost::shared_ptr<AssemblyMap> XxtLinearSpaceMap(const ExpList &locexp);
MULTI_REGIONS_EXPORT boost::shared_ptr<AssemblyMap> LinearSpaceMap(const ExpList &locexp, GlobalSysSolnType solnType);
/// Returns the bandwidth of the boundary system.
MULTI_REGIONS_EXPORT int GetBndSystemBandWidth() const;
......@@ -473,8 +473,8 @@ namespace Nektar
v_GetExtraDirEdges();
/// Generate a linear space mapping from existing mapping
virtual boost::shared_ptr<AssemblyMap> v_XxtLinearSpaceMap
(const ExpList &locexp);
virtual boost::shared_ptr<AssemblyMap> v_LinearSpaceMap(
const ExpList &locexp, GlobalSysSolnType solnType);
};
......
......@@ -351,11 +351,12 @@ namespace Nektar
* @brief Construct an AssemblyMapCG object which corresponds to the
* linear space of the current object.
*
* This function is used in an XXT solve to apply a linear space
* preconditioner in the conjugate gradient solve.
* This function is used to create a linear-space assembly map, which is
* then used in the linear space preconditioner in the conjugate
* gradient solve.
*/
AssemblyMapSharedPtr AssemblyMapCG::v_XxtLinearSpaceMap(
const ExpList &locexp)
AssemblyMapSharedPtr AssemblyMapCG::v_LinearSpaceMap(
const ExpList &locexp, GlobalSysSolnType solnType)
{
AssemblyMapCGSharedPtr returnval;
......@@ -368,7 +369,7 @@ namespace Nektar
// Get Default Map and turn off any searched values.
returnval = MemoryManager<AssemblyMapCG>
::AllocateSharedPtr(m_session);
returnval->m_solnType = ePETScFullMatrix; //XxtFullMatrix;
returnval->m_solnType = solnType;
returnval->m_preconType = eNull;
returnval->m_maxStaticCondLevel = 0;
returnval->m_signChange = false;
......
......@@ -195,7 +195,8 @@ namespace Nektar
MULTI_REGIONS_EXPORT virtual const Array<OneD, const int>& v_GetExtraDirEdges();
MULTI_REGIONS_EXPORT virtual AssemblyMapSharedPtr v_XxtLinearSpaceMap(const ExpList &locexp);
MULTI_REGIONS_EXPORT virtual AssemblyMapSharedPtr v_LinearSpaceMap(
const ExpList &locexp, GlobalSysSolnType solnType);
};
......
......@@ -123,13 +123,11 @@ IF(NEKTAR_USE_PETSC)
GlobalLinSysPETSc.h
GlobalLinSysPETScFull.h
GlobalLinSysPETScStaticCond.h
PreconditionerPETScLinear.h
)
SET(MULTI_REGIONS_SOURCES ${MULTI_REGIONS_SOURCES}
GlobalLinSysPETSc.cpp
GlobalLinSysPETScFull.cpp
GlobalLinSysPETScStaticCond.cpp
PreconditionerPETScLinear.cpp
)
ENDIF(NEKTAR_USE_PETSC)
......
......@@ -127,8 +127,7 @@ namespace Nektar
eLowEnergy,
eLinearWithLowEnergy,
eBlock,
eLinearWithBlock,
eLinearPETSc
eLinearWithBlock
};
const char* const PreconditionerTypeMap[] =
......@@ -140,8 +139,7 @@ namespace Nektar
"LowEnergyBlock",
"FullLinearSpaceWithLowEnergyBlock",
"Block",
"FullLinearSpaceWithBlock",
"LinearPETSc"
"FullLinearSpaceWithBlock"
};
......
......@@ -42,7 +42,7 @@ namespace Nektar
{
namespace MultiRegions
{
std::string Preconditioner::lookupIds[9] = {
std::string Preconditioner::lookupIds[8] = {
LibUtilities::SessionReader::RegisterEnumValue(
"Preconditioner", "Null", eNull),
LibUtilities::SessionReader::RegisterEnumValue(
......@@ -61,8 +61,6 @@ namespace Nektar
"Preconditioner", "Block",eBlock),
LibUtilities::SessionReader::RegisterEnumValue(
"Preconditioner", "FullLinearSpaceWithBlock",eLinearWithBlock),
LibUtilities::SessionReader::RegisterEnumValue(
"Preconditioner", "LinearPETSc",eLinearPETSc),
};
std::string Preconditioner::def =
LibUtilities::SessionReader::RegisterDefaultSolverInfo(
......
......@@ -39,6 +39,11 @@
#include <MultiRegions/GlobalLinSysIterativeStaticCond.h>
#include <MultiRegions/GlobalLinSys.h>
#include <MultiRegions/GlobalLinSysXxtFull.h>
#ifdef NEKTAR_USING_PETSC
#include <MultiRegions/GlobalLinSysPETScFull.h>
#endif
#include <LocalRegions/MatrixKey.h>
#include <math.h>
......@@ -56,7 +61,22 @@ namespace Nektar
PreconditionerLinear::create,
"Full Linear space inverse Preconditioning");
/**
std::string PreconditionerLinear::solveType =
LibUtilities::SessionReader::RegisterDefaultSolverInfo(
"LinearPreconSolver",
"Xxt");
std::string PreconditionerLinear::solveTypeIds[] = {
LibUtilities::SessionReader::RegisterEnumValue(
"LinearPreconSolver",
"PETSc",
MultiRegions::eLinearPreconPETSc),
LibUtilities::SessionReader::RegisterEnumValue(
"LinearPreconSolver",
"Xxt",
MultiRegions::eLinearPreconXxt)
};
/**
* @class PreconditionerLinear
*
* This class implements preconditioning for the conjugate
......@@ -76,36 +96,67 @@ namespace Nektar
void PreconditionerLinear::v_BuildPreconditioner()
{
GlobalSysSolnType solvertype=m_locToGloMap->GetGlobalSysSolnType();
if(solvertype != eIterativeStaticCond)
{
ASSERTL0(0,"This type of preconditioning is not implemented for this solver");
}
GlobalSysSolnType sType = m_locToGloMap->GetGlobalSysSolnType();
ASSERTL0(sType == eIterativeStaticCond,
"This type of preconditioning is not implemented "
"for this solver");
boost::shared_ptr<MultiRegions::ExpList>
boost::shared_ptr<MultiRegions::ExpList>
expList=((m_linsys.lock())->GetLocMat()).lock();
m_vertLocToGloMap = m_locToGloMap->XxtLinearSpaceMap(*expList);
// Generate XXT system.
if(m_linsys.lock()->GetKey().GetMatrixType() == StdRegions::eMass)
{
GlobalLinSysKey preconKey(StdRegions::ePreconLinearSpaceMass,
m_vertLocToGloMap);
m_vertLinsys = MemoryManager<GlobalLinSysXxtFull>::
AllocateSharedPtr(preconKey,expList,m_vertLocToGloMap);
}
else
LinearPreconSolver solveType =
expList->GetSession()->GetSolverInfoAsEnum<LinearPreconSolver>(
"LinearPreconSolver");
GlobalSysSolnType linSolveType;
switch(solveType)
{
GlobalLinSysKey preconKey(StdRegions::ePreconLinearSpace,
m_vertLocToGloMap,
(m_linsys.lock())->GetKey().GetConstFactors());
m_vertLinsys = MemoryManager<GlobalLinSysXxtFull>::
AllocateSharedPtr(preconKey,expList,m_vertLocToGloMap);
case eLinearPreconXxt:
{
linSolveType = eXxtFullMatrix;
break;
}
case eLinearPreconPETSc:
{
#ifdef NEKTAR_USING_PETSC
linSolveType = ePETScFullMatrix;
#else
ASSERTL0(false, "Nektar++ has not been compiled with "
"PETSc support.");
#endif
}
}
m_vertLocToGloMap = m_locToGloMap->LinearSpaceMap(*expList, linSolveType);
// Generate linear solve system.
StdRegions::MatrixType mType =
m_linsys.lock()->GetKey().GetMatrixType() == StdRegions::eMass ?
StdRegions::ePreconLinearSpaceMass :
StdRegions::ePreconLinearSpace;
GlobalLinSysKey preconKey(mType, m_vertLocToGloMap);
switch(solveType)
{
case eLinearPreconXxt:
{
m_vertLinsys = MemoryManager<GlobalLinSysXxtFull>::
AllocateSharedPtr(preconKey,expList,m_vertLocToGloMap);
break;
}
case eLinearPreconPETSc:
{
#ifdef NEKTAR_USING_PETSC
m_vertLinsys = MemoryManager<GlobalLinSysPETScFull>::
AllocateSharedPtr(preconKey,expList,m_vertLocToGloMap);
#else
ASSERTL0(false, "Nektar++ has not been compiled with "
"PETSc support.");
#endif
}
}
}
/**
......
......@@ -46,6 +46,12 @@ namespace Nektar
{
namespace MultiRegions
{
enum LinearPreconSolver
{
eLinearPreconXxt,
eLinearPreconPETSc
};
class PreconditionerLinear;
typedef boost::shared_ptr<PreconditionerLinear> PreconditionerLinearSharedPtr;
......@@ -78,6 +84,8 @@ namespace Nektar
boost::shared_ptr<AssemblyMap> m_vertLocToGloMap;
private:
static std::string solveType;
static std::string solveTypeIds[];
virtual void v_InitObject();
......
///////////////////////////////////////////////////////////////////////////////
//
// File PreconditionerPETScLinear.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: PreconditionerPETScLinear definition
//
///////////////////////////////////////////////////////////////////////////////
#include <LibUtilities/BasicUtils/VDmathArray.hpp>
#include <MultiRegions/PreconditionerPETScLinear.h>
#include <MultiRegions/GlobalMatrixKey.h>
#include <MultiRegions/GlobalLinSysIterativeStaticCond.h>
#include <MultiRegions/GlobalLinSys.h>
#include <MultiRegions/GlobalLinSysPETScFull.h>
#include <LocalRegions/MatrixKey.h>
#include <math.h>
namespace Nektar
{
namespace MultiRegions
{
/**
* Registers the class with the Factory.
*/
string PreconditionerPETScLinear::className1
= GetPreconFactory().RegisterCreatorFunction(
"LinearPETSc",
PreconditionerPETScLinear::create,
"PETSc Preconditioning");
/**
* @class PreconditionerPETScLinear
*
* This class implements preconditioning for the conjugate
* gradient matrix solver.
*/
PreconditionerPETScLinear::PreconditionerPETScLinear(
const boost::shared_ptr<GlobalLinSys> &plinsys,
const AssemblyMapSharedPtr &pLocToGloMap)
: Preconditioner(plinsys, pLocToGloMap)
{
}
void PreconditionerPETScLinear::v_InitObject()
{
}
void PreconditionerPETScLinear::v_BuildPreconditioner()
{
GlobalSysSolnType solvertype=m_locToGloMap->GetGlobalSysSolnType();
boost::shared_ptr<MultiRegions::ExpList>
expList=((m_linsys.lock())->GetLocMat()).lock();
m_vertLocToGloMap = m_locToGloMap->XxtLinearSpaceMap(*expList);
// Generate PETSc system.
GlobalLinSysKey preconKey(StdRegions::ePreconLinearSpace,
m_vertLocToGloMap,
(m_linsys.lock())->GetKey().GetConstFactors());
m_vertLinsys = MemoryManager<GlobalLinSysPETScFull>::
AllocateSharedPtr(preconKey,expList,m_vertLocToGloMap);
}
/**
*
*/
void PreconditionerPETScLinear::v_DoPreconditioner(
const Array<OneD, NekDouble>& pInput,
Array<OneD, NekDouble>& pOutput)
{
v_DoPreconditionerWithNonVertOutput(pInput,pOutput,NullNekDouble1DArray);
}
/**
*
*/
void PreconditionerPETScLinear::v_DoPreconditionerWithNonVertOutput(
const Array<OneD, NekDouble>& pInput,
Array<OneD, NekDouble>& pOutput,
const Array<OneD, NekDouble>& pNonVertOutput)
{
GlobalSysSolnType solvertype=m_locToGloMap->GetGlobalSysSolnType();
switch(solvertype)
{
case MultiRegions::eIterativeStaticCond:
{
int i,val;
int nloc = m_vertLocToGloMap->GetNumLocalCoeffs();
int nglo = m_vertLocToGloMap->GetNumGlobalCoeffs();
// mapping from full space to vertices
Array<OneD, int> LocToGloBnd = m_vertLocToGloMap->GetLocalToGlobalBndMap();
// Global to local for linear solver (different from above)
Array<OneD, int> LocToGlo = m_vertLocToGloMap->GetLocalToGlobalMap();
// number of Dir coeffs in from full problem
int nDirFull = m_locToGloMap->GetNumGlobalDirBndCoeffs();
Array<OneD,NekDouble> In(nglo,0.0);
Array<OneD,NekDouble> Out(nglo,0.0);
// Gather rhs
for(i = 0; i < nloc; ++i)
{
val = LocToGloBnd[i];
if(val >= nDirFull)
{
In[LocToGlo[i]] = pInput[val-nDirFull];
}
}
// Do solve without enforcing any boundary conditions.
m_vertLinsys->SolveLinearSystem(m_vertLocToGloMap->GetNumLocalCoeffs(),
In,Out,m_vertLocToGloMap);
if(pNonVertOutput != NullNekDouble1DArray)
{
ASSERTL1(pNonVertOutput.num_elements() >= pOutput.num_elements(),"Non Vert output is not of sufficient length");
Vmath::Vcopy(pOutput.num_elements(),pNonVertOutput,1,pOutput,1);
}
else
{
//Copy input to output as a unit preconditioner on
//any other value
Vmath::Vcopy(pInput.num_elements(),pInput,1,pOutput,1);
}
// Scatter back soln from linear solve
for(i = 0; i < nloc; ++i)
{
val = LocToGloBnd[i];
if(val >= nDirFull)
{
pOutput[val-nDirFull] = Out[LocToGlo[i]];
}
}
}
break;
default:
ASSERTL0(0,"Unsupported solver type");
break;
}
}
}
}
///////////////////////////////////////////////////////////////////////////////
//
// File PreconditionerPETScLinear.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: Preconditioner header
//
///////////////////////////////////////////////////////////////////////////////
#ifndef NEKTAR_LIB_MULTIREGIONS_PRECONDITIONERPETSCLINEAR_H
#define NEKTAR_LIB_MULTIREGIONS_PRECONDITIONERPETSCLINEAR_H
#include <MultiRegions/GlobalLinSys.h>
#include <MultiRegions/Preconditioner.h>
#include <MultiRegions/MultiRegionsDeclspec.h>
#include <MultiRegions/AssemblyMap/AssemblyMapCG.h>
#include <LocalRegions/TetExp.h>
#include <LocalRegions/PrismExp.h>
namespace Nektar
{
namespace MultiRegions
{
class PreconditionerPETScLinear;
typedef boost::shared_ptr<PreconditionerPETScLinear> PreconditionerPETScLinearSharedPtr;
class PreconditionerPETScLinear: public Preconditioner
{
public:
/// Creates an instance of this class
static PreconditionerSharedPtr create(
const boost::shared_ptr<GlobalLinSys> &plinsys,
const boost::shared_ptr<AssemblyMap>
&pLocToGloMap)
{
PreconditionerSharedPtr p = MemoryManager<PreconditionerPETScLinear>::AllocateSharedPtr(plinsys,pLocToGloMap);
p->InitObject();
return p;
}
/// Name of class
static std::string className1;
MULTI_REGIONS_EXPORT PreconditionerPETScLinear(
const boost::shared_ptr<GlobalLinSys> &plinsys,
const AssemblyMapSharedPtr &pLocToGloMap);
MULTI_REGIONS_EXPORT
virtual ~PreconditionerPETScLinear() {}
protected:
GlobalLinSysSharedPtr m_vertLinsys;
boost::shared_ptr<AssemblyMap> m_vertLocToGloMap;
private:
virtual void v_InitObject();
virtual void v_DoPreconditioner(
const Array<OneD, NekDouble>& pInput,
Array<OneD, NekDouble>& pOutput);
virtual void v_BuildPreconditioner();
virtual void v_DoPreconditionerWithNonVertOutput(
const Array<OneD, NekDouble>& pInput,
Array<OneD, NekDouble>& pOutput,
const Array<OneD, NekDouble>& pNonVertOutput);
};
}
}
#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