pyopensn.solver.DiscreteOrdinatesProblem

class pyopensn.solver.DiscreteOrdinatesProblem

Base class for discrete ordinates problems in Cartesian geometry.

This class implements the algorithms necessary to solve a problem using the discrete ordinates method. When paired with a solver base, the result is a solver instance configured for a specific problem type (steady-state, transient, adjoint, k-eigenvalue, etc.).

Wrapper of opensn::DiscreteOrdinatesProblem.

ComputeFieldFunctionPowerScaleFactor(self: pyopensn.solver.LBSProblem, power_normalization_target: float) → float

Compute the scale factor that would normalize the current scalar flux’s total power to a target value.

This is a collective operation and must be called on all MPI ranks.

Parameters:

power_normalization_target (float) – Target total power (must be positive). The returned factor is power_normalization_target / global_total_power, where global_total_power is the same MPI-reduced, kappa-weighted total power CreateFieldFunction(..., "power", ...) and the power field function use.

Notes

This does not mutate any solver state. It is the same scale factor CreateFieldFunction(..., "power", power_normalization_target) applies internally, exposed directly so callers can apply it to their own derived quantities (e.g. postprocessor output) without needing a field function.

ComputeFissionProduction(self: pyopensn.solver.LBSProblem, scalar_flux_iterate: str) → float

Computes the total fission production (nu*fission).

Parameters:

scalar_flux_iterate ({'old', 'new'}) –

Specifies which scalar flux vector to use in the calculation.
  • ’old’: Use the previous scalar flux iterate.

  • ’new’: Use the current scalar flux iterate.

Returns:

The total fission production.

Return type:

float

Raises:

ValueError – If scalar_flux_iterate is not ‘old’ or ‘new’.

ComputeFissionRate(self: pyopensn.solver.LBSProblem, scalar_flux_iterate: str) → float

Computes the total fission rate.

Parameters:

scalar_flux_iterate ({'old', 'new'}) –

Specifies which scalar flux vector to use in the calculation.
  • ’old’: Use the previous scalar flux iterate.

  • ’new’: Use the current scalar flux iterate.

Returns:

The total fission rate.

Return type:

float

Raises:

ValueError – If scalar_flux_iterate is not ‘old’ or ‘new’.

ComputeLeakage(self: pyopensn.solver.DiscreteOrdinatesProblem, bnd_names: list) → dict

Compute leakage for the problem.

Parameters:

bnd_names (List[str]) – A list of boundary names for which leakage should be computed. An empty list selects all boundaries. RZ problems use rmin, rmax, zmin, and zmax.

Returns:

A dictionary mapping boundary names to group-wise leakage vectors. Each array contains the outflow (the outgoing partial current, per group) integrated over the corresponding boundary surface. Incoming flux is not subtracted, so on boundaries with inflow (sources or reflection) this is not the net leakage. In RZ geometry the surface integral covers the full revolution.

Return type:

Dict[str, numpy.ndarray]

Raises:
  • RuntimeError – If save_angular_flux option was not enabled during problem setup.

  • ValueError – If one or more boundary ids are not present on the current mesh.

CreateAndWriteSourceMoments(self: pyopensn.solver.LBSProblem, file_base: str) → None

Write source moments from latest flux iterate to file.

Parameters:

file_base (str) – File basename.

CreateFieldFunction(self: pyopensn.solver.LBSProblem, name: str, xs_name: str, power_normalization_target: float = -1.0) → pyopensn.fieldfunc.FieldFunctionGridBased

Create a named scalar field function derived from a 1D XS or power.

Parameters:
  • name (str) – Name to assign to the returned field function.

  • xs_name (str) – Built-in 1D XS name, custom XS name, or the special value power. CSDA-enabled discrete-ordinates problems also support csda_energy_deposition, cepxs_energy_deposition, csda_charge_deposition, csda_charge_deposition_term, and csda_charge_deposition_term_cellavg. When CSDA is enabled, energy_deposition is an alias for the conservative csda_energy_deposition. cepxs_energy_deposition preserves the imported CEPXS response plus the CSDA energy-space contribution.

  • power_normalization_target (float, default=-1.0) – If positive, scale the derived field function so that the raw power field would integrate to this total power.

