Nektar++
Static Public Member Functions | Static Public Attributes | Protected Member Functions | Static Protected Attributes | Private Member Functions | Private Attributes | Friends | List of all members
Nektar::SolverUtils::DriverPFASST Class Reference

Base class for the development of solvers. More...

#include <DriverPFASST.h>

Inheritance diagram for Nektar::SolverUtils::DriverPFASST:
[legend]

Static Public Member Functions

static DriverSharedPtr create (const LibUtilities::SessionReaderSharedPtr &pSession, const SpatialDomains::MeshGraphSharedPtr &pGraph)
 Creates an instance of this class. More...
 

Static Public Attributes

static std::string className
 Name of the class. More...
 

Protected Member Functions

SOLVER_UTILS_EXPORT DriverPFASST (const LibUtilities::SessionReaderSharedPtr pSession, const SpatialDomains::MeshGraphSharedPtr pGraph)
 Constructor. More...
 
SOLVER_UTILS_EXPORT ~DriverPFASST () override=default
 Destructor. More...
 
SOLVER_UTILS_EXPORT void v_InitObject (std::ostream &out=std::cout) override
 Virtual function for initialisation implementation. More...
 
SOLVER_UTILS_EXPORT void v_Execute (std::ostream &out=std::cout) override
 Virtual function for solve implementation. More...
 
- Protected Member Functions inherited from Nektar::SolverUtils::DriverParallelInTime
SOLVER_UTILS_EXPORT DriverParallelInTime (const LibUtilities::SessionReaderSharedPtr pSession, const SpatialDomains::MeshGraphSharedPtr pGraph)
 Constructor. More...
 
SOLVER_UTILS_EXPORT ~DriverParallelInTime () override=default
 Destructor. More...
 
SOLVER_UTILS_EXPORT void v_InitObject (std::ostream &out=std::cout) override
 Virtual function for initialisation implementation. More...
 
SOLVER_UTILS_EXPORT void v_Execute (std::ostream &out=std::cout) override
 Virtual function for solve implementation. More...
 
void SetParallelInTimeEquationSystem (std::string AdvectiveType)
 
void GetParametersFromSession (void)
 
void InitialiseEqSystem (bool turnoff_output)
 
void InitialiseInterpolationField (void)
 
void PrintSolverInfo (std::ostream &out=std::cout)
 
void PrintHeader (const std::string &title, const char c)
 
void RecvFromPreviousProc (Array< OneD, Array< OneD, NekDouble > > &array, int &convergence)
 
void RecvFromPreviousProc (Array< OneD, NekDouble > &array)
 
void SendToNextProc (Array< OneD, Array< OneD, NekDouble > > &array, int &convergence)
 
void SendToNextProc (Array< OneD, NekDouble > &array)
 
void CopySolutionVector (const Array< OneD, const Array< OneD, NekDouble > > &in, Array< OneD, Array< OneD, NekDouble > > &out)
 
void CopyFromPhysField (const size_t timeLevel, Array< OneD, Array< OneD, NekDouble > > &out)
 
void CopyToPhysField (const size_t timeLevel, const Array< OneD, const Array< OneD, NekDouble > > &in)
 
void UpdateFieldCoeffs (const size_t timeLevel, const Array< OneD, const Array< OneD, NekDouble > > &in=NullNekDoubleArrayOfArray)
 
void EvaluateExactSolution (const size_t timeLevel, const NekDouble &time)
 
void SolutionConvergenceMonitoring (const size_t timeLevel, const size_t iter)
 
void SolutionConvergenceSummary (const size_t timeLevel)
 
void UpdateErrorNorm (const size_t timeLevel, const bool normalized)
 
void PrintErrorNorm (const size_t timeLevel, const bool normalized)
 
NekDouble vL2ErrorMax (void)
 
NekDouble EstimateCommunicationTime (Array< OneD, Array< OneD, NekDouble > > &buffer1, Array< OneD, Array< OneD, NekDouble > > &buffer2)
 
void Interpolate (const Array< OneD, MultiRegions::ExpListSharedPtr > &infield, const Array< OneD, MultiRegions::ExpListSharedPtr > &outfield, const Array< OneD, Array< OneD, NekDouble > > &inarray, Array< OneD, Array< OneD, NekDouble > > &outarray)
 
- Protected Member Functions inherited from Nektar::SolverUtils::Driver
 Driver (const LibUtilities::SessionReaderSharedPtr pSession, const SpatialDomains::MeshGraphSharedPtr pGraph)
 Initialises EquationSystem class members. More...
 
virtual SOLVER_UTILS_EXPORT void v_InitObject (std::ostream &out=std::cout)
 Virtual function for initialisation implementation. More...
 
virtual SOLVER_UTILS_EXPORT void v_Execute (std::ostream &out=std::cout)=0
 Virtual function for solve implementation. More...
 

Static Protected Attributes

static std::string driverLookupId
 
- Static Protected Attributes inherited from Nektar::SolverUtils::Driver
static std::string evolutionOperatorLookupIds []
 
static std::string evolutionOperatorDef
 
static std::string driverDefault
 

Private Member Functions

void AssertParameters (void)
 
void InitialiseSDCScheme (void)
 
void SetTimeInterpolator (void)
 
bool IsNotInitialCondition (const size_t n)
 
void PropagateQuadratureSolutionAndResidual (const size_t timeLevel, const size_t index)
 
void UpdateFirstQuadrature (const size_t timeLevel)
 
void RunSweep (const NekDouble time, const size_t timeLevel, const bool update=false)
 
void ResidualEval (const NekDouble time, const size_t timeLevel, const size_t n)
 
void ResidualEval (const NekDouble time, const size_t timeLevel)
 
void IntegratedResidualEval (const size_t timeLevel)
 
void Interpolate (const size_t coarseLevel, const SDCarray &in, const size_t fineLevel, SDCarray &out, bool forced)
 
void InterpolateSolution (const size_t timeLevel)
 
void InterpolateResidual (const size_t timeLevel)
 
void Restrict (const size_t fineLevel, const SDCarray &in, const size_t coarseLevel, SDCarray &out)
 
void RestrictSolution (const size_t timeLevel)
 
void RestrictResidual (const size_t timeLevel)
 
void ComputeFASCorrection (const size_t timeLevel)
 
void Correct (const size_t coarseLevel, const Array< OneD, Array< OneD, NekDouble > > &in, const size_t fineLevel, Array< OneD, Array< OneD, NekDouble > > &out, bool forced)
 
void CorrectInitialSolution (const size_t timeLevel)
 
void CorrectInitialResidual (const size_t timeLevel)
 
void Correct (const size_t coarseLevel, const SDCarray &rest, const SDCarray &in, const size_t fineLevel, SDCarray &out, bool forced)
 
void CorrectSolution (const size_t timeLevel)
 
void CorrectResidual (const size_t timeLevel)
 
void ApplyWindowing (void)
 
void EvaluateSDCResidualNorm (const size_t timeLevel)
 
void WriteOutput (const size_t step, const NekDouble time)
 
void Interpolate (const Array< OneD, MultiRegions::ExpListSharedPtr > &infield, const Array< OneD, MultiRegions::ExpListSharedPtr > &outfield, const Array< OneD, Array< OneD, NekDouble > > &inarray, Array< OneD, Array< OneD, NekDouble > > &outarray)
 

Private Attributes

Array< OneD, size_t > m_QuadPts
 
Array< OneD, Array< OneD, NekDouble > > m_ImatFtoC
 
Array< OneD, Array< OneD, NekDouble > > m_ImatCtoF
 
Array< OneD, SDCarraym_solutionRest
 
Array< OneD, SDCarraym_residualRest
 
Array< OneD, SDCarraym_integralRest
 
Array< OneD, SDCarraym_correction
 
Array< OneD, SDCarraym_storage
 
Array< OneD, std::shared_ptr< LibUtilities::TimeIntegrationSchemeSDC > > m_SDCSolver
 
bool m_updateResidual = false
 

Friends

class MemoryManager< DriverPFASST >
 

Additional Inherited Members

- Public Member Functions inherited from Nektar::SolverUtils::Driver
virtual ~Driver ()
 Destructor. More...
 
SOLVER_UTILS_EXPORT void InitObject (std::ostream &out=std::cout)
 Initialise Object. More...
 
SOLVER_UTILS_EXPORT void Execute (std::ostream &out=std::cout)
 Execute driver. More...
 
SOLVER_UTILS_EXPORT Array< OneD, EquationSystemSharedPtrGetEqu ()
 
- Protected Attributes inherited from Nektar::SolverUtils::DriverParallelInTime
NekDouble m_totalTime
 Total time integration interval. More...
 
NekDouble m_chunkTime
 Time integration interval per chunk. More...
 
NekDouble m_time
 Local time. More...
 
size_t m_numChunks
 Number of time chunks. More...
 
size_t m_chunkRank
 Rank in time. More...
 
size_t m_iterMaxPIT
 Maximum number of parallel-in-time iteration. More...
 
size_t m_numWindowsPIT
 
bool m_exactSolution
 Using exact solution to compute error norms. More...
 
NekDouble m_tolerPIT
 ParallelInTime tolerance. More...
 
size_t m_nVar
 Number of variables. More...
 
size_t m_nTimeLevel
 Number of time levels. More...
 
Array< OneD, size_t > m_nsteps
 Number of time steps for each time level. More...
 
