From 766bcaec6bd9b48b0d9c2a491861ab8701e94e53 Mon Sep 17 00:00:00 2001 From: Andrew Benson Date: Fri, 17 Nov 2023 10:04:47 -0800 Subject: [PATCH 1/4] feat: Add a new class that provides accretion rates onto black holes This is intended to replace the prior SMBH accretion models that were hard-coded into the `blackHole` components. --- source/black_holes.accretion_rates.F90 | 50 +++ ...oles.accretion_rates.spheroid_tracking.F90 | 127 ++++++ .../black_holes.accretion_rates.standard.F90 | 374 ++++++++++++++++++ 3 files changed, 551 insertions(+) create mode 100644 source/black_holes.accretion_rates.F90 create mode 100644 source/black_holes.accretion_rates.spheroid_tracking.F90 create mode 100644 source/black_holes.accretion_rates.standard.F90 diff --git a/source/black_holes.accretion_rates.F90 b/source/black_holes.accretion_rates.F90 new file mode 100644 index 0000000000..ec4c274aed --- /dev/null +++ b/source/black_holes.accretion_rates.F90 @@ -0,0 +1,50 @@ +!! Copyright 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, +!! 2019, 2020, 2021, 2022, 2023 +!! Andrew Benson +!! +!! This file is part of Galacticus. +!! +!! Galacticus is free software: you can redistribute it and/or modify +!! it under the terms of the GNU General Public License as published by +!! the Free Software Foundation, either version 3 of the License, or +!! (at your option) any later version. +!! +!! Galacticus is distributed in the hope that it will be useful, +!! but WITHOUT ANY WARRANTY; without even the implied warranty of +!! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +!! GNU General Public License for more details. +!! +!! You should have received a copy of the GNU General Public License +!! along with Galacticus. If not, see . + +!!{ +Contains a module which implements a class for black hole accretion rates. +!!} + +module Black_Hole_Accretion_Rates + !!{ + Implements a class for black hole accretion rates. + !!} + use :: Galacticus_Nodes, only : nodeComponentBlackHole + implicit none + private + + !![ + + blackHoleAccretionRate + Black Hole Accretion Rates + + Class providing models of black hole accretion. + + standard + + Computes the mass accretion rate onto a black hole. + void + yes + class (nodeComponentBlackHole), intent(inout) :: blackHole + double precision , intent( out) :: rateMassAccretionSpheroid, rateMassAccretionHotHalo + + + !!] + +end module Black_Hole_Accretion_Rates diff --git a/source/black_holes.accretion_rates.spheroid_tracking.F90 b/source/black_holes.accretion_rates.spheroid_tracking.F90 new file mode 100644 index 0000000000..35b27c17c5 --- /dev/null +++ b/source/black_holes.accretion_rates.spheroid_tracking.F90 @@ -0,0 +1,127 @@ +!! Copyright 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, +!! 2019, 2020, 2021, 2022, 2023 +!! Andrew Benson +!! +!! This file is part of Galacticus. +!! +!! Galacticus is free software: you can redistribute it and/or modify +!! it under the terms of the GNU General Public License as published by +!! the Free Software Foundation, either version 3 of the License, or +!! (at your option) any later version. +!! +!! Galacticus is distributed in the hope that it will be useful, +!! but WITHOUT ANY WARRANTY; without even the implied warranty of +!! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +!! GNU General Public License for more details. +!! +!! You should have received a copy of the GNU General Public License +!! along with Galacticus. If not, see . + + !!{ + Implements the a black hole accretion rate model that tracks the growth of the spheroid. + !!} + + use :: Star_Formation_Rates_Spheroids, only : starFormationRateSpheroidsClass + + !![ + + + A black hole accretion rate calculation that tracks the growth of the spheroid. + + + !!] + type, extends(blackHoleAccretionRateClass) :: blackHoleAccretionRateSpheroidTracking + !!{ + The spheroidTracking black hole accretion rate calculation. + !!} + private + class (starFormationRateSpheroidsClass), pointer :: starFormationRateSpheroids_ => null() + double precision :: growthRatioToStellarSpheroid + contains + final :: spheroidTrackingDestructor + procedure :: rateAccretion => spheroidTrackingRateAccretion + end type blackHoleAccretionRateSpheroidTracking + + interface blackHoleAccretionRateSpheroidTracking + !!{ + Constructors for the {\normalfont \ttfamily spheroidTracking} black hole accretion rate class. + !!} + module procedure spheroidTrackingConstructorParameters + module procedure spheroidTrackingConstructorInternal + end interface blackHoleAccretionRateSpheroidTracking + +contains + + function spheroidTrackingConstructorParameters(parameters) result(self) + !!{ + Constructor for the {\normalfont \ttfamily spheroidTracking} black hole accretion rate class which takes a parameter list as input. + !!} + use :: Input_Parameters, only : inputParameters + implicit none + type (blackHoleAccretionRateSpheroidTracking) :: self + type (inputParameters ), intent(inout) :: parameters + class (starFormationRateSpheroidsClass ), pointer :: starFormationRateSpheroids_ + double precision :: growthRatioToStellarSpheroid + + !![ + + growthRatioToStellarSpheroid + 1.0d-3 + The ratio of the rates of black hole growth and spheroid stellar mass growth. + parameters + + + !!] + self=blackHoleAccretionRateSpheroidTracking(growthRatioToStellarSpheroid,starFormationRateSpheroids_) + !![ + + + !!] + return + end function spheroidTrackingConstructorParameters + + function spheroidTrackingConstructorInternal(growthRatioToStellarSpheroid,starFormationRateSpheroids_) result(self) + !!{ + Internal constructor for the {\normalfont \ttfamily spheroidTracking} node operator class. + !!} + implicit none + type (blackHoleAccretionRateSpheroidTracking) :: self + class (starFormationRateSpheroidsClass ), intent(in ), target :: starFormationRateSpheroids_ + double precision , intent(in ) :: growthRatioToStellarSpheroid + !![ + + !!] + + return + end function spheroidTrackingConstructorInternal + + subroutine spheroidTrackingDestructor(self) + !!{ + Destructor for the critical overdensity spheroidTracking set barrier class. + !!} + implicit none + type(blackHoleAccretionRateSpheroidTracking), intent(inout) :: self + + !![ + + !!] + return + end subroutine spheroidTrackingDestructor + + subroutine spheroidTrackingRateAccretion(self,blackHole,rateMassAccretionSpheroid,rateMassAccretionHotHalo) + !!{ + Compute the accretion rate onto a black hole. + !!} + use :: Galacticus_Nodes, only : treeNode + implicit none + class (blackHoleAccretionRateSpheroidTracking), intent(inout) :: self + class (nodeComponentBlackHole ), intent(inout) :: blackHole + double precision , intent( out) :: rateMassAccretionSpheroid,rateMassAccretionHotHalo + type (treeNode ), pointer :: node + + node => blackHole %host ( ) + rateMassAccretionSpheroid = +self %growthRatioToStellarSpheroid & + & *self %starFormationRateSpheroids_%rate (node) + rateMassAccretionHotHalo = +0.0d0 + return + end subroutine spheroidTrackingRateAccretion diff --git a/source/black_holes.accretion_rates.standard.F90 b/source/black_holes.accretion_rates.standard.F90 new file mode 100644 index 0000000000..169dcd73b1 --- /dev/null +++ b/source/black_holes.accretion_rates.standard.F90 @@ -0,0 +1,374 @@ +!! Copyright 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, +!! 2019, 2020, 2021, 2022, 2023 +!! Andrew Benson +!! +!! This file is part of Galacticus. +!! +!! Galacticus is free software: you can redistribute it and/or modify +!! it under the terms of the GNU General Public License as published by +!! the Free Software Foundation, either version 3 of the License, or +!! (at your option) any later version. +!! +!! Galacticus is distributed in the hope that it will be useful, +!! but WITHOUT ANY WARRANTY; without even the implied warranty of +!! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +!! GNU General Public License for more details. +!! +!! You should have received a copy of the GNU General Public License +!! along with Galacticus. If not, see . + + !!{ + Implements the standard black hole accretion rate calculation. + !!} + + use :: Black_Hole_Binary_Separations, only : blackHoleBinarySeparationGrowthRateClass + use :: Galactic_Structure , only : galacticStructureClass + use :: Accretion_Disks , only : accretionDisksClass + use :: Hot_Halo_Temperature_Profiles, only : hotHaloTemperatureProfileClass + use :: Cooling_Radii , only : coolingRadiusClass + use :: Dark_Matter_Halo_Scales , only : darkMatterHaloScaleClass + + !![ + + + The standard black hole accretion rate calculation. + + + !!] + type, extends(blackHoleAccretionRateClass) :: blackHoleAccretionRateStandard + !!{ + The standard black hole accretion rate calculation. + !!} + private + class (galacticStructureClass ), pointer :: galacticStructure_ => null() + class (blackHoleBinarySeparationGrowthRateClass), pointer :: blackHoleBinarySeparationGrowthRate_ => null() + class (accretionDisksClass ), pointer :: accretionDisks_ => null() + class (hotHaloTemperatureProfileClass ), pointer :: hotHaloTemperatureProfile_ => null() + class (coolingRadiusClass ), pointer :: coolingRadius_ => null() + class (darkMatterHaloScaleClass ), pointer :: darkMatterHaloScale_ => null() + ! Enhancement factors for the accretion rate. + double precision :: bondiHoyleAccretionEnhancementHotHalo , bondiHoyleAccretionEnhancementSpheroid + ! Temperature of accreting gas. + double precision :: bondiHoyleAccretionTemperatureSpheroid + ! Control for hot mode only accretion. + logical :: bondiHoyleAccretionHotModeOnly + ! Record of whether cold mode is explicitly tracked. + logical :: coldModeTracked + contains + !![ + + + + !!] + final :: standardDestructor + procedure :: rateAccretion => standardRateAccretion + procedure :: hotModeFraction => standardHotModeFraction + end type blackHoleAccretionRateStandard + + interface blackHoleAccretionRateStandard + !!{ + Constructors for the {\normalfont \ttfamily standard} black hole accretion rate class. + !!} + module procedure standardConstructorParameters + module procedure standardConstructorInternal + end interface blackHoleAccretionRateStandard + +contains + + function standardConstructorParameters(parameters) result(self) + !!{ + Constructor for the {\normalfont \ttfamily standard} black hole accretion rate class which takes a parameter list as input. + !!} + use :: Input_Parameters, only : inputParameters + implicit none + type (blackHoleAccretionRateStandard ) :: self + type (inputParameters ), intent(inout) :: parameters + class (galacticStructureClass ), pointer :: galacticStructure_ + class (blackHoleBinarySeparationGrowthRateClass), pointer :: blackHoleBinarySeparationGrowthRate_ + class (accretionDisksClass ), pointer :: accretionDisks_ + class (hotHaloTemperatureProfileClass ), pointer :: hotHaloTemperatureProfile_ + class (coolingRadiusClass ), pointer :: coolingRadius_ + class (darkMatterHaloScaleClass ), pointer :: darkMatterHaloScale_ + double precision :: bondiHoyleAccretionEnhancementHotHalo , bondiHoyleAccretionEnhancementSpheroid, & + & bondiHoyleAccretionTemperatureSpheroid + logical :: bondiHoyleAccretionHotModeOnly + + !![ + + bondiHoyleAccretionEnhancementSpheroid + 5.0d0 + The factor by which the Bondi-Hoyle accretion rate of spheroid gas onto black holes in enhanced. + parameters + + + bondiHoyleAccretionEnhancementHotHalo + 6.0d0 + The factor by which the Bondi-Hoyle accretion rate of hot halo gas onto black holes in enhanced. + parameters + + + bondiHoyleAccretionHotModeOnly + .true. + Determines whether accretion from the hot halo should only occur if the halo is in the hot accretion mode. + parameters + + + bondiHoyleAccretionTemperatureSpheroid + 1.0d2 + The assumed temperature (in Kelvin) of gas in the spheroid when computing Bondi-Hoyle accretion rates onto black holes. + parameters + + + + + + + + !!] + self=blackHoleAccretionRateStandard(bondiHoyleAccretionEnhancementHotHalo,bondiHoyleAccretionEnhancementSpheroid,bondiHoyleAccretionTemperatureSpheroid,bondiHoyleAccretionHotModeOnly,galacticStructure_,blackHoleBinarySeparationGrowthRate_,hotHaloTemperatureProfile_,accretionDisks_,coolingRadius_,darkMatterHaloScale_) + !![ + + + + + + + + !!] + return + end function standardConstructorParameters + + function standardConstructorInternal(bondiHoyleAccretionEnhancementHotHalo,bondiHoyleAccretionEnhancementSpheroid,bondiHoyleAccretionTemperatureSpheroid,bondiHoyleAccretionHotModeOnly,galacticStructure_,blackHoleBinarySeparationGrowthRate_,hotHaloTemperatureProfile_,accretionDisks_,coolingRadius_,darkMatterHaloScale_) result(self) + !!{ + Internal constructor for the {\normalfont \ttfamily standard} node operator class. + !!} + use :: Galacticus_Nodes, only : defaultHotHaloComponent + implicit none + type (blackHoleAccretionRateStandard ) :: self + class (galacticStructureClass ), target, intent(in ) :: galacticStructure_ + class (blackHoleBinarySeparationGrowthRateClass), target, intent(in ) :: blackHoleBinarySeparationGrowthRate_ + class (accretionDisksClass ), target, intent(in ) :: accretionDisks_ + class (hotHaloTemperatureProfileClass ), target, intent(in ) :: hotHaloTemperatureProfile_ + class (coolingRadiusClass ), target, intent(in ) :: coolingRadius_ + class (darkMatterHaloScaleClass ), target, intent(in ) :: darkMatterHaloScale_ + double precision , intent(in ) :: bondiHoyleAccretionEnhancementHotHalo , bondiHoyleAccretionEnhancementSpheroid, & + & bondiHoyleAccretionTemperatureSpheroid + logical , intent(in ) :: bondiHoyleAccretionHotModeOnly + !![ + + !!] + + ! Check if cold mode is explicitly tracked. + self%coldModeTracked=defaultHotHaloComponent%massColdIsGettable() + return + end function standardConstructorInternal + + subroutine standardDestructor(self) + !!{ + Destructor for the critical overdensity standard set barrier class. + !!} + implicit none + type(blackHoleAccretionRateStandard), intent(inout) :: self + + !![ + + + + + + + !!] + return + end subroutine standardDestructor + + subroutine standardRateAccretion(self,blackHole,rateMassAccretionSpheroid,rateMassAccretionHotHalo) + !!{ + Compute the accretion rate onto a black hole. + !!} + use :: Black_Hole_Fundamentals , only : Black_Hole_Eddington_Accretion_Rate + use :: Bondi_Hoyle_Lyttleton_Accretion , only : Bondi_Hoyle_Lyttleton_Accretion_Radius, Bondi_Hoyle_Lyttleton_Accretion_Rate + use :: Galactic_Structure_Options , only : componentTypeColdHalo , componentTypeHotHalo , componentTypeSpheroid, coordinateSystemCylindrical, & + & massTypeGaseous + use :: Galacticus_Nodes , only : nodeComponentBlackHole , nodeComponentHotHalo , nodeComponentSpheroid, treeNode + use :: Ideal_Gases_Thermodynamics , only : Ideal_Gas_Jeans_Length , Ideal_Gas_Sound_Speed + use :: Numerical_Constants_Astronomical, only : Mpc_per_km_per_s_To_Gyr , gigaYear , megaParsec + use :: Numerical_Constants_Prefixes , only : kilo + implicit none + class (blackHoleAccretionRateStandard), intent(inout) :: self + class (nodeComponentBlackHole ), intent(inout) :: blackHole + double precision , intent( out) :: rateMassAccretionSpheroid ,rateMassAccretionHotHalo + type (treeNode ), pointer :: node + class (nodeComponentSpheroid ), pointer :: spheroid + class (nodeComponentHotHalo ), pointer :: hotHalo + ! Lowest gas density to consider when computing accretion rates onto black hole (in units of M☉/Mpc³). + double precision , parameter :: densityGasMinimum =1.0d0 + double precision , dimension(3) :: position + double precision :: radiusAccretion , rateAccretionMaximum , & + & massBlackHole , densityGas , & + & temperatureHotHalo , fractionHotMode , & + & lengthJeans , fractionColdMode , & + & efficiencyRadiative , velocityRelative + & + + ! Get the host node. + node => blackHole%host() + ! Get black hole mass. + massBlackHole = blackHole%mass() + ! Check black hole mass is positive. + if (massBlackHole > 0.0d0) then + ! Compute the relative velocity of black hole and gas. We assume that relative motion arises only from the radial + ! migration of the black hole. + velocityRelative=+self%blackHoleBinarySeparationGrowthRate_%growthRate(blackHole) & + & *Mpc_per_km_per_s_To_Gyr + ! Contribution from spheroid: + ! Get the accretion radius. We take this to be the larger of the Bondi-Hoyle radius and the current radius position of + ! the black hole. + radiusAccretion=max( & + & Bondi_Hoyle_Lyttleton_Accretion_Radius(massBlackHole,self%bondiHoyleAccretionTemperatureSpheroid) & + & ,blackHole%radialPosition() & + & ) + ! Set the position. + position=[radiusAccretion,0.0d0,0.0d0] + ! Get density of gas at the galactic center. + densityGas=self%galacticStructure_%density(node,position,coordinateSystem=coordinateSystemCylindrical,componentType=componentTypeSpheroid,massType =massTypeGaseous) + ! Check if we have a non-negligible gas density. + if (densityGas > densityGasMinimum) then + ! Get the spheroid component. + spheroid => node%spheroid() + ! Get the Jeans length scale. + lengthJeans=Ideal_Gas_Jeans_Length(self%bondiHoyleAccretionTemperatureSpheroid,densityGas) + ! Limit the smoothing scale to the scale of the spheroid. + lengthJeans=min(lengthJeans,spheroid%radius()) + ! If the Jeans length exceeds the Bondi-Hoyle-Lyttleton accretion radius, then recompute gas density for a larger + ! radius, as the gas should be smoothly distributed on scales below the Jeans length. + if (lengthJeans > radiusAccretion) then + ! Set the position. + position=[lengthJeans,0.0d0,0.0d0] + ! Get density of gas at the galactic center. + densityGas=self%galacticStructure_%density(node,position,coordinateSystem=coordinateSystemCylindrical,componentType=componentTypeSpheroid,massType=massTypeGaseous) + end if + ! Compute the accretion rate. + rateMassAccretionSpheroid=max( & + & +self%bondiHoyleAccretionEnhancementSpheroid & + & *Bondi_Hoyle_Lyttleton_Accretion_Rate(massBlackHole,densityGas,velocityRelative,self%bondiHoyleAccretionTemperatureSpheroid), & + & +0.0d0 & + & ) + ! Get the radiative efficiency of the accretion. + efficiencyRadiative=self%accretionDisks_%efficiencyRadiative(blackHole,rateMassAccretionSpheroid) + ! Limit the accretion rate to the Eddington limit. + if (efficiencyRadiative > 0.0d0) rateMassAccretionSpheroid=min(rateMassAccretionSpheroid,Black_Hole_Eddington_Accretion_Rate(blackHole) /efficiencyRadiative) + else + ! Gas density is negative - set zero accretion rate. + rateMassAccretionSpheroid=0.0d0 + end if + ! Contribution from hot halo: + ! Get the hot halo component. + hotHalo => node%hotHalo() + ! Get halo gas temperature. + temperatureHotHalo=self%hotHaloTemperatureProfile_%temperature(node,radius=0.0d0) + ! Get the accretion radius. + radiusAccretion=Bondi_Hoyle_Lyttleton_Accretion_Radius(massBlackHole,temperatureHotHalo) + radiusAccretion=min(radiusAccretion,hotHalo%outerRadius()) + ! Set the position. + position=[radiusAccretion,0.0d0,0.0d0] + ! Find the fraction of gas in the halo which is in the hot mode. Set this to unity if hot/cold mode is not to be + ! considered. + select case (self%bondiHoyleAccretionHotModeOnly) + case (.true.) + if (self%coldModeTracked) then + fractionHotMode=1.0d0 + else + fractionHotMode=self%hotModeFraction(node) + end if + fractionColdMode=0.0d0 + case (.false.) + fractionHotMode=1.0d0 + if (self%coldModeTracked) then + fractionColdMode=1.0d0 + else + fractionColdMode=0.0d0 + end if + end select + ! Get density of gas at the galactic center - scaled by the fraction in the hot accretion mode. + densityGas =+fractionHotMode & + & *self%galacticStructure_%density( & + & node , & + & position , & + & coordinateSystem=coordinateSystemCylindrical, & + & componentType =componentTypeHotHalo , & + & massType =massTypeGaseous & + & ) + if (self%coldModeTracked.and.fractionColdMode > 0.0d0) & + & densityGas=+densityGas & + & +fractionColdMode & + & *self%galacticStructure_%density( & + & node , & + & position , & + & coordinateSystem=coordinateSystemCylindrical, & + & componentType =componentTypeColdHalo , & + & massType =massTypeGaseous & + & ) + ! Check if we have a non-zero gas density. + if (densityGas > densityGasMinimum) then + ! Compute the accretion rate. + rateMassAccretionHotHalo=max( & + & +self%bondiHoyleAccretionEnhancementHotHalo & + & *Bondi_Hoyle_Lyttleton_Accretion_Rate(massBlackHole,densityGas,velocityRelative,temperatureHotHalo,radiusAccretion), & + & +0.0d0 & + & ) + ! Limit the accretion rate to the total mass of the hot halo, divided by the sound crossing time. + rateAccretionMaximum=max( & + & +hotHalo%mass() & + & /( & + & +hotHalo%outerRadius() & + & /Ideal_Gas_Sound_Speed(temperatureHotHalo) & + & *Mpc_per_km_per_s_To_Gyr & + & ) , & + & +0.0d0 & + & ) + rateMassAccretionHotHalo=min(rateMassAccretionHotHalo,rateAccretionMaximum) + ! Get the radiative efficiency of the accretion. + efficiencyRadiative=self%accretionDisks_%efficiencyRadiative(blackHole,rateMassAccretionHotHalo) + ! Limit the accretion rate to the Eddington limit. + if (efficiencyRadiative > 0.0d0) & + & rateMassAccretionHotHalo=min( & + & +rateMassAccretionHotHalo , & + & +Black_Hole_Eddington_Accretion_Rate(blackHole) & + & /efficiencyRadiative & + & ) + else + ! No gas density, so zero accretion rate. + rateMassAccretionHotHalo=0.0d0 + end if + else + rateMassAccretionSpheroid=0.0d0 + rateMassAccretionHotHalo =0.0d0 + end if + return + end subroutine standardRateAccretion + + double precision function standardHotModeFraction(self,node) + !!{ + A simple interpolating function which is used as a measure of the fraction of a halo which is in the hot accretion mode. + !!} + use :: Galacticus_Nodes, only : treeNode + implicit none + class (blackHoleAccretionRateStandard), intent(inout) :: self + type (treeNode ), intent(inout) :: node + double precision , parameter :: coolingRadiusFractionalTransitionMinimum=0.9d0 + double precision , parameter :: coolingRadiusFractionalTransitionMaximum=1.0d0 + double precision :: coolingRadiusFractional , x + + coolingRadiusFractional=+self%coolingRadius_ % radius(node) & + & /self%darkMatterHaloScale_%radiusVirial(node) + if (coolingRadiusFractional < coolingRadiusFractionalTransitionMinimum) then + standardHotModeFraction=1.0d0 + else if (coolingRadiusFractional > coolingRadiusFractionalTransitionMaximum) then + standardHotModeFraction=0.0d0 + else + x= (coolingRadiusFractional -coolingRadiusFractionalTransitionMinimum) & + & /(coolingRadiusFractionalTransitionMaximum-coolingRadiusFractionalTransitionMinimum) + standardHotModeFraction=x**2*(2.0d0*x-3.0d0)+1.0d0 + end if + return + end function standardHotModeFraction From dd8c005fc2499ad42e4e12e370938a8e7deeb4c8 Mon Sep 17 00:00:00 2001 From: Andrew Benson Date: Fri, 17 Nov 2023 10:06:03 -0800 Subject: [PATCH 2/4] feat: Add nodePropertyExtractors to extract a variety of black hole properties These are intended to replace the SMBH property output functions that were hard-coded into the `blackHole` components. --- ...operty_extractor.jet_power_black_holes.F90 | 190 ++++++++++++++++++ ...ractor.mass_accretion_rate_black_holes.F90 | 180 +++++++++++++++++ ...es.property_extractor.mass_black_holes.F90 | 140 +++++++++++++ ...actor.radiative_efficiency_black_holes.F90 | 186 +++++++++++++++++ ....property_extractor.radius_black_holes.F90 | 180 +++++++++++++++++ ...es.property_extractor.spin_black_holes.F90 | 139 +++++++++++++ 6 files changed, 1015 insertions(+) create mode 100644 source/nodes.property_extractor.jet_power_black_holes.F90 create mode 100644 source/nodes.property_extractor.mass_accretion_rate_black_holes.F90 create mode 100644 source/nodes.property_extractor.mass_black_holes.F90 create mode 100644 source/nodes.property_extractor.radiative_efficiency_black_holes.F90 create mode 100644 source/nodes.property_extractor.radius_black_holes.F90 create mode 100644 source/nodes.property_extractor.spin_black_holes.F90 diff --git a/source/nodes.property_extractor.jet_power_black_holes.F90 b/source/nodes.property_extractor.jet_power_black_holes.F90 new file mode 100644 index 0000000000..e46b7217f8 --- /dev/null +++ b/source/nodes.property_extractor.jet_power_black_holes.F90 @@ -0,0 +1,190 @@ +!! Copyright 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, +!! 2019, 2020, 2021, 2022, 2023 +!! Andrew Benson +!! +!! This file is part of Galacticus. +!! +!! Galacticus is free software: you can redistribute it and/or modify +!! it under the terms of the GNU General Public License as published by +!! the Free Software Foundation, either version 3 of the License, or +!! (at your option) any later version. +!! +!! Galacticus is distributed in the hope that it will be useful, +!! but WITHOUT ANY WARRANTY; without even the implied warranty of +!! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +!! GNU General Public License for more details. +!! +!! You should have received a copy of the GNU General Public License +!! along with Galacticus. If not, see . + + use :: Accretion_Disks , only : accretionDisksClass + use :: Black_Hole_Accretion_Rates, only : blackHoleAccretionRateClass + + !![ + + + A node property extractor which extracts a list of all super-massive jet powers. + + + !!] + type, extends(nodePropertyExtractorList) :: nodePropertyExtractorJetPowerBlackHoles + !!{ + A property extractor which extracts a list of all super-massive black hole jet powers. + !!} + private + class(accretionDisksClass ), pointer :: accretionDisks_ => null() + class(blackHoleAccretionRateClass), pointer :: blackHoleAccretionRate_ => null() + contains + final :: jetPowerBlackHolesDestructor + procedure :: elementCount => jetPowerBlackHolesElementCount + procedure :: extract => jetPowerBlackHolesExtract + procedure :: names => jetPowerBlackHolesNames + procedure :: descriptions => jetPowerBlackHolesDescriptions + procedure :: unitsInSI => jetPowerBlackHolesUnitsInSI + end type nodePropertyExtractorJetPowerBlackHoles + + interface nodePropertyExtractorJetPowerBlackHoles + !!{ + Constructors for the ``jetPowerBlackHoles'' output extractor class. + !!} + module procedure jetPowerBlackHolesConstructorParameters + module procedure jetPowerBlackHolesConstructorInternal + end interface nodePropertyExtractorJetPowerBlackHoles + +contains + + function jetPowerBlackHolesConstructorParameters(parameters) result(self) + !!{ + Constructor for the ``jetPowerBlackHoles'' property extractor class which takes a parameter set as input. + !!} + use :: Input_Parameters, only : inputParameter, inputParameters + implicit none + type (nodePropertyExtractorJetPowerBlackHoles) :: self + type (inputParameters ), intent(inout) :: parameters + class(accretionDisksClass ), pointer :: accretionDisks_ + class(blackHoleAccretionRateClass ), pointer :: blackHoleAccretionRate_ + + !![ + + + !!] + self=nodePropertyExtractorJetPowerBlackHoles(blackHoleAccretionRate_,accretionDisks_) + !![ + + + + !!] + return + end function jetPowerBlackHolesConstructorParameters + + function jetPowerBlackHolesConstructorInternal(blackHoleAccretionRate_,accretionDisks_) result(self) + !!{ + Internal constructor for the {\normalfont \ttfamily jetPowerBlackHoles} node operator class. + !!} + use :: Galacticus_Nodes, only : defaultBasicComponent + implicit none + type (nodePropertyExtractorJetPowerBlackHoles) :: self + class(accretionDisksClass ), intent(in ), target :: accretionDisks_ + class(blackHoleAccretionRateClass ), intent(in ), target :: blackHoleAccretionRate_ + !![ + + !!] + + return + end function jetPowerBlackHolesConstructorInternal + + subroutine jetPowerBlackHolesDestructor(self) + !!{ + Destructor for the critical overdensity jetPowerBlackHoles set barrier class. + !!} + implicit none + type(nodePropertyExtractorJetPowerBlackHoles), intent(inout) :: self + + !![ + + + !!] + return + end subroutine jetPowerBlackHolesDestructor + + integer function jetPowerBlackHolesElementCount(self) + !!{ + Return a count of the number of properties extracted. + !!} + implicit none + class(nodePropertyExtractorJetPowerBlackHoles), intent(inout) :: self + + jetPowerBlackHolesElementCount=1 + return + end function jetPowerBlackHolesElementCount + + function jetPowerBlackHolesExtract(self,node,instance) result(radiativeEfficiency) + !!{ + Implement an output extractor for the radiative efficiencies of all supermassive black holes. + !!} + use :: Galacticus_Nodes, only : nodeComponentBlackHole + implicit none + double precision , dimension(:,:), allocatable :: radiativeEfficiency + class (nodePropertyExtractorJetPowerBlackHoles), intent(inout) :: self + type (treeNode ), intent(inout) :: node + type (multiCounter ), intent(inout) , optional :: instance + class (nodeComponentBlackHole ) , pointer :: blackHole + integer :: i , countBlackHoles + double precision :: rateMassAccretionSpheroid, rateMassAccretionHotHalo + !$GLC attributes unused :: instance + + countBlackHoles=node%blackHoleCount() + allocate(radiativeEfficiency(countBlackHoles,1)) + do i=1,countBlackHoles + blackHole => node %blackHole(instance=i) + call self%blackHoleAccretionRate_%rateAccretion(blackHole,rateMassAccretionSpheroid,rateMassAccretionHotHalo) + radiativeEfficiency(i,1) = self%accretionDisks_%powerJet(blackHole,rateMassAccretionSpheroid+rateMassAccretionHotHalo) + end do + return + end function jetPowerBlackHolesExtract + + subroutine jetPowerBlackHolesNames(self,names) + !!{ + Return the names of the {\normalfont \ttfamily jetPowerBlackHoles} properties. + !!} + implicit none + class(nodePropertyExtractorJetPowerBlackHoles), intent(inout) :: self + type (varying_string ), intent(inout), dimension(:) , allocatable :: names + !$GLC attributes unused :: self + + allocate(names(1)) + names(1)=var_str('powerJetBlackHoles') + return + end subroutine jetPowerBlackHolesNames + + subroutine jetPowerBlackHolesDescriptions(self,descriptions) + !!{ + Return the descriptions of the {\normalfont \ttfamily jetPowerBlackHoles} properties. + !!} + implicit none + class(nodePropertyExtractorJetPowerBlackHoles), intent(inout) :: self + type (varying_string ), intent(inout), dimension(:) , allocatable :: descriptions + !$GLC attributes unused :: self + + allocate(descriptions(1)) + descriptions(1)=var_str('Jet power of super-massive black holes in this galaxy [M☉ (km/s)² Gyr¯¹].') + return + end subroutine jetPowerBlackHolesDescriptions + + function jetPowerBlackHolesUnitsInSI(self) result(unitsInSI) + !!{ + Return the units of the {\normalfont \ttfamily jetPowerBlackHoles} properties in the SI system. + !!} + use :: Numerical_Constants_Prefixes , only : kilo + use :: Numerical_Constants_Astronomical, only : massSolar, gigaYear + implicit none + double precision , dimension(:) , allocatable :: unitsInSI + class (nodePropertyExtractorJetPowerBlackHoles), intent(inout) :: self + !$GLC attributes unused :: self + + allocate(unitsInSI(1)) + unitsInSI(1)=+massSolar & + & *kilo **2 & + & /gigaYear + return + end function jetPowerBlackHolesUnitsInSI diff --git a/source/nodes.property_extractor.mass_accretion_rate_black_holes.F90 b/source/nodes.property_extractor.mass_accretion_rate_black_holes.F90 new file mode 100644 index 0000000000..12c6c4cdbd --- /dev/null +++ b/source/nodes.property_extractor.mass_accretion_rate_black_holes.F90 @@ -0,0 +1,180 @@ +!! Copyright 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, +!! 2019, 2020, 2021, 2022, 2023 +!! Andrew Benson +!! +!! This file is part of Galacticus. +!! +!! Galacticus is free software: you can redistribute it and/or modify +!! it under the terms of the GNU General Public License as published by +!! the Free Software Foundation, either version 3 of the License, or +!! (at your option) any later version. +!! +!! Galacticus is distributed in the hope that it will be useful, +!! but WITHOUT ANY WARRANTY; without even the implied warranty of +!! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +!! GNU General Public License for more details. +!! +!! You should have received a copy of the GNU General Public License +!! along with Galacticus. If not, see . + + use :: Black_Hole_Accretion_Rates, only : blackHoleAccretionRateClass + + !![ + + + A node property extractor which extracts a list of all super-massive black hole mass accretion rates. + + + !!] + type, extends(nodePropertyExtractorList) :: nodePropertyExtractorMassAccretionRateBlackHoles + !!{ + A property extractor which extracts a list of all super-massive black hole mass accretion rates. + !!} + private + class(blackHoleAccretionRateClass), pointer :: blackHoleAccretionRate_ => null() + contains + final :: massAccretionRateBlackHolesDestructor + procedure :: elementCount => massAccretionRateBlackHolesElementCount + procedure :: extract => massAccretionRateBlackHolesExtract + procedure :: names => massAccretionRateBlackHolesNames + procedure :: descriptions => massAccretionRateBlackHolesDescriptions + procedure :: unitsInSI => massAccretionRateBlackHolesUnitsInSI + end type nodePropertyExtractorMassAccretionRateBlackHoles + + interface nodePropertyExtractorMassAccretionRateBlackHoles + !!{ + Constructors for the ``massAccretionRateBlackHoles'' output extractor class. + !!} + module procedure massAccretionRateBlackHolesConstructorParameters + module procedure massAccretionRateBlackHolesConstructorInternal + end interface nodePropertyExtractorMassAccretionRateBlackHoles + +contains + + function massAccretionRateBlackHolesConstructorParameters(parameters) result(self) + !!{ + Constructor for the ``massAccretionRateBlackHoles'' property extractor class which takes a parameter set as input. + !!} + use :: Input_Parameters, only : inputParameter, inputParameters + implicit none + type (nodePropertyExtractorMassAccretionRateBlackHoles) :: self + type (inputParameters ), intent(inout) :: parameters + class(blackHoleAccretionRateClass ), pointer :: blackHoleAccretionRate_ + + !![ + + !!] + self=nodePropertyExtractorMassAccretionRateBlackHoles(blackHoleAccretionRate_) + !![ + + + !!] + return + end function massAccretionRateBlackHolesConstructorParameters + + function massAccretionRateBlackHolesConstructorInternal(blackHoleAccretionRate_) result(self) + !!{ + Internal constructor for the {\normalfont \ttfamily massAccretionRateBlackHoles} node operator class. + !!} + implicit none + type (nodePropertyExtractorMassAccretionRateBlackHoles) :: self + class(blackHoleAccretionRateClass ), intent(in ), target :: blackHoleAccretionRate_ + !![ + + !!] + + return + end function massAccretionRateBlackHolesConstructorInternal + + subroutine massAccretionRateBlackHolesDestructor(self) + !!{ + Destructor for the critical overdensity massAccretionRateBlackHoles set barrier class. + !!} + implicit none + type(nodePropertyExtractorMassAccretionRateBlackHoles), intent(inout) :: self + + !![ + + !!] + return + end subroutine massAccretionRateBlackHolesDestructor + + integer function massAccretionRateBlackHolesElementCount(self) + !!{ + Return a count of the number of properties extracted. + !!} + implicit none + class(nodePropertyExtractorMassAccretionRateBlackHoles), intent(inout) :: self + + massAccretionRateBlackHolesElementCount=1 + return + end function massAccretionRateBlackHolesElementCount + + function massAccretionRateBlackHolesExtract(self,node,instance) result(massAccretionRate) + !!{ + Implement an output extractor for the radiative efficiencies of all supermassive black holes. + !!} + use :: Galacticus_Nodes, only : nodeComponentBlackHole + implicit none + double precision , dimension(:,:), allocatable :: massAccretionRate + class (nodePropertyExtractorMassAccretionRateBlackHoles), intent(inout) :: self + type (treeNode ), intent(inout) :: node + type (multiCounter ), intent(inout) , optional :: instance + class (nodeComponentBlackHole ) , pointer :: blackHole + integer :: i , countBlackHoles + double precision :: rateMassAccretionSpheroid, rateMassAccretionHotHalo + !$GLC attributes unused :: instance + + countBlackHoles=node%blackHoleCount() + allocate(massAccretionRate(countBlackHoles,1)) + do i=1,countBlackHoles + blackHole => node%blackHole(instance=i) + call self%blackHoleAccretionRate_%rateAccretion(blackHole,rateMassAccretionSpheroid, rateMassAccretionHotHalo) + massAccretionRate (i,1) = +rateMassAccretionSpheroid & + & +rateMassAccretionHotHalo + end do + return + end function massAccretionRateBlackHolesExtract + + subroutine massAccretionRateBlackHolesNames(self,names) + !!{ + Return the names of the {\normalfont \ttfamily massAccretionRateBlackHoles} properties. + !!} + implicit none + class(nodePropertyExtractorMassAccretionRateBlackHoles), intent(inout) :: self + type (varying_string ), intent(inout), dimension(:) , allocatable :: names + !$GLC attributes unused :: self + + allocate(names(1)) + names(1)=var_str('massAccretionRateBlackHoles') + return + end subroutine massAccretionRateBlackHolesNames + + subroutine massAccretionRateBlackHolesDescriptions(self,descriptions) + !!{ + Return the descriptions of the {\normalfont \ttfamily massAccretionRateBlackHoles} properties. + !!} + implicit none + class(nodePropertyExtractorMassAccretionRateBlackHoles), intent(inout) :: self + type (varying_string ), intent(inout), dimension(:) , allocatable :: descriptions + !$GLC attributes unused :: self + + allocate(descriptions(1)) + descriptions(1)=var_str('Mass accretion rates of super-massive black holes in this galaxy.') + return + end subroutine massAccretionRateBlackHolesDescriptions + + function massAccretionRateBlackHolesUnitsInSI(self) result(unitsInSI) + !!{ + Return the units of the {\normalfont \ttfamily massAccretionRateBlackHoles} properties in the SI system. + !!} + use :: Numerical_Constants_Astronomical, only : massSolar, gigaYear + implicit none + double precision , dimension(:) , allocatable :: unitsInSI + class (nodePropertyExtractorMassAccretionRateBlackHoles), intent(inout) :: self + !$GLC attributes unused :: self + + allocate(unitsInSI(1)) + unitsInSI(1)=massSolar/gigaYear + return + end function massAccretionRateBlackHolesUnitsInSI diff --git a/source/nodes.property_extractor.mass_black_holes.F90 b/source/nodes.property_extractor.mass_black_holes.F90 new file mode 100644 index 0000000000..e64224cca3 --- /dev/null +++ b/source/nodes.property_extractor.mass_black_holes.F90 @@ -0,0 +1,140 @@ +!! Copyright 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, +!! 2019, 2020, 2021, 2022, 2023 +!! Andrew Benson +!! +!! This file is part of Galacticus. +!! +!! Galacticus is free software: you can redistribute it and/or modify +!! it under the terms of the GNU General Public License as published by +!! the Free Software Foundation, either version 3 of the License, or +!! (at your option) any later version. +!! +!! Galacticus is distributed in the hope that it will be useful, +!! but WITHOUT ANY WARRANTY; without even the implied warranty of +!! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +!! GNU General Public License for more details. +!! +!! You should have received a copy of the GNU General Public License +!! along with Galacticus. If not, see . + + !![ + + + A node property extractor which extracts a list of all super-massive black hole masses. + + + !!] + type, extends(nodePropertyExtractorList) :: nodePropertyExtractorMassBlackHoles + !!{ + A property extractor which extracts a list of all super-massive black hole masses. + !!} + private + contains + procedure :: elementCount => massBlackHolesElementCount + procedure :: extract => massBlackHolesExtract + procedure :: names => massBlackHolesNames + procedure :: descriptions => massBlackHolesDescriptions + procedure :: unitsInSI => massBlackHolesUnitsInSI + end type nodePropertyExtractorMassBlackHoles + + interface nodePropertyExtractorMassBlackHoles + !!{ + Constructors for the ``massBlackHoles'' output extractor class. + !!} + module procedure massBlackHolesConstructorParameters + end interface nodePropertyExtractorMassBlackHoles + +contains + + function massBlackHolesConstructorParameters(parameters) result(self) + !!{ + Constructor for the ``massBlackHoles'' property extractor class which takes a parameter set as input. + !!} + use :: Input_Parameters, only : inputParameter, inputParameters + implicit none + type(nodePropertyExtractorMassBlackHoles) :: self + type(inputParameters ), intent(inout) :: parameters + + self=nodePropertyExtractorMassBlackHoles() + !![ + + !!] + return + end function massBlackHolesConstructorParameters + + integer function massBlackHolesElementCount(self) + !!{ + Return a count of the number of properties extracted. + !!} + implicit none + class(nodePropertyExtractorMassBlackHoles), intent(inout) :: self + + massBlackHolesElementCount=1 + return + end function massBlackHolesElementCount + + function massBlackHolesExtract(self,node,instance) result(mass) + !!{ + Implement an output extractor for the masses of all supermassive black holes. + !!} + use :: Galacticus_Nodes, only : nodeComponentBlackHole + implicit none + double precision , dimension(:,:), allocatable :: mass + class (nodePropertyExtractorMassBlackHoles), intent(inout) :: self + type (treeNode ), intent(inout) :: node + type (multiCounter ), intent(inout) , optional :: instance + class (nodeComponentBlackHole ) , pointer :: blackHole + integer :: i , countBlackHoles + !$GLC attributes unused :: instance + + countBlackHoles=node%blackHoleCount() + allocate(mass(countBlackHoles,1)) + do i=1,countBlackHoles + blackHole => node %blackHole(instance=i) + mass (i,1) = blackHole%mass ( ) + end do + return + end function massBlackHolesExtract + + subroutine massBlackHolesNames(self,names) + !!{ + Return the names of the {\normalfont \ttfamily massBlackHoles} properties. + !!} + implicit none + class(nodePropertyExtractorMassBlackHoles), intent(inout) :: self + type (varying_string ), intent(inout), dimension(:) , allocatable :: names + !$GLC attributes unused :: self + + allocate(names(1)) + names(1)=var_str('massBlackHoles') + return + end subroutine massBlackHolesNames + + subroutine massBlackHolesDescriptions(self,descriptions) + !!{ + Return the descriptions of the {\normalfont \ttfamily massBlackHoles} properties. + !!} + implicit none + class(nodePropertyExtractorMassBlackHoles), intent(inout) :: self + type (varying_string ), intent(inout), dimension(:) , allocatable :: descriptions + !$GLC attributes unused :: self + + allocate(descriptions(1)) + descriptions(1)=var_str('Masses of super-massive black holes in this galaxy.') + return + end subroutine massBlackHolesDescriptions + + function massBlackHolesUnitsInSI(self) result(unitsInSI) + !!{ + Return the units of the {\normalfont \ttfamily massBlackHoles} properties in the SI system. + !!} + use :: Numerical_Constants_Astronomical, only : massSolar + implicit none + double precision , dimension(:) , allocatable :: unitsInSI + class (nodePropertyExtractorMassBlackHoles), intent(inout) :: self + !$GLC attributes unused :: self + + allocate(unitsInSI(1)) + unitsInSI(1)=massSolar + return + end function massBlackHolesUnitsInSI diff --git a/source/nodes.property_extractor.radiative_efficiency_black_holes.F90 b/source/nodes.property_extractor.radiative_efficiency_black_holes.F90 new file mode 100644 index 0000000000..d5dafe71af --- /dev/null +++ b/source/nodes.property_extractor.radiative_efficiency_black_holes.F90 @@ -0,0 +1,186 @@ +!! Copyright 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, +!! 2019, 2020, 2021, 2022, 2023 +!! Andrew Benson +!! +!! This file is part of Galacticus. +!! +!! Galacticus is free software: you can redistribute it and/or modify +!! it under the terms of the GNU General Public License as published by +!! the Free Software Foundation, either version 3 of the License, or +!! (at your option) any later version. +!! +!! Galacticus is distributed in the hope that it will be useful, +!! but WITHOUT ANY WARRANTY; without even the implied warranty of +!! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +!! GNU General Public License for more details. +!! +!! You should have received a copy of the GNU General Public License +!! along with Galacticus. If not, see . + + use :: Accretion_Disks , only : accretionDisksClass + use :: Black_Hole_Accretion_Rates, only : blackHoleAccretionRateClass + + !![ + + + A node property extractor which extracts a list of all super-massive black hole radiative efficiencies. + + + !!] + type, extends(nodePropertyExtractorList) :: nodePropertyExtractorRadiativeEfficiencyBlackHoles + !!{ + A property extractor which extracts a list of all super-massive black hole radiative efficiencies. + !!} + private + class(accretionDisksClass ), pointer :: accretionDisks_ => null() + class(blackHoleAccretionRateClass), pointer :: blackHoleAccretionRate_ => null() + contains + final :: radiativeEfficiencyBlackHolesDestructor + procedure :: elementCount => radiativeEfficiencyBlackHolesElementCount + procedure :: extract => radiativeEfficiencyBlackHolesExtract + procedure :: names => radiativeEfficiencyBlackHolesNames + procedure :: descriptions => radiativeEfficiencyBlackHolesDescriptions + procedure :: unitsInSI => radiativeEfficiencyBlackHolesUnitsInSI + end type nodePropertyExtractorRadiativeEfficiencyBlackHoles + + interface nodePropertyExtractorRadiativeEfficiencyBlackHoles + !!{ + Constructors for the ``radiativeEfficiencyBlackHoles'' output extractor class. + !!} + module procedure radiativeEfficiencyBlackHolesConstructorParameters + module procedure radiativeEfficiencyBlackHolesConstructorInternal + end interface nodePropertyExtractorRadiativeEfficiencyBlackHoles + +contains + + function radiativeEfficiencyBlackHolesConstructorParameters(parameters) result(self) + !!{ + Constructor for the ``radiativeEfficiencyBlackHoles'' property extractor class which takes a parameter set as input. + !!} + use :: Input_Parameters, only : inputParameter, inputParameters + implicit none + type (nodePropertyExtractorRadiativeEfficiencyBlackHoles) :: self + type (inputParameters ), intent(inout) :: parameters + class(accretionDisksClass ), pointer :: accretionDisks_ + class(blackHoleAccretionRateClass ), pointer :: blackHoleAccretionRate_ + + !![ + + + !!] + self=nodePropertyExtractorRadiativeEfficiencyBlackHoles(blackHoleAccretionRate_,accretionDisks_) + !![ + + + + !!] + return + end function radiativeEfficiencyBlackHolesConstructorParameters + + function radiativeEfficiencyBlackHolesConstructorInternal(blackHoleAccretionRate_,accretionDisks_) result(self) + !!{ + Internal constructor for the {\normalfont \ttfamily radiativeEfficiencyBlackHoles} node operator class. + !!} + use :: Galacticus_Nodes, only : defaultBasicComponent + implicit none + type (nodePropertyExtractorRadiativeEfficiencyBlackHoles) :: self + class(accretionDisksClass ), intent(in ), target :: accretionDisks_ + class(blackHoleAccretionRateClass ), intent(in ), target :: blackHoleAccretionRate_ + !![ + + !!] + + return + end function radiativeEfficiencyBlackHolesConstructorInternal + + subroutine radiativeEfficiencyBlackHolesDestructor(self) + !!{ + Destructor for the critical overdensity radiativeEfficiencyBlackHoles set barrier class. + !!} + implicit none + type(nodePropertyExtractorRadiativeEfficiencyBlackHoles), intent(inout) :: self + + !![ + + + !!] + return + end subroutine radiativeEfficiencyBlackHolesDestructor + + integer function radiativeEfficiencyBlackHolesElementCount(self) + !!{ + Return a count of the number of properties extracted. + !!} + implicit none + class(nodePropertyExtractorRadiativeEfficiencyBlackHoles), intent(inout) :: self + + radiativeEfficiencyBlackHolesElementCount=1 + return + end function radiativeEfficiencyBlackHolesElementCount + + function radiativeEfficiencyBlackHolesExtract(self,node,instance) result(radiativeEfficiency) + !!{ + Implement an output extractor for the radiative efficiencies of all supermassive black holes. + !!} + use :: Galacticus_Nodes, only : nodeComponentBlackHole + implicit none + double precision , dimension(:,:), allocatable :: radiativeEfficiency + class (nodePropertyExtractorRadiativeEfficiencyBlackHoles), intent(inout) :: self + type (treeNode ), intent(inout) :: node + type (multiCounter ), intent(inout) , optional :: instance + class (nodeComponentBlackHole ) , pointer :: blackHole + integer :: i , countBlackHoles + double precision :: rateMassAccretionSpheroid, rateMassAccretionHotHalo + !$GLC attributes unused :: instance + + countBlackHoles=node%blackHoleCount() + allocate(radiativeEfficiency(countBlackHoles,1)) + do i=1,countBlackHoles + blackHole => node %blackHole(instance=i) + call self%blackHoleAccretionRate_%rateAccretion(blackHole,rateMassAccretionSpheroid,rateMassAccretionHotHalo) + radiativeEfficiency(i,1) = self%accretionDisks_%efficiencyRadiative(blackHole,rateMassAccretionSpheroid+rateMassAccretionHotHalo) + end do + return + end function radiativeEfficiencyBlackHolesExtract + + subroutine radiativeEfficiencyBlackHolesNames(self,names) + !!{ + Return the names of the {\normalfont \ttfamily radiativeEfficiencyBlackHoles} properties. + !!} + implicit none + class(nodePropertyExtractorRadiativeEfficiencyBlackHoles), intent(inout) :: self + type (varying_string ), intent(inout), dimension(:) , allocatable :: names + !$GLC attributes unused :: self + + allocate(names(1)) + names(1)=var_str('radiativeEfficiencyBlackHoles') + return + end subroutine radiativeEfficiencyBlackHolesNames + + subroutine radiativeEfficiencyBlackHolesDescriptions(self,descriptions) + !!{ + Return the descriptions of the {\normalfont \ttfamily radiativeEfficiencyBlackHoles} properties. + !!} + implicit none + class(nodePropertyExtractorRadiativeEfficiencyBlackHoles), intent(inout) :: self + type (varying_string ), intent(inout), dimension(:) , allocatable :: descriptions + !$GLC attributes unused :: self + + allocate(descriptions(1)) + descriptions(1)=var_str('Radiative efficiencies of super-massive black holes in this galaxy.') + return + end subroutine radiativeEfficiencyBlackHolesDescriptions + + function radiativeEfficiencyBlackHolesUnitsInSI(self) result(unitsInSI) + !!{ + Return the units of the {\normalfont \ttfamily radiativeEfficiencyBlackHoles} properties in the SI system. + !!} + implicit none + double precision , dimension(:) , allocatable :: unitsInSI + class (nodePropertyExtractorRadiativeEfficiencyBlackHoles), intent(inout) :: self + !$GLC attributes unused :: self + + allocate(unitsInSI(1)) + unitsInSI(1)=1.0d0 + return + end function radiativeEfficiencyBlackHolesUnitsInSI diff --git a/source/nodes.property_extractor.radius_black_holes.F90 b/source/nodes.property_extractor.radius_black_holes.F90 new file mode 100644 index 0000000000..25ad970090 --- /dev/null +++ b/source/nodes.property_extractor.radius_black_holes.F90 @@ -0,0 +1,180 @@ +!! Copyright 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, +!! 2019, 2020, 2021, 2022, 2023 +!! Andrew Benson +!! +!! This file is part of Galacticus. +!! +!! Galacticus is free software: you can redistribute it and/or modify +!! it under the terms of the GNU General Public License as published by +!! the Free Software Foundation, either version 3 of the License, or +!! (at your option) any later version. +!! +!! Galacticus is distributed in the hope that it will be useful, +!! but WITHOUT ANY WARRANTY; without even the implied warranty of +!! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +!! GNU General Public License for more details. +!! +!! You should have received a copy of the GNU General Public License +!! along with Galacticus. If not, see . + + use :: Black_Hole_Binary_Separations, only : blackHoleBinarySeparationGrowthRateClass + + !![ + + + A node property extractor which extracts a list of all super-massive black hole radii and radial migration rates. + + + !!] + type, extends(nodePropertyExtractorList) :: nodePropertyExtractorRadiusBlackHoles + !!{ + A property extractor which extracts a list of all super-massive black hole radii and radial migration rates. + !!} + private + class(blackHoleBinarySeparationGrowthRateClass), pointer :: blackHoleBinarySeparationGrowthRate_ => null() + contains + procedure :: elementCount => radiusBlackHolesElementCount + procedure :: extract => radiusBlackHolesExtract + procedure :: names => radiusBlackHolesNames + procedure :: descriptions => radiusBlackHolesDescriptions + procedure :: unitsInSI => radiusBlackHolesUnitsInSI + end type nodePropertyExtractorRadiusBlackHoles + + interface nodePropertyExtractorRadiusBlackHoles + !!{ + Constructors for the ``radiusBlackHoles'' output extractor class. + !!} + module procedure radiusBlackHolesConstructorParameters + end interface nodePropertyExtractorRadiusBlackHoles + +contains + + function radiusBlackHolesConstructorParameters(parameters) result(self) + !!{ + Constructor for the ``radiusBlackHoles'' property extractor class which takes a parameter set as input. + !!} + use :: Input_Parameters, only : inputParameter, inputParameters + implicit none + type (nodePropertyExtractorRadiusBlackHoles ) :: self + type (inputParameters ), intent(inout) :: parameters + class(blackHoleBinarySeparationGrowthRateClass), pointer :: blackHoleBinarySeparationGrowthRate_ + + !![ + + !!] + self=nodePropertyExtractorRadiusBlackHoles(blackHoleBinarySeparationGrowthRate_) + !![ + + + !!] + return + end function radiusBlackHolesConstructorParameters + + function radiusBlackHolesConstructorInternal(blackHoleBinarySeparationGrowthRate_) result(self) + !!{ + Internal constructor for the {\normalfont \ttfamily radiusBlackHoles} node operator class. + !!} + use :: Galacticus_Nodes, only : defaultBasicComponent + implicit none + type (nodePropertyExtractorRadiusBlackHoles ) :: self + class(blackHoleBinarySeparationGrowthRateClass), intent(in ), target :: blackHoleBinarySeparationGrowthRate_ + !![ + + !!] + + return + end function radiusBlackHolesConstructorInternal + + subroutine radiusBlackHolesDestructor(self) + !!{ + Destructor for the critical overdensity radiusBlackHoles set barrier class. + !!} + implicit none + type(nodePropertyExtractorRadiusBlackHoles), intent(inout) :: self + + !![ + + !!] + return + end subroutine radiusBlackHolesDestructor + + integer function radiusBlackHolesElementCount(self) + !!{ + Return a count of the number of properties extracted. + !!} + implicit none + class(nodePropertyExtractorRadiusBlackHoles), intent(inout) :: self + + radiusBlackHolesElementCount=2 + return + end function radiusBlackHolesElementCount + + function radiusBlackHolesExtract(self,node,instance) result(radius) + !!{ + Implement an output extractor for the masses of all supermassive black holes. + !!} + use :: Galacticus_Nodes, only : nodeComponentBlackHole + implicit none + double precision , dimension(:,:), allocatable :: radius + class (nodePropertyExtractorRadiusBlackHoles), intent(inout) :: self + type (treeNode ), intent(inout) :: node + type (multiCounter ), intent(inout) , optional :: instance + class (nodeComponentBlackHole ) , pointer :: blackHole + integer :: i , countBlackHoles + !$GLC attributes unused :: instance + + countBlackHoles=node%blackHoleCount() + allocate(radius(countBlackHoles,2)) + do i=1,countBlackHoles + blackHole => node %blackHole (instance=i ) + radius (i,1) = blackHole%radialPosition ( ) + radius (i,2) = self %blackHoleBinarySeparationGrowthRate_%growthRate( blackHole) + end do + return + end function radiusBlackHolesExtract + + subroutine radiusBlackHolesNames(self,names) + !!{ + Return the names of the {\normalfont \ttfamily radiusBlackHoles} properties. + !!} + implicit none + class(nodePropertyExtractorRadiusBlackHoles), intent(inout) :: self + type (varying_string ), intent(inout), dimension(:) , allocatable :: names + !$GLC attributes unused :: self + + allocate(names(2)) + names(1)=var_str('radiusBlackHoles' ) + names(2)=var_str('radialMigrationRateBlackHoles') + return + end subroutine radiusBlackHolesNames + + subroutine radiusBlackHolesDescriptions(self,descriptions) + !!{ + Return the descriptions of the {\normalfont \ttfamily radiusBlackHoles} properties. + !!} + implicit none + class(nodePropertyExtractorRadiusBlackHoles), intent(inout) :: self + type (varying_string ), intent(inout), dimension(:) , allocatable :: descriptions + !$GLC attributes unused :: self + + allocate(descriptions(2)) + descriptions(1)=var_str('Radial positions of super-massive black holes in this galaxy.' ) + descriptions(2)=var_str('Radial migration rates of super-massive black holes in this galaxy.') + return + end subroutine radiusBlackHolesDescriptions + + function radiusBlackHolesUnitsInSI(self) result(unitsInSI) + !!{ + Return the units of the {\normalfont \ttfamily radiusBlackHoles} properties in the SI system. + !!} + use :: Numerical_Constants_Astronomical, only : megaParsec, gigaYear + implicit none + double precision , dimension(:) , allocatable :: unitsInSI + class (nodePropertyExtractorRadiusBlackHoles), intent(inout) :: self + !$GLC attributes unused :: self + + allocate(unitsInSI(2)) + unitsInSI(1)=megaParsec + unitsInSI(2)=megaParsec/gigaYear + return + end function radiusBlackHolesUnitsInSI diff --git a/source/nodes.property_extractor.spin_black_holes.F90 b/source/nodes.property_extractor.spin_black_holes.F90 new file mode 100644 index 0000000000..6c137b19dc --- /dev/null +++ b/source/nodes.property_extractor.spin_black_holes.F90 @@ -0,0 +1,139 @@ +!! Copyright 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, +!! 2019, 2020, 2021, 2022, 2023 +!! Andrew Benson +!! +!! This file is part of Galacticus. +!! +!! Galacticus is free software: you can redistribute it and/or modify +!! it under the terms of the GNU General Public License as published by +!! the Free Software Foundation, either version 3 of the License, or +!! (at your option) any later version. +!! +!! Galacticus is distributed in the hope that it will be useful, +!! but WITHOUT ANY WARRANTY; without even the implied warranty of +!! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +!! GNU General Public License for more details. +!! +!! You should have received a copy of the GNU General Public License +!! along with Galacticus. If not, see . + + !![ + + + A node property extractor which extracts a list of all super-massive black hole spins. + + + !!] + type, extends(nodePropertyExtractorList) :: nodePropertyExtractorSpinBlackHoles + !!{ + A property extractor which extracts a list of all super-massive black hole spins. + !!} + private + contains + procedure :: elementCount => spinBlackHolesElementCount + procedure :: extract => spinBlackHolesExtract + procedure :: names => spinBlackHolesNames + procedure :: descriptions => spinBlackHolesDescriptions + procedure :: unitsInSI => spinBlackHolesUnitsInSI + end type nodePropertyExtractorSpinBlackHoles + + interface nodePropertyExtractorSpinBlackHoles + !!{ + Constructors for the ``spinBlackHoles'' output extractor class. + !!} + module procedure spinBlackHolesConstructorParameters + end interface nodePropertyExtractorSpinBlackHoles + +contains + + function spinBlackHolesConstructorParameters(parameters) result(self) + !!{ + Constructor for the ``spinBlackHoles'' property extractor class which takes a parameter set as input. + !!} + use :: Input_Parameters, only : inputParameter, inputParameters + implicit none + type(nodePropertyExtractorSpinBlackHoles) :: self + type(inputParameters ), intent(inout) :: parameters + + self=nodePropertyExtractorSpinBlackHoles() + !![ + + !!] + return + end function spinBlackHolesConstructorParameters + + integer function spinBlackHolesElementCount(self) + !!{ + Return a count of the number of properties extracted. + !!} + implicit none + class(nodePropertyExtractorSpinBlackHoles), intent(inout) :: self + + spinBlackHolesElementCount=1 + return + end function spinBlackHolesElementCount + + function spinBlackHolesExtract(self,node,instance) result(spin) + !!{ + Implement an output extractor for the spins of all supermassive black holes. + !!} + use :: Galacticus_Nodes, only : nodeComponentBlackHole + implicit none + double precision , dimension(:,:), allocatable :: spin + class (nodePropertyExtractorSpinBlackHoles), intent(inout) :: self + type (treeNode ), intent(inout) :: node + type (multiCounter ), intent(inout) , optional :: instance + class (nodeComponentBlackHole ) , pointer :: blackHole + integer :: i , countBlackHoles + !$GLC attributes unused :: instance + + countBlackHoles=node%blackHoleCount() + allocate(spin(countBlackHoles,1)) + do i=1,countBlackHoles + blackHole => node %blackHole(instance=i) + spin (i,1) = blackHole%spin ( ) + end do + return + end function spinBlackHolesExtract + + subroutine spinBlackHolesNames(self,names) + !!{ + Return the names of the {\normalfont \ttfamily spinBlackHoles} properties. + !!} + implicit none + class(nodePropertyExtractorSpinBlackHoles), intent(inout) :: self + type (varying_string ), intent(inout), dimension(:) , allocatable :: names + !$GLC attributes unused :: self + + allocate(names(1)) + names(1)=var_str('spinBlackHoles') + return + end subroutine spinBlackHolesNames + + subroutine spinBlackHolesDescriptions(self,descriptions) + !!{ + Return the descriptions of the {\normalfont \ttfamily spinBlackHoles} properties. + !!} + implicit none + class(nodePropertyExtractorSpinBlackHoles), intent(inout) :: self + type (varying_string ), intent(inout), dimension(:) , allocatable :: descriptions + !$GLC attributes unused :: self + + allocate(descriptions(1)) + descriptions(1)=var_str('Spins of super-massive black holes in this galaxy.') + return + end subroutine spinBlackHolesDescriptions + + function spinBlackHolesUnitsInSI(self) result(unitsInSI) + !!{ + Return the units of the {\normalfont \ttfamily spinBlackHoles} properties in the SI system. + !!} + implicit none + double precision , dimension(:) , allocatable :: unitsInSI + class (nodePropertyExtractorSpinBlackHoles), intent(inout) :: self + !$GLC attributes unused :: self + + allocate(unitsInSI(1)) + unitsInSI(1)=1.0d0 + return + end function spinBlackHolesUnitsInSI From 29559a8807a47275714c20c0806169dbd1656528 Mon Sep 17 00:00:00 2001 From: Andrew Benson Date: Fri, 17 Nov 2023 10:08:11 -0800 Subject: [PATCH 3/4] feat: Remove output of black hole properties, and hard-coded accretion rate physics from the `blackHole` components These is now implemented by `nodePropertyExtractors` and the new `blackHoleAccretionRate` class. --- ...cts.nodes.components.black_hole.simple.F90 | 218 ++------ ...s.nodes.components.black_hole.standard.F90 | 473 +----------------- testSuite/parameters/bolshoiTestTreesGLC.xml | 9 +- testSuite/test-methods.xml | 9 + 4 files changed, 67 insertions(+), 642 deletions(-) diff --git a/source/objects.nodes.components.black_hole.simple.F90 b/source/objects.nodes.components.black_hole.simple.F90 index 99b28df105..e24b532a09 100644 --- a/source/objects.nodes.components.black_hole.simple.F90 +++ b/source/objects.nodes.components.black_hole.simple.F90 @@ -26,16 +26,15 @@ module Node_Component_Black_Hole_Simple Implements the simple black hole node component. !!} use :: Black_Hole_Binary_Mergers , only : blackHoleBinaryMergerClass + use :: Black_Hole_Accretion_Rates , only : blackHoleAccretionRateClass use :: Cooling_Radii , only : coolingRadiusClass use :: Dark_Matter_Halo_Scales , only : darkMatterHaloScaleClass - use :: Star_Formation_Rates_Spheroids, only : starFormationRateSpheroidsClass implicit none private public :: Node_Component_Black_Hole_Simple_Initialize , Node_Component_Black_Hole_Simple_Scale_Set , & - & Node_Component_Black_Hole_Simple_Thread_Uninitialize, Node_Component_Black_Hole_Simple_Output_Names , & - & Node_Component_Black_Hole_Simple_Output_Count , Node_Component_Black_Hole_Simple_Output , & - & Node_Component_Black_Hole_Simple_Rate_Compute , Node_Component_Black_Hole_Simple_Thread_Initialize, & - & Node_Component_Black_Hole_Simple_State_Store , Node_Component_Black_Hole_Simple_State_Restore + & Node_Component_Black_Hole_Simple_Thread_Uninitialize, Node_Component_Black_Hole_Simple_Thread_Initialize, & + & Node_Component_Black_Hole_Simple_State_Store , Node_Component_Black_Hole_Simple_State_Restore , & + & Node_Component_Black_Hole_Simple_Rate_Compute !![ @@ -71,20 +70,16 @@ module Node_Component_Black_Hole_Simple class(darkMatterHaloScaleClass ), pointer :: darkMatterHaloScale_ class(coolingRadiusClass ), pointer :: coolingRadius_ class(blackHoleBinaryMergerClass ), pointer :: blackHoleBinaryMerger_ - class(starFormationRateSpheroidsClass), pointer :: starFormationRateSpheroids_ - !$omp threadprivate(darkMatterHaloScale_,coolingRadius_,blackHoleBinaryMerger_,starFormationRateSpheroids_) + class(blackHoleAccretionRateClass ), pointer :: blackHoleAccretionRate_ + !$omp threadprivate(darkMatterHaloScale_,blackHoleAccretionRate_,coolingRadius_,blackHoleBinaryMerger_) ! Seed mass for black holes. double precision :: massSeed ! Feedback parameters. - double precision :: efficiencyHeating , efficiencyWind , & - & growthRatioToStellarSpheroid + double precision :: efficiencyHeating, efficiencyWind logical :: heatsHotHalo - ! Output options. - logical :: outputAccretion - ! A threadprivate object used to track to which thread events are attached. integer :: thread !$omp threadprivate(thread) @@ -120,15 +115,6 @@ subroutine Node_Component_Black_Hole_Simple_Initialize(parameters) The mass of the seed black hole placed at the center of each newly formed galaxy. !!] - ! Get accretion rate enhancement factors. - !![ - - growthRatioToStellarSpheroid - 1.0d-3 - The ratio of the rates of black hole growth and spheroid stellar mass growth. - subParameters - - !!] ! Options controlling AGN feedback. !![ @@ -159,15 +145,6 @@ subroutine Node_Component_Black_Hole_Simple_Initialize(parameters) subParameters !!] - ! Get options controlling output. - !![ - - outputAccretion - .false. - Determines whether or not accretion rates and jet powers will be output. - subParameters - - !!] return end subroutine Node_Component_Black_Hole_Simple_Initialize @@ -192,10 +169,10 @@ subroutine Node_Component_Black_Hole_Simple_Thread_Initialize(parameters) ! Find our parameters. subParameters=parameters%subParameters('componentBlackHole') !![ - - - - + + + + !!] dependencies(1)=dependencyRegEx(dependencyDirectionAfter,'^remnantStructure:') call satelliteMergerEvent%attach(thread,satelliteMerger,openMPThreadBindingAtLevel,label='nodeComponentBlackHoleSimple',dependencies=dependencies) @@ -218,10 +195,10 @@ subroutine Node_Component_Black_Hole_Simple_Thread_Uninitialize() if (defaultBlackHoleComponent%simpleIsActive()) then !![ - - - - + + + + !!] if (satelliteMergerEvent%isAttached(thread,satelliteMerger)) call satelliteMergerEvent%detach(thread,satelliteMerger) end if @@ -243,7 +220,7 @@ subroutine Node_Component_Black_Hole_Simple_Scale_Set(node) type (treeNode ), intent(inout), pointer :: node class (nodeComponentBlackHole) , pointer :: blackHole class (nodeComponentSpheroid ) , pointer :: spheroid - double precision , parameter :: massScaleAbsolute=1.0d+0 + double precision , parameter :: massScaleAbsolute=1.0d+0, massScaleRelative=1.0d-3 ! Check if we are the default method. if (.not.defaultBlackHoleComponent%simpleIsActive()) return @@ -255,17 +232,17 @@ subroutine Node_Component_Black_Hole_Simple_Scale_Set(node) ! Get the spheroid component. spheroid => node%spheroid() ! Set scale for mass. - call blackHole%massScale( & - & max( & - & blackHole%massSeed (), & - & max( & - & growthRatioToStellarSpheroid*spheroid %massStellar (), & - & max( & - & massScaleAbsolute , & - & blackHole%mass () & - & ) & - & ) & - & ) & + call blackHole%massScale( & + & max( & + & blackHole%massSeed (), & + & max( & + & massScaleRelative*spheroid %massStellar (), & + & max( & + & massScaleAbsolute , & + & blackHole%mass () & + & ) & + & ) & + & ) & & ) end select return @@ -297,17 +274,20 @@ subroutine Node_Component_Black_Hole_Simple_Rate_Compute(node,interrupt,interrup double precision :: coolingRadiusFractional , couplingEfficiency , & & energyInputRate , heatingRate , & & massAccretionRate , restMassAccretionRate, & + & accretionRateSpheroid , accretionRateHotHalo , & & x ! Return immediately if inactive variables are requested. if (propertyInactive(propertyType)) return if (defaultBlackHoleComponent%simpleIsActive()) then - ! Get the spheroid component. - spheroid => node%spheroid() + ! Get the black hole component. + blackHole => node%blackHole() ! Find the rate of rest mass accretion onto the black hole. - restMassAccretionRate=growthRatioToStellarSpheroid*starFormationRateSpheroids_%rate(node) + call blackHoleAccretionRate_%rateAccretion(blackHole,accretionRateSpheroid,accretionRateHotHalo) + restMassAccretionRate=+accretionRateSpheroid & + & +accretionRateHotHalo ! Finish if there is no accretion. if (restMassAccretionRate <= 0.0d0) return @@ -315,9 +295,6 @@ subroutine Node_Component_Black_Hole_Simple_Rate_Compute(node,interrupt,interrup ! Find the rate of increase in mass of the black hole. massAccretionRate=restMassAccretionRate*max((1.0d0-efficiencyHeating-efficiencyWind),0.0d0) - ! Get the black hole component. - blackHole => node%blackHole() - ! Detect black hole component type. select type (blackHole) type is (nodeComponentBlackHole) @@ -328,7 +305,9 @@ subroutine Node_Component_Black_Hole_Simple_Rate_Compute(node,interrupt,interrup end if return class is (nodeComponentBlackHoleSimple) - ! Simple type - continue processing. + ! Get the spheroid component. + spheroid => node%spheroid() + ! Add accretion to the black hole. call blackHole%massRate ( massAccretionRate) ! Remove the accreted mass from the spheroid component. call spheroid %massGasSinkRate(-restMassAccretionRate) @@ -411,127 +390,6 @@ subroutine Node_Component_Black_Hole_Simple_Create(node) return end subroutine Node_Component_Black_Hole_Simple_Create - !![ - - Node_Component_Black_Hole_Simple_Output_Names - Node_Component_Black_Hole_Simple_Output - - !!] - subroutine Node_Component_Black_Hole_Simple_Output_Names(node,integerProperty,integerProperties,doubleProperty,doubleProperties,time) - !!{ - Set names of black hole properties to be written to the \glc\ output file. - !!} - use :: Galacticus_Nodes , only : treeNode - use :: Numerical_Constants_Astronomical , only : gigaYear , massSolar - use :: Merger_Tree_Outputter_Buffer_Types, only : outputPropertyInteger, outputPropertyDouble - implicit none - type (treeNode) , intent(inout) :: node - double precision , intent(in ) :: time - integer , intent(inout) :: doubleProperty , integerProperty - type (outputPropertyInteger), dimension(:), intent(inout) :: integerProperties - type (outputPropertyDouble ), dimension(:), intent(inout) :: doubleProperties - !$GLC attributes unused :: time, integerProperty, integerProperties - - ! Ensure that the black hole component is of the simple class. - if (Node_Component_Black_Hole_Simple_Matches(node)) then - if (outputAccretion) then - doubleProperty=doubleProperty+1 - doubleProperties(doubleProperty)%name ='blackHoleAccretionRate' - doubleProperties(doubleProperty)%comment ='Rest-mass accretion rate onto the black hole.' - doubleProperties(doubleProperty)%unitsInSI=massSolar/gigaYear - end if - end if - return - end subroutine Node_Component_Black_Hole_Simple_Output_Names - - !![ - - Node_Component_Black_Hole_Simple_Output_Count - Node_Component_Black_Hole_Simple_Output - - !!] - subroutine Node_Component_Black_Hole_Simple_Output_Count(node,integerPropertyCount,doublePropertyCount,time) - !!{ - Account for the number of black hole properties to be written to the the \glc\ output file. - !!} - use :: Galacticus_Nodes, only : treeNode - implicit none - type (treeNode), intent(inout) :: node - double precision , intent(in ) :: time - integer , intent(inout) :: doublePropertyCount , integerPropertyCount - integer , parameter :: extraPropertyCount =1 - !$GLC attributes unused :: time, integerPropertyCount - - ! Ensure that the black hole component is of the simple class. - if (Node_Component_Black_Hole_Simple_Matches(node)) then - if (outputAccretion) doublePropertyCount=doublePropertyCount+extraPropertyCount - end if - return - end subroutine Node_Component_Black_Hole_Simple_Output_Count - - !![ - - Node_Component_Black_Hole_Simple_Output - Node_Component_Black_Hole_Simple_Output - - !!] - subroutine Node_Component_Black_Hole_Simple_Output(node,integerProperty,integerBufferCount,integerProperties,doubleProperty,doubleBufferCount,doubleProperties,time,instance) - !!{ - Store black hole properties in the \glc\ output file buffers. - !!} - use :: Galacticus_Nodes , only : nodeComponentBlackHole, nodeComponentSpheroid, treeNode - use :: Kind_Numbers , only : kind_int8 - use :: Multi_Counters , only : multiCounter - use :: Merger_Tree_Outputter_Buffer_Types, only : outputPropertyInteger , outputPropertyDouble - implicit none - double precision , intent(in ) :: time - type (treeNode ), intent(inout) :: node - integer , intent(inout) :: doubleBufferCount , doubleProperty , & - & integerBufferCount , integerProperty - type (outputPropertyInteger ), intent(inout), dimension(:) :: integerProperties - type (outputPropertyDouble ), intent(inout), dimension(:) :: doubleProperties - type (multiCounter ), intent(inout) :: instance - class (nodeComponentBlackHole) , pointer :: blackHole - double precision :: restMassAccretionRate - !$GLC attributes unused :: time, integerProperty, integerBufferCount, integerProperties, instance - - ! Ensure that the black hole component is of the simple class. - if (Node_Component_Black_Hole_Simple_Matches(node)) then - ! Get the black hole component. - blackHole => node%blackHole() - ! Store the properties. - if (outputAccretion) then - ! Get the rest mass accretion rate. - restMassAccretionRate=growthRatioToStellarSpheroid*starFormationRateSpheroids_%rate(node) - doubleProperty=doubleProperty+1 - doubleProperties(doubleProperty)%scalar(doubleBufferCount)=restMassAccretionRate - end if - end if - return - end subroutine Node_Component_Black_Hole_Simple_Output - - logical function Node_Component_Black_Hole_Simple_Matches(node) - !!{ - Return true if the black hole component of {\normalfont \ttfamily node} is a match to the simple implementation. - !!} - use :: Galacticus_Nodes, only : defaultBlackHoleComponent, nodeComponentBlackHole, nodeComponentBlackHoleSimple, treeNode - implicit none - type (treeNode ), intent(inout) :: node - class(nodeComponentBlackHole), pointer :: blackHole - - ! Get the black hole component. - blackHole => node%blackHole() - ! Ensure that it is of the simple class. - Node_Component_Black_Hole_Simple_Matches=.false. - select type (blackHole) - class is (nodeComponentBlackHoleSimple) - Node_Component_Black_Hole_Simple_Matches=.true. - type is (nodeComponentBlackHole ) - Node_Component_Black_Hole_Simple_Matches=defaultBlackHoleComponent%simpleIsActive() - end select - return - end function Node_Component_Black_Hole_Simple_Matches - double precision function Node_Component_Black_Hole_Simple_Seed_Mass(self) !!{ Return the seed mass for simple black holes. @@ -563,7 +421,7 @@ subroutine Node_Component_Black_Hole_Simple_State_Store(stateFile,gslStateFile,s call displayMessage('Storing state for: componentBlackHole -> simple',verbosity=verbosityLevelInfo) !![ - + !!] return end subroutine Node_Component_Black_Hole_Simple_State_Store @@ -586,7 +444,7 @@ subroutine Node_Component_Black_Hole_Simple_State_Restore(stateFile,gslStateFile call displayMessage('Retrieving state for: componentBlackHole -> simple',verbosity=verbosityLevelInfo) !![ - + !!] return end subroutine Node_Component_Black_Hole_Simple_State_Restore diff --git a/source/objects.nodes.components.black_hole.standard.F90 b/source/objects.nodes.components.black_hole.standard.F90 index 73dbd66cd7..27b0953960 100644 --- a/source/objects.nodes.components.black_hole.standard.F90 +++ b/source/objects.nodes.components.black_hole.standard.F90 @@ -30,18 +30,15 @@ module Node_Component_Black_Hole_Standard use :: Black_Hole_Binary_Mergers , only : blackHoleBinaryMergerClass use :: Black_Hole_Binary_Recoil_Velocities , only : blackHoleBinaryRecoilClass use :: Black_Hole_Binary_Separations , only : blackHoleBinarySeparationGrowthRateClass - use :: Cooling_Radii , only : coolingRadiusClass + use :: Black_Hole_Accretion_Rates , only : blackHoleAccretionRateClass use :: Cosmology_Parameters , only : cosmologyParametersClass use :: Dark_Matter_Halo_Scales , only : darkMatterHaloScaleClass - use :: Hot_Halo_Temperature_Profiles , only : hotHaloTemperatureProfileClass use :: Galactic_Structure , only : galacticStructureClass implicit none private - public :: Node_Component_Black_Hole_Standard_Rate_Compute , Node_Component_Black_Hole_Standard_Scale_Set , & - & Node_Component_Black_Hole_Standard_Thread_Uninitialize, Node_Component_Black_Hole_Standard_Output_Properties, & - & Node_Component_Black_Hole_Standard_Output_Names , Node_Component_Black_Hole_Standard_Output_Count , & - & Node_Component_Black_Hole_Standard_Output , Node_Component_Black_Hole_Standard_Initialize , & - & Node_Component_Black_Hole_Standard_Post_Evolve , Node_Component_Black_Hole_Standard_Thread_Initialize, & + public :: Node_Component_Black_Hole_Standard_Rate_Compute , Node_Component_Black_Hole_Standard_Scale_Set , & + & Node_Component_Black_Hole_Standard_Thread_Uninitialize, Node_Component_Black_Hole_Standard_Post_Evolve , & + & Node_Component_Black_Hole_Standard_Thread_Initialize , Node_Component_Black_Hole_Standard_Initialize , & & Node_Component_Black_Hole_Standard_State_Store , Node_Component_Black_Hole_Standard_State_Restore !![ @@ -116,17 +113,15 @@ module Node_Component_Black_Hole_Standard !!] ! Objects used by this component. - class(cosmologyParametersClass ), pointer :: cosmologyParameters_ class(accretionDisksClass ), pointer :: accretionDisks_ class(blackHoleBinaryRecoilClass ), pointer :: blackHoleBinaryRecoil_ + class(blackHoleAccretionRateClass ), pointer :: blackHoleAccretionRate_ class(blackHoleBinaryInitialSeparationClass ), pointer :: blackHoleBinaryInitialSeparation_ class(blackHoleBinaryMergerClass ), pointer :: blackHoleBinaryMerger_ class(blackHoleBinarySeparationGrowthRateClass), pointer :: blackHoleBinarySeparationGrowthRate_ - class(coolingRadiusClass ), pointer :: coolingRadius_ - class(hotHaloTemperatureProfileClass ), pointer :: hotHaloTemperatureProfile_ class(darkMatterHaloScaleClass ), pointer :: darkMatterHaloScale_ class(galacticStructureClass ), pointer :: galacticStructure_ - !$omp threadprivate(accretionDisks_,cosmologyParameters_,blackHoleBinaryRecoil_,blackHoleBinaryInitialSeparation_,blackHoleBinaryMerger_,blackHoleBinarySeparationGrowthRate_,coolingRadius_,hotHaloTemperatureProfile_,darkMatterHaloScale_,galacticStructure_) + !$omp threadprivate(accretionDisks_,blackHoleAccretionRate_,blackHoleBinaryRecoil_,blackHoleBinaryInitialSeparation_,blackHoleBinaryMerger_,blackHoleBinarySeparationGrowthRate_,darkMatterHaloScale_,galacticStructure_) ! Accretion model parameters. ! Enhancement factors for the accretion rate. @@ -144,8 +139,6 @@ module Node_Component_Black_Hole_Standard logical :: heatsHotHalo , efficiencyWindScalesWithEfficiencyRadiative ! Output options. - logical :: outputAccretion - logical :: outputData logical :: outputMergers ! Record of whether cold mode is explicitly tracked. @@ -251,25 +244,6 @@ subroutine Node_Component_Black_Hole_Standard_Initialize(parameters) !!] ! Get options controlling output. - !![ - - outputAccretion - .false. - Determines whether or not accretion rates and jet powers will be output. - subParameters - - !!] - - ! Get options controlling output. - !![ - - outputData - .false. - Determines whether or not properties for all black holes (rather than just the central black hole) will be output. - subParameters - - !!] - !![ outputMergers @@ -310,14 +284,12 @@ subroutine Node_Component_Black_Hole_Standard_Thread_Initialize(parameters) ! Find our parameters. subParameters=parameters%subParameters('componentBlackHole') !![ - + - - !!] @@ -341,14 +313,12 @@ subroutine Node_Component_Black_Hole_Standard_Thread_Uninitialize() if (defaultBlackHoleComponent%standardIsActive()) then if (satelliteMergerEvent%isAttached(thread,satelliteMerger)) call satelliteMergerEvent%detach(thread,satelliteMerger) !![ - + - - !!] @@ -410,7 +380,7 @@ subroutine Node_Component_Black_Hole_Standard_Rate_Compute(node,interrupt,interr ! Get the black hole. blackHole => node%blackHole(instance=iInstance) ! Find the rate of rest mass accretion onto the black hole. - call Node_Component_Black_Hole_Standard_Mass_Accretion_Rate(blackHole,accretionRateSpheroid,accretionRateHotHalo) + call blackHoleAccretionRate_%rateAccretion(blackHole,accretionRateSpheroid,accretionRateHotHalo) restMassAccretionRate=accretionRateSpheroid+accretionRateHotHalo ! Finish if there is no accretion. if (restMassAccretionRate <= 0.0d0) cycle @@ -666,154 +636,6 @@ logical function Node_Component_Black_Hole_Standard_Recoil_Escapes(node,velocity return end function Node_Component_Black_Hole_Standard_Recoil_Escapes - subroutine Node_Component_Black_Hole_Standard_Mass_Accretion_Rate(blackHole,accretionRateSpheroid,accretionRateHotHalo) - !!{ - Returns the rate of mass accretion onto the black hole in {\normalfont \ttfamily node}. - !!} - use :: Black_Hole_Fundamentals , only : Black_Hole_Eddington_Accretion_Rate - use :: Bondi_Hoyle_Lyttleton_Accretion , only : Bondi_Hoyle_Lyttleton_Accretion_Radius, Bondi_Hoyle_Lyttleton_Accretion_Rate - use :: Galactic_Structure_Options , only : componentTypeColdHalo , componentTypeHotHalo , componentTypeSpheroid, coordinateSystemCylindrical, & - & massTypeGaseous - use :: Galacticus_Nodes , only : nodeComponentBlackHole , nodeComponentHotHalo , nodeComponentSpheroid, treeNode - use :: Ideal_Gases_Thermodynamics , only : Ideal_Gas_Jeans_Length , Ideal_Gas_Sound_Speed - use :: Numerical_Constants_Astronomical, only : Mpc_per_km_per_s_To_Gyr , gigaYear , megaParsec - use :: Numerical_Constants_Prefixes , only : kilo - implicit none - class (nodeComponentBlackHole), intent(inout) :: blackHole - double precision , intent( out) :: accretionRateHotHalo , accretionRateSpheroid - type (treeNode ) , pointer :: node - class (nodeComponentSpheroid ) , pointer :: spheroid - class (nodeComponentHotHalo ) , pointer :: hotHalo - double precision , parameter :: gasDensityMinimum =1.0d0 ! Lowest gas density to consider when computing accretion rates onto black hole (in units of M☉/Mpc³). - double precision :: accretionRadius , accretionRateMaximum , & - & massBlackHole , gasDensity , & - & hotHaloTemperature , hotModeFraction , & - & jeansLength , position (3), & - & radiativeEfficiency , relativeVelocity , & - & coldModeFraction - - ! Get the host node. - node => blackHole%host() - ! Get black hole mass. - massBlackHole=blackHole%mass() - ! Check black hole mass is positive. - if (massBlackHole > 0.0d0) then - ! Compute the relative velocity of black hole and gas. We assume that relative motion arises only from the radial - ! migration of the black hole. - relativeVelocity=blackHoleBinarySeparationGrowthRate_%growthRate(blackHole)*Mpc_per_km_per_s_To_Gyr - ! Contribution from spheroid: - ! Get the accretion radius. We take this to be the larger of the Bondi-Hoyle radius and the current radius position of - ! the black hole. - accretionRadius=max( & - & Bondi_Hoyle_Lyttleton_Accretion_Radius(massBlackHole,bondiHoyleAccretionTemperatureSpheroid) & - & ,blackHole%radialPosition() & - & ) - ! Set the position. - position=[accretionRadius,0.0d0,0.0d0] - ! Get density of gas at the galactic center. - gasDensity=galacticStructure_%density(node,position,coordinateSystem=coordinateSystemCylindrical,componentType=componentTypeSpheroid,massType =massTypeGaseous) - ! Check if we have a non-negligible gas density. - if (gasDensity > gasDensityMinimum) then - ! Get the spheroid component. - spheroid => node%spheroid() - ! Get the Jeans length scale. - jeansLength=Ideal_Gas_Jeans_Length(bondiHoyleAccretionTemperatureSpheroid,gasDensity) - ! Limit the smoothing scale to the scale of the spheroid. - jeansLength=min(jeansLength,spheroid%radius()) - ! If the Jeans length exceeds the Bondi-Hoyle-Lyttleton accretion radius, then recompute gas density for a larger - ! radius, as the gas should be smoothly distributed on scales below the Jeans length. - if (jeansLength > accretionRadius) then - ! Set the position. - position=[jeansLength,0.0d0,0.0d0] - ! Get density of gas at the galactic center. - gasDensity=galacticStructure_%density(node,position,coordinateSystem=coordinateSystemCylindrical,componentType=componentTypeSpheroid,massType =massTypeGaseous) - end if - ! Compute the accretion rate. - accretionRateSpheroid=max(bondiHoyleAccretionEnhancementSpheroid*Bondi_Hoyle_Lyttleton_Accretion_Rate(massBlackHole& - &,gasDensity ,relativeVelocity,bondiHoyleAccretionTemperatureSpheroid),0.0d0) - ! Get the radiative efficiency of the accretion. - radiativeEfficiency=accretionDisks_%efficiencyRadiative(blackHole,accretionRateSpheroid) - ! Limit the accretion rate to the Eddington limit. - if (radiativeEfficiency > 0.0d0) accretionRateSpheroid=min(accretionRateSpheroid& - &,Black_Hole_Eddington_Accretion_Rate(blackHole) /radiativeEfficiency) - else - ! Gas density is negative - set zero accretion rate. - accretionRateSpheroid=0.0d0 - end if - ! Contribution from hot halo: - ! Get the hot halo component. - hotHalo => node%hotHalo() - ! Get halo gas temperature. - hotHaloTemperature=hotHaloTemperatureProfile_%temperature(node,radius=0.0d0) - ! Get the accretion radius. - accretionRadius=Bondi_Hoyle_Lyttleton_Accretion_Radius(massBlackHole,hotHaloTemperature) - accretionRadius=min(accretionRadius,hotHalo%outerRadius()) - ! Set the position. - position=[accretionRadius,0.0d0,0.0d0] - ! Find the fraction of gas in the halo which is in the hot mode. Set this to unity if hot/cold mode is not to be - ! considered. - select case (bondiHoyleAccretionHotModeOnly) - case (.true.) - if (coldModeTracked) then - hotModeFraction=1.0d0 - else - hotModeFraction=Hot_Mode_Fraction(node) - end if - coldModeFraction=0.0d0 - case (.false.) - hotModeFraction=1.0d0 - if (coldModeTracked) then - coldModeFraction=1.0d0 - else - coldModeFraction=0.0d0 - end if - end select - ! Get density of gas at the galactic center - scaled by the fraction in the hot accretion mode. - gasDensity= & - & hotModeFraction & - & *galacticStructure_%density( & - & node , & - & position , & - & coordinateSystem=coordinateSystemCylindrical , & - & componentType =componentTypeHotHalo , & - & massType =massTypeGaseous & - & ) - if (coldModeTracked.and.coldModeFraction > 0.0d0) & - & gasDensity= & - & gasDensity & - & +coldModeFraction & - & *galacticStructure_%density( & - & node , & - & position , & - & coordinateSystem=coordinateSystemCylindrical, & - & componentType =componentTypeColdHalo , & - & massType =massTypeGaseous & - & ) - ! Check if we have a non-zero gas density. - if (gasDensity > gasDensityMinimum) then - ! Compute the accretion rate. - accretionRateHotHalo=max(bondiHoyleAccretionEnhancementHotHalo*Bondi_Hoyle_Lyttleton_Accretion_Rate(massBlackHole& - &,gasDensity,relativeVelocity,hotHaloTemperature,accretionRadius),0.0d0) - ! Limit the accretion rate to the total mass of the hot halo, divided by the sound crossing time. - accretionRateMaximum=max(hotHalo%mass()/(hotHalo%outerRadius()/(kilo*gigaYear/megaParsec)& - &/Ideal_Gas_Sound_Speed(hotHaloTemperature)),0.0d0) - accretionRateHotHalo=min(accretionRateHotHalo,accretionRateMaximum) - ! Get the radiative efficiency of the accretion. - radiativeEfficiency=accretionDisks_%efficiencyRadiative(blackHole,accretionRateHotHalo) - ! Limit the accretion rate to the Eddington limit. - if (radiativeEfficiency > 0.0d0) accretionRateHotHalo=min(accretionRateHotHalo& - &,Black_Hole_Eddington_Accretion_Rate(blackHole)/radiativeEfficiency) - else - ! No gas density, so zero accretion rate. - accretionRateHotHalo=0.0d0 - end if - else - accretionRateSpheroid=0.0d0 - accretionRateHotHalo =0.0d0 - end if - return - end subroutine Node_Component_Black_Hole_Standard_Mass_Accretion_Rate - subroutine Node_Component_Black_Hole_Standard_Create(node) !!{ Creates a black hole component for {\normalfont \ttfamily node}. @@ -832,147 +654,6 @@ subroutine Node_Component_Black_Hole_Standard_Create(node) return end subroutine Node_Component_Black_Hole_Standard_Create - !![ - - Node_Component_Black_Hole_Standard_Output_Names - Node_Component_Black_Hole_Standard_Output - - !!] - subroutine Node_Component_Black_Hole_Standard_Output_Names(node,integerProperty,integerProperties,doubleProperty,doubleProperties,time) - !!{ - Set names of black hole properties to be written to the \glc\ output file. - !!} - use :: Galacticus_Nodes , only : treeNode - use :: Numerical_Constants_Astronomical , only : gigaYear , massSolar - use :: Numerical_Constants_Prefixes , only : kilo - use :: Merger_Tree_Outputter_Buffer_Types, only : outputPropertyInteger, outputPropertyDouble - implicit none - type (treeNode ) , intent(inout) :: node - double precision , intent(in ) :: time - integer , intent(inout) :: doubleProperty , integerProperty - type (outputPropertyInteger), dimension(:), intent(inout) :: integerProperties - type (outputPropertyDouble ), dimension(:), intent(inout) :: doubleProperties - !$GLC attributes unused :: time - - if (Node_Component_Black_Hole_Standard_Matches(node)) then - integerProperty=integerProperty+1 - integerProperties(integerProperty)%name ='blackHoleCount' - integerProperties(integerProperty)%comment ='Number of super-massive black holes in the galaxy.' - integerProperties(integerProperty)%unitsInSI=0.0d0 - if (outputAccretion) then - doubleProperty=doubleProperty+1 - doubleProperties(doubleProperty)%name ='blackHoleAccretionRate' - doubleProperties(doubleProperty)%comment ='Rest-mass accretion rate onto the black hole.' - doubleProperties(doubleProperty)%unitsInSI=massSolar/gigaYear - doubleProperty=doubleProperty+1 - doubleProperties(doubleProperty)%name ='blackHoleJetPower' - doubleProperties(doubleProperty)%comment ='Power of the black hole-driven jet.' - doubleProperties(doubleProperty)%unitsInSI=massSolar*kilo**2/gigaYear - doubleProperty=doubleProperty+1 - doubleProperties(doubleProperty)%name ='blackHoleRadiativeEfficiency' - doubleProperties(doubleProperty)%comment ='The radiative efficiency of the black hole accretion system.' - doubleProperties(doubleProperty)%unitsInSI=0.0d0 - end if - end if - return - end subroutine Node_Component_Black_Hole_Standard_Output_Names - - !![ - - Node_Component_Black_Hole_Standard_Output_Count - Node_Component_Black_Hole_Standard_Output - - !!] - subroutine Node_Component_Black_Hole_Standard_Output_Count(node,integerPropertyCount,doublePropertyCount,time) - !!{ - Account for the number of black hole properties to be written to the the \glc\ output file. - !!} - use :: Galacticus_Nodes, only : treeNode - implicit none - type (treeNode), intent(inout) :: node - double precision , intent(in ) :: time - integer , intent(inout) :: doublePropertyCount , integerPropertyCount - integer , parameter :: extraPropertyCount =3 - !$GLC attributes unused :: time - - if (Node_Component_Black_Hole_Standard_Matches(node)) then - integerPropertyCount=integerPropertyCount+1 - if (outputAccretion) doublePropertyCount=doublePropertyCount+extraPropertyCount - end if - return - end subroutine Node_Component_Black_Hole_Standard_Output_Count - - !![ - - Node_Component_Black_Hole_Standard_Output - Node_Component_Black_Hole_Standard_Output - - !!] - subroutine Node_Component_Black_Hole_Standard_Output(node,integerProperty,integerBufferCount,integerProperties,doubleProperty,doubleBufferCount,doubleProperties,time,instance) - !!{ - Store black hole properties in the \glc\ output file buffers. - !!} - use :: Galacticus_Nodes , only : nodeComponentBlackHole, treeNode - use :: Kind_Numbers , only : kind_int8 - use :: Multi_Counters , only : multiCounter - use :: Merger_Tree_Outputter_Buffer_Types, only : outputPropertyInteger , outputPropertyDouble - implicit none - double precision , intent(in ) :: time - type (treeNode ), intent(inout) :: node - integer , intent(inout) :: doubleBufferCount , doubleProperty , & - & integerBufferCount , integerProperty - type (outputPropertyInteger ), intent(inout), dimension(:) :: integerProperties - type (outputPropertyDouble ), intent(inout), dimension(:) :: doubleProperties - type (multiCounter ), intent(inout) :: instance - class (nodeComponentBlackHole) , pointer :: blackHole - double precision :: accretionRateHotHalo , accretionRateSpheroid, & - & restMassAccretionRate - !$GLC attributes unused :: time, instance - - if (Node_Component_Black_Hole_Standard_Matches(node)) then - ! Store the properties. - if (outputAccretion) then - ! Get the black hole component. - blackHole => node%blackHole(instance=1) - ! Get the rest mass accretion rate. - call Node_Component_Black_Hole_Standard_Mass_Accretion_Rate(blackHole,accretionRateSpheroid,accretionRateHotHalo) - restMassAccretionRate=accretionRateSpheroid+accretionRateHotHalo - doubleProperty=doubleProperty+1 - doubleProperties(doubleProperty)%scalar(doubleBufferCount)=restMassAccretionRate - doubleProperty=doubleProperty+1 - doubleProperties(doubleProperty)%scalar(doubleBufferCount)=accretionDisks_%powerJet (blackHole,restMassAccretionRate) - doubleProperty=doubleProperty+1 - doubleProperties(doubleProperty)%scalar(doubleBufferCount)=accretionDisks_%efficiencyRadiative(blackHole,restMassAccretionRate) - end if - ! Count number of black holes associated with this galaxy. - integerProperty=integerProperty+1 - integerProperties(integerProperty)%scalar(integerBufferCount)=node%blackHoleCount() - end if - return - end subroutine Node_Component_Black_Hole_Standard_Output - - logical function Node_Component_Black_Hole_Standard_Matches(node) - !!{ - Return true if the black hole component of {\normalfont \ttfamily node} is a match to the standard implementation. - !!} - use :: Galacticus_Nodes, only : defaultBlackHoleComponent, nodeComponentBlackHole, nodeComponentBlackHoleStandard, treeNode - implicit none - type (treeNode ), intent(inout) :: node - class(nodeComponentBlackHole), pointer :: blackHole - - ! Get the black hole component. - blackHole => node%blackHole() - ! Ensure that it is of the standard class. - Node_Component_Black_Hole_Standard_Matches=.false. - select type (blackHole) - class is (nodeComponentBlackHoleStandard) - Node_Component_Black_Hole_Standard_Matches=.true. - type is (nodeComponentBlackHole ) - Node_Component_Black_Hole_Standard_Matches=defaultBlackHoleComponent%standardIsActive() - end select - return - end function Node_Component_Black_Hole_Standard_Matches - subroutine Node_Component_Black_Hole_Standard_Output_Merger(node,massBlackHole1,massBlackHole2) !!{ Outputs properties of merging black holes. @@ -1009,134 +690,6 @@ subroutine Node_Component_Black_Hole_Standard_Output_Merger(node,massBlackHole1, return end subroutine Node_Component_Black_Hole_Standard_Output_Merger - !![ - - Node_Component_Black_Hole_Standard_Output_Properties - - !!] - subroutine Node_Component_Black_Hole_Standard_Output_Properties(node,iOutput,treeIndex,nodePassesFilter,treeLock) - !!{ - Output properties for all black holes in {\normalfont \ttfamily node}. - !!} - use :: Output_HDF5 , only : outputFile - use :: Galacticus_Nodes , only : nodeComponentBlackHole, treeNode - use :: HDF5_Access , only : hdf5Access - use :: IO_HDF5 , only : hdf5Object - use, intrinsic :: ISO_C_Binding , only : c_size_t - use :: ISO_Varying_String, only : assignment(=) , char , varying_string - use :: Kind_Numbers , only : kind_int8 - use :: String_Handling , only : operator(//) - use :: Locks , only : ompLock - implicit none - type (treeNode ), intent(inout), pointer :: node - integer (kind=kind_int8 ), intent(in ) :: treeIndex - integer (c_size_t ), intent(in ) :: iOutput - logical , intent(in ) :: nodePassesFilter - type (ompLock ), intent(inout) :: treeLock - class (nodeComponentBlackHole) , pointer :: blackHole - integer (kind=kind_int8 ), allocatable , dimension(:) :: mergerTreeIndex , nodeIndex - double precision , allocatable , dimension(:) :: mass , massAccretionRate , radiativeEfficiency, & - & radius , spin , timescale - double precision :: accretionRateHotHalo, accretionRateSpheroid - integer :: blackHoleCount , instance - type (hdf5Object ) :: blackHolesGroup , outputGroup - type (varying_string ) :: groupName - !$GLC attributes unused :: treeLock - - ! If black hole output was requested , output their properties. - if (nodePassesFilter .and. outputData) then - ! Get a count of the number of black holes present. - blackHoleCount=node%blackHoleCount() - ! Open the output group. - !$ call hdf5Access%set() - blackHolesGroup=outputFile%openGroup("blackHole","Black hole data.") - groupName="Output" - groupName=groupName//iOutput - outputGroup=blackHolesGroup%openGroup(char(groupName),"Properties of black holes for all trees at each output.") - !$ call hdf5Access%unset() - ! Allocate array to store profile. - allocate(radius (blackHoleCount)) - allocate(spin (blackHoleCount)) - allocate(mass (blackHoleCount)) - allocate(timescale (blackHoleCount)) - allocate(massAccretionRate (blackHoleCount)) - allocate(radiativeEfficiency(blackHoleCount)) - allocate(nodeIndex (blackHoleCount)) - allocate(mergerTreeIndex (blackHoleCount)) - ! Construct arrays of black hole properties. - do instance=1,blackHoleCount - blackHole => node%blackHole(instance=instance) - call Node_Component_Black_Hole_Standard_Mass_Accretion_Rate(blackHole,accretionRateSpheroid& - &,accretionRateHotHalo) - mass (instance)=blackHole%mass() - spin (instance)=blackHole%spin() - radius (instance)=blackHole%radialPosition() - massAccretionRate (instance)=accretionRateSpheroid+accretionRateHotHalo - radiativeEfficiency(instance)=accretionDisks_%efficiencyRadiative(blackHole,massAccretionRate(instance)) - nodeIndex (instance)=node%index() - mergerTreeIndex (instance)=treeIndex - if (instance > 1) then - if (blackHoleBinarySeparationGrowthRate_%growthRate(blackHole) /= 0.0d0 )then - timescale(instance)=-blackHole %radialPosition( ) & - & /blackHoleBinarySeparationGrowthRate_%growthRate (blackHole) - else - timescale(instance)=0.0d0 - end if - else - timescale (instance)=0.0d0 - end if - end do - ! Write dataset to the group, first the arrays containing all data. - !$ call hdf5Access %set ( ) - call outputGroup %writeDataset(mass ,"mass" ,"The black hole masses." ,appendTo=.true.) - call outputGroup %writeDataset(spin ,"spin" ,"The black hole spins." ,appendTo=.true.) - call outputGroup %writeDataset(radius ,"radius" ,"The black hole radial positions." ,appendTo=.true.) - call outputGroup %writeDataset(timescale ,"timescale" ,"The black hole timescales for merger." ,appendTo=.true.) - call outputGroup %writeDataset(radiativeEfficiency,"radiativeEfficiency","The black hole radiative efficiencies.",appendTo=.true.) - call outputGroup %writeDataset(massAccretionRate ,"accretionRate" ,"The black hole accretion rates." ,appendTo=.true.) - call outputGroup %writeDataset(nodeIndex ,"nodeIndex" ,"The black hole host galaxy inices." ,appendTo=.true.) - call outputGroup %writeDataset(mergerTreeIndex ,"mergerTreeIndex" ,"The black hole merger tree indices." ,appendTo=.true.) - call outputGroup %close ( ) - call blackHolesGroup%close ( ) - !$ call hdf5Access%unset() - ! Deallocate profile arrays. - deallocate(mass ) - deallocate(spin ) - deallocate(radius ) - deallocate(timescale ) - deallocate(radiativeEfficiency) - deallocate(massAccretionRate ) - deallocate(nodeIndex ) - deallocate(mergerTreeIndex ) - end if - return - end subroutine Node_Component_Black_Hole_Standard_Output_Properties - - double precision function Hot_Mode_Fraction(node) - !!{ - A simple interpolating function which is used as a measure of the fraction of a halo which is in the hot accretion mode. - !!} - use :: Galacticus_Nodes, only : treeNode - implicit none - type (treeNode), intent(inout) :: node - double precision , parameter :: coolingRadiusFractionalTransitionMinimum=0.9d0 - double precision , parameter :: coolingRadiusFractionalTransitionMaximum=1.0d0 - double precision :: coolingRadiusFractional , x - - coolingRadiusFractional=+coolingRadius_ % radius(node) & - & /darkMatterHaloScale_%radiusVirial(node) - if (coolingRadiusFractional < coolingRadiusFractionalTransitionMinimum) then - Hot_Mode_Fraction=1.0d0 - else if (coolingRadiusFractional > coolingRadiusFractionalTransitionMaximum) then - Hot_Mode_Fraction=0.0d0 - else - x= (coolingRadiusFractional -coolingRadiusFractionalTransitionMinimum) & - & /(coolingRadiusFractionalTransitionMaximum-coolingRadiusFractionalTransitionMinimum) - Hot_Mode_Fraction=x**2*(2.0d0*x-3.0d0)+1.0d0 - end if - return - end function Hot_Mode_Fraction - double precision function Node_Component_Black_Hole_Standard_Accretion_Rate(self) !!{ Return the rest mass accretion rate onto a standard black hole. @@ -1145,8 +698,8 @@ double precision function Node_Component_Black_Hole_Standard_Accretion_Rate(self implicit none class (nodeComponentBlackHoleStandard), intent(inout) :: self double precision :: accretionRateSpheroid, accretionRateHotHalo - - call Node_Component_Black_Hole_Standard_Mass_Accretion_Rate(self,accretionRateSpheroid,accretionRateHotHalo) + + call blackHoleAccretionRate_%rateAccretion(self,accretionRateSpheroid,accretionRateHotHalo) Node_Component_Black_Hole_Standard_Accretion_Rate=accretionRateSpheroid+accretionRateHotHalo return end function Node_Component_Black_Hole_Standard_Accretion_Rate @@ -1236,7 +789,7 @@ subroutine Node_Component_Black_Hole_Standard_State_Store(stateFile,gslStateFile call displayMessage('Storing state for: componentBlackHole -> standard',verbosity=verbosityLevelInfo) !![ - + !!] return end subroutine Node_Component_Black_Hole_Standard_State_Store @@ -1259,7 +812,7 @@ subroutine Node_Component_Black_Hole_Standard_State_Restore(stateFile,gslStateFi call displayMessage('Retrieving state for: componentBlackHole -> standard',verbosity=verbosityLevelInfo) !![ - + !!] return end subroutine Node_Component_Black_Hole_Standard_State_Restore diff --git a/testSuite/parameters/bolshoiTestTreesGLC.xml b/testSuite/parameters/bolshoiTestTreesGLC.xml index 9261681473..345e201e2d 100644 --- a/testSuite/parameters/bolshoiTestTreesGLC.xml +++ b/testSuite/parameters/bolshoiTestTreesGLC.xml @@ -14,7 +14,6 @@ - @@ -292,7 +291,13 @@ - + + + + + + + diff --git a/testSuite/test-methods.xml b/testSuite/test-methods.xml index 8880a7c315..e6841ac540 100644 --- a/testSuite/test-methods.xml +++ b/testSuite/test-methods.xml @@ -650,6 +650,15 @@ 0.9.4 + + + + + + + + + From 8769e8dd16d00b8e21906196e1a121df0951fca5 Mon Sep 17 00:00:00 2001 From: Andrew Benson Date: Fri, 17 Nov 2023 10:15:31 -0800 Subject: [PATCH 4/4] fix: Remove obsoleted old-style `include` tasks The following old-style `include` tasks are no longer used, so can be removed: * mergerTreeExtraOutputTask; * mergerTreeOutputTask; * mergerTreeOutputPropertyCount; * mergerTreeOutputNames --- source/merger_trees.outputter.standard.F90 | 61 +--------------------- 1 file changed, 1 insertion(+), 60 deletions(-) diff --git a/source/merger_trees.outputter.standard.F90 b/source/merger_trees.outputter.standard.F90 index 8d52b634dd..4b4584c8f5 100644 --- a/source/merger_trees.outputter.standard.F90 +++ b/source/merger_trees.outputter.standard.F90 @@ -229,14 +229,6 @@ subroutine standardOutputTree(self,tree,indexOutput,time) use :: IO_HDF5 , only : hdf5Object use, intrinsic :: ISO_C_Binding , only : c_size_t use :: Merger_Tree_Walkers, only : mergerTreeWalkerAllNodes - use omp_lib - !![ - - !!] - include 'merger_trees.outputter.tasks.extra.modules.inc' - !![ - - !!] implicit none class (mergerTreeOutputterStandard), intent(inout) :: self type (mergerTree ), intent(inout), target :: tree @@ -276,14 +268,8 @@ subroutine standardOutputTree(self,tree,indexOutput,time) if (basic%time() == time) then ! Perform our output. call self%output(node,time) - ! Perform an extra output tasks. + ! Perform an extra output. !![ - - node,indexOutput,node%hostTree%index,self%galacticFilter_%passes(node),treeLock - !!] - include 'merger_trees.outputter.tasks.extra.inc' - !![ - node,indexOutput,node%hostTree,self%galacticFilter_%passes(node),treeLock @@ -404,13 +390,6 @@ subroutine standardOutput(self,node,time) & nodePropertyExtractorMulti, nodePropertyExtractorNull, nodePropertyExtractorScalar , nodePropertyExtractorTuple , & & nodePropertyExtractorArray, nodePropertyExtractorList, nodePropertyExtractorList2D use :: Poly_Ranks , only : polyRankInteger , polyRankDouble , assignment(=) - !![ - - !!] - include 'output.merger_tree.tasks.modules.inc' - !![ - - !!] implicit none class (mergerTreeOutputterStandard), intent(inout) :: self type (treeNode ), intent(inout) :: node @@ -456,14 +435,6 @@ subroutine standardOutput(self,node,time) ! Populate the output buffers with properties. We first populate with any "extra" properties that may be ! being computed, and then call the standard treeNode output method to populate with all "standard" ! properties. - !![ - - node,integerProperty,self%integerBufferCount,self%integerProperty,doubleProperty,self%doubleBufferCount,self%doubleProperty,time,instance - !!] - include 'output.merger_tree.tasks.inc' - !![ - - !!] call node%output(integerProperty,self%integerBufferCount,self%integerProperty,doubleProperty,self%doubleBufferCount,self%doubleProperty,time,instance) ! Handle any extracted properties. select type (extractor_ => self%nodePropertyExtractor_) @@ -891,13 +862,6 @@ subroutine standardPropertiesCount(self,time,node) use :: Node_Property_Extractors, only : elementTypeDouble , elementTypeInteger , nodePropertyExtractorIntegerScalar, nodePropertyExtractorIntegerTuple, & & nodePropertyExtractorMulti, nodePropertyExtractorNull, nodePropertyExtractorScalar , nodePropertyExtractorTuple , & & nodePropertyExtractorArray, nodePropertyExtractorList, nodePropertyExtractorList2D - !![ - - !!] - include 'output.merger_tree.property_count.modules.inc' - !![ - - !!] implicit none class (mergerTreeOutputterStandard), intent(inout) :: self double precision , intent(in ) :: time @@ -905,14 +869,6 @@ subroutine standardPropertiesCount(self,time,node) self%integerPropertyCount=0 self%doublePropertyCount =0 - !![ - - node,self%integerPropertyCount,self%doublePropertyCount,time - !!] - include 'output.merger_tree.property_count.inc' - !![ - - !!] call node%outputCount(self%integerPropertyCount,self%doublePropertyCount,time) self%integerScalarCount=self%integerPropertyCount self% doubleScalarCount=self% doublePropertyCount @@ -981,13 +937,6 @@ subroutine standardPropertyNamesEstablish(self,time,node) use :: Node_Property_Extractors, only : elementTypeDouble , elementTypeInteger , nodePropertyExtractorIntegerScalar, nodePropertyExtractorIntegerTuple, & & nodePropertyExtractorMulti, nodePropertyExtractorNull, nodePropertyExtractorScalar , nodePropertyExtractorTuple , & & nodePropertyExtractorArray, nodePropertyExtractorList, nodePropertyExtractorList2D - !![ - - !!] - include 'output.merger_tree.names.modules.inc' - !![ - - !!] implicit none class (mergerTreeOutputterStandard), intent(inout) :: self double precision , intent(in ) :: time @@ -1015,14 +964,6 @@ subroutine standardPropertyNamesEstablish(self,time,node) end if integerProperty=0 doubleProperty =0 - !![ - - node,integerProperty,self%integerProperty,doubleProperty,self%doubleProperty,time - !!] - include 'output.merger_tree.names.inc' - !![ - - !!] call node%outputNames(integerProperty,self%integerProperty,doubleProperty,self%doubleProperty,time) ! Handle extracted properties. select type (extractor_ => self%nodePropertyExtractor_)