Notes

The returned field function is created on demand from the current scalar-flux iterate. For ordinary XS names this computes sum_g xs[g] * phi_g at each node.

The returned field function is a snapshot of the solver state at creation time; it is not refreshed automatically if the solver state changes. It supports CanUpdate() and Update() while its owning problem is still alive. Calling Update() explicitly recomputes the same field function from the solver’s latest state.

If xs_name == "power", the same power-generation formula used elsewhere by the solver is applied on demand.

CSDA deposition fields are derived from the current scalar flux and terminal charged-particle current information. They should normally be created after the CSDA solve has converged.

If power_normalization_target > 0, the returned field function is scaled using the power implied by the current scalar flux. This scaling affects only the returned field function; it does not mutate the solver’s internal phi vectors.

The returned field function is a fresh object created for this call. It is not automatically updated by later solves or timesteps.

GetAngularFieldFunctionList(self: pyopensn.solver.DiscreteOrdinatesProblem, groups: list, angles: list) → list

Create field functions for selected angular flux components.

Note: You must enable angular flux storage (save_angular_flux=True) in the problem options. For transient problems this is required. Otherwise the returned field functions will remain zero.

Example

solver.Initialize()
solver.Execute()
ang_ff = phys.GetAngularFieldFunctionList(groups=[0], angles=[0])

For transient/time-dependent runs, each field function is still a snapshot. Either call this after each timestep to create a fresh object or keep the returned object and call Update() after each timestep before exporting or interpolating it. Two common patterns are:

  1. Use TransientSolver.Execute() with a post-advance callback:

solver = TransientSolver(problem=phys)
solver.Initialize()
ang_ff = phys.GetAngularFieldFunctionList(groups=[0], angles=[0])

def post_advance():
    for ff in ang_ff:
        ff.Update()
    FieldFunctionGridBased.ExportMultipleToPVTU(ang_ff, "angular_flux_t")

solver.SetPostAdvanceCallback(post_advance)
solver.Execute()
  1. Use a custom Python loop with TransientSolver.Advance():

solver = TransientSolver(problem=phys)
solver.Initialize()
ang_ff = phys.GetAngularFieldFunctionList(groups=[0], angles=[0])
for _ in range(num_steps):
    solver.Advance()
    for ff in ang_ff:
        ff.Update()
    FieldFunctionGridBased.ExportMultipleToPVTU(ang_ff, "angular_flux_t")
Parameters:
  • groups (List[int]) – Global group indices to export.

  • angles (List[int]) – Angle indices within the groupset quadrature for each group.

Returns:

Field functions for the requested (group, angle) pairs. Each returned field function is a snapshot, but supports CanUpdate() and Update() while its owning problem is alive.

Return type:

List[pyopensn.fieldfunc.FieldFunctionGridBased]

GetPhiNewLocal(self: pyopensn.solver.LBSProblem) → memoryview

Get the current scalar flux iterate (local vector).

Returns:

Memory view of the local new scalar flux vector.

Return type:

memoryview

GetPhiOldLocal(self: pyopensn.solver.LBSProblem) → memoryview

Get the previous scalar flux iterate (local vector).

Returns:

Memory view of the local old scalar flux vector.

Return type:

memoryview

GetPsi(self: pyopensn.solver.DiscreteOrdinatesProblem) → list

Return psi as a list of NumPy arrays (float64).

The arrays are copies of the current angular-flux state. Mutating them does not mutate the problem.

GetScalarFluxFieldFunction(self: pyopensn.solver.LBSProblem, only_scalar_flux: bool = True) → list

Return scalar-flux or flux-moment field functions grouped by energy group.

Parameters:

only_scalar_flux (bool, default=True) – If True, returns only the zeroth moment (scalar flux) field function for each group. If False, returns all moment field functions for each group.

Returns:

