tardis.plasma.equilibrium.thermal_balance module

class tardis.plasma.equilibrium.thermal_balance.ElectronThermalBalanceSolver(evaluator: PlasmaEquilibriumEvaluator, radiation_temperature: ndarray[tuple[Any, ...], dtype[float64]], level_initial_guess: DataFrame, maximum_electron_density: ndarray[tuple[Any, ...], dtype[float64]])[source]

Bases: object

Solve electron density and temperature balance across plasma shells.

Initialize a solve from one frozen plasma-equilibrium snapshot.

Parameters:
evaluatorPlasmaEquilibriumEvaluator

Fixed equilibrium evaluator for the outer thermal solve.

radiation_temperaturenumpy.ndarray

Radiation temperature in each shell [K].

level_initial_guesspandas.DataFrame

Frozen normalized level populations used during optimization.

maximum_electron_densitynumpy.ndarray

Maximum electron number density in each shell [cm^-3].

calculate_residual(candidate: ndarray[tuple[Any, ...], dtype[float64]]) → ndarray[tuple[Any, ...], dtype[float64]][source]

Calculate charge and heating residuals for all shells.

Parameters:
candidatenumpy.ndarray

Interleaved electron-density fractions and electron-to-radiation temperature ratios for each shell.

Returns:
numpy.ndarray

Interleaved normalized electron-density and fractional-heating residuals for each shell.

evaluate_candidate(candidate: ndarray[tuple[Any, ...], dtype[float64]]) → PlasmaEquilibriumEvaluation[source]

Rebuild the terminal equilibrium state for a candidate.

Parameters:
candidatenumpy.ndarray

Interleaved electron-density fractions and temperature ratios for each shell.

Returns:
tardis.plasma.equilibrium.evaluator.PlasmaEquilibriumEvaluation

Equilibrium state rebuilt using the candidate’s converged level populations as the terminal seed.

least_squares_settings = {'ftol': 1e-12, 'gtol': 1e-14, 'max_nfev': 100, 'x_scale': 'jac', 'xtol': 1e-14}
solve(initial_guess: ndarray[tuple[Any, ...], dtype[float64]], lower_bound: ndarray[tuple[Any, ...], dtype[float64]], upper_bound: ndarray[tuple[Any, ...], dtype[float64]]) → tuple[ndarray[tuple[Any, ...], dtype[float64]], PlasmaEquilibriumEvaluation][source]

Solve jointly, then retry shells that fail final closure.

Parameters:
initial_guessnumpy.ndarray

Initial interleaved electron-density fractions and temperature ratios for each shell.

lower_boundnumpy.ndarray

Lower bounds for each value in initial_guess.

upper_boundnumpy.ndarray

Upper bounds for each value in initial_guess.

Returns:
accepted_candidatenumpy.ndarray

Interleaved electron-density fractions and temperature ratios from the accepted joint and single-shell solves.

evaluationtardis.plasma.equilibrium.evaluator.PlasmaEquilibriumEvaluation

Validated terminal equilibrium state for accepted_candidate.

Raises:
RuntimeError

If the joint failure cannot be attributed to individual charge or heating residuals, or if shell-local retries do not restore final closure.

solve_multiple_shells(initial_guess: ndarray[tuple[Any, ...], dtype[float64]], lower_bound: ndarray[tuple[Any, ...], dtype[float64]], upper_bound: ndarray[tuple[Any, ...], dtype[float64]]) → OptimizeResult[source]

Solve charge and heating balance for all shells jointly.

Parameters:
initial_guessnumpy.ndarray

Initial interleaved electron-density fractions and temperature ratios for each shell.

lower_boundnumpy.ndarray

Lower bounds for each value in initial_guess.

upper_boundnumpy.ndarray

Upper bounds for each value in initial_guess.

Returns:
scipy.optimize.OptimizeResult

Result of the joint nonlinear least-squares solve.

