Beispiel #1
0
def test_shift_reference_state_model_contribs_take_effect():
    """Shift reference state with contrib_mods set adds contributions to the pure elements."""
    TDB = """
     ELEMENT A    GRAPHITE                   12.011     1054.0      5.7423 !
     ELEMENT B   BCC_A2                     55.847     4489.0     27.2797 !
     TYPE_DEFINITION % SEQ * !
     PHASE TEST % 1 1 !
     CONSTITUENT TEST : A,B: !
    """
    dbf = Database(TDB)
    comps = ['A', 'B']
    phase = 'TEST'
    m = Model(dbf, comps, phase)
    refstates = [ReferenceState('A', phase), ReferenceState('B', phase)]
    m.shift_reference_state(refstates, dbf)

    statevars = {
        v.T: 298.15,
        v.P: 101325,
        v.SiteFraction(phase, 0, 'A'): 0.5,
        v.SiteFraction(phase, 0, 'B'): 0.5,
    }

    # ideal mixing should be present for GMR
    idmix_val = 2 * 0.5 * np.log(0.5) * v.R * 298.15
    check_output(m, statevars, 'GMR', idmix_val)

    # shifting the reference state, adding an excess contribution
    # should see that addition in the output
    m.shift_reference_state(refstates, dbf, contrib_mods={'xsmix': S(1000.0)})
    # each pure element contribution is has xsmix changed from 0 to 1
    # At x=0.5, the reference xsmix energy is added to by 0.5*1000.0, which is
    # then subtracted out of the GM energy
    check_output(m, statevars, 'GMR', idmix_val - 1000.0)
Beispiel #2
0
def test_non_zero_reference_mixing_enthalpy_for_va_interaction():
    """The referenced mixing enthalpy for a Model with a VA interaction parameter is non-zero."""
    m = Model(VA_INTERACTION_DBF, ['AL', 'VA'], 'FCC_A1')
    refstates = [ReferenceState('AL', 'FCC_A1')]
    m.shift_reference_state(refstates, VA_INTERACTION_DBF)

    statevars_pure = {
        v.T: 300,
        v.SiteFraction('FCC_A1', 0, 'AL'): 1,
        v.SiteFraction('FCC_A1', 0, 'VA'): 0,
        v.SiteFraction('FCC_A1', 1, 'VA'): 1
    }
    check_output(m, statevars_pure, 'GMR', 0.0)

    statevars_mix = {
        v.T: 300,
        v.SiteFraction('FCC_A1', 0, 'AL'): 0.5,
        v.SiteFraction('FCC_A1', 0, 'VA'): 0.5,
        v.SiteFraction('FCC_A1', 1, 'VA'): 1
    }
    # 4000.0 * 0.5=2000 +500 # (Y0VA doesn't contribute), but the VA endmember does (not referenced)
    check_output(m, statevars_mix, 'HMR', 2500.0)

    statevars_mix = {
        v.T: 300,
        v.SiteFraction('FCC_A1', 0, 'AL'): 0.5,
        v.SiteFraction('FCC_A1', 0, 'VA'): 0.5,
        v.SiteFraction('FCC_A1', 1, 'VA'): 1
    }
    # 4000.0 * 0.5 (Y0VA doesn't contribute)
    check_output(m, statevars_mix, 'HM_MIX', 2000.0)
Beispiel #3
0
def test_shift_reference_state_model_contribs_take_effect():
    """Shift reference state with contrib_mods set adds contributions to the pure elements."""
    TDB = """
     ELEMENT A    GRAPHITE                   12.011     1054.0      5.7423 !
     ELEMENT B   BCC_A2                     55.847     4489.0     27.2797 !
     TYPE_DEFINITION % SEQ * !
     PHASE TEST % 1 1 !
     CONSTITUENT TEST : A,B: !
    """
    dbf = Database(TDB)
    comps = ['A', 'B']
    phase = 'TEST'
    m = Model(dbf, comps, phase)
    refstates = [ReferenceState('A', phase), ReferenceState('B', phase)]
    m.shift_reference_state(refstates, dbf)

    statevars =  {
        v.T: 298.15, v.P: 101325,
        v.SiteFraction(phase, 0, 'A'): 0.5, v.SiteFraction(phase, 0, 'B'): 0.5,
        }

    # ideal mixing should be present for GMR
    idmix_val = 2*0.5*np.log(0.5)*v.R*298.15
    check_output(m, statevars, 'GMR', idmix_val)

    # shifting the reference state, adding an excess contribution
    # should see that addition in the output
    m.shift_reference_state(refstates, dbf, contrib_mods={'xsmix': S(1000.0)})
    # each pure element contribution is has xsmix changed from 0 to 1
    # At x=0.5, the reference xsmix energy is added to by 0.5*1000.0, which is
    # then subtracted out of the GM energy
    check_output(m, statevars, 'GMR', idmix_val-1000.0)