If only_scalar_flux=True: result[g] is the scalar-flux field function for group g.

If only_scalar_flux=False: result[g][m] is the field function for group g and moment m.

Return type:

Union[List[pyopensn.fieldfunc.FieldFunctionGridBased], List[List[pyopensn.fieldfunc.FieldFunctionGridBased]]]

Notes

Field functions are created on demand from the current solver state.

The returned field functions are snapshots of the solver state at creation time; they are not refreshed automatically if the solver state changes.

They support CanUpdate() and Update() while their owning problem is still alive. Calling Update() explicitly refreshes the same field-function object from the solver’s latest state.

Calling GetScalarFluxFieldFunction(only_scalar_flux=False) creates all requested moments from the current phi iterate at the time of the call.

In the nested form (only_scalar_flux=False), the moment index varies fastest within each group (inner index = moment, outer index = group).

GetTime(self: pyopensn.solver.LBSProblem) → float

Get the current simulation time in seconds.

GetTimeStep(self: pyopensn.solver.LBSProblem) → float

Get the current timestep size.

IsAdjoint(self: pyopensn.solver.LBSProblem) → bool

Return True if the problem is in adjoint mode, otherwise False.

IsTimeDependent(self: pyopensn.solver.DiscreteOrdinatesProblem) → bool

Return True if the problem is currently in time-dependent mode.

ReadAngularFluxes(self: opensn::DiscreteOrdinatesProblem, file_base: str) → None

Read angular fluxes from file.

Parameters:

file_base (str) – File basename.

ReadFluxMoments(self: pyopensn.solver.LBSProblem, file_base: str, single_file_flag: bool) → None

Read flux moment data.

Parameters:
  • file_base (str) – File basename.

  • single_file_flag (bool) – True if all flux moments are in a single file.

ReadFluxMomentsAndMakeSourceMoments(self: pyopensn.solver.LBSProblem, file_base: str, single_file_flag: bool) → None

Read flux moments and compute corresponding source moments.

Parameters:
  • file_base (str) – File basename.

  • single_file_flag (bool) – True if all flux moments are in a single file.

ReadSourceMoments(self: pyopensn.solver.LBSProblem, file_base: str, single_file_flag: bool) → None

Read source moments from file.

Parameters:
  • file_base (str) – File basename.

  • single_file_flag (bool) – True if all source moments are in a single file.

ReadSurfaceAngularFluxes(self: opensn::DiscreteOrdinatesProblem, file_base: str, surfaces: list) → list

Read surface angular fluxes from file.

Parameters:
  • file_base (str) – File basename.

  • surfaces (list[str]) – Stored surface tags to read. Use the boundary name for an exterior boundary. For an interior surface named ‘<name>’, use ‘<name>_u’ for faces whose outward normal aligns with the positive axis and ‘<name>_d’ for faces with the opposite orientation.

Returns:

Surface mapping and angular-flux data for each groupset and requested surface. Each entry has keys ‘groupset_id’, ‘adjoint’, ‘surface_name’, ‘mapping’, and ‘data’. ‘adjoint’ is True when the file was written from an adjoint problem. The ‘cell_map’ in ‘mapping’ maps face centroids, with ‘centroid_origin’ subtracted before each coordinate is divided by ‘centroid_spacing’ (1e-9 times the global mesh extent) and rounded to an integer, to the surface face index. The same face has the same key from either side of an interior surface and in every file for the same mesh.

Return type:

List[dict]

Notes

Each rank reads <file_base><rank>.h5; the files must have been written with the same mesh partitioning.

SetAdjoint(self: pyopensn.solver.LBSProblem, adjoint: bool = True) → None

Set forward/adjoint transport mode.

Parameters:

adjoint (bool, default=True) – True enables adjoint mode and False enables forward mode. Adjoint mode is supported only for Cartesian geometries with standard quadrature operators (operator_method='standard'), in steady-state mode, and without an uncollided flux. Uncollided flux generation (UncollidedProblem) is forward only. An unsupported request raises ValueError before any state changes.

