Example #1
0
def crf_generic(calibval=None, sample=sample_class.Sample({}), bounds={}):
    comp = sample.get_composition(units='wtpt_oxides')
    testresults = []
    for ox in sfvfCompRange:
        testresults.append(comp[ox] >= bounds[ox][0])
        testresults.append(comp[ox] <= bounds[ox][1])
    return all(testresults)
Example #2
0
def crf_CarbonComp(calibval=None, sample=sample_class.Sample({})):
    comp = sample.get_composition(units='wtpt_oxides')

    test_results = []
    for ox in carboncomprange.keys():
        test_results.append(comp[ox] >= carboncomprange[ox][0]
                            and comp[ox] <= carboncomprange[ox][1])

    return all(test_results)
Example #3
0
def crf_MixedComp(calibval=None, sample=sample_class.Sample({})):
    comp = sample.get_composition(units='wtpt_oxides')

    test_results = []
    for ox in carboncomprange.keys():
        test_results.append(
            comp[ox] >= np.min([watercomprange[ox][0], carboncomprange[ox][0]])
        )
        test_results.append(
            comp[ox] <= np.max([watercomprange[ox][1], carboncomprange[ox][1]])
        )

    return all(test_results)
Example #4
0
def test():
    """
    This is a set of tests for the module, firstly to ensure all of the functions that should run, do run.
    Secondly, the output can be used to check the module reproduces the results in each of the manuscripts
    describing the models.
    """

    sample_comp = {'SiO2':47.95,
                 'TiO2':1.67,
                 'Al2O3':17.32,
                 'FeO':10.24,
                 'Fe2O3':0.1,
                 'MgO':5.76,
                 'CaO':10.93,
                 'Na2O':3.45,
                 'K2O':1.99,
                 'P2O5':0.51,
                 'MnO':0.1,
                 'CO2':0.08,
                 'H2O':4.0}

    test_sample = sample_class.Sample(sample_comp)

    test_pressure = 2000.0
    test_temperature = 1473.15
    test_pressure_list = [1000.0,2000.0,5000.0]
    test_isopleth_list = [0.0,0.5,1.0]


    print("\n================================\n= MAGMASATPLUS TESTING ROUTINE =\n================================")

    print("\n This routine will check that key methods run using typical values of variables. \
The routine does not check that the results are correct (though this may be obvious from the outputs),\
nor does it check every possible iteration of methods and input types. It will check that an update hasn't \
COMPLETELY broken the module.")

    for i, model_name in zip(range(len(models.default_models)),list(models.default_models.keys())):
        print("\nTesting model {:d} of {:d}: {:s}".format(i+1,len(models.default_models),model_name))

        ### calculate_dissolved_volatiles
        model = models.default_models[model_name]
        print("Model contains "+" ".join(model.volatile_species))

        print("Testing calculate_dissolved_volatiles method...")

        if len(model.volatile_species) == 1:
            dissolved = model.calculate_dissolved_volatiles(pressure=test_pressure,temperature=test_temperature,
                                                            sample=test_sample)
        else:
            X_fluid = 1.0/len(model.volatile_species)
            X_fluid = tuple(X_fluid for x in range(len(model.volatile_species)))
            print("Setting X_fluid to "+str(X_fluid))
            dissolved = model.calculate_dissolved_volatiles(pressure=test_pressure,temperature=test_temperature,
                                                            sample=test_sample,X_fluid=X_fluid)

        if len(model.volatile_species) == 1:
            print("  {:s} solubility at {:.0f} bars and {:.0f} K is {:.3f} wt%".format(model.volatile_species[0],
                                                                                     test_pressure,test_temperature,
                                                                                     dissolved))
        else:
            for i,volatile in zip(range(len(model.volatile_species)),model.volatile_species):
                print("  {:s} solubility at {:.0f} bars and {:.0f} K is {:.3f} wt%".format(volatile,
                                                                                         test_pressure,test_temperature,
                                                                                         dissolved[i]))

        print("Testing calculate_dissolved_volatiles class interface...")
        if len(model.volatile_species) == 1:
            result = calculate_dissolved_volatiles(sample=test_sample,pressure=test_pressure,
                                                   temperature=test_temperature,model=model_name)
        else:
            result = calculate_dissolved_volatiles(sample=test_sample,pressure=test_pressure,
                                                   temperature=test_temperature,model=model_name,
                                                   X_fluid=X_fluid)

        if len(model.volatile_species) == 1:
            print("  {:s} solubility at {:.0f} bars and {:.0f} K is {:.3f} wt%".format(model.volatile_species[0],
                                                                                     test_pressure,test_temperature,
                                                                                     result.result))
        else:
            for volatile in model.volatile_species:
                print("  {:s} solubility at {:.0f} bars and {:.0f} K is {:.3f} wt%".format(volatile,
                                                                                         test_pressure,test_temperature,
                                                                                         result.result[volatile+'_liq']))



        ### calculate_saturation_pressure
        print("Testing calculate_saturation_pressure method...")
        satP = model.calculate_saturation_pressure(sample=test_sample,temperature=test_temperature)
        if len(model.volatile_species) == 1:
            print("  A concentration of {:.2f} wt% {:s} is saturated at {:.0f} bars at {:.0f} K".format(test_sample.get_composition(model.volatile_species[0]),
                                                                                                       model.volatile_species[0],satP,
                                                                                                       test_temperature))
        else:
            concstr = ""
            for volatile in model.volatile_species:
                concstr += "{:.2f}".format(test_sample.get_composition(volatile))
                concstr += " wt% "
                concstr += volatile
                concstr += ", "
            print("  Concentrations of "+concstr[:-1]+" are saturated at {:.0f} bars at {:.0f} K".format(satP,test_temperature))

        print("Testing calculate_saturation_pressure class interface...")
        satP = calculate_saturation_pressure(model=model_name,sample=test_sample,temperature=test_temperature).result
        if len(model.volatile_species) == 1:
            print("  A concentration of {:.2f} wt% {:s} is saturated at {:.0f} bars at {:.0f} K".format(test_sample.get_composition(model.volatile_species[0]),
                                                                                                       model.volatile_species[0],satP,
                                                                                                       test_temperature))
        else:
            concstr = ""
            for volatile in model.volatile_species:
                concstr += "{:.2f}".format(test_sample.get_composition(volatile))
                concstr += " wt% "
                concstr += volatile
                concstr += ", "
            print("  Concentrations of "+concstr[:-1]+" are saturated at {:.0f} bars at {:.0f} K".format(satP,test_temperature))


        ### calculate_equilibrium_fluid_comp
        print("Testing calculate_equilibrium_fluid_comp method...")
        fluid = model.calculate_equilibrium_fluid_comp(sample=test_sample,temperature=test_temperature,pressure=test_pressure)

        if len(model.volatile_species) == 1:
            print("  A mole fraction of {:.2f} of {:s} is present in the fluid.".format(fluid,model.volatile_species[0]))
        else:
            fluidstr = ""
            for i,volatile in zip(range(len(model.volatile_species)),model.volatile_species):
                fluidstr += "{:.2f}".format(fluid[model.volatile_species[i]])
                fluidstr += " "
                fluidstr += volatile
                fluidstr += ", "
            print("  Mole fractions of "+fluidstr +"are present in the fluid.")
            if np.sum(list(fluid.values())) != 0.0 and np.sum(list(fluid.values())) != 1.0:
                print("  WARNING: MOLE FRACTIONS DO NOT SUM TO 1.0")

        print("Testing calculate_equilibrium_fluid_comp class interface...")
        fluid = model.calculate_equilibrium_fluid_comp(model=model_name,sample=test_sample,
                                                       temperature=test_temperature,pressure=test_pressure)
        if len(model.volatile_species) == 1:
            print("  A mole fraction of {:.2f} of {:s} is present in the fluid.".format(fluid,model.volatile_species[0]))
        else:
            fluidstr = ""
            for i,volatile in zip(range(len(model.volatile_species)),model.volatile_species):
                fluidstr += "{:.2f}".format(fluid[model.volatile_species[i]])
                fluidstr += " "
                fluidstr += volatile
                fluidstr += ", "
            print("  Mole fractions of "+fluidstr +"are present in the fluid.")
            if np.sum(list(fluid.values())) != 0.0 and np.sum(list(fluid.values())) != 1.0:
                print("  WARNING: MOLE FRACTIONS DO NOT SUM TO 1.0")

        ### calculate_isobars_and_isopleths
        if len(model.volatile_species) > 1:
            print("Testing calculate_isobars_and_isopleths method...")
            isobars, isopleths = model.calculate_isobars_and_isopleths(pressure_list=test_pressure_list,
                                                                       isopleth_list=test_isopleth_list,
                                                                       sample=test_sample,
                                                                       temperature=test_temperature)
            print("Isobars:")
            print(isobars)
            print("\nIsopleths:")
            print(isopleths)

            print("Testing calculate_isobars_and_isopleths class interface...")
            isobars, isopleths = calculate_isobars_and_isopleths(model=model_name,pressure_list=test_pressure_list,
                                                                 isopleth_list=test_isopleth_list,
                                                                 sample=test_sample,
                                                                 temperature=test_temperature).result
            print("Isobars:")
            print(isobars)
            print("\nIsopleths:")
            print(isopleths)

        ### calculate_degassing_path
        test_sample = Sample(sample_comp)
        if len(model.volatile_species) > 1:
            print("Testing calculate_degassing_path method...")
            degassing = model.calculate_degassing_path(sample=test_sample,temperature=test_temperature)
            print("  Degassing path:")
            print(degassing)

            print("Testing calculate_degassing_path class interface...")
            degassing = calculate_degassing_path(model=model_name,sample=test_sample,
                                                        temperature=test_temperature).result
            print("  Degassing path:")
            print(degassing)


    print("\nTesting routine complete.\n")