Beispiel #4
0
def test_reference_energy_of_unary_twostate_einstein_magnetic_is_zero():
    """The referenced energy for the pure elements in a unary Model with twostate and Einstein contributions referenced to that phase is zero."""
    m = Model(FEMN_DBF, ['FE', 'VA'], 'LIQUID')
    statevars = {v.T: 298.15, v.SiteFraction('LIQUID', 0, 'FE'): 1, v.SiteFraction('LIQUID', 1, 'VA'): 1}
    refstates = [ReferenceState(v.Species('FE'), 'LIQUID')]
    m.shift_reference_state(refstates, FEMN_DBF)
    check_output(m, statevars, 'GMR', 0.0)
Beispiel #5
0
def test_reference_energy_for_different_phase():
    """The referenced energy a different phase should be correct."""
    m = Model(ALFE_DBF, ['AL', 'FE', 'VA'], 'AL2FE')
    # formation reference states
    refstates = [ReferenceState('AL', 'FCC_A1'), ReferenceState('FE', 'BCC_A2')]
    m.shift_reference_state(refstates, ALFE_DBF)

    statevars = {v.T: 300, v.SiteFraction('AL2FE', 0, 'AL'): 1, v.SiteFraction('AL2FE', 1, 'FE'): 1}
    check_output(m, statevars, 'GMR', -28732.525)  # Checked in Thermo-Calc
Beispiel #6
0
def test_reference_energy_of_unary_twostate_einstein_magnetic_is_zero():
    """The referenced energy for the pure elements in a unary Model with twostate and Einstein contributions referenced to that phase is zero."""
    m = Model(FEMN_DBF, ['FE', 'VA'], 'LIQUID')
    statevars = {
        v.T: 298.15,
        v.SiteFraction('LIQUID', 0, 'FE'): 1,
        v.SiteFraction('LIQUID', 1, 'VA'): 1
    }
    refstates = [ReferenceState(v.Species('FE'), 'LIQUID')]
    m.shift_reference_state(refstates, FEMN_DBF)
    check_output(m, statevars, 'GMR', 0.0)
Beispiel #7
0
def test_magnetic_reference_energy_is_zero():
    """The referenced energy binary magnetic Model is zero."""
    m = Model(CRFE_DBF, ['CR', 'FE', 'VA'], 'BCC_A2')
    refstates = [ReferenceState('CR', 'BCC_A2'), ReferenceState('FE', 'BCC_A2')]
    m.shift_reference_state(refstates, CRFE_DBF)

    statevars_FE = {v.T: 300,
             v.SiteFraction('BCC_A2', 0, 'CR'): 0, v.SiteFraction('BCC_A2', 0, 'FE'): 1,
             v.SiteFraction('BCC_A2', 1, 'VA'): 1}
    check_output(m, statevars_FE, 'GMR', 0.0)

    statevars_CR = {v.T: 300,
             v.SiteFraction('BCC_A2', 0, 'CR'): 1, v.SiteFraction('BCC_A2', 0, 'FE'): 0,
             v.SiteFraction('BCC_A2', 1, 'VA'): 1}
    check_output(m, statevars_CR, 'GMR', 0.0)
Beispiel #8
0
def test_reference_energy_for_different_phase():
    """The referenced energy a different phase should be correct."""
    m = Model(ALFE_DBF, ['AL', 'FE', 'VA'], 'AL2FE')
    # formation reference states
    refstates = [
        ReferenceState('AL', 'FCC_A1'),
        ReferenceState('FE', 'BCC_A2')
    ]
    m.shift_reference_state(refstates, ALFE_DBF)

    statevars = {
        v.T: 300,
        v.SiteFraction('AL2FE', 0, 'AL'): 1,
        v.SiteFraction('AL2FE', 1, 'FE'): 1
    }
    check_output(m, statevars, 'GMR', -28732.525)  # Checked in Thermo-Calc