Raises:

ValueError – If adjoint=True and the problem is time-dependent, has options.csda_enabled=True, was constructed with an uncollided_flux file, or is an UncollidedProblem. The problem is left unchanged.

Notes

This is one of two supported mode-setting paths in Python:
  1. options={'adjoint': ...} in the problem constructor.

  2. SetAdjoint(...) (this method).

If this changes mode, OpenSn performs a full mode-transition reset:
  • Materials are reinitialized in the selected mode.

  • Point and volumetric sources are cleared.

  • Boundary conditions are cleared.

  • Scalar and angular flux vectors are zeroed.

If this is called with the same mode as the current setting, no reset is performed.

The block-id to cross-section map is preserved across the transition. However, the mode change is applied to the mapped MultiGroupXS objects themselves. If those objects are shared with other problems, they observe the same mode toggle.

After a mode change, reapply the desired driving terms before solving, typically:

This routine is intentionally destructive with respect to source/boundary/flux state to avoid hidden coupling between forward and adjoint setups.

This is a collective operation and must be called on all ranks.

SetBoundaryOptions(self: pyopensn.solver.DiscreteOrdinatesProblem, **kwargs) → None

Set or clear boundary conditions.

Parameters:
  • clear_boundary_conditions (bool, default=False) – If true, all current boundary conditions are deleted.

  • boundary_conditions (List[Dict]) –

    A list of boundary condition dictionaries. Each dictionary supports:
    • name: str (required)

      Boundary name that identifies the specific boundary.

    • type: {‘vacuum’, ‘isotropic’, ‘reflecting’, ‘arbitrary’} (required)

      Boundary type specification.

    • group_strength: List[float], optional

      Required when type='isotropic'. Isotropic strength per group.

    • start_time: float, optional

      Active start time for isotropic boundaries only. Defaults to -infinity.

    • end_time: float, optional

      Active end time for isotropic boundaries only. Defaults to infinity.

    • function: AngularFluxFunction, optional

      Required when type='arbitrary' unless time_function is supplied. Callable that returns incoming angular flux from group and direction.

    • time_function: AngularFluxTimeFunction, optional

      Required when type='arbitrary' unless function is supplied. Callable that returns incoming angular flux from group, direction, and time.

    Isotropic boundaries may use start_time/end_time for simple on/off behavior. Arbitrary boundaries must specify exactly one of function or time_function; use time_function for time-dependent arbitrary inflow and handle any active window inside that callback.

Notes

Mode transitions via LBSProblem.SetAdjoint() clear all boundary conditions. Reapply boundaries with this method before solving in the new mode.

This is a collective operation and must be called on all ranks.

SetForward(self: pyopensn.solver.LBSProblem) → None

Set forward transport mode.

Equivalent to SetAdjoint(False).

SetPointSources(self: pyopensn.solver.LBSProblem, **kwargs) → None

Set or clear point sources.

Parameters:
  • clear_point_sources (bool, default=False) – If true, all current the point sources of the problem are deleted.

  • point_sources (List[pyopensn.source.PointSource]) – List of new point sources to be added to the problem. When both arguments are given, the current sources are cleared before the new ones are added, regardless of keyword order. The new list is validated as a whole: a rejected call leaves the problem’s sources unchanged.

Notes

This is collective. A source caches mesh data when added. Prefer a separate source object for each problem. Share one only when both problems use the same mesh and spatial layout.

SetSteadyStateMode(self: pyopensn.solver.DiscreteOrdinatesProblem) → None

Set the problem to steady-state mode.

Notes

Switch problem from time-dependent to steady-state mode. This updates problem internals (sweep chunk mode and source-function) while preserving user boundary conditions and fixed sources.

This is a collective operation and must be called on all ranks.

SetTimeDependentMode(self: pyopensn.solver.DiscreteOrdinatesProblem) → None

Set the problem to time-dependent mode.

Notes

Switch problem from steady-state to time-dependent mode. This updates problem internals (sweep chunk mode and source-function) while preserving user boundary conditions and fixed sources.