Array< OneD, NekDoublem_timestep
 Time step for each time level. More...
 
Array< OneD, size_t > m_npts
 Number of dof for each time level. More...
 
Array< OneD, std::shared_ptr< UnsteadySystem > > m_EqSys
 Equation system to solve. More...
 
Array< OneD, NekDoublem_vL2Errors
 Storage for parallel-in-time iteration. More...
 
Array< OneD, NekDoublem_vLinfErrors
 
Array< OneD, Array< OneD, NekDouble > > m_exactsoln
 
- Protected Attributes inherited from Nektar::SolverUtils::Driver
LibUtilities::CommSharedPtr m_comm
 Communication object. More...
 
LibUtilities::SessionReaderSharedPtr m_session
 Session reader object. More...
 
LibUtilities::SessionReaderSharedPtr session_LinNS
 Coupling between SFD and arnoldi. More...
 
SpatialDomains::MeshGraphSharedPtr m_graph
 MeshGraph object. More...
 
Array< OneD, EquationSystemSharedPtrm_equ
 Equation system to solve. More...
 
int m_nequ
 number of equations More...
 
enum EvolutionOperatorType m_EvolutionOperator
 Evolution Operator. More...
 

Detailed Description

Base class for the development of solvers.

Definition at line 48 of file DriverPFASST.h.

Constructor & Destructor Documentation

◆ DriverPFASST()

Nektar::SolverUtils::DriverPFASST::DriverPFASST ( const LibUtilities::SessionReaderSharedPtr  pSession,
const SpatialDomains::MeshGraphSharedPtr  pGraph 
)
protected

Constructor.

Definition at line 52 of file DriverPFASST.cpp.

54 : DriverParallelInTime(pSession, pGraph)
55{
56}
SOLVER_UTILS_EXPORT DriverParallelInTime(const LibUtilities::SessionReaderSharedPtr pSession, const SpatialDomains::MeshGraphSharedPtr pGraph)
Constructor.

◆ ~DriverPFASST()

SOLVER_UTILS_EXPORT Nektar::SolverUtils::DriverPFASST::~DriverPFASST ( )
overrideprotecteddefault

Destructor.

Member Function Documentation

◆ ApplyWindowing()

void Nektar::SolverUtils::DriverPFASST::ApplyWindowing ( void  )
private

Definition at line 891 of file DriverPFASST.cpp.

892{
893 // Use last chunk solution as initial condition for the next window.
894 if (m_chunkRank == m_numChunks - 1)
895 {
897 for (size_t timeLevel = 0; timeLevel < m_nTimeLevel - 1; timeLevel++)
898 {
899 Interpolate(m_EqSys[timeLevel]->UpdateFields(),
900 m_EqSys[timeLevel + 1]->UpdateFields(),
901 m_SDCSolver[timeLevel]->GetSolutionVector()[0],
902 m_SDCSolver[timeLevel + 1]->UpdateSolutionVector()[0]);
903 }
904 }
905
906 // Broadcast I.C. for windowing.
907 for (size_t timeLevel = 0; timeLevel < m_nTimeLevel; timeLevel++)
908 {
909 for (size_t i = 0; i < m_nVar; ++i)
910 {
911 m_comm->GetTimeComm()->Bcast(
912 m_SDCSolver[timeLevel]->UpdateSolutionVector()[0][i],
913 m_numChunks - 1);
914 }
915 }
916}
LibUtilities::CommSharedPtr m_comm
Communication object.
Definition: Driver.h:80
void UpdateFirstQuadrature(const size_t timeLevel)
void Interpolate(const size_t coarseLevel, const SDCarray &in, const size_t fineLevel, SDCarray &out, bool forced)
Array< OneD, std::shared_ptr< LibUtilities::TimeIntegrationSchemeSDC > > m_SDCSolver
Definition: DriverPFASST.h:160
Array< OneD, std::shared_ptr< UnsteadySystem > > m_EqSys
Equation system to solve.

References Interpolate(), Nektar::SolverUtils::DriverParallelInTime::m_chunkRank, Nektar::SolverUtils::Driver::m_comm, Nektar::SolverUtils::DriverParallelInTime::m_EqSys, Nektar::SolverUtils::DriverParallelInTime::m_nTimeLevel, Nektar::SolverUtils::DriverParallelInTime::m_numChunks, Nektar::SolverUtils::DriverParallelInTime::m_nVar, m_SDCSolver, and UpdateFirstQuadrature().

Referenced by v_Execute().

◆ AssertParameters()

void Nektar::SolverUtils::DriverPFASST::AssertParameters ( void  )
private

Definition at line 280 of file DriverPFASST.cpp.

281{
282 // Assert time-stepping parameters.
283 for (size_t timeLevel = 0; timeLevel < m_nTimeLevel; timeLevel++)
284 {
285 ASSERTL0(
286 m_nsteps[timeLevel] % m_numChunks == 0,
287 "Total number of steps should be divisible by number of chunks.");
288
289 ASSERTL0(m_timestep[0] == m_timestep[timeLevel],
290 "All SDC levels should have the same timestep");
291
292 ASSERTL0(m_nsteps[0] == m_nsteps[timeLevel],
293 "All SDC levels should have the same timestep");
294 }
295
296 // Assert I/O parameters.
297 if (m_EqSys[0]->GetCheckpointSteps())
298 {
299 ASSERTL0(m_nsteps[0] % m_EqSys[0]->GetCheckpointSteps() == 0,
300 "number of IO_CheckSteps should divide number of steps "
301 "per time chunk");
302 }
303
304 if (m_EqSys[0]->GetInfoSteps())
305 {
306 ASSERTL0(m_nsteps[0] % m_EqSys[0]->GetInfoSteps() == 0,
307 "number of IO_InfoSteps should divide number of steps "
308 "per time chunk");
309 }
310}
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:208
Array< OneD, size_t > m_nsteps
Number of time steps for each time level.
Array< OneD, NekDouble > m_timestep
Time step for each time level.

References ASSERTL0, Nektar::SolverUtils::DriverParallelInTime::m_EqSys, Nektar::SolverUtils::DriverParallelInTime::m_nsteps, Nektar::SolverUtils::DriverParallelInTime::m_nTimeLevel, Nektar::SolverUtils::DriverParallelInTime::m_numChunks, and Nektar::SolverUtils::DriverParallelInTime::m_timestep.

◆ ComputeFASCorrection()

void Nektar::SolverUtils::DriverPFASST::ComputeFASCorrection ( const size_t  timeLevel)
private

Definition at line 682 of file DriverPFASST.cpp.

