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

Open-Sn / opensn / 25478472129

07 May 2026 04:23AM UTC coverage: 75.685% (+0.3%) from 75.416%
25478472129

push

github

web-flow
Merge pull request #1057 from wdhawkins/c5g7_fixes

Updating tests.json for c5g7 tests and new iterative output.

22081 of 29175 relevant lines covered (75.68%)

65079358.06 hits per line

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

40.0
/modules/linear_boltzmann_solvers/lbs_problem/lbs_problem.h
1
// SPDX-FileCopyrightText: 2024 The OpenSn Authors <https://open-sn.github.io/opensn/>
2
// SPDX-License-Identifier: MIT
3

4
#pragma once
5

6
#include "modules/problem.h"
7
#include "modules/linear_boltzmann_solvers/lbs_problem/compute/lbs_compute.h"
8
#include "modules/linear_boltzmann_solvers/lbs_problem/groupset/lbs_groupset.h"
9
#include "modules/linear_boltzmann_solvers/lbs_problem/source_functions/source_flags.h"
10
#include "modules/linear_boltzmann_solvers/lbs_problem/point_source/point_source.h"
11
#include "modules/linear_boltzmann_solvers/lbs_problem/volumetric_source/volumetric_source.h"
12
#include "modules/linear_boltzmann_solvers/lbs_problem/lbs_structs.h"
13
#include "modules/linear_boltzmann_solvers/lbs_problem/lbs_view.h"
14
#include "framework/math/spatial_discretization/spatial_discretization.h"
15
#include "framework/mesh/mesh_continuum/mesh_continuum.h"
16
#include "framework/math/linear_solver/linear_solver.h"
17
#include "framework/math/spatial_discretization/finite_element/unit_cell_matrices.h"
18
#include "framework/math/geometry.h"
19
#include "framework/utils/hdf_utils.h"
20
#include <memory>
21
#include <petscksp.h>
22
#include <chrono>
23
#include <functional>
24