Requires options.save_angular_flux=True at problem creation and VELOCITY or INV_VELOCITY data in every cross section. Not supported for adjoint, GPU, curvilinear, or uncollided-flux problems. An unsupported request raises ValueError before any state changes.

This is a collective operation and must be called on all ranks.

SetVolumetricSources(self: pyopensn.solver.LBSProblem, **kwargs) → None

Set or clear volumetric sources.

Parameters:
  • clear_volumetric_sources (bool, default=False) – If true, all current the volumetric sources of the problem are deleted.

  • volumetric_sources (List[pyopensn.source.VolumetricSource]) – List of new volumetric sources to be added to the problem. When both arguments are given, the current sources are cleared before the new ones are added, regardless of keyword order. The new list is validated as a whole: a rejected call leaves the problem’s sources unchanged.

Notes

This is collective. A source caches mesh data when added. Prefer a separate source object for each problem. Share one only when both problems use the same mesh and spatial layout.

SetXSMap(self: pyopensn.solver.LBSProblem, **kwargs) → None

Replace the block-id to cross-section map.

Parameters:

xs_map (List[Dict]) –

A list of block-id to cross-section mapping dictionaries. Each dictionary supports:
  • block_ids: List[int] (required)

    Mesh block ids to associate with the cross section.

  • xs: pyopensn.xs.MultiGroupXS (required)

    Cross section object.

Raises:

ValueError – If the problem was constructed with an uncollided_flux file, or if options.csda_enabled=True and the new cross sections split a charged-particle group block across groupsets, contain more than two charged-particle group ranges, have negative or non-finite stopping powers or non-positive energy-group widths, or have stopping power or energy bounds that do not match the problem’s group count. CSDA also rejects conflicting supplied energy structures, unknown or conflicting charged-particle species, or a map with no energy structure. Individual materials may omit bounds and use the shared structure.

Notes

This is collective.

The problem is refreshed immediately after replacing the map. Material metadata, precursor storage, GPU carriers, and derived solver state owned by the concrete problem are rebuilt for the new cross sections.

If options.use_precursors=True, this flag remains active across XS-map changes even when the current map has no precursor-bearing material. In that case delayed-neutron source terms are simply inactive until a later map provides precursor data again.

Existing precursor concentrations are remapped by local cell and precursor-family index. When the new material for a cell has fewer precursor families, extra old families are dropped. When it has more families, newly introduced families are initialized to zero. If a cell changes through a material with zero precursors, the precursor history for that cell is discarded and any later reintroduced precursor families start from zero.

If any fissionable material in the new map contains delayed-neutron precursor data and options.use_precursors=True, all fissionable materials in the map must contain precursor data. Non-fissionable materials may have zero precursors.

The new map is validated before it is committed. A validation error leaves the map unchanged. A later rebuild failure may leave partial changes. In time-dependent mode, every cross section must provide VELOCITY or INV_VELOCITY data.

Forward/adjoint mode toggles via LBSProblem.SetAdjoint() do not change this map. The MultiGroupXS objects themselves are mutable and shared by pointer. If the same MultiGroupXS handle is shared across multiple problems, toggling adjoint mode in one problem also changes the transport mode seen by the others.

WriteAngularFluxes(self: opensn::DiscreteOrdinatesProblem, file_base: str) → None

Write angular flux data to file.

Parameters:

file_base (str) – File basename.

WriteFluxMoments(self: pyopensn.solver.LBSProblem, file_base: str) → None

Write flux moments to file.

Parameters:

file_base (str) – File basename.

WriteSurfaceAngularFluxes(self: opensn::DiscreteOrdinatesProblem, file_base: str, boundary_surfaces: list[str] = [], interior_surfaces: dict[str, tuple[str, float]] = {}) → None

Write surface angular flux data to file.

