• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

CSMMLab / KiT-RT / #95

28 May 2025 02:06AM UTC coverage: 46.655% (-11.1%) from 57.728%
#95

push

travis-ci

web-flow
Release 2025 (#44)

* New neural models (#30)

* extend kitrt script

* added new neural models

* extend to m3 models

* added M3_2D models

* added M2 and M4 models

* configure ml optimizer for high order models

* added configuration for high order models

* add option for rotation postprcessing in neural networks. remove unneccessary python scripts

* started rotational symmetric postprocessing

* added rotational invariance postprocessing for m2 and m1 models

* fix post merge bugs

* created hohlraum mesh

* add hohlraum tes case

* add hohlraum test case

* add hohlraum cfg filees

* fixed hohlraum testcase

* add hohlraum cfg files

* changed hohlraum cfg

* changed hohlraum testcase to isotropic inflow source boundary condition

* added ghost cell bonudary for hohlraum testcase

* update readme and linesource mesh creator

* added proper scaling for linesource reference solution

* regularized newton debugging

* Data generator with reduced objective functional (#33)

* added reduced optimizer for sampling

* remove old debugging comments

* mesh acceleration (#38)

* added new ansatz (#36)

* added new ansatz

* debug new ansatz

* branch should be abandoned here

* debug new ansatz

* fix scaling error new ansatz

* fix config errors

* temporarily fixed dynamic ansatz rotation bug

* fix inheritance error for new ansatz

* mesh acceleration

* add structured hohlraum

* Mesh acc (#41)

* mesh acceleration

* added floor value for starmap moment methods

* enable accelleration

* delete minimum value starmap

* Update README.md

* Spherical harmonics nn (#40)

* added new ansatz

* debug new ansatz

* branch should be abandoned here

* debug new ansatz

* fix scaling error new ansatz

* fix config errors

* temporarily fixed dynamic ansatz rotation bug

* fix inheritance error for new ansatz

* mesh acceleration

* add structured hohlraum

* added sph... (continued)

767 of 3019 new or added lines in 51 files covered. (25.41%)

131 existing lines in 8 files now uncovered.

4422 of 9478 relevant lines covered (46.66%)

57163.05 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

67.81
/src/solvers/solverbase.cpp
1
#include "solvers/solverbase.hpp"
2
#include "common/config.hpp"
3
#include "common/globalconstants.hpp"
4
#include "common/io.hpp"
5
#include "common/mesh.hpp"
6
#include "fluxes/numericalflux.hpp"
7
#include "problems/problembase.hpp"
8
#include "quadratures/quadraturebase.hpp"
9
#include "solvers/csdmnsolver.hpp"
10
#include "solvers/csdpnsolver.hpp"
11
#include "solvers/csdsnsolver.hpp"
12
#include "solvers/mnsolver.hpp"
13
#include "solvers/mnsolver_normalized.hpp"
14
#include "solvers/pnsolver.hpp"
15
#include "solvers/snsolver.hpp"
16
#include "toolboxes/textprocessingtoolbox.hpp"
17
#include <chrono>
18
#include <cmath>
19
#include <limits>
20

21
SolverBase::SolverBase( Config* settings ) {
22✔
22
    _currTime = 0.0;
22✔
23
    _settings = settings;
22✔
24

25
    _mesh = LoadSU2MeshFromFile( settings );
22✔
26

27
    _areas     = _mesh->GetCellAreas();
22✔
28
    _neighbors = _mesh->GetNeighbours();
22✔
29
    _normals   = _mesh->GetNormals();
22✔
30
    _nCells    = _mesh->GetNumCells();
22✔
31
    _settings->SetNCells( _nCells );
22✔
32

33
    // build quadrature object and store frequently used params
34
    _quadrature = QuadratureBase::Create( settings );
22✔
35
    _nq         = _quadrature->GetNq();
22✔
36
    _settings->SetNQuadPoints( _nq );
22✔
37

38
    // build slope related params
39
    _reconstructor      = new Reconstructor( settings );    // Not used!
22✔
40
    _reconsOrder        = _reconstructor->GetSpatialOrder();
22✔
41
    _interfaceMidPoints = _mesh->GetInterfaceMidPoints();
22✔
42

43
    _cellMidPoints = _mesh->GetCellMidPoints();
22✔
44

45
    // set time step or energy step
46
    _dT = ComputeTimeStep( _settings->GetCFL() );
22✔
47
    if( _settings->GetIsCSD() ) {
22✔
48
        // carefull: This gets overwritten by almost all subsolvers
49
        double minE = 5e-5;    // 2.231461e-01;    // 5e-5;
4✔
50
        double maxE = _settings->GetMaxEnergyCSD();
4✔
51
        _nEnergies  = std::ceil( ( maxE - minE ) / _dT );
4✔
52
        _energies   = blaze::linspace( _nEnergies, minE, maxE );
4✔
53
    }
54
    else {                                                     // Not CSD Solver
55
        _nEnergies = unsigned( settings->GetTEnd() / _dT );    // redundancy with nIter (<-Better) ?
18✔
56
        _energies  = 0;    // blaze::linspace( _nEnergies, 0.0, settings->GetTEnd() );    // go upward from 0 to T_end =>Not needed
18✔
57
    }
58

59
    // Adjust maxIter, depending if we have a normal run or a csd Run
60
    _nIter = _nEnergies;
22✔
61
    if( _settings->GetIsCSD() ) {
22✔
62
        _nIter = _nEnergies - 1;    // Since CSD does not go the last energy step
4✔
63
    }
64
    else {
65
        _nIter++;
18✔
66
    }
67

68
    // setup problem  and store frequently used params
69

70
    _problem = ProblemBase::Create( _settings, _mesh, _quadrature );
22✔
71

72
    _sol = _problem->SetupIC();
22✔
73

74
    _solNew = _sol;    // setup temporary sol variable
22✔
75
    if( !_settings->GetIsCSD() ) {
22✔
76
        _sigmaT = _problem->GetTotalXS( _energies );
18✔
77
        _sigmaS = _problem->GetScatteringXS( _energies );
18✔
78
        _Q      = _problem->GetExternalSource( _energies );
18✔
79
    }
80

81
    // setup numerical flux
82
    _g = NumericalFluxBase::Create();
22✔
83

84
    // boundary type
85
    _boundaryCells = _mesh->GetBoundaryTypes();
22✔
86

87
    PrepareScreenOutput();     // Screen Output
22✔
88
    PrepareHistoryOutput();    // History Output
22✔
89

90
    // initialize Helper Variables
91
    _scalarFluxNew = Vector( _nCells, 0 );
22✔
92
    _scalarFlux    = Vector( _nCells, 0 );
22✔
93
    // write density
94
    _density = _problem->GetDensity( _mesh->GetCellMidPoints() );
22✔
95
}
22✔
96

97
SolverBase::~SolverBase() {
16✔
98
    delete _quadrature;
16✔
99
    delete _mesh;
16✔
100
    delete _problem;
16✔
101
    delete _reconstructor;
16✔
102
    delete _g;
16✔
103
}
16✔
104

×
105
SolverBase* SolverBase::Create( Config* settings ) {
106
    switch( settings->GetSolverName() ) {
107
        case SN_SOLVER: return new SNSolver( settings );
108
        case PN_SOLVER: return new PNSolver( settings );
109
        case MN_SOLVER: return new MNSolver( settings );
110
        case MN_SOLVER_NORMALIZED: return new MNSolverNormalized( settings );
111
        case CSD_SN_SOLVER: return new CSDSNSolver( settings );
16✔
112
        case CSD_PN_SOLVER: return new CSDPNSolver( settings );
16✔
113
        case CSD_MN_SOLVER: return new CSDMNSolver( settings );
16✔
114

16✔
115
        default: ErrorMessages::Error( "Creator for the chosen solver does not yet exist. This is is the fault of the coder!", CURRENT_FUNCTION );
16✔
116
    }
16✔
117
    ErrorMessages::Error( "Creator for the chosen solver does not yet exist. This is is the fault of the coder!", CURRENT_FUNCTION );
16✔
118
    return nullptr;    // This code is never reached. Just to disable compiler warnings.
119
}
22✔
120

22✔
121
void SolverBase::Solve() {
6✔
122

4✔
123
    // --- Preprocessing ---
8✔
124
    PrepareVolumeOutput();
×
125

×
126
    DrawPreSolverOutput();
4✔
UNCOV
127

×
128
    // Preprocessing before first pseudo time step
UNCOV
129
    SolverPreprocessing();
×
130
    unsigned rkStages = _settings->GetTemporalOrder();
UNCOV
131
    // Create Backup solution for Runge Kutta
×
UNCOV
132
    VectorVector solRK0 = _sol;
×
133

134
    auto start = std::chrono::high_resolution_clock::now();    // Start timing
135
    std::chrono::duration<double> duration;
22✔
136
    // Loop over energies (pseudo-time of continuous slowing down approach)
137
    for( unsigned iter = 0; iter < _nIter; iter++ ) {
138
        if( iter == _nIter - 1 ) {    // last iteration
22✔
139
            _dT = _settings->GetTEnd() - iter * _dT;
140
        }
22✔
141

142
        if( rkStages == 2 ) solRK0 = _sol;
143

22✔
144
        for( unsigned rkStep = 0; rkStep < rkStages; ++rkStep ) {
22✔
145
            // --- Prepare Boundaries and temp variables
146
            IterPreprocessing( iter + rkStep );
44✔
147

148
            // --- Compute Fluxes ---
22✔
149
            FluxUpdate();
150

151
            // --- Finite Volume Update ---
160✔
152
            FVMUpdate( iter + rkStep );
138✔
153

22✔
154
            // --- Update Solution within Runge Kutta Stages
155
            _sol = _solNew;
156
        }
138✔
157
        // --- Iter Postprocessing ---
158
        IterPostprocessing( iter );
276✔
159

160
        // --- Wall time measurement
138✔
161
        duration  = std::chrono::high_resolution_clock::now() - start;
162
        _currTime = std::chrono::duration_cast<std::chrono::duration<double>>( duration ).count();
163

138✔
164
        // --- Runge Kutta Timestep ---
165
        if( rkStages == 2 ) RKUpdate( solRK0, _sol );
166

138✔
167
        // --- Write Output ---
168
        WriteVolumeOutput( iter );
169
        WriteScalarOutput( iter );
138✔
170

171
        // --- Update Scalar Fluxes
172
        _scalarFlux = _scalarFluxNew;
138✔
173

174
        // --- Print Output ---
175
        PrintScreenOutput( iter );
138✔
176
        PrintHistoryOutput( iter );
138✔
177
        PrintVolumeOutput( iter );
178
    }
179

138✔
180
    // --- Postprocessing ---
181

182
    DrawPostSolverOutput();
138✔
183
}
138✔
184

185
void SolverBase::RKUpdate( VectorVector& sol_0, VectorVector& sol_rk ) {
186
#pragma omp parallel for
138✔
187
    for( unsigned i = 0; i < _nCells; ++i ) {
188
        _sol[i] = 0.5 * ( sol_0[i] + sol_rk[i] );
189
    }
138✔
190
}
138✔
191

138✔
192
void SolverBase::PrintVolumeOutput() const { ExportVTK( _settings->GetOutputFile(), _outputFields, _outputFieldNames, _mesh ); }
193

194
void SolverBase::PrintVolumeOutput( int currEnergy ) const {
195
    if( _settings->GetVolumeOutputFrequency() != 0 && currEnergy % (unsigned)_settings->GetVolumeOutputFrequency() == 0 ) {
196
        ExportVTK( _settings->GetOutputFile() + "_" + std::to_string( currEnergy ), _outputFields, _outputFieldNames, _mesh );
22✔
197
    }
22✔
198
    if( currEnergy == (int)_nIter - 1 ) {    // Last iteration write without suffix.
199
        ExportVTK( _settings->GetOutputFile(), _outputFields, _outputFieldNames, _mesh );
×
200
    }
×
201
}
202

203
// --- Helper ---
204
double SolverBase::ComputeTimeStep( double cfl ) const {
205
    // for pseudo 1D, set timestep to dx
206
    double dx, dy;
20✔
207
    switch( _settings->GetProblemName() ) {
208
        case PROBLEM_Checkerboard1D:
138✔
209
            dx = 7.0 / (double)_nCells;
138✔
210
            dy = 0.3;
×
211
            return cfl * ( dx * dy ) / ( dx + dy );
212
            break;
138✔
213
        case PROBLEM_Linesource1D:     // Fallthrough
22✔
214
        case PROBLEM_Meltingcube1D:    // Fallthrough
215
        case PROBLEM_Aircavity1D:
138✔
216
            dx = 3.0 / (double)_nCells;
217
            dy = 0.3;
218
            return cfl * ( dx * dy ) / ( dx + dy );
22✔
219
            break;
220
        default: break;    // 2d as normal
221
    }
22✔
222
    // 2D case
×
NEW
223
    double charSize = __DBL_MAX__;    // minimum char size of all mesh cells in the mesh
×
224
    for( unsigned j = 0; j < _nCells; j++ ) {
×
NEW
225
        double currCharSize = sqrt( _areas[j] );
×
226
        if( currCharSize < charSize ) {
NEW
227
            charSize = currCharSize;
×
228
        }
229
    }
NEW
230
    auto log         = spdlog::get( "event" );
×
NEW
231
    std::string line = "| Smallest characteristic length of a grid cell in this mesh: " + std::to_string( charSize );
×
NEW
232
    log->info( line );
×
233
    line = "| Corresponding maximal time-step: " + std::to_string( cfl * charSize );
234
    log->info( line );
22✔
235
    return cfl * charSize;
236
}
237

22✔
238
// --- IO ----
11,110✔
239
void SolverBase::PrepareScreenOutput() {
11,088✔
240
    unsigned nFields = (unsigned)_settings->GetNScreenOutput();
11,088✔
241

256✔
242
    _screenOutputFieldNames.resize( nFields );
243
    _screenOutputFields.resize( nFields );
244

66✔
245
    // Prepare all output Fields ==> Specified in option SCREEN_OUTPUT
22✔
246
    for( unsigned idx_field = 0; idx_field < nFields; idx_field++ ) {
22✔
247
        // Prepare all Output Fields per group
22✔
248

22✔
249
        // Different procedure, depending on the Group...
22✔
250
        switch( _settings->GetScreenOutput()[idx_field] ) {
251
            case MASS: _screenOutputFieldNames[idx_field] = "Mass"; break;
252
            case ITER: _screenOutputFieldNames[idx_field] = "Iter"; break;
253
            case WALL_TIME: _screenOutputFieldNames[idx_field] = "Wall time [s]"; break;
22✔
254
            case RMS_FLUX: _screenOutputFieldNames[idx_field] = "RMS flux"; break;
22✔
255
            case VTK_OUTPUT: _screenOutputFieldNames[idx_field] = "VTK out"; break;
256
            case CSV_OUTPUT: _screenOutputFieldNames[idx_field] = "CSV out"; break;
22✔
257
            case CUR_OUTFLOW: _screenOutputFieldNames[idx_field] = "Cur. outflow"; break;
22✔
258
            case TOTAL_OUTFLOW: _screenOutputFieldNames[idx_field] = "Tot. outflow"; break;
259
            case MAX_OUTFLOW: _screenOutputFieldNames[idx_field] = "Max outflow"; break;
260
            case CUR_PARTICLE_ABSORPTION: _screenOutputFieldNames[idx_field] = "Cur. absorption"; break;
116✔
261
            case TOTAL_PARTICLE_ABSORPTION: _screenOutputFieldNames[idx_field] = "Tot. absorption"; break;
262
            case MAX_PARTICLE_ABSORPTION: _screenOutputFieldNames[idx_field] = "Max absorption"; break;
263
            case TOTAL_PARTICLE_ABSORPTION_CENTER: _screenOutputFieldNames[idx_field] = "Tot. abs. center"; break;
264
            case TOTAL_PARTICLE_ABSORPTION_VERTICAL: _screenOutputFieldNames[idx_field] = "Tot. abs. vertical wall"; break;
94✔
265
            case TOTAL_PARTICLE_ABSORPTION_HORIZONTAL: _screenOutputFieldNames[idx_field] = "Tot. abs. horizontal wall"; break;
22✔
266
            case PROBE_MOMENT_TIME_TRACE:
22✔
NEW
267
                _screenOutputFieldNames[idx_field] = "Probe 1 u_0";
×
268
                idx_field++;
22✔
269
                _screenOutputFieldNames[idx_field] = "Probe 2 u_0";
22✔
270
                if( _settings->GetProblemName() == PROBLEM_SymmetricHohlraum ) {
6✔
NEW
271
                    idx_field++;
×
NEW
272
                    _screenOutputFieldNames[idx_field] = "Probe 3 u_0";
×
NEW
273
                    idx_field++;
×
NEW
274
                    _screenOutputFieldNames[idx_field] = "Probe 4 u_0";
×
NEW
275
                }
×
NEW
276
                break;
×
NEW
277
            case VAR_ABSORPTION_GREEN: _screenOutputFieldNames[idx_field] = "Var. absorption green"; break;
×
UNCOV
278
            default: ErrorMessages::Error( "Screen output field not defined!", CURRENT_FUNCTION ); break;
×
UNCOV
279
        }
×
UNCOV
280
    }
×
UNCOV
281
}
×
UNCOV
282

×
NEW
283
void SolverBase::WriteScalarOutput( unsigned idx_iter ) {
×
NEW
284
    unsigned n_probes = 4;
×
UNCOV
285

×
NEW
286
    unsigned nFields                  = (unsigned)_settings->GetNScreenOutput();
×
NEW
287
    const VectorVector probingMoments = _problem->GetCurrentProbeMoment();
×
UNCOV
288
    // -- Screen Output
×
289
    for( unsigned idx_field = 0; idx_field < nFields; idx_field++ ) {
UNCOV
290
        // Prepare all Output Fields per group
×
UNCOV
291
        // Different procedure, depending on the Group...
×
292
        switch( _settings->GetScreenOutput()[idx_field] ) {
×
293
            case MASS: _screenOutputFields[idx_field] = _problem->GetMass(); break;
294
            case ITER: _screenOutputFields[idx_field] = idx_iter; break;
295
            case WALL_TIME: _screenOutputFields[idx_field] = _currTime; break;
22✔
296
            case RMS_FLUX: _screenOutputFields[idx_field] = _problem->GetChangeRateFlux(); break;
297
            case VTK_OUTPUT:
138✔
298
                _screenOutputFields[idx_field] = 0;
138✔
299
                if( ( _settings->GetVolumeOutputFrequency() != 0 && idx_iter % (unsigned)_settings->GetVolumeOutputFrequency() == 0 ) ||
300
                    ( idx_iter == _nIter - 1 ) /* need sol at last iteration */ ) {
138✔
301
                    _screenOutputFields[idx_field] = 1;
276✔
302
                }
303
                break;
768✔
304
            case CSV_OUTPUT:
305
                _screenOutputFields[idx_field] = 0;
306
                if( ( _settings->GetHistoryOutputFrequency() != 0 && idx_iter % (unsigned)_settings->GetHistoryOutputFrequency() == 0 ) ||
630✔
307
                    ( idx_iter == _nIter - 1 ) /* need sol at last iteration */ ) {
138✔
308
                    _screenOutputFields[idx_field] = 1;
138✔
UNCOV
309
                }
×
310
                break;
138✔
311
            case CUR_OUTFLOW: _screenOutputFields[idx_field] = _problem->GetCurrentOutflow(); break;
138✔
312
            case TOTAL_OUTFLOW: _screenOutputFields[idx_field] = _problem->GetTotalOutflow(); break;
138✔
313
            case MAX_OUTFLOW: _screenOutputFields[idx_field] = _problem->GetMaxOrdinatewiseOutflow(); break;
276✔
314
            case CUR_PARTICLE_ABSORPTION: _screenOutputFields[idx_field] = _problem->GetCurAbsorptionLattice(); break;
138✔
315
            case TOTAL_PARTICLE_ABSORPTION: _screenOutputFields[idx_field] = _problem->GetTotalAbsorptionLattice(); break;
22✔
316
            case MAX_PARTICLE_ABSORPTION: _screenOutputFields[idx_field] = _problem->GetMaxAbsorptionLattice(); break;
317
            case TOTAL_PARTICLE_ABSORPTION_CENTER: _screenOutputFields[idx_field] = _problem->GetTotalAbsorptionHohlraumCenter(); break;
138✔
318
            case TOTAL_PARTICLE_ABSORPTION_VERTICAL: _screenOutputFields[idx_field] = _problem->GetTotalAbsorptionHohlraumVertical(); break;
78✔
319
            case TOTAL_PARTICLE_ABSORPTION_HORIZONTAL: _screenOutputFields[idx_field] = _problem->GetTotalAbsorptionHohlraumHorizontal(); break;
78✔
320
            case PROBE_MOMENT_TIME_TRACE:
150✔
321
                if( _settings->GetProblemName() == PROBLEM_SymmetricHohlraum ) n_probes = 4;
72✔
322
                if( _settings->GetProblemName() == PROBLEM_QuarterHohlraum ) n_probes = 2;
10✔
323
                for( unsigned i = 0; i < n_probes; i++ ) {
324
                    _screenOutputFields[idx_field] = probingMoments[i][0];
78✔
NEW
325
                    idx_field++;
×
NEW
326
                }
×
NEW
327
                idx_field--;
×
NEW
328
                break;
×
NEW
329
            case VAR_ABSORPTION_GREEN: _screenOutputFields[idx_field] = _problem->GetVarAbsorptionHohlraumGreen(); break;
×
UNCOV
330
            default: ErrorMessages::Error( "Screen output group not defined!", CURRENT_FUNCTION ); break;
×
UNCOV
331
        }
×
UNCOV
332
    }
×
UNCOV
333

×
UNCOV
334
    // --- History output ---
×
UNCOV
335
    nFields = (unsigned)_settings->GetNHistoryOutput();
×
UNCOV
336

×
UNCOV
337
    std::vector<SCALAR_OUTPUT> screenOutputFields = _settings->GetScreenOutput();
×
UNCOV
338
    for( unsigned idx_field = 0; idx_field < nFields; idx_field++ ) {
×
UNCOV
339

×
340
        // Prepare all Output Fields per group
UNCOV
341
        // Different procedure, depending on the Group...
×
UNCOV
342
        switch( _settings->GetHistoryOutput()[idx_field] ) {
×
NEW
343
            case MASS: _historyOutputFields[idx_field] = _problem->GetMass(); break;
×
NEW
344
            case ITER: _historyOutputFields[idx_field] = idx_iter; break;
×
345
            case WALL_TIME: _historyOutputFields[idx_field] = _currTime; break;
346
            case RMS_FLUX: _historyOutputFields[idx_field] = _problem->GetChangeRateFlux(); break;
347
            case VTK_OUTPUT:
348
                _historyOutputFields[idx_field] = 0;
349
                if( ( _settings->GetVolumeOutputFrequency() != 0 && idx_iter % (unsigned)_settings->GetVolumeOutputFrequency() == 0 ) ||
138✔
350
                    ( idx_iter == _nIter - 1 ) /* need sol at last iteration */ ) {
351
                    _historyOutputFields[idx_field] = 1;
276✔
352
                }
828✔
353
                break;
354

355
            case CSV_OUTPUT:
356
                _historyOutputFields[idx_field] = 0;
690✔
357
                if( ( _settings->GetHistoryOutputFrequency() != 0 && idx_iter % (unsigned)_settings->GetHistoryOutputFrequency() == 0 ) ||
138✔
358
                    ( idx_iter == _nIter - 1 ) /* need sol at last iteration */ ) {
138✔
UNCOV
359
                    _historyOutputFields[idx_field] = 1;
×
360
                }
138✔
361
                break;
138✔
362
            case CUR_OUTFLOW: _historyOutputFields[idx_field] = _problem->GetCurrentOutflow(); break;
138✔
363
            case TOTAL_OUTFLOW: _historyOutputFields[idx_field] = _problem->GetTotalOutflow(); break;
276✔
364
            case MAX_OUTFLOW: _historyOutputFields[idx_field] = _problem->GetMaxOrdinatewiseOutflow(); break;
138✔
365
            case CUR_PARTICLE_ABSORPTION: _historyOutputFields[idx_field] = _problem->GetCurAbsorptionLattice(); break;
22✔
366
            case TOTAL_PARTICLE_ABSORPTION: _historyOutputFields[idx_field] = _problem->GetTotalAbsorptionLattice(); break;
367
            case MAX_PARTICLE_ABSORPTION: _historyOutputFields[idx_field] = _problem->GetMaxAbsorptionLattice(); break;
138✔
368
            case TOTAL_PARTICLE_ABSORPTION_CENTER: _historyOutputFields[idx_field] = _problem->GetTotalAbsorptionHohlraumCenter(); break;
369
            case TOTAL_PARTICLE_ABSORPTION_VERTICAL: _historyOutputFields[idx_field] = _problem->GetTotalAbsorptionHohlraumVertical(); break;
138✔
370
            case TOTAL_PARTICLE_ABSORPTION_HORIZONTAL: _historyOutputFields[idx_field] = _problem->GetTotalAbsorptionHohlraumHorizontal(); break;
138✔
371
            case PROBE_MOMENT_TIME_TRACE:
210✔
372
                if( _settings->GetProblemName() == PROBLEM_SymmetricHohlraum ) n_probes = 4;
72✔
373
                if( _settings->GetProblemName() == PROBLEM_QuarterHohlraum ) n_probes = 2;
70✔
374
                for( unsigned i = 0; i < n_probes; i++ ) {
375
                    for( unsigned j = 0; j < 3; j++ ) {
138✔
NEW
376
                        _historyOutputFields[idx_field] = probingMoments[i][j];
×
NEW
377
                        idx_field++;
×
NEW
378
                    }
×
NEW
379
                }
×
NEW
380
                idx_field--;
×
NEW
381
                break;
×
NEW
382
            case VAR_ABSORPTION_GREEN: _historyOutputFields[idx_field] = _problem->GetVarAbsorptionHohlraumGreen(); break;
×
NEW
383
            case ABSORPTION_GREEN_LINE:
×
NEW
384
                for( unsigned i = 0; i < _settings->GetNumProbingCellsLineHohlraum(); i++ ) {
×
NEW
385
                    _historyOutputFieldNames[idx_field] = _problem->GetCurrentVarProbeValuesGreenLine()[i];
×
NEW
386
                    idx_field++;
×
NEW
387
                }
×
NEW
388
                idx_field--;
×
NEW
389
                break;
×
UNCOV
390
            default: ErrorMessages::Error( "History output group not defined!", CURRENT_FUNCTION ); break;
×
UNCOV
391
        }
×
392
    }
393
}
UNCOV
394

×
NEW
395
void SolverBase::PrintScreenOutput( unsigned idx_iter ) {
×
UNCOV
396
    auto log = spdlog::get( "event" );
×
UNCOV
397

×
NEW
398
    unsigned strLen  = 15;    // max width of one column
×
UNCOV
399
    char paddingChar = ' ';
×
UNCOV
400

×
401
    // assemble the line to print
UNCOV
402
    std::string lineToPrint = "| ";
×
UNCOV
403
    std::string tmp;
×
UNCOV
404
    for( unsigned idx_field = 0; idx_field < _settings->GetNScreenOutput(); idx_field++ ) {
×
405
        tmp = std::to_string( _screenOutputFields[idx_field] );
406

407
        // Format outputs correctly
138✔
408
        std::vector<SCALAR_OUTPUT> integerFields    = { ITER };
409
        std::vector<SCALAR_OUTPUT> scientificFields = { RMS_FLUX,
138✔
410
                                                        MASS,
414✔
411
                                                        WALL_TIME,
412
                                                        CUR_OUTFLOW,
138✔
413
                                                        TOTAL_OUTFLOW,
138✔
414
                                                        MAX_OUTFLOW,
415
                                                        CUR_PARTICLE_ABSORPTION,
416
                                                        TOTAL_PARTICLE_ABSORPTION,
276✔
417
                                                        MAX_PARTICLE_ABSORPTION,
276✔
418
                                                        TOTAL_PARTICLE_ABSORPTION_CENTER,
768✔
419
                                                        TOTAL_PARTICLE_ABSORPTION_VERTICAL,
630✔
420
                                                        TOTAL_PARTICLE_ABSORPTION_HORIZONTAL,
421
                                                        PROBE_MOMENT_TIME_TRACE,
422
                                                        VAR_ABSORPTION_GREEN,
1,260✔
423
                                                        ABSORPTION_GREEN_BLOCK,
424
                                                        ABSORPTION_GREEN_LINE };
425
        std::vector<SCALAR_OUTPUT> booleanFields    = { VTK_OUTPUT, CSV_OUTPUT };
426

427
        if( !( integerFields.end() == std::find( integerFields.begin(), integerFields.end(), _settings->GetScreenOutput()[idx_field] ) ) ) {
428
            tmp = std::to_string( (int)_screenOutputFields[idx_field] );
429
        }
430
        else if( !( booleanFields.end() == std::find( booleanFields.begin(), booleanFields.end(), _settings->GetScreenOutput()[idx_field] ) ) ) {
431
            tmp = "no";
432
            if( (bool)_screenOutputFields[idx_field] ) tmp = "yes";
433
        }
434
        else if( !( scientificFields.end() ==
435
                    std::find( scientificFields.begin(), scientificFields.end(), _settings->GetScreenOutput()[idx_field] ) ) ) {
436

437
            std::stringstream ss;
438
            ss << TextProcessingToolbox::DoubleToScientificNotation( _screenOutputFields[idx_field] );
1,260✔
439
            tmp = ss.str();
630✔
440
            tmp.erase( std::remove( tmp.begin(), tmp.end(), '+' ), tmp.end() );    // removing the '+' sign
441
        }
630✔
442

138✔
443
        if( strLen > tmp.size() )    // Padding
444
            tmp.insert( 0, strLen - tmp.size(), paddingChar );
492✔
445
        else if( strLen < tmp.size() )    // Cutting
216✔
446
            tmp.resize( strLen );
216✔
447

448
        lineToPrint += tmp + " |";
276✔
449
    }
552✔
450
    if( _settings->GetScreenOutputFrequency() != 0 && idx_iter % (unsigned)_settings->GetScreenOutputFrequency() == 0 ) {
451
        log->info( lineToPrint );
276✔
452
    }
276✔
453
    else if( idx_iter == _nIter - 1 ) {    // Always print last iteration
276✔
454
        log->info( lineToPrint );
276✔
455
    }
456
}
457

630✔
458
void SolverBase::PrepareHistoryOutput() {
630✔
NEW
459
    unsigned n_probes = 4;
×
NEW
460

×
461
    unsigned nFields = (unsigned)_settings->GetNHistoryOutput();
462

630✔
463
    _historyOutputFieldNames.resize( nFields );
464
    _historyOutputFields.resize( nFields );
138✔
465

138✔
466
    // Prepare all output Fields ==> Specified in option SCREEN_OUTPUT
UNCOV
467
    for( unsigned idx_field = 0; idx_field < nFields; idx_field++ ) {
×
468
        // Prepare all Output Fields per group
×
469

470
        // Different procedure, depending on the Group...
138✔
471
        switch( _settings->GetHistoryOutput()[idx_field] ) {
472
            case MASS: _historyOutputFieldNames[idx_field] = "Mass"; break;
22✔
473
            case ITER: _historyOutputFieldNames[idx_field] = "Iter"; break;
22✔
474
            case WALL_TIME: _historyOutputFieldNames[idx_field] = "Wall_time_[s]"; break;
475
            case RMS_FLUX: _historyOutputFieldNames[idx_field] = "RMS_flux"; break;
22✔
476
            case VTK_OUTPUT: _historyOutputFieldNames[idx_field] = "VTK_out"; break;
477
            case CSV_OUTPUT: _historyOutputFieldNames[idx_field] = "CSV_out"; break;
22✔
478
            case CUR_OUTFLOW: _historyOutputFieldNames[idx_field] = "Cur_outflow"; break;
22✔
479
            case TOTAL_OUTFLOW: _historyOutputFieldNames[idx_field] = "Total_outflow"; break;
480
            case MAX_OUTFLOW: _historyOutputFieldNames[idx_field] = "Max_outflow"; break;
481
            case CUR_PARTICLE_ABSORPTION: _historyOutputFieldNames[idx_field] = "Cur_absorption"; break;
132✔
482
            case TOTAL_PARTICLE_ABSORPTION: _historyOutputFieldNames[idx_field] = "Total_absorption"; break;
483
            case MAX_PARTICLE_ABSORPTION: _historyOutputFieldNames[idx_field] = "Max_absorption"; break;
484
            case TOTAL_PARTICLE_ABSORPTION_CENTER: _historyOutputFieldNames[idx_field] = "Cumulated_absorption_center"; break;
485
            case TOTAL_PARTICLE_ABSORPTION_VERTICAL: _historyOutputFieldNames[idx_field] = "Cumulated_absorption_vertical_wall"; break;
110✔
486
            case TOTAL_PARTICLE_ABSORPTION_HORIZONTAL: _historyOutputFieldNames[idx_field] = "Cumulated_absorption_horizontal_wall"; break;
22✔
487
            case PROBE_MOMENT_TIME_TRACE:
22✔
NEW
488
                if( _settings->GetProblemName() == PROBLEM_SymmetricHohlraum ) n_probes = 4;
×
489
                if( _settings->GetProblemName() == PROBLEM_QuarterHohlraum ) n_probes = 2;
22✔
490
                for( unsigned i = 0; i < n_probes; i++ ) {
22✔
491
                    for( unsigned j = 0; j < 3; j++ ) {
22✔
NEW
492
                        _historyOutputFieldNames[idx_field] = "Probe " + std::to_string( i ) + " u_" + std::to_string( j );
×
NEW
493
                        idx_field++;
×
NEW
494
                    }
×
NEW
495
                }
×
NEW
496
                idx_field--;
×
NEW
497
                break;
×
NEW
498
            case VAR_ABSORPTION_GREEN: _historyOutputFieldNames[idx_field] = "Var. absorption green"; break;
×
NEW
499
            case ABSORPTION_GREEN_LINE:
×
NEW
500
                for( unsigned i = 0; i < _settings->GetNumProbingCellsLineHohlraum(); i++ ) {
×
NEW
501
                    _historyOutputFieldNames[idx_field] = "Probe Green Line " + std::to_string( i );
×
NEW
502
                    idx_field++;
×
NEW
503
                }
×
NEW
504
                idx_field--;
×
NEW
505
                break;
×
UNCOV
506
            default: ErrorMessages::Error( "History output field not defined!", CURRENT_FUNCTION ); break;
×
UNCOV
507
        }
×
508
    }
509
}
UNCOV
510

×
NEW
511
void SolverBase::PrintHistoryOutput( unsigned idx_iter ) {
×
NEW
512

×
UNCOV
513
    auto log = spdlog::get( "tabular" );
×
UNCOV
514

×
UNCOV
515
    // assemble the line to print
×
UNCOV
516
    std::string lineToPrint = "";
×
517
    std::string tmp;
NEW
518
    for( int idx_field = 0; idx_field < _settings->GetNHistoryOutput() - 1; idx_field++ ) {
×
NEW
519
        if( idx_field == 0 ) {
×
NEW
520
            tmp = std::to_string( _historyOutputFields[idx_field] );    // Iteration count
×
521
        }
522
        else {
523
            tmp = TextProcessingToolbox::DoubleToScientificNotation( _historyOutputFields[idx_field] );
22✔
524
        }
525
        lineToPrint += tmp + ",";
138✔
526
    }
527
    tmp = TextProcessingToolbox::DoubleToScientificNotation( _historyOutputFields[_settings->GetNScreenOutput() - 1] );
414✔
528
    lineToPrint += tmp;    // Last element without comma
529

530
    if( _settings->GetHistoryOutputFrequency() != 0 && idx_iter % (unsigned)_settings->GetHistoryOutputFrequency() == 0 ) {
276✔
531
        log->info( lineToPrint );
276✔
532
    }
690✔
533
    else if( idx_iter == _nEnergies - 1 ) {    // Always print last iteration
552✔
534
        log->info( lineToPrint );
138✔
535
    }
536
}
537

414✔
538
void SolverBase::DrawPreSolverOutput() {
539

552✔
540
    // Logger
541
    auto log    = spdlog::get( "event" );
138✔
542
    auto logCSV = spdlog::get( "tabular" );
138✔
543

544
    std::string hLine = "--";
138✔
545

66✔
546
    unsigned strLen  = 15;    // max width of one column
547
    char paddingChar = ' ';
72✔
UNCOV
548

×
549
    // Assemble Header for Screen Output
550
    std::string lineToPrint = "| ";
138✔
551
    std::string tmpLine     = "-----------------";
552
    for( unsigned idxFields = 0; idxFields < _settings->GetNScreenOutput(); idxFields++ ) {
22✔
553
        std::string tmp = _screenOutputFieldNames[idxFields];
554

555
        if( strLen > tmp.size() )    // Padding
66✔
556
            tmp.insert( 0, strLen - tmp.size(), paddingChar );
66✔
557
        else if( strLen < tmp.size() )    // Cutting
558
            tmp.resize( strLen );
44✔
559

560
        lineToPrint += tmp + " |";
22✔
561
        hLine += tmpLine;
22✔
562
    }
563
    log->info( "---------------------------- Solver Starts -----------------------------" );
564
    log->info( "| The simulation will run for {} iterations.", _nEnergies );
44✔
565
    log->info( "| The spatial grid contains {} cells.", _nCells );
44✔
566
    if( _settings->GetSolverName() != PN_SOLVER && _settings->GetSolverName() != CSD_PN_SOLVER ) {
116✔
567
        log->info( "| The velocity grid contains {} points.", _quadrature->GetNq() );
188✔
568
    }
569
    log->info( hLine );
94✔
570
    log->info( lineToPrint );
94✔
NEW
571
    log->info( hLine );
×
NEW
572

×
573
    std::string lineToPrintCSV = "";
574
    for( int idxFields = 0; idxFields < _settings->GetNHistoryOutput() - 1; idxFields++ ) {
94✔
575
        std::string tmp = _historyOutputFieldNames[idxFields];
94✔
576
        lineToPrintCSV += tmp + ",";
577
    }
22✔
578
    lineToPrintCSV += _historyOutputFieldNames[_settings->GetNHistoryOutput() - 1];
22✔
579
    logCSV->info( lineToPrintCSV );
22✔
580
}
22✔
581

14✔
582
void SolverBase::DrawPostSolverOutput() {
583

22✔
584
    // Logger
22✔
585
    auto log = spdlog::get( "event" );
22✔
586

587
    std::string hLine = "--";
44✔
588

110✔
589
    unsigned strLen  = 10;    // max width of one column
88✔
590
    char paddingChar = ' ';
88✔
591

592
    // Assemble Header for Screen Output
22✔
593
    std::string lineToPrint = "| ";
22✔
594
    std::string tmpLine     = "------------";
22✔
595
    for( unsigned idxFields = 0; idxFields < _settings->GetNScreenOutput(); idxFields++ ) {
596
        std::string tmp = _screenOutputFieldNames[idxFields];
22✔
597

598
        if( strLen > tmp.size() )    // Padding
599
            tmp.insert( 0, strLen - tmp.size(), paddingChar );
66✔
600
        else if( strLen < tmp.size() )    // Cutting
601
            tmp.resize( strLen );
44✔
602

603
        lineToPrint += tmp + " |";
22✔
604
        hLine += tmpLine;
22✔
605
    }
606
    log->info( hLine );
607
#ifndef BUILD_TESTING
44✔
608
    log->info( "| The volume output files have been stored at " + _settings->GetOutputFile() );
44✔
609
    log->info( "| The log files have been stored at " + _settings->GetLogDir() + _settings->GetLogFile() );
116✔
610
#endif
188✔
611
    log->info( "--------------------------- Solver Finished ----------------------------" );
612
}
94✔
613

94✔
614
void SolverBase::SolverPreprocessing() {}
×
NEW
615

×
616
void SolverBase::IterPostprocessing( unsigned /*idx_iter*/ ) {
617
    // --- Compute Quantities of interest for Volume and Screen Output ---
94✔
618
    ComputeScalarFlux();    // Needs to be called first is a solver function
94✔
619

620
    _problem->ComputeMass( _scalarFluxNew );
22✔
621
    _problem->ComputeChangeRateFlux( _scalarFlux, _scalarFluxNew );
622

623
    _problem->ComputeCurrentOutflow( _sol );
624
    _problem->ComputeTotalOutflow( _dT );
625
    _problem->ComputeMaxOrdinatewiseOutflow( _sol );
22✔
626

22✔
627
    if( _settings->GetProblemName() == PROBLEM_Lattice || _settings->GetProblemName() == PROBLEM_HalfLattice ) {
628
        _problem->ComputeCurrentAbsorptionLattice( _scalarFlux );
18✔
629
        _problem->ComputeTotalAbsorptionLattice( _dT );
630
        _problem->ComputeMaxAbsorptionLattice( _scalarFlux );
66✔
631
    }
632
    if( _settings->GetProblemName() == PROBLEM_SymmetricHohlraum || _settings->GetProblemName() == PROBLEM_QuarterHohlraum ) {
66✔
633
        _problem->ComputeCurrentAbsorptionHohlraum( _scalarFlux );    // Unify
634
        _problem->ComputeTotalAbsorptionHohlraum( _dT );              // Unify and parallelize
66✔
635
        _problem->ComputeCurrentProbeMoment( _sol );
66✔
636
        _problem->ComputeVarAbsorptionGreen( _scalarFlux );
637
        _problem->ComputeQOIsGreenProbingLine( _scalarFlux );
66✔
638
    }
66✔
639
}
66✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc