Nektar++
DriverPFASST.cpp
Go to the documentation of this file.
1///////////////////////////////////////////////////////////////////////////////
2//
3// File DriverPFASST.cpp
4//
5// For more information, please see: http://www.nektar.info
6//
7// The MIT License
8//
9// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
10// Department of Aeronautics, Imperial College London (UK), and Scientific
11// Computing and Imaging Institute, University of Utah (USA).
12//
13// Permission is hereby granted, free of charge, to any person obtaining a
14// copy of this software and associated documentation files (the "Software"),
15// to deal in the Software without restriction, including without limitation
16// the rights to use, copy, modify, merge, publish, distribute, sublicense,
17// and/or sell copies of the Software, and to permit persons to whom the
18// Software is furnished to do so, subject to the following conditions:
19//
20// The above copyright notice and this permission notice shall be included
21// in all copies or substantial portions of the Software.
22//
23// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
24// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29// DEALINGS IN THE SOFTWARE.
30//
31// Description: Driver class for the PFASST solver
32//
33///////////////////////////////////////////////////////////////////////////////
34
35#include <iomanip>
36
40#include <boost/format.hpp>
41
42namespace Nektar
43{
44namespace SolverUtils
45{
46std::string DriverPFASST::className =
50
51/**
52 *
53 */
56 : DriverParallelInTime(pSession, pGraph)
57{
58}
59
60/**
61 *
62 */
63void DriverPFASST::v_InitObject(std::ostream &out)
64{
66}
67
68/**
69 *
70 */
71void DriverPFASST::v_Execute(std::ostream &out)
72{
73 // Set timer.
75 NekDouble CPUtime = 0.0;
76
77 // Set time communication parameters.
78 LibUtilities::CommSharedPtr tComm = m_session->GetComm()->GetTimeComm();
79 m_numChunks = tComm->GetSize();
80 m_chunkRank = tComm->GetRank();
81
82 // Set parameters from session file.
85
86 // Print solver summay.
89
90 // Initialization.
96
97 // Start iteration windows.
98 tComm->Block();
99 size_t chkPts = m_chunkRank;
103 for (size_t w = 0; w < m_numWindowsPIT; w++)
104 {
105 timer.Start();
106 PrintHeaderTitle1((boost::format("WINDOWS #%1%") % (w + 1)).str());
107
108 // Compute initial guess for coarse solver.
113 for (size_t k = 0; k < m_chunkRank; k++)
114 {
120 }
122
123 // Interpolate coarse solution and residual to fine.
126
127 // Start PFASST iteration.
128 size_t k = 0;
129 int convergenceCurr = 0;
130 int convergencePrev = (m_chunkRank == 0);
131 int convergence = convergencePrev;
132 while (k < m_iterMaxPIT && !convergenceCurr)
133 {
134 // The PFASST implementation follow "Bolten, M., Moser, D., & Speck,
135 // R. (2017). A multigrid perspective on the parallel full
136 // approximation scheme in space and time. Numerical Linear Algebra
137 // with Applications, 24(6)".
138
139 if (m_chunkRank == m_numChunks - 1 &&
140 m_comm->GetSpaceComm()->GetRank() == 0)
141 {
142 std::cout << "Iteration " << k + 1 << std::endl << std::flush;
143 }
144
145 // Performe fine sweep (parallel-in-time).
147 RunFineSweep();
148
149 // Compute FAS correction.
156
157 // Perform coarse sweep (serial-in-time).
159 m_coarseSDCSolver->UpdateFirstQuadratureSolutionVector(),
160 convergence);
163 convergenceCurr = (vL2ErrorMax() < m_tolerPIT && convergence);
165 m_coarseSDCSolver->UpdateLastQuadratureSolutionVector(),
166 convergenceCurr);
167
168 // Display L2norm.
169 PrintErrorNorm(true);
170
171 // Correct fine solution and residual.
173 m_fineSDCSolver->UpdateLastQuadratureSolutionVector(),
174 convergenceCurr);
178 m_fineSDCSolver->UpdateFirstQuadratureSolutionVector(),
179 convergencePrev);
181
182 k++;
183 }
184
185 // Apply windowing.
186 if (w < m_numWindowsPIT - 1)
187 {
189 }
190 timer.Stop();
191
192 // Update field and write output.
193 WriteOutput(chkPts);
194 chkPts += m_numChunks;
195 CPUtime += timer.Elapsed().count();
196 }
197
198 // Post-processing.
199 tComm->Block();
200 PrintHeaderTitle1("SUMMARY");
204}
205
206/**
207 *
208 */
210{
211 // Allocate memory.
214 for (size_t i = 0; i < m_nVar; ++i)
215 {
216 buffer1[i] = Array<OneD, NekDouble>(m_coarseNpts, 0.0);
217 buffer2[i] = Array<OneD, NekDouble>(m_coarseNpts, 0.0);
218 }
219 // Estimate coarse communication time.
220 return EstimateCommunicationTime(buffer1, buffer2);
221}
222
223/**
224 *
225 */
227{
228 // Average restriction time over niter iteration.
229 size_t niter = 20;
231 timer.Start();
232 for (size_t n = 0; n < niter; n++)
233 {
240 }
241 timer.Stop();
242 return timer.Elapsed().count() / niter;
243}
244
245/**
246 *
247 */
249{
250 // Average interpolation time over niter iteration.
251 size_t niter = 20;
253 timer.Start();
254 for (size_t n = 0; n < niter; n++)
255 {
259 }
260 timer.Stop();
261 return timer.Elapsed().count() / niter;
262}
263
264/**
265 *
266 */
268{
269 // Estimate coarse solver time.
270 size_t niter = 20;
272 timer.Start();
273 for (int i = 0; i < niter; i++)
274 {
277 }
278 timer.Stop();
279 return timer.Elapsed().count() / niter;
280}
281
282/**
283 *
284 */
286{
287 // Estimate coarse solver time.
288 size_t niter = 20;
290 timer.Start();
291 for (int i = 0; i < niter; i++)
292 {
294 RunFineSweep();
295 }
296 timer.Stop();
297 return timer.Elapsed().count() / niter;
298}
299
300/**
301 *
302 */
304{
305 // Estimate coarse overhead time.
306 size_t niter = 20;
308 timer.Start();
309 for (int i = 0; i < niter; i++)
310 {
314 }
315 timer.Stop();
316 return timer.Elapsed().count() / niter;
317}
318
319/**
320 *
321 */
323{
324 // Estimate overhead time.
325 size_t niter = 20;
327 timer.Start();
328 for (int i = 0; i < niter; i++)
329 {
333 }
334 timer.Stop();
335 return timer.Elapsed().count() / niter;
336}
337
338/**
339 *
340 */
342 const size_t iter, NekDouble fineSolveTime, NekDouble coarseSolveTime,
343 NekDouble restTime, NekDouble interTime, NekDouble commTime,
344 NekDouble predictorTime, NekDouble overheadTime)
345{
346 // The speed-up estimate based on "Emmett, M., & Minion, M. (2012). Toward
347 // an efficient parallel in time method for partial differential equations.
348 // Communications in Applied Mathematics and Computational Science, 7(1),
349 // 105-132" and on "Lunet, T., Bodart, J., Gratton, S., &
350 // Vasseur, X. (2018). Time-parallel simulation of the decay of homogeneous
351 // turbulence using parareal with spatial coarsening. Computing and
352 // Visualization in Science, 19, 31-44".
353
354 size_t Kiter = m_fineSDCSolver->GetMaxOrder();
355 size_t nComm = (iter * (2 * m_numChunks - iter - 1)) / 2;
356 NekDouble ratio = double(iter) / m_numChunks;
357 NekDouble ratioPredictor = predictorTime / fineSolveTime;
358 NekDouble ratioSolve = coarseSolveTime / fineSolveTime;
359 NekDouble ratioFAS = (restTime + interTime) / fineSolveTime;
360 NekDouble ratioComm = commTime / fineSolveTime;
361 NekDouble ratioOverhead = overheadTime / fineSolveTime;
362
363 // Speed-up relative to SDC.
364 return Kiter / (ratioPredictor + ratio * (1.0 + ratioSolve + ratioFAS) +
365 (ratioComm * nComm + ratioOverhead) / m_numChunks);
366 // Speed-up relative to MLSDC.
367 /*return Kiter * (1.0 + ratioSolve + ratioFAS + ratioOverhead / m_numChunks)
368 / (ratioPredictor + ratio * (1.0 + ratioSolve + ratioFAS) +
369 (ratioComm * nComm + ratioOverhead) / m_numChunks);*/
370}
371
372/**
373 *
374 */
376{
377 // Assert time-stepping parameters.
378 ASSERTL0(
380 "Total number of fine step should be divisible by number of chunks.");
381
382 ASSERTL0(
384 "Total number of coarse step should be divisible by number of chunks.");
385
387 "Please use same timestep for both coarse and fine solver");
388
390 "Please use same timestep for both coarse and fine solver");
391
392 // Assert I/O parameters.
393 if (m_checkSteps)
394 {
396 "number of IO_CheckSteps should divide number of fine steps "
397 "per time chunk");
398 }
399
400 if (m_infoSteps)
401 {
403 "number of IO_InfoSteps should divide number of fine steps "
404 "per time chunk");
405 }
406}
407
408/**
409 *
410 */
412{
413 // Cast pointer for TimeIntegrationSchemeSDC.
415 std::dynamic_pointer_cast<LibUtilities::TimeIntegrationSchemeSDC>(
416 m_fineEqSys->GetTimeIntegrationScheme());
418 std::dynamic_pointer_cast<LibUtilities::TimeIntegrationSchemeSDC>(
419 m_coarseEqSys->GetTimeIntegrationScheme());
420
421 // Assert if a SDC time-integration is used.
422 ASSERTL0(m_fineSDCSolver != nullptr,
423 "Should only be run with a SDC method");
424
425 ASSERTL0(m_coarseSDCSolver != nullptr,
426 "Should only be run with a SDC method");
427
428 // Initialize fine SDC scheme.
430 m_fineSDCSolver->SetPFASST(pfasst);
431 m_fineSDCSolver->InitializeScheme(
433 m_fineEqSys->GetTimeIntegrationSchemeOperators());
434
435 // Initialize coarse SDC scheme.
437 m_coarseSDCSolver->SetPFASST(pfasst);
438 m_coarseSDCSolver->InitializeScheme(
440 m_coarseEqSys->GetTimeIntegrationSchemeOperators());
441
442 // Set some member variables.
443 m_fineQuadPts = m_fineSDCSolver->GetQuadPtsNumber();
444 m_coarseQuadPts = m_coarseSDCSolver->GetQuadPtsNumber();
445
446 // Alocate memory.
455 for (size_t n = 0; n < m_coarseQuadPts; ++n)
456 {
461 for (size_t i = 0; i < m_nVar; ++i)
462 {
467 }
468 }
469}
470
471/**
472 *
473 */
475{
476 // Initialize time interpolator.
477 LibUtilities::PointsKey fpoints = m_fineSDCSolver->GetPointsKey();
478 LibUtilities::PointsKey cpoints = m_coarseSDCSolver->GetPointsKey();
479 DNekMatSharedPtr ImatFtoC =
480 LibUtilities::PointsManager()[fpoints]->GetI(cpoints);
481 DNekMatSharedPtr ImatCtoF =
482 LibUtilities::PointsManager()[cpoints]->GetI(fpoints);
485
486 // Determine if Radau quadrature are used.
487 int i0 = m_fineSDCSolver->HasFirstQuadrature() ? 0 : 1;
488 int j0 = m_coarseSDCSolver->HasFirstQuadrature() ? 0 : 1;
489
490 // Adapt fine to coarse time interpolator.
491 for (size_t i = i0; i < m_fineQuadPts; ++i)
492 {
493 for (size_t j = j0; j < m_coarseQuadPts; ++j)
494 {
495 m_ImatFtoC[i * m_coarseQuadPts + j] =
496 (ImatFtoC
497 ->GetPtr())[(i - i0) * (m_coarseQuadPts - j0) + (j - j0)];
498 }
499 }
500 if (j0 == 1)
501 {
502 m_ImatFtoC[0] = 1.0;
503 }
504
505 // Adapt coarse to fine time interpolator.
506 for (size_t j = j0; j < m_coarseQuadPts; ++j)
507 {
508 for (size_t i = i0; i < m_fineQuadPts; ++i)
509 {
510 m_ImatCtoF[j * m_fineQuadPts + i] =
511 (ImatCtoF
512 ->GetPtr())[(j - j0) * (m_fineQuadPts - i0) + (i - i0)];
513 }
514 }
515 if (i0 == 1)
516 {
517 m_ImatCtoF[0] = 1.0;
518 }
519}
520
521/**
522 *
523 */
525{
526 return !(n == 0 && m_chunkRank == 0);
527}
528
529/**
530 *
531 */
533{
534 m_coarseEqSys->SetTime(time);
535 m_coarseSDCSolver->SetTime(time);
536 m_fineEqSys->SetTime(time);
537 m_fineSDCSolver->SetTime(time);
538}
539
540/**
541 *
542 */
544 std::shared_ptr<LibUtilities::TimeIntegrationSchemeSDC> SDCsolver,
545 const int index)
546{
547 int nQuad = SDCsolver->GetQuadPtsNumber();
548 int nVar = SDCsolver->GetNvars();
549
550 for (int n = 0; n < nQuad; ++n)
551 {
552 if (n != index)
553 {
554 for (int i = 0; i < nVar; ++i)
555 {
556 Vmath::Vcopy(SDCsolver->GetNpoints(),
557 SDCsolver->GetSolutionVector()[index][i], 1,
558 SDCsolver->UpdateSolutionVector()[n][i], 1);
559 Vmath::Vcopy(SDCsolver->GetNpoints(),
560 SDCsolver->GetResidualVector()[index][i], 1,
561 SDCsolver->UpdateResidualVector()[n][i], 1);
562 }
563 }
564 }
565}
566
567/**
568 *
569 */
571{
572 m_coarseSDCSolver->UpdateFirstQuadrature();
573}
574
575/**
576 *
577 */
579{
580 m_fineSDCSolver->UpdateFirstQuadrature();
581}
582
583/**
584 *
585 */
587{
588 m_coarseSDCSolver->ComputeInitialGuess(m_chunkTime);
589 m_coarseSDCSolver->UpdateLastQuadrature();
590}
591
592/**
593 *
594 */
596{
597 m_fineSDCSolver->ComputeInitialGuess(m_chunkTime);
598 m_fineSDCSolver->UpdateLastQuadrature();
599}
600
601/**
602 *
603 */
605{
606 // Start SDC iteration loop.
607 for (size_t k = 0; k < m_coarseSDCSolver->GetOrder(); k++)
608 {
609 m_coarseSDCSolver->SDCIterationLoop(m_chunkTime);
610 }
611
612 // Update last quadrature point.
613 m_coarseSDCSolver->UpdateLastQuadrature();
614}
615
616/**
617 *
618 */
620{
621 // Start SDC iteration loop.
622 for (size_t k = 0; k < m_fineSDCSolver->GetOrder(); k++)
623 {
624 m_fineSDCSolver->SDCIterationLoop(m_chunkTime);
625 }
626
627 // Update last quadrature point.
628 m_fineSDCSolver->UpdateLastQuadrature();
629}
630
631/**
632 *
633 */
635{
636 m_coarseSDCSolver->ResidualEval(m_chunkTime, n);
637}
638
639/**
640 *
641 */
643{
644 m_coarseSDCSolver->ResidualEval(m_chunkTime);
645}
646
647/**
648 *
649 */
651{
652 m_fineSDCSolver->ResidualEval(m_chunkTime, n);
653}
654
655/**
656 *
657 */
659{
660 m_fineSDCSolver->ResidualEval(m_chunkTime);
661}
662
663/**
664 *
665 */
667{
668 m_coarseSDCSolver->UpdateIntegratedResidualQFint(m_chunkTime);
669}
670
671/**
672 *
673 */
675{
676 m_fineSDCSolver->UpdateIntegratedResidualQFint(m_chunkTime);
677}
678
679/**
680 *
681 */
683 const Array<OneD, Array<OneD, Array<OneD, NekDouble>>> &coarse,
684 Array<OneD, Array<OneD, Array<OneD, NekDouble>>> &fine, bool forced)
685{
686
687 // Interpolate coarse solution in space.
688 for (size_t n = 0; n < m_coarseQuadPts; ++n)
689 {
690 Interpolator(coarse[n], m_tmpfine_arr[n]);
691 }
692
693 // Interpolate coarse solution in time.
694 for (size_t n = 0; n < m_fineQuadPts; ++n)
695 {
696 if (forced || IsNotInitialCondition(n))
697 {
698 for (size_t i = 0; i < m_nVar; ++i)
699 {
700 Vmath::Zero(m_fineNpts, fine[n][i], 1);
701 for (size_t k = 0; k < m_coarseQuadPts; ++k)
702 {
703 size_t index = k * m_fineQuadPts + n;
705 m_tmpfine_arr[k][i], 1, fine[n][i], 1,
706 fine[n][i], 1);
707 }
708 }
709 }
710 }
711}
712
713/**
714 *
715 */
717{
718 Interpolate(m_coarseSDCSolver->GetSolutionVector(),
719 m_fineSDCSolver->UpdateSolutionVector(), false);
720}
721
722/**
723 *
724 */
726{
727 Interpolate(m_coarseSDCSolver->GetResidualVector(),
728 m_fineSDCSolver->UpdateResidualVector(), true);
729}
730
731/**
732 *
733 */
737{
738 // Restrict fine solution in time.
739 for (size_t n = 0; n < m_coarseQuadPts; ++n)
740 {
741 for (size_t i = 0; i < m_nVar; ++i)
742 {
744 for (size_t k = 0; k < m_fineQuadPts; ++k)
745 {
746 size_t index = k * m_coarseQuadPts + n;
747 Vmath::Svtvp(m_fineNpts, m_ImatFtoC[index], fine[k][i], 1,
748 m_tmpfine_arr[n][i], 1, m_tmpfine_arr[n][i], 1);
749 }
750 }
751 }
752
753 // Restrict fine solution in space.
754 for (size_t n = 0; n < m_coarseQuadPts; ++n)
755 {
756 Interpolator(m_tmpfine_arr[n], coarse[n]);
757 }
758}
759
760/**
761 *
762 */
764{
765 Restrict(m_fineSDCSolver->GetSolutionVector(),
766 m_coarseSDCSolver->UpdateSolutionVector());
767}
768
769/**
770 *
771 */
773{
775}
776
777/**
778 *
779 */
781{
782 for (size_t n = 0; n < m_coarseQuadPts; ++n)
783 {
784 CopySolutionVector(m_coarseSDCSolver->GetSolutionVector()[n],
785 m_solutionRest[n]);
786 }
787}
788
789/**
790 *
791 */
793{
795 {
796 for (size_t n = 0; n < m_coarseQuadPts; ++n)
797 {
798 CopySolutionVector(m_coarseSDCSolver->GetResidualVector()[n],
799 m_residualRest[n]);
800 }
801 }
802}
803
804/**
805 *
806 */
808{
809 // Compute fine integrated residual.
811
812 // Compute coarse integrated residual.
814
815 // Restrict fine integratued residual.
816 Restrict(m_fineSDCSolver->GetIntegratedResidualQFintVector(),
817 m_coarseSDCSolver->UpdateFAScorrectionVector());
818
819 // Compute coarse FAS correction terms.
820 for (size_t n = 0; n < m_coarseQuadPts; ++n)
821 {
822 for (size_t i = 0; i < m_nVar; ++i)
823 {
825 m_coarseNpts, m_coarseSDCSolver->GetFAScorrectionVector()[n][i],
826 1, m_coarseSDCSolver->GetIntegratedResidualQFintVector()[n][i],
827 1, m_coarseSDCSolver->UpdateFAScorrectionVector()[n][i], 1);
828 }
829 }
830}
831
832/**
833 *
834 */
837 bool forced)
838{
839 if (forced || IsNotInitialCondition(0))
840 {
841 // Compute difference between coarse solution and restricted
842 // solution.
844 for (size_t i = 0; i < m_nVar; ++i)
845 {
846 Vmath::Vsub(m_coarseNpts, coarse[i], 1, m_tmpcoarse[i], 1,
847 m_tmpcoarse[i], 1);
848 }
849
850 // Add correction to fine solution.
852 for (size_t i = 0; i < m_nVar; ++i)
853 {
854 Vmath::Vadd(m_fineNpts, m_tmpfine[i], 1, fine[i], 1, fine[i], 1);
855 }
856 }
857}
858
859/**
860 *
861 */
863{
864 Correct(m_coarseSDCSolver->GetSolutionVector()[0],
865 m_fineSDCSolver->UpdateSolutionVector()[0], false);
866}
867
868/**
869 *
870 */
872{
873 Correct(m_coarseSDCSolver->GetResidualVector()[0],
874 m_fineSDCSolver->UpdateResidualVector()[0], false);
875}
876
877/**
878 *
879 */
882 const Array<OneD, Array<OneD, Array<OneD, NekDouble>>> &coarse,
883 Array<OneD, Array<OneD, Array<OneD, NekDouble>>> &fine, bool forced)
884{
885 // Compute difference between coarse solution and restricted
886 // solution.
887 for (size_t n = 0; n < m_coarseQuadPts; ++n)
888 {
889 if (forced || IsNotInitialCondition(n))
890 {
891 for (size_t i = 0; i < m_nVar; ++i)
892 {
893 Vmath::Vsub(m_coarseNpts, coarse[n][i], 1, rest[n][i], 1,
894 m_tmpcoarse_arr[n][i], 1);
895 }
896 }
897 else
898 {
899 for (size_t i = 0; i < m_nVar; ++i)
900 {
902 }
903 }
904 }
905
906 // Interpolate coarse solution delta in space.
907 for (size_t n = 0; n < m_coarseQuadPts; ++n)
908 {
910 }
911
912 // Interpolate coarse solution delta in time and correct fine solution.
913 for (size_t n = 0; n < m_fineQuadPts; ++n)
914 {
915 if (forced || IsNotInitialCondition(n))
916 {
917 for (size_t i = 0; i < m_nVar; ++i)
918 {
919 for (size_t k = 0; k < m_coarseQuadPts; ++k)
920 {
921 size_t index = k * m_fineQuadPts + n;
923 m_tmpfine_arr[k][i], 1, fine[n][i], 1,
924 fine[n][i], 1);
925 }
926 }
927 }
928 }
929}
930
931/**
932 *
933 */
935{
936 Correct(m_solutionRest, m_coarseSDCSolver->GetSolutionVector(),
937 m_fineSDCSolver->UpdateSolutionVector(), false);
938}
939
940/**
941 *
942 */
944{
945 // Evaluate fine residual.
947 {
948 for (size_t n = 1; n < m_fineQuadPts; ++n)
949 {
951 }
952 }
953 // Correct fine residual.
954 else
955 {
956 Correct(m_residualRest, m_coarseSDCSolver->GetResidualVector(),
957 m_fineSDCSolver->UpdateResidualVector(), false);
958 }
959}
960
961/**
962 *
963 */
965{
966 LibUtilities::CommSharedPtr tComm = m_session->GetComm()->GetTimeComm();
967
968 // Use last chunk solution as initial condition for the next window.
969 if (m_chunkRank == m_numChunks - 1)
970 {
972 Interpolator(m_fineSDCSolver->GetSolutionVector()[0],
973 m_coarseSDCSolver->UpdateSolutionVector()[0]);
974 }
975
976 // Broadcast I.C. for windowing.
977 for (size_t i = 0; i < m_nVar; ++i)
978 {
979 tComm->Bcast(m_coarseSDCSolver->UpdateSolutionVector()[0][i],
980 m_numChunks - 1);
981 tComm->Bcast(m_fineSDCSolver->UpdateSolutionVector()[0][i],
982 m_numChunks - 1);
983 }
984}
985
986/**
987 *
988 */
990{
991 // Update integrated residual
993
994 // Compute SDC residual norm
995 for (size_t i = 0; i < m_nVar; ++i)
996 {
998 m_fineNpts, m_fineSDCSolver->GetSolutionVector()[0][i], 1,
1000 ->GetIntegratedResidualQFintVector()[m_fineQuadPts - 1][i],
1001 1, m_exactsoln[i], 1);
1002 m_fineEqSys->CopyToPhysField(
1003 i, m_fineSDCSolver->GetSolutionVector()[m_fineQuadPts - 1][i]);
1004 m_vL2Errors[i] = m_fineEqSys->L2Error(i, m_exactsoln[i], 1);
1005 m_vLinfErrors[i] = m_fineEqSys->LinfError(i, m_exactsoln[i]);
1006 }
1007}
1008
1009/**
1010 *
1011 */
1012void DriverPFASST::WriteOutput(size_t chkPts)
1013{
1014 static size_t IOChkStep = m_checkSteps ? m_checkSteps : m_fineSteps;
1015 static std::string newdir = m_session->GetSessionName() + ".pit";
1016
1017 if ((chkPts + 1) % IOChkStep == 0)
1018 {
1019 size_t index = (chkPts + 1) / IOChkStep;
1020 std::string filename = newdir + "/" + m_session->GetSessionName();
1021
1022 if (!fs::is_directory(newdir))
1023 {
1024 fs::create_directory(newdir);
1025 }
1026
1027 UpdateSolution(m_fineSDCSolver->UpdateLastQuadratureSolutionVector());
1028 m_fineEqSys->WriteFld(filename + "_" +
1029 boost::lexical_cast<std::string>(index) + ".fld");
1030 }
1031}
1032
1033} // namespace SolverUtils
1034} // namespace Nektar
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:215
tKey RegisterCreatorFunction(tKey idKey, CreatorFunction classCreator, std::string pDesc="")
Register a class with the factory.
Definition: NekFactory.hpp:198
Defines a specification for a set of points.
Definition: Points.h:55
static std::string RegisterEnumValue(std::string pEnum, std::string pString, int pEnumValue)
Registers an enumeration value.
LibUtilities::SessionReaderSharedPtr m_session
Session reader object.
Definition: Driver.h:85
LibUtilities::CommSharedPtr m_comm
Communication object.
Definition: Driver.h:82
Array< OneD, Array< OneD, Array< OneD, NekDouble > > > m_solutionRest
Definition: DriverPFASST.h:190
std::shared_ptr< LibUtilities::TimeIntegrationSchemeSDC > m_coarseSDCSolver
Definition: DriverPFASST.h:195
virtual NekDouble v_EstimateFineSolverTime(void) override
static std::string className
Name of the class.
Definition: DriverPFASST.h:65
virtual NekDouble v_ComputeSpeedUp(const size_t iter, NekDouble fineSolveTime, NekDouble coarseSolveTime, NekDouble restTime, NekDouble interTime, NekDouble commTime, NekDouble predictorOverheadTime, NekDouble overheadTime) override
virtual NekDouble v_EstimateRestrictionTime(void) override
Array< OneD, Array< OneD, Array< OneD, NekDouble > > > m_residualRest
Definition: DriverPFASST.h:191
static DriverSharedPtr create(const LibUtilities::SessionReaderSharedPtr &pSession, const SpatialDomains::MeshGraphSharedPtr &pGraph)
Creates an instance of this class.
Definition: DriverPFASST.h:54
void Correct(const Array< OneD, Array< OneD, NekDouble > > &coarse, Array< OneD, Array< OneD, NekDouble > > &fine, bool forced)
Array< OneD, Array< OneD, Array< OneD, NekDouble > > > m_tmpcoarse_arr
Definition: DriverPFASST.h:193
void SetTime(const NekDouble &time)
Array< OneD, NekDouble > m_ImatFtoC
Definition: DriverPFASST.h:188
virtual NekDouble v_EstimatePredictorTime(void) override
void Interpolate(const Array< OneD, Array< OneD, Array< OneD, NekDouble > > > &coarse, Array< OneD, Array< OneD, Array< OneD, NekDouble > > > &fine, bool forced)
virtual SOLVER_UTILS_EXPORT void v_Execute(std::ostream &out=std::cout) override
Virtual function for solve implementation.
virtual SOLVER_UTILS_EXPORT void v_InitObject(std::ostream &out=std::cout) override
Virtual function for initialisation implementation.
Array< OneD, NekDouble > m_ImatCtoF
Definition: DriverPFASST.h:189
void CopyQuadratureSolutionAndResidual(std::shared_ptr< LibUtilities::TimeIntegrationSchemeSDC > SDCsolver, const int index)
virtual NekDouble v_EstimateCommunicationTime(void) override
virtual NekDouble v_EstimateCoarseSolverTime(void) override
virtual NekDouble v_EstimateInterpolationTime(void) override
virtual NekDouble v_EstimateOverheadTime(void) override
Array< OneD, Array< OneD, Array< OneD, NekDouble > > > m_tmpfine_arr
Definition: DriverPFASST.h:192
SOLVER_UTILS_EXPORT DriverPFASST(const LibUtilities::SessionReaderSharedPtr pSession, const SpatialDomains::MeshGraphSharedPtr pGraph)
Constructor.
void Restrict(const Array< OneD, Array< OneD, Array< OneD, NekDouble > > > &fine, Array< OneD, Array< OneD, Array< OneD, NekDouble > > > &coarse)
static std::string driverLookupId
Definition: DriverPFASST.h:103
bool IsNotInitialCondition(const size_t n)
std::shared_ptr< LibUtilities::TimeIntegrationSchemeSDC > m_fineSDCSolver
Definition: DriverPFASST.h:194
Base class for the development of parallel-in-time solvers.
NekDouble m_totalTime
Total time integration interval.
size_t m_coarseSteps
Number of steps for the coarse solver.
void SendSolutionToNextProc(Array< OneD, Array< OneD, NekDouble > > &array, int &convergence)
size_t m_iterMaxPIT
Maximum number of parallel-in-time iteration.
size_t m_fineSteps
Number of steps for the fine solver.
NekDouble m_coarseTimeStep
Timestep for coarse solver.
void RecvInitialConditionFromPreviousProc(Array< OneD, Array< OneD, NekDouble > > &array, int &convergence)
void CopyFromFinePhysField(Array< OneD, Array< OneD, NekDouble > > &out)
Array< OneD, Array< OneD, NekDouble > > m_tmpfine
void Interpolator(const Array< OneD, const Array< OneD, NekDouble > > &inarray, Array< OneD, Array< OneD, NekDouble > > &outarray)
std::shared_ptr< SolverUtils::UnsteadySystem > m_coarseEqSys
virtual SOLVER_UTILS_EXPORT void v_InitObject(std::ostream &out=std::cout) override
Virtual function for initialisation implementation.
void PrintHeaderTitle1(const std::string &title)
NekDouble m_tolerPIT
ParallelInTime tolerance.
void PrintCoarseSolverInfo(std::ostream &out=std::cout)
NekDouble m_fineTimeStep
Timestep for fine solver.
void PrintFineSolverInfo(std::ostream &out=std::cout)
size_t m_checkSteps
Number of steps for checkpoint.
Array< OneD, Array< OneD, NekDouble > > m_tmpcoarse
std::shared_ptr< SolverUtils::UnsteadySystem > m_fineEqSys
Array< OneD, Array< OneD, NekDouble > > m_exactsoln
NekDouble EstimateCommunicationTime(Array< OneD, Array< OneD, NekDouble > > &buffer1, Array< OneD, Array< OneD, NekDouble > > &buffer2)
void SolutionConvergenceSummary(const NekDouble &time)
void CopyFromCoarsePhysField(Array< OneD, Array< OneD, NekDouble > > &out)
void UpdateSolution(const Array< OneD, const Array< OneD, NekDouble > > &in)
void CopySolutionVector(const Array< OneD, const Array< OneD, NekDouble > > &in, Array< OneD, Array< OneD, NekDouble > > &out)
size_t m_infoSteps
Number of steps for info I/O.
PointsManagerT & PointsManager(void)
std::shared_ptr< SessionReader > SessionReaderSharedPtr
std::shared_ptr< Comm > CommSharedPtr
Pointer to a Communicator object.
Definition: Comm.h:57
DriverFactory & GetDriverFactory()
Definition: Driver.cpp:67
std::shared_ptr< MeshGraph > MeshGraphSharedPtr
Definition: MeshGraph.h:176
std::vector< double > w(NPUPPER)
The above copyright notice and this permission notice shall be included.
Definition: CoupledSolver.h:2
std::shared_ptr< DNekMat > DNekMatSharedPtr
Definition: NekTypeDefs.hpp:75
double NekDouble
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.cpp:617
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.cpp:354
void Zero(int n, T *x, const int incx)
Zero vector.
Definition: Vmath.cpp:487
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
Definition: Vmath.cpp:1191
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.cpp:414