Parameters:
  • file_base (str) – File basename.

  • boundary_surfaces (list[str], default=[]) – Boundary names to export.

  • interior_surfaces (dict[str, tuple[str, float]], default={}) – Interior surfaces in the form {‘name’: (‘axis’, value)}, where axis is ‘x’, ‘y’, or ‘z’. Each interior surface is written under two tags: ‘<name>_u’ for faces whose outward normal aligns with the positive axis and ‘<name>_d’ for faces with the opposite orientation. An interior surface must match at least one cell face, must lie on cell faces inside the mesh, and may not share a plane with another interior surface. Its generated tags may not equal a requested boundary name. It may not coincide with an exterior boundary; export that boundary by name using boundary_surfaces instead.

Notes

Requires options.save_angular_flux=True. Collective over all ranks; surface selections may differ by rank. Each rank writes <file_base><rank>.h5. The file records whether the problem is in adjoint mode. After an adjoint steady-state solve, the stored angular flux is the adjoint flux for the listed direction, so forward and adjoint data with the same indices refer to the same direction.

ZeroPhi(self: pyopensn.solver.LBSProblem) → None

Zero the scalar-flux vectors (phi_old and phi_new) in-place.

ZeroPsi(self: pyopensn.solver.DiscreteOrdinatesProblem) → None

Zero the angular-flux storage.

__init__(self: pyopensn.solver.DiscreteOrdinatesProblem, **kwargs) → None

Construct a discrete ordinates problem with Cartesian geometry.