683{
684 size_t fineLevel = timeLevel - 1;
685 size_t coarseLevel = timeLevel;
686
687 if (fineLevel != 0)
688 {
689 // Restrict fine FAS correction term
690 Restrict(fineLevel, m_SDCSolver[fineLevel]->UpdateFAScorrectionVector(),
691 coarseLevel,
692 m_SDCSolver[coarseLevel]->UpdateFAScorrectionVector());
693
694 // Restrict fine integrated residual.
695 Restrict(fineLevel,
696 m_SDCSolver[fineLevel]->GetIntegratedResidualVector(),
697 coarseLevel, m_integralRest[fineLevel]);
698 }
699 else
700 {
701 // Restrict fine integrated residual.
702 Restrict(
703 fineLevel, m_SDCSolver[fineLevel]->GetIntegratedResidualVector(),
704 coarseLevel, m_SDCSolver[coarseLevel]->UpdateFAScorrectionVector());
705 }
706
707 // Compute coarse FAS correction terms.
708 for (size_t n = 0; n < m_QuadPts[coarseLevel]; ++n)
709 {
710 for (size_t i = 0; i < m_nVar; ++i)
711 {
712 if (fineLevel != 0)
713 {
715 m_npts[coarseLevel],
716 m_SDCSolver[coarseLevel]->GetFAScorrectionVector()[n][i], 1,
717 m_integralRest[fineLevel][n][i], 1,
718 m_SDCSolver[coarseLevel]->UpdateFAScorrectionVector()[n][i],
719 1);
720 }
721
723 m_npts[coarseLevel],
724 m_SDCSolver[coarseLevel]->GetFAScorrectionVector()[n][i], 1,
725 m_SDCSolver[coarseLevel]->GetIntegratedResidualVector()[n][i],
726 1, m_SDCSolver[coarseLevel]->UpdateFAScorrectionVector()[n][i],
727 1);
728 }
729 }
730}
void Restrict(const size_t fineLevel, const SDCarray &in, const size_t coarseLevel, SDCarray &out)
Array< OneD, SDCarray > m_integralRest
Definition: DriverPFASST.h:156
Array< OneD, size_t > m_QuadPts
Definition: DriverPFASST.h:151
Array< OneD, size_t > m_npts
Number of dof for each time level.
void Vadd(int n, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Add vector z = x+y.
Definition: Vmath.hpp:180
void Vsub(int n, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Subtract vector z = x-y.
Definition: Vmath.hpp:220

References m_integralRest, Nektar::SolverUtils::DriverParallelInTime::m_npts, Nektar::SolverUtils::DriverParallelInTime::m_nVar, m_QuadPts, m_SDCSolver, Restrict(), Vmath::Vadd(), and Vmath::Vsub().

Referenced by v_Execute().

◆ Correct() [1/2]

void Nektar::SolverUtils::DriverPFASST::Correct ( const size_t  coarseLevel,
const Array< OneD, Array< OneD, NekDouble > > &  in,
const size_t  fineLevel,
Array< OneD, Array< OneD, NekDouble > > &  out,
bool  forced 
)
private

Definition at line 735 of file DriverPFASST.cpp.

740{
741 if (forced || IsNotInitialCondition(0))
742 {
743 // Compute difference between coarse solution and restricted
744 // solution.
745 Interpolate(m_EqSys[fineLevel]->UpdateFields(),
746 m_EqSys[coarseLevel]->UpdateFields(), out,
747 m_correction[fineLevel][0]);
748 for (size_t i = 0; i < m_nVar; ++i)
749 {
750 Vmath::Vsub(m_npts[coarseLevel], in[i], 1,
751 m_correction[fineLevel][0][i], 1,
752 m_correction[fineLevel][0][i], 1);
753 }
754
755 // Add correction to fine solution.
756 Interpolate(m_EqSys[coarseLevel]->UpdateFields(),
757 m_EqSys[fineLevel]->UpdateFields(),
758 m_correction[fineLevel][0], m_storage[fineLevel][0]);
759 for (size_t i = 0; i < m_nVar; ++i)
760 {
761 Vmath::Vadd(m_npts[fineLevel], m_storage[fineLevel][0][i], 1,
762 out[i], 1, out[i], 1);
763 }
764 }
765}
Array< OneD, SDCarray > m_correction
Definition: DriverPFASST.h:157
Array< OneD, SDCarray > m_storage
Definition: DriverPFASST.h:158
bool IsNotInitialCondition(const size_t n)

References Interpolate(), IsNotInitialCondition(), m_correction, Nektar::SolverUtils::DriverParallelInTime::m_EqSys, Nektar::SolverUtils::DriverParallelInTime::m_npts, Nektar::SolverUtils::DriverParallelInTime::m_nVar, m_storage, Vmath::Vadd(), and Vmath::Vsub().

Referenced by CorrectInitialResidual(), CorrectInitialSolution(), CorrectResidual(), and CorrectSolution().

◆ Correct() [2/2]

void Nektar::SolverUtils::DriverPFASST::Correct ( const size_t  coarseLevel,
const SDCarray rest,
const SDCarray in,
const size_t  fineLevel,
SDCarray out,
bool  forced 
)
private

Definition at line 796 of file DriverPFASST.cpp.

799{
800 // Compute difference between coarse solution and restricted
801 // solution.
802 for (size_t n = 0; n < m_QuadPts[coarseLevel]; ++n)
803 {
804 if (forced || IsNotInitialCondition(n))
805 {
806 for (size_t i = 0; i < m_nVar; ++i)
807 {
808 Vmath::Vsub(m_npts[coarseLevel], in[n][i], 1, rest[n][i], 1,
809 m_correction[fineLevel][n][i], 1);
810 }
811 }
812 else
813 {
814 for (size_t i = 0; i < m_nVar; ++i)
815 {
816 Vmath::Zero(m_npts[coarseLevel], m_correction[fineLevel][n][i],
817 1);
818 }
819 }
820 }
821
822 // Interpolate coarse solution delta in space.
823 for (size_t n = 0; n < m_QuadPts[coarseLevel]; ++n)
824 {
825 Interpolate(m_EqSys[coarseLevel]->UpdateFields(),
826 m_EqSys[fineLevel]->UpdateFields(),
827 m_correction[fineLevel][n], m_storage[fineLevel][n]);
828 }
829
830 // Interpolate coarse solution delta in time and correct fine solution.
831 for (size_t n = 0; n < m_QuadPts[fineLevel]; ++n)
832 {
833 if (forced || IsNotInitialCondition(n))
834 {
835 for (size_t i = 0; i < m_nVar; ++i)
836 {
837 for (size_t k = 0; k < m_QuadPts[coarseLevel]; ++k)
838 {
839 size_t index = k * m_QuadPts[fineLevel] + n;
840 Vmath::Svtvp(m_npts[fineLevel],
841 m_ImatCtoF[fineLevel][index],
842 m_storage[fineLevel][k][i], 1, out[n][i], 1,
843 out[n][i], 1);
844 }
845 }
846 }
847 }
848}
Array< OneD, Array< OneD, NekDouble > > m_ImatCtoF
Definition: DriverPFASST.h:153
void Svtvp(int n, const T alpha, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Svtvp (scalar times vector plus vector): z = alpha*x + y.
Definition: Vmath.hpp:396
void Zero(int n, T *x, const int incx)
Zero vector.
Definition: Vmath.hpp:273

References Interpolate(), IsNotInitialCondition(), m_correction, Nektar::SolverUtils::DriverParallelInTime::m_EqSys, m_ImatCtoF, Nektar::SolverUtils::DriverParallelInTime::m_npts, Nektar::SolverUtils::DriverParallelInTime::m_nVar, m_QuadPts, m_storage, Vmath::Svtvp(), Vmath::Vsub(), and Vmath::Zero().

◆ CorrectInitialResidual()

void Nektar::SolverUtils::DriverPFASST::CorrectInitialResidual ( const size_t  timeLevel)
private

Definition at line 783 of file DriverPFASST.cpp.

784{
785 size_t fineLevel = timeLevel;
786 size_t coarseLevel = timeLevel + 1;
787
788 Correct(coarseLevel, m_SDCSolver[coarseLevel]->GetResidualVector()[0],
789 fineLevel, m_SDCSolver[fineLevel]->UpdateResidualVector()[0],
790 false);
791}
void Correct(const size_t coarseLevel, const Array< OneD, Array< OneD, NekDouble > > &in, const size_t fineLevel, Array< OneD, Array< OneD, NekDouble > > &out, bool forced)

References Correct(), and m_SDCSolver.

◆ CorrectInitialSolution()

void Nektar::SolverUtils::DriverPFASST::CorrectInitialSolution ( const size_t  timeLevel)
private

Definition at line 770 of file DriverPFASST.cpp.

771{
772 size_t fineLevel = timeLevel;
773 size_t coarseLevel = timeLevel + 1;
774
775 Correct(coarseLevel, m_SDCSolver[coarseLevel]->GetSolutionVector()[0],
776 fineLevel, m_SDCSolver[fineLevel]->UpdateSolutionVector()[0],
777 false);
778}

References Correct(), and m_SDCSolver.

◆ CorrectResidual()

void Nektar::SolverUtils::DriverPFASST::CorrectResidual ( const size_t  timeLevel)
private

Definition at line 866 of file DriverPFASST.cpp.

867{
868 size_t coarseLevel = timeLevel + 1;
869 size_t fineLevel = timeLevel;
870
871 // Evaluate fine residual.
873 {
874 for (size_t n = 1; n < m_QuadPts[fineLevel]; ++n)
875 {
876 ResidualEval(fineLevel, n);
877 }
878 }
879 // Correct fine residual.
880 else
881 {
882 Correct(coarseLevel, m_residualRest[fineLevel],
883 m_SDCSolver[coarseLevel]->GetResidualVector(), fineLevel,
884 m_SDCSolver[fineLevel]->UpdateResidualVector(), false);
885 }
886}
void ResidualEval(const NekDouble time, const size_t timeLevel, const size_t n)
Array< OneD, SDCarray > m_residualRest
Definition: DriverPFASST.h:155

References Correct(), m_QuadPts, m_residualRest, m_SDCSolver, m_updateResidual, and ResidualEval().

Referenced by v_Execute().

◆ CorrectSolution()

void Nektar::SolverUtils::DriverPFASST::CorrectSolution ( const size_t  timeLevel)
private

Definition at line 853 of file DriverPFASST.cpp.

854{
855 size_t coarseLevel = timeLevel + 1;
856 size_t fineLevel = timeLevel;
857
858 Correct(coarseLevel, m_solutionRest[fineLevel],
859 m_SDCSolver[coarseLevel]->GetSolutionVector(), fineLevel,
860 m_SDCSolver[fineLevel]->UpdateSolutionVector(), false);
861}
Array< OneD, SDCarray > m_solutionRest
Definition: DriverPFASST.h:154

References Correct(), m_SDCSolver, and m_solutionRest.

Referenced by v_Execute().

◆ create()

static DriverSharedPtr Nektar::SolverUtils::DriverPFASST::create ( const LibUtilities::SessionReaderSharedPtr pSession,
const SpatialDomains::MeshGraphSharedPtr pGraph 
)
inlinestatic

Creates an instance of this class.

Definition at line 54 of file DriverPFASST.h.

57 {
60 p->InitObject();
61 return p;
62 }
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
std::shared_ptr< Driver > DriverSharedPtr
A shared pointer to a Driver object.
Definition: Driver.h:52

References Nektar::MemoryManager< DataType >::AllocateSharedPtr(), and CellMLToNektar.cellml_metadata::p.

◆ EvaluateSDCResidualNorm()

void Nektar::SolverUtils::DriverPFASST::EvaluateSDCResidualNorm ( const size_t  timeLevel)
private

Definition at line 921 of file DriverPFASST.cpp.

922{
923 // Compute SDC residual norm
924 for (size_t i = 0; i < m_nVar; ++i)
925 {
927 m_npts[timeLevel],
928 m_SDCSolver[timeLevel]->GetSolutionVector()[0][i], 1,
929 m_SDCSolver[timeLevel]
930 ->GetIntegratedResidualVector()[m_QuadPts[timeLevel] - 1][i],
931 1, m_exactsoln[i], 1);
932 m_EqSys[timeLevel]->CopyToPhysField(
933 i, m_SDCSolver[timeLevel]
934 ->GetSolutionVector()[m_QuadPts[timeLevel] - 1][i]);
935 m_vL2Errors[i] = m_EqSys[timeLevel]->L2Error(i, m_exactsoln[i], 1);
936 m_vLinfErrors[i] = m_EqSys[timeLevel]->LinfError(i, m_exactsoln[i]);
937 }
938}
Array< OneD, NekDouble > m_vL2Errors
Storage for parallel-in-time iteration.
Array< OneD, Array< OneD, NekDouble > > m_exactsoln

References Nektar::SolverUtils::DriverParallelInTime::m_EqSys, Nektar::SolverUtils::DriverParallelInTime::m_exactsoln, Nektar::SolverUtils::DriverParallelInTime::m_npts, Nektar::SolverUtils::DriverParallelInTime::m_nVar, m_QuadPts, m_SDCSolver, Nektar::SolverUtils::DriverParallelInTime::m_vL2Errors, Nektar::SolverUtils::DriverParallelInTime::m_vLinfErrors, and Vmath::Vadd().

Referenced by v_Execute().

◆ InitialiseSDCScheme()

void Nektar::SolverUtils::DriverPFASST::InitialiseSDCScheme ( void  )
private

Definition at line 315 of file DriverPFASST.cpp.

316{
318 Array<OneD, std::shared_ptr<LibUtilities::TimeIntegrationSchemeSDC>>(
320 for (size_t timeLevel = 0; timeLevel < m_nTimeLevel; timeLevel++)
321 {
322 // Cast pointer for TimeIntegrationSchemeSDC.
323 m_SDCSolver[timeLevel] =
324 std::dynamic_pointer_cast<LibUtilities::TimeIntegrationSchemeSDC>(
325 m_EqSys[timeLevel]->GetTimeIntegrationScheme());
326
327 // Assert if a SDC time-integration is used.
328 ASSERTL0(m_SDCSolver[timeLevel] != nullptr,
329 "Should only be run with a SDC method");
330
331 // Order storage to list time-integrated fields first.
332 Array<OneD, Array<OneD, NekDouble>> fields(m_nVar);
333 for (size_t i = 0; i < m_nVar; ++i)
334 {
335 fields[i] = m_EqSys[timeLevel]->UpdatePhysField(i);
336 }
337
338 // Initialize SDC scheme.
339 m_SDCSolver[timeLevel]->SetPFASST(timeLevel != 0);
340 m_SDCSolver[timeLevel]->InitializeScheme(
341 m_timestep[timeLevel], fields, 0.0,
342 m_EqSys[timeLevel]->GetTimeIntegrationSchemeOperators());
343 }
344
345 // Alocate memory.
346 m_QuadPts = Array<OneD, size_t>(m_nTimeLevel);
347 for (size_t timeLevel = 0; timeLevel < m_nTimeLevel; timeLevel++)
348 {
349 m_QuadPts[timeLevel] = m_SDCSolver[timeLevel]->GetQuadPtsNumber();
350 }
351
352 m_solutionRest = Array<OneD, SDCarray>(m_nTimeLevel - 1);
353 m_residualRest = Array<OneD, SDCarray>(m_nTimeLevel - 1);
354 m_integralRest = Array<OneD, SDCarray>(m_nTimeLevel - 1);
355 m_correction = Array<OneD, SDCarray>(m_nTimeLevel - 1);
356 m_storage = Array<OneD, SDCarray>(m_nTimeLevel - 1);
357 for (size_t timeLevel = 0; timeLevel < m_nTimeLevel - 1; timeLevel++)
358 {
359 m_solutionRest[timeLevel] = SDCarray(m_QuadPts[timeLevel + 1]);
360 m_residualRest[timeLevel] = SDCarray(m_QuadPts[timeLevel + 1]);
361 m_integralRest[timeLevel] = SDCarray(m_QuadPts[timeLevel + 1]);
362 m_correction[timeLevel] = SDCarray(m_QuadPts[timeLevel + 1]);
363 m_storage[timeLevel] = SDCarray(m_QuadPts[timeLevel + 1]);
364 for (size_t n = 0; n < m_QuadPts[timeLevel + 1]; ++n)
365 {
366 m_solutionRest[timeLevel][n] =
367 Array<OneD, Array<OneD, NekDouble>>(m_nVar);
368 m_residualRest[timeLevel][n] =
369 Array<OneD, Array<OneD, NekDouble>>(m_nVar);
370 m_integralRest[timeLevel][n] =
371 Array<OneD, Array<OneD, NekDouble>>(m_nVar);
372 m_correction[timeLevel][n] =
373 Array<OneD, Array<OneD, NekDouble>>(m_nVar);
374 m_storage[timeLevel][n] =
375 Array<OneD, Array<OneD, NekDouble>>(m_nVar);
376 for (size_t i = 0; i < m_nVar; ++i)
377 {
378 m_solutionRest[timeLevel][n][i] =
379 Array<OneD, NekDouble>(m_npts[timeLevel + 1], 0.0);
380 m_residualRest[timeLevel][n][i] =
381 Array<OneD, NekDouble>(m_npts[timeLevel + 1], 0.0);
382 m_integralRest[timeLevel][n][i] =
383 Array<OneD, NekDouble>(m_npts[timeLevel + 1], 0.0);
384 m_correction[timeLevel][n][i] =
385 Array<OneD, NekDouble>(m_npts[timeLevel + 1], 0.0);
386 m_storage[timeLevel][n][i] =
387 Array<OneD, NekDouble>(m_npts[timeLevel], 0.0);
388 }
389 }
390 }
391}
Array< OneD, Array< OneD, Array< OneD, NekDouble > > > SDCarray
Definition: DriverPFASST.h:45

References ASSERTL0, m_correction, Nektar::SolverUtils::DriverParallelInTime::m_EqSys, m_integralRest, Nektar::SolverUtils::DriverParallelInTime::m_npts, Nektar::SolverUtils::DriverParallelInTime::m_nTimeLevel, Nektar::SolverUtils::DriverParallelInTime::m_nVar, m_QuadPts, m_residualRest, m_SDCSolver, m_solutionRest, m_storage, and Nektar::SolverUtils::DriverParallelInTime::m_timestep.

Referenced by v_InitObject().

◆ IntegratedResidualEval()

void Nektar::SolverUtils::DriverPFASST::IntegratedResidualEval ( const size_t  timeLevel)
private

Definition at line 541 of file DriverPFASST.cpp.

542{
543 m_SDCSolver[timeLevel]->UpdateIntegratedResidualQFint(m_chunkTime);
544}
NekDouble m_chunkTime
Time integration interval per chunk.

References Nektar::SolverUtils::DriverParallelInTime::m_chunkTime, and m_SDCSolver.

Referenced by v_Execute().

◆ Interpolate() [1/2]

void Nektar::SolverUtils::DriverParallelInTime::Interpolate ( const Array< OneD, MultiRegions::ExpListSharedPtr > &  infield,
const Array< OneD, MultiRegions::ExpListSharedPtr > &  outfield,
const Array< OneD, Array< OneD, NekDouble > > &  inarray,
Array< OneD, Array< OneD, NekDouble > > &  outarray 
)
private

Definition at line 116 of file DriverParallelInTime.cpp.

614{
615 if (infield.size() != outfield.size())
616 {
617 NEKERROR(ErrorUtil::efatal, "not the same number of variables")
618 }
619
620 for (size_t n = 0; n < infield.size(); ++n)
621 {
622 // Interpolation from infield -> outfield assuming that infield and
623 // outfield are the same explists, but at potentially different
624 // polynomial orders.
625 if (infield[n]->GetExpSize() != outfield[n]->GetExpSize())
626 {
627 NEKERROR(ErrorUtil::efatal, "not the same mesh")
628 }
629
630 // Assign input/output array.
631 auto inphys = (inarray == NullNekDoubleArrayOfArray)
632 ? infield[n]->UpdatePhys()
633 : inarray[n];
634 auto outphys = (outarray == NullNekDoubleArrayOfArray)
635 ? outfield[n]->UpdatePhys()
636 : outarray[n];
637
638 // If same polynomial orders, simply copy solution.
639 if (infield[n]->GetTotPoints() == outfield[n]->GetTotPoints())
640 {
641 Vmath::Vcopy(infield[n]->GetTotPoints(), inphys, 1, outphys, 1);
642 }
643 // If different polynomial orders, interpolate solution.
644 else
645 {
646 // Assign memory for coefficient space.
647 Array<OneD, NekDouble> incoeff(infield[n]->GetNcoeffs());
648
649 // Transform solution from physical to coefficient space.
650 infield[n]->FwdTransLocalElmt(inphys, incoeff);
651
652 for (size_t i = 0; i < infield[n]->GetExpSize(); ++i)
653 {
654 // Get the elements.
655 auto inElmt = infield[n]->GetExp(i);
656 auto outElmt = outfield[n]->GetExp(i);
657
658 // Get the offset of elements in the storage arrays.
659 size_t inoffset = infield[n]->GetCoeff_Offset(i);
660 size_t outoffset = outfield[n]->GetPhys_Offset(i);
661
662 // Interpolate elements.
663 Array<OneD, NekDouble> tmp;
665 if (inElmt->DetShapeType() == LibUtilities::Seg)
666 {
667 expPtr = std::make_shared<StdRegions::StdSegExp>(
668 LibUtilities::BasisKey(
669 inElmt->GetBasis(0)->GetBasisType(),
670 inElmt->GetBasis(0)->GetNumModes(),
671 outElmt->GetBasis(0)->GetPointsKey()));
672 }
673 else if (inElmt->DetShapeType() == LibUtilities::Quad)
674 {
675 expPtr = std::make_shared<StdRegions::StdQuadExp>(
676 LibUtilities::BasisKey(
677 inElmt->GetBasis(0)->GetBasisType(),
678 inElmt->GetBasis(0)->GetNumModes(),
679 outElmt->GetBasis(0)->GetPointsKey()),
680 LibUtilities::BasisKey(
681 inElmt->GetBasis(1)->GetBasisType(),
682 inElmt->GetBasis(1)->GetNumModes(),
683 outElmt->GetBasis(1)->GetPointsKey()));
684 }
685 else if (inElmt->DetShapeType() == LibUtilities::Tri)
686 {
687 expPtr = std::make_shared<StdRegions::StdTriExp>(
688 LibUtilities::BasisKey(
689 inElmt->GetBasis(0)->GetBasisType(),
690 inElmt->GetBasis(0)->GetNumModes(),
691 outElmt->GetBasis(0)->GetPointsKey()),
692 LibUtilities::BasisKey(
693 inElmt->GetBasis(1)->GetBasisType(),
694 inElmt->GetBasis(1)->GetNumModes(),
695 outElmt->GetBasis(1)->GetPointsKey()));
696 }
697 else if (inElmt->DetShapeType() == LibUtilities::Hex)
698 {
699 expPtr = std::make_shared<StdRegions::StdHexExp>(
700 LibUtilities::BasisKey(
701 inElmt->GetBasis(0)->GetBasisType(),
702 inElmt->GetBasis(0)->GetNumModes(),
703 outElmt->GetBasis(0)->GetPointsKey()),
704 LibUtilities::BasisKey(
705 inElmt->GetBasis(1)->GetBasisType(),
706 inElmt->GetBasis(1)->GetNumModes(),
707 outElmt->GetBasis(1)->GetPointsKey()),
708 LibUtilities::BasisKey(
709 inElmt->GetBasis(2)->GetBasisType(),
710 inElmt->GetBasis(2)->GetNumModes(),
711 outElmt->GetBasis(2)->GetPointsKey()));
712 }
713 else if (inElmt->DetShapeType() == LibUtilities::Prism)
714 {
715 expPtr = std::make_shared<StdRegions::StdPrismExp>(
716 LibUtilities::BasisKey(
717 inElmt->GetBasis(0)->GetBasisType(),
718 inElmt->GetBasis(0)->GetNumModes(),
719 outElmt->GetBasis(0)->GetPointsKey()),
720 LibUtilities::BasisKey(
721 inElmt->GetBasis(1)->GetBasisType(),
722 inElmt->GetBasis(1)->GetNumModes(),
723 outElmt->GetBasis(1)->GetPointsKey()),
724 LibUtilities::BasisKey(
725 inElmt->GetBasis(2)->GetBasisType(),
726 inElmt->GetBasis(2)->GetNumModes(),
727 outElmt->GetBasis(2)->GetPointsKey()));
728 }
729 else if (inElmt->DetShapeType() == LibUtilities::Pyr)
730 {
731 expPtr = std::make_shared<StdRegions::StdPyrExp>(
732 LibUtilities::BasisKey(
733 inElmt->GetBasis(0)->GetBasisType(),
734 inElmt->GetBasis(0)->GetNumModes(),
735 outElmt->GetBasis(0)->GetPointsKey()),
736 LibUtilities::BasisKey(
737 inElmt->GetBasis(1)->GetBasisType(),
738 inElmt->GetBasis(1)->GetNumModes(),
739 outElmt->GetBasis(1)->GetPointsKey()),
740 LibUtilities::BasisKey(
741 inElmt->GetBasis(2)->GetBasisType(),
742 inElmt->GetBasis(2)->GetNumModes(),
743 outElmt->GetBasis(2)->GetPointsKey()));
744 }
745 else if (inElmt->DetShapeType() == LibUtilities::Tet)
746 {
747 expPtr = std::make_shared<StdRegions::StdTetExp>(
748 LibUtilities::BasisKey(
749 inElmt->GetBasis(0)->GetBasisType(),
750 inElmt->GetBasis(0)->GetNumModes(),
751 outElmt->GetBasis(0)->GetPointsKey()),
752 LibUtilities::BasisKey(
753 inElmt->GetBasis(1)->GetBasisType(),
754 inElmt->GetBasis(1)->GetNumModes(),
755 outElmt->GetBasis(1)->GetPointsKey()),
756 LibUtilities::BasisKey(
757 inElmt->GetBasis(2)->GetBasisType(),
758 inElmt->GetBasis(2)->GetNumModes(),
759 outElmt->GetBasis(2)->GetPointsKey()));
760 }
761 expPtr->BwdTrans(incoeff + inoffset, tmp = outphys + outoffset);
762 }
763 }
764 }
765}
#define NEKERROR(type, msg)
Assert Level 0 – Fundamental assert which is used whether in FULLDEBUG, DEBUG or OPT compilation mode...
Definition: ErrorUtil.hpp:202
std::shared_ptr< StdExpansion > StdExpansionSharedPtr
static Array< OneD, Array< OneD, NekDouble > > NullNekDoubleArrayOfArray
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
Definition: Vmath.hpp:825

◆ Interpolate() [2/2]

void Nektar::SolverUtils::DriverPFASST::Interpolate ( const size_t  coarseLevel,
const SDCarray in,
const size_t  fineLevel,
SDCarray out,
bool  forced 
)
private

Definition at line 549 of file DriverPFASST.cpp.

552{
553 // Interpolate solution in space.
554 for (size_t n = 0; n < m_QuadPts[coarseLevel]; ++n)
555 {
556 Interpolate(m_EqSys[coarseLevel]->UpdateFields(),
557 m_EqSys[fineLevel]->UpdateFields(), in[n],
558 m_storage[fineLevel][n]);
559 }
560
561 // Interpolate solution in time.
562 for (size_t n = 0; n < m_QuadPts[fineLevel]; ++n)
563 {
564 if (forced || IsNotInitialCondition(n))
565 {
566 for (size_t i = 0; i < m_nVar; ++i)
567 {
568 Vmath::Smul(m_npts[fineLevel], m_ImatCtoF[fineLevel][n],
569 m_storage[fineLevel][0][i], 1, out[n][i], 1);
570 for (size_t k = 1; k < m_QuadPts[coarseLevel]; ++k)
571 {
572 size_t index = k * m_QuadPts[fineLevel] + n;
573 Vmath::Svtvp(m_npts[fineLevel],
574 m_ImatCtoF[fineLevel][index],
575 m_storage[fineLevel][k][i], 1, out[n][i], 1,
576 out[n][i], 1);
577 }
578 }
579 }
580 }
581}
void Smul(int n, const T alpha, const T *x, const int incx, T *y, const int incy)
Scalar multiply y = alpha*x.
Definition: Vmath.hpp:100

References Interpolate(), IsNotInitialCondition(), Nektar::SolverUtils::DriverParallelInTime::m_EqSys, m_ImatCtoF, Nektar::SolverUtils::DriverParallelInTime::m_npts, Nektar::SolverUtils::DriverParallelInTime::m_nVar, m_QuadPts, m_storage, Vmath::Smul(), and Vmath::Svtvp().

Referenced by ApplyWindowing(), Correct(), Interpolate(), InterpolateResidual(), InterpolateSolution(), and Restrict().

◆ InterpolateResidual()

void Nektar::SolverUtils::DriverPFASST::InterpolateResidual ( const size_t  timeLevel)
private

Definition at line 599 of file DriverPFASST.cpp.

600{
601 size_t coarseLevel = timeLevel;
602 size_t fineLevel = timeLevel - 1;
603
604 Interpolate(coarseLevel, m_SDCSolver[coarseLevel]->GetResidualVector(),
605 fineLevel, m_SDCSolver[fineLevel]->UpdateResidualVector(),
606 true);
607}

References Interpolate(), and m_SDCSolver.

Referenced by v_Execute().

◆ InterpolateSolution()

void Nektar::SolverUtils::DriverPFASST::InterpolateSolution ( const size_t  timeLevel)
private

Definition at line 586 of file DriverPFASST.cpp.

587{
588 size_t coarseLevel = timeLevel;
589 size_t fineLevel = timeLevel - 1;
590
591 Interpolate(coarseLevel, m_SDCSolver[coarseLevel]->GetSolutionVector(),
592 fineLevel, m_SDCSolver[fineLevel]->UpdateSolutionVector(),
593 false);
594}

References Interpolate(), and m_SDCSolver.

Referenced by v_Execute().

◆ IsNotInitialCondition()

bool Nektar::SolverUtils::DriverPFASST::IsNotInitialCondition ( const size_t  n)
private

Definition at line 457 of file DriverPFASST.cpp.

458{
459 return !(n == 0 && m_chunkRank == 0);
460}

References Nektar::SolverUtils::DriverParallelInTime::m_chunkRank.

Referenced by Correct(), and Interpolate().

◆ PropagateQuadratureSolutionAndResidual()

void Nektar::SolverUtils::DriverPFASST::PropagateQuadratureSolutionAndResidual ( const size_t  timeLevel,
const size_t  index 
)
private

Definition at line 465 of file DriverPFASST.cpp.

467{
468 for (size_t n = 0; n < m_QuadPts[timeLevel]; ++n)
469 {
470 if (n != index)
471 {
472 for (size_t i = 0; i < m_nVar; ++i)
473 {
475 m_npts[timeLevel],
476 m_SDCSolver[timeLevel]->GetSolutionVector()[index][i], 1,
477 m_SDCSolver[timeLevel]->UpdateSolutionVector()[n][i], 1);
479 m_npts[timeLevel],
480 m_SDCSolver[timeLevel]->GetResidualVector()[index][i], 1,
481 m_SDCSolver[timeLevel]->UpdateResidualVector()[n][i], 1);
482 }
483 }
484 }
485}

References Nektar::SolverUtils::DriverParallelInTime::m_npts, Nektar::SolverUtils::DriverParallelInTime::m_nVar, m_QuadPts, m_SDCSolver, and Vmath::Vcopy().

Referenced by v_Execute().

◆ ResidualEval() [1/2]

void Nektar::SolverUtils::DriverPFASST::ResidualEval ( const NekDouble  time,
const size_t  timeLevel 
)
private

Definition at line 532 of file DriverPFASST.cpp.

533{
534 m_SDCSolver[timeLevel]->SetTime(time);
535 m_SDCSolver[timeLevel]->ResidualEval(m_chunkTime);
536}

References Nektar::SolverUtils::DriverParallelInTime::m_chunkTime, and m_SDCSolver.

◆ ResidualEval() [2/2]

void Nektar::SolverUtils::DriverPFASST::ResidualEval ( const NekDouble  time,
const size_t  timeLevel,
const size_t  n 
)
private

Definition at line 522 of file DriverPFASST.cpp.

524{
525 m_SDCSolver[timeLevel]->SetTime(time);
526 m_SDCSolver[timeLevel]->ResidualEval(m_chunkTime, n);
527}

References Nektar::SolverUtils::DriverParallelInTime::m_chunkTime, and m_SDCSolver.

Referenced by CorrectResidual(), RestrictResidual(), RunSweep(), and v_Execute().

◆ Restrict()

void Nektar::SolverUtils::DriverPFASST::Restrict ( const size_t  fineLevel,
const SDCarray in,
const size_t  coarseLevel,
SDCarray out 
)
private

Definition at line 612 of file DriverPFASST.cpp.

614{
615 // Restrict fine solution in time.
616 for (size_t n = 0; n < m_QuadPts[coarseLevel]; ++n)
617 {
618 for (size_t i = 0; i < m_nVar; ++i)
619 {
620 Vmath::Smul(m_npts[fineLevel], m_ImatFtoC[fineLevel][n], in[0][i],
621 1, m_storage[fineLevel][n][i], 1);
622 for (size_t k = 1; k < m_QuadPts[fineLevel]; ++k)
623 {
624 size_t index = k * m_QuadPts[coarseLevel] + n;
625 Vmath::Svtvp(m_npts[fineLevel], m_ImatFtoC[fineLevel][index],
626 in[k][i], 1, m_storage[fineLevel][n][i], 1,
627 m_storage[fineLevel][n][i], 1);
628 }
629 }
630 }
631
632 // Restrict fine solution in space.
633 for (size_t n = 0; n < m_QuadPts[coarseLevel]; ++n)
634 {
635 Interpolate(m_EqSys[fineLevel]->UpdateFields(),
636 m_EqSys[coarseLevel]->UpdateFields(),
637 m_storage[fineLevel][n], out[n]);
638 }
639}
Array< OneD, Array< OneD, NekDouble > > m_ImatFtoC
Definition: DriverPFASST.h:152

References Interpolate(), Nektar::SolverUtils::DriverParallelInTime::m_EqSys, m_ImatFtoC, Nektar::SolverUtils::DriverParallelInTime::m_npts, Nektar::SolverUtils::DriverParallelInTime::m_nVar, m_QuadPts, m_storage, Vmath::Smul(), and Vmath::Svtvp().

Referenced by ComputeFASCorrection(), and RestrictSolution().

◆ RestrictResidual()

void Nektar::SolverUtils::DriverPFASST::RestrictResidual ( const size_t  timeLevel)
private

Definition at line 662 of file DriverPFASST.cpp.

663{
664 size_t fineLevel = timeLevel;
665 size_t coarseLevel = timeLevel + 1;
666
667 ResidualEval(m_time, coarseLevel);
668
669 if (!m_updateResidual)
670 {
671 for (size_t n = 0; n < m_QuadPts[coarseLevel]; ++n)
672 {
673 CopySolutionVector(m_SDCSolver[coarseLevel]->GetResidualVector()[n],
674 m_residualRest[fineLevel][n]);
675 }
676 }
677}
void CopySolutionVector(const Array< OneD, const Array< OneD, NekDouble > > &in, Array< OneD, Array< OneD, NekDouble > > &out)

References Nektar::SolverUtils::DriverParallelInTime::CopySolutionVector(), m_QuadPts, m_residualRest, m_SDCSolver, Nektar::SolverUtils::DriverParallelInTime::m_time, m_updateResidual, and ResidualEval().

Referenced by v_Execute().

◆ RestrictSolution()

void Nektar::SolverUtils::DriverPFASST::RestrictSolution ( const size_t  timeLevel)
private

Definition at line 644 of file DriverPFASST.cpp.

645{
646 size_t fineLevel = timeLevel;
647 size_t coarseLevel = timeLevel + 1;
648
649 Restrict(fineLevel, m_SDCSolver[fineLevel]->GetSolutionVector(),
650 coarseLevel, m_SDCSolver[coarseLevel]->UpdateSolutionVector());
651
652 for (size_t n = 0; n < m_QuadPts[coarseLevel]; ++n)
653 {
654 CopySolutionVector(m_SDCSolver[coarseLevel]->GetSolutionVector()[n],
655 m_solutionRest[fineLevel][n]);
656 }
657}

References Nektar::SolverUtils::DriverParallelInTime::CopySolutionVector(), m_QuadPts, m_SDCSolver, m_solutionRest, and Restrict().

Referenced by v_Execute().

◆ RunSweep()

void Nektar::SolverUtils::DriverPFASST::RunSweep ( const NekDouble  time,
const size_t  timeLevel,
const bool  update = false 
)
private

Definition at line 498 of file DriverPFASST.cpp.

500{
501 size_t niter = m_SDCSolver[timeLevel]->GetOrder();
502
503 if (update == true)
504 {
505 ResidualEval(m_time, timeLevel, 0);
506 }
507
508 // Start SDC iteration loop.
509 m_SDCSolver[timeLevel]->SetTime(time);
510 for (size_t k = 0; k < niter; k++)
511 {
512 m_SDCSolver[timeLevel]->SDCIterationLoop(m_chunkTime);
513 }
514
515 // Update last quadrature point.
516 m_SDCSolver[timeLevel]->UpdateLastQuadrature();
517}

References Nektar::SolverUtils::DriverParallelInTime::m_chunkTime, m_SDCSolver, Nektar::SolverUtils::DriverParallelInTime::m_time, and ResidualEval().

Referenced by v_Execute().

◆ SetTimeInterpolator()

void Nektar::SolverUtils::DriverPFASST::SetTimeInterpolator ( void  )
private

Definition at line 396 of file DriverPFASST.cpp.

397{
398 // Initialize time interpolator.
399 m_ImatFtoC = Array<OneD, Array<OneD, NekDouble>>(m_nTimeLevel - 1);
400 m_ImatCtoF = Array<OneD, Array<OneD, NekDouble>>(m_nTimeLevel - 1);
401 for (size_t timeLevel = 0; timeLevel < m_nTimeLevel - 1; timeLevel++)
402 {
403 LibUtilities::PointsKey fpoints =
404 m_SDCSolver[timeLevel]->GetPointsKey();
405 LibUtilities::PointsKey cpoints =
406 m_SDCSolver[timeLevel + 1]->GetPointsKey();
407 DNekMatSharedPtr ImatFtoC =
408 LibUtilities::PointsManager()[fpoints]->GetI(cpoints);
409 DNekMatSharedPtr ImatCtoF =
410 LibUtilities::PointsManager()[cpoints]->GetI(fpoints);
411 m_ImatFtoC[timeLevel] = Array<OneD, NekDouble>(
412 m_QuadPts[timeLevel] * m_QuadPts[timeLevel + 1], 0.0);
413 m_ImatCtoF[timeLevel] = Array<OneD, NekDouble>(
414 m_QuadPts[timeLevel] * m_QuadPts[timeLevel + 1], 0.0);
415
416 // Determine if Radau quadrature are used.
417 size_t i0 = m_SDCSolver[timeLevel]->HasFirstQuadrature() ? 0 : 1;
418 size_t j0 = m_SDCSolver[timeLevel + 1]->HasFirstQuadrature() ? 0 : 1;
419
420 // Adapt fine to coarse time interpolator.
421 for (size_t i = i0; i < m_QuadPts[timeLevel]; ++i)
422 {
423 for (size_t j = j0; j < m_QuadPts[timeLevel + 1]; ++j)
424 {
425 m_ImatFtoC[timeLevel][i * m_QuadPts[timeLevel + 1] + j] =
426 (ImatFtoC->GetPtr())[(i - i0) *
427 (m_QuadPts[timeLevel + 1] - j0) +
428 (j - j0)];
429 }
430 }
431 if (j0 == 1)
432 {
433 m_ImatFtoC[timeLevel][0] = 1.0;
434 }
435
436 // Adapt coarse to fine time interpolator.
437 for (size_t j = j0; j < m_QuadPts[timeLevel + 1]; ++j)
438 {
439 for (size_t i = i0; i < m_QuadPts[timeLevel]; ++i)
440 {
441 m_ImatCtoF[timeLevel][j * m_QuadPts[timeLevel] + i] =
442 (ImatCtoF
443 ->GetPtr())[(j - j0) * (m_QuadPts[timeLevel] - i0) +
444 (i - i0)];
445 }
446 }
447 if (i0 == 1)
448 {
449 m_ImatCtoF[timeLevel][0] = 1.0;
450 }
451 }
452}
PointsManagerT & PointsManager(void)
std::shared_ptr< DNekMat > DNekMatSharedPtr
Definition: NekTypeDefs.hpp:75

References m_ImatCtoF, m_ImatFtoC, Nektar::SolverUtils::DriverParallelInTime::m_nTimeLevel, m_QuadPts, m_SDCSolver, and Nektar::LibUtilities::PointsManager().

Referenced by v_InitObject().

◆ UpdateFirstQuadrature()

void Nektar::SolverUtils::DriverPFASST::UpdateFirstQuadrature ( const size_t  timeLevel)
private

Definition at line 490 of file DriverPFASST.cpp.

491{
492 m_SDCSolver[timeLevel]->UpdateFirstQuadrature();
493}

References m_SDCSolver.

Referenced by ApplyWindowing(), and v_Execute().

◆ v_Execute()

void Nektar::SolverUtils::DriverPFASST::v_Execute ( std::ostream &  out = std::cout)
overrideprotectedvirtual

Virtual function for solve implementation.

Reimplemented from Nektar::SolverUtils::DriverParallelInTime.

Definition at line 74 of file DriverPFASST.cpp.

75{
76 // Timing.
78 NekDouble totalTime = 0.0, predictorTime = 0.0, fineSolveTime = 0.0,
79 coarseSolveTime = 0.0, fasTime = 0.0;
80
81 // Initialie time step parameters.
82 size_t step = m_chunkRank;
86
87 // Start iteration windows.
88 m_comm->GetTimeComm()->Block();
89 for (size_t w = 0; w < m_numWindowsPIT; w++)
90 {
91 timer.Start();
92 PrintHeader((boost::format("WINDOWS #%1%") % (w + 1)).str(), '*');
93
94 // Compute initial guess for coarse solver.
98 for (size_t k = 0; k < m_chunkRank; k++)
99 {
104 }
106
107 // Interpolate coarse solution and residual to fine.
108 for (size_t timeLevel = m_nTimeLevel - 1; timeLevel > 0; timeLevel--)
109 {
110 InterpolateSolution(timeLevel);
111 InterpolateResidual(timeLevel);
112 }
113 timer.Stop();
114 predictorTime += timer.Elapsed().count();
115 totalTime += timer.Elapsed().count();
116
117 // Start CorrectInitialPFASST iteration.
118 size_t k = 0;
119 int convergenceCurr = 0;
120 std::vector<int> convergencePrev(m_nTimeLevel, m_chunkRank == 0);
121 while (k < m_iterMaxPIT && !convergenceCurr)
122 {
123 // The PFASST implementation follow "Bolten, M., Moser, D., & Speck,
124 // R. (2017). A multigrid perspective on the parallel full
125 // approximation scheme in space and time. Numerical Linear Algebra
126 // with Applications, 24(6)".
127
128 if (m_chunkRank == m_numChunks - 1 &&
129 m_comm->GetSpaceComm()->GetRank() == 0)
130 {
131 std::cout << "Iteration " << k + 1 << std::endl << std::flush;
132 }
133
134 // Performe sweep (parallel-in-time).
135 timer.Start();
136 RunSweep(m_time, 0, true);
137 timer.Stop();
138 fineSolveTime += timer.Elapsed().count();
139 totalTime += timer.Elapsed().count();
140
141 // Fine-to-coarse
142 timer.Start();
143 for (size_t timeLevel = 0; timeLevel < m_nTimeLevel - 1;
144 timeLevel++)
145 {
146 // Performe sweep (parallel-in-time).
147 if (timeLevel != 0)
148 {
149 RunSweep(m_time, timeLevel, true);
150 }
151
152 // Compute FAS correction (parallel-in-time).
153 RestrictSolution(timeLevel);
154 RestrictResidual(timeLevel);
155 IntegratedResidualEval(timeLevel);
156 IntegratedResidualEval(timeLevel + 1);
157 ComputeFASCorrection(timeLevel + 1);
158
159 // Check convergence.
160 if (timeLevel == 0)
161 {
162 // Evaluate SDC residual norm.
163 EvaluateSDCResidualNorm(timeLevel);
164
165 // Display L2norm.
166 PrintErrorNorm(timeLevel, true);
167 }
168 }
169 timer.Stop();
170 fasTime += timer.Elapsed().count();
171 totalTime += timer.Elapsed().count();
172
173 // Perform coarse sweep (serial-in-time).
174 timer.Start();
176 ->UpdateFirstQuadratureSolutionVector(),
177 convergencePrev[m_nTimeLevel - 1]);
178 timer.Stop();
179 totalTime += timer.Elapsed().count();
180 timer.Start();
181 RunSweep(m_time, m_nTimeLevel - 1, true);
182 timer.Stop();
183 coarseSolveTime += timer.Elapsed().count();
184 totalTime += timer.Elapsed().count();
185 convergenceCurr = (vL2ErrorMax() < m_tolerPIT &&
186 convergencePrev[m_nTimeLevel - 1]);
187 timer.Start();
189 ->UpdateLastQuadratureSolutionVector(),
190 convergenceCurr);
191 timer.Stop();
192 totalTime += timer.Elapsed().count();
193
194 // Coarse-to-fine.
195 timer.Start();
196 for (size_t timeLevel = m_nTimeLevel - 1; timeLevel > 0;
197 timeLevel--)
198 {
199 // Correct solution and residual.
200 /*SendToNextProc(m_SDCSolver[timeLevel - 1]
201 ->UpdateLastQuadratureSolutionVector(),
202 convergenceCurr);*/
203 CorrectSolution(timeLevel - 1);
204 CorrectResidual(timeLevel - 1);
205 /*RecvFromPreviousProc(
206 m_SDCSolver[timeLevel - 1]
207 ->UpdateFirstQuadratureSolutionVector(),
208 convergencePrev[timeLevel - 1]);
209 CorrectInitialSolution(timeLevel - 1);*/
210 if (timeLevel - 1 != 0)
211 {
212 RunSweep(m_time, timeLevel - 1, true);
213 }
214 }
215 timer.Stop();
216 fasTime += timer.Elapsed().count();
217 totalTime += timer.Elapsed().count();
218 k++;
219 }
220
221 // Apply windowing.
222 timer.Start();
223 if (w < m_numWindowsPIT - 1)
224 {
226 }
227 timer.Stop();
228 totalTime += timer.Elapsed().count();
229
230 // Update field and write output.
231 WriteOutput(step, m_time);
232 if (m_chunkRank == m_numChunks - 1 &&
233 m_comm->GetSpaceComm()->GetRank() == 0)
234 {
235 std::cout << "Total Computation Time : " << totalTime << "s"
236 << std::endl
237 << std::flush;
238 std::cout << " - Predictor Time = " << predictorTime << "s"
239 << std::endl
240 << std::flush;
241 std::cout << " - Coarse Solve Time = " << coarseSolveTime << "s"
242 << std::endl
243 << std::flush;
244 std::cout << " - Fine Solve Time = " << fineSolveTime << "s"
245 << std::endl
246 << std::flush;
247 std::cout << " - FAS Correction Time = " << fasTime << "s"
248 << std::endl
249 << std::flush;
250 }
251 step += m_numChunks;
252 }
253
254 m_comm->GetTimeComm()->Block();
255 PrintHeader("SUMMARY", '*');
258 if (m_chunkRank == m_numChunks - 1 &&
259 m_comm->GetSpaceComm()->GetRank() == 0)
260 {
261 std::cout << "Total Computation Time : " << totalTime << "s"
262 << std::endl
263 << std::flush;
264 std::cout << " - Predictor Time = " << predictorTime << "s" << std::endl
265 << std::flush;
266 std::cout << " - Coarse Solve Time = " << coarseSolveTime << "s"
267 << std::endl
268 << std::flush;
269 std::cout << " - Fine Solve Time = " << fineSolveTime << "s"
270 << std::endl
271 << std::flush;
272 std::cout << " - FAS Correction Time = " << fasTime << "s" << std::endl
273 << std::flush;
274 }
275}
void RestrictResidual(const size_t timeLevel)
void RestrictSolution(const size_t timeLevel)
void InterpolateResidual(const size_t timeLevel)
void CorrectSolution(const size_t timeLevel)
void EvaluateSDCResidualNorm(const size_t timeLevel)
void IntegratedResidualEval(const size_t timeLevel)
void RunSweep(const NekDouble time, const size_t timeLevel, const bool update=false)
void ComputeFASCorrection(const size_t timeLevel)
void WriteOutput(const size_t step, const NekDouble time)
void InterpolateSolution(const size_t timeLevel)
void PropagateQuadratureSolutionAndResidual(const size_t timeLevel, const size_t index)
void CorrectResidual(const size_t timeLevel)
NekDouble m_totalTime
Total time integration interval.
void SendToNextProc(Array< OneD, Array< OneD, NekDouble > > &array, int &convergence)
size_t m_iterMaxPIT
Maximum number of parallel-in-time iteration.
void PrintErrorNorm(const size_t timeLevel, const bool normalized)
void EvaluateExactSolution(const size_t timeLevel, const NekDouble &time)
void RecvFromPreviousProc(Array< OneD, Array< OneD, NekDouble > > &array, int &convergence)
void PrintHeader(const std::string &title, const char c)
NekDouble m_tolerPIT
ParallelInTime tolerance.
void SolutionConvergenceSummary(const size_t timeLevel)
std::vector< double > w(NPUPPER)
double NekDouble

