99#include " quadratures/quadraturebase.hpp"
1010#include " solvers/snsolver_hpc.hpp"
1111#include " toolboxes/textprocessingtoolbox.hpp"
12+ #include < cassert>
1213
1314SNSolverHPC::SNSolverHPC ( Config* settings ) {
1415#ifdef IMPORT_MPI
@@ -286,7 +287,8 @@ void SNSolverHPC::Solve() {
286287 PrepareVolumeOutput ();
287288 DrawPreSolverOutput ();
288289 }
289- _curSimTime = 0.0 ;
290+ // On restart, continue simulation time from the loaded iteration index.
291+ _curSimTime = static_cast <double >( _idx_start_iter ) * _dT;
290292 auto start = std::chrono::high_resolution_clock::now (); // Start timing
291293
292294 std::chrono::duration<double > duration;
@@ -311,6 +313,25 @@ void SNSolverHPC::Solve() {
311313 _sol[Idx2D ( idx_cell, idx_sys, _localNSys )] ); // Solution averaging with HEUN
312314 }
313315 }
316+
317+ // Keep scalar flux consistent with the final RK2-averaged solution used in postprocessing.
318+ std::vector<double > temp_scalarFluxRK ( _nCells, 0.0 );
319+ #pragma omp parallel for
320+ for ( unsigned long idx_cell = 0 ; idx_cell < _nCells; ++idx_cell ) {
321+ double localScalarFlux = 0.0 ;
322+ #pragma omp simd reduction( + : localScalarFlux )
323+ for ( unsigned long idx_sys = 0 ; idx_sys < _localNSys; idx_sys++ ) {
324+ localScalarFlux += _sol[Idx2D ( idx_cell, idx_sys, _localNSys )] * _quadWeights[idx_sys];
325+ }
326+ temp_scalarFluxRK[idx_cell] = localScalarFlux;
327+ }
328+ #ifdef IMPORT_MPI
329+ MPI_Barrier ( MPI_COMM_WORLD );
330+ MPI_Allreduce ( temp_scalarFluxRK.data (), _scalarFlux.data (), _nCells, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD );
331+ MPI_Barrier ( MPI_COMM_WORLD );
332+ #else
333+ _scalarFlux = temp_scalarFluxRK;
334+ #endif
314335 }
315336 else {
316337
@@ -334,12 +355,12 @@ void SNSolverHPC::Solve() {
334355 PrintScreenOutput ( iter );
335356 PrintHistoryOutput ( iter );
336357 }
337- #ifdef BUILD_MPI
358+ #ifdef IMPORT_MPI
338359 MPI_Barrier ( MPI_COMM_WORLD );
339360#endif
340361
341362 PrintVolumeOutput ( iter );
342- #ifdef BUILD_MPI
363+ #ifdef IMPORT_MPI
343364 MPI_Barrier ( MPI_COMM_WORLD );
344365#endif
345366 }
@@ -536,8 +557,9 @@ void SNSolverHPC::FVMUpdate() {
536557 _mass = 0.0 ;
537558 _rmsFlux = 0.0 ;
538559 std::vector<double > temp_scalarFlux ( _nCells ); // for MPI allreduce
560+ std::vector<double > prev_scalarFlux ( _scalarFlux );
539561
540- #pragma omp parallel for reduction( + : _mass, _rmsFlux )
562+ #pragma omp parallel for reduction( + : _mass )
541563 for ( unsigned long idx_cell = 0 ; idx_cell < _nCells; ++idx_cell ) {
542564
543565#pragma omp simd
@@ -556,17 +578,27 @@ void SNSolverHPC::FVMUpdate() {
556578 localScalarFlux += _sol[Idx2D ( idx_cell, idx_sys, _localNSys )] * _quadWeights[idx_sys];
557579 }
558580 _mass += localScalarFlux * _areas[idx_cell];
559- _rmsFlux += ( localScalarFlux - _scalarFlux[idx_cell] ) * ( localScalarFlux - _scalarFlux[idx_cell] );
560581 temp_scalarFlux[idx_cell] = localScalarFlux; // set flux
561582 }
562583// MPI Allreduce: _scalarFlux
563584#ifdef IMPORT_MPI
564585 MPI_Barrier ( MPI_COMM_WORLD );
565586 MPI_Allreduce ( temp_scalarFlux.data (), _scalarFlux.data (), _nCells, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD );
566587 MPI_Barrier ( MPI_COMM_WORLD );
588+ if ( _rank == 0 ) {
589+ for ( unsigned long idx_cell = 0 ; idx_cell < _nCells; ++idx_cell ) {
590+ double diff = _scalarFlux[idx_cell] - prev_scalarFlux[idx_cell];
591+ _rmsFlux += diff * diff;
592+ }
593+ }
567594#endif
568595#ifndef IMPORT_MPI
569596 _scalarFlux = temp_scalarFlux;
597+ #pragma omp parallel for reduction( + : _rmsFlux )
598+ for ( unsigned long idx_cell = 0 ; idx_cell < _nCells; ++idx_cell ) {
599+ double diff = _scalarFlux[idx_cell] - prev_scalarFlux[idx_cell];
600+ _rmsFlux += diff * diff;
601+ }
570602#endif
571603}
572604
@@ -714,6 +746,7 @@ void SNSolverHPC::IterPostprocessing() {
714746 double tmp_curScalarOutflow = 0.0 ;
715747 double tmp_curScalarOutflowPeri1 = 0.0 ;
716748 double tmp_curScalarOutflowPeri2 = 0.0 ;
749+ double tmp_curMaxOrdinateOutflow = 0.0 ;
717750 double tmp_mass = 0.0 ;
718751 double tmp_rmsFlux = 0.0 ;
719752 MPI_Barrier ( MPI_COMM_WORLD );
@@ -726,6 +759,9 @@ void SNSolverHPC::IterPostprocessing() {
726759 MPI_Allreduce ( &_curScalarOutflowPeri2, &tmp_curScalarOutflowPeri2, 1 , MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD );
727760 _curScalarOutflowPeri2 = tmp_curScalarOutflowPeri2;
728761 MPI_Barrier ( MPI_COMM_WORLD );
762+ MPI_Allreduce ( &_curMaxOrdinateOutflow, &tmp_curMaxOrdinateOutflow, 1 , MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD );
763+ _curMaxOrdinateOutflow = tmp_curMaxOrdinateOutflow;
764+ MPI_Barrier ( MPI_COMM_WORLD );
729765 MPI_Allreduce ( &_mass, &tmp_mass, 1 , MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD );
730766 _mass = tmp_mass;
731767 MPI_Barrier ( MPI_COMM_WORLD );
@@ -973,7 +1009,7 @@ void SNSolverHPC::WriteScalarOutput( unsigned idx_iter ) {
9731009 }
9741010 idx_field--;
9751011 break ;
976- case VAR_ABSORPTION_GREEN: _screenOutputFields[idx_field] = _absorptionValsBlocksGreen[ 0 ] ; break ;
1012+ case VAR_ABSORPTION_GREEN: _screenOutputFields[idx_field] = _varAbsorptionHohlraumGreen ; break ;
9771013 default : ErrorMessages::Error ( " Screen output group not defined!" , CURRENT_FUNCTION ); break ;
9781014 }
9791015 }
@@ -1318,7 +1354,7 @@ void SNSolverHPC::WriteVolumeOutput( unsigned idx_iter ) {
13181354 _quadPts[Idx2D ( idx_sys, 1 , _nDim )] * _sol[Idx2D ( idx_cell, idx_sys, _localNSys )] * _quadWeights[idx_sys];
13191355 }
13201356 }
1321- #ifdef BUILD_MPI
1357+ #ifdef IMPORT_MPI
13221358 MPI_Barrier ( MPI_COMM_WORLD );
13231359 MPI_Allreduce (
13241360 _outputFields[idx_group][0 ].data (), _outputFields[idx_group][0 ].data (), _nCells, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD );
@@ -1455,28 +1491,8 @@ void SNSolverHPC::SetGhostCells() {
14551491
14561492void SNSolverHPC::SetProbingCellsLineGreen () {
14571493
1458- // if( _settings->GetProblemName() == PROBLEM_QuarterHohlraum ) {
1459- // double verticalLineWidth = std::abs( _cornerUpperLeftGreen[1] - _cornerLowerLeftGreen[1] );
1460- // double horizontalLineWidth = std::abs( _cornerUpperLeftGreen[0] - _cornerUpperRightGreen[0] );
1461- //
1462- // // double dx = 2 * ( horizontalLineWidth + verticalLineWidth ) / ( (double)_nProbingCellsLineGreen );
1463- //
1464- // unsigned nHorizontalProbingCells =
1465- // (unsigned)std::ceil( _nProbingCellsLineGreen * ( horizontalLineWidth / ( horizontalLineWidth + verticalLineWidth ) ) );
1466- // unsigned nVerticalProbingCells = _nProbingCellsLineGreen - nHorizontalProbingCells;
1467- //
1468- // _probingCellsLineGreen = std::vector<unsigned>( _nProbingCellsLineGreen );
1469- //
1470- // // Sample points on each side of the rectangle
1471- // std::vector<unsigned> side3 = linspace2D( _cornerLowerRightGreen, _cornerUpperRightGreen, nVerticalProbingCells );
1472- // std::vector<unsigned> side4 = linspace2D( _cornerUpperRightGreen, _cornerUpperLeftGreen, nHorizontalProbingCells );
1473- //
1474- // // Combine the points from each side
1475- // _probingCellsLineGreen.insert( _probingCellsLineGreen.end(), side3.begin(), side3.end() );
1476- // _probingCellsLineGreen.insert( _probingCellsLineGreen.end(), side4.begin(), side4.end() );
1477- // }
1478- // else
14791494 if ( _settings->GetProblemName () == PROBLEM_SymmetricHohlraum ) {
1495+ assert ( _nProbingCellsLineGreen % 2 == 0 );
14801496
14811497 std::vector<double > p1 = { _cornerUpperLeftGreen[0 ] + _thicknessGreen / 2.0 , _cornerUpperLeftGreen[1 ] - _thicknessGreen / 2.0 };
14821498 std::vector<double > p2 = { _cornerUpperRightGreen[0 ] - _thicknessGreen / 2.0 , _cornerUpperRightGreen[1 ] - _thicknessGreen / 2.0 };
@@ -1490,6 +1506,8 @@ void SNSolverHPC::SetProbingCellsLineGreen() {
14901506
14911507 unsigned nHorizontalProbingCells = (unsigned )std::ceil ( _nProbingCellsLineGreen / 2 * pt_ratio_h );
14921508 unsigned nVerticalProbingCells = _nProbingCellsLineGreen / 2 - nHorizontalProbingCells;
1509+ assert ( nHorizontalProbingCells > 1 );
1510+ assert ( nVerticalProbingCells > 1 );
14931511
14941512 _probingCellsLineGreen = std::vector<unsigned >( 2 * ( nVerticalProbingCells + nHorizontalProbingCells ) );
14951513
@@ -1517,13 +1535,15 @@ void SNSolverHPC::SetProbingCellsLineGreen() {
15171535 std::vector<std::vector<std::vector<double >>> block_corners;
15181536
15191537 double block_size = 0.05 ;
1538+ const double cx = _centerGreen[0 ];
1539+ const double cy = _centerGreen[1 ];
15201540
15211541 // Loop to fill the blocks
15221542 for ( int i = 0 ; i < 8 ; ++i ) { // 8 blocks in the x-direction (horizontal) (upper) (left to right)
15231543
15241544 // Top row
1525- double x1 = -0.2 + i * block_size;
1526- double y1 = 0.4 ;
1545+ double x1 = -0.2 + cx + i * block_size;
1546+ double y1 = 0.4 + cy ;
15271547 double x2 = x1 + block_size;
15281548 double y2 = y1 - block_size;
15291549
@@ -1538,8 +1558,8 @@ void SNSolverHPC::SetProbingCellsLineGreen() {
15381558
15391559 for ( int j = 0 ; j < 14 ; ++j ) { // 14 blocks in the y-direction (vertical)
15401560 // right column double x1 = 0.15;
1541- double x1 = 0.15 ;
1542- double y1 = 0.35 - j * block_size;
1561+ double x1 = 0.15 + cx ;
1562+ double y1 = 0.35 + cy - j * block_size;
15431563 double x2 = x1 + block_size;
15441564 double y2 = y1 - block_size;
15451565
@@ -1556,8 +1576,8 @@ void SNSolverHPC::SetProbingCellsLineGreen() {
15561576
15571577 for ( int i = 0 ; i < 8 ; ++i ) { // 8 blocks in the x-direction (horizontal) (lower) (right to left)
15581578 // bottom row
1559- double x1 = 0.15 - i * block_size;
1560- double y1 = -0.35 ;
1579+ double x1 = 0.15 + cx - i * block_size;
1580+ double y1 = -0.35 + cy ;
15611581 double x2 = x1 + block_size;
15621582 double y2 = y1 - block_size;
15631583
@@ -1573,8 +1593,8 @@ void SNSolverHPC::SetProbingCellsLineGreen() {
15731593 for ( int j = 0 ; j < 14 ; ++j ) { // 14 blocks in the y-direction (vertical) (down to up)
15741594
15751595 // left column
1576- double x1 = -0.2 ;
1577- double y1 = -0.3 + j * block_size;
1596+ double x1 = -0.2 + cx ;
1597+ double y1 = -0.3 + cy + j * block_size;
15781598 double x2 = x1 + block_size;
15791599 double y2 = y1 - block_size;
15801600
@@ -1628,6 +1648,7 @@ std::vector<unsigned> SNSolverHPC::linspace2D( const std::vector<double>& start,
16281648 */
16291649
16301650 std::vector<unsigned > result;
1651+ assert ( num_points > 1 );
16311652 result.resize ( num_points );
16321653 double stepX = ( end[0 ] - start[0 ] ) / ( num_points - 1 );
16331654 double stepY = ( end[1 ] - start[1 ] ) / ( num_points - 1 );
@@ -1662,23 +1683,22 @@ void SNSolverHPC::ComputeCellsPerimeterLattice() {
16621683 continue ; // Skip boundary - ghost cells
16631684 }
16641685
1665- if ( abs ( ( cellMids[neigbors[idx_cell][idx_nbr]][0 ] ) > l_1 && abs ( cellMids[idx_cell][0 ] ) < l_1 ) ||
1666- abs ( ( cellMids[neigbors[idx_cell][idx_nbr]][1 ] ) > l_1 && abs ( cellMids[idx_cell][1 ] ) < l_1 ) ) {
1686+ if ( ( abs ( cellMids[neigbors[idx_cell][idx_nbr]][0 ] ) > l_1 && abs ( cellMids[idx_cell][0 ] ) < l_1 ) ||
1687+ ( abs ( cellMids[neigbors[idx_cell][idx_nbr]][1 ] ) > l_1 && abs ( cellMids[idx_cell][1 ] ) < l_1 ) ) {
16671688 // neighbor is outside perimeter
16681689 _cellsLatticePerimeter1[idx_cell].push_back ( idx_nbr );
16691690 _isPerimeterLatticeCell1[idx_cell] = true ;
16701691 }
16711692 }
16721693 }
1673- if ( abs ( cellMids[idx_cell][0 ] ) < l_2 && abs ( cellMids[idx_cell][1 ] ) < l_2 && abs ( cellMids[idx_cell][0 ] ) > l_1 &&
1674- abs ( cellMids[idx_cell][1 ] ) > l_1 ) {
1694+ else if ( abs ( cellMids[idx_cell][0 ] ) < l_2 && abs ( cellMids[idx_cell][1 ] ) < l_2 ) {
16751695 // Cell is within perimeter
16761696 for ( unsigned idx_nbr = 0 ; idx_nbr < _mesh->GetNumNodesPerCell (); ++idx_nbr ) {
16771697 if ( neigbors[idx_cell][idx_nbr] == _mesh->GetNumCells () ) {
16781698 continue ; // Skip boundary - ghost cells
16791699 }
1680- if ( abs ( ( cellMids[neigbors[idx_cell][idx_nbr]][0 ] ) > l_2 && abs ( cellMids[idx_cell][0 ] ) < l_2 ) ||
1681- abs ( ( cellMids[neigbors[idx_cell][idx_nbr]][1 ] ) > l_2 && abs ( cellMids[idx_cell][1 ] ) < l_2 ) ) {
1700+ if ( ( abs ( cellMids[neigbors[idx_cell][idx_nbr]][0 ] ) > l_2 && abs ( cellMids[idx_cell][0 ] ) < l_2 ) ||
1701+ ( abs ( cellMids[neigbors[idx_cell][idx_nbr]][1 ] ) > l_2 && abs ( cellMids[idx_cell][1 ] ) < l_2 ) ) {
16821702 // neighbor is outside perimeter
16831703 _cellsLatticePerimeter2[idx_cell].push_back ( idx_nbr );
16841704 _isPerimeterLatticeCell2[idx_cell] = true ;
0 commit comments