Beispiel #9
0
def test_non_zero_reference_mixing_enthalpy_for_va_interaction():
    """The referenced mixing enthalpy for a Model with a VA interaction parameter is non-zero."""
    m = Model(VA_INTERACTION_DBF, ['AL', 'VA'], 'FCC_A1')
    refstates = [ReferenceState('AL', 'FCC_A1')]
    m.shift_reference_state(refstates, VA_INTERACTION_DBF)

    statevars_pure = {v.T: 300,
         v.SiteFraction('FCC_A1', 0, 'AL'): 1, v.SiteFraction('FCC_A1', 0, 'VA'): 0,
         v.SiteFraction('FCC_A1', 1, 'VA'): 1}
    check_output(m, statevars_pure, 'GMR', 0.0)

    statevars_mix = {v.T: 300,
        v.SiteFraction('FCC_A1', 0, 'AL'): 0.5, v.SiteFraction('FCC_A1', 0, 'VA'): 0.5,
        v.SiteFraction('FCC_A1', 1, 'VA'): 1}
    # 4000.0 * 0.5=2000 +500 # (Y0VA doesn't contribute), but the VA endmember does (not referenced)
    check_output(m, statevars_mix, 'HMR', 2500.0)

    statevars_mix = {v.T: 300,
        v.SiteFraction('FCC_A1', 0, 'AL'): 0.5, v.SiteFraction('FCC_A1', 0, 'VA'): 0.5,
        v.SiteFraction('FCC_A1', 1, 'VA'): 1}
    # 4000.0 * 0.5 (Y0VA doesn't contribute)
    check_output(m, statevars_mix, 'HM_MIX', 2000.0)
Beispiel #10
0
def test_magnetic_reference_energy_is_zero():
    """The referenced energy binary magnetic Model is zero."""
    m = Model(CRFE_DBF, ['CR', 'FE', 'VA'], 'BCC_A2')
    refstates = [
        ReferenceState('CR', 'BCC_A2'),
        ReferenceState('FE', 'BCC_A2')
    ]
    m.shift_reference_state(refstates, CRFE_DBF)

    statevars_FE = {
        v.T: 300,
        v.SiteFraction('BCC_A2', 0, 'CR'): 0,
        v.SiteFraction('BCC_A2', 0, 'FE'): 1,
        v.SiteFraction('BCC_A2', 1, 'VA'): 1
    }
    check_output(m, statevars_FE, 'GMR', 0.0)

    statevars_CR = {
        v.T: 300,
        v.SiteFraction('BCC_A2', 0, 'CR'): 1,
        v.SiteFraction('BCC_A2', 0, 'FE'): 0,
        v.SiteFraction('BCC_A2', 1, 'VA'): 1
    }
    check_output(m, statevars_CR, 'GMR', 0.0)
