40#include <boost/format.hpp>
78 NekDouble totalTime = 0.0, predictorTime = 0.0, fineSolveTime = 0.0,
79 coarseSolveTime = 0.0, fasTime = 0.0;
88 m_comm->GetTimeComm()->Block();
108 for (
size_t timeLevel =
m_nTimeLevel - 1; timeLevel > 0; timeLevel--)
114 predictorTime += timer.
Elapsed().count();
115 totalTime += timer.
Elapsed().count();
119 int convergenceCurr = 0;
129 m_comm->GetSpaceComm()->GetRank() == 0)
131 std::cout <<
"Iteration " << k + 1 << std::endl << std::flush;
138 fineSolveTime += timer.
Elapsed().count();
139 totalTime += timer.
Elapsed().count();
143 for (
size_t timeLevel = 0; timeLevel <
m_nTimeLevel - 1;
170 fasTime += timer.
Elapsed().count();
171 totalTime += timer.
Elapsed().count();
176 ->UpdateFirstQuadratureSolutionVector(),
179 totalTime += timer.
Elapsed().count();
183 coarseSolveTime += timer.
Elapsed().count();
184 totalTime += timer.
Elapsed().count();
189 ->UpdateLastQuadratureSolutionVector(),
192 totalTime += timer.
Elapsed().count();
196 for (
size_t timeLevel =
m_nTimeLevel - 1; timeLevel > 0;
210 if (timeLevel - 1 != 0)
216 fasTime += timer.
Elapsed().count();
217 totalTime += timer.
Elapsed().count();
228 totalTime += timer.
Elapsed().count();
233 m_comm->GetSpaceComm()->GetRank() == 0)
235 std::cout <<
"Total Computation Time : " << totalTime <<
"s"
238 std::cout <<
" - Predictor Time = " << predictorTime <<
"s"
241 std::cout <<
" - Coarse Solve Time = " << coarseSolveTime <<
"s"
244 std::cout <<
" - Fine Solve Time = " << fineSolveTime <<
"s"
247 std::cout <<
" - FAS Correction Time = " << fasTime <<
"s"
254 m_comm->GetTimeComm()->Block();
259 m_comm->GetSpaceComm()->GetRank() == 0)
261 std::cout <<
"Total Computation Time : " << totalTime <<
"s"
264 std::cout <<
" - Predictor Time = " << predictorTime <<
"s" << std::endl
266 std::cout <<
" - Coarse Solve Time = " << coarseSolveTime <<
"s"
269 std::cout <<
" - Fine Solve Time = " << fineSolveTime <<
"s"
272 std::cout <<
" - FAS Correction Time = " << fasTime <<
"s" << std::endl
283 for (
size_t timeLevel = 0; timeLevel <
m_nTimeLevel; timeLevel++)
287 "Total number of steps should be divisible by number of chunks.");
290 "All SDC levels should have the same timestep");
293 "All SDC levels should have the same timestep");
297 if (
m_EqSys[0]->GetCheckpointSteps())
300 "number of IO_CheckSteps should divide number of steps "
304 if (
m_EqSys[0]->GetInfoSteps())
307 "number of IO_InfoSteps should divide number of steps "
320 for (
size_t timeLevel = 0; timeLevel <
m_nTimeLevel; timeLevel++)
324 std::dynamic_pointer_cast<LibUtilities::TimeIntegrationSchemeSDC>(
325 m_EqSys[timeLevel]->GetTimeIntegrationScheme());
329 "Should only be run with a SDC method");
333 for (
size_t i = 0; i <
m_nVar; ++i)
335 fields[i] =
m_EqSys[timeLevel]->UpdatePhysField(i);
342 m_EqSys[timeLevel]->GetTimeIntegrationSchemeOperators());
347 for (
size_t timeLevel = 0; timeLevel <
m_nTimeLevel; timeLevel++)
357 for (
size_t timeLevel = 0; timeLevel <
m_nTimeLevel - 1; timeLevel++)
364 for (
size_t n = 0; n <
m_QuadPts[timeLevel + 1]; ++n)
376 for (
size_t i = 0; i <
m_nVar; ++i)
401 for (
size_t timeLevel = 0; timeLevel <
m_nTimeLevel - 1; timeLevel++)
417 size_t i0 =
m_SDCSolver[timeLevel]->HasFirstQuadrature() ? 0 : 1;
418 size_t j0 =
m_SDCSolver[timeLevel + 1]->HasFirstQuadrature() ? 0 : 1;
421 for (
size_t i = i0; i <
m_QuadPts[timeLevel]; ++i)
423 for (
size_t j = j0; j <
m_QuadPts[timeLevel + 1]; ++j)
426 (ImatFtoC->GetPtr())[(i - i0) *
437 for (
size_t j = j0; j <
m_QuadPts[timeLevel + 1]; ++j)
439 for (
size_t i = i0; i <
m_QuadPts[timeLevel]; ++i)
443 ->GetPtr())[(j - j0) * (
m_QuadPts[timeLevel] - i0) +
466 const size_t timeLevel,
const size_t index)
468 for (
size_t n = 0; n <
m_QuadPts[timeLevel]; ++n)
472 for (
size_t i = 0; i <
m_nVar; ++i)
476 m_SDCSolver[timeLevel]->GetSolutionVector()[index][i], 1,
477 m_SDCSolver[timeLevel]->UpdateSolutionVector()[n][i], 1);
480 m_SDCSolver[timeLevel]->GetResidualVector()[index][i], 1,
481 m_SDCSolver[timeLevel]->UpdateResidualVector()[n][i], 1);
510 for (
size_t k = 0; k < niter; k++)
550 const size_t fineLevel,
SDCarray &out,
554 for (
size_t n = 0; n <
m_QuadPts[coarseLevel]; ++n)
557 m_EqSys[fineLevel]->UpdateFields(), in[n],
562 for (
size_t n = 0; n <
m_QuadPts[fineLevel]; ++n)
566 for (
size_t i = 0; i <
m_nVar; ++i)
569 m_storage[fineLevel][0][i], 1, out[n][i], 1);
570 for (
size_t k = 1; k <
m_QuadPts[coarseLevel]; ++k)
572 size_t index = k *
m_QuadPts[fineLevel] + n;
575 m_storage[fineLevel][k][i], 1, out[n][i], 1,
588 size_t coarseLevel = timeLevel;
589 size_t fineLevel = timeLevel - 1;
592 fineLevel,
m_SDCSolver[fineLevel]->UpdateSolutionVector(),
601 size_t coarseLevel = timeLevel;
602 size_t fineLevel = timeLevel - 1;
605 fineLevel,
m_SDCSolver[fineLevel]->UpdateResidualVector(),
613 const size_t coarseLevel,
SDCarray &out)
616 for (
size_t n = 0; n <
m_QuadPts[coarseLevel]; ++n)
618 for (
size_t i = 0; i <
m_nVar; ++i)
622 for (
size_t k = 1; k <
m_QuadPts[fineLevel]; ++k)
624 size_t index = k *
m_QuadPts[coarseLevel] + n;
626 in[k][i], 1,
m_storage[fineLevel][n][i], 1,
633 for (
size_t n = 0; n <
m_QuadPts[coarseLevel]; ++n)
636 m_EqSys[coarseLevel]->UpdateFields(),
646 size_t fineLevel = timeLevel;
647 size_t coarseLevel = timeLevel + 1;
650 coarseLevel,
m_SDCSolver[coarseLevel]->UpdateSolutionVector());
652 for (
size_t n = 0; n <
m_QuadPts[coarseLevel]; ++n)
664 size_t fineLevel = timeLevel;
665 size_t coarseLevel = timeLevel + 1;
671 for (
size_t n = 0; n <
m_QuadPts[coarseLevel]; ++n)
684 size_t fineLevel = timeLevel - 1;
685 size_t coarseLevel = timeLevel;
692 m_SDCSolver[coarseLevel]->UpdateFAScorrectionVector());
696 m_SDCSolver[fineLevel]->GetIntegratedResidualVector(),
703 fineLevel,
m_SDCSolver[fineLevel]->GetIntegratedResidualVector(),
704 coarseLevel,
m_SDCSolver[coarseLevel]->UpdateFAScorrectionVector());
708 for (
size_t n = 0; n <
m_QuadPts[coarseLevel]; ++n)
710 for (
size_t i = 0; i <
m_nVar; ++i)
716 m_SDCSolver[coarseLevel]->GetFAScorrectionVector()[n][i], 1,
718 m_SDCSolver[coarseLevel]->UpdateFAScorrectionVector()[n][i],
724 m_SDCSolver[coarseLevel]->GetFAScorrectionVector()[n][i], 1,
725 m_SDCSolver[coarseLevel]->GetIntegratedResidualVector()[n][i],
726 1,
m_SDCSolver[coarseLevel]->UpdateFAScorrectionVector()[n][i],
737 const size_t fineLevel,
746 m_EqSys[coarseLevel]->UpdateFields(), out,
748 for (
size_t i = 0; i <
m_nVar; ++i)
757 m_EqSys[fineLevel]->UpdateFields(),
759 for (
size_t i = 0; i <
m_nVar; ++i)
762 out[i], 1, out[i], 1);
772 size_t fineLevel = timeLevel;
773 size_t coarseLevel = timeLevel + 1;
776 fineLevel,
m_SDCSolver[fineLevel]->UpdateSolutionVector()[0],
785 size_t fineLevel = timeLevel;
786 size_t coarseLevel = timeLevel + 1;
789 fineLevel,
m_SDCSolver[fineLevel]->UpdateResidualVector()[0],
797 const SDCarray &in,
const size_t fineLevel,
802 for (
size_t n = 0; n <
m_QuadPts[coarseLevel]; ++n)
806 for (
size_t i = 0; i <
m_nVar; ++i)
814 for (
size_t i = 0; i <
m_nVar; ++i)
823 for (
size_t n = 0; n <
m_QuadPts[coarseLevel]; ++n)
826 m_EqSys[fineLevel]->UpdateFields(),
831 for (
size_t n = 0; n <
m_QuadPts[fineLevel]; ++n)
835 for (
size_t i = 0; i <
m_nVar; ++i)
837 for (
size_t k = 0; k <
m_QuadPts[coarseLevel]; ++k)
839 size_t index = k *
m_QuadPts[fineLevel] + n;
842 m_storage[fineLevel][k][i], 1, out[n][i], 1,
855 size_t coarseLevel = timeLevel + 1;
856 size_t fineLevel = timeLevel;
859 m_SDCSolver[coarseLevel]->GetSolutionVector(), fineLevel,
860 m_SDCSolver[fineLevel]->UpdateSolutionVector(),
false);
868 size_t coarseLevel = timeLevel + 1;
869 size_t fineLevel = timeLevel;
874 for (
size_t n = 1; n <
m_QuadPts[fineLevel]; ++n)
883 m_SDCSolver[coarseLevel]->GetResidualVector(), fineLevel,
884 m_SDCSolver[fineLevel]->UpdateResidualVector(),
false);
897 for (
size_t timeLevel = 0; timeLevel <
m_nTimeLevel - 1; timeLevel++)
900 m_EqSys[timeLevel + 1]->UpdateFields(),
902 m_SDCSolver[timeLevel + 1]->UpdateSolutionVector()[0]);
907 for (
size_t timeLevel = 0; timeLevel <
m_nTimeLevel; timeLevel++)
909 for (
size_t i = 0; i <
m_nVar; ++i)
911 m_comm->GetTimeComm()->Bcast(
912 m_SDCSolver[timeLevel]->UpdateSolutionVector()[0][i],
924 for (
size_t i = 0; i <
m_nVar; ++i)
928 m_SDCSolver[timeLevel]->GetSolutionVector()[0][i], 1,
930 ->GetIntegratedResidualVector()[
m_QuadPts[timeLevel] - 1][i],
932 m_EqSys[timeLevel]->CopyToPhysField(
934 ->GetSolutionVector()[
m_QuadPts[timeLevel] - 1][i]);
945 size_t timeLevel = 0;
947 m_EqSys[timeLevel]->GetSession()->DefinesParameter(
"IO_CheckSteps")
948 ?
m_EqSys[timeLevel]->GetSession()->GetParameter(
"IO_CheckSteps")
950 IOChkStep = IOChkStep ? IOChkStep :
m_nsteps[timeLevel];
951 static std::string dirname =
m_session->GetSessionName() +
".pit";
953 if ((step + 1) % IOChkStep == 0)
956 size_t nchk = (step + 1) / IOChkStep;
959 if (!fs::is_directory(dirname))
961 fs::create_directory(dirname);
967 m_SDCSolver[timeLevel]->UpdateLastQuadratureSolutionVector());
970 std::string filename = dirname +
"/" +
m_session->GetSessionName() +
971 "_" + std::to_string(nchk) +
".fld";
974 m_EqSys[timeLevel]->SetTime(time);
977 m_EqSys[timeLevel]->WriteFld(filename);
#define ASSERTL0(condition, msg)
tKey RegisterCreatorFunction(tKey idKey, CreatorFunction classCreator, std::string pDesc="")
Register a class with the factory.
Defines a specification for a set of points.
static std::string RegisterEnumValue(std::string pEnum, std::string pString, int pEnumValue)
Registers an enumeration value.
LibUtilities::SessionReaderSharedPtr m_session
Session reader object.
LibUtilities::CommSharedPtr m_comm
Communication object.
void RestrictResidual(const size_t timeLevel)
void UpdateFirstQuadrature(const size_t timeLevel)
void InitialiseSDCScheme(void)
void AssertParameters(void)
void RestrictSolution(const size_t timeLevel)
Array< OneD, Array< OneD, NekDouble > > m_ImatFtoC
Array< OneD, Array< OneD, NekDouble > > m_ImatCtoF
void Restrict(const size_t fineLevel, const SDCarray &in, const size_t coarseLevel, SDCarray &out)
void ResidualEval(const NekDouble time, const size_t timeLevel, const size_t n)
static std::string className
Name of the class.
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)
static DriverSharedPtr create(const LibUtilities::SessionReaderSharedPtr &pSession, const SpatialDomains::MeshGraphSharedPtr &pGraph)
Creates an instance of this class.
void Interpolate(const size_t coarseLevel, const SDCarray &in, const size_t fineLevel, SDCarray &out, bool forced)
void ComputeFASCorrection(const size_t timeLevel)
Array< OneD, SDCarray > m_solutionRest
void CorrectInitialResidual(const size_t timeLevel)
SOLVER_UTILS_EXPORT void v_Execute(std::ostream &out=std::cout) override
Virtual function for solve implementation.
void WriteOutput(const size_t step, const NekDouble time)
void CorrectInitialSolution(const size_t timeLevel)
Array< OneD, std::shared_ptr< LibUtilities::TimeIntegrationSchemeSDC > > m_SDCSolver
Array< OneD, SDCarray > m_correction
SOLVER_UTILS_EXPORT void v_InitObject(std::ostream &out=std::cout) override
Virtual function for initialisation implementation.
Array< OneD, SDCarray > m_storage
Array< OneD, SDCarray > m_integralRest
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)
Array< OneD, SDCarray > m_residualRest
void InterpolateSolution(const size_t timeLevel)
void PropagateQuadratureSolutionAndResidual(const size_t timeLevel, const size_t index)
SOLVER_UTILS_EXPORT DriverPFASST(const LibUtilities::SessionReaderSharedPtr pSession, const SpatialDomains::MeshGraphSharedPtr pGraph)
Constructor.
static std::string driverLookupId
void CorrectResidual(const size_t timeLevel)
Array< OneD, size_t > m_QuadPts
bool IsNotInitialCondition(const size_t n)
void ApplyWindowing(void)
void SetTimeInterpolator(void)
Base class for the development of parallel-in-time solvers.
size_t m_numChunks
Number of time chunks.
NekDouble m_totalTime
Total time integration interval.
NekDouble vL2ErrorMax(void)
Array< OneD, NekDouble > m_vL2Errors
Storage for parallel-in-time iteration.
void UpdateFieldCoeffs(const size_t timeLevel, const Array< OneD, const Array< OneD, NekDouble > > &in=NullNekDoubleArrayOfArray)
NekDouble m_chunkTime
Time integration interval per chunk.
void SendToNextProc(Array< OneD, Array< OneD, NekDouble > > &array, int &convergence)
size_t m_nTimeLevel
Number of time levels.
size_t m_iterMaxPIT
Maximum number of parallel-in-time iteration.
void PrintErrorNorm(const size_t timeLevel, const bool normalized)
Array< OneD, size_t > m_nsteps
Number of time steps for each time level.
void InitialiseEqSystem(bool turnoff_output)
SOLVER_UTILS_EXPORT void v_InitObject(std::ostream &out=std::cout) override
Virtual function for initialisation implementation.
Array< OneD, NekDouble > m_vLinfErrors
void EvaluateExactSolution(const size_t timeLevel, const NekDouble &time)
void GetParametersFromSession(void)
void RecvFromPreviousProc(Array< OneD, Array< OneD, NekDouble > > &array, int &convergence)
Array< OneD, std::shared_ptr< UnsteadySystem > > m_EqSys
Equation system to solve.
void PrintHeader(const std::string &title, const char c)
NekDouble m_tolerPIT
ParallelInTime tolerance.
size_t m_chunkRank
Rank in time.
void PrintSolverInfo(std::ostream &out=std::cout)
size_t m_nVar
Number of variables.
Array< OneD, size_t > m_npts
Number of dof for each time level.
Array< OneD, Array< OneD, NekDouble > > m_exactsoln
void SolutionConvergenceSummary(const size_t timeLevel)
NekDouble m_time
Local time.
Array< OneD, NekDouble > m_timestep
Time step for each time level.
void CopySolutionVector(const Array< OneD, const Array< OneD, NekDouble > > &in, Array< OneD, Array< OneD, NekDouble > > &out)
PointsManagerT & PointsManager(void)
std::shared_ptr< SessionReader > SessionReaderSharedPtr
DriverFactory & GetDriverFactory()
Array< OneD, Array< OneD, Array< OneD, NekDouble > > > SDCarray
std::shared_ptr< MeshGraph > MeshGraphSharedPtr
std::vector< double > w(NPUPPER)
std::shared_ptr< DNekMat > DNekMatSharedPtr
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.
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.
void Smul(int n, const T alpha, const T *x, const int incx, T *y, const int incy)
Scalar multiply y = alpha*x.
void Zero(int n, T *x, const int incx)
Zero vector.
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
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.