uclchem.advanced ================ .. py:module:: uclchem.advanced .. autoapi-nested-parse:: UCLCHEM Advanced Module. Runtime configuration and introspection for UCLCHEM's Fortran modules. This package provides class-based interfaces for: - HeatingSettings: Control heating and cooling mechanisms - NetworkState: Access and modify the chemical network state during runtime - GeneralSettings: Access and modify all UCLCHEM settings **Thread Safety Warning:** All classes in this module modify global Fortran module state and are **NOT thread-safe**. Do not use these classes with multiprocessing, multithreading, or concurrent model runs. Settings should only be modified during initialization, before running models. Submodules ---------- .. toctree:: :titlesonly: :maxdepth: 1 advanced_heating/index.rst advanced_network/index.rst advanced_settings/index.rst constants/index.rst generate_metadata/index.rst runtime_network/index.rst worker_state/index.rst Package Contents ---------------- Classes ~~~~~~~ .. autoapisummary:: uclchem.advanced.GeneralSettings uclchem.advanced.HeatingSettings uclchem.advanced.NetworkState uclchem.advanced.RuntimeNetwork Functions ~~~~~~~~~ .. autoapisummary:: uclchem.advanced.create_snapshot uclchem.advanced.restore_snapshot .. py:class:: GeneralSettings General interface to all UCLCHEM settings across all Fortran modules. Provides dynamic access to modifiable parameters in any uclchemwrap module, with automatic detection of read-only PARAMETERs and internal solver settings. Each setting is represented by a Setting object that tracks: - Current value (with caching) - Edit status - Default value - Metadata (dtype, shape, flags) **Thread Safety Warning:** This class modifies global Fortran module state and is **NOT thread-safe**. Do not use with multiprocessing or concurrent model runs. Settings should only be modified during initialization, before running models. Usage: >>> from uclchem.advanced.advanced_settings import GeneralSettings >>> settings = GeneralSettings() >>> >>> # Access a setting >>> setting = settings.defaultparameters.initialdens >>> print(setting.get()) 100.0 >>> >>> # Modify a setting >>> setting.set(500.0) >>> >>> # Get the modified value >>> print(setting.get()) 500.0 >>> >>> # Or use attribute-style syntax >>> settings.defaultparameters.initialdens = 500.0 >>> >>> # List all settings in a module >>> settings.defaultparameters.print_settings() # doctest: +SKIP ... >>> >>> # Use context manager for temporary changes >>> with settings.temporary_changes(): ... settings.defaultparameters.initialdens = 1000.0 ... print(setting.get()) ... # Run model with modified settings ... 1000.0 >>> # Settings automatically restored after context >>> print(setting.get()) 500.0 >>> # As well as in the GeneralSettings instance >>> print(settings.defaultparameters.initialdens) Setting(defaultparameters.initialdens = 500.0 [EDITED]) >>> >>> # Reset to the original value >>> setting.set(100.0) Initialize with all available uclchemwrap modules. .. py:method:: list_modules() -> None List all available modules with statistics. .. py:method:: print_all_edited() -> None Print all settings that have been modified from defaults. .. py:method:: print_all_settings() -> None Print all settings across all modules. .. py:method:: reset_all(confirm: bool = True) -> None Reset all settings to their default values. :param confirm: If True, require user confirmation. Default = True. :type confirm: bool .. py:method:: search(pattern: str, include_internal: bool = False, include_parameters: bool = False) -> dict[str, Setting] Search for settings matching a pattern across all modules. :param pattern: String pattern to search for (case-insensitive). :type pattern: str :param include_internal: Include internal solver parameters. Default = False. :type include_internal: bool :param include_parameters: Include read-only PARAMETERs. Default = False. :type include_parameters: bool :returns: Dict mapping "module.setting" to Setting objects :rtype: dict[str, Setting] .. py:method:: temporary_changes() -> collections.abc.Iterator[GeneralSettings] Context manager for temporary setting modifications. Saves current state on entry and restores it on exit, even if an exception occurs. Useful for running models with temporary parameter changes without affecting the global state. :Yields: **self** (*GeneralSettings*) -- The GeneralSettings instance for chaining .. rubric:: Examples >>> settings = GeneralSettings() >>> settings.defaultparameters.initialdens = 100.0 >>> print(settings.defaultparameters.initialdens.get()) 100.0 >>> >>> with settings.temporary_changes(): ... settings.defaultparameters.initialdens = 5000.0 ... print(settings.defaultparameters.initialdens.get()) ... # Run model here ... 5000.0 >>> >>> print(settings.defaultparameters.initialdens.get()) 100.0 .. py:class:: HeatingSettings Class-based wrapper for UCLCHEM heating and cooling configuration. This class provides access to the heating and cooling mechanism controls, solver parameters, and computed values from heating.f90. .. attribute:: PHOTOELECTRIC Photoelectric heating implementations - 'BAKES': Bakes & Tielens method (index 1) - 'WEINGARTNER': Weingartner method (index 2) (Only one can be enabled at a time) :type: dict .. attribute:: H2_FORMATION Index for H2 formation heating (3) :type: int .. attribute:: H2_PHOTODISSOCIATION Index for H2 photodissociation heating (4) :type: int .. attribute:: H2_FUV_PUMPING Index for H2 FUV pumping heating (5) :type: int .. attribute:: CARBON_IONIZATION Index for carbon ionization heating (6) :type: int .. attribute:: COSMIC_RAY Index for cosmic ray heating (7) :type: int .. attribute:: TURBULENT Index for turbulent heating (8) :type: int .. attribute:: GAS_GRAIN_COLLISIONS Index for gas-grain collisional heating/cooling (9) :type: int .. attribute:: ATOMIC_LINE_COOLING Index for atomic line cooling :type: int .. attribute:: H2_COLLISIONALLY_INDUCED Index for H2 collisionally induced emission :type: int .. attribute:: COMPTON_COOLING Index for Compton cooling :type: int .. attribute:: CONTINUUM_EMISSION Index for continuum emission cooling :type: int .. attribute:: MOLECULAR_LINE_COOLING Index for molecular line cooling :type: int .. attribute:: DUST_TEMP_HOCUK Hocuk et al. 2017 dust temperature method :type: int .. attribute:: DUST_TEMP_HOLLENBACH Hollenbach 1991 dust temperature method :type: int .. attribute:: COOLANT_WARM Warm restart mode - initialize LTE, rescale on density change (default) :type: int .. attribute:: COOLANT_FORCE_LTE Always reset to LTE before SE iteration (original behavior) :type: int .. attribute:: COOLANT_FORCE_GROUND Always reset to ground state before SE iteration :type: int .. rubric:: Examples >>> from uclchem.advanced import HeatingSettings >>> settings = HeatingSettings() >>> settings.print_configuration() # doctest: +SKIP ... >>> # Switch photoelectric method (auto-disables Bakes when enabling Weingartner) >>> settings.set_heating_mechanism(settings.PHOTOELECTRIC['WEINGARTNER'], True) >>> # Disable H2 formation >>> settings.set_heating_mechanism(settings.H2_FORMATION, False) Initialize the HeatingSettings wrapper. This connects to the Fortran heating module and provides access to its configuration parameters. Captures the current state as the default configuration for reset_to_defaults(). .. py:method:: get_coolant_active() -> dict[str, bool] Get the active state of all line coolant species. :returns: Dictionary mapping coolant names to their enabled state :rtype: dict[str, bool] .. rubric:: Examples >>> settings = HeatingSettings() >>> state = settings.get_coolant_active() >>> print(state) {'H': True, 'C+': True, 'O': True, ...} .. py:method:: get_coolant_directory() -> str Get the current collisional rate data directory. :returns: Directory path as string (stripped of trailing spaces) :rtype: str .. py:method:: get_coolant_restart_mode() -> int Get the current coolant population restart mode. :returns: Current restart mode (0=WARM, 1=FORCE_LTE, 2=FORCE_GROUND) :rtype: int .. py:method:: get_cooling_modules() -> dict[str, bool] Obtain the state (on/off) of all cooling mechanisms. :returns: Dictionary mapping mechanism names to their enabled state :rtype: dict[str, bool] .. rubric:: Examples >>> settings = HeatingSettings() >>> state = settings.get_cooling_modules() >>> print(state['AtomicLineEmission']) True .. py:method:: get_dust_gas_coupling_method() -> int Get the current dust-gas temperature coupling method. :returns: Current method (1=Hocuk, 2=Hollenbach) :rtype: int .. py:method:: get_heating_modules() -> dict[str, bool] Obtain the state (on/off) of all heating mechanisms. :returns: Dictionary mapping mechanism names to their enabled state :rtype: dict[str, bool] .. rubric:: Examples >>> settings = HeatingSettings() >>> state = settings.get_heating_modules() >>> print(state['H2Formation']) False .. py:method:: get_line_solver_attempts() -> int Get the current number of line cooling solver attempts. :returns: Number of solver attempts :rtype: int .. py:method:: get_pah_abundance() -> float Get the current PAH abundance. :returns: PAH abundance :rtype: float .. py:method:: print_configuration() -> None Print the current heating and cooling configuration. .. rubric:: Examples >>> settings = HeatingSettings() >>> settings.print_configuration() # doctest: +SKIP ... .. py:method:: reset_to_defaults() -> None Reset all heating and cooling mechanisms to their initial values. Restores the configuration that was present when this HeatingSettings instance was first initialized. This allows reverting any changes made during the session back to the starting state. .. rubric:: Examples >>> settings = HeatingSettings() >>> settings.set_heating_mechanism(settings.H2_FORMATION, False) >>> settings.reset_to_defaults() # Restores original state .. py:method:: set_coolant_active(coolant_name: str, enabled: bool = True) -> None Enable or disable a specific line coolant species. This controls individual coolant species within the molecular line cooling mechanism (cooling_modules index 5). When a coolant is disabled, its level population calculation is skipped entirely and its cooling contribution is set to zero. :param coolant_name: Name of the coolant species (e.g. "CO", "C+", "p-H2"). Use get_coolant_active() to see available names. :type coolant_name: str :param enabled: True to enable, False to disable. Default: True :type enabled: bool :raises ValueError: If coolant_name is not found in the network. .. rubric:: Examples >>> settings = HeatingSettings() >>> settings.set_coolant_active("CO", False) >>> settings.set_coolant_active("p-H2", False) .. py:method:: set_coolant_directory(directory: str | pathlib.Path) -> None Set the directory containing collisional rate data files. This directory must contain the LAMDA-format collisional rate files (e.g., co.dat, o-h2.dat, etc.) used for molecular line cooling calculations. :param directory: Path to directory containing LAMDA-format rate files. Must end with '/'. Max 255 characters. :type directory: str | Path :raises ValueError: If path is too long or doesn't end with '/' :raises FileNotFoundError: If directory doesn't exist .. rubric:: Examples >>> settings = HeatingSettings() >>> settings.set_coolant_directory("/custom/rates/") # doctest: +SKIP .. py:method:: set_coolant_restart_mode(mode: int) -> None Set the coolant population restart mode. :param mode: Restart mode (0=WARM, 1=FORCE_LTE, 2=FORCE_GROUND) :type mode: int :raises ValueError: If mode is not one of `[0, 1, 2]`. :raises AssertionError: If the mode could not be set in the Fortran module. .. rubric:: Examples >>> settings = HeatingSettings() >>> settings.set_coolant_restart_mode(settings.COOLANT_WARM) .. py:method:: set_cooling_mechanism(mechanism_id: int, enabled: bool = True) -> None Enable or disable a specific cooling mechanism. :param mechanism_id: Index of the cooling mechanism (1-5). Use class constants (e.g., self.ATOMIC_LINE_COOLING) :type mechanism_id: int :param enabled: True to enable, False to disable. Default: True :type enabled: bool :raises ValueError: If mechanism_id is not between 1 and the number of cooling mechanisms. .. rubric:: Examples >>> settings = HeatingSettings() >>> settings.set_cooling_mechanism(settings.MOLECULAR_LINE_COOLING, False) .. py:method:: set_dust_gas_coupling_method(method: int) -> None Set the dust-gas temperature coupling method. :param method: Coupling method to use: - 1 (DUST_TEMP_HOCUK): Hocuk et al. 2017 - 2 (DUST_TEMP_HOLLENBACH): Hollenbach 1991 :type method: int :raises ValueError: If method is not one of `[1, 2]`. .. rubric:: Examples >>> settings = HeatingSettings() >>> settings.set_dust_gas_coupling_method(settings.DUST_TEMP_HOLLENBACH) .. py:method:: set_heating_mechanism(mechanism_id: int, enabled: bool = True) -> None Enable or disable a specific heating mechanism. For mechanisms with multiple implementations (like PHOTOELECTRIC), enabling one automatically disables others in the same group. :param mechanism_id: Index of the heating mechanism (1-9). Use class constants (e.g., self.PHOTOELECTRIC['BAKES'], self.H2_FORMATION) :type mechanism_id: int :param enabled: True to enable, False to disable. Default: True :type enabled: bool :raises ValueError: If mechanism_id is not between 1 and the number of heating mechanisms. .. rubric:: Examples >>> settings = HeatingSettings() >>> # Enable Weingartner photoelectric (auto-disables Bakes) >>> settings.set_heating_mechanism(settings.PHOTOELECTRIC['WEINGARTNER'], True) >>> # Or disable H2 formation >>> settings.set_heating_mechanism(settings.H2_FORMATION, False) .. py:method:: set_line_solver_attempts(attempts: int) -> None Set the number of line cooling solver iterations. The line cooling is computed multiple times and the median is used. :param attempts: Number of solver attempts (odd number recommended). Default is 5. Recommended range: 3-11. :type attempts: int :raises ValueError: If attempts is less than 1. .. rubric:: Examples >>> settings = HeatingSettings() >>> settings.set_line_solver_attempts(7) .. py:method:: set_pah_abundance(abundance: float) -> None Set the PAH (Polycyclic Aromatic Hydrocarbon) abundance. :param abundance: PAH abundance relative to hydrogen. Default: 6e-7 :type abundance: float :raises ValueError: if abundance is smaller than 0 .. rubric:: Examples >>> settings = HeatingSettings() >>> settings.set_pah_abundance(1e-6) .. py:attribute:: ATOMIC_LINE_COOLING :value: 1 .. py:attribute:: CARBON_IONIZATION :value: 6 .. py:attribute:: COMPTON_COOLING :value: 3 .. py:attribute:: CONTINUUM_EMISSION :value: 4 .. py:attribute:: COOLANT_FORCE_GROUND :value: 2 .. py:attribute:: COOLANT_FORCE_LTE :value: 1 .. py:attribute:: COOLANT_WARM :value: 0 .. py:attribute:: COSMIC_RAY :value: 7 .. py:attribute:: DUST_TEMP_HOCUK :value: 1 .. py:attribute:: DUST_TEMP_HOLLENBACH :value: 2 .. py:attribute:: GAS_GRAIN_COLLISIONS :value: 9 .. py:attribute:: H2_COLLISIONALLY_INDUCED :value: 2 .. py:attribute:: H2_FORMATION :value: 3 .. py:attribute:: H2_FUV_PUMPING :value: 5 .. py:attribute:: H2_PHOTODISSOCIATION :value: 4 .. py:attribute:: MOLECULAR_LINE_COOLING :value: 5 .. py:attribute:: PHOTOELECTRIC .. py:attribute:: TURBULENT :value: 8 .. py:class:: NetworkState Runtime interface to UCLCHEM's compiled chemical network. Loads the network from CSV files (on-disk version) and compares with the compiled Fortran network (in-memory version) to ensure consistency. **Thread Safety Warning:** This class modifies global Fortran module state and is **NOT thread-safe**. Do not use with multiprocessing, multithreading, or concurrent model runs. .. rubric:: Examples >>> from uclchem.advanced import NetworkState >>> network = NetworkState() >>> network.validate() # Check on-disk matches in-memory >>> print(f"Species: {len(network.species_list)}") Species: ... >>> print(f"Reactions: {len(network.reaction_list)}") Reactions: ... Initialize the NetworkState interface. Loads species and reactions from CSV files and compares with the compiled Fortran network data. Caches the initial state of all modifiable network parameters for fast resetting. .. py:method:: reset_network_from_csv() -> None Reset the Fortran network to match the cached initial state. This method now uses cached values for better performance and reliability. It's equivalent to reset_state() but kept for backward compatibility. Note: This uses the cached initial state from when NetworkState was created, not by re-reading CSV files. Use reset_state() for the same functionality with a clearer name. Modifiable arrays restored: - alpha, beta, gama: Reaction rate parameters - bindingenergy: Species binding energies .. rubric:: Examples >>> network = NetworkState() >>> # Modify some reaction... >>> network._network.alpha[0] = 999.0 >>> # Reset back to initial values >>> network.reset_state() .. py:method:: reset_state() -> None Reset the Fortran network to its initial cached state. Uses cached values instead of re-reading and parsing CSV files. Restores all modifiable network parameters to their initial values from when NetworkState was created. Modifiable arrays restored: - alpha, beta, gama: Reaction rate parameters - bindingenergy: Species binding energies - formationenthalpy: Formation enthalpies (if available) .. rubric:: Examples >>> network = NetworkState() >>> # Modify some reaction parameters >>> network._network.alpha[0] = 999.0 >>> # Restore to initial state >>> network.reset_state() .. py:method:: validate() -> None Re-run validation to check on-disk matches in-memory. Useful after modifications to verify consistency. .. py:class:: RuntimeNetwork Bases: :py:obj:`uclchem.makerates.network.BaseNetwork` Runtime interface to UCLCHEM's compiled Fortran network. Provides read access and parameter modification for the compiled chemical network during model execution. The network structure (species/reactions) is fixed, but parameters can be modified. To "remove" a reaction: set its alpha parameter to 0.0 using disable_reaction(). To reset changes: call :meth:`reset_to_initial_state`. .. rubric:: Examples >>> # Load runtime network >>> network = RuntimeNetwork() >>> print(f"Species: {len(network.get_species_list())}") Species: ... >>> print(f"Reactions: {len(network.get_reaction_list())}") Reactions: ... >>> # Modify parameters >>> network.modify_reaction_parameters(0, alpha=1e-10, beta=2.0) >>> network.change_binding_energy("#H2O", 5773.0) >>> # Disable a reaction >>> network.disable_reaction(5) >>> # Reset when done >>> network.reset_to_initial_state() You can use this to do a sensitivity analysis in a simple way. >>> # Artificially set a higher diffusion barrier of atomic hydrogen >>> network.change_diffusion_barrier("#H", 600) >>> >>> # Run a model at the increased hydrogen diffusion barrier >>> import uclchem >>> param_dict = {"initialDens": 1e5, "initialTemp": 10, "finalTime": 1e5} >>> high_diffusion_barrier_model = uclchem.model.Cloud(param_dict=param_dict) >>> >>> # Reset to initial state, and then run a "standard" model >>> network.reset_to_initial_state() >>> regular_diffusion_barrier_model = uclchem.model.Cloud(param_dict=param_dict) >>> >>> # Do some analysis to see the effect of a higher hydrogen diffusion barrier >>> # ... Initialize RuntimeNetwork by loading the compiled Fortran module. Automatically imports uclchemwrap.network and validates against species.csv and reactions.csv from the installation directory. :raises ImportError: If uclchemwrap.network cannot be imported .. py:method:: add_reactions(reactions: uclchem.makerates.reaction.Reaction | list[uclchem.makerates.reaction.Reaction]) -> None NOT SUPPORTED: Cannot add reactions to compiled Fortran network. :param reactions: Reactions to add to the network. :type reactions: Reaction | list[Reaction] :raises NotImplementedError: Always - Fortran arrays have fixed size .. py:method:: add_species(species: uclchem.makerates.species.Species | list[uclchem.makerates.species.Species]) -> None NOT SUPPORTED: Cannot add species to compiled Fortran network. :param species: Species instance or list of species to add. :type species: Species | list[Species] :raises NotImplementedError: Always - Fortran arrays have fixed size .. py:method:: change_binding_energy(specie: str, new_binding_energy: float) -> None Change binding energy of a species (modifies Fortran array). :param specie: Name of the species :type specie: str :param new_binding_energy: New binding energy in Kelvin :type new_binding_energy: float .. py:method:: change_diffusion_barrier(specie: str, new_diffusion_barrier: float) -> None Change diffusion barrier of a species (modifies Fortran array). :param specie: Name of the species. :type specie: str :param new_diffusion_barrier: New diffusion barrier in Kelvin. :type new_diffusion_barrier: float .. py:method:: change_reaction_barrier(reaction: uclchem.makerates.reaction.Reaction, barrier: float) -> None Change activation barrier of a reaction (modifies Fortran gamma). :param reaction: Reaction to modify :type reaction: Reaction :param barrier: New activation barrier in Kelvin :type barrier: float :raises RuntimeError: If reaction is not a reaction on the ices. .. py:method:: disable_reaction(reaction_idx: int) -> None Disable a reaction by setting alpha=0. This is the only way to "remove" a reaction at runtime since the Fortran network has fixed structure. Setting alpha=0 makes the reaction have zero rate. :param reaction_idx: Index of reaction to disable (0-based) :type reaction_idx: int .. rubric:: Examples >>> network = RuntimeNetwork() >>> network.disable_reaction(5) >>> network.reset_to_initial_state() .. py:method:: modify_reaction_parameters(reaction_idx: int, alpha: float | None = None, beta: float | None = None, gamma: float | None = None) -> None Modify reaction rate parameters in Fortran arrays. :param reaction_idx: Index of reaction to modify (0-based) :type reaction_idx: int :param alpha: New alpha value (pre-exponential factor) (Default value = None) :type alpha: float | None :param beta: New beta value (temperature exponent) (Default value = None) :type beta: float | None :param gamma: New gamma value (activation energy in K) (Default value = None) :type gamma: float | None :raises IndexError: If reaction_idx out of range .. rubric:: Examples >>> network = RuntimeNetwork() >>> network.modify_reaction_parameters(0, alpha=1e-10, beta=2.0) >>> network.reset_to_initial_state() .. py:method:: remove_reaction(reaction: uclchem.makerates.reaction.Reaction) -> None NOT SUPPORTED: Cannot remove reactions from compiled Fortran network. Use disable_reaction() to set alpha=0 instead. :param reaction: Reaction instance to look up or modify. :type reaction: Reaction :raises NotImplementedError: Always - Fortran arrays have fixed size .. py:method:: remove_reaction_by_index(reaction_idx: int) -> None NOT SUPPORTED: Cannot remove reactions from compiled Fortran network. Use disable_reaction() to set alpha=0 instead. :param reaction_idx: Index of the reaction in the network. :type reaction_idx: int :raises NotImplementedError: Always - Fortran arrays have fixed size .. py:method:: remove_species(specie_name: str) -> None NOT SUPPORTED: Cannot remove species from compiled Fortran network. :param specie_name: Name of the species. :type specie_name: str :raises NotImplementedError: Always - Fortran arrays have fixed size .. py:method:: reset_to_initial_state() -> None Reset all Fortran parameters to their initial cached values. Restores: - All reaction parameters (alpha, beta, gamma) - All species binding energies .. rubric:: Examples >>> network = RuntimeNetwork() >>> network.modify_reaction_parameters(0, alpha=999.0) >>> network.reset_to_initial_state() # Restores original alpha .. py:method:: set_reaction(reaction_idx: int, reaction: uclchem.makerates.reaction.Reaction) -> None NOT SUPPORTED: Cannot replace reactions in compiled Fortran network. :param reaction_idx: Index of the reaction in the network. :type reaction_idx: int :param reaction: Reaction instance to look up or modify. :type reaction: Reaction :raises NotImplementedError: Always - Fortran arrays have fixed size .. py:method:: set_reaction_dict(new_dict: dict[int, uclchem.makerates.reaction.Reaction]) -> None NOT SUPPORTED: Cannot replace reaction dictionary. :param new_dict: Replacement reactions dictionary. :type new_dict: dict[int, Reaction] :raises NotImplementedError: Always - Fortran arrays have fixed size .. py:method:: set_specie(species_name: str, species: uclchem.makerates.species.Species) -> None NOT SUPPORTED: Cannot replace species in compiled Fortran network. :param species_name: Name of the species. :type species_name: str :param species: Species instance or list of species to add. :type species: Species :raises NotImplementedError: Always - Fortran arrays have fixed size .. py:method:: set_species_dict(new_species_dict: dict[str, uclchem.makerates.species.Species]) -> None NOT SUPPORTED: Cannot replace species dictionary. :param new_species_dict: Replacement species dictionary. :type new_species_dict: dict[str, Species] :raises NotImplementedError: Always - Fortran arrays have fixed size .. py:method:: sort_reactions() -> None NOT SUPPORTED: Reaction order is fixed in compiled network. :raises NotImplementedError: Always - reaction order is fixed .. py:method:: sort_species() -> None NOT SUPPORTED: Species order is fixed in compiled network. :raises NotImplementedError: Always - species order is fixed .. py:property:: fortran_module :type: types.ModuleType Direct access to Fortran module for advanced users. Warning: Use with caution. Direct modification bypasses safety checks. :returns: The underlying Fortran module handle for this runtime network. :rtype: ModuleType .. py:function:: create_snapshot() -> dict[str, Any] Capture the current Fortran module state into a picklable dict. Reads directly from Fortran memory (not cached Python values) to ensure accuracy even when settings were modified outside the wrapper classes. The returned dict has three sections: * ``"general"`` – scalar settings from all uclchemwrap sub-modules (excluding PARAMETERs, INTERNAL, FILE_PATH, and arrays). * ``"heating"`` – heating/cooling boolean arrays, scalars, and coolant configuration. * ``"network"`` – Everything in :data:`_NETWORK_ARRAYS_TO_TAKE_SNAPSHOT_OF`. :returns: Fully picklable dict suitable for passing to :func:`restore_snapshot`. :rtype: dict[str, Any] .. py:function:: restore_snapshot(snapshot: dict[str, Any]) -> None Apply a previously captured snapshot to the current process. Must be called **before** running any model in the worker process. :param snapshot: Dict produced by :func:`create_snapshot`. :type snapshot: dict[str, Any]