def get_thermochemical_data(dbf,
                            comps,
                            phases,
                            datasets,
                            weight_dict=None,
                            symbols_to_fit=None):
    """

    Parameters
    ----------
    dbf : pycalphad.Database
        Database to consider
    comps : list
        List of active component names
    phases : list
        List of phases to consider
    datasets : espei.utils.PickleableTinyDB
        Datasets that contain single phase data
    weight_dict : dict
        Dictionary of weights for each data type, e.g. {'HM': 200, 'SM': 2}
    symbols_to_fit : list
        Parameters to fit. Used to build the models and PhaseRecords.

    Returns
    -------
    list
        List of data dictionaries to iterate over
    """
    # phase by phase, then property by property, then by model exclusions
    if weight_dict is None:
        weight_dict = {}

    if symbols_to_fit is not None:
        symbols_to_fit = sorted(symbols_to_fit)
    else:
        symbols_to_fit = database_symbols_to_fit(dbf)

    # estimated from NIST TRC uncertainties
    property_std_deviation = {
        'HM': 500.0 / weight_dict.get('HM', 1.0),  # J/mol
        'SM': 0.2 / weight_dict.get('SM', 1.0),  # J/K-mol
        'CPM': 0.2 / weight_dict.get('CPM', 1.0),  # J/K-mol
    }
    properties = [
        'HM_FORM', 'SM_FORM', 'CPM_FORM', 'HM_MIX', 'SM_MIX', 'CPM_MIX'
    ]

    ref_states = []
    for el in get_pure_elements(dbf, comps):
        ref_state = ReferenceState(el, dbf.refstates[el]['phase'])
        ref_states.append(ref_state)
    all_data_dicts = []
    for phase_name in phases:
        for prop in properties:
            desired_data = get_prop_data(
                comps,
                phase_name,
                prop,
                datasets,
                additional_query=(where('solver').exists()))
            if len(desired_data) == 0:
                continue
            unique_exclusions = set([
                tuple(sorted(d.get('excluded_model_contributions', [])))
                for d in desired_data
            ])
            for exclusion in unique_exclusions:
                data_dict = {
                    'phase_name': phase_name,
                    'prop': prop,
                    # needs the following keys to be added:
                    # species, calculate_dict, phase_records, model, output, weights
                }
                # get all the data with these model exclusions
                if exclusion == tuple([]):
                    exc_search = (
                        ~where('excluded_model_contributions').exists()) & (
                            where('solver').exists())
                else:
                    exc_search = (where('excluded_model_contributions').test(
                        lambda x: tuple(sorted(x)) == exclusion)) & (
                            where('solver').exists())
                curr_data = get_prop_data(comps,
                                          phase_name,
                                          prop,
                                          datasets,
                                          additional_query=exc_search)
                calculate_dict = get_prop_samples(dbf, comps, phase_name,
                                                  curr_data)
                mod = Model(dbf, comps, phase_name, parameters=symbols_to_fit)
                if prop.endswith('_FORM'):
                    output = ''.join(prop.split('_')[:-1]) + 'R'
                    mod.shift_reference_state(
                        ref_states,
                        dbf,
                        contrib_mods={e: sympy.S.Zero
                                      for e in exclusion})
                else:
                    output = prop
                for contrib in exclusion:
                    mod.models[contrib] = sympy.S.Zero
                    mod.reference_model.models[contrib] = sympy.S.Zero
                species = sorted(unpack_components(dbf, comps), key=str)
                data_dict['species'] = species
                model = {phase_name: mod}
                statevar_dict = {
                    getattr(v, c, None): vals
                    for c, vals in calculate_dict.items()
                    if isinstance(getattr(v, c, None), v.StateVariable)
                }
                statevar_dict = OrderedDict(
                    sorted(statevar_dict.items(), key=lambda x: str(x[0])))
                str_statevar_dict = OrderedDict(
                    (str(k), vals) for k, vals in statevar_dict.items())
                phase_records = build_phase_records(
                    dbf,
                    species, [phase_name],
                    statevar_dict,
                    model,
                    output=output,
                    parameters={s: 0
                                for s in symbols_to_fit},
                    build_gradients=False,
                    build_hessians=False)
                data_dict['str_statevar_dict'] = str_statevar_dict
                data_dict['phase_records'] = phase_records
                data_dict['calculate_dict'] = calculate_dict
                data_dict['model'] = model
                data_dict['output'] = output
                data_dict['weights'] = np.array(
                    property_std_deviation[prop.split('_')[0]]) / np.array(
                        calculate_dict.pop('weights'))
                all_data_dicts.append(data_dict)
    return all_data_dicts
Beispiel #12
0
def test_underspecified_refstate_raises():
    """A Model cannot be shifted to a new reference state unless references for all pure elements are specified."""
    m = Model(FEMN_DBF, ['FE', 'MN', 'VA'], 'LIQUID')
    refstates = [ReferenceState(v.Species('FE'), 'LIQUID')]
    with pytest.raises(DofError):
        m.shift_reference_state(refstates, FEMN_DBF)
Beispiel #13
0
def test_underspecified_refstate_raises():
    """A Model cannot be shifted to a new reference state unless references for all pure elements are specified."""
    m = Model(FEMN_DBF, ['FE', 'MN', 'VA'], 'LIQUID')
    refstates = [ReferenceState(v.Species('FE'), 'LIQUID')]
    m.shift_reference_state(refstates, FEMN_DBF)