25
namespace opensn
26
{
27

28
class MPICommunicatorSet;
29
class GridFaceHistogram;
30
class FieldFunctionGridBased;
31
class TotalXSCarrier;
32
class OutflowCarrier;
33
class MeshCarrier;
34
template <typename T>
35
class MemoryPinner;
36

37
/**
38
 * Base class for all Linear Boltzmann Solvers.
39
 *
40
 * Problems are created through derived-class factory functions. The factory
41
 * function performs all constructor-time parsing and calls BuildRuntime
42
 * before returning the shared pointer, so public methods operate on a fully
43
 * built problem.
44
 */
45
class LBSProblem : public Problem, public std::enable_shared_from_this<LBSProblem>
46
{
47
public:
48
  using RestartDataHook = std::function<bool(hid_t)>;
49

50
  /// Construction and lifetime.
51
  LBSProblem(const LBSProblem&) = delete;
52

53
  LBSProblem& operator=(const LBSProblem&) = delete;
54

55
  ~LBSProblem() override;
56

57
  /// Time and adjoint-mode controls.
58
  /// Returns a constant reference to the solver options.
59
  const LBSOptions& GetOptions() const;
60

61
  /// Returns simulation time in seconds for time dependent problems.
62
  double GetTime() const;
63

64
  /// Sets simulation time in seconds for time dependent problems.
65
  virtual void SetTime(double time);
66

67
  /// Sets dt.
68
  void SetTimeStep(double dt);
69

70
  /// Returns dt.
71
  double GetTimeStep() const;
72

73
  /// Sets theta for time discretization.
74
  void SetTheta(double theta);
75

76
  /// Returns theta for time discretization.
77
  double GetTheta() const;
78

79
  /// Returns true if the problem is currently in time-dependent mode.
80
  virtual bool IsTimeDependent() const;
81

82
  /// Set the problem to time-dependent mode.
83
  virtual void SetTimeDependentMode();
84

85
  /// Set the problem to steady-state mode.
86
  virtual void SetSteadyStateMode();
87

88
  /**
89
   * Toggle forward/adjoint transport mode.
90
   *
91
   * If the requested mode differs from the current mode, this performs a
92
   * mode-transition reset. Materials are reinitialized in the selected mode,
93
   * sources and boundaries are cleared, and solution vectors are zeroed.
94
   */
95
  void SetAdjoint(bool adjoint = true);
96

97
  /// Set the problem to forward mode.
98
  void SetForward();
99

100
  /// Returns true if the problem is in adjoint mode.
101
  bool IsAdjoint() const;
102

103
  /// Supported solution-vector operations.
104
  void ZeroPhi();
105
  void CopyPhiNewToOld();
106
  void SetPhiOldFrom(const std::vector<double>& phi_old);
107
  void SetPhiNewFrom(const std::vector<double>& phi_new);
108
  void ScalePhiOld(double factor);
109
  void ScalePhiNew(double factor);
110
  void ZeroQMoments();
111
  void ScaleQMoments(double factor);
112
  void SetQMomentsFrom(const std::vector<double>& q_moments);
113
  void ScalePrecursors(double factor);
114
  void ZeroPrecursors();
115
  void ZeroExtSrcMoments();
116
  void ScaleExtSrcMoments(double factor);
117

118
  /// Problem metadata and immutable access.
119
  GeometryType GetGeometryType() const;
120

121
  /// Returns the number of moments for the solver.
122
  unsigned int GetNumMoments() const;
123

124
  unsigned int GetMaxCellDOFCount() const;
125

126
  unsigned int GetMinCellDOFCount() const;
127

128
  bool UseGPUs() const;
129

130
  /// Returns the number of groups for the solver.
131
  unsigned int GetNumGroups() const;
132

133
  /// Returns the scattering order for the solver.
134
  unsigned int GetScatteringOrder() const;
135

136
  /// Returns the number of precursors for the solver.
137
  unsigned int GetNumPrecursors() const;
138

139
  /// Returns the maximum number of precursors defined on any material.
140
  unsigned int GetMaxPrecursorsPerMaterial() const;
141

142
  const std::vector<LBSGroupset>& GetGroupsets() const;
143
  LBSGroupset& GetGroupset(size_t groupset_id);
144
  const LBSGroupset& GetGroupset(size_t groupset_id) const;
145
  size_t GetNumGroupsets() const;
146

147
  /**
148
   * Problem runtime reconfiguration.
149
   *
150
   * These methods are the public mutators available after construction.
151
   * They refresh the runtime data owned by the problem where needed.
152
   * Other mutable state accessors below are exposed for solvers and
153
   * low-level I/O, not as general user-facing methods.
154
   */
155
  /// Adds a point source to the solver.
156
  void AddPointSource(std::shared_ptr<PointSource> point_source);
157

158
  /// Clears all the point sources from the solver.
159
  void ClearPointSources();
160

161
  /// Constant accessor to the list of point sources.
162
  const std::vector<std::shared_ptr<PointSource>>& GetPointSources() const;
163

164
  /// Adds a volumetric source to the solver.
165
  void AddVolumetricSource(std::shared_ptr<VolumetricSource> volumetric_source);
166

167
  /// Clears all the volumetric sources from the solver.
168
  void ClearVolumetricSources();
169

170
  /// Constant accessor to the list of volumetric sources.
171
  const std::vector<std::shared_ptr<VolumetricSource>>& GetVolumetricSources() const;
172

173
  /// Clears all the boundary conditions from the solver.
174
  virtual void ClearBoundaries() = 0;
175

176
  /// Returns a reference to the map of material ids to XSs.
177
  const BlockID2XSMap& GetBlockID2XSMap() const;
178

179
  /// Replaces the map of block ids to XSs and refreshes material data.
180
  virtual void SetBlockID2XSMap(const BlockID2XSMap& xs_map);
181

182
  /// Obtains a reference to the grid.
183
  std::shared_ptr<MeshContinuum> GetGrid() const;
184

185
  /// Low-level device/runtime carriers used by solver components.
186
  TotalXSCarrier* GetTotalXSCarrier() { return total_xs_carrier_.get(); }
187
  const TotalXSCarrier* GetTotalXSCarrier() const { return total_xs_carrier_.get(); }
188

189
  OutflowCarrier* GetOutflowCarrier() { return outflow_carrier_.get(); }
190
  const OutflowCarrier* GetOutflowCarrier() const { return outflow_carrier_.get(); }
191

192
  MeshCarrier* GetMeshCarrier() { return mesh_carrier_.get(); }
193
  const MeshCarrier* GetMeshCarrier() const { return mesh_carrier_.get(); }
194

195
  MemoryPinner<double>* GetSourceMomentsPinner() { return source_pinner_.get(); }
196
  const MemoryPinner<double>* GetSourceMomentsPinner() const { return source_pinner_.get(); }
197

198
  MemoryPinner<double>* GetPhiPinner() { return phi_pinner_.get(); }
199
  const MemoryPinner<double>* GetPhiPinner() const { return phi_pinner_.get(); }
200

201
  /// Discretization and local transport data.
202
  /// Obtains a reference to the spatial discretization.
203
  const SpatialDiscretization& GetSpatialDiscretization() const;
204

205
  /// Returns read-only access to the unit cell matrices.
206
  const std::vector<UnitCellMatrices>& GetUnitCellMatrices() const;
207

208
  /// Returns read-only access to the unit ghost cell matrices.
209
  const std::map<uint64_t, UnitCellMatrices>& GetUnitGhostCellMatrices() const;
210

211
  /// Returns read-only access to the list of local cell transport views.
212
  const std::vector<CellLBSView>& GetCellTransportViews() const;
213

214
  /// Returns read/write access to local cell outflow tallies.
215
  std::vector<CellOutflowView>& GetCellOutflowViews();
216

217
  /// Returns read-only access to local cell outflow tallies.
218
  const std::vector<CellOutflowView>& GetCellOutflowViews() const;
219

220
  /// Obtains a reference to the unknown manager for flux-moments.
221
  const UnknownManager& GetUnknownManager() const;
222

223
  /// Returns the local node count for the flux-moments data structures.
224
  size_t GetLocalNodeCount() const;
225

226
  /// Returns the global node count for the flux-moments data structures.
227
  size_t GetGlobalNodeCount() const;
228

229
  /**
230
   * Internal solver-state access.
231
   *
232
   * These mutable references are intentionally available to solver kernels,
233
   * iterative methods, acceleration routines, and restart/flux I/O. User-facing
234
   * code should prefer the explicit operations above or read-only field-function/query
235
   * APIs.
236
   */
237
  /// Read/write access to source moments vector.
238
  std::vector<double>& GetQMomentsLocal();
239

240
  /// Read access to source moments vector.
241
  const std::vector<double>& GetQMomentsLocal() const;
242

243
  /// Read access to exterior src moments vector.
244
  const std::vector<double>& GetExtSrcMomentsLocal() const;
245

246
  /// Replaces exterior source moments vector.
247
  void SetExtSrcMomentsFrom(const std::vector<double>& ext_src_moments);
248

249
  /// Read/write access to last updated flux vector.
250
  std::vector<double>& GetPhiOldLocal();
251

252
  /// Read access to last updated flux vector.
253
  const std::vector<double>& GetPhiOldLocal() const;
254

255
  /// Read/write access to newest updated flux vector.
256
  std::vector<double>& GetPhiNewLocal();
257

258
  /// Read access to newest updated flux vector.
259
  const std::vector<double>& GetPhiNewLocal() const;
260

261
  /// Read/write access to newest updated precursors vector.
262
  std::vector<double>& GetPrecursorsNewLocal();
263

264
  /// Read access to newest updated precursors vector.
265
  const std::vector<double>& GetPrecursorsNewLocal() const;
266

267
  SetSourceFunction GetActiveSetSourceFunction() const;
268

269
  /**
270
   * Gets the local and global number of iterative unknowns. This is
271
   * typically only the flux moments, however, the sweep based solvers
272
   * might include delayed angular fluxes in this number.
273
   */
274
  virtual std::pair<size_t, size_t> GetNumPhiIterativeUnknowns();
275

276
  /// Field-function and postprocessing helpers.
277
  /**
278
   * Returns a flux-moment field function for a given group and moment.
279
   *
280
   * The returned field function is created on demand from the current \c phi_new state.
281
   */
282
  std::shared_ptr<FieldFunctionGridBased> CreateScalarFluxFieldFunction(unsigned int g,
283
                                                                        unsigned int m = 0);
284

285
  /// Creates a named field function from a 1D XS or the special case `power`.
286
  std::shared_ptr<FieldFunctionGridBased> CreateFieldFunction(
287
    const std::string& name, const std::string& xs_name, double power_normalization_target = -1.0);
288

289
  bool ReadRestartData(const RestartDataHook& extra_reader = {});
290
  bool WriteRestartData(const RestartDataHook& extra_writer = {});
291

292
  bool TriggerRestartDump() const { return options_.restart.IsWriteDue(); }
293

294
  void UpdateRestartWriteTime() { options_.restart.MarkWriteComplete(); }
295

296
  /// Makes a source-moments vector from scattering and fission based on the latest phi-solution.
297
  std::vector<double> MakeSourceMomentsFromPhi();
298

299
  /**
300
   * A method for post-processing an adjoint solution.
301
   *
302
   * @note This does nothing for diffusion-based solvers.
303
   */
304
  virtual void ReorientAdjointSolution() {};
×
305

306
protected:
307
  /// Input parameters based construction.
308
  explicit LBSProblem(const InputParameters& params);
309

310
  /// Internal factory step: build runtime data after constructor-time configuration is complete.
311
  void BuildRuntime();
312

313
  virtual void PrintSimHeader();
314

315
  virtual void ResetDerivedSolutionVectors() {}
×
316

317
  void ComputeUnitIntegrals();
318

319
  virtual void InitializeSpatialDiscretization();
320

321
  /// Initializes boundaries.
322
  virtual void InitializeBoundaries() {}
×
323

8✔
324
  void SetActiveSetSourceFunction(SetSourceFunction source_function);
4✔
325

326
  std::shared_ptr<FieldFunctionGridBased> CreateEmptyFieldFunction(const std::string& name) const;
327
  std::string MakeFieldFunctionName(const std::string& base_name) const;
328
  void UpdateScalarFluxFieldFunction(FieldFunctionGridBased& ff, unsigned int g, unsigned int m);
329
  void UpdateDerivedFieldFunction(FieldFunctionGridBased& ff,
330
                                  const std::string& xs_name,
331
                                  double power_normalization_target);
332
  virtual bool ReadProblemRestartData(hid_t file_id);
333
  virtual bool WriteProblemRestartData(hid_t file_id) const;
334

335
  LBSOptions options_;
336
  double time_ = 0.0;
337
  double theta_ = 1.0;
338
  double dt_ = 1.0;
339
  GeometryType geometry_type_ = GeometryType::INVALID;
340
  unsigned int num_moments_ = 0;
341
  unsigned int num_groups_ = 0;
342
  unsigned int scattering_order_ = 0;
343
  unsigned int num_precursors_ = 0;
344
  unsigned int max_precursors_per_material_ = 0;
345

346
  std::vector<LBSGroupset> groupsets_;
347

348
  BlockID2XSMap block_id_to_xs_map_;
349

350
  std::vector<std::shared_ptr<PointSource>> point_sources_;
351
  std::vector<std::shared_ptr<VolumetricSource>> volumetric_sources_;
352

353
  std::shared_ptr<MeshContinuum> grid_;
354
  std::shared_ptr<SpatialDiscretization> discretization_ = nullptr;
355

356
  std::vector<CellFaceNodalMapping> grid_nodal_mappings_;
357
  std::shared_ptr<MPICommunicatorSet> grid_local_comm_set_ = nullptr;
358

359
  std::vector<UnitCellMatrices> unit_cell_matrices_;
360
  std::map<uint64_t, UnitCellMatrices> unit_ghost_cell_matrices_;
361
  std::vector<CellLBSView> cell_transport_views_;
362
  std::vector<CellOutflowView> cell_outflow_views_;
363

364
  UnknownManager flux_moments_uk_man_;
365

366
  unsigned int max_cell_dof_count_ = 0;
367
  unsigned int min_cell_dof_count_ = 0;
368
  uint64_t local_node_count_ = 0;
369
  uint64_t global_node_count_ = 0;
370

371
  std::vector<double> q_moments_local_, ext_src_moments_local_;
372
  std::vector<double> phi_new_local_, phi_old_local_;
373
  std::vector<double> precursor_new_local_;
374

375
  SetSourceFunction active_set_source_function_;
376

377
  /// Data carriers needed to run the sweep on GPU.
378
  std::shared_ptr<TotalXSCarrier> total_xs_carrier_ = nullptr;
379
  std::shared_ptr<OutflowCarrier> outflow_carrier_ = nullptr;
380
  std::shared_ptr<MeshCarrier> mesh_carrier_ = nullptr;
381

382
  /// Memory pinners for source moments and destination phi.
383
  std::shared_ptr<MemoryPinner<double>> source_pinner_ = nullptr;
384
  std::shared_ptr<MemoryPinner<double>> phi_pinner_ = nullptr;
385

386
  /// Flag indicating if GPU acceleration is enabled.
387
  bool use_gpus_;
388

389
private:
390
  void InitializeRuntimeCore();
391
  void ValidateRuntimeModeConfiguration() const;
392
  void InitializeSources();
393
  /// Initializes parallel arrays.
394
  void InitializeParrays();
395
  std::string MakeScalarFluxFieldFunctionName(unsigned int g, unsigned int m) const;
396
  std::vector<double> ComputeScalarFluxFieldFunctionData(unsigned int g, unsigned int m) const;
397
  double ComputeFieldFunctionPowerScaleFactor(double power_normalization_target) const;
398
  std::vector<double> ComputeXSFieldFunctionData(const std::string& xs_name) const;
399
  std::vector<double> ComputePowerFieldFunctionData(double& local_total_power) const;
400
  /// Initializes data carriers to GPUs and memory pinner.
401
  void InitializeGPUExtras();
402
  /// Reset data carriers to null and unpin memory.
403
  void ResetGPUCarriers();
404

405
  /// Initialize groupsets
406
  void InitializeGroupsets(const InputParameters& params);
407

408
  /// Initializes materials
409
  void InitializeXSMap(const InputParameters& params);
410
  void InitializeMaterials();
411

412
  /// Initialize sources
413
  void InitializeSources(const InputParameters& params);
414

415
  void ParseOptions(const InputParameters& input);
416

417
  static std::filesystem::path BuildRestartPath(const std::string& path_stem);
418

419
  /// Checks if the current CPU is associated with any GPU.
420
  static void CheckCapableDevices();
421

422
public:
423
  /// Max number of DOFs per cell that the sweep kernel on GPU can handle.
424
  static constexpr std::uint32_t max_dofs_gpu = 10;
425

426
  /// Returns the input parameters for this object.
427
  static InputParameters GetInputParameters();
428

429
  static InputParameters GetOptionsBlock();
430

431
  static InputParameters GetXSMapEntryBlock();
432
};
433

434
} // namespace opensn
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