[1]:
## These are stretching model functions
import RelaxiFI as pf
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import math
import warnings
relax.__version__
## These are functions to find the pressure corresponding to a specific depth using a RelaxiFI models
from scipy.optimize import newton
def pressure_equation(P_kbar, target_depth, model):
current_depth = relax.convert_pressure_to_depth(P_kbar=P_kbar, model=model)[0]
return current_depth - target_depth
def find_P_for_kmdepth(target_depth, model, tolerance=0.1):
initial_pressure = 0
pressure = newton(pressure_equation, initial_pressure, args=(target_depth, model), tol=tolerance)
return pressure
## Example: find the pressure at 5 km depth
target_depth = 5
model = 'ryan_lerner'
tolerance = 0.001 # how close you want to be
# run it
pressure = find_P_for_kmdepth(target_depth, model, tolerance)
# print the result
print("Pressure:", pressure)
print("Depth:", relax.convert_pressure_to_depth(P_kbar=pressure, model=model)[0])
Pressure: 1.1834708907085945
Depth: 4.999999838702872
[2]:
class config_crustalmodel:
def __init__(self, crust_dens_kgm3=None,
d1=None, d2=None, rho1=None, rho2=None, rho3=None, model=None):
self.crust_dens_kgm3 = crust_dens_kgm3
self.d1 = d1
self.d2 = d2
self.rho1 = rho1
self.rho2 = rho2
self.rho3 = rho3
self.model = model
def objective_function_depth(P_kbar, target_depth, crust_dens_kgm3,
d1, d2, rho1, rho2, rho3, model):
"""
Calculate the difference between the current depth and the target depth
given pressure (P_kbar) and other parameters.
Parameters:
- P_kbar (float): The pressure in kilobars (kbar) to be used in the depth calculation.
- target_depth (float): The desired depth in kilometers (km).
- crust_dens_kgm3 (float): The density of the crust in kilograms per cubic meter (kg/m^3).
- d1, d2 (float): Depth boundaries for different layers (km).
- rho1, rho2, rho3 (float): Densities for different layers (kg/m^3).
- model (str): The name of the model used for the depth calculation.
Returns:
- float: The difference between the current depth and the target depth.
"""
current_depth = relax.convert_pressure_to_depth(P_kbar=P_kbar, crust_dens_kgm3=crust_dens_kgm3, g=9.81,
d1=d1, d2=d2, rho1=rho1, rho2=rho2, rho3=rho3, model=model)[0]
return current_depth - target_depth
def find_P_for_kmdepth(target_depth, config=config_crustalmodel(), initial_P_guess=0,tolerance=0.1):
"""
Approximate the pressure (P_kbar) based on the target depth using the Newton-Raphson method.
Parameters:
- target_depth (float): The desired depth in kilometers (km).
- P_kbar (float, optional): Initial guess for the pressure in kilobars (kbar). Default is None.
- crust_dens_kgm3 (float, optional): The density of the crust in kilograms per cubic meter (kg/m^3). Default is None.
- d1, d2 (float, optional): Depth boundaries for different layers (km). Default is None.
- rho1, rho2, rho3 (float, optional): Densities for different layers (kg/m^3). Default is None.
- model (str, optional): The name of the model used for the depth calculation. Default is None.
- tolerance (float, optional): How close the pressure estimate should be to the true value. Default is 0.1.
Returns:
- float: The estimated pressure (P_kbar) that corresponds to the target depth.
"""
if all(v is None for v in [config.crust_dens_kgm3, config.d1, config.d2, config.rho1, config.rho2, config.rho3, config.model]):
config.crust_dens_kgm3 = 2750
warnings.warn("No crustal parameters were provided, setting crust_dens_kgm3 to 2750. Please use config_crustalmodel(...) to set your desired crustal model parameters.", UserWarning)
pressure = newton(objective_function_depth, initial_P_guess, args=(target_depth, config.crust_dens_kgm3, config.d1, config.d2, config.rho1, config.rho2, config.rho3, config.model), tol=tolerance)
return pressure
## Example: find the pressure at 5 km depth
target_depth = 5
config=config_crustalmodel()
tolerance = 0.001 # how close you want to be
# run it
pressure = find_P_for_kmdepth(target_depth=5, config=config, tolerance=tolerance)
print("Pressure:", pressure)
Pressure: 1.3488749999999998
C:\Users\charl\AppData\Local\Temp\ipykernel_32732\1308236487.py:54: UserWarning: No crustal parameters were provided, setting crust_dens_kgm3 to 2750. Please use config_crustalmodel(...) to set your desired crustal model parameters.
warnings.warn("No crustal parameters were provided, setting crust_dens_kgm3 to 2750. Please use config_crustalmodel(...) to set your desired crustal model parameters.", UserWarning)
[3]:
## Functions that do the work
# Calculating density using ideal gas law for sphere of radius r, P in MPa, T in K.
def ideal_calc_rho_for_r_P_T(*,P_MPa,T,r):
P=P_MPa*10**6 # convert MPa to Pa
M=44.01/1000 #kg/mol
V=4/3*math.pi*r**3 #m3
R=8.314 #J.mol/K J: kg·m²/s²
m=P*V*M/(R*T) #CO2 mass in kg
rho=(m/V)/1000 # rho in g/cm3
return rho, m/1000
# Calculating pressure using ideal gas law for sphere of radius r, CO2 mass in grams, T in K.
def ideal_calc_P_for_V_rho_T(*,co2_mass_g,T,r):
M=44.01/1000 #kg/mol
m=co2_mass_g*1000
V=4/3*math.pi*r**3 #m3
R=8.314 #J.mol/K J: kg·m²/s²
P=m*R*T/(M*V) #P in Pa
P_MPa=P/(10**6) #P in MPa
rho=(m/V)/1000 #rho in g/cm3
return rho,P_MPa
def calculate_DPdt(ascent_rate_ms,D_initial=30,D_final=0,D_step=100):
D = pd.Series(list(np.linspace(D_initial, D_final, D_step))) # km
h = D * 10 ** 3 # m
rho = 3058 # kg/m3
g = 9.81 # m/s2
P = rho * g * h * 10 ** -6 # MPa lithostatic pressure
Pexternal_steps = list(P) # These are the pressure steps
# Time steps of the ascent
ascent_rate = ascent_rate_ms / 1000 # km/s
D_change = abs(D.diff())
time_series = D_change / ascent_rate # calculates the time in between each step based on ascent rate
dt = time_series.max() # this sets the time step for the integration part
return D, Pexternal_steps, dt
def calculate_initial_V_CO2rho_mass(*,EOS='SW96',P,T,r):
### This function calculates CO2 mass as a function of P,T, and FI radius(Volume), r has to be in cm,
### V is output in cm3, rho in g/cm3 and mass in g
###
V=4/3*math.pi*r**3 #cm3, Volume of the FI, assume sphere
P_kbar=P/100 #Internal pressure of the FI
CO2_dens=relax.calculate_rho_for_P_T(EOS=EOS,P_kbar=P_kbar,T_K=T)[0] #g/cm3, CO2 density, calc by Span&Wagner(96)
CO2_mass=CO2_dens*V # this is our CO2 mass in the FI
return V, CO2_dens, CO2_mass
def calculate_step_P_for_m_r(*,EOS='SW96',m,T,r):
### This function internal pressure and volume of the inclusion as a function of T, FI radius and CO2 mass, r has to be in cm,
### V is output in cm3, rho in g/cm3 and mass in g.
###
V=4/3*math.pi*r**3 #cm3, Volume of the FI, assume sphere
CO2_dens=m/V
try:
P_new=relax.calculate_P_for_rho_T(EOS=EOS,CO2_dens_gcm3=CO2_dens, T_K=T)['P_MPa'][0] #g/cm3, CO2 density, calc by Span&Wagner(96)
return V, CO2_dens, P_new
except ValueError:
return V,CO2_dens,np.nan
class power_creep_law_constants:
def __init__(self):
self.A = 3.9*10**3 #7.0 * 10**4
self.n = 3.6 #3
self.Q = 523000 # 520 Activation energy for dislocation motions in J/mol
self.IgasR= 8.314 # Gas constant in J/(mol*K)
# # Helper function to calculate dR/dt
def calculate_dR_dt(*,R, b, T, Pinternal, Pexternal):
pl_Cs = power_creep_law_constants()
if Pinternal<Pexternal==True:
S=-1
else:
S=1
try:
dR_dt = 2 * (S * pl_Cs.A * math.exp(-pl_Cs.Q / (pl_Cs.IgasR * T))) * (((R * b)**3) / (((b**(3 / pl_Cs.n)) - (R**(3 / pl_Cs.n))))**pl_Cs.n) * (((3 * abs(Pinternal - Pexternal)) / (2 * pl_Cs.n))**pl_Cs.n) / R**2
return dR_dt
except FloatingPointError:
return np.nan
# Euler method for iterative numerical solving (range of Pext)
def findR_Pi_rho_4Pestep_euler(*,R0, b, T,D,Pexternal_steps,dt,EOS,plotfig=True,display_df=True,Pinternal=None):
if Pinternal is None:
Pinternal = Pexternal_steps[0]
_,CO2_dens_initial,CO2_mass_initial=calculate_initial_V_CO2rho_mass(EOS=EOS,P=Pinternal,T=T,r=R0*10**2)
R_values = [R0] # List to store R values at different time points
Pinternal_list=[Pinternal]
CO2_dens_list=[CO2_dens_initial]
dR_dt_list=[]
results=pd.DataFrame(columns={'Pexternal(MPa)','Pinternal(MPa)',
'Depth(km)','Fi_radius(\u03BCm)',
'CO2_dens_gcm3','dR/dt(m/s)' })
for i in range(len(Pexternal_steps)):
Pexternal = Pexternal_steps[i]
dR_dt = calculate_dR_dt(R=R_values[-1], b=b,Pinternal=Pinternal, Pexternal=Pexternal, T=T)
R_new = R_values[-1] + dR_dt * dt
_,CO2_dens_new,P_new=calculate_step_P_for_m_r(EOS=EOS,m=CO2_mass_initial,T=T,r=R_new*10**2)
Pinternal=P_new
dR_dt_list.append(dR_dt)
R_values.append(R_new)
Pinternal_list.append(Pinternal)
CO2_dens_list.append(CO2_dens_new)
results['Pexternal(MPa)']=Pexternal_steps
results['Pinternal(MPa)']=Pinternal_list[1:]
results['Depth(km)']=D
results['Fi_radius(\u03BCm)']=[num * 10**6 for num in R_values][1:]
results['CO2_dens_gcm3']=CO2_dens_list[1:]
results['dR/dt(m/s)']=dR_dt_list
results['\u0394R/R0']=(results['Fi_radius(μm)']-results['Fi_radius(μm)'][0])/results['Fi_radius(μm)'][0]
if display_df==True:
display(results.head())
if plotfig==True:
fig, (ax0,ax1) = ax.subplots(1,2, figsize=(10,3))
ax0.plot(-results['Depth(km)'],results['ΔR/R0'],marker='s')
ax0.set_xlabel("Depth")
ax0.set_ylabel("DeltaR/R0")
ax1.plot(-results['Depth(km)'],results['CO2_dens_gcm3'],marker='s')
ax1.set_xlabel("Depth")
ax1.set_ylabel("CO2_density_gmL")
return results, fig if 'fig' in locals() else results
def findR_Pi_rho_fixedPe(*,R,b=None,T,EOS_method=None,EOS='SW96',Pinternal,Pexternal,totaltime,steps,int_method='Euler'):
dt=totaltime/steps
if b is None:
b=R*1000
if EOS_method=='ideal':
CO2_dens_initial,CO2_mass_initial=ideal_calc_rho_for_r_P_T(P_MPa=Pinternal,T=T,r=R*10**2)
else:
_,CO2_dens_initial,CO2_mass_initial=calculate_initial_V_CO2rho_mass(EOS=EOS,P=Pinternal,T=T,r=R*10**2)
results = pd.DataFrame([{'Time(s)': 0,
'Step':0,
'dt(s)':0,
'Pexternal(MPa)': Pexternal,
'Pinternal(MPa)': Pinternal,
'dR/dt(m/s)': calculate_dR_dt(R=R, b=b, Pinternal=Pinternal, Pexternal=Pexternal, T=T),
'Fi_radius(μm)': R*10**6,
'b (distance to xtal rim -μm)':b*10**6,
'\u0394R/R0 (fractional change in radius)':0,
'CO2_dens_gcm3': CO2_dens_initial}], index=range(steps))
if int_method=='Euler':
for step in range(1,steps):
dR_dt = calculate_dR_dt(R=R, b=b,Pinternal=Pinternal, Pexternal=Pexternal, T=T)
R_new= R + dR_dt*dt
if EOS_method=='ideal':
CO2_dens_new,P_new=ideal_calc_P_for_V_rho_T(co2_mass_g=CO2_mass_initial,T=T,r=R_new*10**2)
else:
_,CO2_dens_new,P_new=calculate_step_P_for_m_r(EOS=EOS,m=CO2_mass_initial,T=T,r=R_new*10**2)
R=R_new
b=1000*R
Pinternal=P_new
results.loc[step,'Time(s)']=step*dt
results.loc[step,'Step']=step
results.loc[step,'dt(s)']=dt
results.loc[step,'Pexternal(MPa)']=Pexternal
results.loc[step,'Pinternal(MPa)']=Pinternal
results.loc[step,'dR/dt(m/s)']=dR_dt
results.loc[step,'Fi_radius(μm)']=R*10**6
results.loc[step,'\u0394R/R0 (fractional change in radius)']=(R*10**6-results.loc[0,'Fi_radius(μm)'])/results.loc[0,'Fi_radius(μm)']
results.loc[step,'b (distance to xtal rim -μm)']=b*10**6
results.loc[step,'CO2_dens_gcm3']=CO2_dens_new
if int_method=='RK4':
for step in range(1, steps):
# Calculate k1
dR_dt = calculate_dR_dt(R=R, b=b, Pinternal=Pinternal, Pexternal=Pexternal, T=T)
k1 = dR_dt * dt
# Calculate k2
R_temp = R + 0.5 * k1
if EOS_method == 'ideal':
CO2_dens_temp, P_temp = ideal_calc_P_for_V_rho_T(co2_mass_g=CO2_mass_initial, T=T, r=R_temp * 10**2)
else:
_, CO2_dens_temp, P_temp = calculate_step_P_for_m_r(EOS=EOS, m=CO2_mass_initial, T=T, r=R_temp * 10**2)
k2 = (P_temp - Pinternal) * dt
# Calculate k3
R_temp = R + 0.5 * k2
if EOS_method == 'ideal':
CO2_dens_temp, P_temp = ideal_calc_P_for_V_rho_T(co2_mass_g=CO2_mass_initial, T=T, r=R_temp * 10**2)
else:
_, CO2_dens_temp, P_temp = calculate_step_P_for_m_r(EOS=EOS, m=CO2_mass_initial, T=T, r=R_temp * 10**2)
k3 = (P_temp - Pinternal) * dt
# Calculate k4
R_temp = R + k3
if EOS_method == 'ideal':
CO2_dens_temp, P_temp = ideal_calc_P_for_V_rho_T(co2_mass_g=CO2_mass_initial, T=T, r=R_temp * 10**2)
else:
_, CO2_dens_temp, P_temp = calculate_step_P_for_m_r(EOS=EOS, m=CO2_mass_initial, T=T, r=R_temp * 10**2)
k4 = (P_temp - Pinternal) * dt
# Update R and Pinternal using the weighted average of the four k values
R += (k1 + 2 * k2 + 2 * k3 + k4) / 6
Pinternal = P_temp
b=1000*R
results.loc[step,'Time(s)']=step*dt
results.loc[step,'Step']=step
results.loc[step,'dt(s)']=dt
results.loc[step,'Pexternal(MPa)']=Pexternal
results.loc[step,'Pinternal(MPa)']=Pinternal
results.loc[step,'dR/dt(m/s)']=dR_dt
results.loc[step,'Fi_radius(μm)']=R*10**6
results.loc[step,'\u0394R/R0 (fractional change in radius)']=(R*10**6-results.loc[0,'Fi_radius(μm)'])/results.loc[0,'Fi_radius(μm)']
results.loc[step,'b (distance to xtal rim -μm)']=b*10**6
results.loc[step,'CO2_dens_gcm3']=CO2_dens_temp
return results
def solve_runge_kutta(*, R, b=None, T, Pinternal, Pexternal, totaltime, steps=1000, EOS_method='ideal', order=4):
dt = totaltime / steps
if b is None:
b = R * 1000
if EOS_method == 'ideal':
CO2_dens_initial, CO2_mass_initial = ideal_calc_rho_for_r_P_T(P_MPa=Pinternal, T=T, r=R * 10 ** 2)
else:
_, CO2_dens_initial, CO2_mass_initial = calculate_initial_V_CO2rho_mass(EOS=EOS, P=Pinternal, T=T, r=R * 10 ** 2)
results = pd.DataFrame(columns=['Time(s)', 'Step', 'dt(s)', 'Pexternal(MPa)', 'Pinternal(MPa)', 'dR/dt(m/s)',
'Fi_radius(μm)', 'b (distance to xtal rim -μm)',
'ΔR/R0 (fractional change in radius)', 'CO2_dens_gcm3'])
results.loc[0] = [0, 0, 0, Pexternal, Pinternal, calculate_dR_dt(R=R, b=b, Pinternal=Pinternal, Pexternal=Pexternal, T=T),
R * 10 ** 6, b * 10 ** 6, 0, CO2_dens_initial]
for step in range(steps):
if order == 2:
k1 = dt * calculate_dR_dt(R=R, b=b, T=T, Pinternal=Pinternal, Pexternal=Pexternal)
k2 = dt * calculate_dR_dt(R=R + 0.5 * k1, b=b, T=T, Pinternal=Pinternal, Pexternal=Pexternal)
dR_dt = ((k1 + k2) / 2) / dt
R += (k1 + k2) / 2
elif order == 4:
k1 = dt * calculate_dR_dt(R=R, b=b, T=T, Pinternal=Pinternal, Pexternal=Pexternal)
k2 = dt * calculate_dR_dt(R=R + 0.5 * k1, b=b, T=T, Pinternal=Pinternal, Pexternal=Pexternal)
k3 = dt * calculate_dR_dt(R=R + 0.5 * k2, b=b, T=T, Pinternal=Pinternal, Pexternal=Pexternal)
k4 = dt * calculate_dR_dt(R=R + k3, b=b, T=T, Pinternal=Pinternal, Pexternal=Pexternal)
dR_dt = ((k1 + 2 * k2 + 2 * k3 + k4) / 6) / dt
R += (k1 + 2 * k2 + 2 * k3 + k4) / 6
if EOS_method == 'ideal':
CO2_dens_temp, P_temp = ideal_calc_P_for_V_rho_T(co2_mass_g=CO2_mass_initial, T=T, r=R * 10 ** 2)
else:
_, CO2_dens_temp, P_temp = calculate_step_P_for_m_r(EOS=EOS, m=CO2_mass_initial, T=T, r=R * 10 ** 2)
Pinternal = P_temp
b = R * 1000
results.loc[step] = [step * dt, step, dt, Pexternal, Pinternal, dR_dt, R * 10 ** 6,
(R * 10 ** 6 - results.loc[0, 'Fi_radius(μm)']) / results.loc[0, 'Fi_radius(μm)'],
b * 10 ** 6, CO2_dens_temp]
return results
def calculate_results(R_values, b_values, T, EOS, Pinternal, Pexternal, totaltime_in_s, steps, T4endcalc_PD):
results_dict = {}
for R in R_values:
R_name = [name for name, value in globals().items() if value is R][0]
R_key = f'{R_name}'
results_dict[R_key] = {}
for idx_b, b in enumerate(b_values):
b_key = f'b{idx_b}'
results = findR_Pi_rho_fixedPe_euler(R=R, b=b, T=T, EOS=EOS, Pinternal=Pinternal, Pexternal=Pexternal, totaltime=totaltime_in_s, steps=steps)
results['Calculated depths (km)_HMT'] = relax.convert_pressure_to_depth(P_kbar=results['Pinternal(MPa)'] / 100, model='ryan_lerner')
results['Calculated P from rho_SCTemp (MPa)'] = relax.calculate_P_for_rho_T(EOS='SW96', CO2_dens_gcm3=results['CO2_dens_gcm3'], T_K=T4endcalc_PD + 273.15)['P_MPa']
results['Calculated depths (km)'] = relax.convert_pressure_to_depth(P_kbar=results['Calculated P from rho_SCTemp (MPa)'] / 100, model='ryan_lerner')
results_dict[R_key][b_key] = results
return results_dict
[4]:
###### Let's model an FI (5 um) coming from South Caldera reservoir(4km @ 1300 C) and erupting to surface (0km @ 1150 C) ##############
####### Establish reservoir PTX conditions
## SC reservoir conditions
SC_temp=1400
SC_pressure = 10
## surface conditions
HM_temp=1400 # T in C
HM_pressure = 0.001
####### Let's start our model
### First let's calculate the CO2 density
fi_rho_initial_gcm3=relax.calculate_rho_for_P_T(EOS='SW96',P_kbar=SC_pressure,T_K=SC_temp+273.15)[0]
## Now we move the FI to surface
fi_Pi_HM_initial_MPa=relax.calculate_P_for_rho_T(EOS='SW96',CO2_dens_gcm3=fi_rho_initial_gcm3,T_K=HM_temp+273.15)['P_MPa'][0]
[15]:
def findR_Pi_rho_fixedPe_euler(*,R,b=None,T,EOS_method=None,EOS='SW96',Pinternal,Pexternal,totaltime,steps):
dt=totaltime/steps
if b is None:
b=R*1000
if EOS_method=='ideal':
CO2_dens_initial,CO2_mass_initial=ideal_calc_rho_for_r_P_T(P_MPa=Pinternal,T=T,r=R*10**2)
else:
_,CO2_dens_initial,CO2_mass_initial=calculate_initial_V_CO2rho_mass(EOS=EOS,P=Pinternal,T=T,r=R*10**2)
results = pd.DataFrame([{'Time(s)': 0,
'Step':0,
'dt(s)':0,
'Pexternal(MPa)': Pexternal,
'Pinternal(MPa)': Pinternal,
'dR/dt(m/s)': calculate_dR_dt(R=R, b=b, Pinternal=Pinternal, Pexternal=Pexternal, T=T),
'Fi_radius(μm)': R*10**6,
'b (distance to xtal rim -μm)':b*10**6,
'\u0394R/R0 (fractional change in radius)':0,
'CO2_dens_gcm3': CO2_dens_initial}], index=range(steps))
for step in range(1,steps):
dR_dt = calculate_dR_dt(R=R, b=b,Pinternal=Pinternal, Pexternal=Pexternal, T=T)
R_new= R + dR_dt*dt
if EOS_method=='ideal':
CO2_dens_new,P_new=ideal_calc_P_for_V_rho_T(co2_mass_g=CO2_mass_initial,T=T,r=R_new*10**2)
else:
_,CO2_dens_new,P_new=calculate_step_P_for_m_r(EOS=EOS,m=CO2_mass_initial,T=T,r=R_new*10**2)
R=R_new
#b=1000*R
Pinternal=P_new
results.loc[step,'Time(s)']=step*dt
results.loc[step,'Step']=step
results.loc[step,'dt(s)']=dt
results.loc[step,'Pexternal(MPa)']=Pexternal
results.loc[step,'Pinternal(MPa)']=Pinternal
results.loc[step,'dR/dt(m/s)']=dR_dt
results.loc[step,'Fi_radius(μm)']=R*10**6
results.loc[step,'\u0394R/R0 (fractional change in radius)']=(R*10**6-results.loc[0,'Fi_radius(μm)'])/results.loc[0,'Fi_radius(μm)']
results.loc[step,'b (distance to xtal rim -μm)']=b*10**6
results.loc[step,'CO2_dens_gcm3']=CO2_dens_new
return results
[16]:
## Now let's leave it on the surface for 7 days
# set initial parameters
days=1
T = HM_temp + 273.15
R0 = 2.5 * 10 ** -6 # FI radius in m
def calc_multiplier(R0, dist2defect_um):
multiplier = (dist2defect_um) / (R0 * 10**6)
return multiplier
dist2defect_list=[20,50,100,500]
b_list_R0=[calc_multiplier(R0, dist)*R0 for dist in dist2defect_list]
b0=b_list_R0[0]
b1 = b_list_R0[1]
b2=b_list_R0[2]
b3=b_list_R0[3]
steps=1000
EOS='SW96'
day_in_sec=(24*60*60)
totaltime_in_s=days*day_in_sec
Pinternal=fi_Pi_HM_initial_MPa
Pexternal=HM_pressure*100 ##Pressure in MPa for this model
# Call the function with appropriate arguments
R_values = [R0] # Define R values
b_values = [b0, b1, b2, b3]
b_list= [b0, b1, b2, b3]
results_dict_surface = calculate_results(R_values, b_values, T, EOS, Pinternal, Pexternal, totaltime_in_s, steps, SC_temp)
results_dict_surface['R0']['b0']['Fi_radius(μm)']
[16]:
0 2.500000
1 2.929995
2 2.946897
3 2.962176
4 2.976140
...
995 3.911827
996 3.912114
997 3.912401
998 3.912687
999 3.912973
Name: Fi_radius(μm), Length: 1000, dtype: float64
[49]:
results_dict_surface['R0']['b0'].head()
linecolor='darkred'
linecolor2='orange'
seconds_in_e_year = 365.25 * 24 * 60 * 60
y_col='CO2_dens_gcm3'
x_col='Time(s)'
twin_col='Calculated depths (km)'
xlabel4plot='Time(years)'
ylabel4plot='CO2 density (g/cm3)'
twinlabel4plot='Calculated depth (km)'
linecolor='midnightblue'
linecolor2='purple'
linewidth=0.5
fig, ax = plt.subplots()
ax.plot(results_dict_surface['R0']['b0'][x_col]/day_in_sec,results_dict_surface['R0']['b0'][y_col],color=linecolor2,linestyle=':',linewidth=linewidth,label=str(round(b0*10**6)))
ax.plot(results_dict_surface['R0']['b1'][x_col]/day_in_sec,results_dict_surface['R0']['b1'][y_col],color=linecolor2,linestyle='-.',linewidth=linewidth,label=str(round(b1*10**6)))
ax.plot(results_dict_surface['R0']['b2'][x_col]/day_in_sec,results_dict_surface['R0']['b2'][y_col],color=linecolor2,linestyle='--', linewidth=linewidth,label=str(round(b2*10**6)))
ax.plot(results_dict_surface['R0']['b3'][x_col]/day_in_sec,results_dict_surface['R0']['b3'][y_col],color=linecolor2,linestyle='-',linewidth=linewidth, label=str(round(b3*10**6)))
xlim_F=([round(min(results_dict_surface['R0']['b0'][x_col]/day_in_sec)),round(max(results_dict_surface['R0']['b0'][x_col]/day_in_sec))])
ymin_F=np.nanmin([np.nanmin(results_dict_surface['R0']['b0'][y_col])])
ylim_F=[ymin_F,fi_rho_initial_gcm3]
ax.set_xlim(xlim_F)
ax.set_ylim(ylim_F)
ax.set_xlabel('Time(days)')
ax.set_ylabel(ylabel4plot)
ax.legend(title='Distance to defect (\u03BCm)')
[49]:
<matplotlib.legend.Legend at 0x2a0aaae2610>
[29]:
ylim_F
[29]:
[0.5358775078218901, 1.0]
[20]:
import matplotlib.pyplot as plt
import numpy as np
# Define some constants and variables
linecolor = 'darkred'
linecolor2 = 'orange'
seconds_in_e_year = 365.25 * 24 * 60 * 60
y_col = 'CO2_dens_gcm3'
x_col = 'Time(s)'
twin_col = 'Calculated depths (km)'
xlabel4plot = 'Time(years)'
ylabel4plot = 'CO2 density (g/cm3)'
twinlabel4plot = 'Calculated depth (km)'
linecolor = 'midnightblue'
linecolor2 = 'purple'
linewidth = 0.5
# Create a figure and axes
fig, ax = ax.subplots()
# Plot the data on the primary y-axis
ax.plot(results_dict_surface['R0']['b0'][x_col] / seconds_in_e_year, results_dict_surface['R0']['b0'][y_col], color=linecolor2, linestyle=':', linewidth=linewidth, label=str(round(b0 * 10 ** 6)))
ax.plot(results_dict_surface['R0']['b1'][x_col] / seconds_in_e_year, results_dict_surface['R0']['b1'][y_col], color=linecolor2, linestyle='-.', linewidth=linewidth, label=str(round(b1 * 10 ** 6)))
ax.plot(results_dict_surface['R0']['b2'][x_col] / seconds_in_e_year, results_dict_surface['R0']['b2'][y_col], color=linecolor2, linestyle='--', linewidth=linewidth, label=str(round(b2 * 10 ** 6)))
ax.plot(results_dict_surface['R0']['b3'][x_col] / seconds_in_e_year, results_dict_surface['R0']['b3'][y_col], color=linecolor2, linestyle='-', linewidth=linewidth, label=str(round(b3 * 10 ** 6)))
# Plot the data on the secondary y-axis
ax.plot(results_dict_surface['R0_2']['b4'][x_col] / seconds_in_e_year, results_dict_surface['R0_2']['b4'][y_col], color=linecolor, linestyle=':', linewidth=linewidth)
ax.plot(results_dict_surface['R0_2']['b5'][x_col] / seconds_in_e_year, results_dict_surface['R0_2']['b5'][y_col], color=linecolor, linestyle='-.', linewidth=linewidth)
ax.plot(results_dict_surface['R0_2']['b6'][x_col] / seconds_in_e_year, results_dict_surface['R0_2']['b6'][y_col], color=linecolor, linestyle='--', linewidth=linewidth)
ax.plot(results_dict_surface['R0_2']['b7'][x_col] / seconds_in_e_year, results_dict_surface['R0_2']['b7'][y_col], color=linecolor, linestyle='-', linewidth=linewidth)
ax2 = ax.twinx()
# Set the y-axis limits for both axes
ax.set_ylim([ymin_F, fi_rho_initial_gcm3])
ax2.set_ylim([ymin_F, fi_rho_initial_gcm3])
# Customize axis labels and legends
ax.set_xlabel('Time (years)')
ax.set_ylabel(ylabel4plot)
ax2.set_ylabel('Deviation from Entrapment Pressure (%)')
ax.legend(title='Distance to defect (μm)')
# Show the plot
ax.show()