Nektar++
EquationSystem.cpp
Go to the documentation of this file.
1////////////////////////////////////////////////////////////////////////////////
2//
3// File: EquationSystem.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:
32//
33///////////////////////////////////////////////////////////////////////////////
34
37
43
47
50
52
53#include <boost/format.hpp>
54
55#include <iostream>
56#include <string>
57
58using namespace std;
59
60namespace Nektar::SolverUtils
61{
62
65 LibUtilities::SessionReader::RegisterEnumValue("DEALIASING", "False", 1)};
66
68 LibUtilities::SessionReader::RegisterEnumValue("Projection", "Continuous",
70 LibUtilities::SessionReader::RegisterEnumValue("Projection", "CONTINUOUS",
77 "Projection", "DisContinuous", MultiRegions::eDiscontinuous),
79 "Projection", "Mixed_CG_Discontinuous",
82 "Projection", "MixedCGDG", MultiRegions::eMixed_CG_Discontinuous),
83};
84
85/**
86 * @class EquationSystem
87 *
88 * This class is a base class for all solver implementations. It
89 * provides the underlying generic functionality and interface for
90 * solving equations.
91 *
92 * To solve a steady-state equation, create a derived class from this
93 * class and reimplement the virtual functions to provide custom
94 * implementation for the problem.
95 *
96 * To solve unsteady problems, derive from the UnsteadySystem class
97 * instead which provides general time integration.
98 */
100{
101 static EquationSystemFactory instance;
102 return instance;
103}
104
105/**
106 * This constructor is protected as the objects of this class are never
107 * instantiated directly.
108 * @param pSession The session reader holding problem parameters.
109 */
113 : m_comm(pSession->GetComm()), m_session(pSession), m_graph(pGraph),
114 m_lambda(0), m_infosteps(10),
115 m_fieldMetaDataMap(LibUtilities::NullFieldMetaDataMap)
116{
117 // set up session names in fieldMetaDataMap
118 const vector<std::string> filenames = m_session->GetFilenames();
119
120 for (int i = 0; i < filenames.size(); ++i)
121 {
122 string sessionname = "SessionName";
123 sessionname += std::to_string(i);
124 m_fieldMetaDataMap[sessionname] = filenames[i];
125 m_fieldMetaDataMap["ChkFileNum"] = std::to_string(0);
126 }
127}
128
129/**
130 * @brief Destructor for class EquationSystem.
131 */
133{
135 LocalRegions::MatrixKey::opLess>::ClearManager();
137 LocalRegions::MatrixKey::opLess>::ClearManager();
138}
139
140/**
141 * @brief Initialisation object for EquationSystem.
142 */
143void EquationSystem::v_InitObject(bool DeclareFields)
144{
145 // Save the basename of input file name for output details
146 m_sessionName = m_session->GetSessionName();
147
148 // Instantiate a field reader/writer
150
151 // Also read and store the boundary conditions
155
156 // Set space dimension for use in class
157 m_spacedim = m_graph->GetSpaceDimension();
158
159 // Setting parameteres for homogenous problems
160 m_HomoDirec = 0;
161 m_useFFT = false;
162 m_homogen_dealiasing = false;
163 m_singleMode = false;
164 m_halfMode = false;
165 m_multipleModes = false;
167
168 m_verbose = m_session->DefinesCmdLineArgument("verbose");
169
170 if (m_session->DefinesSolverInfo("HOMOGENEOUS"))
171 {
172 std::string HomoStr = m_session->GetSolverInfo("HOMOGENEOUS");
173 m_spacedim = 3;
174
175 if ((HomoStr == "HOMOGENEOUS1D") || (HomoStr == "Homogeneous1D") ||
176 (HomoStr == "1D") || (HomoStr == "Homo1D"))
177 {
179 m_session->LoadParameter("LZ", m_LhomZ);
180 m_HomoDirec = 1;
181
182 if (m_session->DefinesSolverInfo("ModeType"))
183 {
184 m_session->MatchSolverInfo("ModeType", "SingleMode",
185 m_singleMode, false);
186 m_session->MatchSolverInfo("ModeType", "HalfMode", m_halfMode,
187 false);
188 m_session->MatchSolverInfo("ModeType", "MultipleModes",
189 m_multipleModes, false);
190 }
191
192 // Stability Analysis flags
193 if (m_session->DefinesSolverInfo("ModeType"))
194 {
195 if (m_singleMode)
196 {
197 m_npointsZ = 2;
198 }
199 else if (m_halfMode)
200 {
201 m_npointsZ = 1;
202 }
203 else if (m_multipleModes)
204 {
205 m_npointsZ = m_session->GetParameter("HomModesZ");
206 }
207 else
208 {
209 ASSERTL0(false, "SolverInfo ModeType not valid");
210 }
211 }
212 else
213 {
214 m_npointsZ = m_session->GetParameter("HomModesZ");
215 }
216 }
217
218 if ((HomoStr == "HOMOGENEOUS2D") || (HomoStr == "Homogeneous2D") ||
219 (HomoStr == "2D") || (HomoStr == "Homo2D"))
220 {
222 m_session->LoadParameter("HomModesY", m_npointsY);
223 m_session->LoadParameter("LY", m_LhomY);
224 m_session->LoadParameter("HomModesZ", m_npointsZ);
225 m_session->LoadParameter("LZ", m_LhomZ);
226 m_HomoDirec = 2;
227 }
228
229 if ((HomoStr == "HOMOGENEOUS3D") || (HomoStr == "Homogeneous3D") ||
230 (HomoStr == "3D") || (HomoStr == "Homo3D"))
231 {
233 m_session->LoadParameter("HomModesY", m_npointsY);
234 m_session->LoadParameter("LY", m_LhomY);
235 m_session->LoadParameter("HomModesZ", m_npointsZ);
236 m_session->LoadParameter("LZ", m_LhomZ);
237 m_HomoDirec = 2;
238 }
239
240 m_session->MatchSolverInfo("USEFFT", "FFTW", m_useFFT, false);
241
242 m_session->MatchSolverInfo("DEALIASING", "True", m_homogen_dealiasing,
243 false);
244 }
245 else
246 {
247 // set to default value so can use to identify 2d or 3D
248 // (homogeneous) expansions
249 m_npointsZ = 1;
250 }
251
252 m_session->MatchSolverInfo("SPECTRALHPDEALIASING", "True",
253 m_specHP_dealiasing, false);
254 if (m_specHP_dealiasing == false)
255 {
256 m_session->MatchSolverInfo("SPECTRALHPDEALIASING", "On",
257 m_specHP_dealiasing, false);
258 }
259
260 // Options to determine type of projection from file or directly
261 // from constructor
262 if (m_session->DefinesSolverInfo("PROJECTION"))
263 {
264 std::string ProjectStr = m_session->GetSolverInfo("PROJECTION");
265
266 if ((ProjectStr == "Continuous") || (ProjectStr == "Galerkin") ||
267 (ProjectStr == "CONTINUOUS") || (ProjectStr == "GALERKIN"))
268 {
270 }
271 else if ((ProjectStr == "MixedCGDG") ||
272 (ProjectStr == "Mixed_CG_Discontinuous"))
273 {
275 }
276 else if (ProjectStr == "DisContinuous")
277 {
279 }
280 else
281 {
282 ASSERTL0(false, "PROJECTION value not recognised");
283 }
284 }
285 else
286 {
287 cerr << "Projection type not specified in SOLVERINFO,"
288 "defaulting to continuous Galerkin"
289 << endl;
291 }
292
293 // Enforce singularity check for some problems
295
296 int i;
297 int nvariables = m_session->GetVariables().size();
298 bool DeclareCoeffPhysArrays = true;
299
301 m_spacedim = m_graph->GetSpaceDimension() + m_HomoDirec;
302 m_expdim = m_graph->GetMeshDimension();
303
304 if (DeclareFields) // declare field if required
305 {
306 /// Continuous field
309 {
310 switch (m_expdim)
311 {
312 case 1:
313 {
316 {
317 const LibUtilities::PointsKey PkeyY(
319 const LibUtilities::BasisKey BkeyY(
321 const LibUtilities::PointsKey PkeyZ(
323 const LibUtilities::BasisKey BkeyZ(
325
326 for (i = 0; i < m_fields.size(); i++)
327 {
330 AllocateSharedPtr(m_session, BkeyY, BkeyZ,
333 m_session->GetVariable(i));
334 }
335 }
336 else
337 {
338 for (i = 0; i < m_fields.size(); i++)
339 {
340 m_fields[i] =
344 m_session->GetVariable(i));
345 }
346 }
347 break;
348 }
349 case 2:
350 {
352 {
353 // Fourier single mode stability analysis
354 if (m_singleMode)
355 {
356 const LibUtilities::PointsKey PkeyZ(
359
360 const LibUtilities::BasisKey BkeyZ(
362 PkeyZ);
363
364 for (i = 0; i < m_fields.size(); i++)
365 {
368 AllocateSharedPtr(
369 m_session, BkeyZ, m_LhomZ, m_useFFT,
371 m_session->GetVariable(i),
373 }
374 }
375 // Half mode stability analysis
376 else if (m_halfMode)
377 {
378 const LibUtilities::PointsKey PkeyZ(
381
382 const LibUtilities::BasisKey BkeyZR(
384 PkeyZ);
385
386 const LibUtilities::BasisKey BkeyZI(
388 PkeyZ);
389
390 for (i = 0; i < m_fields.size(); i++)
391 {
392 if (m_session->GetVariable(i).compare("w") == 0)
393 {
395 MultiRegions::
396 ContField3DHomogeneous1D>::
397 AllocateSharedPtr(
398 m_session, BkeyZI, m_LhomZ,
400 m_graph, m_session->GetVariable(i),
402 }
403 else
404 {
406 MultiRegions::
407 ContField3DHomogeneous1D>::
408 AllocateSharedPtr(
409 m_session, BkeyZR, m_LhomZ,
411 m_graph, m_session->GetVariable(i),
413 }
414 }
415 }
416 // Normal homogeneous 1D
417 else
418 {
419 const LibUtilities::PointsKey PkeyZ(
421 const LibUtilities::BasisKey BkeyZ(
423
424 for (i = 0; i < m_fields.size(); i++)
425 {
428 AllocateSharedPtr(
429 m_session, BkeyZ, m_LhomZ, m_useFFT,
431 m_session->GetVariable(i),
433 }
434 }
435 }
436 else
437 {
438 i = 0;
442 m_session->GetVariable(i),
443 DeclareCoeffPhysArrays,
445 m_fields[0] = firstfield;
446 for (i = 1; i < m_fields.size(); i++)
447 {
448 if (m_graph->SameExpansionInfo(
449 m_session->GetVariable(0),
450 m_session->GetVariable(i)))
451 {
452 m_fields[i] =
455 *firstfield, m_graph,
456 m_session->GetVariable(i),
457 DeclareCoeffPhysArrays,
459 }
460 else
461 {
462 m_fields[i] =
466 m_session->GetVariable(i),
467 DeclareCoeffPhysArrays,
469 }
470 }
471
472 if (m_projectionType ==
474 {
475 /// Setting up the normals
478
479 for (i = 0; i < m_spacedim; ++i)
480 {
481 m_traceNormals[i] =
483 }
484
485 m_fields[0]->GetTrace()->GetNormals(m_traceNormals);
486 }
487 }
488
489 break;
490 }
491 case 3:
492 {
493 i = 0;
497 m_session->GetVariable(i),
498 DeclareCoeffPhysArrays,
500
501 m_fields[0] = firstfield;
502 for (i = 1; i < m_fields.size(); i++)
503 {
504 if (m_graph->SameExpansionInfo(
505 m_session->GetVariable(0),
506 m_session->GetVariable(i)))
507 {
508 m_fields[i] =
511 *firstfield, m_graph,
512 m_session->GetVariable(i),
513 DeclareCoeffPhysArrays,
515 }
516 else
517 {
518 m_fields[i] =
522 m_session->GetVariable(i),
523 DeclareCoeffPhysArrays,
525 }
526 }
527
528 if (m_projectionType ==
530 {
531 /// Setting up the normals
534 for (i = 0; i < m_spacedim; ++i)
535 {
536 m_traceNormals[i] =
538 }
539
540 m_fields[0]->GetTrace()->GetNormals(m_traceNormals);
541 // Call the trace on all fields to ensure DG setup.
542 for (i = 1; i < m_fields.size(); ++i)
543 {
544 m_fields[i]->GetTrace();
545 }
546 }
547 break;
548 }
549 default:
550 ASSERTL0(false, "Expansion dimension not recognised");
551 break;
552 }
553 }
554 // Discontinuous field
555 else
556 {
557 switch (m_expdim)
558 {
559 case 1:
560 {
563 {
564 const LibUtilities::PointsKey PkeyY(
566 const LibUtilities::BasisKey BkeyY(
568 const LibUtilities::PointsKey PkeyZ(
570 const LibUtilities::BasisKey BkeyZ(
572
573 for (i = 0; i < m_fields.size(); i++)
574 {
577 AllocateSharedPtr(m_session, BkeyY, BkeyZ,
580 m_session->GetVariable(i));
581 }
582 }
583 else
584 {
585 for (i = 0; i < m_fields.size(); i++)
586 {
587 m_fields[i] =
591 m_session->GetVariable(i));
592 }
593 }
594
595 break;
596 }
597 case 2:
598 {
600 {
601 const LibUtilities::PointsKey PkeyZ(
603 const LibUtilities::BasisKey BkeyZ(
605
606 for (i = 0; i < m_fields.size(); i++)
607 {
610 AllocateSharedPtr(m_session, BkeyZ, m_LhomZ,
611 m_useFFT,
613 m_session->GetVariable(i));
614 }
615 }
616 else
617 {
618 i = 0;
622 m_session->GetVariable(i));
623 m_fields[0] = firstfield;
624 for (i = 1; i < m_fields.size(); i++)
625 {
626 if (m_graph->SameExpansionInfo(
627 m_session->GetVariable(0),
628 m_session->GetVariable(i)))
629 {
630 m_fields[i] =
633 *firstfield, m_graph,
634 m_session->GetVariable(i));
635 }
636 else
637 {
638 m_fields[i] =
642 m_session->GetVariable(i));
643 }
644 }
645 }
646
647 break;
648 }
649 case 3:
650 {
652 {
653 ASSERTL0(
654 false,
655 "3D fully periodic problems not implemented yet");
656 }
657 else
658 {
659 i = 0;
663 m_session->GetVariable(i));
664 m_fields[0] = firstfield;
665 for (i = 1; i < m_fields.size(); i++)
666 {
667 if (m_graph->SameExpansionInfo(
668 m_session->GetVariable(0),
669 m_session->GetVariable(i)))
670 {
671 m_fields[i] =
674 *firstfield, m_graph,
675 m_session->GetVariable(i));
676 }
677 else
678 {
679 m_fields[i] =
683 m_session->GetVariable(i));
684 }
685 }
686 }
687 break;
688 }
689 default:
690 ASSERTL0(false, "Expansion dimension not recognised");
691 break;
692 }
693
694 // Setting up the normals
696
697 for (i = 0; i < m_spacedim; ++i)
698 {
699 m_traceNormals[i] =
701 }
702
703 m_fields[0]->GetTrace()->GetNormals(m_traceNormals);
704 }
705 // Zero all physical fields initially
707 }
708
709 // Set Default Parameter
710 m_session->LoadParameter("Time", m_time, 0.0);
711 m_session->LoadParameter("TimeStep", m_timestep, 0.0);
712 m_session->LoadParameter("NumSteps", m_steps, 0);
713 m_session->LoadParameter("IO_CheckSteps", m_checksteps, 0);
714 m_session->LoadParameter("IO_CheckTime", m_checktime, 0.0);
715 m_session->LoadParameter("FinTime", m_fintime, 0);
716 m_session->LoadParameter("NumQuadPointsError", m_NumQuadPointsError, 0);
717
718 // Check uniqueness of checkpoint output
719 ASSERTL0((m_checktime == 0.0 && m_checksteps == 0) ||
720 (m_checktime > 0.0 && m_checksteps == 0) ||
721 (m_checktime == 0.0 && m_checksteps > 0),
722 "Only one of IO_CheckTime and IO_CheckSteps "
723 "should be set!");
724 m_session->LoadParameter("TimeIncrementFactor", m_TimeIncrementFactor, 1.0);
725
726 // Check for parallel-in-time
727 if (m_comm->IsParallelInTime())
728 {
729 ASSERTL0(m_fintime == 0.0,
730 "Only specify NumSteps and TimeSteps for Parallel-in-Time. "
731 "FinTime should not be used! ");
732 }
733
734 m_nchk = 0;
735 m_iterPIT = 0;
736}
737
738/**
739 *
740 */
742 std::string name, const MultiRegions::ExpListSharedPtr &field, bool cache)
743{
744 MultiRegions::ExpListSharedPtr vField = field;
745 if (!field)
746 {
747 vField = m_fields[0];
748 }
749
750 if (cache)
751 {
752 if ((m_sessionFunctions.find(name) == m_sessionFunctions.end()) ||
753 (m_sessionFunctions[name]->GetSession() != m_session) ||
754 (m_sessionFunctions[name]->GetExpansion() != vField))
755 {
758 m_session, vField, name, cache);
759 }
760
761 return m_sessionFunctions[name];
762 }
763 else
764 {
766 new SessionFunction(m_session, vField, name, cache));
767 }
768}
769
770/**
771 * If boundary conditions are time-dependent, they will be evaluated at
772 * the time specified.
773 * @param time The time at which to evaluate the BCs
774 */
776{
777 std::string varName;
778 int nvariables = m_fields.size();
779 for (int i = 0; i < nvariables; ++i)
780 {
781 varName = m_session->GetVariable(i);
782 m_fields[i]->EvaluateBoundaryConditions(time, varName);
783 }
784}
785
786/**
787 * Compute the error in the L2-norm.
788 * @param field The field to compare.
789 * @param exactsoln The exact solution to compare with.
790 * @param Normalised Normalise L2-error.
791 * @returns Error in the L2-norm.
792 */
794 const Array<OneD, NekDouble> &exactsoln,
795 bool Normalised)
796{
797 NekDouble L2error = -1.0;
798
799 if (m_NumQuadPointsError == 0)
800 {
801 if (m_fields[field]->GetPhysState() == false)
802 {
803 m_fields[field]->BwdTrans(m_fields[field]->GetCoeffs(),
804 m_fields[field]->UpdatePhys());
805 }
806
807 if (exactsoln.size())
808 {
809 L2error =
810 m_fields[field]->L2(m_fields[field]->GetPhys(), exactsoln);
811 }
812 else if (m_session->DefinesFunction("ExactSolution"))
813 {
814 Array<OneD, NekDouble> exactsoln(m_fields[field]->GetNpoints());
815
816 GetFunction("ExactSolution")
817 ->Evaluate(m_session->GetVariable(field), exactsoln, m_time);
818
819 L2error =
820 m_fields[field]->L2(m_fields[field]->GetPhys(), exactsoln);
821 }
822 else
823 {
824 L2error = m_fields[field]->L2(m_fields[field]->GetPhys());
825 }
826
827 if (Normalised == true)
828 {
829 Array<OneD, NekDouble> one(m_fields[field]->GetNpoints(), 1.0);
830
831 NekDouble Vol = m_fields[field]->Integral(one);
832 L2error = sqrt(L2error * L2error / Vol);
833 }
834 }
835 else
836 {
837 Array<OneD, NekDouble> L2INF(2);
838 L2INF = ErrorExtraPoints(field);
839 L2error = L2INF[0];
840 }
841 return L2error;
842}
843
844/**
845 * Compute the error in the L_inf-norm
846 * @param field The field to compare.
847 * @param exactsoln The exact solution to compare with.
848 * @returns Error in the L_inft-norm.
849 */
851 const Array<OneD, NekDouble> &exactsoln)
852{
853 NekDouble Linferror = -1.0;
854
855 if (m_NumQuadPointsError == 0)
856 {
857 if (m_fields[field]->GetPhysState() == false)
858 {
859 m_fields[field]->BwdTrans(m_fields[field]->GetCoeffs(),
860 m_fields[field]->UpdatePhys());
861 }
862
863 if (exactsoln.size())
864 {
865 Linferror =
866 m_fields[field]->Linf(m_fields[field]->GetPhys(), exactsoln);
867 }
868 else if (m_session->DefinesFunction("ExactSolution"))
869 {
870 Array<OneD, NekDouble> exactsoln(m_fields[field]->GetNpoints());
871
872 GetFunction("ExactSolution")
873 ->Evaluate(m_session->GetVariable(field), exactsoln, m_time);
874
875 Linferror =
876 m_fields[field]->Linf(m_fields[field]->GetPhys(), exactsoln);
877 }
878 else
879 {
880 Linferror = m_fields[field]->Linf(m_fields[field]->GetPhys());
881 }
882 }
883 else
884 {
885 Array<OneD, NekDouble> L2INF(2);
886 L2INF = ErrorExtraPoints(field);
887 Linferror = L2INF[1];
888 }
889
890 return Linferror;
891}
892
893/**
894 * Compute the error in the L2-norm, L-inf for a larger number of
895 * quadrature points.
896 * @param field The field to compare.
897 * @returns Error in the L2-norm and L-inf norm.
898 */
900{
901 int NumModes = GetNumExpModes();
902 Array<OneD, NekDouble> L2INF(2);
903
907 LibUtilities::eGaussRadauMAlpha1Beta0);
913 PkeyT1);
915 PkeyT2);
917 PkeyQ1);
919 PkeyQ2);
920
921 LibUtilities::BasisKeyVector Tkeys, Qkeys;
922
923 // make a copy of the ExpansionInfoMap
924 SpatialDomains::ExpansionInfoMap NewExpInfo = m_graph->GetExpansionInfo();
927 NewExpInfo);
928
929 // reset new graph with new keys
930 Tkeys.push_back(BkeyT1);
931 Tkeys.push_back(BkeyT2);
932 m_graph->ResetExpansionInfoToBasisKey(ExpInfo, LibUtilities::eTriangle,
933 Tkeys);
934 Qkeys.push_back(BkeyQ1);
935 Qkeys.push_back(BkeyQ2);
936 m_graph->ResetExpansionInfoToBasisKey(ExpInfo, LibUtilities::eQuadrilateral,
937 Qkeys);
938
941 NewExpInfo);
942
943 int ErrorCoordim = ErrorExp->GetCoordim(0);
944 int ErrorNq = ErrorExp->GetTotPoints();
945
946 Array<OneD, NekDouble> ErrorXc0(ErrorNq, 0.0);
947 Array<OneD, NekDouble> ErrorXc1(ErrorNq, 0.0);
948 Array<OneD, NekDouble> ErrorXc2(ErrorNq, 0.0);
949
950 switch (ErrorCoordim)
951 {
952 case 1:
953 ErrorExp->GetCoords(ErrorXc0);
954 break;
955 case 2:
956 ErrorExp->GetCoords(ErrorXc0, ErrorXc1);
957 break;
958 case 3:
959 ErrorExp->GetCoords(ErrorXc0, ErrorXc1, ErrorXc2);
960 break;
961 }
963 m_session->GetFunction("ExactSolution", field);
964
965 // Evaluate the exact solution
966 Array<OneD, NekDouble> ErrorSol(ErrorNq);
967
968 exSol->Evaluate(ErrorXc0, ErrorXc1, ErrorXc2, m_time, ErrorSol);
969
970 // Calcualte spectral/hp approximation on the quadrature points
971 // of this new expansion basis
972 ErrorExp->BwdTrans(m_fields[field]->GetCoeffs(), ErrorExp->UpdatePhys());
973
974 L2INF[0] = ErrorExp->L2(ErrorExp->GetPhys(), ErrorSol);
975 L2INF[1] = ErrorExp->Linf(ErrorExp->GetPhys(), ErrorSol);
976
977 return L2INF;
978}
979
980/**
981 * Set the physical fields based on a restart file, or a function
982 * describing the initial condition given in the session.
983 * @param initialtime Time at which to evaluate the function.
984 * @param dumpInitialConditions Write the initial condition to file?
985 */
987 [[maybe_unused]] NekDouble initialtime, bool dumpInitialConditions,
988 const int domain)
989{
990 if (m_session->GetComm()->GetRank() == 0)
991 {
992 cout << "Initial Conditions:" << endl;
993 }
994
995 if (m_session->DefinesFunction("InitialConditions"))
996 {
997 GetFunction("InitialConditions")
998 ->Evaluate(m_session->GetVariables(), m_fields, m_time, domain);
999 // Enforce C0 Continutiy of initial condiiton
1002 {
1003 for (int i = 0; i < m_fields.size(); ++i)
1004 {
1005 m_fields[i]->LocalToGlobal();
1006 m_fields[i]->GlobalToLocal();
1007 m_fields[i]->BwdTrans(m_fields[i]->GetCoeffs(),
1008 m_fields[i]->UpdatePhys());
1009 }
1010 }
1011
1012 if (m_session->GetComm()->GetRank() == 0)
1013 {
1014 for (int i = 0; i < m_fields.size(); ++i)
1015 {
1016 std::string varName = m_session->GetVariable(i);
1017 cout << " - Field " << varName << ": "
1018 << GetFunction("InitialConditions")
1019 ->Describe(varName, domain)
1020 << endl;
1021 }
1022 }
1023 }
1024 else
1025 {
1026 int nq = m_fields[0]->GetNpoints();
1027 for (int i = 0; i < m_fields.size(); i++)
1028 {
1029 Vmath::Zero(nq, m_fields[i]->UpdatePhys(), 1);
1030 m_fields[i]->SetPhysState(true);
1031 Vmath::Zero(m_fields[i]->GetNcoeffs(), m_fields[i]->UpdateCoeffs(),
1032 1);
1033 if (m_session->GetComm()->GetRank() == 0)
1034 {
1035 cout << " - Field " << m_session->GetVariable(i)
1036 << ": 0 (default)" << endl;
1037 }
1038 }
1039 }
1040
1041 if (dumpInitialConditions && m_checksteps && m_nchk == 0 &&
1042 !m_comm->IsParallelInTime())
1043 {
1045 }
1046 else if (dumpInitialConditions && m_nchk == 0 && m_comm->IsParallelInTime())
1047 {
1048 std::string newdir = m_sessionName + ".pit";
1049 if (!fs::is_directory(newdir))
1050 {
1051 fs::create_directory(newdir);
1052 }
1053 if (m_comm->GetTimeComm()->GetRank() == 0)
1054 {
1055 WriteFld(newdir + "/" + m_sessionName + "_0.fld");
1056 }
1057 }
1058 ++m_nchk;
1059}
1060
1061/**
1062 *
1063 */
1065 Array<OneD, NekDouble> &outfield,
1066 const NekDouble time)
1067{
1068 ASSERTL0(outfield.size() == m_fields[field]->GetNpoints(),
1069 "ExactSolution array size mismatch.");
1070 Vmath::Zero(outfield.size(), outfield, 1);
1071 if (m_session->DefinesFunction("ExactSolution"))
1072 {
1073 GetFunction("ExactSolution")
1074 ->Evaluate(m_session->GetVariable(field), outfield, time);
1075 }
1076}
1077
1078/**
1079 * By default, nothing needs initialising at the EquationSystem level.
1080 */
1081void EquationSystem::v_DoInitialise([[maybe_unused]] bool dumpInitialConditions)
1082{
1083}
1084
1085/**
1086 *
1087 */
1089{
1090}
1091
1092/**
1093 * Virtual function to define if operator in DoSolve is
1094 * negated with regard to the strong form. This is currently
1095 * only used in Arnoldi solves. Default is false.
1096 */
1098{
1099 return false;
1100}
1101
1102/**
1103 *
1104 */
1106{
1107}
1108
1109/**
1110 *
1111 */
1113{
1114}
1115
1116/// Virtual function for generating summary information.
1118{
1119 SessionSummary(l);
1120}
1121
1122/**
1123 * Write the field data to file. The file is named according to the
1124 * session name with the extension .fld appended.
1125 */
1127{
1128 if (!m_comm->IsParallelInTime())
1129 {
1130 // Serial-in-time
1131 WriteFld(m_sessionName + ".fld");
1132 }
1133 else
1134 {
1135 // Parallel-in-time
1136 std::string newdir = m_sessionName + ".pit";
1137 if (!fs::is_directory(newdir))
1138 {
1139 fs::create_directory(newdir);
1140 }
1141 WriteFld(newdir + "/" + m_sessionName + "_" +
1142 std::to_string(m_windowPIT * m_comm->GetTimeComm()->GetSize() +
1143 m_comm->GetTimeComm()->GetRank() + 1) +
1144 ".fld");
1145 }
1146}
1147
1148/**
1149 * Zero the physical fields.
1150 */
1152{
1153 for (int i = 0; i < m_fields.size(); i++)
1154 {
1155 Vmath::Zero(m_fields[i]->GetNpoints(), m_fields[i]->UpdatePhys(), 1);
1156 }
1157}
1158
1159/**
1160 * FwdTrans the m_fields members
1161 */
1163{
1164 for (int i = 0; i < m_fields.size(); i++)
1165 {
1166 m_fields[i]->FwdTrans(m_fields[i]->GetPhys(),
1167 m_fields[i]->UpdateCoeffs());
1168 m_fields[i]->SetPhysState(false);
1169 }
1170}
1171
1172/**
1173 * Write the n-th checkpoint file.
1174 * @param n The index of the checkpoint file.
1175 */
1177{
1178 if (!m_comm->IsParallelInTime())
1179 {
1180 // Serial-in-time
1181 std::string outname = m_sessionName + "_" + std::to_string(n);
1182 WriteFld(outname + ".chk");
1183 }
1184 else
1185 {
1186 // Parallel-in-time
1187 auto loc = m_sessionName.find("_xml/");
1188 auto sessionName = m_sessionName.substr(0, loc);
1189 std::string paradir =
1190 sessionName + "_" + std::to_string(m_iterPIT) + ".pit";
1191 if (!fs::is_directory(paradir))
1192 {
1193 fs::create_directory(paradir);
1194 }
1195 std::string outname = paradir + "/" + sessionName + "_timeLevel" +
1196 std::to_string(m_session->GetTimeLevel()) + "_" +
1197 std::to_string(n);
1198 WriteFld(outname + ".chk");
1199 }
1200}
1201
1202/**
1203 * Write the n-th checkpoint file.
1204 * @param n The index of the checkpoint file.
1205 */
1207 const int n, MultiRegions::ExpListSharedPtr &field,
1208 std::vector<Array<OneD, NekDouble>> &fieldcoeffs,
1209 std::vector<std::string> &variables)
1210{
1211 if (!m_comm->IsParallelInTime())
1212 {
1213 // Serial-in-time
1214 std::string outname = m_sessionName + "_" + std::to_string(n);
1215 WriteFld(outname, field, fieldcoeffs, variables);
1216 }
1217 else
1218 {
1219 ASSERTL0(false, "Not Implemented for Parallel-in-Time");
1220 }
1221}
1222
1223/**
1224 * Write the n-th base flow into a .chk file
1225 * @param n The index of the base flow file.
1226 */
1228{
1229 std::string outname = m_sessionName + "_BaseFlow_" + std::to_string(n);
1230
1231 WriteFld(outname + ".chk");
1232}
1233
1234/**
1235 * Writes the field data to a file with the given filename.
1236 * @param outname Filename to write to.
1237 */
1238void EquationSystem::WriteFld(const std::string &outname)
1239{
1240 std::vector<Array<OneD, NekDouble>> fieldcoeffs(m_fields.size());
1241 std::vector<std::string> variables(m_fields.size());
1242
1243 for (int i = 0; i < m_fields.size(); ++i)
1244 {
1245 if (m_fields[i]->GetNcoeffs() == m_fields[0]->GetNcoeffs())
1246 {
1247 fieldcoeffs[i] = m_fields[i]->UpdateCoeffs();
1248 }
1249 else
1250 {
1251 fieldcoeffs[i] = Array<OneD, NekDouble>(m_fields[0]->GetNcoeffs());
1252 m_fields[0]->ExtractCoeffsToCoeffs(
1253 m_fields[i], m_fields[i]->GetCoeffs(), fieldcoeffs[i]);
1254 }
1255 variables[i] = m_boundaryConditions->GetVariable(i);
1256 }
1257
1258 ExtraFldOutput(fieldcoeffs, variables);
1259
1260 WriteFld(outname, m_fields[0], fieldcoeffs, variables);
1261}
1262
1263/**
1264 * Writes the field data to a file with the given filename.
1265 * @param outname Filename to write to.
1266 * @param field ExpList on which data is based.
1267 * @param fieldcoeffs An array of array of expansion coefficients.
1268 * @param variables An array of variable names.
1269 */
1270void EquationSystem::WriteFld(const std::string &outname,
1272 std::vector<Array<OneD, NekDouble>> &fieldcoeffs,
1273 std::vector<std::string> &variables)
1274{
1275 std::vector<LibUtilities::FieldDefinitionsSharedPtr> FieldDef =
1276 field->GetFieldDefinitions();
1277 std::vector<std::vector<NekDouble>> FieldData(FieldDef.size());
1278
1279 // Copy Data into FieldData and set variable
1280 for (int j = 0; j < fieldcoeffs.size(); ++j)
1281 {
1282 for (int i = 0; i < FieldDef.size(); ++i)
1283 {
1284 // Could do a search here to find correct variable
1285 FieldDef[i]->m_fields.push_back(variables[j]);
1286 field->AppendFieldData(FieldDef[i], FieldData[i], fieldcoeffs[j]);
1287 }
1288 }
1289
1290 // Update time in field info if required
1291 if (m_fieldMetaDataMap.find("Time") != m_fieldMetaDataMap.end())
1292 {
1293 m_fieldMetaDataMap["Time"] = boost::lexical_cast<std::string>(m_time);
1294 }
1295
1296 // Update step in field info if required
1297 if (m_fieldMetaDataMap.find("ChkFileNum") != m_fieldMetaDataMap.end())
1298 {
1299 m_fieldMetaDataMap["ChkFileNum"] = std::to_string(m_nchk);
1300 }
1301
1302 // If necessary, add mapping information to metadata
1303 // and output mapping coordinates
1305 fields[0] = field;
1309 mapping->Output(fieldMetaDataMap, outname);
1310
1311 // If necessary, add informaton for moving frame reference to metadata
1312 // X, Y, Z translational displacements
1313 // Theta_x, Theta_y, Theta_z angular displacements
1314 // X0, Y0, Z0 pivot point
1315 std::vector<std::string> strFrameData = {
1316 "X", "Y", "Z", "Theta_x", "Theta_y", "Theta_z", "X0", "Y0", "Z0"};
1317 for (size_t i = 0; i < strFrameData.size() && i < m_movingFrameData.size();
1318 ++i)
1319 {
1320 fieldMetaDataMap[strFrameData[i]] =
1321 boost::lexical_cast<std::string>(m_movingFrameData[i]);
1322 }
1323
1324 m_fld->Write(outname, FieldDef, FieldData, fieldMetaDataMap,
1325 m_session->GetBackups());
1326}
1327
1328/**
1329 * Import field from infile and load into \a m_fields. This routine will
1330 * also perform a \a BwdTrans to ensure data is in both the physical and
1331 * coefficient storage.
1332 * @param infile Filename to read.
1333 */
1335 const std::string &infile,
1337{
1338 std::vector<LibUtilities::FieldDefinitionsSharedPtr> FieldDef;
1339 std::vector<std::vector<NekDouble>> FieldData;
1342 field_fld->Import(infile, FieldDef, FieldData);
1343
1344 // Copy FieldData into m_fields
1345 for (int j = 0; j < pFields.size(); ++j)
1346 {
1347 Vmath::Zero(pFields[j]->GetNcoeffs(), pFields[j]->UpdateCoeffs(), 1);
1348
1349 for (int i = 0; i < FieldDef.size(); ++i)
1350 {
1351 ASSERTL1(FieldDef[i]->m_fields[j] == m_session->GetVariable(j),
1352 std::string("Order of ") + infile +
1353 std::string(" data and that defined in "
1354 "m_boundaryconditions differs"));
1355
1356 pFields[j]->ExtractDataToCoeffs(FieldDef[i], FieldData[i],
1357 FieldDef[i]->m_fields[j],
1358 pFields[j]->UpdateCoeffs());
1359 }
1360 pFields[j]->BwdTrans(pFields[j]->GetCoeffs(), pFields[j]->UpdatePhys());
1361 }
1362}
1363
1364/**
1365 * Import field from infile and load into \a m_fields. This routine will
1366 * also perform a \a BwdTrans to ensure data is in both the physical and
1367 * coefficient storage.
1368 * @param infile Filename to read.
1369 * If optionan \a ndomains is specified it assumes we loop over nodmains
1370 * for each nvariables.
1371 */
1373 const std::string &infile,
1374 Array<OneD, MultiRegions::ExpListSharedPtr> &pFields, const int ndomains)
1375{
1376 std::vector<LibUtilities::FieldDefinitionsSharedPtr> FieldDef;
1377 std::vector<std::vector<NekDouble>> FieldData;
1378
1379 LibUtilities::Import(infile, FieldDef, FieldData);
1380
1381 int nvariables = GetNvariables();
1382
1383 ASSERTL0(
1384 ndomains * nvariables == pFields.size(),
1385 "Number of fields does not match the number of variables and domains");
1386
1387 // Copy FieldData into m_fields
1388 for (int j = 0; j < ndomains; ++j)
1389 {
1390 for (int i = 0; i < nvariables; ++i)
1391 {
1392 Vmath::Zero(pFields[j * nvariables + i]->GetNcoeffs(),
1393 pFields[j * nvariables + i]->UpdateCoeffs(), 1);
1394
1395 for (int n = 0; n < FieldDef.size(); ++n)
1396 {
1397 ASSERTL1(FieldDef[n]->m_fields[i] == m_session->GetVariable(i),
1398 std::string("Order of ") + infile +
1399 std::string(" data and that defined in "
1400 "m_boundaryconditions differs"));
1401
1402 pFields[j * nvariables + i]->ExtractDataToCoeffs(
1403 FieldDef[n], FieldData[n], FieldDef[n]->m_fields[i],
1404 pFields[j * nvariables + i]->UpdateCoeffs());
1405 }
1406 pFields[j * nvariables + i]->BwdTrans(
1407 pFields[j * nvariables + i]->GetCoeffs(),
1408 pFields[j * nvariables + i]->UpdatePhys());
1409 }
1410 }
1411}
1412
1413/**
1414 * Import field from infile and load into \a pField. This routine will
1415 * also perform a \a BwdTrans to ensure data is in both the physical and
1416 * coefficient storage.
1417 */
1418void EquationSystem::ImportFld(const std::string &infile,
1420 std::string &pFieldName)
1421{
1422 std::vector<LibUtilities::FieldDefinitionsSharedPtr> FieldDef;
1423 std::vector<std::vector<NekDouble>> FieldData;
1424
1427 field_fld->Import(infile, FieldDef, FieldData);
1428 int idx = -1;
1429
1430 Vmath::Zero(pField->GetNcoeffs(), pField->UpdateCoeffs(), 1);
1431
1432 for (int i = 0; i < FieldDef.size(); ++i)
1433 {
1434 // find the index of the required field in the file.
1435 for (int j = 0; j < FieldData.size(); ++j)
1436 {
1437 if (FieldDef[i]->m_fields[j] == pFieldName)
1438 {
1439 idx = j;
1440 }
1441 }
1442 ASSERTL1(idx >= 0, "Field " + pFieldName + " not found.");
1443
1444 pField->ExtractDataToCoeffs(FieldDef[i], FieldData[i],
1445 FieldDef[i]->m_fields[idx],
1446 pField->UpdateCoeffs());
1447 }
1448 pField->BwdTrans(pField->GetCoeffs(), pField->UpdatePhys());
1449}
1450
1451/**
1452 * Import field from infile and load into the array \a coeffs.
1453 *
1454 * @param infile Filename to read.
1455 * @param fieldStr an array of string identifying fields to be imported
1456 * @param coeffs array of array of coefficients to store imported data
1457 */
1458void EquationSystem::ImportFld(const std::string &infile,
1459 std::vector<std::string> &fieldStr,
1461{
1462
1463 ASSERTL0(fieldStr.size() <= coeffs.size(),
1464 "length of fieldstr should be the same as coeffs");
1465
1466 std::vector<LibUtilities::FieldDefinitionsSharedPtr> FieldDef;
1467 std::vector<std::vector<NekDouble>> FieldData;
1468
1471 field_fld->Import(infile, FieldDef, FieldData);
1472
1473 // Copy FieldData into m_fields
1474 for (int j = 0; j < fieldStr.size(); ++j)
1475 {
1476 Vmath::Zero(coeffs[j].size(), coeffs[j], 1);
1477 for (int i = 0; i < FieldDef.size(); ++i)
1478 {
1479 m_fields[0]->ExtractDataToCoeffs(FieldDef[i], FieldData[i],
1480 fieldStr[j], coeffs[j]);
1481 }
1482 }
1483}
1484
1485/**
1486 * Write out a summary of the session data.
1487 * @param out Output stream to write data to.
1488 */
1490{
1491 AddSummaryItem(s, "EquationType", m_session->GetSolverInfo("EQTYPE"));
1492 AddSummaryItem(s, "Session Name", m_sessionName);
1493 AddSummaryItem(s, "Spatial Dim.", m_spacedim);
1494 AddSummaryItem(s, "Max SEM Exp. Order",
1495 m_fields[0]->EvalBasisNumModesMax());
1496
1497 if (m_session->GetComm()->GetSize() > 1)
1498 {
1499 AddSummaryItem(s, "Num. Processes", m_session->GetComm()->GetSize());
1500 }
1501
1503 {
1504 AddSummaryItem(s, "Quasi-3D", "Homogeneous in z-direction");
1505 AddSummaryItem(s, "Expansion Dim.", m_expdim + 1);
1506 AddSummaryItem(s, "Num. Hom. Modes (z)", m_npointsZ);
1507 AddSummaryItem(s, "Hom. length (LZ)", m_LhomZ);
1508 AddSummaryItem(s, "FFT Type", m_useFFT ? "FFTW" : "MVM");
1509 if (m_halfMode)
1510 {
1511 AddSummaryItem(s, "ModeType", "Half Mode");
1512 }
1513 else if (m_singleMode)
1514 {
1515 AddSummaryItem(s, "ModeType", "Single Mode");
1516 }
1517 else if (m_multipleModes)
1518 {
1519 AddSummaryItem(s, "ModeType", "Multiple Modes");
1520 }
1521 }
1523 {
1524 AddSummaryItem(s, "Quasi-3D", "Homogeneous in yz-plane");
1525 AddSummaryItem(s, "Expansion Dim.", m_expdim + 2);
1526 AddSummaryItem(s, "Num. Hom. Modes (y)", m_npointsY);
1527 AddSummaryItem(s, "Num. Hom. Modes (z)", m_npointsZ);
1528 AddSummaryItem(s, "Hom. length (LY)", m_LhomY);
1529 AddSummaryItem(s, "Hom. length (LZ)", m_LhomZ);
1530 AddSummaryItem(s, "FFT Type", m_useFFT ? "FFTW" : "MVM");
1531 }
1532 else
1533 {
1534 AddSummaryItem(s, "Expansion Dim.", m_expdim);
1535 }
1536
1537 if (m_session->DefinesSolverInfo("UpwindType"))
1538 {
1539 AddSummaryItem(s, "Riemann Solver",
1540 m_session->GetSolverInfo("UpwindType"));
1541 }
1542
1543 if (m_session->DefinesSolverInfo("AdvectionType"))
1544 {
1545 std::string AdvectionType;
1546 AdvectionType = m_session->GetSolverInfo("AdvectionType");
1548 s, "Advection Type",
1549 GetAdvectionFactory().GetClassDescription(AdvectionType));
1550 }
1551
1553 {
1554 AddSummaryItem(s, "Projection Type", "Continuous Galerkin");
1555 }
1557 {
1558 AddSummaryItem(s, "Projection Type", "Discontinuous Galerkin");
1559 }
1561 {
1562 AddSummaryItem(s, "Projection Type",
1563 "Mixed Continuous Galerkin and Discontinuous");
1564 }
1565
1566 if (m_session->DefinesSolverInfo("DiffusionType"))
1567 {
1568 std::string DiffusionType;
1569 DiffusionType = m_session->GetSolverInfo("DiffusionType");
1571 s, "Diffusion Type",
1572 GetDiffusionFactory().GetClassDescription(DiffusionType));
1573 }
1574}
1575
1576/**
1577 *
1578 */
1580{
1581 return Array<OneD, bool>(m_session->GetVariables().size(), false);
1582}
1583
1584/**
1585 *
1586 */
1588{
1589 ASSERTL0(false, "This function is not valid for the Base class");
1591 return null;
1592}
1593
1594/**
1595 *
1596 */
1598 [[maybe_unused]] std::vector<Array<OneD, NekDouble>> &fieldcoeffs,
1599 [[maybe_unused]] std::vector<std::string> &variables)
1600{
1601}
1602
1603} // namespace Nektar::SolverUtils
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:208
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode....
Definition: ErrorUtil.hpp:242
static GLOBAL_MAPPING_EXPORT MappingSharedPtr Load(const LibUtilities::SessionReaderSharedPtr &pSession, const Array< OneD, MultiRegions::ExpListSharedPtr > &pFields)
Return a pointer to the mapping, creating it on first call.
Definition: Mapping.cpp:266
Describes the specification for a Basis.
Definition: Basis.h:45
static std::shared_ptr< FieldIO > CreateForFile(const LibUtilities::SessionReaderSharedPtr session, const std::string &filename)
Construct a FieldIO object for a given input filename.
Definition: FieldIO.cpp:224
static std::shared_ptr< FieldIO > CreateDefault(const LibUtilities::SessionReaderSharedPtr session)
Returns an object for the default FieldIO method.
Definition: FieldIO.cpp:195
Provides a generic Factory class.
Definition: NekFactory.hpp:104
Defines a specification for a set of points.
Definition: Points.h:50
static std::string RegisterEnumValue(std::string pEnum, std::string pString, int pEnumValue)
Registers an enumeration value.
General purpose memory allocation routines with the ability to allocate from thread specific memory p...
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
int m_spacedim
Spatial dimension (>= expansion dim).
SOLVER_UTILS_EXPORT int GetTraceNpoints()
SOLVER_UTILS_EXPORT void ExtraFldOutput(std::vector< Array< OneD, NekDouble > > &fieldcoeffs, std::vector< std::string > &variables)
bool m_useFFT
Flag to determine if FFT is used for homogeneous transform.
SOLVER_UTILS_EXPORT int GetNvariables()
int m_expdim
Expansion dimension.
LibUtilities::FieldIOSharedPtr m_fld
Field input/output.
SOLVER_UTILS_EXPORT void SessionSummary(SummaryList &vSummary)
Write out a session summary.
virtual SOLVER_UTILS_EXPORT void v_SetInitialConditions(NekDouble initialtime=0.0, bool dumpInitialConditions=true, const int domain=0)
virtual SOLVER_UTILS_EXPORT ~EquationSystem()
Destructor.
SpatialDomains::MeshGraphSharedPtr m_graph
Pointer to graph defining mesh.
LibUtilities::CommSharedPtr m_comm
Communicator.
NekDouble m_timestep
Time step size.
SOLVER_UTILS_EXPORT void ImportFld(const std::string &infile, Array< OneD, MultiRegions::ExpListSharedPtr > &pFields)
Input field data from the given file.
NekDouble m_time
Current time of simulation.
int m_iterPIT
Number of parallel-in-time time iteration.
bool m_multipleModes
Flag to determine if use multiple homogenenous modes are used.
Array< OneD, MultiRegions::ExpListSharedPtr > m_fields
Array holding all dependent variables.
int m_windowPIT
Index of windows for parallel-in-time time iteration.
virtual SOLVER_UTILS_EXPORT void v_TransPhysToCoeff()
Virtual function for transformation to coefficient space.
virtual SOLVER_UTILS_EXPORT bool v_NegatedOp(void)
Virtual function to identify if operator is negated in DoSolve.
NekDouble m_fintime
Finish time of the simulation.
virtual SOLVER_UTILS_EXPORT NekDouble v_L2Error(unsigned int field, const Array< OneD, NekDouble > &exactsoln=NullNekDouble1DArray, bool Normalised=false)
Virtual function for the L_2 error computation between fields and a given exact solution.
virtual SOLVER_UTILS_EXPORT MultiRegions::ExpListSharedPtr v_GetPressure(void)
static std::string projectionTypeLookupIds[]
int m_npointsZ
number of points in Z direction (if homogeneous)
SOLVER_UTILS_EXPORT void Checkpoint_Output(const int n)
Write checkpoint file of m_fields.
virtual SOLVER_UTILS_EXPORT void v_ExtraFldOutput(std::vector< Array< OneD, NekDouble > > &fieldcoeffs, std::vector< std::string > &variables)
std::map< std::string, SolverUtils::SessionFunctionSharedPtr > m_sessionFunctions
Map of known SessionFunctions.
NekDouble m_checktime
Time between checkpoints.
virtual SOLVER_UTILS_EXPORT void v_InitObject(bool DeclareFeld=true)
Initialisation object for EquationSystem.
virtual SOLVER_UTILS_EXPORT NekDouble v_LinfError(unsigned int field, const Array< OneD, NekDouble > &exactsoln=NullNekDouble1DArray)
Virtual function for the L_inf error computation between fields and a given exact solution.
static std::string equationSystemTypeLookupIds[]
virtual SOLVER_UTILS_EXPORT void v_EvaluateExactSolution(unsigned int field, Array< OneD, NekDouble > &outfield, const NekDouble time)
virtual SOLVER_UTILS_EXPORT void v_DoInitialise(bool dumpInitialConditions=true)
Virtual function for initialisation implementation.
SOLVER_UTILS_EXPORT void WriteFld(const std::string &outname)
Write field data to the given filename.
SOLVER_UTILS_EXPORT void ImportFldToMultiDomains(const std::string &infile, Array< OneD, MultiRegions::ExpListSharedPtr > &pFields, const int ndomains)
Input field data from the given file to multiple domains.
NekDouble m_LhomY
physical length in Y direction (if homogeneous)
int m_npointsY
number of points in Y direction (if homogeneous)
std::string m_sessionName
Name of the session.
SOLVER_UTILS_EXPORT void Checkpoint_BaseFlow(const int n)
Write base flow file of m_fields.
bool m_specHP_dealiasing
Flag to determine if dealisising is usde for the Spectral/hp element discretisation.
LibUtilities::SessionReaderSharedPtr m_session
The session reader.
bool m_singleMode
Flag to determine if single homogeneous mode is used.
SOLVER_UTILS_EXPORT void ZeroPhysFields()
int m_HomoDirec
number of homogenous directions
Array< OneD, Array< OneD, NekDouble > > m_traceNormals
Array holding trace normals for DG simulations in the forwards direction.
enum HomogeneousType m_HomogeneousType
SOLVER_UTILS_EXPORT Array< OneD, NekDouble > ErrorExtraPoints(unsigned int field)
Compute error (L2 and L_inf) over an larger set of quadrature points return [L2 Linf].
SOLVER_UTILS_EXPORT int GetNpoints()
Array< OneD, bool > m_checkIfSystemSingular
Flag to indicate if the fields should be checked for singularity.
bool m_homogen_dealiasing
Flag to determine if dealiasing is used for homogeneous simulations.
SOLVER_UTILS_EXPORT int GetNcoeffs()
int m_nchk
Number of checkpoints written so far.
enum MultiRegions::ProjectionType m_projectionType
Type of projection; e.g continuous or discontinuous.
virtual SOLVER_UTILS_EXPORT void v_DoSolve()
Virtual function for solve implementation.
virtual SOLVER_UTILS_EXPORT Array< OneD, bool > v_GetSystemSingularChecks()
int m_steps
Number of steps to take.
int m_NumQuadPointsError
Number of Quadrature points used to work out the error.
SOLVER_UTILS_EXPORT EquationSystem(const LibUtilities::SessionReaderSharedPtr &pSession, const SpatialDomains::MeshGraphSharedPtr &pGraph)
Initialises EquationSystem class members.
LibUtilities::FieldMetaDataMap m_fieldMetaDataMap
Map to identify relevant solver info to dump in output fields.
SOLVER_UTILS_EXPORT int GetNumExpModes()
SpatialDomains::BoundaryConditionsSharedPtr m_boundaryConditions
Pointer to boundary conditions object.
Array< OneD, NekDouble > m_movingFrameData
Moving frame of reference angles with respect to the.
SOLVER_UTILS_EXPORT void SetBoundaryConditions(NekDouble time)
Evaluates the boundary conditions at the given time.
NekDouble m_LhomZ
physical length in Z direction (if homogeneous)
virtual SOLVER_UTILS_EXPORT void v_GenerateSummary(SummaryList &l)
Virtual function for generating summary information.
bool m_halfMode
Flag to determine if half homogeneous mode is used.
SOLVER_UTILS_EXPORT void FwdTransFields()
int m_checksteps
Number of steps between checkpoints.
SOLVER_UTILS_EXPORT SessionFunctionSharedPtr GetFunction(std::string name, const MultiRegions::ExpListSharedPtr &field=MultiRegions::NullExpListSharedPtr, bool cache=false)
Get a SessionFunction by name.
virtual SOLVER_UTILS_EXPORT void v_Output(void)
virtual SOLVER_UTILS_EXPORT void v_TransCoeffToPhys()
Virtual function for transformation to physical space.
GLOBAL_MAPPING_EXPORT typedef std::shared_ptr< Mapping > MappingSharedPtr
A shared pointer to a Mapping object.
Definition: Mapping.h:51
std::vector< BasisKey > BasisKeyVector
Name for a vector of BasisKeys.
void Import(const std::string &infilename, std::vector< FieldDefinitionsSharedPtr > &fielddefs, std::vector< std::vector< NekDouble > > &fielddata, FieldMetaDataMap &fieldinfomap, const Array< OneD, int > &ElementIDs)
This function allows for data to be imported from an FLD file when a session and/or communicator is n...
Definition: FieldIO.cpp:288
std::shared_ptr< FieldIO > FieldIOSharedPtr
Definition: FieldIO.h:322
std::map< std::string, std::string > FieldMetaDataMap
Definition: FieldIO.h:50
std::shared_ptr< SessionReader > SessionReaderSharedPtr
std::shared_ptr< Equation > EquationSharedPtr
Definition: Equation.h:125
static FieldMetaDataMap NullFieldMetaDataMap
Definition: FieldIO.h:51
@ eFourierEvenlySpaced
1D Evenly-spaced points using Fourier Fit
Definition: PointsType.h:74
@ eGaussLobattoLegendre
1D Gauss-Lobatto-Legendre quadrature points
Definition: PointsType.h:51
@ eFourierSingleModeSpaced
1D Non Evenly-spaced points for Single Mode analysis
Definition: PointsType.h:75
@ eModified_B
Principle Modified Functions .
Definition: BasisType.h:49
@ eFourierSingleMode
Fourier ModifiedExpansion with just the first mode .
Definition: BasisType.h:64
@ eModified_A
Principle Modified Functions .
Definition: BasisType.h:48
@ eFourierHalfModeIm
Fourier Modified expansions with just the imaginary part of the first mode .
Definition: BasisType.h:68
@ eFourierHalfModeRe
Fourier Modified expansions with just the real part of the first mode .
Definition: BasisType.h:66
@ eFourier
Fourier Expansion .
Definition: BasisType.h:55
std::shared_ptr< DisContField > DisContFieldSharedPtr
Definition: DisContField.h:345
std::shared_ptr< ExpList > ExpListSharedPtr
Shared pointer to an ExpList object.
std::shared_ptr< ContField > ContFieldSharedPtr
Definition: ContField.h:268
AdvectionFactory & GetAdvectionFactory()
Gets the factory for initialising advection objects.
Definition: Advection.cpp:43
std::vector< std::pair< std::string, std::string > > SummaryList
Definition: Misc.h:46
DiffusionFactory & GetDiffusionFactory()
Definition: Diffusion.cpp:39
EquationSystemFactory & GetEquationSystemFactory()
void AddSummaryItem(SummaryList &l, const std::string &name, const std::string &value)
Adds a summary item to the summary info list.
Definition: Misc.cpp:47
std::shared_ptr< SessionFunction > SessionFunctionSharedPtr
std::shared_ptr< ExpansionInfoMap > ExpansionInfoMapShPtr
Definition: MeshGraph.h:143
std::shared_ptr< MeshGraph > MeshGraphSharedPtr
Definition: MeshGraph.h:174
std::map< int, ExpansionInfoShPtr > ExpansionInfoMap
Definition: MeshGraph.h:141
NekMatrix< NekMatrix< NekMatrix< NekDouble, StandardMatrixTag >, ScaledMatrixTag >, BlockMatrixTag > DNekScalBlkMat
Definition: NekTypeDefs.hpp:68
NekMatrix< NekMatrix< NekDouble, StandardMatrixTag >, ScaledMatrixTag > DNekScalMat
double NekDouble
void Zero(int n, T *x, const int incx)
Zero vector.
Definition: Vmath.hpp:273
scalarT< T > sqrt(scalarT< T > in)
Definition: scalar.hpp:294
Used to lookup the create function in NekManager.
Definition: MatrixKey.h:69