References ApplyWindowing(), ComputeFASCorrection(), CorrectResidual(), CorrectSolution(), Nektar::LibUtilities::Timer::Elapsed(), Nektar::SolverUtils::DriverParallelInTime::EvaluateExactSolution(), EvaluateSDCResidualNorm(), CellMLToNektar.pycml::format, IntegratedResidualEval(), InterpolateResidual(), InterpolateSolution(), Nektar::SolverUtils::DriverParallelInTime::m_chunkRank, Nektar::SolverUtils::DriverParallelInTime::m_chunkTime, Nektar::SolverUtils::Driver::m_comm, Nektar::SolverUtils::DriverParallelInTime::m_iterMaxPIT, Nektar::SolverUtils::DriverParallelInTime::m_nsteps, Nektar::SolverUtils::DriverParallelInTime::m_nTimeLevel, Nektar::SolverUtils::DriverParallelInTime::m_numChunks, Nektar::SolverUtils::DriverParallelInTime::m_numWindowsPIT, m_SDCSolver, Nektar::SolverUtils::DriverParallelInTime::m_time, Nektar::SolverUtils::DriverParallelInTime::m_timestep, Nektar::SolverUtils::DriverParallelInTime::m_tolerPIT, Nektar::SolverUtils::DriverParallelInTime::m_totalTime, Nektar::SolverUtils::DriverParallelInTime::PrintErrorNorm(), Nektar::SolverUtils::DriverParallelInTime::PrintHeader(), PropagateQuadratureSolutionAndResidual(), Nektar::SolverUtils::DriverParallelInTime::RecvFromPreviousProc(), ResidualEval(), RestrictResidual(), RestrictSolution(), RunSweep(), Nektar::SolverUtils::DriverParallelInTime::SendToNextProc(), Nektar::SolverUtils::DriverParallelInTime::SolutionConvergenceSummary(), Nektar::LibUtilities::Timer::Start(), Nektar::LibUtilities::Timer::Stop(), UpdateFirstQuadrature(), Nektar::SolverUtils::DriverParallelInTime::vL2ErrorMax(), Nektar::UnitTests::w(), and WriteOutput().