Parameters:
  • mesh (MeshContinuum) – The spatial mesh.

  • num_groups (int) – The total number of energy groups.

  • groupsets (List[Dict]) –

    A list of input parameter blocks, each block provides the iterative properties for a groupset. The inclusive ranges must partition all groups in order, starting at group 0 and ending at num_groups - 1, without gaps or overlaps. Each dictionary supports:

    • groups_from_to: List[int] (required)

      Two-entry list with the first and last group id for the groupset, e.g. [0, 3].

    • angular_quadrature: pyopensn.aquad.AngularQuadrature, optional

      Handle to an angular quadrature.

    • angle_aggregation_type: {‘polar’, ‘single’, ‘azimuthal’}, default=’single’

      Angle aggregation method to use during sweeping.

    • inner_linear_method: {‘classic_richardson’, ‘petsc_richardson’, ‘petsc_gmres’, ‘petsc_bicgstab’}, default=’petsc_richardson’

      Iterative method used for inner linear solves.

    • l_abs_tol: float, default=1.0e-6

      Inner linear solver absolute residual tolerance.

    • l_max_its: int, default=200

      Inner linear solver maximum iterations.

    • gmres_restart_interval: int, default=30

      GMRES restart interval, if GMRES is used.

    • allow_cycles: bool, default=True

      Whether cyclic dependencies are allowed in sweeps.

    • apply_wgdsa: bool, default=False

      Enable within-group DSA for this groupset.

    • wgdsa_l_abs_tol: float, default=1.0e-4

      WGDSA linear absolute tolerance.

    • wgdsa_l_max_its: int, default=30

      WGDSA maximum iterations.

    • wgdsa_verbose: bool, default=False

      Verbose WGDSA output.

    • wgdsa_petsc_options: str, default=’’

      PETSc options string for the WGDSA solver.

    • wgdsa_solver_policy: {‘auto’, ‘direct’, ‘iterative’, ‘petsc_options’}, default=’auto’

      WGDSA diffusion solver policy. auto uses a direct PETSc LU solve below wgdsa_direct_solve_threshold global unknowns and an iterative solve otherwise. petsc_options lets wgdsa_petsc_options control the PETSc KSP/PC setup.

    • wgdsa_direct_solve_threshold: int, default=20000

      Maximum global WGDSA diffusion unknown count for the automatic direct solve.

    • apply_tgdsa: bool, default=False

      Enable two-grid DSA for this groupset.

    • tgdsa_l_abs_tol: float, default=1.0e-4

      TGDSA linear absolute tolerance.

    • tgdsa_l_max_its: int, default=30

      TGDSA maximum iterations.

    • tgdsa_verbose: bool, default=False

      Verbose TGDSA output.

    • tgdsa_petsc_options: str, default=’’

      PETSc options string for the TGDSA solver.

    • tgdsa_solver_policy: {‘auto’, ‘direct’, ‘iterative’, ‘petsc_options’}, default=’auto’

      TGDSA diffusion solver policy. auto uses a direct PETSc LU solve below tgdsa_direct_solve_threshold global unknowns and an iterative solve otherwise. petsc_options lets tgdsa_petsc_options control the PETSc KSP/PC setup.

    • tgdsa_direct_solve_threshold: int, default=20000

      Maximum global TGDSA diffusion unknown count for the automatic direct solve.

  • xs_map (List[Dict]) –

    A list of mappings from block ids to cross-section definitions. Each dictionary supports:
    • block_ids: List[int] (required)

      Mesh block IDs to associate with the cross section.

    • xs: pyopensn.xs.MultiGroupXS (required)

      Cross-section object to assign to the specified blocks.

  • boundary_conditions (List[Dict], default=[]) –

    A list containing tables for each boundary specification. Each dictionary supports:
    • name: str (required)

      Boundary name that identifies the specific boundary.

    • type: {‘vacuum’, ‘isotropic’, ‘reflecting’, ‘arbitrary’} (required)

      Boundary type specification.

    • group_strength: List[float], optional

      Required when type='isotropic'. Isotropic strength per group.

    • start_time: float, optional

      Active start time for isotropic boundaries only. Defaults to -infinity.

    • end_time: float, optional

      Active end time for isotropic boundaries only. Defaults to infinity.

    • function: AngularFluxFunction, optional

      Required when type='arbitrary' unless time_function is supplied. Callable that returns incoming angular flux from group and direction.

    • time_function: AngularFluxTimeFunction, optional

      Required when type='arbitrary' unless function is supplied. Callable that returns incoming angular flux from group, direction, and time.

    Isotropic boundaries may use start_time/end_time for simple on/off behavior. Arbitrary boundaries must specify exactly one of function or time_function; use time_function for time-dependent arbitrary inflow and handle any active window inside that callback.

  • point_sources (List[pyopensn.source.PointSource], default=[]) – A list of point sources.

  • volumetric_sources (List[pyopensn.source.VolumetricSource], default=[]) – A list of volumetric sources.

  • options (Dict, default={}) –

    A block of optional configuration parameters, including:
    • max_mpi_message_size: int, default=32768

    • restart_writes_enabled: bool, default=False

      Enable restart dump writes for solvers that support restart output.

    • write_delayed_psi_to_restart: bool, default=True

      Include delayed sweep angular-flux buffers in steady-state restart dumps. These buffers are optional when a steady-state restart is used only as a transient initial condition because the transient initialization can reconstruct angular state from the flux moments. Time-dependent restart dumps always include them, regardless of this option, because continuing a transient requires them whenever the problem has delayed sweep angular state, including partitioned parallel, reflected-boundary, and cyclic-sweep cases.

    • write_angular_flux_to_restart: bool, default=True

      Include stored angular fluxes in steady-state restart dumps when save_angular_flux=True. They are optional when a steady-state restart is used only as a transient initial condition. Time-dependent restart dumps always include them, regardless of this option, because continuing a transient requires them.

    • read_restart_path: str, default=’’

      File stem for reading a full restart. Scalar flux and precursor data can be remapped when the MPI rank count or mesh partition changes. Full transient continuation still requires the original partitioned angular state layout.

    • read_initial_condition_path: str, default=’’

      File stem for reading restart data as an initial condition. Cannot be combined with read_restart_path. A steady-state restart may be used by TransientSolver through this option. The first TransientSolver.Initialize() loads it once; later initializations continue from the problem’s current state.

    • write_restart_path: str, default=’’

      File stem for restart dump writes. OpenSn appends the MPI rank and .restart.h5 to this stem.

    • write_restart_time_interval: int, default=0 (must be 0 or >=30)

    • use_precursors: bool, default=True Enable delayed-neutron precursor treatment. This is treated as user intent and remains active across later SetXSMap calls, even if the current XS map temporarily contains no precursor-bearing material. When XS maps are swapped, existing precursor concentrations are remapped by cell and precursor-family index; new families start at zero and removed families are discarded. If any fissionable material in the active map has precursor data and use_precursors=True, all fissionable materials in that map must have precursor data. Non-fissionable materials may have zero precursors.

    • use_source_moments: bool, default=False Use the problem’s source moments as the fixed source instead of its volumetric and point sources. Provide them (e.g. with ReadSourceMoments) after creating the problem and before solving; a solve without them raises ValueError. They are an external source, so the k-eigenvalue solvers reject a problem with this option.

    • save_angular_flux: bool, default=False Store angular flux state (psi) for transient mode, angular-flux field functions, and angular-flux I/O.

    • adjoint: bool, default=False

    • csda_enabled: bool, default=False Enable CSDA charged-particle transport for CEPXS data loaded with csda_format=True. CSDA requires a Cartesian SteadyStateSourceSolver solve, sweep_type='AAH', CPU sweeps, and charged-particle group ranges that are not split across groupsets. All materials must supply identical per-group energy bounds or omit them; at least one material must supply the shared structure.

    • verbose_inner_iterations: bool, default=True Print inner iteration details, including WGS and AGS iterations.

    • verbose_outer_iterations: bool, default=True Print outer solver progress, including PI/NLKE iterations and transient steps.

    • max_ags_iterations: int, default=100

    • ags_tolerance: float, default=1.0e-6

    • ags_convergence_check: {‘l2’, ‘pointwise’}, default=’l2’

    • power_default_kappa: float, default=3.20435e-11

    • field_function_prefix_option: {‘prefix’, ‘solver_name’}, default=’prefix’

    • field_function_prefix: str, default=’’

    • fused_aao_sweep: bool, default=False Use the fused all-at-once GPU scheduler for AAH sweeps. Each kernel launch sweeps the current level of up to 256 ready angle sets instead of one, which reduces launch count when individual levels are too small to fill the GPU. Up to fused_aao_lanes such runs are in flight at once, so angle sets that become ready later (for example when upstream angular fluxes arrive from another rank) start without waiting for the others. The solution matches the default scheduler to floating-point rounding. Requires sweep_type="AAH" and use_gpus=True. Otherwise construction raises an error.

    • fused_aao_lanes: int, default=8 With fused_aao_sweep=True, the number of fused runs (each a batch of angle sets on its own GPU stream) that may be in flight at once on each rank. Must be at least 1. Ignored unless fused_aao_sweep=True.

    These options are applied at problem creation.

  • sweep_type (str, default="AAH") – The sweep type to use. Must be one of AAH or CBC. Defaults to AAH. Both sweep types support time-dependent (transient) mode.

  • time_dependent (bool, default=False) – If true, the problem starts in time-dependent mode. Otherwise it starts in steady-state mode. Requires options.save_angular_flux=True and VELOCITY or INV_VELOCITY data in every cross section. Both AAH and CBC sweep types support time-dependent mode.

  • uncollided_flux (str, default="") – HDF5 file generated by UncollidedSolver. For steady-state forward fixed-source calculations, OpenSn uses its moments to construct the first-collision scattering and fission source, solves for the collided component, and adds the uncollided moments back to the converged state. The file must match the current group count, mesh cell IDs, cell-node layout and coordinates, total cross sections, and reflecting boundary set. Its maximum moment order must be at least this problem’s scattering order. The same serial file may be read by any MPI partitioning of the matching mesh. The first-collision source replaces the fixed sources, so the problem must not also have volumetric or point sources or incoming-flux (isotropic or arbitrary) boundaries, and its cross sections cannot be replaced.

  • use_gpus (bool, default=False) – A flag specifying whether GPU acceleration is used for the sweep. Both `AAH` and `CBC` sweep types support GPU acceleration.

Notes

Construction validates and builds the runtime problem. It is collective. Use equivalent input on every MPI rank.