47 "Parareal", DriverParareal::create);
48 string DriverParareal::driverLookupId =
49 LibUtilities::SessionReader::RegisterEnumValue(
"Driver",
"Parareal", 0);
54 DriverParareal::DriverParareal(
77 "EqType SolverInfo tag must be defined.");
78 std::string vEquation =
m_session->GetSolverInfo(
"EqType");
79 if (
m_session->DefinesSolverInfo(
"SolverType"))
81 vEquation =
m_session->GetSolverInfo(
"SolverType");
87 "EquationSystem '" + vEquation +
89 "Ensure equation name is correct and module is compiled.\n");
109 m_session->SetTag(
"AdvectiveType",
"Convective");
110 m_session->SetTag(
"PararealSolver",
"FineSolver");
125 m_session->SetTag(
"AdvectiveType",
"Linearised");
126 m_session->SetTag(
"PararealSolver",
"FineSolver");
141 m_session->SetTag(
"AdvectiveType",
"Adjoint");
142 m_session->SetTag(
"PararealSolver",
"FineSolver");
157 m_session->SetTag(
"AdvectiveType",
"SkewSymmetric");
158 m_session->SetTag(
"PararealSolver",
"FineSolver");
169 ASSERTL0(
false,
"Unrecognised evolution operator.");
174 ASSERTL0(e == -1,
"No such class class defined.");
175 out <<
"An error occurred during driver initialisation." << endl;
184 string coarseSolverFile;
185 vector<string> coarseSolverFilenames;
186 bool opt = (
m_session->GetFilenames()[0].substr(
187 m_session->GetFilenames()[0].size() - 3) ==
"opt");
188 meshFile =
m_session->GetFilenames()[0 + opt];
189 coarseSolverFile =
m_session->GetFilenames().size() > 1 + opt
192 coarseSolverFile = coarseSolverFile.substr(0, coarseSolverFile.size() - 4);
193 coarseSolverFile +=
"_coarseSolver.xml";
194 std::ifstream f(coarseSolverFile);
199 if (
m_session->GetFilenames().size() > 1 + opt)
201 coarseSolverFilenames.push_back(meshFile);
203 coarseSolverFilenames.push_back(coarseSolverFile);
208 coarseSolverFilenames.push_back(
m_session->GetFilenames()[0 + opt]);
209 if (
m_session->GetFilenames().size() > 1 + opt)
211 coarseSolverFilenames.push_back(
m_session->GetFilenames()[1 + opt]);
216 int npx =
m_session->DefinesCmdLineArgument(
"npx")
217 ?
m_session->GetCmdLineArgument<
int>(
"npx")
219 int npy =
m_session->DefinesCmdLineArgument(
"npy")
220 ?
m_session->GetCmdLineArgument<
int>(
"npy")
222 int npz =
m_session->DefinesCmdLineArgument(
"npz")
223 ?
m_session->GetCmdLineArgument<
int>(
"npz")
225 int nsz =
m_session->DefinesCmdLineArgument(
"nsz")
226 ?
m_session->GetCmdLineArgument<
int>(
"nsz")
228 int npt =
m_session->DefinesCmdLineArgument(
"npt")
229 ?
m_session->GetCmdLineArgument<
int>(
"npt")
233 std::string npx_string = std::to_string(npx);
234 std::string npy_string = std::to_string(npy);
235 std::string npz_string = std::to_string(npz);
236 std::string nsz_string = std::to_string(nsz);
237 std::string npt_string = std::to_string(npt);
239 char *argv[] = {
const_cast<char *
>(
"Solver"),
240 const_cast<char *
>(
"--npx"),
241 const_cast<char *
>(npx_string.c_str()),
242 const_cast<char *
>(
"--npy"),
243 const_cast<char *
>(npy_string.c_str()),
244 const_cast<char *
>(
"--npz"),
245 const_cast<char *
>(npz_string.c_str()),
246 const_cast<char *
>(
"--nsz"),
247 const_cast<char *
>(nsz_string.c_str()),
248 const_cast<char *
>(
"--npt"),
249 const_cast<char *
>(npt_string.c_str()),
254 11, argv, coarseSolverFilenames,
m_session->GetComm());
280 const NekDouble time,
const int nstep,
const int iter,
293 m_equ[1]->SetTime(time);
294 m_equ[1]->SetSteps(nstep);
297 if (
m_equ[0]->GetNpoints() ==
m_equ[1]->GetNpoints())
300 for (
int i = 0; i <
m_equ[1]->GetNvariables(); ++i)
302 m_equ[1]->CopyToPhysField(i, input[i]);
308 for (
int i = 0; i <
m_equ[0]->GetNvariables(); ++i)
310 m_equ[0]->CopyToPhysField(i, input[i]);
313 m_equ[1]->UpdateFields());
320 if (
m_equ[0]->GetNpoints() ==
m_equ[1]->GetNpoints())
323 for (
int i = 0; i <
m_equ[1]->GetNvariables(); ++i)
325 m_equ[1]->CopyFromPhysField(i, output[i]);
332 m_equ[0]->UpdateFields());
333 for (
int i = 0; i <
m_equ[1]->GetNvariables(); ++i)
335 m_equ[0]->CopyFromPhysField(i, output[i]);
341 const NekDouble time,
const int nstep,
const int iter,
361 int nIter =
m_equ[0]->GetPararealIterationNumber();
364 m_equ[0]->SetTime(time);
365 m_equ[0]->SetSteps(nstep);
371 m_equ[0]->SetPararealIterationNumber(++nIter);
374 for (
int i = 0; i <
m_equ[0]->GetNvariables(); ++i)
376 m_equ[0]->CopyToPhysField(i, input[i]);
383 for (
int i = 0; i <
m_equ[0]->GetNvariables(); ++i)
385 m_equ[0]->CopyFromPhysField(i, output[i]);
399 ?
m_session->GetParameter(
"PararealToler")
402 ?
m_session->GetParameter(
"PararealIterMax")
411 ?
m_session->GetParameter(
"ExactSolution")
415 m_equ[1]->SetInfoSteps(0);
416 m_equ[1]->SetCheckpointSteps(0);
421 "Total number of fine step should be divisible by number of chunks.");
425 "Total number of coarse step should be divisible by number of chunks.");
429 "Fine and coarse total computational times do not match");
432 if (
m_session->GetParameter(
"IO_InfoSteps"))
437 "number of IO_InfoSteps should divide number of fine steps "
440 if (
m_session->GetParameter(
"IO_CheckSteps"))
445 "number of IO_CheckSteps should divide number of fine steps "
452 std::cout <<
"========================================================="
456 std::cout <<
"========================= FINE PROPAGATOR INFO "
457 "========================"
460 m_equ[0]->PrintSummary(out);
462 std::cout << std::endl << std::flush;
468 std::cout <<
"========================================================="
472 std::cout <<
"======================== COARSE PROPAGATOR INFO "
473 "======================="
476 m_equ[1]->PrintSummary(out);
482 int nPts =
m_equ[0]->GetNpoints();
483 int nVar =
m_equ[0]->GetNvariables();
489 for (
int i = 0; i < nVar; ++i)
499 m_equ[0]->DoInitialise();
502 m_equ[1]->SetUseInitialCondition(
false);
503 m_equ[1]->DoInitialise();
506 for (
int i = 0; i < nVar; ++i)
508 m_equ[0]->CopyFromPhysField(i, ic[i]);
514 std::cout <<
"** INITIAL CONDITION **" << std::endl << std::flush;
527 int convergenceCurr =
false;
544 std::cout <<
"** ITERATION " << 0 <<
" **" << std::endl << std::flush;
548 ic, solutionCoarsePrev);
550 for (
int i = 0; i < nVar; ++i)
552 for (
int q = 0; q < nPts; ++q)
554 solution[i][q] = solutionCoarsePrev[i][q];
561 for (
int i = 0; i < nVar; ++i)
563 m_equ[0]->EvaluateExactSolution(i, exactsoln[i],
569 CPUtime += timer.
Elapsed().count();
571 m_comm->GetSpaceComm()->GetRank() == 0)
573 std::cout <<
"-------------------------------------------" << std::endl
575 std::cout <<
"Total Computation Time = " << CPUtime <<
"s" << std::endl
577 std::cout <<
"-------------------------------------------" << std::endl
580 for (
int i = 0; i < nVar; ++i)
582 vL2Errors[i] =
m_equ[1]->L2Error(i, exactsoln[i], 1);
583 vLinfErrors[i] =
m_equ[1]->LinfError(i, exactsoln[i]);
585 m_comm->GetSpaceComm()->GetRank() == 0)
587 std::cout <<
"L2 error (variable " <<
m_equ[1]->GetVariable(i)
588 <<
") : " << vL2Errors[i] << std::endl
590 std::cout <<
"Linf error (variable " <<
m_equ[1]->GetVariable(i)
591 <<
") : " << vLinfErrors[i] << std::endl
601 m_comm->GetSpaceComm()->GetRank() == 0)
603 std::cout <<
"** ITERATION " << k + 1 <<
" **" << std::endl
610 for (
int i = 0; i < nVar; ++i)
612 for (
int q = 0; q < nPts; ++q)
614 exactsoln[i][q] = solution[i][q];
631 tComm->Recv(recvProc, convergencePrev);
632 for (
int i = 0; i < nVar; ++i)
634 tComm->Recv(recvProc, ic[i]);
640 k, ic, solutionCoarseCurr);
644 for (
int i = 0; i < nVar; ++i)
646 for (
int q = 0; q < nPts; ++q)
649 solutionCoarseCurr[i][q] - solutionCoarsePrev[i][q];
651 solutionCoarsePrev[i][q] = solutionCoarseCurr[i][q];
657 for (
int i = 0; i < nVar; ++i)
660 m_equ[0]->CopyToPhysField(i, solution[i]);
662 vL2Error = max(vL2Error,
m_equ[0]->L2Error(i, exactsoln[i], 1));
668 convergenceCurr =
true;
676 tComm->Send(sendProc, convergenceCurr);
677 for (
int i = 0; i < nVar; ++i)
679 tComm->Send(sendProc, solution[i]);
686 for (
int i = 0; i < nVar; ++i)
688 m_equ[0]->EvaluateExactSolution(
694 CPUtime += timer.
Elapsed().count();
696 m_comm->GetSpaceComm()->GetRank() == 0)
698 std::cout <<
"-------------------------------------------"
701 std::cout <<
"Total Computation Time = " << CPUtime <<
"s"
704 std::cout <<
"-------------------------------------------"
708 for (
int i = 0; i < nVar; ++i)
710 vL2Errors[i] =
m_equ[0]->L2Error(i, exactsoln[i], 1);
711 vLinfErrors[i] =
m_equ[0]->LinfError(i, exactsoln[i]);
713 m_comm->GetSpaceComm()->GetRank() == 0)
715 std::cout <<
"L2 error (variable " <<
m_equ[0]->GetVariable(i)
716 <<
") : " << vL2Errors[i] << std::endl
718 std::cout <<
"Linf error (variable " <<
m_equ[0]->GetVariable(i)
719 <<
") : " << vLinfErrors[i] << std::endl
733 for (; k < kmax; k++)
735 if (
m_comm->GetSpaceComm()->GetRank() == 0 &&
736 m_session->GetParameter(
"IO_CheckSteps"))
738 std::string olddir =
m_equ[0]->GetSessionName() +
"_" +
739 boost::lexical_cast<std::string>(k) +
".pit";
740 std::string outdir =
m_equ[0]->GetSessionName() +
"_" +
741 boost::lexical_cast<std::string>(k + 1) +
747 for (
int i = 0; i < nChkPts; i++)
750 std::string oldname =
751 olddir +
"/" +
m_equ[0]->GetSessionName() +
"_" +
752 boost::lexical_cast<std::string>(
m_chunkRank * nChkPts + i +
757 std::string outname =
758 outdir +
"/" +
m_equ[0]->GetSessionName() +
"_" +
759 boost::lexical_cast<std::string>(
m_chunkRank * nChkPts + i +
764 fs::remove_all(outname);
773 for (
int i = 0; i < nVar; ++i)
775 m_equ[0]->CopyToPhysField(i, solution[i]);
776 m_equ[0]->UpdateFields()[i]->FwdTransLocalElmt(
777 m_equ[0]->UpdateFields()[i]->GetPhys(),
778 m_equ[0]->UpdateFields()[i]->UpdateCoeffs());
790 if (
m_comm->GetSpaceComm()->GetRank() == 0)
792 std::cout <<
"-------------------------------------------"
795 std::cout <<
"Total Computation Time = " << CPUtime <<
"s"
798 std::cout <<
"-------------------------------------------"
804 for (
int i = 0; i < nVar; ++i)
807 m_equ[0]->CopyToPhysField(i, solution[i]);
816 if (
m_comm->GetSpaceComm()->GetRank() == 0)
818 std::cout <<
"L 2 error (variable " <<
m_equ[0]->GetVariable(i)
819 <<
") : " << vL2Error << std::endl
821 std::cout <<
"L inf error (variable "
822 <<
m_equ[0]->GetVariable(i) <<
") : " << vLinfError
835 m_comm->GetSpaceComm()->GetRank() == 0)
837 std::cout <<
"-------------------------------------------"
840 std::cout <<
"PARAREAL SPEED-UP ANALYSIS" << std::endl
842 std::cout <<
"-------------------------------------------"
850 for (
int n = 0; n < count; n++)
854 for (
int i = 0; i < nVar; ++i)
856 tComm->Recv(recvProc, ic[i]);
862 for (
int i = 0; i < nVar; ++i)
864 tComm->Send(sendProc, solution[i]);
869 commTime = timer.
Elapsed().count() / count;
873 m_comm->GetSpaceComm()->GetRank() == 0)
875 std::cout <<
"-------------------------------------------"
878 std::cout <<
"Mean Communication Time = " << commTime <<
"s"
881 std::cout <<
"-------------------------------------------"
888 if (
m_equ[0]->GetNpoints() !=
m_equ[1]->GetNpoints())
891 for (
int n = 0; n < count; n++)
894 m_equ[1]->UpdateFields());
897 restTime = timer.
Elapsed().count() / count;
901 m_comm->GetSpaceComm()->GetRank() == 0)
903 std::cout <<
"-------------------------------------------"
906 std::cout <<
"Mean Restriction Time = " << restTime <<
"s"
909 std::cout <<
"-------------------------------------------"
917 if (
m_equ[0]->GetNpoints() !=
m_equ[1]->GetNpoints())
920 for (
int n = 0; n < count; n++)
923 m_equ[0]->UpdateFields());
926 interTime = timer.
Elapsed().count() / count;
930 m_comm->GetSpaceComm()->GetRank() == 0)
932 std::cout <<
"-------------------------------------------"
935 std::cout <<
"Mean Interpolation Time = " << interTime <<
"s"
938 std::cout <<
"-------------------------------------------"
947 for (
int n = 0; n < count; n++)
952 coarseSolveTime = 0.01 * timer.
Elapsed().count() / count *
954 restTime - interTime;
958 m_comm->GetSpaceComm()->GetRank() == 0)
960 std::cout <<
"-------------------------------------------"
963 std::cout <<
"Mean Coarse Solve Time = " << coarseSolveTime <<
"s"
966 std::cout <<
"-------------------------------------------"
975 m_equ[0]->SetInfoSteps(0);
976 m_equ[0]->SetCheckpointSteps(0);
977 for (
int n = 0; n < count; n++)
982 fineSolveTime = 0.01 * timer.
Elapsed().count() / count *
987 m_comm->GetSpaceComm()->GetRank() == 0)
989 std::cout <<
"-------------------------------------------"
992 std::cout <<
"Mean Fine Solve Time = " << fineSolveTime <<
"s"
995 std::cout <<
"-------------------------------------------"
1002 m_comm->GetSpaceComm()->GetRank() == 0)
1004 std::cout <<
"-------------------------------------------"
1007 std::cout <<
"Maximum Speed-up" << std::endl << std::flush;
1008 std::cout <<
"-------------------------------------------"
1014 NekDouble ratioSolve = coarseSolveTime / fineSolveTime;
1015 NekDouble speedup = 1.0 / ((1.0 + ratio) * ratioSolve + ratio);
1016 std::cout <<
"Speed-up (" << k <<
") = " << speedup << std::endl
1019 std::cout <<
"-------------------------------------------"
1022 std::cout <<
"Speed-up with comm." << std::endl << std::flush;
1023 std::cout <<
"-------------------------------------------"
1029 NekDouble ratioComm = commTime / fineSolveTime;
1030 NekDouble ratioSolve = coarseSolveTime / fineSolveTime;
1031 NekDouble speedup = 1.0 / ((1.0 + ratio) * ratioSolve + ratio +
1033 std::cout <<
"Speed-up (" << k <<
") = " << speedup << std::endl
1036 std::cout <<
"-------------------------------------------"
1039 std::cout <<
"Speed-up with comm. and interp." << std::endl
1041 std::cout <<
"-------------------------------------------"
1047 NekDouble ratioComm = commTime / fineSolveTime;
1049 (coarseSolveTime + restTime + interTime) / fineSolveTime;
1051 1.0 / ((1.0 + ratio) * ratioSolve + ratio +
1054 std::cout <<
"Speed-up (" << k <<
") = " << speedup << std::endl
1057 std::cout <<
"-------------------------------------------"
#define ASSERTL0(condition, msg)
tKey RegisterCreatorFunction(tKey idKey, CreatorFunction classCreator, std::string pDesc="")
Register a class with the factory.
tBaseSharedPtr CreateInstance(tKey idKey, tParam... args)
Create an instance of the class referred to by idKey.
static SessionReaderSharedPtr CreateInstance(int argc, char *argv[])
Creates an instance of the SessionReader class.
Base class for the development of solvers.
LibUtilities::SessionReaderSharedPtr m_session
Session reader object.
LibUtilities::CommSharedPtr m_comm
Communication object.
SpatialDomains::MeshGraphSharedPtr m_graph
MeshGraph object.
enum EvolutionOperatorType m_EvolutionOperator
Evolution Operator.
Array< OneD, EquationSystemSharedPtr > m_equ
Equation system to solve.
int m_nequ
number of equations
virtual SOLVER_UTILS_EXPORT void v_Execute(std::ostream &out=std::cout) override
Virtual function for solve implementation.
virtual SOLVER_UTILS_EXPORT ~DriverParareal()
Destructor.
NekDouble m_chunkTime
Time for chunks.
int m_pararealIterMax
Maximum number of parareal iteration.
int m_coarseSteps
Number of steps for the coarse solver.
void RunCoarseSolve(const NekDouble time, const int nstep, const int iter, const Array< OneD, const Array< OneD, NekDouble >> &input, Array< OneD, Array< OneD, NekDouble >> &output)
void RunFineSolve(const NekDouble time, const int nstep, const int iter, const Array< OneD, const Array< OneD, NekDouble >> &input, Array< OneD, Array< OneD, NekDouble >> &output)
virtual SOLVER_UTILS_EXPORT void v_InitObject(std::ostream &out=std::cout) override
Second-stage initialisation.
NekDouble m_pararealToler
Parareal tolerance.
NekDouble m_coarseTimeStep
Timestep for coarse solver.
LibUtilities::SessionReaderSharedPtr m_sessionCoarse
Parareal (coarse solver) session reader object.
int m_numChunks
Number of time chunks.
NekDouble m_fineTimeStep
Timestep for fine solver.
NekDouble m_totalTime
Total time integration interval.
FieldUtils::Interpolator< Array< OneD, MultiRegions::ExpListSharedPtr > > m_interp
int m_fineSteps
Number of steps for the fine solver.
SpatialDomains::MeshGraphSharedPtr m_graphCoarse
Parareal (coarse solver) MeshGraph object.
bool m_exactSolution
Using exact solution to compute error norms.
NekDouble m_coarseSolveFactor
Coarse solver time factor.
void SetPararealSessionFile(void)
Set the Parareal (coarse solver) session file.
int m_chunkRank
Rank in time.
static MeshGraphSharedPtr Read(const LibUtilities::SessionReaderSharedPtr pSession, LibUtilities::DomainRangeShPtr rng=LibUtilities::NullDomainRangeShPtr, bool fillGraph=true)
std::shared_ptr< SessionReader > SessionReaderSharedPtr
std::shared_ptr< Comm > CommSharedPtr
Pointer to a Communicator object.
DriverFactory & GetDriverFactory()
EquationSystemFactory & GetEquationSystemFactory()
std::shared_ptr< MeshGraph > MeshGraphSharedPtr
The above copyright notice and this permission notice shall be included.