◆ v_InitObject()

void Nektar::SolverUtils::DriverPFASST::v_InitObject ( std::ostream &  out = std::cout)
overrideprotectedvirtual

Virtual function for initialisation implementation.

Reimplemented from Nektar::SolverUtils::DriverParallelInTime.

Definition at line 61 of file DriverPFASST.cpp.

References Nektar::SolverUtils::DriverParallelInTime::GetParametersFromSession(), Nektar::SolverUtils::DriverParallelInTime::InitialiseEqSystem(), InitialiseSDCScheme(), Nektar::SolverUtils::DriverParallelInTime::PrintSolverInfo(), SetTimeInterpolator(), and Nektar::SolverUtils::DriverParallelInTime::v_InitObject().

◆ WriteOutput()

void Nektar::SolverUtils::DriverPFASST::WriteOutput ( const size_t  step,
const NekDouble  time 
)
private

Definition at line 943 of file DriverPFASST.cpp.

944{
945 size_t timeLevel = 0;
946 static size_t IOChkStep = m_EqSys[0]->GetCheckpointSteps()
947 ? m_EqSys[0]->GetCheckpointSteps()
948 : m_nsteps[timeLevel];
949 static std::string dirname = m_session->GetSessionName() + ".pit";
950
951 if ((step + 1) % IOChkStep == 0)
952 {
953 // Compute checkpoint index.
954 size_t nchk = (step + 1) / IOChkStep;
955
956 // Create directory if does not exist.
957 if (!fs::is_directory(dirname))
958 {
959 fs::create_directory(dirname);
960 }
961
962 // Update solution field.
964 timeLevel,
965 m_SDCSolver[timeLevel]->UpdateLastQuadratureSolutionVector());
966
967 // Set filename.
968 std::string filename = dirname + "/" + m_session->GetSessionName() +
969 "_" + std::to_string(nchk) + ".fld";
970
971 // Set time metadata.
972 m_EqSys[timeLevel]->SetTime(time);
973
974 // Write checkpoint.
975 m_EqSys[timeLevel]->WriteFld(filename);
976 }
977}
LibUtilities::SessionReaderSharedPtr m_session
Session reader object.
Definition: Driver.h:83
void UpdateFieldCoeffs(const size_t timeLevel, const Array< OneD, const Array< OneD, NekDouble > > &in=NullNekDoubleArrayOfArray)

