MAIA bb96820c
Multiphysics at AIA
Loading...
Searching...
No Matches
dgcartesiansolver.h
Go to the documentation of this file.
1// Copyright (C) 2024 The m-AIA AUTHORS
2//
3// This file is part of m-AIA (https://git.rwth-aachen.de/aia/m-AIA/m-AIA)
4//
5// SPDX-License-Identifier: LGPL-3.0-only
6
7#ifndef DGSOLVER_H_
8#define DGSOLVER_H_
9
10#include <array>
11#include <memory>
12#include <vector>
14#include "GRID/cartesiangrid.h"
15#include "POST/postprocessing.h"
16#include "POST/samplingdata.h"
17#include "cartesiansolver.h"
20#include "dgcartesiangridmap.h"
23#include "dgcartesianslices.h"
24#include "dgcartesiansponge.h"
26#include "dgcartesiantimers.h"
27#include "filter.h"
29
30template <MInt nDim, class SysEqn>
32template <MInt nDim, class SysEqn>
34template <MInt nDim, class SysEqn>
35class CouplingDg;
36template <MInt nDim, class CouplingX>
37class CouplingDgApe;
38template <MInt nDim, class SysEqn>
40template <MInt nDim, class ppType>
41class PostProcessing;
42
43template <MInt nDim, class SysEqn>
44class DgCartesianSolver : public maia::CartesianSolver<nDim, DgCartesianSolver<nDim, SysEqn>> {
45 friend class DgBoundaryCondition<nDim, SysEqn>;
46 template <MInt nDim_, class CouplingX>
47 friend class CouplingDgApe;
48 friend class DgCcAcousticPerturb<nDim, SysEqn>;
49 friend class CouplingDg<nDim, SysEqn>;
50 friend class DgSlices<nDim, SysEqn>;
51 friend class maia::CartesianSolver<nDim, DgCartesianSolver<nDim, SysEqn>>;
52 template <MInt nDim_, class ppType>
53 friend class PostProcessing;
54
55 // Types
56 private:
62
63 public:
66 using Grid = typename CartesianSolver::Grid;
67 using GridProxy = typename CartesianSolver::GridProxy;
68 using CartesianSolver::disableDlbTimers;
69 using CartesianSolver::domainId;
70 using CartesianSolver::enableDlbTimers;
71 using CartesianSolver::getIdentifier;
72 using CartesianSolver::grid;
73 using CartesianSolver::isActive;
74 using CartesianSolver::m_restart;
75 using CartesianSolver::m_restartInterval;
76 using CartesianSolver::m_restartTimeStep;
77 using CartesianSolver::m_solutionInterval;
78 using CartesianSolver::m_solverId;
79 using CartesianSolver::m_useNonSpecifiedRestartFile;
80 using CartesianSolver::mpiComm;
81 using CartesianSolver::noDomains;
82 using CartesianSolver::outputDir;
83 using CartesianSolver::readSolverSamplingVarNames;
84 using CartesianSolver::restartDir;
85 using CartesianSolver::returnIdleRecord;
86 using CartesianSolver::returnLoadRecord;
87 using CartesianSolver::solverId;
88 using CartesianSolver::startLoadTimer;
89 using CartesianSolver::stopLoadTimer;
90 using CartesianSolver::updateDomainInfo;
91
92 // Type for cell properties
94
95 // Methods
96 public:
97 DgCartesianSolver(const MInt solverId, GridProxy& gridProxy_, Geometry<nDim>& geometry_, const MPI_Comm comm);
98 ~DgCartesianSolver() override;
99 void run();
100 MInt getCurrentTimeStep() const override { return m_timeStep; }
102 void forceTimeStep(const MFloat dt) {
103 m_externalDt = dt;
104 if(m_restart) {
105 // m_dt is only updated via calcTimeStep(), not necessarily at a restart
107 }
108 }
109
110 // STUBS required after method removal
111 MFloat time() const override { return m_time; }
112 MInt noVariables() const override { return SysEqn::noVars(); }
113
114 void loadSampleVariables(MInt timeStep) {
115 std::cerr << "loadSampleVariables DgCartesianSolver " << timeStep << std::endl;
116 };
117 void getSampleVariables(MInt cellId, const MFloat*& vars) {
118 std::cerr << "getSampleVariables DgCartesianSolver " << cellId << " " << vars << std::endl;
119 };
120 void getSampleVariables(const MInt cellId, std::vector<MFloat>& /*vars*/) {
121 std::cerr << "getSampleVariables DgCartesianSolver " << cellId << std::endl;
122 };
123 void calculateHeatRelease() { std::cerr << "calculateHeatRelease DgCartesianSolver " << std::endl; }
124 void getHeatRelease(MFloat*& heatRelease) {
125 std::cerr << "getHeatRelease DgCartesianSolver " << heatRelease << std::endl;
126 }
127
129 constexpr const Geom& geometry() const { return m_geometry; }
130
131 private:
133
135 Geom& geometry() { return m_geometry; }
136
137 public:
138 // These methods are necessary for the postprocessing solver to work
139 const MFloat& a_coordinate(const MInt cellId, const MInt dim) const { return grid().tree().coordinate(cellId, dim); }
140 MInt a_noCells() const { TERMM(1, "Make this function return something meaningful in future!"); }
141 MInt a_hasNeighbor(const MInt cellId, const MInt dir) const { return grid().tree().hasNeighbor(cellId, dir); }
142 MInt a_level(const MInt) const { TERMM(1, "Make this function return something meaningful in future!"); }
143
144 private:
145 // Constructor methods
147 void initTimers();
151
152 // Initialization methods for the solver
153 public:
154 void initSolver() override;
155 void finalizeInitSolver() override;
156
157 private:
158 void initGridMap();
159 void loadGridMap(const MString& gridMapFileName);
160 void checkGridMap(const MString& donorGridFileName);
161 void initElements();
162 MBool needElementForCell(const MInt cellId);
164 MBool pointIsInside(const MFloat* const coordinates);
165 void createElement(const MInt cellId);
167 void initInterpolation();
168 void initNodeCoordinates();
169 void initJacobian();
170 void checkCellProperties();
171 std::array<MInt, 2 * nDim> getBoundaryConditionIds(const MInt cellId);
172 void initSurfaces();
173 MInt initBoundarySurface(const MInt elementId, const MInt dir);
174 MInt initInnerSurface(const MInt elementId, const MInt dir);
175 MInt initMpiSurface(const MInt elementId, const MInt dir);
176 MBool hasSurface(const MInt elementId, const MInt dir);
177 MInt createSurface(const MInt elementId, const MInt dir, MInt nghbrId = -1);
178 void calcSurfaceNodeCoordinates(const MInt surfaceId);
179 void calcElementNodeCoordinates(const MInt elementId);
180 void initMpiExchange();
181 void updateNodeVariables();
182 void extendNodeVariables();
183 void extendNodeVariablesSingleDirection(const MInt extendDir, const MFloat extendOffset, const MFloat extendLimit);
184 void updateNodeVariablesSingleElement(const MInt elementId,
185 const MInt extendDir,
186 MIntTensor hForwardSurfaceId,
187 MIntTensor hReverseSurfaceId,
188 std::vector<MBool>& cellHasUpdatedMeans,
189 std::vector<MInt>& SurfaceWantsToMPISend,
190 MBool& noMoreUpdates);
192 void initSolverObjects();
193 void initData();
194 void initMainLoop();
195
196 // Methods for handling elements and cells
197 private:
198 MInt getLevelByElementId(const MInt elementId);
199 // MInt getLevelOfNeighborElement(const MInt elementId, const MInt dir);
200 MInt getLevelOfDirectNeighborCell(const MInt cellId, const MInt dir);
201 MBool hasNeighborCell(const MInt elementId, const MInt dir);
202 // MBool hasNeighborElement(const MInt elementId, const MInt dir);
203 MBool isMpiSurface(const MInt id) const;
206 void writeEOC();
207 MInt getHElementId(const MInt elementId) const;
208
209 // Finalization methods for the solver
210 public:
211 void cleanUp() override;
212
213 private:
214 void finalizeMpiExchange();
215
216 // Initialization methods for the solution
217 virtual void initialCondition();
218 void outputInitSummary();
219
220 // Input/output
221 void saveSolutionFile();
222 void saveSolutionFile(const MString& suffix);
223 virtual void saveRestartFile();
224 void loadRestartFile() override;
225 void saveNodalData(const MString& fileNameBase,
226 const MInt noVars,
227 const std::vector<MString>& varNames,
228 const MFloat* const data) const;
229 void saveNodeVarsFile();
230 void loadNodeVarsFile();
231 MString getRestartFileName(const MInt timeStep, const MInt useNonSpecifiedRestartFile);
232
233 // Physical properties and system of equations
234 // Method to create new boundary condition
235 BC make_bc(MInt bcId);
236
237 // Main DG discretization methods
238 void calcDgTimeDerivative(const MFloat t, const MFloat tStage);
239 void prolongToSurfaces();
240 void prolongToSurfaces(const MInt begin, const MInt end);
242 void calcVolumeIntegral();
243 template <class F>
244 void calcVolumeIntegral(const MInt noElements, ElementCollector& elem, F& fluxFct);
247 void calcMpiSurfaceFlux();
248 template <class F>
249 void calcRegularSurfaceFlux(const MInt begin, const MInt end, SurfaceCollector& surf, F& riemannFct);
250 void calcSurfaceIntegral();
251 void calcSurfaceIntegral(const MInt begin, const MInt end, ElementCollector& elem, SurfaceCollector& surf,
252 HElementCollector& helem, const MInt noHElements);
253 void applySurfaceIntegral(MFloat* rhs, const MInt polyDeg, const MInt noNodes1D, const MInt srfcId, const MInt side,
254 const MFloat* flux, SurfaceCollector& surf);
255 void applyJacobian();
256 void applyJacobian(const MInt noElements, ElementCollector& elem);
257 void calcSourceTerms(MFloat t);
258 template <class F>
259 void calcSourceTerms(MFloat t, const MInt noElements, ElementCollector& elem, F& sourceFct);
261
262 // Parallelization
263 MBool isMpiRoot() const;
264 MBool hasMpiExchange() const;
267 void cancelMpiRequests() override;
268
269 // Time integration
270 public:
271 // methods for NEW unified run loop
272 void preTimeStep() override;
273 MBool solutionStep() override;
274 void postTimeStep();
275 // DG-Solver is converged if the final time is reached
277
278 void saveSolverSolution(const MBool forceOutput, const MBool finalTimeStep) override;
279 void writeRestartFile(const MBool writeRestart, const MBool writeBackup, const MString gridFileName,
280 MInt* recalcIdTree) override;
281 MBool prepareRestart(MBool, MBool&) override;
282 virtual void reIntAfterRestart(MBool){};
283
284 // TODO labels:DG dummy functions that are required to allow adaptation for another solver in a multisolver
285 // computation without changing the grid for the DG solver
287 // Note: resize with current tree size since the number of cells should not change
288 grid().resizeGridMap(grid().tree().size());
289 }
290 void swapProxy(const MInt cellId0, const MInt cellId1) { grid().swapGridIds(cellId0, cellId1); }
291
292 void prepareAdaptation() override{};
293 void setSensors(std::vector<std::vector<MFloat>>& NotUsed(sensors),
294 std::vector<MFloat>& NotUsed(sensorWeight),
295 std::vector<std::bitset<64>>& NotUsed(sensorCellFlag),
296 std::vector<MInt>& NotUsed(sensorSolverId)) override{};
297 void postAdaptation() override{};
298 void finalizeAdaptation() override {
299 // TODO labels:DG,GRID check this, previously in reinitAfterAdaptation()
300 grid().updateOther();
302 };
303
304
305 MBool step(const MFloat externalDt = -std::numeric_limits<MFloat>::infinity(), const MBool substep = false);
306
308
310
312 MInt getCellIdByIndex(const MInt index) { return m_elements.cellId(index); }
313
315 MInt getIdAtPoint(const MFloat* point, const MBool globalUnique = false) {
316 return getElementIdAtPoint(point, globalUnique);
317 }
318
319 void calcSamplingVarAtPoint(const MFloat* point, const MInt elementId, const MInt sampleVarId, MFloat* state,
320 const MBool interpolate) override;
321 void getSolverSamplingProperties(std::vector<MInt>& samplingVarIds, std::vector<MInt>& noSamplingVars,
322 std::vector<std::vector<MString>>& samplingVarNames,
323 const MString featureName = "") override;
324
325 // Sampling functions which have nothing to do for the DG solver at the moment
326 virtual void initSolverSamplingVariables(const std::vector<MInt>& NotUsed(varIds),
327 const std::vector<MInt>& NotUsed(noSamplingVars)){};
328 virtual void initInterpolationForCell(const MInt NotUsed(cellId)){};
329 virtual void calcSamplingVariables(const std::vector<MInt>& NotUsed(varIds), const MBool NotUsed(exchange)){};
330
331 private:
332 void timeStepRk(const MFloat t, const MFloat dt, const MInt substep = -1);
333 void subTimeStepRk(const MFloat dt, const MInt stage, const MInt totalSize, const MFloat* const rhs,
334 MFloat* const variables, MFloat* const timeIntStorage);
335 void analyzeTimeStep(MFloat t, MFloat runTimeRelative, MFloat runTimeTotal, MInt timeStep, MFloat dt);
336 void calcErrorNorms(const MFloat t, std::vector<MFloat>& L2Error, std::vector<MFloat>& LInfError,
337 std::vector<MFloat>& L2ErrLocal, std::vector<MFloat>& LInfErrLocal);
338 virtual void resetRHS();
340 void resetBuffer(const MInt totalSize, MFloat* const buffer);
341
342 // Post-Processing
343 // MInt getCellIdAtPoint(const MFloat* point);
344 MInt getElementIdAtPoint(const MFloat* point, MBool globalUnique = false);
345 MBool calcStateAtPoint(const MFloat* point, MFloat* state);
346 void calcStateAtPoint(const MFloat* point, const MInt elementId, MFloat* state);
347 void calcStateAtPoint(const MFloat* point, const MInt elementId, const MInt noVars, const MFloat* const u,
348 MFloat* state);
349 // MBool calcNodeVarsAtPoint(const MFloat* point, MFloat* nodeVars);
350 // void
351 // calcNodeVarsAtPoint(const MFloat* const point, const MInt elementId,
352 // MFloat* const nodeVars);
353
354
355 public:
356 MInt noInternalCells() const override { return grid().noInternalCells(); }
357
358 private:
359 // Sponge
361 MBool useSponge() const { return m_useSponge; }
362
363 // H/p-refinement
365 void initPrefinement();
366 template <MBool forward, MInt noVars>
367 void calcMortarProjectionH(const MInt srfcId, const MInt dir, MFloat* source, MFloat* destination,
369 template <MBool forward, MInt noVars>
370 void calcMortarProjectionP(const MInt srfcId, const MInt dir, MFloat* source, MFloat* destination,
372 template <MBool forward, MInt noVars>
373 void calcMortarProjection(const MInt srfcId, const MInt dir, MFloat* source, MFloat* destination,
375 template <MBool forward>
376 MFloat* mortarP(const MInt sourcePolyDeg, const MInt targetPolyDeg);
377 template <MBool forward>
378 MFloat* mortarH(const MInt polyDeg, const MInt position);
380 void adaptiveRefinement(const MInt timeStep);
381 void calcErrorEstimate(std::vector<MFloat>& errorEstimate);
382 void interpolateElement(const MInt elementId, const MInt newPolyDeg);
383 MBool hasAdaptivePref() const;
384 MBool needHElementForCell(const MInt cellId);
385 void createHElement(const MInt cellId);
386 void initHElements();
387 MInt createHMPISurfaces(const MInt elementId, const MInt dir);
388 MBool hasPref() const;
389 MBool isAdaptationTimeStep(const MInt timeStep) const;
390
391
392 public:
393 // Dynamic load balancing
394 void resetSolver() override;
395 void setCellWeights(MFloat* solverCellWeight) override;
396
397 // Partitioning
398 MInt noLoadTypes() const override;
399 void getDefaultWeights(MFloat* weights, std::vector<MString>& names) const;
400 void getLoadQuantities(MInt* const loadQuantities) const override;
401 MFloat getCellLoad(const MInt cellId, const MFloat* const weights) const override;
402
403 void balance(const MInt* const NotUsed(noCellsToReceiveByDomain),
404 const MInt* const NotUsed(noCellsToSendByDomain),
405 const MInt* const NotUsed(targetDomainsByCell),
406 const MInt NotUsed(oldNoCells)) override {
407 TERMM(1, "Use split balancing methods for DG solver instead of balance().");
408 };
409 // DG solver requires the balancing to be split into separate methods
410 MBool hasSplitBalancing() const override { return 1; }
411 void balancePre() override;
412 void balancePost() override;
413 void finalizeBalance() override{};
414
415 void localToGlobalIds() override;
416 void globalToLocalIds() override;
417
419 MInt noCellDataDlb() const override {
420 if(grid().isActive()) {
422 } else {
423 return 0;
424 }
425 };
426 MInt cellDataTypeDlb(const MInt dataId) const override;
427 MInt cellDataSizeDlb(const MInt dataId, const MInt cellId) override;
428 template <typename dataType>
429 void getCellDataDlb_(const MInt dataId, const MInt oldNoCells, const MInt* const bufferIdToCellId,
430 dataType* const data);
431 void getCellDataDlb(const MInt dataId, const MInt oldNoCells, const MInt* const bufferIdToCellId,
432 MInt* const data) override {
433 getCellDataDlb_(dataId, oldNoCells, bufferIdToCellId, data);
434 };
435 void getCellDataDlb(const MInt dataId, const MInt oldNoCells, const MInt* const bufferIdToCellId,
436 MFloat* const data) override {
437 getCellDataDlb_(dataId, oldNoCells, bufferIdToCellId, data);
438 };
439 template <typename dataType>
440 void setCellDataDlb_(const MInt dataId, const dataType* const data);
441 void setCellDataDlb(const MInt dataId, const MInt* const data) override { setCellDataDlb_(dataId, data); };
442 void setCellDataDlb(const MInt dataId, const MFloat* const data) override { setCellDataDlb_(dataId, data); };
443
444 void getGlobalSolverVars(std::vector<MFloat>& NotUsed(globalFloatVars),
445 std::vector<MInt>& NotUsed(globalIntVars)) override;
446 void setGlobalSolverVars(std::vector<MFloat>& NotUsed(globalFloatVars),
447 std::vector<MInt>& NotUsed(globalIdVars)) override;
448
449 MInt noSolverTimers(const MBool allTimings) override {
450#ifdef MAIA_TIMER_FUNCTION
451 if(allTimings) {
452 return 28;
453 } else {
454 return 5;
455 }
456#else
457 return 2;
458#endif
459 }
460
461 void getSolverTimings(std::vector<std::pair<MString, MFloat>>& solverTimings, const MBool allTimings) override;
462 void getDomainDecompositionInformation(std::vector<std::pair<MString, MInt>>& domainInfo) override;
463
464 private:
466
469 MInt count = 0;
470 for(auto&& bc : m_boundaryConditions) {
471 count += bc->noCellDataDlb();
472 }
473 return count;
474 };
475
476 // DLB reinitialization stage
478
479 struct CellData;
480
481 static const std::array<MInt, CellData::count> s_cellDataTypeDlb;
482
483 // // void checkRhsForNan(MString tag);
484
485 // // // Member variables
486 // // //////////////////////////////////////////////////////////////////////////////
487 // // // RULES FOR DEFAULT MEMBER INITIALIZATION
488 //
489 // If the member is an aggregate and cannot be aggregate-initialized,
490 // value-initialize it (e.g. 'm_var()') in the member initializer list of the
491 // constructor(s).
492 // Else if there is a typical, sensible default value/constructor, use it.
493 // Else use a value for initialization that, if unchanged, leads to an early
494 // and deterministic abort so it can be detected and fixed immediately.
495 //
496 // REMINDER: Never leave a variable uninitialized!
498
499 // Flow control
500 // Current time step
502 // Total number of time steps
504 // Identify first time step
506 // Specify number of time steps between recalculation of m_dt
508 // Current Runge Kutta stage
510 // Number of Runge Kutta stages
512 // Time Integration Coefficient A
513 std::vector<MFloat> m_timeIntegrationCoefficientsA{};
514 // Time Integration Coefficient B
515 std::vector<MFloat> m_timeIntegrationCoefficientsB{};
516 // Time Integration Coefficient C
517 std::vector<MFloat> m_timeIntegrationCoefficientsC{};
518 // Identify if there are open MPI recv/send surface exchange requests
521
522 // Numerical properties
523 // SBP Mode
525 // SBP Operator
527 // Initial polynomial degree for all elements
529 // Minimum polynomial degree for all elements
531 // Maximum polynomial degree for all elements
533 // Initial number of nodes 1D for all elements
535 // Minimum number of nodes 1D for all elements
537 // Maximum number of nodes 1D for all elements
539 // Integration method for the DG method
541 // Time integration scheme for the DG method
543 // Polynomial type for the DG method
545 // Physical time at which to start calculations
547 // Physical time at which to end calculations
549 // Indicates if the final time step is reached
551 // Non-dimensional Courant-Friedrichs-Levy number
553
554 // Interpolation
555 // Interpolation information (access by polynomial degree and number of nodes)
556 std::vector<std::vector<DgInterpolation>> m_interpolation{};
557 // Global domain volume (needed for error norm calculations)
559 // Local domain volume (needed for error norm calculations)
561 // Specify whether to calculate error norms
563 // Specify number of time steps between performance output
564 /* MInt m_aliveInterval = -1; */
565 // Specify number of time steps between two analyses
567 // Number of nodes (1D) to use for error analysis
569 // Polynomial degree for error analysis
571 // Number of significant digits in error analysis output
573 // Interpolation information for error analysis
575 // Volume weights for error analysis
577 // Vandermonde matrices for error analysis (access by polynomial degree
578 // and number of nodes of original solution)
579 std::vector<std::vector<MFloatTensor>> m_vdmAnalysis{};
580
581 // Parallelization
582 // Number of domains with which surface data needs to be exchanged
584 // Domain ids of neighbors with which surface data needs to be exchanged
585 std::vector<MInt> m_exchangeNghbrDomains{};
586 // Surface ids of MPI surfaces for each neighbor domain
587 std::vector<std::vector<MInt>> m_mpiSurfaces{};
588 // Surface ids of MPI surfaces for each neighbor domain for receiving (needed for periodic
589 // boundary conditions)
590 std::vector<std::vector<MInt>> m_mpiRecvSurfaces{};
591#ifdef DG_USE_MPI_BUFFERS
592 // Send buffers for each neighbor domain
593 std::vector<std::vector<MFloat>> m_sendBuffers{};
594 // Receive buffers for each neighbor domain
595 std::vector<std::vector<MFloat>> m_recvBuffers{};
596#endif
597#ifdef DG_USE_MPI_DERIVED_TYPES
598 // MPI datatypes for sending (access by neighbor domain id)
599 std::vector<MPI_Datatype> m_sendTypes{};
600 // MPI datatypes for receiving (access by neighbor domain id)
601 std::vector<MPI_Datatype> m_recvTypes{};
602#endif
603 // Send requests for each neighbor domain
604 std::vector<MPI_Request> m_sendRequests{};
605 // Receive requests for each neighbor domain
606 std::vector<MPI_Request> m_recvRequests{};
607
608 // If true, always save solution file after last time step
610 // If true, always save restart file after last time step
612 // If true, save node variables to solution/restart files
614 // Save time derivative
616 // Sponge eta will be included in data output
618 // How many minutes before the job ends a restart file should be written
620 // How often (timesteps) to check if an end autosave file should be written
622 // Update cell weights and min-cell workloads and save them to the grid file.
624 // Factor by which the DG contributions to the cell weights are scaled.
626 // Additional weight per DG element independent of the polynomial degree.
628 // Weight per cell
630 // Restore default cell weights in grid file.
632 // Save intial solution to solution file
634 // Save node vars to node vars file
636
637 // Auxiliary class for collecting and saving point data
639 // Auxiliary class for collecting and saving surface data
641 // Auxiliary class for collecting and saving volume data
643 // Auxiliary class for creating 2D slices from 3D simulations
645
646 // Grid map
647 // Offsets to donor grid
648 std::vector<maia::dg::GridMapOffset> m_gridMapOffsets{};
649 // Maximum number of offsets on all domains
651
652 // Sponge
655
656 // H/P-refinement
657 // If true, pRefinement is utilized based on additional properties
659 // Adaptive refinement setup
661 // Error threshold
663 // Interval for adaptive refinement
665 // Storage for mortar projections
666 std::vector<MFloat*> m_projectionMatrixPointersH{};
667 std::vector<MFloat> m_projectionMatricesH{};
668 std::vector<MFloat*> m_projectionMatrixPointersP{};
669 std::vector<MFloat> m_projectionMatricesP{};
670 // Collector for h-refined elements
672
673 // Storage for the coordinates and polyDeg of p-refinement patches
674 std::vector<std::array<MFloat, 2 * nDim>> m_prefPatchesCoords{};
675 std::vector<MFloat> m_prefPatchesPolyDeg{};
676 std::vector<MString> m_prefPatchesOperators{};
677 std::vector<MInt> m_prefPatchesNoNodes1D{};
678
679 // Geometry Intersection
681
682 // Physical properties and system of equations
683 // System of equation-specific methods and variables
684 SysEqn m_sysEqn;
685 // Boundary condition factory to translate bcIds into objects
687 // Container with boundary conditions
688 std::vector<BC> m_boundaryConditions{};
689 // Enable/disable support for cut-off boundaries
691 // Store cut-off boundaries
692 std::array<MInt, 2 * nDim> m_cutOffBoundaryConditionIds{};
693 // Count number of surfaces with cut-off boundary conditions
694 std::array<MInt, 2 * nDim> m_noCutOffBoundarySurfaces{};
695
696 // Ramp up the external source term in time
698 // Time at which the external source term is fully ramped up
700
701 // Memory management
702 // Maximum number of surfaces that can be created
704 // Total number of values (DOF * noVars * noInternalCells)
706 // Total number of nodes
708
709 // Element variables
710 // Collector of elements
712
713 // Surface variables
714 // Collector of surfaces
716 // Number of boundary surfaces
718 // Number of inner surfaces
720 // Number of MPI surfaces
722 // Offset for (i.e. id of first) boundary surfaces
723 // MInt m_boundarySurfacesOffset = -1;
724 // Offset for (i.e. id of first) inner surfaces
726 // Offset for (i.e. id of first) MPI surfaces
728
729 // Time derivative calculation
730 // Current simulation time
732 // Current time step size
733 MFloat m_dt = -1.0;
734 // Current external time step size set from outside the solver
736
737 // Simulation statistics
738 // Minimum polynomial degree on this domain
740 // Maximum polynomial degree on this domain
742 // Minimum refinement level on this domain
744 // Maximum refinement level on this domain
746 // Number of all cells on this domain
748 // Number of internal cells on this domain
750 // Number of halo cells on this domain
752 // Collector size for cells on this domain
754 // Number of all elements on this domain
756 // Number of all helements on this domain
758 // Number of all surfaces on this domain
760 // Number of boundary surfaces on this domain
762 // Number of inner surfaces on this domain
764 // Number of MPI surfaces on this domain
766 // Collector size for surfaces on this domain
768 // Number of active cells on this domain
770 // Number of active degrees of freedom on this domain
772 // Local number of active degrees of freedom for each polynomial degree
774 // Sum of polynomial degrees for all elements on this domain
776 // Sum of h-refined surfaces
778 // Sum of p-refined surfaces
780 // Minimum polynomial degree on all domains
782 // Maximum polynomial degree on all domains
784 // Minimum refinement level on all domains
786 // Maximum refinement level on all domains
788 // Number of all cells on all domains
790 // Number of internal cells on all domains
792 // Number of halo cells on all domains
794 // Collector size for cells on all domains
796 // Number of all elements on all domains
798 // Number of all surfaces on all domains
800 // Number of boundary surfaces on all domains
802 // Number of inner surfaces on all domains
804 // Number of MPI surfaces on all domains
806 // Collector size for surfaces on all domains
808 // Number of active cells on all domains
810 // Number of active degrees of freedom on all domains
812 // Sum of polynomial degrees for all elements on this domain
814 // Sum of h-refined surfaces
816 // Sum of p-refined surfaces
818 // Sum of number of helements
820 // Sum of number of surfaces with cut-off boundary condition (max 6 for 3D)
822
823 // Timers
824 // Timer group which holds all solver-wide timers
826 // Stores all solver-wide timers
827 std::array<MInt, Timers::_count> m_timers{};
828
829 // Initialization status
835
836 // Variables related to main loop execution
840 std::time_t m_endAutoSaveTime = -1;
843};
844
845// Ensure that only one type of MPI communication is enabled. For more
846// information, please refer to config.h.
847#if defined(DG_USE_MPI_BUFFERS) && defined(DG_USE_MPI_DERIVED_TYPES)
848#error Both methods of doing MPI surface exchanges are enabled. Pick one.
849#endif
850#if !defined(DG_USE_MPI_BUFFERS) && !defined(DG_USE_MPI_DERIVED_TYPES)
851#error No method of doing MPI surface exchanges is enabled. Pick one.
852#endif
853
854// Ensure that if DG_USE_MPI_DERIVED_TYPES and DG_USE_MPI_WAITSOME are
855// not enabled at the same time
856#if defined(DG_USE_MPI_DERIVED_TYPES) && defined(DG_USE_MPI_WAITSOME)
857#error It makes no sense to use MPI_Waitsome with the derived data types.
858#endif
859
860
861// Struct to differentiate cell (element) data
862template <MInt nDim, class SysEqn>
863struct DgCartesianSolver<nDim, SysEqn>::CellData {
864 static constexpr const MInt count = 5;
865
866 static constexpr const MInt ELEM_CELL_ID = 0;
867 static constexpr const MInt ELEM_POLY_DEG = 1;
868 static constexpr const MInt ELEM_NO_NODES_1D = 2;
869 static constexpr const MInt ELEM_VARIABLES = 3;
870 static constexpr const MInt ELEM_NODE_VARS = 4;
871};
872
873
874// Data types of cell data
875template <MInt nDim, class SysEqn>
876const std::array<MInt, DgCartesianSolver<nDim, SysEqn>::CellData::count>
878
879
892template <MInt nDim, class SysEqn>
893template <class F>
895 TRACE();
896
897 const MInt noVars = SysEqn::noVars();
898 const MInt* const polyDegs = &elem.polyDeg(0);
899 const MInt* const noNodes = &elem.noNodes1D(0);
900
901 // Create temporary storage for flux values
902 const MInt maxNoNodesXD = elem.maxNoNodesXD();
903 std::vector<MFloat> flux(maxNoNodesXD * noVars * nDim);
904
905#ifdef _OPENMP
906#pragma omp parallel for firstprivate(flux)
907#endif
908 for(MInt elementId = 0; elementId < noElements; elementId++) {
909 const MInt polyDeg = polyDegs[elementId];
910 const MInt noNodes1D = noNodes[elementId];
911 const MFloat* const dhat = &m_interpolation[polyDeg][noNodes1D].m_Dhat[0];
912 MFloat* const ut = &elem.rightHandSide(elementId);
913 MInt index = 0;
914
915 // Calculate flux
916 fluxFct.calcFlux(&elem.nodeVars(elementId), &elem.variables(elementId), noNodes1D, &flux[0]);
917
918 IF_CONSTEXPR(nDim == 2) {
919 // Copy flux to time derivative
920 MFloatTensor f(&flux[0], noNodes1D, noNodes1D, nDim, noVars);
921 for(MInt i = 0; i < noNodes1D; i++) {
922 for(MInt j = 0; j < noNodes1D; j++) {
923 for(MInt n = 0; n < noVars; n++) {
924 // auto df = 0.0;
925 for(MInt l = 0; l < noNodes1D; l++) {
926 ut[index] += dhat[i * noNodes1D + l] * f(l, j, 0, n) + dhat[j * noNodes1D + l] * f(i, l, 1, n);
927 }
928 index++;
929 }
930 }
931 }
932 }
933 else IF_CONSTEXPR(nDim == 3) {
934 // Copy flux to time derivative
935 MFloatTensor f(&flux[0], noNodes1D, noNodes1D, noNodes1D, nDim, noVars);
936
937 for(MInt i = 0; i < noNodes1D; i++) {
938 for(MInt j = 0; j < noNodes1D; j++) {
939 for(MInt k = 0; k < noNodes1D; k++) {
940 for(MInt n = 0; n < noVars; n++) {
941 for(MInt l = 0; l < noNodes1D; l++) {
942 ut[index] += dhat[i * noNodes1D + l] * f(l, j, k, 0, n) + dhat[j * noNodes1D + l] * f(i, l, k, 1, n)
943 + dhat[k * noNodes1D + l] * f(i, j, l, 2, n);
944 }
945 index++;
946 }
947 }
948 }
949 }
950 }
951 }
952}
953
954
968template <MInt nDim, class SysEqn>
969template <class F>
971 const MInt end,
972 SurfaceCollector& surf,
973 F& riemannFct) {
974 TRACE();
975
976#ifdef _OPENMP
977#pragma omp parallel for
978#endif
979 // Loop over all surfaces, calculate the numerical flux
980 for(MInt srfcId = begin; srfcId < end; srfcId++) {
981 MFloat* flux = &surf.flux(srfcId);
982 MFloat* nodeVarsL = &surf.nodeVars(srfcId, 0);
983 MFloat* nodeVarsR = &surf.nodeVars(srfcId, 1);
984 MFloat* stateL = &surf.variables(srfcId, 0);
985 MFloat* stateR = &surf.variables(srfcId, 1);
986 const MInt noNodes1D = surf.noNodes1D(srfcId);
987 const MInt dirId = surf.orientation(srfcId);
988
989 riemannFct.calcRiemann(nodeVarsL, nodeVarsR, stateL, stateR, noNodes1D, dirId, flux);
990 }
991}
992
993
1007template <MInt nDim, class SysEqn>
1008template <class F>
1010 const MInt noElements,
1011 ElementCollector& elem,
1012 F& sourceFct) {
1013 TRACE();
1014
1015 const MInt* const noNodes1D = &elem.noNodes1D(0);
1016
1017 const MInt maxDataBlockSize = ipow(m_maxNoNodes1D, nDim) * SysEqn::noVars();
1018 std::vector<MFloat> sources(maxDataBlockSize);
1019
1020#ifdef _OPENMP
1021#pragma omp parallel for firstprivate(sources)
1022#endif
1023 for(MInt elementId = 0; elementId < noElements; elementId++) {
1024 const MInt noNodesXD = elem.noNodesXD(elementId);
1025 const MInt dataBlockSize = noNodesXD * SysEqn::noVars();
1026 sourceFct.calcSource(&elem.nodeVars(elementId), &elem.variables(elementId), noNodes1D[elementId], t,
1027 &elem.nodeCoordinates(elementId), &sources[0]);
1028
1029 MFloat* const rhs = &elem.rightHandSide(elementId);
1030 for(MInt dataId = 0; dataId < dataBlockSize; dataId++) {
1031 rhs[dataId] += sources[dataId];
1032 }
1033 }
1034}
1035
1036
1048template <MInt nDim, class SysEqn>
1049template <typename DataType>
1051 const MInt oldNoCells,
1052 const MInt* const bufferIdToCellId,
1053 DataType* const data) {
1054 TRACE();
1055
1056 // Check for unsorted cells, not supported yet, data needs to be resorted into buffers
1057 MInt prevCellId = -1;
1058 for(MInt i = 0; i < oldNoCells; i++) {
1059 const MInt mapping = bufferIdToCellId[i];
1060 if(mapping != -1) {
1061 if(mapping <= prevCellId) {
1062 TERMM(1, "Error: assembling data buffers for unsorted cells not supported yet in DG solver.");
1063 }
1064 prevCellId = mapping;
1065 }
1066 }
1067
1068 const MInt noElements = m_elements.size();
1069
1070 if(dataId > -1 && dataId < noDgCartesianSolverCellData()) {
1071 // DG solver cell data
1072 switch(dataId) {
1073 case CellData::ELEM_CELL_ID:
1074 std::copy_n(&m_elements.cellId(0), noElements, data);
1075 break;
1076 case CellData::ELEM_POLY_DEG:
1077 std::copy_n(&m_elements.polyDeg(0), noElements, data);
1078 break;
1079 case CellData::ELEM_NO_NODES_1D:
1080 std::copy_n(&m_elements.noNodes1D(0), noElements, data);
1081 break;
1082 case CellData::ELEM_VARIABLES: {
1083 MInt dataOffset = 0;
1084 // Store all element variables in the data buffer
1085 for(MInt elementId = 0; elementId < noElements; elementId++) {
1086 const MInt noNodesXD = m_elements.noNodesXD(elementId);
1087 const MInt dataSize = noNodesXD * SysEqn::noVars();
1088 std::copy_n(&m_elements.variables(elementId), dataSize, &data[dataOffset]);
1089 dataOffset += dataSize;
1090 }
1091 break;
1092 }
1093 case CellData::ELEM_NODE_VARS: {
1094 MInt dataOffset = 0;
1095 // Store all element node variables in the data buffer
1096 for(MInt elementId = 0; elementId < noElements; elementId++) {
1097 const MInt noNodesXD = m_elements.noNodesXD(elementId);
1098 const MInt dataSize = noNodesXD * SysEqn::noNodeVars();
1099 std::copy_n(&m_elements.nodeVars(elementId), dataSize, &data[dataOffset]);
1100 dataOffset += dataSize;
1101 }
1102 break;
1103 }
1104 default:
1105 TERMM(1, "Unknown data id (" + std::to_string(dataId) + ").");
1106 break;
1107 }
1108 } else if(dataId >= noDgCartesianSolverCellData() && dataId < noCellDataDlb()) {
1109 // Boundary condition cell data
1110 MInt offset = noDgCartesianSolverCellData();
1111 for(auto&& bc : m_boundaryConditions) {
1112 const MInt bcNoCellData = bc->noCellDataDlb();
1113 if(dataId >= offset && dataId < offset + bcNoCellData) {
1114 bc->getCellDataDlb(dataId - offset, data);
1115 break;
1116 }
1117 offset += bcNoCellData;
1118 }
1119 } else {
1120 // TODO labels:DG support exchange of CC mean vars data -> needs to be performed via gridcontroller!
1121 TERMM(1, "Invalid dataId (" + std::to_string(dataId) + ").");
1122 }
1123}
1124
1125
1135template <MInt nDim, class SysEqn>
1136template <typename DataType>
1137void DgCartesianSolver<nDim, SysEqn>::setCellDataDlb_(const MInt dataId, const DataType* const data) {
1138 TRACE();
1139
1140 // Nothing to do if solver is not active
1141 if(!grid().isActive()) {
1142 return;
1143 }
1144
1145 const MInt noElements = m_elements.size();
1146
1147 if(dataId > -1 && dataId < noDgCartesianSolverCellData()) {
1148 // Skip if this is the wrong reinitialization stage
1149 if(m_loadBalancingReinitStage != 0) {
1150 return;
1151 }
1152
1153 // DG solver cell data
1154 switch(dataId) {
1155 case CellData::ELEM_CELL_ID:
1156 std::copy_n(data, noElements, &m_elements.cellId(0));
1157 break;
1158 case CellData::ELEM_POLY_DEG:
1159 std::copy_n(data, noElements, &m_elements.polyDeg(0));
1160 break;
1161 case CellData::ELEM_NO_NODES_1D:
1162 std::copy_n(data, noElements, &m_elements.noNodes1D(0));
1163 break;
1164 case CellData::ELEM_VARIABLES: {
1165 MInt dataOffset = 0;
1166 for(MInt elementId = 0; elementId < noElements; elementId++) {
1167 // NOTE: assumes polynomial degree is already set!
1168 const MInt noNodesXD = m_elements.noNodesXD(elementId);
1169 const MInt dataSize = noNodesXD * SysEqn::noVars();
1170 std::copy_n(&data[dataOffset], dataSize, &m_elements.variables(elementId));
1171 dataOffset += dataSize;
1172 }
1173 break;
1174 }
1175 case CellData::ELEM_NODE_VARS: {
1176 MInt dataOffset = 0;
1177 for(MInt elementId = 0; elementId < noElements; elementId++) {
1178 // NOTE: assumes polynomial degree is already set!
1179 const MInt noNodesXD = m_elements.noNodesXD(elementId);
1180 const MInt dataSize = noNodesXD * SysEqn::noNodeVars();
1181 std::copy_n(&data[dataOffset], dataSize, &m_elements.nodeVars(elementId));
1182 dataOffset += dataSize;
1183 }
1184 break;
1185 }
1186 default:
1187 TERMM(1, "Unknown data id.");
1188 break;
1189 }
1190 } else if(dataId >= noDgCartesianSolverCellData() && dataId < noCellDataDlb()) {
1191 // Note: this should happen after boundary conditions are created, skip if
1192 // this is the wrong reinitialization stage
1193 if(m_loadBalancingReinitStage != 2) {
1194 return;
1195 }
1196
1197 // Boundary condition cell data
1198 MInt offset = noDgCartesianSolverCellData();
1199 for(auto&& bc : m_boundaryConditions) {
1200 const MInt bcNoCellData = bc->noCellDataDlb();
1201 if(dataId >= offset && dataId < offset + bcNoCellData) {
1202 bc->setCellDataDlb(dataId - offset, data);
1203 break;
1204 }
1205 offset += bcNoCellData;
1206 }
1207 } else {
1208 // TODO labels:DG support exchange of CC mean vars data -> needs to be performed via gridcontroller!
1209 // Note: when setting the data for the first time the boundary conditions are not created yet
1210 // and the total cell data count does not match
1211 if(m_loadBalancingReinitStage == 2) {
1212 TERMM(1, "Invalid dataId: " + std::to_string(dataId));
1213 }
1214 }
1215}
1216
1217#endif // DGSOLVER_H_
GridCell
Grid cell Property Labels.
Intermediate class for coupling DG solver with APE sysEqn.
Class to handle creation of boundary condition objects.
std::unique_ptr< DgBoundaryCondition< nDim, SysEqn > > ReturnType
MBool needHElementForCell(const MInt cellId)
Return true if h-element is needed for cell, false otherwise.
std::vector< MInt > m_statLocalNoActiveDOFsPolyDeg
std::array< MInt, 2 *nDim > getBoundaryConditionIds(const MInt cellId)
Determine if element is boundary is cut by geometry elements and return corresponding boundary condit...
std::vector< MFloat > m_projectionMatricesH
void finalizeAdaptation() override
finalize adaptation for split sadptation after the adaptation loop
void calcRegularSurfaceFlux(const MInt begin, const MInt end, SurfaceCollector &surf, F &riemannFct)
Calculate the numerical flux for a regular (i.e. inner or MPI) surface.
MInt noLoadTypes() const override
Return the number of DG load types.
void resetBuffer(const MInt totalSize, MFloat *const buffer)
Reset the given buffer to zero.
std::vector< maia::dg::GridMapOffset > m_gridMapOffsets
MInt a_noCells() const
DgBoundaryConditionFactory< nDim, SysEqn > m_boundaryConditionFactory
MBool hasMpiExchange() const
void prolongToSurfaces()
Extrapolate the solution from inside the elements to the surfaces.
MFloat * mortarP(const MInt sourcePolyDeg, const MInt targetPolyDeg)
void checkCellProperties()
Check all relevant bit properties in the cells.
void calcSurfaceIntegral()
Calculate the surface integral for all faces of element and update dU/dt.
void applyJacobian()
Adds the negative of the inverse Jacobian to the time derivative.
std::vector< MPI_Datatype > m_recvTypes
void preTimeStep() override
Perform pre-time-step operations, e.g. set new dt if required.
std::vector< std::vector< MFloat > > m_recvBuffers
void forceTimeStep(const MFloat dt)
Force time step externally.
void initTimers()
Initialize all solver-wide timers and start the solver timer.
void calcInnerSurfaceFlux()
Calculate the numerical flux on the internal surfaces and update m_flux.
typename CartesianSolver::Grid Grid
MBool useSponge() const
MBool calcStateAtPoint(const MFloat *point, MFloat *state)
returns the cellId of a cell containing a given point
typename DgBoundaryConditionFactory< nDim, SysEqn >::ReturnType BC
std::vector< MFloat * > m_projectionMatrixPointersH
void calcMortarProjectionH(const MInt srfcId, const MInt dir, MFloat *source, MFloat *destination, ElementCollector &elem, SurfaceCollector &surf)
Calculate the h-refinement mortar projection.
std::vector< MFloat > m_prefPatchesPolyDeg
MInt getLevelOfDirectNeighborCell(const MInt cellId, const MInt dir)
MLong m_statGlobalNoBoundarySurfaces
MInt a_hasNeighbor(const MInt cellId, const MInt dir) const
void applyExternalSourceTerms(const MFloat time)
Add the external coupling source terms to the right hand side.
virtual void reIntAfterRestart(MBool)
MInt getHElementId(const MInt elementId) const
Return h-element id of a given element (if it exists).
void createHElement(const MInt cellId)
Create h-element for cell with id cellId.
MFloat calcTimeStep()
Calculate the next time step.
void loadNodeVarsFile()
Load node variables from file.
MInt noVariables() const override
Return the number of variables.
void swapProxy(const MInt cellId0, const MInt cellId1)
Swap the given cells.
void resizeGridMap()
Swap the given cells.
void calcSamplingVarAtPoint(const MFloat *point, const MInt elementId, const MInt sampleVarId, MFloat *state, const MBool interpolate) override
Calculate the state vector at a given point and for the specified sampling variable.
void createElement(const MInt cellId)
Create element for cell with id cellId.
std::vector< MFloat > m_timeIntegrationCoefficientsB
std::vector< std::vector< DgInterpolation > > m_interpolation
maia::dg::collector::ElementCollector< nDim, SysEqn > ElementCollector
void initSurfaces()
Create for all elements and directions surfaces if necessary.
void setGlobalSolverVars(std::vector< MFloat > &NotUsed(globalFloatVars), std::vector< MInt > &NotUsed(globalIdVars)) override
Set global solver variables for DLB (same on each domain)
DgInterpolation m_interpAnalysis
MBool pointIsInside(const MFloat *const coordinates)
Check if point is inside the computational domain.
void calcMpiSurfaceFlux()
Calculate the numerical flux on the MPI surfaces and update m_flux.
void initJacobian()
Calculates the inverse Jacobian for each element.
MBool hasAdaptivePref() const
Return true if adaptive hp-refinement is activated.
MInt getIdAtPoint(const MFloat *point, const MBool globalUnique=false)
Return the element id containing a given point.
std::vector< MFloat > m_timeIntegrationCoefficientsA
void getSolverSamplingProperties(std::vector< MInt > &samplingVarIds, std::vector< MInt > &noSamplingVars, std::vector< std::vector< MString > > &samplingVarNames, const MString featureName="") override
Return sampling properties for the DG solver.
void getLoadQuantities(MInt *const loadQuantities) const override
Return the cumulative load quantities on this domain.
std::vector< std::vector< MFloatTensor > > m_vdmAnalysis
void writeRestartFile(const MBool writeRestart, const MBool writeBackup, const MString gridFileName, MInt *recalcIdTree) override
Write a restart file.
MInt initMpiSurface(const MInt elementId, const MInt dir)
Check if the surface of the element in the given direction is a MPI surface. If it is,...
MInt noSolverTimers(const MBool allTimings) override
Geom & geometry()
Access the solver's geometry (non-const version)
MInt getCurrentTimeStep() const override
MInt calculateNeededNoSurfaces()
Determine the number of surfaces that need to be created on this domain.
MBool solutionStep() override
Perform one Runge-Kutta step/stage.
MInt initInnerSurface(const MInt elementId, const MInt dir)
Check if the surface of the element in the given direction is an inner surface without h/p-refinement...
void cleanUp() override
Clean up after a simulation run.
MBool m_saveNodeVariablesToSolutionFile
virtual void calcSamplingVariables(const std::vector< MInt > &NotUsed(varIds), const MBool NotUsed(exchange))
MInt getCellIdByIndex(const MInt index)
Return cell id belonging to an element id/index.
std::vector< BC > m_boundaryConditions
MString getRestartFileName(const MInt timeStep, const MInt useNonSpecifiedRestartFile)
Return name of a restart file for the given time step.
static const std::array< MInt, CellData::count > s_cellDataTypeDlb
void getCellDataDlb(const MInt dataId, const MInt oldNoCells, const MInt *const bufferIdToCellId, MFloat *const data) override
virtual void saveRestartFile()
Saves a file to disk with all information that is necessary to restart the calculations from here.
MBool isMpiSurface(const MInt id) const
Return true if a surface is a MPI surface.
std::vector< MPI_Request > m_recvRequests
std::vector< MFloat * > m_projectionMatrixPointersP
MBool hasSurface(const MInt elementId, const MInt dir)
Check if a surface exists for the element in the given direction.
void calcMortarProjection(const MInt srfcId, const MInt dir, MFloat *source, MFloat *destination, ElementCollector &elem, SurfaceCollector &surf)
void setCellDataDlb(const MInt dataId, const MInt *const data) override
void initDgCartesianSolver()
Initializes basic properties of the solver.
void globalToLocalIds() override
Change global into local ids.
void initMortarProjections()
Calculate all necessary mortar projection matrices.
MInt createHMPISurfaces(const MInt elementId, const MInt dir)
MInt cellDataTypeDlb(const MInt dataId) const override
Get data type of cell data.
void checkGridMap(const MString &donorGridFileName)
Perform some sanity checks on loaded grid map.
MInt noDgCartesianSolverCellData() const
void setCellWeights(MFloat *solverCellWeight) override
Set cell weights with constant weighting factor weightPerNode.
void getSampleVariables(MInt cellId, const MFloat *&vars)
void loadSampleVariables(MInt timeStep)
std::array< MInt, 2 *nDim > m_cutOffBoundaryConditionIds
std::array< MInt, Timers::_count > m_timers
Geom & m_geometry
Reference to geometry object.
void calcSourceTerms(MFloat t)
Calculates the source terms for each node and adds them to the time derivative of the conservative va...
void saveNodeVarsFile()
Save node variables to file.
void extendNodeVariables()
Extends nodeVars from given planes to given directions.
void updateNodeVariablesSingleElement(const MInt elementId, const MInt extendDir, MIntTensor hForwardSurfaceId, MIntTensor hReverseSurfaceId, std::vector< MBool > &cellHasUpdatedMeans, std::vector< MInt > &SurfaceWantsToMPISend, MBool &noMoreUpdates)
Sets nodeVars of an element to values on the surface opposite to extendDir.
MFloat time() const override
Return the time.
void adaptiveRefinement(const MInt timeStep)
Apply adaptive refinement (right now: only p-refinement)
void initNodeCoordinates()
Calculates the coordinates of the integration nodes within each element.
~DgCartesianSolver() override
Frees resources that were allocated in the constructor and that are not automatically released when t...
void calcVolumeIntegral()
Calculate the volume integral for all elements and update m_rightHandSide.
void calcElementNodeCoordinates(const MInt elementId)
Calculates the coordinates of the integration nodes within the element.
const MFloat & a_coordinate(const MInt cellId, const MInt dim) const
void getCellDataDlb(const MInt dataId, const MInt oldNoCells, const MInt *const bufferIdToCellId, MInt *const data) override
std::vector< std::vector< MInt > > m_mpiSurfaces
maia::dg::collector::SurfaceCollector< nDim, SysEqn > SurfaceCollector
MFloat * mortarH(const MInt polyDeg, const MInt position)
void setCellDataDlb(const MInt dataId, const MFloat *const data) override
void initPolynomialDegree()
Calculate and set initial polynomial degree and number of nodes in all elements.
void loadGridMap(const MString &gridMapFileName)
Load previously created grid map.
void initInterpolation()
Calculates necessary coefficients for interpolation and stores them once for the whole solver.
void initElements()
Initialize all elements by iterating over all cells and creating an element for each internal leaf ce...
void calcMortarProjectionP(const MInt srfcId, const MInt dir, MFloat *source, MFloat *destination, ElementCollector &elem, SurfaceCollector &surf)
Calculate the p-refinement mortar projection.
std::vector< MPI_Datatype > m_sendTypes
SurfaceCollector m_surfaces
std::vector< std::array< MFloat, 2 *nDim > > m_prefPatchesCoords
DgSponge< nDim, SysEqn > & sponge()
typename maia::grid::tree::Tree< nDim >::Cell Cell
PointData< nDim, DgCartesianSolver< nDim, SysEqn > > m_pointData
void calcBoundarySurfaceFlux(MFloat t)
Calculate the numerical flux on the boundary surfaces and update m_flux.
std::vector< MString > m_prefPatchesOperators
void savePartitionCellWorkloads()
void saveSolverSolution(const MBool forceOutput, const MBool finalTimeStep) override
Save the solver solution, i.e. write solution files and sampling/slice output.
std::vector< MPI_Request > m_sendRequests
void calcErrorEstimate(std::vector< MFloat > &errorEstimate)
Calculate error estimate for adaptive hp-refinement.
void initSolver() override
Initialize the solver.
void updateWeightsAndWorkloads()
GeometryIntersection< nDim > * m_geometryIntersection
constexpr const Geom & geometry() const
Access the solver's geometry.
void postAdaptation() override
post adaptation for split adaptation within the adaptation loop
void allocateAndInitSolverMemory()
Allocates main memory resources.
void analyzeTimeStep(MFloat t, MFloat runTimeRelative, MFloat runTimeTotal, MInt timeStep, MFloat dt)
Calculates and prints the L^2 and L^inf errors (using calcErrorNorms()) for the current time.
void initData()
Initialize solver data, i.e. set initial conditions or load restart file.
MFloat getCellLoad(const MInt cellId, const MFloat *const weights) const override
Return the load of a single cell (given computational weights).
virtual void initSolverSamplingVariables(const std::vector< MInt > &NotUsed(varIds), const std::vector< MInt > &NotUsed(noSamplingVars))
MInt getLevelByElementId(const MInt elementId)
MBool needElementForCell(const MInt cellId)
Return true if element is needed for cell, false otherwise.
MBool hasPref() const
Return true if p-refinement is set.
MInt noCellDataDlb() const override
Methods to inquire solver data information.
MBool hasNeighborCell(const MInt elementId, const MInt dir)
SurfaceData< nDim, DgCartesianSolver< nDim, SysEqn > > m_surfaceData
void getSolverTimings(std::vector< std::pair< MString, MFloat > > &solverTimings, const MBool allTimings) override
Get solver timings.
MInt cellDataSizeDlb(const MInt dataId, const MInt cellId) override
Return data size of cell data.
MInt a_level(const MInt) const
void interpolateElement(const MInt elementId, const MInt newPolyDeg)
Interpolate an element to a different polynomial degree.
void initMainLoop()
Perform all operations that prepare the execution of the main loop.
void getGlobalSolverVars(std::vector< MFloat > &NotUsed(globalFloatVars), std::vector< MInt > &NotUsed(globalIntVars)) override
Get global solver variables that need to be communicated for DLB (same on each domain)
void getDomainDecompositionInformation(std::vector< std::pair< MString, MInt > > &domainInfo) override
Return decomposition information, i.e. number of local elements,...
void balancePost() override
Reinitialize solver after setting solution data.
void calcErrorNorms(const MFloat t, std::vector< MFloat > &L2Error, std::vector< MFloat > &LInfError, std::vector< MFloat > &L2ErrLocal, std::vector< MFloat > &LInfErrLocal)
Calculate the L^2 and L^infinity error norms at a given time. The error is calculated in comparison t...
typename CartesianSolver::GridProxy GridProxy
void setSensors(std::vector< std::vector< MFloat > > &NotUsed(sensors), std::vector< MFloat > &NotUsed(sensorWeight), std::vector< std::bitset< 64 > > &NotUsed(sensorCellFlag), std::vector< MInt > &NotUsed(sensorSolverId)) override
void applySurfaceIntegral(MFloat *rhs, const MInt polyDeg, const MInt noNodes1D, const MInt srfcId, const MInt side, const MFloat *flux, SurfaceCollector &surf)
Calculate the surface integral for a face of an element and update dU/dt.
MInt initBoundarySurface(const MInt elementId, const MInt dir)
Check if the surface of the element in the given direction is a boundary surface. If it is init,...
MInt createSurface(const MInt elementId, const MInt dir, MInt nghbrId=-1)
void cancelMpiRequests() override
Cancel open MPI (receive) requests.
std::array< MLong, 6 > m_statGlobalNoCutOffBoundarySurfaces
void getHeatRelease(MFloat *&heatRelease)
void timeStepRk(const MFloat t, const MFloat dt, const MInt substep=-1)
Time integration using the five-stage fourth-order low-storage Runge-Kutta scheme as described in the...
void saveNodalData(const MString &fileNameBase, const MInt noVars, const std::vector< MString > &varNames, const MFloat *const data) const
Save nodal data to file.
std::array< MInt, 2 *nDim > m_noCutOffBoundarySurfaces
void calcDgTimeDerivative(const MFloat t, const MFloat tStage)
Main routine to calculate the discontinuous Galerkin time derivative. After this method was called,...
void subTimeStepRk(const MFloat dt, const MInt stage, const MInt totalSize, const MFloat *const rhs, MFloat *const variables, MFloat *const timeIntStorage)
Perform one Runge-Kutta substep on the given elements.
void extendNodeVariablesSingleDirection(const MInt extendDir, const MFloat extendOffset, const MFloat extendLimit)
Set nodeVars upstream of given plane to values of elements in plane.
MInt getElementIdAtPoint(const MFloat *point, MBool globalUnique=false)
returns the elementId of a element containing a given point
void initPrefinement()
Set polynomial degree for static p-refinement case.
ElementCollector m_elements
void initGridMap()
Determine grid-to-grid mapping.
std::vector< MFloat > m_timeIntegrationCoefficientsC
MInt noBcSolverCellData() const
void run()
Main method to run this solver.
void getSampleVariables(const MInt cellId, std::vector< MFloat > &)
MBool prepareRestart(MBool, MBool &) override
Return true if the solver wants to write a restart file.
void finalizeInitSolver() override
Finalization of the solver initialization.
void localToGlobalIds() override
Change local into global ids.
void finishMpiSurfaceExchange()
Finish sending the window-side data and finish receiving the halo-side data for all MPI surfaces.
void initHElements()
Initialize all helements by iterating over all cells and creating an element for each coarse cell in ...
typename maia::CartesianSolver< nDim, DgCartesianSolver > CartesianSolver
void postTimeStep()
Perform post-time-step operations, e.g. advance time, error analysis.
void getCellDataDlb_(const MInt dataId, const MInt oldNoCells, const MInt *const bufferIdToCellId, dataType *const data)
virtual void initInterpolationForCell(const MInt NotUsed(cellId))
MBool step(const MFloat externalDt=-std::numeric_limits< MFloat >::infinity(), const MBool substep=false)
Advance the solution by one time step.
DgSlices< nDim, SysEqn > m_slice
HElementCollector m_helements
std::time_t m_endAutoSaveTime
MBool isAdaptationTimeStep(const MInt timeStep) const
Return if the given timestep is an adaptation timestep.
void resetSolver() override
Reset solver (for load balancing)
void setNumericalProperties()
Reads properties associated with the numerical method.
std::vector< std::vector< MInt > > m_mpiRecvSurfaces
void calcSurfaceNodeCoordinates(const MInt surfaceId)
void loadRestartFile() override
Load restart file with all information that is necessary to restart the calculations from here.
std::vector< MInt > m_prefPatchesNoNodes1D
void balancePre() override
Reinitialize solver prior to setting solution data in DLB.
void initSolverObjects()
Initializes the solver. This must be called before using any of the discretization methods,...
void setCellDataDlb_(const MInt dataId, const dataType *const data)
std::vector< MInt > m_exchangeNghbrDomains
MInt noInternalCells() const override
Return the number of internal cells within this solver.
void startMpiSurfaceExchange()
Start sending the window-side data and start receiving the halo-side data for all MPI surfaces.
MBool hasSplitBalancing() const override
Return if load balancing for solver is split into multiple methods or implemented in balance()
DgSponge< nDim, SysEqn > m_sponge
std::vector< MFloat > m_projectionMatricesP
void updateNodeVariables()
Update all node variables at the surfaces.
MBool isMpiRoot() const
Return true if this is the root rank of the solver MPI communicator.
virtual void initialCondition()
Set the initial condition in all elements.
void finalizeBalance() override
void saveSolutionFile()
Saves all available data to disk.
void getDefaultWeights(MFloat *weights, std::vector< MString > &names) const
Return the default weights for all load quantities.
MFloatTensor m_wVolumeAnalysis
void prepareAdaptation() override
prepare adaptation for split adaptation before the adaptation loop
void outputInitSummary()
Print initialization summary to user and m_log.
VolumeData< nDim, DgCartesianSolver< nDim, SysEqn > > m_volumeData
std::vector< std::vector< MFloat > > m_sendBuffers
virtual void resetRHS()
Reset the time derivative of the conservative variables to zero.
void balance(const MInt *const NotUsed(noCellsToReceiveByDomain), const MInt *const NotUsed(noCellsToSendByDomain), const MInt *const NotUsed(targetDomainsByCell), const MInt NotUsed(oldNoCells)) override
Perform load balancing.
Coupling condition for direct-hybrid LES-CAA computations.
Class stores precalculated values for interpolation & integration on the reference interval [-1,...
Determine all coordinates and alloc buffer size create a valid 2D grid which represents a slice from ...
Container for sponge elements.
This class is responsible for the point data feature. It records the state of all sampling variables ...
Definition: samplingdata.h:164
MBool m_restart
Definition: solver.h:97
virtual MInt domainId() const
Return the domainId (rank)
Definition: solver.h:383
MPI_Comm mpiComm() const
Return the MPI communicator used by this solver.
Definition: solver.h:380
MInt solverId() const
Return the solverId.
Definition: solver.h:425
virtual MInt noDomains() const
Definition: solver.h:387
void updateDomainInfo(const MInt domainId, const MInt noDomains, const MPI_Comm mpiComm, const MString &loc)
Set new domain information.
Definition: solver.h:135
Surface data sampling class. Records all sampling variables on all surface elements and outputs addit...
Definition: samplingdata.h:190
Class to handle sampling of volume data.
Definition: samplingdata.h:220
Class that represents DG element collector.
MInt & polyDeg(const MInt id)
Accessor for polynomial degree.
MInt noNodesXD(const MInt id) const
Accessor for number of nodes XD (const version).
MFloat & nodeCoordinates(const MInt id)
Accessor for node coordinates.
MInt & cellId(const MInt id)
Accessor for cell id.
MInt maxNoNodesXD() const
Return maximum number of nodes XD.
MFloat & nodeVars(const MInt id)
Accessor for node variables.
MFloat & variables(const MInt id, const MInt pos)
Accessor for variables.
MFloat & rightHandSide(const MInt id)
Accessor for right hand side.
MInt noNodes1D(const MInt id) const
Accessor for number of nodes 1D (const version).
Class that represents DG element collector.
Class that represents DG element collector.
MInt & noNodes1D(const MInt srfcId)
Accessor for number of nodes 1D.
MFloat & nodeVars(const MInt srfcId, const MInt side)
Accessor for node variables.
MFloat & flux(const MInt srfcId)
Accessor for flux.
MFloat & variables(const MInt srfcId, const MInt side)
Accessor for variables.
MInt & orientation(const MInt srfcId)
Accessor for orientation.
Provides a lightweight and fast class for accessing 1D arrays as multi-dimensional tensors (up to 4D)...
Definition: tensor.h:41
@ MINT
Definition: enums.h:269
@ MFLOAT
Definition: enums.h:269
MInt ipow(MInt base, MInt exp)
Integer exponent function for non-negative exponents.
Definition: functions.h:317
int32_t MInt
Definition: maiatypes.h:62
std::basic_string< char > MString
Definition: maiatypes.h:55
double MFloat
Definition: maiatypes.h:52
int64_t MLong
Definition: maiatypes.h:64
bool MBool
Definition: maiatypes.h:58
static constexpr const MInt count