Nektar++
Loading...
Searching...
No Matches
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 */
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 WARNINGL0(!m_session->DefinesParameter("IO_CheckSteps"),
725 "The IO_CheckSteps parameter is now deprecated.\nPlease use the "
726 "'Checkpoint' filter instead");
727 WARNINGL0(!m_session->DefinesParameter("IO_CheckTime"),
728 "The IO_CheckTime parameter is now deprecated.\nPlease use the "
729 "'Checkpoint' filter instead");
730
731 m_session->LoadParameter("TimeIncrementFactor", m_TimeIncrementFactor, 1.0);
732
733 // Check for parallel-in-time
734 if (m_comm->IsParallelInTime())
735 {
736 ASSERTL0(m_fintime == 0.0,
737 "Only specify NumSteps and TimeSteps for Parallel-in-Time. "
738 "FinTime should not be used! ");
739 }
740
741 m_nchk = 0;
742 m_iterPIT = 0;
743}
744
745/**
746 *
747 */
749 std::string name, const MultiRegions::ExpListSharedPtr &field, bool cache)
750{
751 MultiRegions::ExpListSharedPtr vField = field;
752 if (!field)
753 {
754 vField = m_fields[0];
755 }
756
757 if (cache)
758 {
759 if ((m_sessionFunctions.find(name) == m_sessionFunctions.end()) ||
760 (m_sessionFunctions[name]->GetSession() != m_session) ||
761 (m_sessionFunctions[name]->GetExpansion() != vField))
762 {
763 m_sessionFunctions[name] =
765 m_session, vField, name, cache);
766 }
767
768 return m_sessionFunctions[name];
769 }
770 else
771 {
773 new SessionFunction(m_session, vField, name, cache));
774 }
775}
776
777/**
778 * If boundary conditions are time-dependent, they will be evaluated at
779 * the time specified.
780 * @param time The time at which to evaluate the BCs
781 */
783{
784 std::string varName;
785 int nvariables = m_fields.size();
786 for (int i = 0; i < nvariables; ++i)
787 {
788 varName = m_session->GetVariable(i);
789 m_fields[i]->EvaluateBoundaryConditions(time, varName);
790 }
791}
792
793/**
794 * Compute the error in the L2-norm.
795 * @param field The field to compare.
796 * @param exactsoln The exact solution to compare with.
797 * @param Normalised Normalise L2-error.
798 * @returns Error in the L2-norm.
799 */
801 const Array<OneD, NekDouble> &exactsoln,
802 bool Normalised)
803{
804 NekDouble L2error = -1.0;
805
806 if (m_NumQuadPointsError == 0)
807 {
808 if (m_fields[field]->GetPhysState() == false)
809 {
810 m_fields[field]->BwdTrans(m_fields[field]->GetCoeffs(),
811 m_fields[field]->UpdatePhys());
812 }
813
814 // Transform from (phys, wave) -> (phys, phys), for 2.5D
815 bool physwavetrans = false;
816 if (m_fields[field]->GetWaveSpace() == true)
817 {
818 m_fields[field]->HomogeneousBwdTrans(
819 m_fields[field]->GetTotPoints(), m_fields[field]->GetPhys(),
820 m_fields[field]->UpdatePhys());
821 physwavetrans = true;
822 }
823
824 if (exactsoln.size())
825 {
826 L2error =
827 m_fields[field]->L2(m_fields[field]->GetPhys(), exactsoln);
828 }
829 else if (m_session->DefinesFunction("ExactSolution"))
830 {
831 Array<OneD, NekDouble> exactsoln(m_fields[field]->GetNpoints());
832
833 GetFunction("ExactSolution")
834 ->Evaluate(m_session->GetVariable(field), exactsoln, m_time);
835
836 L2error =
837 m_fields[field]->L2(m_fields[field]->GetPhys(), exactsoln);
838 }
839 else
840 {
841 L2error = m_fields[field]->L2(m_fields[field]->GetPhys());
842 }
843
844 if (Normalised == true)
845 {
846 Array<OneD, NekDouble> one(m_fields[field]->GetNpoints(), 1.0);
847
848 NekDouble Vol = m_fields[field]->Integral(one);
849 L2error = sqrt(L2error * L2error / Vol);
850 }
851
852 // Transform from (phys, phys) -> (phys, wave), for 2.5D
853 if (physwavetrans == true)
854 {
855 m_fields[field]->HomogeneousFwdTrans(
856 m_fields[field]->GetTotPoints(), m_fields[field]->GetPhys(),
857 m_fields[field]->UpdatePhys());
858 physwavetrans = false;
859 }
860 }
861 else
862 {
863 Array<OneD, NekDouble> errNorms(3);
864 errNorms = ErrorExtraPoints(field);
865 L2error = errNorms[0];
866 }
867 return L2error;
868}
869
870/**
871 * Compute the error in the L_inf-norm
872 * @param field The field to compare.
873 * @param exactsoln The exact solution to compare with.
874 * @returns Error in the L_inft-norm.
875 */
877 const Array<OneD, NekDouble> &exactsoln)
878{
879 NekDouble Linferror = -1.0;
880
881 if (m_NumQuadPointsError == 0)
882 {
883 if (m_fields[field]->GetPhysState() == false)
884 {
885 m_fields[field]->BwdTrans(m_fields[field]->GetCoeffs(),
886 m_fields[field]->UpdatePhys());
887 }
888
889 if (exactsoln.size())
890 {
891 Linferror =
892 m_fields[field]->Linf(m_fields[field]->GetPhys(), exactsoln);
893 }
894 else if (m_session->DefinesFunction("ExactSolution"))
895 {
896 Array<OneD, NekDouble> exactsoln(m_fields[field]->GetNpoints());
897
898 GetFunction("ExactSolution")
899 ->Evaluate(m_session->GetVariable(field), exactsoln, m_time);
900
901 Linferror =
902 m_fields[field]->Linf(m_fields[field]->GetPhys(), exactsoln);
903 }
904 else
905 {
906 Linferror = m_fields[field]->Linf(m_fields[field]->GetPhys());
907 }
908 }
909 else
910 {
911 Array<OneD, NekDouble> errNorms(3);
912 errNorms = ErrorExtraPoints(field);
913 Linferror = errNorms[1];
914 }
915
916 return Linferror;
917}
918
919/**
920 * Compute the error in the H1-norm.
921 * @param field The field to compare.
922 * @param exactsoln The exact solution to compare with.
923 * @param Normalised Normalise H1-error.
924 * @returns Error in the H1-norm.
925 */
927 const Array<OneD, NekDouble> &exactsoln,
928 bool Normalised)
929{
930 NekDouble error = -1.0;
931
932 if (m_NumQuadPointsError == 0)
933 {
934 if (m_fields[field]->GetPhysState() == false)
935 {
936 m_fields[field]->BwdTrans(m_fields[field]->GetCoeffs(),
937 m_fields[field]->UpdatePhys());
938 }
939
940 if (exactsoln.size())
941 {
942 error = m_fields[field]->H1(m_fields[field]->GetPhys(), exactsoln);
943 }
944 else if (m_session->DefinesFunction("ExactSolution"))
945 {
946 Array<OneD, NekDouble> exactsoln(m_fields[field]->GetNpoints());
947
948 GetFunction("ExactSolution")
949 ->Evaluate(m_session->GetVariable(field), exactsoln, m_time);
950
951 error = m_fields[field]->H1(m_fields[field]->GetPhys(), exactsoln);
952 }
953 else
954 {
955 error = m_fields[field]->H1(m_fields[field]->GetPhys());
956 }
957
958 if (Normalised == true)
959 {
960 Array<OneD, NekDouble> one(m_fields[field]->GetNpoints(), 1.0);
961
962 NekDouble Vol = m_fields[field]->Integral(one);
963 error = sqrt(error * error / Vol);
964 }
965 }
966 else
967 {
968 Array<OneD, NekDouble> errNorms(3);
969 errNorms = ErrorExtraPoints(field);
970 error = errNorms[2];
971 }
972 return error;
973}
974
975/**
976 * Compute the error in the L2-, Linf- and H1-norm for a larger number of
977 * quadrature points.
978 * @param field The field to compare.
979 * @returns Error in the L2-, Linf- and H1-norm.
980 */
982{
983 int NumModes = GetNumExpModes();
984 Array<OneD, NekDouble> errNorms(3); // Expects 3 norms (L2, Linf, H1)
985
989 LibUtilities::eGaussRadauMAlpha1Beta0);
995 PkeyT1);
997 PkeyT2);
999 PkeyQ1);
1001 PkeyQ2);
1002
1003 LibUtilities::BasisKeyVector Tkeys, Qkeys;
1004
1005 // make a copy of the ExpansionInfoMap
1006 SpatialDomains::ExpansionInfoMap NewExpInfo = m_graph->GetExpansionInfo();
1009 NewExpInfo);
1010
1011 // reset new graph with new keys
1012 Tkeys.push_back(BkeyT1);
1013 Tkeys.push_back(BkeyT2);
1014 m_graph->ResetExpansionInfoToBasisKey(ExpInfo, LibUtilities::eTriangle,
1015 Tkeys);
1016 Qkeys.push_back(BkeyQ1);
1017 Qkeys.push_back(BkeyQ2);
1018 m_graph->ResetExpansionInfoToBasisKey(ExpInfo, LibUtilities::eQuadrilateral,
1019 Qkeys);
1020
1021 MultiRegions::ExpListSharedPtr ErrorExplist =
1023 NewExpInfo);
1024
1025 int ErrorCoordim = ErrorExplist->GetCoordim(0);
1026 int ErrorNq = ErrorExplist->GetTotPoints();
1027
1028 Array<OneD, NekDouble> ErrorXc0(ErrorNq, 0.0);
1029 Array<OneD, NekDouble> ErrorXc1(ErrorNq, 0.0);
1030 Array<OneD, NekDouble> ErrorXc2(ErrorNq, 0.0);
1031
1032 switch (ErrorCoordim)
1033 {
1034 case 1:
1035 ErrorExplist->GetCoords(ErrorXc0);
1036 break;
1037 case 2:
1038 ErrorExplist->GetCoords(ErrorXc0, ErrorXc1);
1039 break;
1040 case 3:
1041 ErrorExplist->GetCoords(ErrorXc0, ErrorXc1, ErrorXc2);
1042 break;
1043 }
1045 m_session->GetFunction("ExactSolution", field);
1046
1047 // Evaluate the exact solution
1048 Array<OneD, NekDouble> ErrorSol(ErrorNq);
1049
1050 exSol->Evaluate(ErrorXc0, ErrorXc1, ErrorXc2, m_time, ErrorSol);
1051
1052 // Calcualte spectral/hp approximation on the quadrature points
1053 // of this new expansion basis
1054 ErrorExplist->BwdTrans(m_fields[field]->GetCoeffs(),
1055 ErrorExplist->UpdatePhys());
1056
1057 errNorms[0] = ErrorExplist->L2(ErrorExplist->GetPhys(), ErrorSol);
1058 errNorms[1] = ErrorExplist->Linf(ErrorExplist->GetPhys(), ErrorSol);
1059 errNorms[2] = ErrorExplist->H1(ErrorExplist->GetPhys(), ErrorSol);
1060
1061 return errNorms;
1062}
1063
1064/**
1065 * Set the physical fields based on a restart file, or a function
1066 * describing the initial condition given in the session.
1067 * @param initialtime Time at which to evaluate the function.
1068 * @param dumpInitialConditions Write the initial condition to file?
1069 */
1071 [[maybe_unused]] NekDouble initialtime, bool dumpInitialConditions,
1072 const int domain)
1073{
1074 if (m_session->GetComm()->GetRank() == 0)
1075 {
1076 cout << "Initial Conditions:" << endl;
1077 }
1078
1079 if (m_session->DefinesFunction("InitialConditions"))
1080 {
1081 GetFunction("InitialConditions")
1082 ->Evaluate(m_session->GetVariables(), m_fields, m_time, domain);
1083 // Enforce C0 Continutiy of initial condiiton
1086 {
1087 for (int i = 0; i < m_fields.size(); ++i)
1088 {
1089 m_fields[i]->LocalToGlobal();
1090 m_fields[i]->GlobalToLocal();
1091 m_fields[i]->BwdTrans(m_fields[i]->GetCoeffs(),
1092 m_fields[i]->UpdatePhys());
1093 }
1094 }
1095
1096 if (m_session->GetComm()->GetRank() == 0)
1097 {
1098 for (int i = 0; i < m_fields.size(); ++i)
1099 {
1100 std::string varName = m_session->GetVariable(i);
1101 cout << " - Field " << varName << ": "
1102 << GetFunction("InitialConditions")
1103 ->Describe(varName, domain)
1104 << endl;
1105 }
1106 }
1107 }
1108 else
1109 {
1110 int nq = m_fields[0]->GetNpoints();
1111 for (int i = 0; i < m_fields.size(); i++)
1112 {
1113 Vmath::Zero(nq, m_fields[i]->UpdatePhys(), 1);
1114 m_fields[i]->SetPhysState(true);
1115 Vmath::Zero(m_fields[i]->GetNcoeffs(), m_fields[i]->UpdateCoeffs(),
1116 1);
1117 if (m_session->GetComm()->GetRank() == 0)
1118 {
1119 cout << " - Field " << m_session->GetVariable(i)
1120 << ": 0 (default)" << endl;
1121 }
1122 }
1123 }
1124
1125 if (dumpInitialConditions && m_checksteps && m_nchk == 0 &&
1126 !m_comm->IsParallelInTime())
1127 {
1129 }
1130 else if (dumpInitialConditions && m_nchk == 0 && m_comm->IsParallelInTime())
1131 {
1132 std::string newdir = m_sessionName + ".pit";
1133 if (!fs::is_directory(newdir))
1134 {
1135 fs::create_directory(newdir);
1136 }
1137 if (m_comm->GetTimeComm()->GetRank() == 0)
1138 {
1139 WriteFld(newdir + "/" + m_sessionName + "_0.fld");
1140 }
1141 }
1142 ++m_nchk;
1143}
1144
1145/**
1146 *
1147 */
1149 Array<OneD, NekDouble> &outfield,
1150 const NekDouble time)
1151{
1152 ASSERTL0(outfield.size() == m_fields[field]->GetNpoints(),
1153 "ExactSolution array size mismatch.");
1154 Vmath::Zero(outfield.size(), outfield, 1);
1155 if (m_session->DefinesFunction("ExactSolution"))
1156 {
1157 GetFunction("ExactSolution")
1158 ->Evaluate(m_session->GetVariable(field), outfield, time);
1159 }
1160}
1161
1162/**
1163 * By default, nothing needs initialising at the EquationSystem level.
1164 */
1165void EquationSystem::v_DoInitialise([[maybe_unused]] bool dumpInitialConditions)
1166{
1167}
1168
1169/**
1170 *
1171 */
1173{
1174}
1175
1176/**
1177 * Virtual function to define if operator in DoSolve is
1178 * negated with regard to the strong form. This is currently
1179 * only used in Arnoldi solves. Default is false.
1180 */
1182{
1183 return false;
1184}
1185
1186/**
1187 *
1188 */
1192
1193/**
1194 *
1195 */
1199
1200/// Virtual function for generating summary information.
1205
1206/**
1207 * Write the field data to file. The file is named according to the
1208 * session name with the extension .fld appended.
1209 */
1211{
1212 if (!m_comm->IsParallelInTime())
1213 {
1214 // Serial-in-time
1215 WriteFld(m_sessionName + ".fld");
1216 }
1217 else
1218 {
1219 // Parallel-in-time
1220 std::string newdir = m_sessionName + ".pit";
1221 if (!fs::is_directory(newdir))
1222 {
1223 fs::create_directory(newdir);
1224 }
1225 WriteFld(newdir + "/" + m_sessionName + "_" +
1226 std::to_string(m_windowPIT * m_comm->GetTimeComm()->GetSize() +
1227 m_comm->GetTimeComm()->GetRank() + 1) +
1228 ".fld");
1229 }
1230}
1231
1232/**
1233 * Zero the physical fields.
1234 */
1236{
1237 for (int i = 0; i < m_fields.size(); i++)
1238 {
1239 Vmath::Zero(m_fields[i]->GetNpoints(), m_fields[i]->UpdatePhys(), 1);
1240 }
1241}
1242
1243/**
1244 * FwdTrans the m_fields members
1245 */
1247{
1248 for (int i = 0; i < m_fields.size(); i++)
1249 {
1250 m_fields[i]->FwdTrans(m_fields[i]->GetPhys(),
1251 m_fields[i]->UpdateCoeffs());
1252 m_fields[i]->SetPhysState(false);
1253 }
1254}
1255
1256/**
1257 * Write the n-th checkpoint file.
1258 * @param n The index of the checkpoint file.
1259 */
1261{
1262 if (!m_comm->IsParallelInTime())
1263 {
1264 // Serial-in-time
1265 std::string outname = m_sessionName + "_" + std::to_string(n);
1266 WriteFld(outname + ".chk");
1267 }
1268 else
1269 {
1270 // Parallel-in-time
1271 auto loc = m_sessionName.find("_xml/");
1272 auto sessionName = m_sessionName.substr(0, loc);
1273 std::string paradir =
1274 sessionName + "_" + std::to_string(m_iterPIT) + ".pit";
1275 if (!fs::is_directory(paradir))
1276 {
1277 fs::create_directory(paradir);
1278 }
1279 std::string outname = paradir + "/" + sessionName + "_timeLevel" +
1280 std::to_string(m_session->GetTimeLevel()) + "_" +
1281 std::to_string(n);
1282 WriteFld(outname + ".chk");
1283 }
1284}
1285
1286/**
1287 * Write the n-th checkpoint file.
1288 * @param n The index of the checkpoint file.
1289 */
1291 const int n, MultiRegions::ExpListSharedPtr &field,
1292 std::vector<Array<OneD, NekDouble>> &fieldcoeffs,
1293 std::vector<std::string> &variables)
1294{
1295 if (!m_comm->IsParallelInTime())
1296 {
1297 // Serial-in-time
1298 std::string outname = m_sessionName + "_" + std::to_string(n);
1299 WriteFld(outname, field, fieldcoeffs, variables);
1300 }
1301 else
1302 {
1303 ASSERTL0(false, "Not Implemented for Parallel-in-Time");
1304 }
1305}
1306
1307/**
1308 * Write the n-th base flow into a .chk file
1309 * @param n The index of the base flow file.
1310 */
1312{
1313 std::string outname = m_sessionName + "_BaseFlow_" + std::to_string(n);
1314
1315 WriteFld(outname + ".chk");
1316}
1317
1318/**
1319 * Writes the field data to a file with the given filename.
1320 * @param outname Filename to write to.
1321 */
1322void EquationSystem::WriteFld(const std::string &outname)
1323{
1324 std::vector<Array<OneD, NekDouble>> fieldcoeffs(m_fields.size());
1325 std::vector<std::string> variables(m_fields.size());
1326
1327 for (int i = 0; i < m_fields.size(); ++i)
1328 {
1329 if (m_fields[i]->GetNcoeffs() == m_fields[0]->GetNcoeffs())
1330 {
1331 fieldcoeffs[i] = m_fields[i]->UpdateCoeffs();
1332 }
1333 else
1334 {
1335 fieldcoeffs[i] = Array<OneD, NekDouble>(m_fields[0]->GetNcoeffs());
1336 m_fields[0]->ExtractCoeffsToCoeffs(
1337 m_fields[i], m_fields[i]->GetCoeffs(), fieldcoeffs[i]);
1338 }
1339 variables[i] = m_boundaryConditions->GetVariable(i);
1340 }
1341
1342 ExtraFldOutput(fieldcoeffs, variables);
1343
1344 WriteFld(outname, m_fields[0], fieldcoeffs, variables);
1345}
1346
1347/**
1348 * Writes the field data to a file with the given filename.
1349 * @param outname Filename to write to.
1350 * @param field ExpList on which data is based.
1351 * @param fieldcoeffs An array of array of expansion coefficients.
1352 * @param variables An array of variable names.
1353 */
1354void EquationSystem::WriteFld(const std::string &outname,
1356 std::vector<Array<OneD, NekDouble>> &fieldcoeffs,
1357 std::vector<std::string> &variables)
1358{
1359 std::vector<LibUtilities::FieldDefinitionsSharedPtr> FieldDef =
1360 field->GetFieldDefinitions();
1361 std::vector<std::vector<NekDouble>> FieldData(FieldDef.size());
1362
1363 // Copy Data into FieldData and set variable
1364 for (int j = 0; j < fieldcoeffs.size(); ++j)
1365 {
1366 for (int i = 0; i < FieldDef.size(); ++i)
1367 {
1368 // Could do a search here to find correct variable
1369 FieldDef[i]->m_fields.push_back(variables[j]);
1370 field->AppendFieldData(FieldDef[i], FieldData[i], fieldcoeffs[j]);
1371 }
1372 }
1373
1374 // Update time in field info if required
1375 if (m_fieldMetaDataMap.find("Time") != m_fieldMetaDataMap.end())
1376 {
1377 m_fieldMetaDataMap["Time"] = boost::lexical_cast<std::string>(m_time);
1378 }
1379
1380 // Update step in field info if required
1381 if (m_fieldMetaDataMap.find("ChkFileNum") != m_fieldMetaDataMap.end())
1382 {
1383 m_fieldMetaDataMap["ChkFileNum"] = std::to_string(m_nchk);
1384 }
1385
1386 // If necessary, add mapping information to metadata
1387 // and output mapping coordinates
1389 fields[0] = field;
1393 mapping->Output(fieldMetaDataMap, outname);
1394
1395 // If necessary, add informaton for moving frame reference to metadata
1396 // X, Y, Z translational displacements
1397 // Theta_x, Theta_y, Theta_z angular displacements
1398 // U, V, W translational velocity
1399 // Omega_x, Omega_y, Omega_z angular velocity
1400 // A_x, A_y, A_z translational acceleration
1401 // DOmega_x, DOmega_y, DOmega_z angular acceleration
1402 // X0, Y0, Z0 pivot point
1403 for (size_t i = 0;
1404 i < m_strFrameData.size() && i < m_movingFrameData.size(); ++i)
1405 {
1406 fieldMetaDataMap[m_strFrameData[i]] =
1407 boost::lexical_cast<std::string>(m_movingFrameData[i]);
1408 }
1409
1410 m_fld->Write(outname, FieldDef, FieldData, fieldMetaDataMap,
1411 m_session->GetBackups());
1412}
1413
1414/**
1415 * Import field from infile and load into \a m_fields. This routine will
1416 * also perform a \a BwdTrans to ensure data is in both the physical and
1417 * coefficient storage.
1418 * @param infile Filename to read.
1419 */
1421 const std::string &infile,
1423{
1424 std::vector<LibUtilities::FieldDefinitionsSharedPtr> FieldDef;
1425 std::vector<std::vector<NekDouble>> FieldData;
1428 field_fld->Import(infile, FieldDef, FieldData);
1429
1430 // Copy FieldData into m_fields
1431 for (int j = 0; j < pFields.size(); ++j)
1432 {
1433 Vmath::Zero(pFields[j]->GetNcoeffs(), pFields[j]->UpdateCoeffs(), 1);
1434
1435 for (int i = 0; i < FieldDef.size(); ++i)
1436 {
1437 ASSERTL1(FieldDef[i]->m_fields[j] == m_session->GetVariable(j),
1438 std::string("Order of ") + infile +
1439 std::string(" data and that defined in "
1440 "m_boundaryconditions differs"));
1441
1442 pFields[j]->ExtractDataToCoeffs(FieldDef[i], FieldData[i],
1443 FieldDef[i]->m_fields[j],
1444 pFields[j]->UpdateCoeffs());
1445 }
1446 pFields[j]->BwdTrans(pFields[j]->GetCoeffs(), pFields[j]->UpdatePhys());
1447 }
1448}
1449
1450/**
1451 * Import field from infile and load into \a m_fields. This routine will
1452 * also perform a \a BwdTrans to ensure data is in both the physical and
1453 * coefficient storage.
1454 * @param infile Filename to read.
1455 * If optionan \a ndomains is specified it assumes we loop over nodmains
1456 * for each nvariables.
1457 */
1459 const std::string &infile,
1460 Array<OneD, MultiRegions::ExpListSharedPtr> &pFields, const int ndomains)
1461{
1462 std::vector<LibUtilities::FieldDefinitionsSharedPtr> FieldDef;
1463 std::vector<std::vector<NekDouble>> FieldData;
1464
1465 LibUtilities::Import(infile, FieldDef, FieldData);
1466
1467 int nvariables = GetNvariables();
1468
1469 ASSERTL0(
1470 ndomains * nvariables == pFields.size(),
1471 "Number of fields does not match the number of variables and domains");
1472
1473 // Copy FieldData into m_fields
1474 for (int j = 0; j < ndomains; ++j)
1475 {
1476 for (int i = 0; i < nvariables; ++i)
1477 {
1478 Vmath::Zero(pFields[j * nvariables + i]->GetNcoeffs(),
1479 pFields[j * nvariables + i]->UpdateCoeffs(), 1);
1480
1481 for (int n = 0; n < FieldDef.size(); ++n)
1482 {
1483 ASSERTL1(FieldDef[n]->m_fields[i] == m_session->GetVariable(i),
1484 std::string("Order of ") + infile +
1485 std::string(" data and that defined in "
1486 "m_boundaryconditions differs"));
1487
1488 pFields[j * nvariables + i]->ExtractDataToCoeffs(
1489 FieldDef[n], FieldData[n], FieldDef[n]->m_fields[i],
1490 pFields[j * nvariables + i]->UpdateCoeffs());
1491 }
1492 pFields[j * nvariables + i]->BwdTrans(
1493 pFields[j * nvariables + i]->GetCoeffs(),
1494 pFields[j * nvariables + i]->UpdatePhys());
1495 }
1496 }
1497}
1498
1499/**
1500 * Import field from infile and load into \a pField. This routine will
1501 * also perform a \a BwdTrans to ensure data is in both the physical and
1502 * coefficient storage.
1503 */
1504void EquationSystem::ImportFld(const std::string &infile,
1506 std::string &pFieldName)
1507{
1508 std::vector<LibUtilities::FieldDefinitionsSharedPtr> FieldDef;
1509 std::vector<std::vector<NekDouble>> FieldData;
1510
1513 field_fld->Import(infile, FieldDef, FieldData);
1514 int idx = -1;
1515
1516 Vmath::Zero(pField->GetNcoeffs(), pField->UpdateCoeffs(), 1);
1517
1518 for (int i = 0; i < FieldDef.size(); ++i)
1519 {
1520 // find the index of the required field in the file.
1521 for (int j = 0; j < FieldData.size(); ++j)
1522 {
1523 if (FieldDef[i]->m_fields[j] == pFieldName)
1524 {
1525 idx = j;
1526 }
1527 }
1528 ASSERTL1(idx >= 0, "Field " + pFieldName + " not found.");
1529
1530 pField->ExtractDataToCoeffs(FieldDef[i], FieldData[i],
1531 FieldDef[i]->m_fields[idx],
1532 pField->UpdateCoeffs());
1533 }
1534 pField->BwdTrans(pField->GetCoeffs(), pField->UpdatePhys());
1535}
1536
1537/**
1538 * Import field from infile and load into the array \a coeffs.
1539 *
1540 * @param infile Filename to read.
1541 * @param fieldStr an array of string identifying fields to be imported
1542 * @param coeffs array of array of coefficients to store imported data
1543 */
1544void EquationSystem::ImportFld(const std::string &infile,
1545 std::vector<std::string> &fieldStr,
1547{
1548
1549 ASSERTL0(fieldStr.size() <= coeffs.size(),
1550 "length of fieldstr should be the same as coeffs");
1551
1552 std::vector<LibUtilities::FieldDefinitionsSharedPtr> FieldDef;
1553 std::vector<std::vector<NekDouble>> FieldData;
1554
1557 field_fld->Import(infile, FieldDef, FieldData);
1558
1559 // Copy FieldData into m_fields
1560 for (int j = 0; j < fieldStr.size(); ++j)
1561 {
1562 Vmath::Zero(coeffs[j].size(), coeffs[j], 1);
1563 for (int i = 0; i < FieldDef.size(); ++i)
1564 {
1565 m_fields[0]->ExtractDataToCoeffs(FieldDef[i], FieldData[i],
1566 fieldStr[j], coeffs[j]);
1567 }
1568 }
1569}
1570
1571/**
1572 * Write out a summary of the session data.
1573 * @param out Output stream to write data to.
1574 */
1576{
1577 if (m_session->DefinesSolverInfo("EQTYPE"))
1578 {
1579 AddSummaryItem(s, "EquationType", m_session->GetSolverInfo("EQTYPE"));
1580 }
1581 AddSummaryItem(s, "Session Name", m_sessionName);
1582 AddSummaryItem(s, "Spatial Dim.", m_spacedim);
1583 AddSummaryItem(s, "Max SEM Exp. Order",
1584 m_fields[0]->EvalBasisNumModesMax());
1585
1586 if (m_session->GetComm()->GetSize() > 1)
1587 {
1588 AddSummaryItem(s, "Num. Processes", m_session->GetComm()->GetSize());
1589 }
1590
1592 {
1593 AddSummaryItem(s, "Quasi-3D", "Homogeneous in z-direction");
1594 AddSummaryItem(s, "Expansion Dim.", m_expdim + 1);
1595 AddSummaryItem(s, "Num. Hom. Modes (z)", m_npointsZ);
1596 AddSummaryItem(s, "Hom. length (LZ)", m_LhomZ);
1597 AddSummaryItem(s, "FFT Type", m_useFFT ? "FFTW" : "MVM");
1598 if (m_halfMode)
1599 {
1600 AddSummaryItem(s, "ModeType", "Half Mode");
1601 }
1602 else if (m_singleMode)
1603 {
1604 AddSummaryItem(s, "ModeType", "Single Mode");
1605 }
1606 else if (m_multipleModes)
1607 {
1608 AddSummaryItem(s, "ModeType", "Multiple Modes");
1609 }
1610 }
1612 {
1613 AddSummaryItem(s, "Quasi-3D", "Homogeneous in yz-plane");
1614 AddSummaryItem(s, "Expansion Dim.", m_expdim + 2);
1615 AddSummaryItem(s, "Num. Hom. Modes (y)", m_npointsY);
1616 AddSummaryItem(s, "Num. Hom. Modes (z)", m_npointsZ);
1617 AddSummaryItem(s, "Hom. length (LY)", m_LhomY);
1618 AddSummaryItem(s, "Hom. length (LZ)", m_LhomZ);
1619 AddSummaryItem(s, "FFT Type", m_useFFT ? "FFTW" : "MVM");
1620 }
1621 else
1622 {
1623 AddSummaryItem(s, "Expansion Dim.", m_expdim);
1624 }
1625
1626 if (m_session->DefinesSolverInfo("UpwindType"))
1627 {
1628 AddSummaryItem(s, "Riemann Solver",
1629 m_session->GetSolverInfo("UpwindType"));
1630 }
1631
1632 if (m_session->DefinesSolverInfo("AdvectionType"))
1633 {
1634 std::string AdvectionType;
1635 AdvectionType = m_session->GetSolverInfo("AdvectionType");
1637 s, "Advection Type",
1638 GetAdvectionFactory().GetClassDescription(AdvectionType));
1639 }
1640
1641 if (m_session->DefinesSolverInfo("DiffusionType"))
1642 {
1643 std::string DiffusionType;
1644 DiffusionType = m_session->GetSolverInfo("DiffusionType");
1646 s, "Diffusion Type",
1647 GetDiffusionFactory().GetClassDescription(DiffusionType));
1648 }
1649
1651 {
1652 AddSummaryItem(s, "Projection Type", "Continuous Galerkin");
1653 }
1655 {
1656 AddSummaryItem(s, "Projection Type", "Discontinuous Galerkin");
1657 }
1659 {
1660 AddSummaryItem(s, "Projection Type",
1661 "Mixed Continuous Galerkin and Discontinuous");
1662 }
1663}
1664
1665/**
1666 *
1667 */
1669{
1670 return Array<OneD, bool>(m_session->GetVariables().size(), false);
1671}
1672
1673/**
1674 *
1675 */
1677{
1678 ASSERTL0(false, "This function is not valid for the Base class");
1680 return null;
1681}
1682
1683/**
1684 *
1685 */
1687 [[maybe_unused]] std::vector<Array<OneD, NekDouble>> &fieldcoeffs,
1688 [[maybe_unused]] std::vector<std::string> &variables)
1689{
1690}
1691
1692} // namespace Nektar::SolverUtils
#define ASSERTL0(condition, msg)
#define WARNINGL0(condition, msg)
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode....
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:264
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:223
static std::shared_ptr< FieldIO > CreateDefault(const LibUtilities::SessionReaderSharedPtr session)
Returns an object for the default FieldIO method.
Definition FieldIO.cpp:194
Provides a generic Factory class.
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).
bool m_useFFT
Flag to determine if FFT is used for homogeneous transform.
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.
SOLVER_UTILS_EXPORT int GetTraceNpoints()
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.
SOLVER_UTILS_EXPORT int GetNpoints()
std::vector< std::string > m_strFrameData
variable name in m_movingFrameData
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[]
SOLVER_UTILS_EXPORT int GetNcoeffs()
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[]
SOLVER_UTILS_EXPORT int GetNumExpModes()
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.
SOLVER_UTILS_EXPORT void ExtraFldOutput(std::vector< Array< OneD, NekDouble > > &fieldcoeffs, std::vector< std::string > &variables)
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].
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 GetTotPoints()
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.
SpatialDomains::BoundaryConditionsSharedPtr m_boundaryConditions
Pointer to boundary conditions object.
Array< OneD, NekDouble > m_movingFrameData
Moving reference frame status in the inertial frame X, Y, Z, Theta_x, Theta_y, Theta_z,...
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()
virtual SOLVER_UTILS_EXPORT NekDouble v_H1Error(unsigned int field, const Array< OneD, NekDouble > &exactsoln=NullNekDouble1DArray, bool Normalised=false)
Virtual function for the H_1 error computation between fields and a given exact solution.
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)
SOLVER_UTILS_EXPORT int GetNvariables()
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:57
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:287
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:131
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
std::shared_ptr< ExpList > ExpListSharedPtr
Shared pointer to an ExpList object.
std::shared_ptr< ContField > ContFieldSharedPtr
Definition ContField.h:278
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:186
std::shared_ptr< MeshGraph > MeshGraphSharedPtr
Definition MeshGraph.h:217
std::map< int, ExpansionInfoShPtr > ExpansionInfoMap
Definition MeshGraph.h:184
NekMatrix< NekMatrix< NekMatrix< NekDouble, StandardMatrixTag >, ScaledMatrixTag >, BlockMatrixTag > DNekScalBlkMat
NekMatrix< NekMatrix< NekDouble, StandardMatrixTag >, ScaledMatrixTag > DNekScalMat
void Zero(int n, T *x, const int incx)
Zero vector.
Definition Vmath.hpp:273
STL namespace.
scalarT< T > sqrt(scalarT< T > in)
Definition scalar.hpp:290
Used to lookup the create function in NekManager.
Definition MatrixKey.h:69