1919
2020from .config import Variables
2121from .config .fargo import Constants , Planet , PlanetConfig , UnitSystem
22+ from .plotting .utils import configure_axes
2223from .setup import Setup
2324
2425__all__ = ["Simulation" , "SimulationRun" , "DiskModel" ]
@@ -28,7 +29,8 @@ def get_default_sampling_config():
2829 return {
2930 "disk_parameters" : {
3031 "aspect_ratio" : [0.01 , 0.1 ], # Disk aspect ratio @ r=R0 (default R0 = 1AU)
31- "sigma0" : [15000.0 , 30000.0 ], # Surface density (kg/m^2) @ r=R0
32+ "disk_mass_ref_radius" : 1000 , # Reference radius R_ref in AU
33+ "disk_mass" : [0.001 , 0.01 ], # Cumulative disk mask @ r=R_ref
3234 "sigma_slope" : [0.05 , 0.3 ], # Exponent of the density profile
3335 "flaring_index" : [0.0 , 0.0 ],
3436 "alpha" : [0.001 , 0.01 ], # Shakura-Sunyaev viscosity parameter
@@ -62,6 +64,46 @@ def get_default_sampling_config():
6264 }
6365
6466
67+ # See https://fargo3d.github.io/documentation/def_setups.html#parameters
68+ def surface_density (
69+ radius : float | ArrayLike , R0 : float , sigma0 : float , sigma_slope : float
70+ ):
71+ return sigma0 * (radius / R0 ) ** (- sigma_slope )
72+
73+
74+ # From https://doi.org/10.1093/mnrasl/slv105 p.75
75+ def sigma0 (
76+ ref_radius : float | ArrayLike , R0 : float , mass : float , sigma_slope : float
77+ ) -> float | ArrayLike :
78+ return (
79+ (2 - sigma_slope )
80+ / (2 * np .pi * R0 ** 2 )
81+ * mass
82+ * ((ref_radius / R0 ) ** (2 - sigma_slope ) - 1 ) ** (- 1 )
83+ )
84+
85+
86+ # From https://fargo3d.github.io/documentation/def_setups.html#parameters
87+ def aspect_ratio (
88+ radius : float | ArrayLike , R0 : float , ref_aspect_ratio : float , flaring_index : float
89+ ) -> float | ArrayLike :
90+ return ref_aspect_ratio * (radius / R0 ) ** flaring_index
91+
92+
93+ # From https://fargo3d.github.io/documentation/def_setups.html#parameters
94+ def disk_height (
95+ radius : float | ArrayLike , ref_aspect_ratio : float , flaring_index : float
96+ ) -> float | ArrayLike :
97+ return (
98+ aspect_ratio (
99+ radius = radius ,
100+ ref_aspect_ratio = ref_aspect_ratio ,
101+ flaring_index = flaring_index ,
102+ )
103+ * radius
104+ )
105+
106+
65107class Simulation :
66108 def __init__ (
67109 self ,
@@ -260,7 +302,14 @@ def simulate(
260302 param_config ["disk_parameters.aspectRatio" ] = disk_parameters [
261303 "aspect_ratio"
262304 ]
263- param_config ["disk_parameters.sigma0" ] = disk_parameters ["sigma0" ]
305+
306+ param_config ["disk_parameters.sigma0" ] = sigma0 (
307+ ref_radius = disk_parameters ["disk_mass_ref_radius" ],
308+ R0 = self ._constants ["R0" ],
309+ mass = disk_parameters ["disk_mass" ],
310+ sigma_slope = disk_parameters ["sigma_slope" ],
311+ )
312+
264313 param_config ["disk_parameters.sigmaSlope" ] = disk_parameters ["sigma_slope" ]
265314 param_config ["disk_parameters.flaringIndex" ] = disk_parameters [
266315 "flaring_index"
@@ -602,6 +651,8 @@ def sample_dict(read_dict):
602651 write_dict [key ] = rng .integers (low = value [0 ], high = value [1 ])
603652 else :
604653 write_dict [key ] = rng .uniform (low = value [0 ], high = value [1 ])
654+ elif np .isscalar (value ):
655+ write_dict [key ] = value
605656
606657 return write_dict
607658
@@ -796,6 +847,82 @@ def get_polar_dust_density(
796847 r_max ,
797848 )
798849
850+ def plot_density_profile (
851+ self ,
852+ save_to : str | PathLike | None = None ,
853+ save_args : dict | None = None ,
854+ r_unit : un .Unit = un .AU ,
855+ density_unit : un .Unit = un .kilogram / un .meter ** 2 ,
856+ show_formula : bool = False ,
857+ r_min : float | None = None ,
858+ r_max : float | None = None ,
859+ plot_args : dict | None = None ,
860+ fig : matplotlib .figure .Figure | None = None ,
861+ fig_args : dict | None = None ,
862+ ax : matplotlib .axes .Axes | None = None ,
863+ ) -> tuple [matplotlib .axes .Axes , matplotlib .figure .Figure ]:
864+ save_args = {} if save_args is None else save_args
865+ fig_args = {} if fig_args is None else fig_args
866+ plot_args = {} if plot_args is None else plot_args
867+
868+ r_min = (
869+ r_min
870+ if r_min is not None
871+ else (self .get_radius_lims ()[0 ] * un .AU ).to (r_unit ).value
872+ )
873+ r_max = (
874+ r_max
875+ if r_max is not None
876+ else (self .get_radius_lims ()[1 ] * un .AU ).to (r_unit ).value
877+ )
878+
879+ radii = np .linspace (r_min , r_max , 10000 )
880+
881+ sample_config = self .get_sample_config ()
882+ unit_system = self ._run ._sim ._unit_system
883+
884+ density = surface_density (
885+ radii ,
886+ R0 = self ._run ._sim ._constants ["R0" ].value ,
887+ sigma0 = sample_config ["disk_parameters.sigma0" ],
888+ sigma_slope = sample_config ["disk_parameters.sigma_slope" ],
889+ ) * (unit_system .mass / unit_system .length ** 2 ).to (density_unit )
890+
891+ fig , ax = configure_axes (fig = fig , ax = ax )
892+
893+ ax .plot (
894+ radii ,
895+ density ,
896+ label = "$\\ Sigma(R)=\\ Sigma_0 \cdot (\\ frac{R}{R_0})^{-p}$"
897+ if show_formula
898+ else None ,
899+ ** plot_args ,
900+ )
901+ ax .axvline (
902+ (self .get_radius_lims ()[0 ] * un .AU ).to (r_unit ).value ,
903+ ls = "dashed" ,
904+ color = "maroon" ,
905+ alpha = 0.4 ,
906+ label = "Inner Simulation Radius" ,
907+ )
908+ ax .axvline (
909+ (self .get_radius_lims ()[1 ] * un .AU ).to (r_unit ).value ,
910+ ls = "dashed" ,
911+ color = "green" ,
912+ alpha = 0.4 ,
913+ label = "Outer Simulation Radius" ,
914+ )
915+ ax .set_xlabel (f"Radius $R$ in { r_unit .to_string (format = 'latex' )} " )
916+ ax .set_ylabel (
917+ f"Density Profile $\\ Sigma$ in { density_unit .to_string (format = 'latex' )} "
918+ )
919+ ax .legend ()
920+
921+ if save_to is not None :
922+ fig .savefig (save_to , ** save_args )
923+
924+ return fig , ax
925+
799926 def plot_dust_density (
800927 self ,
801928 grid_shape : tuple ,
@@ -899,8 +1026,6 @@ def animate_dust_density(
8991026 )
9001027 data [i ] = img
9011028
902- print (f"{ [data [data > 0 ].min (), data .max ()]} " )
903-
9041029 im , fig , ax = self .plot_dust_density (
9051030 grid_shape = grid_shape ,
9061031 output_idx = start_idx ,
0 commit comments