uclchem.advanced.advanced_heating ================================= .. py:module:: uclchem.advanced.advanced_heating .. autoapi-nested-parse:: Heating and cooling mechanism configuration for UCLCHEM. This module provides class-based interface for accessing and modifying the Fortran heating module that controls UCLCHEM's heating and cooling mechanisms during execution. **Thread Safety Warning:** HeatingSettings modifies global Fortran module state and is **NOT thread-safe**. Do not use with multiprocessing, multithreading, or concurrent model runs. Settings should only be modified during initialization, before running models. Note: Changes made through HeatingSettings affect the global Fortran state and persist across model runs in the same Python session. Module Contents --------------- Classes ~~~~~~~ .. autoapisummary:: uclchem.advanced.advanced_heating.HeatingSettings Functions ~~~~~~~~~ .. autoapisummary:: uclchem.advanced.advanced_heating.auto_initialize_coolant_directory uclchem.advanced.advanced_heating.initialize_coolant_directory Attributes ~~~~~~~~~~ .. autoapisummary:: uclchem.advanced.advanced_heating.logger .. 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:function:: auto_initialize_coolant_directory() -> bool Automatically initialize the coolant data directory for the Fortran module. This is a convenience wrapper around initialize_coolant_directory() that: - Attempts to locate coolant data files - Sets the coolant directory in the Fortran module if found - Logs warnings instead of raising exceptions if initialization fails This function is called automatically when the uclchem module is imported. :returns: True if initialization succeeded, False if it failed :rtype: bool .. rubric:: Examples >>> from uclchem.advanced.advanced_heating import auto_initialize_coolant_directory >>> if auto_initialize_coolant_directory(): ... print("Coolant data initialized successfully") ... Coolant data initialized successfully .. py:function:: initialize_coolant_directory() -> str Locate and return the collisional rate data directory. This function searches for coolant data files in the following order: 1. UCLCHEM_COOLANT_DATA environment variable (if set) 2. Installed package data via importlib.resources (normal installation) 3. Development mode: Makerates/data/collisional_rates/ (relative to project root) :returns: Absolute path to the coolant data directory (with trailing slash) :rtype: str :raises RuntimeError: If the Fortran heating module is not available (not compiled) :raises FileNotFoundError: If coolant data directory cannot be found in any location .. rubric:: Examples >>> from uclchem.advanced.advanced_heating import initialize_coolant_directory >>> coolant_dir = initialize_coolant_directory() >>> print(f"Coolant data at: {coolant_dir}") Coolant data at: ... .. py:data:: logger