Nektar++
Loading...
Searching...
No Matches
DriverParallelInTime.cpp
Go to the documentation of this file.
1///////////////////////////////////////////////////////////////////////////////
2//
3// File DriverParallelInTime.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 parallel-in-time solver
32//
33///////////////////////////////////////////////////////////////////////////////
34
35#include <iomanip>
36
38#include <LocalRegions/HexExp.h>
40#include <LocalRegions/PyrExp.h>
42#include <LocalRegions/SegExp.h>
43#include <LocalRegions/TetExp.h>
44#include <LocalRegions/TriExp.h>
47#include <boost/format.hpp>
48
49namespace Nektar::SolverUtils
50{
51
52/**
53 *
54 */
61
62/**
63 *
64 */
66{
67 try
68 {
69 // Retrieve the type of evolution operator to use
71 m_session->GetSolverInfoAsEnum<EvolutionOperatorType>(
72 "EvolutionOperator");
73
74 m_nTimeLevel = 2; // Only two time levels currently implemented.
75
77
78 // Set the AdvectiveType tag and create EquationSystem objects.
79 switch (m_EvolutionOperator)
80 {
81 case eNonlinear:
83 break;
84 case eDirect:
86 break;
87 case eAdjoint:
89 break;
90 case eSkewSymmetric:
91 SetParallelInTimeEquationSystem("SkewSymmetric");
92 break;
93 default:
94 ASSERTL0(false, "Unrecognised evolution operator.");
95 }
96
97 // Set pointers.
99 for (size_t timeLevel = 0; timeLevel < m_nTimeLevel; timeLevel++)
100 {
101 m_EqSys[timeLevel] =
102 std::dynamic_pointer_cast<SolverUtils::UnsteadySystem>(
103 m_equ[timeLevel]);
104 }
105
106 // Set time communication parameters.
107 m_numChunks = m_comm->GetTimeComm()->GetSize();
108 m_chunkRank = m_comm->GetTimeComm()->GetRank();
109 }
110 catch (int e)
111 {
112 ASSERTL0(e == -1, "No such class class defined.");
113 out << "An error occurred during driver initialisation." << std::endl;
114 }
115}
117/**
118 *
119 */
120void DriverParallelInTime::v_Execute([[maybe_unused]] std::ostream &out)
121{
122}
123
124/**
125 * Set the ParallelInTime (coarse solver) session file
126 */
128 std::string AdvectiveType)
129{
130 // Retrieve the equation system to solve.
131 ASSERTL0(m_session->DefinesSolverInfo("EqType"),
132 "EqType SolverInfo tag must be defined.");
133 std::string vEquation = m_session->DefinesSolverInfo("SolverType")
134 ? m_session->GetSolverInfo("SolverType")
135 : m_session->GetSolverInfo("EqType");
136
137 // Check such a module exists for this equation.
138 ASSERTL0(GetEquationSystemFactory().ModuleExists(vEquation),
139 "EquationSystem '" + vEquation +
140 "' is not defined.\n"
141 "Ensure equation name is correct and module is compiled.\n");
142
143 // Set fine parallel-in-time solver.
144 ASSERTL0(m_session->DefinesCmdLineArgument("npt"),
145 "Number of parallel-in-time processes npt must be specified.");
146 m_session->SetTag("AdvectiveType", AdvectiveType);
147 m_session->SetTag("ParallelInTimeSolver", "TimeLevel0");
149 m_graph);
150
151 // Define argument for the coarse parallel-in-time solver.
152 int npx = m_session->DefinesCmdLineArgument("npx")
153 ? m_session->GetCmdLineArgument<int>("npx")
154 : 1;
155 int npy = m_session->DefinesCmdLineArgument("npy")
156 ? m_session->GetCmdLineArgument<int>("npy")
157 : 1;
158 int npz = m_session->DefinesCmdLineArgument("npz")
159 ? m_session->GetCmdLineArgument<int>("npz")
160 : 1;
161 int nsz = m_session->DefinesCmdLineArgument("nsz")
162 ? m_session->GetCmdLineArgument<int>("nsz")
163 : 1;
164 int npt = m_session->GetCmdLineArgument<int>("npt");
165
166 // Convert into string.
167 std::string npx_string = std::to_string(npx);
168 std::string npy_string = std::to_string(npy);
169 std::string npz_string = std::to_string(npz);
170 std::string nsz_string = std::to_string(nsz);
171 std::string npt_string = std::to_string(npt);
172 std::string driver_string = "Driver=" + m_session->GetSolverInfo("Driver");
173
174 // use-opt-file
175 bool useOptFile = m_session->DefinesCmdLineArgument("use-opt-file");
176 std::string optfilename = useOptFile ? m_session->GetFilenames()[0] : "";
177
178 char *argv[] = {const_cast<char *>("Solver"), // this is just a place holder
179 const_cast<char *>("--solverinfo"),
180 const_cast<char *>(driver_string.c_str()),
181 const_cast<char *>("--npx"),
182 const_cast<char *>(npx_string.c_str()),
183 const_cast<char *>("--npy"),
184 const_cast<char *>(npy_string.c_str()),
185 const_cast<char *>("--npz"),
186 const_cast<char *>(npz_string.c_str()),
187 const_cast<char *>("--nsz"),
188 const_cast<char *>(nsz_string.c_str()),
189 const_cast<char *>("--npt"),
190 const_cast<char *>(npt_string.c_str()),
191 const_cast<char *>("-f"),
192 const_cast<char *>("--use-opt-file"),
193 const_cast<char *>(optfilename.c_str()),
194 nullptr};
195
196 size_t argc = useOptFile ? 16 : 14;
197
198 // Get list of session file names.
199 std::vector<std::string> sessionFileNames;
200 for (auto &filename : m_session->GetFilenames())
201 {
202 // Remove optfile name, if necessary.
203 if (filename.substr(filename.find_last_of(".") + 1) != "opt")
204 {
205 sessionFileNames.push_back(filename);
206 }
207 }
208
209 // Set session for coarse solver.
210 for (size_t timeLevel = 1; timeLevel < m_nTimeLevel; timeLevel++)
211 {
213 argc, argv, sessionFileNames, m_session->GetComm(), timeLevel);
214
215 // Set graph for coarse solver.
218
219 // Set BndRegionOrdering (necessary for DG with periodic BC) FIXME
220 graph->SetBndRegionOrdering(m_graph->GetBndRegionOrdering());
221
222 // Set CompositeOrdering (necessary for DG with periodic BC) FIXME
223 graph->SetCompositeOrdering(m_graph->GetCompositeOrdering());
224
225 // Retrieve the equation system to solve.
226 ASSERTL0(session->DefinesSolverInfo("EqType"),
227 "EqType SolverInfo tag must be defined.");
228 auto vEquation = session->DefinesSolverInfo("SolverType")
229 ? session->GetSolverInfo("SolverType")
230 : session->GetSolverInfo("EqType");
231
232 // Check such a module exists for this equation.
233 ASSERTL0(
234 GetEquationSystemFactory().ModuleExists(vEquation),
235 "EquationSystem '" + vEquation +
236 "' is not defined.\n"
237 "Ensure equation name is correct and module is compiled.\n");
238
239 // Set coarse parallel-in-time solver.
240 session->SetTag("AdvectiveType", AdvectiveType);
241 session->SetTag("ParallelInTimeSolver",
242 "TimeLevel" + std::to_string(timeLevel));
244 vEquation, session, graph);
245 }
246}
247
248/**
249 *
250 */
252{
253 // Parallel-in-Time iteration parameters.
254 m_tolerPIT = m_session->DefinesParameter("PITToler")
255 ? m_session->GetParameter("PITToler")
256 : 1.0E-16;
257 m_iterMaxPIT = m_session->DefinesParameter("PITIterMax")
258 ? m_session->GetParameter("PITIterMax")
259 : m_numChunks;
260 m_numWindowsPIT = m_session->DefinesParameter("NumWindows")
261 ? m_session->GetParameter("NumWindows")
262 : 1;
263
264 // Other parameters.
265 m_exactSolution = m_session->DefinesParameter("ExactSolution")
266 ? m_session->GetParameter("ExactSolution")
267 : 0;
268}
269
270/**
271 *
272 */
274{
275 m_nVar = m_EqSys[0]->GetNvariables();
276
277 // Initialize fine solver.
278 if (turnoff_output)
279 {
280 for (size_t timeLevel = 0; timeLevel < m_nTimeLevel; timeLevel++)
281 {
282 m_EqSys[timeLevel]->SetInfoSteps(0);
283 m_EqSys[timeLevel]->SetCheckpointSteps(0);
284 }
285 }
286 m_EqSys[0]->DoInitialise(true);
287
288 // Initialize coarse solver(s).
289 for (size_t timeLevel = 1; timeLevel < m_nTimeLevel; timeLevel++)
290 {
291 m_EqSys[timeLevel]->DoInitialise(false);
292 }
293
294 // Initialize time stepping parameters.
295 m_time0 = m_EqSys[0]->GetTime();
299 for (size_t timeLevel = 0; timeLevel < m_nTimeLevel; timeLevel++)
300 {
301 m_timestep[timeLevel] =
302 m_EqSys[timeLevel]->EquationSystem::GetTimeStep();
303 m_nsteps[timeLevel] = m_EqSys[timeLevel]->EquationSystem::GetSteps();
304 m_npts[timeLevel] = m_EqSys[timeLevel]->EquationSystem::GetNpoints();
305 }
306
307 // Initialize errors.
309 for (size_t i = 0; i < m_nVar; ++i)
310 {
312 }
315}
316
317/**
318 *
319 */
321{
322 if (m_chunkRank == 0 && m_comm->GetSpaceComm()->GetRank() == 0)
323 {
324 for (size_t timeLevel = 0; timeLevel < m_nTimeLevel; timeLevel++)
325 {
326 std::cout << std::string(71, '=') << std::endl << std::flush;
327 std::cout << "=========================== TIME LEVEL " +
328 std::to_string(timeLevel) +
329 " INFO "
330 "========================="
331 << std::endl
332 << std::flush;
333
334 m_EqSys[timeLevel]->PrintSummary(out);
335
336 std::cout << std::endl << std::flush;
337 }
338 }
339}
340
341/**
342 *
343 */
344void DriverParallelInTime::PrintHeader(const std::string &title, const char c)
345{
346 if (m_chunkRank == m_numChunks - 1 &&
347 m_comm->GetSpaceComm()->GetRank() == 0)
348 {
349 std::cout << std::endl;
350 std::cout << std::string(43, c) << std::endl << std::flush;
351 std::cout << title << std::endl << std::flush;
352 std::cout << std::string(43, c) << std::endl << std::flush;
353 }
354}
355
356/**
357 *
358 */
360 Array<OneD, Array<OneD, NekDouble>> &array, int &convergence)
361{
362 if (m_chunkRank > 0)
363 {
364 if (!convergence)
365 {
366 m_comm->GetTimeComm()->Recv(m_chunkRank - 1, convergence);
367 for (size_t i = 0; i < m_nVar; ++i)
368 {
369 m_comm->GetTimeComm()->Recv(m_chunkRank - 1, array[i]);
370 }
371 }
372 }
373}
374
375/**
376 *
377 */
379{
380 if (m_chunkRank > 0)
381 {
382 m_comm->GetTimeComm()->Recv(m_chunkRank - 1, array);
383 }
384}
385
386/**
387 *
388 */
390 Array<OneD, Array<OneD, NekDouble>> &array, int &convergence)
391{
392 if (m_chunkRank < m_numChunks - 1)
393 {
394 m_comm->GetTimeComm()->Send(m_chunkRank + 1, convergence);
395 for (size_t i = 0; i < m_nVar; ++i)
396 {
397 m_comm->GetTimeComm()->Send(m_chunkRank + 1, array[i]);
398 }
399 }
400}
401
402/**
403 *
404 */
406{
407 if (m_chunkRank < m_numChunks - 1)
408 {
409 m_comm->GetTimeComm()->Send(m_chunkRank + 1, array);
410 }
411}
412
413/**
414 *
415 */
417 const Array<OneD, const Array<OneD, NekDouble>> &in,
419{
420 for (size_t i = 0; i < m_nVar; ++i)
421 {
422 Vmath::Vcopy(in[i].size(), in[i], 1, out[i], 1);
423 }
424}
425
426/**
427 *
428 */
430 const size_t timeLevel, Array<OneD, Array<OneD, NekDouble>> &out)
431{
432 for (size_t i = 0; i < m_nVar; ++i)
433 {
434 m_EqSys[timeLevel]->CopyFromPhysField(i, out[i]);
435 }
436}
437
438/**
439 *
440 */
442 const size_t timeLevel, const Array<OneD, const Array<OneD, NekDouble>> &in)
443{
444 for (size_t i = 0; i < m_nVar; ++i)
445 {
446 m_EqSys[timeLevel]->CopyToPhysField(i, in[i]);
447 m_EqSys[timeLevel]->UpdateFields()[i]->SetPhysState(true);
448 }
449}
450
451/**
452 *
453 */
455 const size_t timeLevel, const Array<OneD, const Array<OneD, NekDouble>> &in)
456{
457 for (size_t i = 0; i < m_nVar; ++i)
458 {
460 {
461 m_EqSys[timeLevel]->CopyToPhysField(i, in[i]);
462 }
463 m_EqSys[timeLevel]->UpdateFields()[i]->FwdTrans(
464 m_EqSys[timeLevel]->UpdateFields()[i]->GetPhys(),
465 m_EqSys[timeLevel]->UpdateFields()[i]->UpdateCoeffs());
466 }
467}
468
469/**
470 *
471 */
473 const NekDouble &time)
474{
475 for (size_t i = 0; i < m_nVar; ++i)
476 {
477 m_EqSys[timeLevel]->EvaluateExactSolution(i, m_exactsoln[i], time);
478 }
479}
480
481/**
482 *
483 */
485 const size_t iter)
486{
487 PrintHeader((boost::format("ITERATION %1%") % iter).str(), '-');
488 UpdateErrorNorm(timeLevel, true);
489 PrintErrorNorm(timeLevel, true);
490}
491
492/**
493 *
494 */
496{
497 UpdateErrorNorm(timeLevel, false);
498 PrintErrorNorm(timeLevel, false);
499}
500
501/**
502 *
503 */
504void DriverParallelInTime::UpdateErrorNorm(const size_t timeLevel,
505 const bool normalized)
506{
507 for (size_t i = 0; i < m_nVar; ++i)
508 {
509 m_vL2Errors[i] =
510 m_EqSys[timeLevel]->L2Error(i, m_exactsoln[i], normalized);
511 m_vLinfErrors[i] = m_EqSys[timeLevel]->LinfError(i, m_exactsoln[i]);
512 }
513}
514
515/**
516 *
517 */
518void DriverParallelInTime::PrintErrorNorm(const size_t timeLevel,
519 const bool normalized)
520{
521 if (m_chunkRank == m_numChunks - 1 &&
522 m_comm->GetSpaceComm()->GetRank() == 0)
523 {
524 for (size_t i = 0; i < m_nVar; ++i)
525 {
526 if (normalized)
527 {
528 std::cout << "L2 error (variable "
529 << m_EqSys[timeLevel]->GetVariable(i)
530 << ") : " << m_vL2Errors[i] << std::endl
531 << std::flush;
532 std::cout << "Linf error (variable "
533 << m_EqSys[timeLevel]->GetVariable(i)
534 << ") : " << m_vLinfErrors[i] << std::endl
535 << std::flush;
536 }
537 else
538 {
539 std::cout << "L 2 error (variable "
540 << m_EqSys[timeLevel]->GetVariable(i)
541 << ") : " << m_vL2Errors[i] << std::endl
542 << std::flush;
543 std::cout << "L inf error (variable "
544 << m_EqSys[timeLevel]->GetVariable(i)
545 << ") : " << m_vLinfErrors[i] << std::endl
546 << std::flush;
547 }
548 }
549 }
550}
551
552/**
553 *
554 */
556{
557 NekDouble L2Error = 0.0;
558 for (size_t i = 0; i < m_nVar; ++i)
559 {
560 L2Error = std::max(L2Error, m_vL2Errors[i]);
561 }
562 return L2Error;
563}
564
565/**
566 *
567 */
571{
572 if (m_numChunks == 1)
573 {
574 return 0.0;
575 }
576 else
577 {
578 // Average communication time over niter iteration.
579 size_t niter = 20;
581 for (size_t n = 0; n <= niter; n++)
582 {
583 if (n == 1)
584 {
585 timer.Start(); // Ignore the first iteration
586 }
587
588 if (m_chunkRank == 0)
589 {
590 for (size_t i = 0; i < buffer1.size(); ++i)
591 {
592 m_comm->GetTimeComm()->Send(m_numChunks - 1, buffer1[i]);
593 }
594 }
595
596 if (m_chunkRank == m_numChunks - 1)
597 {
598 for (size_t i = 0; i < buffer2.size(); ++i)
599 {
600 m_comm->GetTimeComm()->Recv(0, buffer2[i]);
601 }
602 }
603 }
604 timer.Stop();
605 return timer.Elapsed().count() / niter;
606 }
607}
608
609/**
610 *
611 */
615 const Array<OneD, Array<OneD, NekDouble>> &inarray,
617{
618 if (infield.size() != outfield.size())
619 {
620 NEKERROR(ErrorUtil::efatal, "not the same number of variables")
621 }
622
623 for (size_t n = 0; n < infield.size(); ++n)
624 {
625 // Interpolation from infield -> outfield assuming that infield and
626 // outfield are the same explists, but at potentially different
627 // polynomial orders.
628 if (infield[n]->GetExpSize() != outfield[n]->GetExpSize())
629 {
630 NEKERROR(ErrorUtil::efatal, "not the same mesh")
631 }
632
633 // Assign input/output array.
634 auto inphys = (inarray == NullNekDoubleArrayOfArray)
635 ? infield[n]->UpdatePhys()
636 : inarray[n];
637 auto outphys = (outarray == NullNekDoubleArrayOfArray)
638 ? outfield[n]->UpdatePhys()
639 : outarray[n];
640
641 // If same polynomial orders, simply copy solution.
642 if (infield[n]->GetTotPoints() == outfield[n]->GetTotPoints())
643 {
644 Vmath::Vcopy(infield[n]->GetTotPoints(), inphys, 1, outphys, 1);
645 }
646 // If different polynomial orders, interpolate solution.
647 else
648 {
649 for (size_t i = 0; i < infield[n]->GetExpSize(); ++i)
650 {
651 // Get the elements.
652 auto inElmt = infield[n]->GetExp(i);
653 auto outElmt = outfield[n]->GetExp(i);
654
655 // Get the offset of elements in the storage arrays.
656 size_t inoffset = infield[n]->GetPhys_Offset(i);
657 size_t outoffset = outfield[n]->GetPhys_Offset(i);
658
659 // Transform solution from physical to coefficient space.
660 Array<OneD, NekDouble> incoeff(inElmt->GetNcoeffs());
661 inElmt->FwdTrans(inphys + inoffset, incoeff);
662
663 // Interpolate elements.
665 if (inElmt->DetShapeType() == LibUtilities::Seg)
666 {
667 expPtr = std::make_shared<StdRegions::StdSegExp>(
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>(
677 inElmt->GetBasis(0)->GetBasisType(),
678 inElmt->GetBasis(0)->GetNumModes(),
679 outElmt->GetBasis(0)->GetPointsKey()),
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>(
689 inElmt->GetBasis(0)->GetBasisType(),
690 inElmt->GetBasis(0)->GetNumModes(),
691 outElmt->GetBasis(0)->GetPointsKey()),
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>(
701 inElmt->GetBasis(0)->GetBasisType(),
702 inElmt->GetBasis(0)->GetNumModes(),
703 outElmt->GetBasis(0)->GetPointsKey()),
705 inElmt->GetBasis(1)->GetBasisType(),
706 inElmt->GetBasis(1)->GetNumModes(),
707 outElmt->GetBasis(1)->GetPointsKey()),
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>(
717 inElmt->GetBasis(0)->GetBasisType(),
718 inElmt->GetBasis(0)->GetNumModes(),
719 outElmt->GetBasis(0)->GetPointsKey()),
721 inElmt->GetBasis(1)->GetBasisType(),
722 inElmt->GetBasis(1)->GetNumModes(),
723 outElmt->GetBasis(1)->GetPointsKey()),
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>(
733 inElmt->GetBasis(0)->GetBasisType(),
734 inElmt->GetBasis(0)->GetNumModes(),
735 outElmt->GetBasis(0)->GetPointsKey()),
737 inElmt->GetBasis(1)->GetBasisType(),
738 inElmt->GetBasis(1)->GetNumModes(),
739 outElmt->GetBasis(1)->GetPointsKey()),
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>(
749 inElmt->GetBasis(0)->GetBasisType(),
750 inElmt->GetBasis(0)->GetNumModes(),
751 outElmt->GetBasis(0)->GetPointsKey()),
753 inElmt->GetBasis(1)->GetBasisType(),
754 inElmt->GetBasis(1)->GetNumModes(),
755 outElmt->GetBasis(1)->GetPointsKey()),
757 inElmt->GetBasis(2)->GetBasisType(),
758 inElmt->GetBasis(2)->GetNumModes(),
759 outElmt->GetBasis(2)->GetPointsKey()));
760 }
761
762 // Transform solution from coefficient to physical space.
763 Array<OneD, NekDouble> tmp = outphys + outoffset;
764 expPtr->BwdTrans(incoeff, tmp);
765 }
766 }
767 }
768}
769
770} // namespace Nektar::SolverUtils
#define ASSERTL0(condition, msg)
#define NEKERROR(type, msg)
Assert Level 0 – Fundamental assert which is used whether in FULLDEBUG, DEBUG or OPT compilation mode...
Describes the specification for a Basis.
Definition Basis.h:45
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.
Definition Driver.h:65
LibUtilities::SessionReaderSharedPtr m_session
Session reader object.
Definition Driver.h:83
LibUtilities::CommSharedPtr m_comm
Communication object.
Definition Driver.h:80
SpatialDomains::MeshGraphSharedPtr m_graph
MeshGraph object.
Definition Driver.h:89
enum EvolutionOperatorType m_EvolutionOperator
Evolution Operator.
Definition Driver.h:98
Array< OneD, EquationSystemSharedPtr > m_equ
Equation system to solve.
Definition Driver.h:92
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)
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 SetParallelInTimeEquationSystem(std::string AdvectiveType)
Array< OneD, size_t > m_nsteps
Number of time steps for each time level.
SOLVER_UTILS_EXPORT void v_InitObject(std::ostream &out=std::cout) override
Virtual function for initialisation implementation.
void EvaluateExactSolution(const size_t timeLevel, const NekDouble &time)
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.
void PrintSolverInfo(std::ostream &out=std::cout)
bool m_exactSolution
Using exact solution to compute error norms.
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)
SOLVER_UTILS_EXPORT void v_Execute(std::ostream &out=std::cout) override
Virtual function for solve implementation.
Array< OneD, size_t > m_npts
Number of dof for each time level.
Array< OneD, Array< OneD, NekDouble > > m_exactsoln
NekDouble EstimateCommunicationTime(Array< OneD, Array< OneD, NekDouble > > &buffer1, Array< OneD, Array< OneD, NekDouble > > &buffer2)
void SolutionConvergenceSummary(const size_t timeLevel)
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)
void UpdateErrorNorm(const size_t timeLevel, const bool normalized)
void SolutionConvergenceMonitoring(const size_t timeLevel, const size_t iter)
SOLVER_UTILS_EXPORT DriverParallelInTime(const LibUtilities::SessionReaderSharedPtr pSession, const SpatialDomains::MeshGraphSharedPtr pGraph)
Constructor.
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)
static MeshGraphSharedPtr Read(const LibUtilities::SessionReaderSharedPtr pSession, LibUtilities::DomainRangeShPtr rng=LibUtilities::NullDomainRangeShPtr, bool fillGraph=true, SpatialDomains::MeshGraphSharedPtr partitionedGraph=nullptr)
std::shared_ptr< SessionReader > SessionReaderSharedPtr
static DomainRangeShPtr NullDomainRangeShPtr
Definition DomainRange.h:70
EquationSystemFactory & GetEquationSystemFactory()
std::shared_ptr< MeshGraph > MeshGraphSharedPtr
Definition MeshGraph.h:224
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