Example #5
0
def crf_sfvf(calibval=None, sample=sample_class.Sample({})):
    return crf_generic(calibval, sample, sfvfCompRange)
Example #6
0
    def calculate_degassing_path(self,
                                 sample,
                                 temperature,
                                 pressure='saturation',
                                 fractionate_vapor=0.0,
                                 init_vapor=0.0,
                                 steps=50,
                                 **kwargs):
        """
        Calculates degassing path for one sample

        Parameters
        ----------
        sample:     Sample class
            Magma major element composition.

            Legacy info follows, might still be useful?
            If pulling from an uploaded file
            with data for many samples, first call get_sample_composition() to get the sample
            desired. Then pass the result into this function.

        temperature: float
            Temperature at which to calculate degassing paths, in degrees C.

        pressure: float
            OPTIONAL. The perssure at which to begin the degassing calculations. Default value is
            'saturation', which runs the calculation with the initial pressure at the saturation
            pressure. If a pressure greater than the saturation pressure is input, the calculation
            will start at saturation, since this is the first pressure at which any degassing will
            occur.

        fractionate_vapor: float
            OPTIONAL. Proportion of vapor removed at each pressure step.
            Default value is 0.0 (completely closed-system degassing). Specifies the type of
            calculation performed, either closed system (0.0) or open system (1.0) degassing. If
            any value between <1.0 is chosen, user can also specify the 'init_vapor' argument
            (see below). A value in between 0 and 1 will remove that proportion of vapor at each
            step. For example, for a value of 0.2, the calculation will remove 20% of the vapor
            and retain 80% of the vapor at each pressure step.

        init_vapor: float
            OPTIONAL. Default value is 0.0. Specifies the amount of vapor (in wt%) coexisting
            with the melt before degassing.

        steps: int
            OPTIONAL. Default value is 50. Specifies the number of steps in pressure space at
            which dissolved volatile concentrations are calculated.

        Returns
        -------
        pandas DataFrame object

        """
        sys.stdout.write("Finding saturation point... "
                         )  # print start of calculation to terminal
        _sample = self.preprocess_sample(sample)

        # Normalize sample composition
        _normed_comp = _sample.get_composition(normalization='standard')
        _sample.change_composition(_normed_comp)
        _sample_dict = _sample.get_composition()

        # ------ RESET MELTS ------ #
        # MELTS needs to be reloaded here. If an unfeasible composition gets set inside of MELTS,
        # which can happen when running open-system degassing path calcs, the following calls to
        # MELTS will fail. This prevents that from happening.
        melts = equilibrate.MELTSmodel('1.2.0')

        # Suppress phases not required in the melts simulation
        phases = melts.get_phase_names()
        for phase in phases:
            melts.set_phase_inclusion_status({phase: False})
        melts.set_phase_inclusion_status({'Fluid': True, 'Liquid': True})

        melts.set_bulk_composition(_sample_dict)
        # ------------------------- #

        # Get saturation pressure
        data = self.calculate_saturation_pressure(sample=_sample,
                                                  temperature=temperature,
                                                  verbose=True)

        if pressure == 'saturation' or pressure >= data["SaturationP_bars"]:
            SatP_MPa = data["SaturationP_bars"] / 10.0
        else:
            SatP_MPa = pressure / 10.0

        # convert number of steps to step size
        MPa_step = SatP_MPa / steps
        if MPa_step < 1:
            MPa_step = 1

        P_array = np.arange(1.0, SatP_MPa, MPa_step)
        P_array = -np.sort(-P_array)
        fl_wtper = data["FluidProportion_wt"]

        while fl_wtper <= init_vapor:
            output = melts.equilibrate_tp(temperature,
                                          SatP_MPa,
                                          initialize=True)
            (status, temperature, p, xmlout) = output[0]
            fl_mass = melts.get_mass_of_phase(xmlout, phase_name='Fluid')
            liq_mass = melts.get_mass_of_phase(xmlout, phase_name='Liquid')
            fl_comp = melts.get_composition_of_phase(xmlout,
                                                     phase_name='Fluid')
            fl_wtper = 100 * fl_mass / (fl_mass + liq_mass)
            try:
                _sample_dict["H2O"] += fl_comp["H2O"] * 0.0005
            except Exception:
                _sample_dict["H2O"] = _sample_dict["H2O"] * 1.1
            try:
                _sample_dict["CO2"] += fl_comp["CO2"] * 0.0005
            except Exception:
                _sample_dict["CO2"] = _sample_dict["CO2"] * 1.1
            _sample = sample_class.Sample(_sample_dict)
            _sample_dict = _sample.get_composition(normalization='standard',
                                                   units="wtpt_oxides")
            melts.set_bulk_composition(_sample_dict)  # reset MELTS

        pressure = []
        H2Oliq = []
        CO2liq = []
        H2Ofl = []
        CO2fl = []
        fluid_wtper = []
        iterno = 0
        sys.stdout.write(
            "\r")  # carriage return to remove previous printed text
        for i in P_array:
            # Handle status_bar
            iterno += 1
            percent = iterno / len(P_array)
            batchfile.status_bar.status_bar(
                percent, btext="Calculating degassing path...")

            fl_mass = 0.0
            melts.set_bulk_composition(_sample_dict)
            output = melts.equilibrate_tp(temperature, i, initialize=True)
            (status, temperature, p, xmlout) = output[0]
            liq_comp = melts.get_composition_of_phase(xmlout,
                                                      phase_name='Liquid')
            fl_comp = melts.get_composition_of_phase(xmlout,
                                                     phase_name='Fluid',
                                                     mode='component')
            liq_mass = melts.get_mass_of_phase(xmlout, phase_name='Liquid')
            fl_mass = melts.get_mass_of_phase(xmlout, phase_name='Fluid')
            fl_wtper = 100 * fl_mass / (fl_mass + liq_mass)

            if fl_mass > 0:
                pressure.append(p * 10.0)
                try:
                    H2Oliq.append(liq_comp["H2O"])
                except Exception:
                    H2Oliq.append(0)
                try:
                    CO2liq.append(liq_comp["CO2"])
                except Exception:
                    CO2liq.append(0)
                try:
                    H2Ofl.append(fl_comp["Water"])
                except Exception:
                    H2Ofl.append(0)
                try:
                    CO2fl.append(fl_comp["Carbon Dioxide"])
                except Exception:
                    CO2fl.append(0)
                fluid_wtper.append(fl_wtper)

                try:
                    _sample_dict["H2O"] = (
                        liq_comp["H2O"] +
                        (_sample_dict["H2O"] - liq_comp["H2O"]) *
                        (1.0 - fractionate_vapor))
                except Exception:
                    _sample_dict["H2O"] = 0
                try:
                    _sample_dict["CO2"] = (
                        liq_comp["CO2"] +
                        (_sample_dict["CO2"] - liq_comp["CO2"]) *
                        (1.0 - fractionate_vapor))
                except Exception:
                    _sample_dict["CO2"] = 0
            _sample = sample_class.Sample(_sample_dict)
            _sample_dict = _sample.get_composition(normalization='standard',
                                                   units='wtpt_oxides')

        melts.set_bulk_composition(
            self.bulk_comp_orig)  # this needs to be reset always!
        open_degassing_df = pd.DataFrame(
            list(zip(pressure, H2Oliq, CO2liq, H2Ofl, CO2fl, fluid_wtper)),
            columns=[
                'Pressure_bars', 'H2O_liq', 'CO2_liq', 'XH2O_fl', 'XCO2_fl',
                'FluidProportion_wt'
            ])

        open_degassing_df = open_degassing_df[
            open_degassing_df.CO2_liq > 0.000001]
        open_degassing_df = open_degassing_df[
            open_degassing_df.H2O_liq > 0.000001]

        return open_degassing_df