Source code for Thermobar.viscosity

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from functools import partial
import inspect
import warnings as w
import numbers
from pathlib import Path
Thermobar_dir=Path(__file__).parent
from Thermobar.import_export import *
from Thermobar.core import *

[docs] def convert_F2O_to_F_ppm(F2O_wt=None): """ Converts from F2O in wt% to F in ppm""" F2O_mass=53.99621 F_mass=18.998403 F_calc=2*F_mass*(F2O_wt/F2O_mass) return F_calc*10000
[docs] def convert_F_to_F2O(F_ppm=None): """ Converts from F in ppm to F2O in wt%""" F=F_ppm/10000 F2O_mass=53.99621 F_mass=18.998403 F2O_calc=(F/F_mass)*0.5*F2O_mass return F2O_calc
# def normalize_anhydrous_to_100_incF_mol_prop(liq_comps, F2O_content=0): # ''' # Calculates normalized hydrous molar proportions following the normalization scheme # of Giordano et al. (2008) in their excel spreadsheet. # # Parameters # ------- # # liq_comps: pandas.DataFrame # liquid compositions with column headings SiO2_Liq, MgO_Liq etc. # # F2O_content: int, pd.series # F2O content of the liquid (wt%), by default is set at zero. # # Returns # ------- # pd.DataFrame # column headings of the form Liq_mol_frac_hyd, ... # ''' # # # if isinstance(F2O_content, pd.Series): # F2O_content.fillna(0, inplace=True) # liq_comps_C=liq_comps.copy() # liq_comps_C['NiO_Liq']=0 # liq_comps_C['Cr2O3_Liq']=0 # liq_comps_C['CoO_Liq']=0 # liq_comps_C['CO2_Liq']=0 # # liq_comps_sum=(liq_comps_C['SiO2_Liq']+liq_comps_C['TiO2_Liq']+ # liq_comps_C['Al2O3_Liq']+liq_comps_C['FeOt_Liq']+liq_comps_C['MnO_Liq']+liq_comps_C['MgO_Liq']+ # liq_comps_C['CaO_Liq']+liq_comps_C['Na2O_Liq']+liq_comps_C['K2O_Liq']+ # liq_comps_C['P2O5_Liq']+F2O_content) # Norm_Factor=(100-liq_comps_C['H2O_Liq'])/(liq_comps_sum) # # # if 'Sample_ID_Liq' in liq_comps_C.columns: # liq_comps_C_nolabel= liq_comps_C.drop('Sample_ID_Liq', axis=1) # else: # liq_comps_C_nolabel=liq_comps_C # liq_comps_c_N=liq_comps_C_nolabel.multiply(Norm_Factor, axis=0) # # liq_comps_c_N=liq_comps_C_nolabel.multiply(Norm_Factor, axis=0) # # Don't normalize water # liq_comps_c_N['H2O_Liq']=liq_comps_C['H2O_Liq'] # liq_comps_N_mol=calculate_hydrous_mol_proportions_liquid(liq_comps=liq_comps_c_N) # # liq_comps_N_mol['F2O_Liq_mol_prop_hyd']=F2O_content*Norm_Factor/37.9968 # liq_comps_N_mol['F2O_Liq_mol_prop_hyd'].fillna(0, inplace=True) # mols_sum = 100/(liq_comps_N_mol.sum(axis='columns')) # cat_frac_anhyd = liq_comps_N_mol.multiply(mols_sum, axis='rows') # cat_frac_anhyd.columns = [str(col).replace('mol_prop', 'mol_frac') # for col in cat_frac_anhyd.columns] # # #print(cat_frac_anhyd) # # # return cat_frac_anhyd #mols_sum #liq_comps_N_mol['sum']
[docs] def normalize_anhydrous_to_100_incF_mol_prop(liq_comps, F2O_content=0): """ Simple normalization to 100 wt% anhydrous (Giordano-style). Only sums specified oxide columns; leaves H2O unscaled. """ # List of oxide wt% columns to include in normalization cols_to_sum = [ 'SiO2_Liq','TiO2_Liq','Al2O3_Liq','FeOt_Liq','MnO_Liq','MgO_Liq', 'CaO_Liq','Na2O_Liq','K2O_Liq','Cr2O3_Liq','P2O5_Liq', 'NiO_Liq','CoO_Liq','CO2_Liq' ] df = liq_comps.copy() for c in cols_to_sum + ['H2O_Liq']: if c not in df: df[c] = 0.0 # Allow F2O as scalar or Series if isinstance(F2O_content, pd.Series): F2O = F2O_content.reindex(df.index).fillna(0) else: F2O = float(F2O_content) # --- Compute normalization factor --- sum_anhydrous = df[cols_to_sum].sum(axis=1) + F2O norm_factor = (100 - df['H2O_Liq']) / sum_anhydrous # --- Apply normalization only to the oxide columns --- df_norm = df.copy() df_norm[cols_to_sum] = df[cols_to_sum].multiply(norm_factor, axis=0) df_norm['H2O_Liq'] = df['H2O_Liq'] # leave water unscaled # --- Convert to molar proportions and then mol fractions --- liq_mol = calculate_hydrous_mol_proportions_liquid(df_norm) liq_mol['F2O_Liq_mol_prop_hyd'] = (F2O * norm_factor) / 37.9968 mol_sum = liq_mol.sum(axis=1) cat_frac_anhyd = liq_mol.multiply(100 / mol_sum, axis=0) cat_frac_anhyd.columns = [ c.replace('mol_prop', 'mol_frac') for c in cat_frac_anhyd.columns ] return cat_frac_anhyd
[docs] def calculate_viscosity_giordano_2008(liq_comps, T=None, T_K=None, H2O_Liq=None, F2O_content=0): ''' Calculates viscosity parameters A, B, C from Giordano et al. 2008. If a temperature is supplied, calculates viscosity. Parameters ------- liq_comps: pandas.DataFrame liquid compositions with column headings SiO2_Liq, MgO_Liq etc. F2O_content: int, pd.series F2O content of the liquid (wt%), by default is set at zero. Optional: T or T_K: int, flt, pd.Series Temperature in Kelvin. If specified, returns viscosity and log viscosity H2O_Liq: int, flt, pd.Series Water content in wt%, overwrites that in input spreadsheet Returns ------- pd.DataFrame viscosity parameters, viscosity (if T supplied), as well user-entered liquid composition. ''' if T_K is not None: T=T_K liq_comps_c=liq_comps.copy() if H2O_Liq is not None: liq_comps_c['H2O_Liq']=H2O_Liq print('Water content from input overridden') mol_percents=normalize_anhydrous_to_100_incF_mol_prop(liq_comps=liq_comps_c, F2O_content=F2O_content) V = mol_percents["H2O_Liq_mol_frac_hyd"] + mol_percents["F2O_Liq_mol_frac_hyd"] TA = mol_percents["TiO2_Liq_mol_frac_hyd"] + mol_percents["Al2O3_Liq_mol_frac_hyd"] FM = mol_percents["FeOt_Liq_mol_frac_hyd"] + mol_percents["MnO_Liq_mol_frac_hyd"] + mol_percents["MgO_Liq_mol_frac_hyd"] NK = mol_percents["Na2O_Liq_mol_frac_hyd"] + mol_percents["K2O_Liq_mol_frac_hyd"] b1 = 159.5600 * (mol_percents["SiO2_Liq_mol_frac_hyd"] + mol_percents["TiO2_Liq_mol_frac_hyd"]) b2 = -173.34 * mol_percents["Al2O3_Liq_mol_frac_hyd"] b3 = 72.13 * (mol_percents["FeOt_Liq_mol_frac_hyd"] + mol_percents["MnO_Liq_mol_frac_hyd"] + mol_percents["P2O5_Liq_mol_frac_hyd"]) b4 = 75.69 * mol_percents["MgO_Liq_mol_frac_hyd"] b5 = -38.98 * mol_percents["CaO_Liq_mol_frac_hyd"] b6 = -84.08 * (mol_percents["Na2O_Liq_mol_frac_hyd"] + V) b7 = 141.54 * (V + np.log(1 + mol_percents["H2O_Liq_mol_frac_hyd"])) b11 = -2.43 * ((mol_percents["SiO2_Liq_mol_frac_hyd"] + mol_percents["TiO2_Liq_mol_frac_hyd"]) * FM) b12 = (-0.91 * ((mol_percents["SiO2_Liq_mol_frac_hyd"] + TA + mol_percents["P2O5_Liq_mol_frac_hyd"]) * (NK + mol_percents["H2O_Liq_mol_frac_hyd"]))) b13 = 17.62 * (mol_percents["Al2O3_Liq_mol_frac_hyd"] * NK) c1 = 2.75 * mol_percents["SiO2_Liq_mol_frac_hyd"] c2 = 15.72 * TA c3 = 8.32 * FM c4 = 10.20 * mol_percents["CaO_Liq_mol_frac_hyd"] c5 = -12.29 * NK c6 = -99.54 * np.log(1 + V) c11 = 0.30 * ((mol_percents["Al2O3_Liq_mol_frac_hyd"] + FM + mol_percents["CaO_Liq_mol_frac_hyd"] - mol_percents["P2O5_Liq_mol_frac_hyd"]) * (NK + V)) df_B = pd.DataFrame(np.array([b1,b2,b3,b4,b5,b6,b7,b11,b12,b13]).T, columns = ['b1','b2','b3','b4','b5','b6','b7','b11','b12','b13'] ) df_C = pd.DataFrame(np.array([c1,c2,c3,c4,c5,c6,c11]).T, columns = ['c1','c2','c3','c4','c5','c6','c11'] ) df_params = pd.concat([df_B, df_C],axis = 'columns') A = -4.55 B = df_params.loc[:,'b1':'b13'].sum(axis = 'columns') C = df_params.loc[:,'c1':'c11'].sum(axis = 'columns') liq_comps_c.insert(0, 'A', A) liq_comps_c.insert(1, 'B', B.values) liq_comps_c.insert(2, 'C', C.values) if T is not None: df_params['T_K'] = T logn_melt = A + (B / (df_params['T_K'] - C)) n_melt=10**(logn_melt) #df_params['logn_melt'] = logn_melt liq_comps_c.insert(0, 'T_K', T) liq_comps_c.insert(0, 'logn_melt', logn_melt.values) liq_comps_c.insert(0, 'n_melt', n_melt.values) combo=pd.concat([liq_comps_c, df_params], axis=1) return combo