References Nektar::SolverUtils::DriverParallelInTime::m_EqSys, Nektar::SolverUtils::DriverParallelInTime::m_nsteps, m_SDCSolver, Nektar::SolverUtils::Driver::m_session, and Nektar::SolverUtils::DriverParallelInTime::UpdateFieldCoeffs().

Referenced by v_Execute().

Friends And Related Function Documentation

◆ MemoryManager< DriverPFASST >

friend class MemoryManager< DriverPFASST >
friend

Definition at line 45 of file DriverPFASST.h.

Member Data Documentation

◆ className

std::string Nektar::SolverUtils::DriverPFASST::className
static
Initial value:
=
tKey RegisterCreatorFunction(tKey idKey, CreatorFunction classCreator, std::string pDesc="")
Register a class with the factory.
Definition: NekFactory.hpp:197
static DriverSharedPtr create(const LibUtilities::SessionReaderSharedPtr &pSession, const SpatialDomains::MeshGraphSharedPtr &pGraph)
Creates an instance of this class.
Definition: DriverPFASST.h:54
DriverFactory & GetDriverFactory()
Definition: Driver.cpp:65

Name of the class.

Definition at line 65 of file DriverPFASST.h.

◆ driverLookupId

std::string Nektar::SolverUtils::DriverPFASST::driverLookupId
staticprotected
Initial value:
=
static std::string RegisterEnumValue(std::string pEnum, std::string pString, int pEnumValue)
Registers an enumeration value.

