def calc_velocities(a, b, c): amount_perovskite = a pv = minerals.SLB_2011.mg_fe_perovskite([b, 1.0 - b, 0.0]) fp = minerals.SLB_2011.ferropericlase([c, 1.0 - c]) rock = burnman.Composite( [pv, fp], [amount_perovskite, 1.0 - amount_perovskite]) mat_rho, mat_vp, mat_vs = rock.evaluate( ['density', 'v_phi', 'v_s'], seis_p, temperature) return mat_vp, mat_vs, mat_rho
def invariant(m1, m2, m3, P=5.e9, T=2000.): composition = m1.formula assemblage = burnman.Composite([m1, m2, m3]) assemblage.set_state(P, T) equality_constraints = [('phase_fraction', (m1, 0.0)), ('phase_fraction', (m2, 0.0))] sol, prm = equilibrate(composition, assemblage, equality_constraints, store_iterates=False) return sol.x[0:2]
def eval(uncertain): rock = burnman.Composite([my_perovskite(uncertain)], [1.0]) rock.set_method('slb3') temperature = burnman.geotherm.adiabatic(seis_p, 1900 * uncertain[8], rock) mat_rho, mat_vs, mat_vphi = rock.evaluate(['rho', 'v_s', 'v_phi'], seis_p, temperature) return seis_p, mat_vs, mat_vphi, mat_rho
def univariant(m1, m2, condition_constraints, P=5.e9, T=2000.): composition = m1.formula assemblage = burnman.Composite([m1, m2]) assemblage.set_state(P, T) equality_constraints = [ condition_constraints, ('phase_fraction', (m1, 0.0)) ] sols, prm = equilibrate(composition, assemblage, equality_constraints, store_iterates=False) pressures = np.array([s.x[0] for s in sols]) temperatures = np.array([s.x[1] for s in sols]) return pressures, temperatures
def eval_material(amount_perovskite): rock = burnman.Composite([ SLB_2011_ZSB_2013_mg_fe_perovskite(0.07), other_ferropericlase(0.2) ], [amount_perovskite, 1.0 - amount_perovskite]) rock.set_method(method) temperature = burnman.geotherm.adiabatic(seis_p, 1900, rock) print("Calculations are done for:") rock.debug_print() mat_rho, mat_vs, mat_vphi = rock.evaluate(['rho', 'v_s', 'v_phi'], seis_p, temperature) #[rho_err,vphi_err,vs_err]=burnman.compare_chifactor(mat_vs,mat_vphi,mat_rho,seis_vs,seis_vphi,seis_rho) return seis_p, mat_vs, mat_vphi, mat_rho
def realize_rock(): phase_1_fraction = 0.5 phase_2_fraction = 1.0 - phase_1_fraction # Setup the minerals for the two phase composite. This is different # from how we did it in step 1 and 2. Instead, we create the two phases # then call realize_mineral() on them to perturb their properties. phase_1 = minerals.SLB_2011.stishovite() realize_mineral(phase_1) phase_2 = minerals.SLB_2011.wuestite() realize_mineral(phase_2) # Set up the rock with the now-perturbed mineral phases mantle_rock = burnman.Composite([phase_1, phase_2], [phase_1_fraction, phase_2_fraction]) mantle_rock.set_method('slb3') # Give back the realization of the rock with the perturbed phases. return mantle_rock
def material_error(amount_perovskite): # Define composite using the values rock = burnman.Composite([perovskite, ferropericlase], [amount_perovskite, 1.0 - amount_perovskite]) # Compute velocities mat_rho, mat_vp, mat_vs, mat_vphi, mat_K, mat_G = \ rock.evaluate( ['density', 'v_p', 'v_s', 'v_phi', 'K_S', 'G'], seis_p, temperature) print("Calculations are done for:") rock.debug_print() # Calculate errors [vs_err, vphi_err, rho_err, K_err, G_err] = \ burnman.compare_l2(depths, [mat_vs, mat_vphi, mat_rho, mat_K, mat_G], [ seis_vs, seis_vphi, seis_rho, seis_K, seis_G]) # Normalize errors vs_err = vs_err / np.mean(seis_vs)**2. vphi_err = vphi_err / np.mean(seis_vphi)**2. rho_err = rho_err / np.mean(seis_rho)**2. K_err = K_err / np.mean(seis_K)**2. G_err = G_err / np.mean(seis_G)**2. return vs_err, vphi_err, rho_err, K_err, G_err
def make_rock(): # approximate four component pyrolite model x_pv = 0.67 x_fp = 0.33 pv_fe_num = 0.07 fp_fe_num = 0.2 mg_perovskite = minerals.SLB_2011_ZSB_2013.mg_perovskite() fe_perovskite = minerals.SLB_2011_ZSB_2013.fe_perovskite() wuestite = minerals.SLB_2011_ZSB_2013.wuestite() periclase = minerals.SLB_2011_ZSB_2013.periclase() perovskite = HelperSolidSolution([mg_perovskite, fe_perovskite], [1.0 - pv_fe_num, pv_fe_num]) ferropericlase = HelperSolidSolution([periclase, wuestite], [1.0 - fp_fe_num, fp_fe_num]) pyrolite = burnman.Composite([perovskite, ferropericlase], [x_pv, x_fp]) pyrolite.set_method('slb3') anchor_temperature = 1935.0 return pyrolite, anchor_temperature
pressure = np.linspace(28.0e9, 129e9, 25) # seismic model for comparison: # pick from .prem() .slow() .fast() # (see burnman/seismic.py) seismic_model = burnman.seismic.PREM() depths = seismic_model.depth(pressure) seis_p, seis_rho, seis_vp, seis_vs, seis_vphi = seismic_model.evaluate( ['pressure', 'density', 'v_p', 'v_s', 'v_phi'], depths) # define temperatures temperature_bs = burnman.geotherm.brown_shankland(depths) temperature_an = burnman.geotherm.anderson(depths) # pure perovskite perovskitite = burnman.Composite([perovskite(0.06)], [1.0]) perovskitite.set_method(method) # pure periclase periclasite = burnman.Composite([ferropericlase(0.21)], [1.0]) periclasite.set_method(method) # pyrolite (80% perovskite) pyrolite = burnman.Composite( [perovskite(0.06), ferropericlase(0.21)], [0.834, 0.166]) pyrolite.set_method(method) # preferred mixture? amount_perovskite = 0.92 preferred_mixture = burnman.Composite( [perovskite(0.06), ferropericlase(0.21)],
import burnman from burnman import minerals if __name__ == "__main__": # input variables ### # # specify material amount_perovskite = 0.95 fe_pv = 0.05 fe_pc = 0.2 pv = minerals.SLB_2011.mg_fe_perovskite() pc = minerals.SLB_2011.ferropericlase() pv.set_composition([1. - fe_pv, fe_pv, 0.]) pc.set_composition([1. - fe_pc, fe_pc]) rock = burnman.Composite([pv, pc], [amount_perovskite, 1.0 - amount_perovskite]) # define some pressure range pressures = np.arange(25e9, 130e9, 5e9) depths = burnman.seismic.PREM().depth(pressures) temperature = burnman.geotherm.brown_shankland(depths) # Begin calculating velocities and density as depth print("Calculations are done for:") rock.debug_print() mat_rho, mat_vp, mat_vs, mat_vphi, mat_K, mat_G = \ rock.evaluate( ['density', 'v_p', 'v_s', 'v_phi', 'K_S', 'G'], pressures, temperature) # write to file: output_filename = "example_woutput.txt"
# Set the starting guess compositions for each of the solutions ol.set_composition([0.90, 0.10]) wad.set_composition([0.90, 0.10]) rw.set_composition([0.80, 0.20]) # Initialize the figure that will be used to plot the binary diagram fig = plt.figure() ax = [fig.add_subplot(1, 1, 1)] # Loop over three temperatures for T, color in [(1200., 'blue'), (1600., 'purple'), (2000., 'red')]: # First, we find the compositions of the three phases # at the univariant. composition = {'Fe': 0.2, 'Mg': 1.8, 'Si': 1.0, 'O': 4.0} assemblage = burnman.Composite([ol, wad, rw], [1., 0., 0.]) equality_constraints = [('T', T), ('phase_fraction', (ol, 0.0)), ('phase_fraction', (rw, 0.0))] free_compositional_vectors = [{'Mg': 1., 'Fe': -1.}] sol, prm = equilibrate(composition, assemblage, equality_constraints, free_compositional_vectors, verbose=False) if not sol.success: raise Exception('Could not find solution for the univariant using ' 'provided starting guesses.') # We interrogate the stored copy of the assemblage for the pressure and
stv = SLB_2011.stishovite() coe = SLB_2011.coesite() cpv = SLB_2011.ca_perovskite() if __name__ == "__main__" and run_aluminosilicates: """ Creates the classic aluminosilicate diagram involving univariate reactions between andalusite, sillimanite and kyanite. """ sillimanite = HP_2011_ds62.sill() andalusite = HP_2011_ds62.andalusite() kyanite = HP_2011_ds62.ky() # First, find the pressure and temperature of the invariant point composition = sillimanite.formula assemblage = burnman.Composite([sillimanite, andalusite, kyanite]) equality_constraints = [('phase_fraction', (kyanite, np.array([0.0]))), ('phase_fraction', (sillimanite, np.array([0.0])))] sol, prm = equilibrate(composition, assemblage, equality_constraints) P_inv, T_inv = sol.x[0:2] print(f'invariant point found at {P_inv/1e9:.2f} GPa, {T_inv:.2f} K') # Now we can find the univariant lines which all converge on the # invariant point. In this case, we assume we know which side of each line # is stable (because the aluminosilicate diagram is so ubiquitous in # metamorphic textbooks), but if we didn't know, # we could also calculate which field is stable around the invariant point # by checking to see which had the minimum Gibbs energy. low_pressures = np.linspace(1.e5, P_inv, 21) high_pressures = np.linspace(P_inv, 1.e9, 21)
# ferropericlase solid solution frac_mg = 0.8 frac_fe = 0.2 mg_fe_periclase = minerals.SLB_2011.ferropericlase() mg_fe_periclase.set_composition([frac_mg, frac_fe]) # Ca Perovskite ca_perovskite = minerals.SLB_2011.ca_perovskite() # Pyrolitic composition pyr_pv = 0.75 pyr_fp = 0.18 pyr_capv = 0.07 pyrolitic_mantle = burnman.Composite( [mg_fe_perovskite, mg_fe_periclase, ca_perovskite], [pyr_pv, pyr_fp, pyr_capv]) # Chondritic composition chon_pv = 0.88 chon_fp = 0.05 chon_capv = 0.07 chondritic_mantle = burnman.Composite( [mg_fe_perovskite, mg_fe_periclase, ca_perovskite], [chon_pv, chon_fp, chon_capv]) # To use an adiabatic temperature profile, one needs to pin the temperature at the top of the lower mantle T0 = 1900 #K temperatures = burnman.geotherm.adiabatic(pressures, T0, pyrolitic_mantle) # An alternative is the Brown+Shankland (1981) # geotherm for mapping pressure to temperature.
# BurnMan import burnman from burnman import minerals if __name__ == "__main__": # This is the first actual work done in this example. We define # composite object and name it "rock". A composite is made by # giving burnman.composite a list of minerals and their molar fractions. # Here "rock" has two constituent minerals: it is 80% Mg perovskite # and 20% periclase. More minerals may be added by simply extending # the list given to burnman.composite # For the preset minerals from the SLB_2011, the equation of state # formulation from Stixrude and Lithgow-Bertolloni (2005) will be used. rock = burnman.Composite( [minerals.SLB_2011.mg_perovskite(), minerals.SLB_2011.periclase()], [0.8, 0.2]) # Here we create and load the PREM seismic velocity model, which will be # used for comparison with the seismic velocities of the "rock" composite seismic_model = burnman.seismic.PREM() # We create an array of 20 depths at which we want to evaluate PREM, and then # query the seismic model for the pressure, density, P wave speed, S wave # speed, and bulk sound velocity at those depths depths = np.linspace(750e3, 2800e3, 20) pressure, seis_rho, seis_vp, seis_vs, seis_vphi = seismic_model.evaluate( ['pressure', 'density', 'v_p', 'v_s', 'v_phi'], depths) # Now we get an array of temperatures at which we compute # the seismic properties of the rock. Here we use the Brown+Shankland (1981)
import sys import numpy as np import matplotlib.pyplot as plt # hack to allow scripts to be placed in subdirectories next to burnman: if not os.path.exists('burnman') and os.path.exists('../burnman'): sys.path.insert(1, os.path.abspath('..')) import burnman from burnman import minerals if __name__ == "__main__": # Input composition. amount_perovskite = 0.95 rock = burnman.Composite([ minerals.Murakami_etal_2012.fe_perovskite(), minerals.Murakami_etal_2012.fe_periclase_LS() ], [amount_perovskite, 1.0 - amount_perovskite]) #(min pressure, max pressure, pressure step) seis_p = np.arange(25e9, 125e9, 5e9) # Input adiabat potential temperature T0 = 1500.0 # Now we'll calculate the models by forcing the rock to use a method. The # preset equation of state for the Murakami_etal_2012 minerals is 'slb2' """ 'slb2' (finite-strain 2nd order shear modulus, stixrude and lithgow-bertelloni, 2005) or 'slb3 (finite-strain 3rd order shear modulus, stixrude and lithgow-bertelloni, 2005) or 'mgd3' (mie-gruneisen-debeye 3rd order shear modulus,
import burnman from burnman import minerals if __name__ == "__main__": # To compute seismic velocities and other properties, we need to supply # burnman with a list of minerals (phases) and their molar abundances. Minerals # are classes found in burnman.minerals and are derived from # burnman.minerals.material. # Here are a few ways to define phases and molar_abundances: # Example 1: two simple fixed minerals if True: amount_perovskite = 0.95 rock = burnman.Composite( [minerals.SLB_2011.mg_perovskite(), minerals.SLB_2011.periclase()], [amount_perovskite, 1 - amount_perovskite]) # Example 2: three materials if False: rock = burnman.Composite([ minerals.SLB_2011.fe_perovskite(), minerals.SLB_2011.periclase(), minerals.SLB_2011.stishovite() ], [0.7, 0.2, 0.1]) # Example 3: Mixing solid solutions if False: # Defining a rock using a predefined solid solution from the mineral # library database. preset_solidsolution = minerals.SLB_2011.mg_fe_perovskite()
# BurnMan import burnman from burnman import minerals if __name__ == "__main__": # This is the first actual work done in this example. We define # composite object and name it "rock". A composite is made by # giving burnman.composite a list of minerals and their molar fractions. # Here "rock" has two constituent minerals: it is 80% Mg perovskite # and 20% periclase. More minerals may be added by simply extending # the list given to burnman.composite # For the preset minerals from the SLB_2011, the equation of state # formulation from Stixrude and Lithgow-Bertolloni (2005) will be used. rock = burnman.Composite( [minerals.SLB_2011.mg_perovskite(), minerals.SLB_2011.periclase()], [0.8, 0.2], name='Simple lower mantle assemblage') print(rock) # Here we create and load the PREM seismic velocity model, which will be # used for comparison with the seismic velocities of the "rock" composite seismic_model = burnman.seismic.PREM() # We create an array of 20 depths at which we want to evaluate PREM, and then # query the seismic model for the pressure, density, P wave speed, S wave # speed, and bulk sound velocity at those depths depths = np.linspace(750e3, 2800e3, 20) pressure, seis_rho, seis_vp, seis_vs, seis_vphi = seismic_model.evaluate( ['pressure', 'density', 'v_p', 'v_s', 'v_phi'], depths)
# In BurnMan, composite materials are those made up of a mechanical # mixture of other materials. Those materials could be minerals, # solutions or other composites. # Initialising a composite material is easy; first initialise all the # material objects you want to add to the composite, and then call the # constructor for the Composite class. # The following lines do this for a mixture of bridgmanite, # ferropericlase and Ca-perovskite. bdg = burnman.minerals.SLB_2011.mg_fe_bridgmanite() fper = burnman.minerals.SLB_2011.ferropericlase() cpv = burnman.minerals.SLB_2011.ca_perovskite() rock = burnman.Composite([bdg, fper, cpv], fractions=[0.7, 0.2, 0.1], fraction_type='molar', name='lower mantle assemblage') # The fractions and fraction_type arguments are optional. # Some methods are immediately available to us. For example, we can # print the endmembers of all the phases. print('Names of endmembers in composite material:') for name in rock.endmember_names: print(name) # We can also print a list of the potential elements in the composite: print('Elements which might be in the composite:') print(rock.elements) # and a stoichiometric array
stixrude and lithgow-bertelloni, 2005) or 'slb3 (finite-strain 3rd order shear modulus, stixrude and lithgow-bertelloni, 2005) or 'mgd3' (mie-gruneisen-debeye 3rd order shear modulus, matas et al. 2007) or 'mgd2' (mie-gruneisen-debeye 2nd order shear modulus, matas et al. 2007) or 'bm2' (birch-murnaghan 2nd order, if you choose to ignore temperature (your choice in geotherm will not matter in this case)) or 'bm3' (birch-murnaghan 3rd order, if you choose to ignore temperature (your choice in geotherm will not matter in this case))""" amount_perovskite = 0.6 rock = burnman.Composite( [minerals.SLB_2011.mg_perovskite(), minerals.SLB_2011.wuestite()], [amount_perovskite, 1.0 - amount_perovskite]) perovskitite = burnman.Composite([minerals.SLB_2011.mg_perovskite()], [1.0]) periclasite = burnman.Composite([minerals.SLB_2011.wuestite()], [1.0]) # seismic model for comparison: # pick from .prem() .slow() .fast() (see burnman/seismic.py) seismic_model = burnman.seismic.PREM() # set on how many depth slices the computations should be done number_of_points = 20 # we will do our computation and comparison at the following depth values: depths = np.linspace(700e3, 2800e3, number_of_points) # alternatively, we could use the values where prem is defined:
For our simplified mantle model, consider a three element model, with Mg, Si, and O. This will make a mantle with magnesium perovskite (MgSiO_3) and periclase (MgO). We can replace minerals.SLB_2011.stishovite() and minerals.SLB_2011.wuestite() with minerals.SLB_2011.mg_perovskite() and minerals.SLB_2011.periclase() and play with the relative fraction of the two phases. """ # ---------------------------------------------------------# # ------------- MAKE MODIFICATIONS HERE -------------------# # ---------------------------------------------------------# phase_1_fraction = 0.5 phase_2_fraction = 1.0 - phase_1_fraction rock = burnman.Composite( [minerals.SLB_2011.stishovite(), minerals.SLB_2011.wuestite()], [phase_1_fraction, phase_2_fraction]) # ---------------------------------------------------------# # ---------------------------------------------------------# # ---------------------------------------------------------# # At this point we want to tell the rock which equation of state to use for # its thermoelastic calculations. In general, we recommend the 'slb3' # equation of state as the most self-consistent model. The parameters from # the SLB_2011 mineral library are fit using this model. rock.set_method('slb3') # Here is the step which does the heavy lifting. rock.evaluate # sets the state of the rock at each of the pressures and temperatures defined, # then calculates each requested material phase averaging over the different phases. density, vp, vs = rock.evaluate(
if __name__ == "__main__": # Two examples available example_layer = True example_planet = True # First example: replacing the lower mantle with a composition from BurnMan if example_layer: modelname = 'perovskitic_mantle' # This is the first actual work done in this example. We define # composite object and name it "rock". mg_fe_perovskite = minerals.SLB_2011.mg_fe_perovskite() mg_fe_perovskite.set_composition( [0.9, 0.1, 0]) # frac_mg, frac_fe, frac_al rock = burnman.Composite([mg_fe_perovskite], [1.]) # We create an array of 20 depths at which we want to evaluate the # layer at depths = np.linspace(2890e3, 670e3, 20) # Here we define the lower mantle as a Layer(). The layer needs various # parameters to set a depth array and radius array. lower_mantle = burnman.Layer( name='Perovskitic Lower Mantle', radii=6371.e3 - depths) # Here we set the composition of the layer as the above defined 'rock'. lower_mantle.set_material(rock) # Now we set the temperature mode of the layer. # Here we use an adiabatic temperature and set the temperature at the # top of the layer
print('Site occupancies for all endmembers:') for string in strs: print(string) """ Part 2: Composites """ print('\n\nComposites are also constrained by linear equalities and ' 'inequalities. Here, we demonstrate how BurnMan can take a ' 'composite and a bulk composition, and simplify the composite so ' 'that it only contains endmembers which can have non-zero ' 'quantities.') gt = SLB_2011.garnet() ol = SLB_2011.mg_fe_olivine() assemblage = burnman.Composite([gt, ol]) composition = {'Fe': 2, 'Mg': 18, 'Si': 15, 'O': 50} print('\nThe starting assemblage includes NCFMAS garnet and FMS olivine.') print(f'Starting composition: {formula_to_string(composition)}') new_assemblage = simplify_composite_with_composition( assemblage, composition) if new_assemblage is not assemblage: print('The simplifying function has returned a modified assemblage.') old_polytope = composite_polytope(assemblage, composition, return_fractions=True) new_polytope = composite_polytope(new_assemblage, composition, return_fractions=True)
stixrude and lithgow-bertelloni, 2005) or 'slb3 (finite-strain 3rd order shear modulus, stixrude and lithgow-bertelloni, 2005) or 'mgd3' (mie-gruneisen-debeye 3rd order shear modulus, matas et al. 2007) or 'mgd2' (mie-gruneisen-debeye 2nd order shear modulus, matas et al. 2007) or 'bm2' (birch-murnaghan 2nd order, if you choose to ignore temperature (your choice in geotherm will not matter in this case)) or 'bm3' (birch-murnaghan 3rd order, if you choose to ignore temperature (your choice in geotherm will not matter in this case))""" amount_perovskite = 0.6 rock = burnman.Composite( [minerals.SLB_2011.mg_perovskite(), minerals.SLB_2011.periclase()], [amount_perovskite, 1.0 - amount_perovskite]) perovskitite = minerals.SLB_2011.mg_perovskite() periclasite = minerals.SLB_2011.periclase() # seismic model for comparison: # pick from .prem() .slow() .fast() (see burnman/seismic.py) seismic_model = burnman.seismic.PREM() # set on how many depth slices the computations should be done number_of_points = 20 # we will do our computation and comparison at the following depth values: depths = np.linspace(700e3, 2800e3, number_of_points) # alternatively, we could use the values where prem is defined: # depths = seismic_model.internal_depth_list(mindepth=700.e3,