solve_single_shell(shell_idx: int, accepted_candidate: ndarray[tuple[Any, ...], dtype[float64]], initial_guess: ndarray[tuple[Any, ...], dtype[float64]], lower_bound: ndarray[tuple[Any, ...], dtype[float64]], upper_bound: ndarray[tuple[Any, ...], dtype[float64]]) → OptimizeResult[source]

Retry one failed shell, including its alternate initial state.

Parameters:
shell_idxint

Zero-based position of the shell to solve.

accepted_candidatenumpy.ndarray

Current interleaved candidate for all shells. Values outside the selected shell remain fixed during the solve.

initial_guessnumpy.ndarray

Original bounded candidate used as the alternate starting state.

lower_boundnumpy.ndarray

Lower bounds for the interleaved candidate values.

upper_boundnumpy.ndarray

Upper bounds for the interleaved candidate values.

Returns:
scipy.optimize.OptimizeResult

Preferred result from the primary or alternate single-shell solve.

static validate_evaluation(evaluation: PlasmaEquilibriumEvaluation) → None[source]

Validate population, charge, level, and thermal closure.

Parameters:
evaluationtardis.plasma.equilibrium.evaluator.PlasmaEquilibriumEvaluation

Terminal equilibrium state to validate.

Raises:
RuntimeError

If populations or derived states are invalid, or if any closure residual exceeds its declared tolerance.

class tardis.plasma.equilibrium.thermal_balance.ThermalBalanceSolver(bound_free_solver: BoundFreeThermalRates, free_free_solver: FreeFreeThermalRates, collisional_ionization_solver: CollisionalIonizationThermalRates, collisional_bound_solver: CollisionalBoundThermalRates)[source]

Bases: object

Class to solve the thermal balance equation using all available

heating and cooling processes. See section 6.4 in Lucy 03, especially equations 55-57.

Initialize the thermal balance solver with individual solver components.

Parameters:
bound_free_solver

Solver for bound-free heating and free-bound cooling processes.

free_free_solver

Solver for free-free heating and cooling processes.

collisional_ionization_solver

Solver for collisional ionization heating and cooling processes.

collisional_bound_solver

Solver for collisional bound-bound heating and cooling processes.

solve(thermal_electron_distribution: ThermalElectronEnergyDistribution, level_population: DataFrame, ion_population: DataFrame, collisional_ionization_rate_coefficient: DataFrame, collisional_deexcitation_rate_coefficient: DataFrame, collisional_excitation_rate_coefficient: DataFrame, free_free_heating_estimator: DataFrame, level_population_ratio: DataFrame, radiation_field: DilutePlanckianRadiationField | None = None, bound_free_heating_estimator: DataFrame | None = None, stimulated_recombination_estimator: DataFrame | None = None) → tuple[Series, Series][source]

Compute the current heating rate and the fractional heating

rate using all available processes. See section 6.4 in Lucy 03.

Parameters:
thermal_electron_distributionThermalElectronEnergyDistribution

Electron energy, temperature, and density.

level_populationpd.DataFrame

Level number density.

ion_populationpd.DataFrame

Ion number density.

collisional_ionization_rate_coefficientpd.DataFrame

Collisional ionization rate coefficient.

collisional_deexcitation_rate_coefficientpd.DataFrame

Collisional deexcitation rate coefficient.

collisional_excitation_rate_coefficientpd.DataFrame

Collisional excitation rate coefficient.

free_free_heating_estimatorpd.DataFrame

Montecarlo estimator for free-free heating.

level_population_ratiopd.DataFrame

Level population to ion population ratio. Lucy 03, equation 14.

radiation_fieldRadiationField, optional

Radiation field for mean intensity calculation.

bound_free_heating_estimatorpd.DataFrame, optional

Bound-free heating estimator.

stimulated_recombination_estimatorpd.DataFrame, optional

Stimulated recombination estimator.

Returns:
tuple[pd.Series, pd.Series]

Total heating rate and fractional heating rate for each cell.