Definition at line 83 of file DriverPFASST.h.

◆ m_correction

Array<OneD, SDCarray> Nektar::SolverUtils::DriverPFASST::m_correction
private

Definition at line 157 of file DriverPFASST.h.

Referenced by Correct(), and InitialiseSDCScheme().

◆ m_ImatCtoF

Array<OneD, Array<OneD, NekDouble> > Nektar::SolverUtils::DriverPFASST::m_ImatCtoF
private

Definition at line 153 of file DriverPFASST.h.

Referenced by Correct(), Interpolate(), and SetTimeInterpolator().

◆ m_ImatFtoC

Array<OneD, Array<OneD, NekDouble> > Nektar::SolverUtils::DriverPFASST::m_ImatFtoC
private

Definition at line 152 of file DriverPFASST.h.

Referenced by Restrict(), and SetTimeInterpolator().

◆ m_integralRest

Array<OneD, SDCarray> Nektar::SolverUtils::DriverPFASST::m_integralRest
private

Definition at line 156 of file DriverPFASST.h.

Referenced by ComputeFASCorrection(), and InitialiseSDCScheme().

◆ m_QuadPts

Array<OneD, size_t> Nektar::SolverUtils::DriverPFASST::m_QuadPts
private

◆ m_residualRest

Array<OneD, SDCarray> Nektar::SolverUtils::DriverPFASST::m_residualRest
private

Definition at line 155 of file DriverPFASST.h.

Referenced by CorrectResidual(), InitialiseSDCScheme(), and RestrictResidual().

◆ m_SDCSolver

Array<OneD, std::shared_ptr<LibUtilities::TimeIntegrationSchemeSDC> > Nektar::SolverUtils::DriverPFASST::m_SDCSolver
private

◆ m_solutionRest

Array<OneD, SDCarray> Nektar::SolverUtils::DriverPFASST::m_solutionRest
private

Definition at line 154 of file DriverPFASST.h.

Referenced by CorrectSolution(), InitialiseSDCScheme(), and RestrictSolution().

◆ m_storage

Array<OneD, SDCarray> Nektar::SolverUtils::DriverPFASST::m_storage
private

Definition at line 158 of file DriverPFASST.h.

Referenced by Correct(), InitialiseSDCScheme(), Interpolate(), and Restrict().

◆ m_updateResidual

bool Nektar::SolverUtils::DriverPFASST::m_updateResidual = false
private

Definition at line 162 of file DriverPFASST.h.

Referenced by CorrectResidual(), and RestrictResidual().