def test_parameter_initialization(): """Determinisitically generated parameters should match.""" initial_parameters = np.array([1, 10, 100, 1000]) opt = EmceeOptimizer(Database()) deterministic_params = opt.initialize_new_chains(initial_parameters, 1, 0.10, deterministic=True) expected_parameters = np.array( [[9.81708401e-01, 9.39027722e+00, 1.08016748e+02, 9.13512881e+02], [1.03116874, 9.01412995, 112.79594345, 916.44725799], [1.00664662e+00, 1.07178898e+01, 9.63696718e+01, 1.36872292e+03], [1.07642366e+00, 1.16413520e+01, 8.71742457e+01, 9.61836382e+02]]) assert np.all(np.isclose(deterministic_params, expected_parameters))
def test(): """ The calculation for the interfacial energy of the FCC_A1/GAMMA_PRIME interface in the Ni-Al system. """ # Given temperature. T = 800.00 # Given initial alloy composition. x0 is the mole fraction of Al. x0 = [0.2] # Render thermodynamic database. db = Database("NiAlHuang1999.tdb") # Define components in the interface. comps = ["NI", "AL", "VA"] # Two phases separated by the interface. phasenames = ["FCC_A1", "GAMMA_PRIME"] # Molar volumes of pure components to construct corresponding molar volume database. # Molar volume of Ni. vni = "6.718*10.0**(-6.0) + (2.936*10.0**(-5)*10.0**(-6.0))*T**(1.355*10.0**(-6.0))" # Molar volume of Al. val = "10.269*10.0**(-6.0) + (3.860*10.0**(-5)*10.0**(-6.0))*T**(1.491*10.0**(-6.0))" purevms = [ [vni, val], ] * 2 # A composition range for searching initial interfacial equilirium composition. limit = [0.0001, 0.3] # The composition step for searching initial interfacial equilirium composition. dx = 0.1 # Call the module for calculating coherent interfacial energies. sigma = SigmaCoherent( T=T, x0=x0, db=db, comps=comps, phasenames=phasenames, purevms=purevms, limit=limit, dx=dx, ) # Print the calculated interfacial energy with xarray.Dataset type. print(sigma, "\n") # Print the calculated interfacial energy with xarray.DataArray type. print(sigma.Interfacial_Energy, "\n") # Print the calculated interfacial energy value. print(sigma.Interfacial_Energy.values, "\n") # Output """
def test_tdb_parser_raises_unterminated_parameters(): """A TDB FUNCTION or PARAMETER should give an error if the parsed Piecewise expression does not end the line.""" # The PARAMETER G(BCC,FE:H;0) parameter is not terminated by an `!`. # The parser merges all newlines until the `!`, meaning both parameters # will be joined on one "line". The parser should raise an error. UNTERMINATED_PARAM_STR = """ PARAMETER G(BCC,FE:H;0) 298.15 +GHSERFE+1.5*GHSERHH +258000-3170*T+498*T*LN(T)-0.275*T**2; 1811.00 Y +232264+82*T+1*GHSERFE+1.5*GHSERHH; 6000.00 N PARAMETER G(BCC,FE:VA;0) 298.15 +GHSERFE; 6000 N ZIM ! """ with pytest.raises(ParseException): Database(UNTERMINATED_PARAM_STR)
def test_equilibrium_thermochemical_error_unsupported_property(datasets_db): """Test that an equilibrium property that is not explictly supported will work.""" # This test specifically tests Curie temperature datasets_db.insert(CR_NI_LIQUID_EQ_TC_DATA) EXPECTED_VALUES = np.array( [374.6625, 0.0, 0.0] ) # the TC should be 374.6625 in both cases, but "values" are [0 and 382.0214], so the differences should be flipped. dbf = Database(CR_NI_TDB) phases = list(dbf.phases.keys()) eqdata = get_equilibrium_thermochemical_data(dbf, ['CR', 'NI'], phases, datasets_db) errors_exact, weights = calc_prop_differences(eqdata[0], np.array([])) assert np.all(np.isclose(errors_exact, EXPECTED_VALUES, atol=1e-3))
def test_get_thermochemical_data_filters_invalid_sublattice_configurations( datasets_db): datasets_db.insert(CU_MG_HM_MIX_CUMG2_ANTISITE) dbf = Database(CU_MG_TDB) comps = ["CU", "MG", "VA"] phases = ["CUMG2"] thermochemical_data = get_thermochemical_data(dbf, comps, phases, datasets_db) print('thermochemical data:', thermochemical_data) assert thermochemical_data[0]["calculate_dict"]["values"].shape == (2, ) error = calculate_non_equilibrium_thermochemical_probability( thermochemical_data) assert np.isclose(error, -14.28729)
def test_eq_issue62_last_component_not_va(): """ VA is not last when components are sorted alphabetically. """ test_tdb = """ ELEMENT VA VACUUM 0.0000E+00 0.0000E+00 0.0000E+00! ELEMENT AL FCC_A1 2.6982E+01 4.5773E+03 2.8322E+01! ELEMENT CO HCP_A3 5.8933E+01 4.7656E+03 3.0040E+00! ELEMENT CR BCC_A2 5.1996E+01 4.0500E+03 2.3560E+01! ELEMENT W BCC_A2 1.8385E+02 4.9700E+03 3.2620E+01! PHASE FCC_A1 % 2 1 1 ! CONSTITUENT FCC_A1 :AL,CO,CR,W : VA% : ! """ equilibrium(Database(test_tdb), ['AL', 'CO', 'CR', 'W', 'VA'], ['FCC_A1'], {"T": 1248, "P": 101325, v.X("AL"): 0.081, v.X("CR"): 0.020, v.X("W"): 0.094})
def test(): """ Calculate solid/liquid interfacial energies of the Ni-Al system. """ # Given temperature. T = 916 # Given initial alloy composition. x0 is the mole fraction of Ni. x0 = [0.01] # Render thermodynamic database. db = Database("AlNiAnsara1997.TDB") # Define components in the interface. comps = ["AL", "NI"] # Two phases separated by the interface. phasenames = ["FCC_A1", "LIQUID"] # Molar volumes of pure components to construct corresponding molar volume database. # Molar volume of Al. val = "10.269*10.0**(-6.0) + (3.860*10.0**(-5)*10.0**(-6.0))*T**(1.491*10.0**(-6.0))" # Molar volume of Ni. vni = "6.718*10.0**(-6.0) + (2.936*10.0**(-5)*10.0**(-6.0))*T**(1.355*10.0**(-6.0))" purevms = [[val, vni], [val, vni]] # A composition range for searching initial interfacial equilirium composition. limit = [10**(-20), 0.2] # The composition step for searching initial interfacial equilirium composition. dx = 0.01 # Call the module for calculating solid/liquid interfacial energies. sigma = SigmaSolLiq( T=T, x0=x0, db=db, comps=comps, phasenames=phasenames, purevms=purevms, limit=limit, dx=dx, ) # Print the calculated interfacial energy with xarray.Dataset type. print(sigma, "\n") # Print the calculated interfacial energy with xarray.DataArray type. print(sigma.Interfacial_Energy, "\n") # Print the calculated interfacial energy value. print(sigma.Interfacial_Energy.values) # Output """
def test_zpf_error_works_for_stoichiometric_cmpd_tielines(datasets_db): """A stochimetric compound with approximate composition can be in the datasets and work""" datasets_db.insert(CU_MG_DATASET_ZPF_STOICH_COMPOUND) dbf = Database(CU_MG_TDB) comps = ['CU','MG'] phases = list(dbf.phases.keys()) # ZPF weight = 1 kJ and there are two points in the tieline zero_error_probability = 2 * scipy.stats.norm(loc=0, scale=1000.0).logpdf(0.0) zpf_data = get_zpf_data(dbf, comps, phases, datasets_db, {}) exact_likelihood = calculate_zpf_error(zpf_data) assert np.isclose(exact_likelihood, zero_error_probability, rtol=1e-6) approx_likelihood = calculate_zpf_error(zpf_data) assert np.isclose(approx_likelihood, zero_error_probability, rtol=1e-6)
def test_equilibrium_thermochemical_correct_probability(datasets_db): """Integration test for equilibrium thermochemical error.""" dbf = Database(CU_MG_TDB) opt = EmceeOptimizer(dbf) datasets_db.insert(CU_MG_EQ_HMR_LIQUID) ctx = setup_context(dbf, datasets_db, ['VV0017']) ctx.update(opt.get_priors(None, ['VV0017'], [0])) prob = opt.predict(np.array([-31626.6]), **ctx) expected_prob = norm(loc=0, scale=500).logpdf([-31626.6 * 0.5 * 0.5]).sum() assert np.isclose(prob, expected_prob) # change to -40000 prob = opt.predict(np.array([-40000], dtype=np.float_), **ctx) expected_prob = norm(loc=0, scale=500).logpdf([-40000 * 0.5 * 0.5]).sum() assert np.isclose(prob, expected_prob)
def test_eq_calc_samples(): tdbfile = resource_filename('pduq.tests', 'CU-MG_param_gen.tdb') dbf = Database(tdbfile) paramfile = resource_filename('pduq.tests', 'trace.csv') params = np.loadtxt(paramfile, delimiter=',') conds = {v.P: 101325, v.T: 1003, v.X('MG'): 0.214} eqC = eq_calc_samples(dbf, conds, params[-2:, :]) tst = eqC.NP.where(eqC.Phase == 'LIQUID').sum(dim='vertex') assert list(eqC.dims.values()) == [1, 1, 1, 1, 2, 4, 2, 3] assert list(np.squeeze(tst)) == [0., 1.]
def test_get_thermochemical_data_filters_configurations_when_all_configurations_are_invalid( datasets_db): datasets_db.insert( CU_MG_HM_MIX_CUMG2_ALL_INVALID) # No valid configurations dbf = Database(CU_MG_TDB) comps = ["CU", "MG", "VA"] phases = ["CUMG2"] thermochemical_data = get_thermochemical_data(dbf, comps, phases, datasets_db) print('thermochemical data:', thermochemical_data) assert thermochemical_data[0]["calculate_dict"]["values"].shape == (0, ) error = calculate_non_equilibrium_thermochemical_probability( thermochemical_data) assert np.isclose(error, 0)
def test_order_disorder_interstital_sublattice_validation(): # Check that substitutional/interstitial sublattices that break our # assumptions raise errors DBF_OrderDisorder_broken = Database(""" ELEMENT VA VACUUM 0.0000E+00 0.0000E+00 0.0000E+00 ! ELEMENT A DISORD 0.0000E+00 0.0000E+00 0.0000E+00 ! ELEMENT B DISORD 0.0000E+00 0.0000E+00 0.0000E+00 ! ELEMENT C DISORD 0.0000E+00 0.0000E+00 0.0000E+00 ! DEFINE_SYSTEM_DEFAULT ELEMENT 2 ! DEFAULT_COMMAND DEF_SYS_ELEMENT VA ! TYPE_DEFINITION % SEQ *! TYPE_DEFINITION ' GES A_P_D ORD_MORE_INSTL DIS_PART DISORD ,,,! TYPE_DEFINITION & GES A_P_D ORD_LESS_INSTL DIS_PART DISORD ,,,! TYPE_DEFINITION ) GES A_P_D ORD_SUBS_INSTL DIS_PART DISORD ,,,! PHASE DISORD % 2 1 3 ! CONSTITUENT DISORD : A,B,VA : VA : ! $ Has one more interstitial sublattice than disordered: PHASE ORD_MORE_INSTL %' 4 0.5 0.5 3 1 ! CONSTITUENT ORD_MORE_INSTL : A,B,VA : A,B,VA : VA : A : ! $ Has one less interstitial sublattice than disordered: PHASE ORD_LESS_INSTL %& 2 0.5 0.5 ! CONSTITUENT ORD_LESS_INSTL : A,B,VA : A,B,VA : ! $ The interstitial sublattice has the same species as the substitutional $ and cannot be distinguished: PHASE ORD_SUBS_INSTL %) 3 0.5 0.5 3 ! CONSTITUENT ORD_SUBS_INSTL : A,B,VA : A,B,VA : A,B,VA : ! """) # Case 1: Ordered phase has one more interstitial sublattice than disordered with pytest.raises(ValueError): Model(DBF_OrderDisorder_broken, ["A", "B", "VA"], "ORD_MORE_INSTL") # Case 2: Ordered phase has one more interstitial sublattice than disordered with pytest.raises(ValueError): Model(DBF_OrderDisorder_broken, ["A", "B", "VA"], "ORD_LESS_INSTL") # Case 3: The ordered phase has interstitial sublattice has the same species # as the substitutional and cannot be distinguished with pytest.raises(ValueError): Model(DBF_OrderDisorder_broken, ["A", "B", "VA"], "ORD_SUBS_INSTL")
def test_zpf_error_equilibrium_failure(datasets_db): """Test that a target hyperplane producing NaN chemical potentials gives a driving force of zero.""" datasets_db.insert(CU_MG_DATASET_ZPF_NAN_EQUILIBRIUM) dbf = Database(CU_MG_TDB) comps = ['CU','MG','VA'] phases = list(dbf.phases.keys()) # ZPF weight = 1 kJ and there are two points in the tieline zero_error_probability = 2 * scipy.stats.norm(loc=0, scale=1000.0).logpdf(0.0) zpf_data = get_zpf_data(dbf, comps, phases, datasets_db, {}) with mock.patch('espei.error_functions.zpf_error.estimate_hyperplane', return_value=np.array([np.nan, np.nan])): exact_likelihood = calculate_zpf_error(zpf_data) assert np.isclose(exact_likelihood, zero_error_probability, rtol=1e-6) approx_likelihood = calculate_zpf_error(zpf_data) assert np.isclose(approx_likelihood, zero_error_probability, rtol=1e-6)
def test_zpf_context_is_pickleable(datasets_db): """Test that the context for ZPF data is pickleable""" datasets_db.insert(CU_MG_DATASET_ZPF_ZERO_ERROR) dbf = Database(CU_MG_TDB) symbols_to_fit = database_symbols_to_fit(dbf) initial_guess = np.array([unpack_piecewise(dbf.symbols[s]) for s in symbols_to_fit]) prior_dict = EmceeOptimizer.get_priors(None, symbols_to_fit, initial_guess) ctx = setup_context(dbf, datasets_db) ctx.update(prior_dict) ctx_pickle = pickle.dumps(ctx) ctx_unpickled = pickle.loads(ctx_pickle) regular_predict = EmceeOptimizer.predict(initial_guess, **ctx) unpickle_predict = EmceeOptimizer.predict(initial_guess, **ctx_unpickled) assert np.isclose(regular_predict, unpickle_predict)
def test_equilibrium_thermochemical_context_is_pickleable(datasets_db): """Test that the context for equilibrium thermochemical data is pickleable""" datasets_db.insert(CU_MG_EQ_HMR_LIQUID) dbf = Database(CU_MG_TDB) symbols_to_fit = database_symbols_to_fit(dbf) initial_guess = np.array([unpack_piecewise(dbf.symbols[s]) for s in symbols_to_fit]) prior_dict = EmceeOptimizer.get_priors(None, symbols_to_fit, initial_guess) ctx = setup_context(dbf, datasets_db) ctx.update(prior_dict) ctx_pickle = pickle.dumps(ctx) ctx_unpickled = pickle.loads(ctx_pickle) regular_predict = EmceeOptimizer.predict(initial_guess, **ctx) unpickle_predict = EmceeOptimizer.predict(initial_guess, **ctx_unpickled) assert np.isclose(regular_predict, unpickle_predict)
def test_zpf_error_equilibrium_failure(datasets_db): """Test that a hyperplane that fails produce a driving force of zero.""" datasets_db.insert(CU_MG_DATASET_ZPF_NAN_EQUILIBRIUM) dbf = Database(CU_MG_TDB) comps = ['CU', 'MG', 'VA'] phases = list(dbf.phases.keys()) # ZPF weight = 1 kJ and there are two points in the tieline zero_error_probability = 2 * scipy.stats.norm(loc=0, scale=1000.0).logpdf(0.0) zpf_data = get_zpf_data(dbf, comps, phases, datasets_db, {}) exact_likelihood = calculate_zpf_error(zpf_data) assert np.isclose(exact_likelihood, zero_error_probability, rtol=1e-6) approx_likelihood = calculate_zpf_error(zpf_data) assert np.isclose(approx_likelihood, zero_error_probability, rtol=1e-6)
def test_tdb_order_disorder_model_hints_applied_correctly(): """Phases using the order/disorder model should have model_hints added to both phases, regardless of the order by which the phases were specified. Model hints should also be applied correctly if only one of the phases has the order/disorder type defintion applied, since this is allowed by commercial software. """ # This test creates a starting template and then tries to add the phase and # type definitions in any order. In this case, the BCC_A2 phase does not # have the type definition while the BCC_B2 phase does. TEMPLATE_TDB = """ ELEMENT VA VACUUM .0000E+00 .0000E+00 .0000E+00! ELEMENT AL FCC_A1 2.6982E+01 4.5773E+03 2.8322E+01! ELEMENT NI FCC_A1 5.8690E+01 4.7870E+03 2.9796E+01! TYPE_DEFINITION % SEQ *! """ PHASE_A2 = """ PHASE BCC_A2 % 2 1 3 ! CONST BCC_A2 :AL,NI : VA : ! """ PHASE_B2 = """ PHASE BCC_B2 %C 3 .5 .5 3 ! CONST BCC_B2 :AL,NI : AL,NI : VA: ! """ TYPE_DEF_ORD = """ TYPE_DEFINITION C GES A_P_D BCC_B2 DIS_PART BCC_A2 ! """ import itertools for (k1, v1), (k2, v2), (k3, v3) in itertools.permutations([ ('PHASE_A2 ', PHASE_A2), ('PHASE_B2 ', PHASE_B2), ('TYPE_DEF ', TYPE_DEF_ORD) ]): print(k1 + k2 + k3) dbf = Database(TEMPLATE_TDB + v1 + v2 + v3) assert 'disordered_phase' in dbf.phases['BCC_A2'].model_hints assert 'ordered_phase' in dbf.phases['BCC_A2'].model_hints assert 'disordered_phase' in dbf.phases['BCC_B2'].model_hints assert 'ordered_phase' in dbf.phases['BCC_B2'].model_hints roundtrip_dbf = Database.from_string(dbf.to_string(fmt='tdb'), fmt='tdb') assert roundtrip_dbf == dbf
def test_equilibrium_thermochemcial_error_species(datasets_db): """Test species work for equilibrium thermochemical data.""" datasets_db.insert(LI_SN_LIQUID_EQ_DATA) dbf = Database(LI_SN_TDB) phases = list(dbf.phases.keys()) eqdata = get_equilibrium_thermochemical_data(dbf, ['LI', 'SN'], phases, datasets_db) # Thermo-Calc truth_values = np.array([0.0, -28133.588, -40049.995, 0.0]) # Approximate errors_approximate, weights = calc_prop_differences(eqdata[0], np.array([]), True) # Looser tolerances because the equilibrium is approximate, note that this is pdens dependent assert np.all(np.isclose(errors_approximate, truth_values, atol=1e-5, rtol=1e-3)) # Exact errors_exact, weights = calc_prop_differences(eqdata[0], np.array([]), False) assert np.all(np.isclose(errors_exact, truth_values, atol=1e-5))
def test_invalid_arguments_energy_zero(): "Undefined symbols in CompiledModel are set to zero (gh-54)." TEST_TDB = """PHASE M7C3_D101 % 2 7 3 ! CONSTITUENT M7C3_D101 :MN:C: ! PARAMETER G(M7C3_D101,MN:C;0) 1 VV22+VV23*T**2+VV24*T**3 +VV25*T**4+VV26*T**5; 6000 N !""" dbf = Database(TEST_TDB) from sympy import Symbol with warnings.catch_warnings(record=True) as w: res = calculate(dbf, ['MN', 'C'], 'M7C3_D101', T=300, P=101325, parameters={Symbol('VV22'): 100}) assert res.GM.values[0, 0, 0] == 10. # 100 / 10 moles per formula-unit categories = [warning.__dict__['_category_name'] for warning in w] assert 'UserWarning' in categories assert len(w) == 4
def test_driving_force_miscibility_gap(datasets_db): datasets_db.insert(A_B_DATASET_ALPHA) dbf = Database(A_B_REGULAR_SOLUTION_TDB) parameters = {"L_ALPHA": None} zpf_data = get_zpf_data(dbf, ["A", "B"], ["ALPHA"], datasets_db, parameters) # probability for zero error error with ZPF weight = 1000.0 zero_error_prob = scipy.stats.norm(loc=0, scale=1000.0).logpdf(0.0) # Ideal solution case params = np.array([0.0]) prob = calculate_zpf_error(zpf_data, parameters=params, approximate_equilibrium=False) assert np.isclose(prob, zero_error_prob) prob = calculate_zpf_error(zpf_data, parameters=params, approximate_equilibrium=True) assert np.isclose(prob, zero_error_prob) # Negative interaction case params = np.array([-10000.0]) prob = calculate_zpf_error(zpf_data, parameters=params, approximate_equilibrium=False) assert np.isclose(prob, zero_error_prob) prob = calculate_zpf_error(zpf_data, parameters=params, approximate_equilibrium=True) assert np.isclose(prob, zero_error_prob) # Miscibility gap case params = np.array([10000.0]) prob = calculate_zpf_error(zpf_data, parameters=params, approximate_equilibrium=False) # Remember these are log probabilities, so more negative means smaller probability and larger error assert prob < zero_error_prob prob = calculate_zpf_error(zpf_data, parameters=params, approximate_equilibrium=True) assert prob < zero_error_prob
def test_eq_ideal_chempot_cond(): TDB = """ ELEMENT A GRAPHITE 12.011 1054.0 5.7423 ! ELEMENT B BCC_A2 55.847 4489.0 27.2797 ! ELEMENT C BCC_A2 55.847 4489.0 27.2797 ! TYPE_DEFINITION % SEQ * ! PHASE TEST % 1 1 ! CONSTITUENT TEST : A,B,C: ! """ my_phases = ['TEST'] comps = ['A', 'B', 'C'] comps = sorted(comps) conds = dict({v.T: 1000, v.P: 101325, v.N: 1}) conds[v.MU('C')] = -1000 conds[v.X('A')] = 0.01 eq = equilibrium(Database(TDB), comps, my_phases, conds, verbose=True) np.testing.assert_allclose(eq.GM.values.squeeze(), -3219.570565) np.testing.assert_allclose(eq.MU.values.squeeze(), [-38289.687511, -18873.23674, -1000.]) np.testing.assert_allclose(eq.X.isel(vertex=0).values.squeeze(), [0.01, 0.103321, 0.886679], atol=1e-4)
def test_equilibrium_thermochemical_error_computes_correct_probability(datasets_db): """Integration test for equilibrium thermochemical error.""" datasets_db.insert(CU_MG_EQ_HMR_LIQUID) dbf = Database(CU_MG_TDB) phases = list(dbf.phases.keys()) # Test that errors update in response to changing parameters # no parameters eqdata = get_equilibrium_thermochemical_data(dbf, ['CU', 'MG'], phases, datasets_db) errors, weights = calc_prop_differences(eqdata[0], np.array([])) expected_vals = [-31626.6*0.5*0.5] assert np.all(np.isclose(errors, expected_vals)) # VV0017 (LIQUID, L0) eqdata = get_equilibrium_thermochemical_data(dbf, ['CU', 'MG'], phases, datasets_db, parameters={'VV0017': -31626.6}) # unchanged, should be the same as before errors, weights = calc_prop_differences(eqdata[0], np.array([-31626.6])) assert np.all(np.isclose(errors, [-31626.6*0.5*0.5])) # change to -40000 errors, weights = calc_prop_differences(eqdata[0], np.array([-40000], np.float_)) assert np.all(np.isclose(errors, [-40000*0.5*0.5]))
def test_get_data_quantities_mixing_entropy(): """Test that mixing entropy produces correct data quantities with excluded idmix model contribution """ data = [{'components': ['AL', 'CR'], 'phases': ['AL11CR2'], 'solver': {'mode': 'manual', 'sublattice_site_ratios': [10.0, 2.0], 'sublattice_configurations': (('AL', ('AL', 'CR')),), 'sublattice_occupancies': [[1.0, [0.5, 0.5]]]}, 'conditions': {'P': 101325.0, 'T': np.array([300.])}, 'output': 'SM_MIX', 'values': np.array([[[0.60605556]]]), 'reference': 'text 1 to write down reference for this work', 'comment': 'test 2 to write down comment for this work', 'excluded_model_contributions': ['idmix']}] dbf = Database(""" ELEMENT AL FCC_A1 26.982 4577.3 28.322 ! ELEMENT CR BCC_A2 51.996 4050.0 23.56 ! PHASE AL11CR2 % 2 10.0 2.0 ! CONSTITUENT AL11CR2 :AL:AL,CR: ! """) mod = Model(dbf, ['AL', 'CR'], 'AL11CR2') # desired_property, fixed_model, fixed_portions, data, samples config_tup = (('AL',), ('AL', 'CR')) calculate_dict = get_prop_samples(data, config_tup) sample_condition_dicts = _get_sample_condition_dicts(calculate_dict, list(map(len, config_tup))) qty = get_data_quantities('SM_MIX', mod, [0], data, sample_condition_dicts) print(qty) assert np.all(np.isclose([7.27266667], qty))
def test_eq_associate(): """ Associate model where the number of elements is different from the number of components (gh-367). """ ASSOC_TDB = """ ELEMENT A BLANK 0.0 0.0 0.0 ! ELEMENT Q BLANK 0.0 0.0 0.0 ! SPECIES COMPA A1.0Q1.0 ! SPECIES COMPB Q2.0 ! SPECIES COMPC A1.0 ! SPECIES COMPD A1.5 ! TYPE_DEFINITION % SEQ * ! DEFINE_SYSTEM_DEFAULT ELEMENT 2 ! PHASE PHASEA % 1 1.0 ! CONSTITUENT PHASEA :Q: ! PHASE PHASEB % 1 1.0 ! CONSTITUENT PHASEB :Q: ! PHASE PHASEC % 1 1.0 ! CONSTITUENT PHASEC :Q: ! PHASE PHASED % 1 1.0 ! CONSTITUENT PHASED :Q: ! PHASE PHASEE % 1 1.0 ! CONSTITUENT PHASEE :A: ! PHASE PHASEF % 1 1.0 ! CONSTITUENT PHASEF :COMPB,COMPC: ! PHASE PHASEG % 1 1.0 ! CONSTITUENT PHASEG :COMPA,COMPD: ! """ dbf = Database(ASSOC_TDB) phases = list(set(dbf.phases.keys())) conds = {v.X('Q'): 0.3, v.T: 500, v.P: 1e5, v.N: 1} eq = equilibrium(dbf, ['A', 'Q'], phases, conds) assert_allclose(eq.GM.values, -1736.981311)
def test_plot_interaction_runs(datasets_db): """Test that plot_interaction runs without an error.""" dbf = Database(CU_MG_TDB) comps = ['CU', 'MG', 'VA'] config = (('CU', 'MG'), ('VA')) # Plot HM_MIX without datasets fig = plt.figure( ) # explictly do NOT pass axes to make sure they are created ax = plot_interaction(dbf, comps, 'FCC_A1', config, 'HM_MIX') # fig.savefig('test_plot_interaction_runs-figure-HM_MIX-no_datasets.png') plt.close(fig) # HM_MIX with a dataset datasets_db.insert(CU_MG_HM_MIX_SINGLE_FCC_A1) fig = plt.figure() ax = fig.add_subplot() plot_interaction(dbf, comps, 'FCC_A1', config, 'HM_MIX', datasets_db, ax=ax) # fig.savefig('test_plot_interaction_runs-figure-HM_MIX.png') plt.close(fig) # Plot SM_MIX where the datasets have no data fig = plt.figure() ax = fig.add_subplot() plot_interaction(dbf, comps, 'FCC_A1', config, 'SM_MIX', datasets_db, ax=ax) # fig.savefig('test_plot_interaction_runs-figure-SM_MIX.png') plt.close(fig)
def main(parameters, seed): np.random.seed(seed) input_database = Database(parameters['input_database']) dataset_names = sorted(glob.glob(parameters['data_path'])) params = [] for pname, paramdist in parameters['parameters'].items(): paramdist = paramdist.copy() # don't want to modify original paramdist.pop('compare') # don't pass this as a kwarg dist = getattr(pymc, paramdist.pop('dist')) params.append(dist(str(pname), **paramdist)) mod, datasets = build_pymc_model(input_database, dataset_names, params) trace_path = os.path.join('Data', parameters['sumatra_label']) os.makedirs(trace_path) mdl = pymc.MCMC(mod, db='hdf5', dbname=str(os.path.join(trace_path, 'traces.h5')), dbcomplevel=4, dbcomplib='bzip2') mdl.sample(**parameters['mcmc']) mdl.db.close() output_files.append(os.path.join(parameters['sumatra_label'], 'traces.h5')) return datasets
def test_zpf_error_zero(datasets_db): """Test that sum of square ZPF errors returns 0 for an exactly correct result""" datasets_db.insert(CU_MG_DATASET_ZPF_ZERO_ERROR) dbf = Database(CU_MG_TDB) errors = calculate_zpf_error( dbf, ['CU', 'MG', 'VA'], list(dbf.phases.keys()), datasets_db, {}, {}, {}, {}, {}, {}, {}, {}, ) assert np.isclose(np.sum(np.square(errors)), 0)
def run_test(): dbf = Database() dbf.elements = frozenset(['A']) dbf.add_phase('TEST', {}, [1]) dbf.add_phase_constituents('TEST', [['A']]) # add THETA parameters here dbf.add_parameter('THETA', 'TEST', [['A']], 0, 334.) conds = {v.T: np.arange(1., 800., 1), v.P: 101325} res = calculate(dbf, ['A'], 'TEST', T=conds[v.T], P=conds[v.P], model=EinsteinModel, output='testprop') #res_TE = calculate(dbf, ['A'], 'TEST', T=conds[v.T], P=conds[v.P], # model=EinsteinModel, output='einstein_temperature') import matplotlib.pyplot as plt plt.scatter(res['T'], res['testprop']) plt.xlabel('Temperature (K)') plt.ylabel('Molar Heat Capacity (J/mol-K)') plt.savefig('einstein.png') print(dbf.to_string(fmt='tdb'))
def test_zpf_error_species(datasets_db): """Tests that ZPF error works if a species is used.""" # Note that the liquid is stabilized by the species for the equilibrium # used in the data. If the SPECIES is removed from the database (and LIQUID # constituents), then the resulting likelihood will NOT match this (and be # closer to 93, according to a test.) datasets_db.insert(LI_SN_ZPF_DATA) dbf = Database(LI_SN_TDB) comps = ['LI', 'SN'] phases = list(dbf.phases.keys()) # ZPF weight = 1 kJ and there are two points in the tieline zero_error_probability = 2 * scipy.stats.norm(loc=0, scale=1000.0).logpdf(0.0) zpf_data = get_zpf_data(dbf, comps, phases, datasets_db, {}) exact_likelihood = calculate_zpf_error(zpf_data, approximate_equilibrium=False) assert np.isclose(exact_likelihood, zero_error_probability) approx_likelihood = calculate_zpf_error(zpf_data, approximate_equilibrium=True) # accept higher tolerance for approximate assert np.isclose(approx_likelihood, zero_error_probability, rtol=1e-4)
def run_test(): dbf = Database('Fe-C_Fei_Brosh_2014_09.TDB') comps = ['FE', 'C', 'VA'] phases = ['FCC_A1', 'LIQUID'] conds = {v.T: 500, v.P: 101325, v.X('C'): 0.1} x0 = {'FE': 0.7, 'C': 0.3} a = 0 b = -10 * v.T slmod = SoluteTrapModel(dbf, comps, 'FCC_A1', a=a, b=b, n=1, x0=x0) # Use custom model for fcc; use default for all others models = {'FCC_A1': slmod} eq = equilibrium(dbf, comps, phases, conds, model=models) print(eq) res = calculate(dbf, comps, 'FCC_A1', T=conds[v.T], P=conds[v.P], model=models) res_nosoltrap = calculate(dbf, comps, 'FCC_A1', T=conds[v.T], P=conds[v.P]) import matplotlib.pyplot as plt plt.scatter(res.X.sel(component='C'), res.GM, c='r') plt.scatter(res.X.sel(component='C'), res_nosoltrap.GM, c='k') plt.xlabel('Mole Fraction C') plt.ylabel('Molar Gibbs Energy') plt.title('T = {} K'.format(conds[v.T])) plt.savefig('fcc_energy.png')