def enthalpy_dH(request, cid, db_type=None, mdb=None): try: pars, _, _, response, payload, x_val = init_isographs(request=request, db_type=db_type, cid=cid, mdb=mdb) resiso, resiso_theo = [], [] if pars['experimental_data_available']: # only execute this if experimental data is available for xv in x_val: # calculate experimental data try: s_th = s_th_o(payload['iso']) args = (payload['iso'], xv, pars, s_th) solutioniso = dh_ds(xv, args[-1], args[-2])[0] / 1000 resiso.append(solutioniso) except ValueError: # if brentq function finds no zero point due to plot out of range resiso.append(None) res_interp, res_fit = [], [] for delta_val, res_i in zip(x_val, resiso): # show interpolation if pars['delta_min'] < delta_val < pars['delta_max']: # result within experimentally covered delta range res_fit.append(res_i) res_interp.append(None) else: # result outside this range res_fit.append(None) res_interp.append(res_i) else: res_fit, res_interp = None, None # don't plot any experimental data if it is not available try: # calculate theoretical data for xv in x_val[::4]: # use less data points for theoretical graphs to improve speed args_theo = (payload['iso'], xv, pars, pars['td_perov'], pars['td_brownm'], \ pars["dh_min"], pars["dh_max"], pars["act_mat"]) solutioniso_theo = d_h_num_dev_calc(delta=xv, dh_1=pars["dh_min"], dh_2=pars["dh_max"], temp=payload['iso'], act=pars["act_mat"]) / 1000 resiso_theo.append(solutioniso_theo) except ValueError: # if brentq function finds no zero point due to plot out of range resiso_theo.append(None) x = list(x_val) x_theo = x[::4] x_exp = None if pars['experimental_data_available']: x_exp = x if max(pd.np.append(resiso, resiso_theo)) > (pars['dh_max'] * 0.0015): # limiting values for the plot y_max = pars['dh_max'] * 0.0015 else: y_max = max(pd.np.append(resiso, resiso_theo))*1.2 if min(pd.np.append(resiso, resiso_theo)) < -10: y_min = -10 else: y_min = min(pd.np.append(resiso, resiso_theo)) * 0.8 response = [{'x': x_exp, 'y': res_fit, 'name': "exp_fit", 'line': { 'color': 'rgb(5,103,166)', 'width': 2.5 }}, {'x': x_exp, 'y': res_interp, 'name': "exp_interp", \ 'line': { 'color': 'rgb(5,103,166)', 'width': 2.5, 'dash': 'dot' }}, {'x': x_theo, 'y': resiso_theo, 'name': "theo", \ 'line': { 'color': 'rgb(217,64,41)', 'width': 2.5}}, [y_min,y_max], [pars['compstr_disp'], pars['compstr_exp'], pars['tens_avail'], pars["last_updated"]]] except Exception as ex: raise ValueError('"REST Error: "{}"'.format(str(ex))) return {"valid_response": True, 'response': response}
def isotherm(request, cid, db_type=None, mdb=None): try: pars, a, b, response, payload, x_val = init_isographs(request=request, db_type=db_type, cid=cid, mdb=mdb) resiso, resiso_theo = [], [] if pars['experimental_data_available']: # only execute this if experimental data is available for xv in x_val: # calculate experimental data try: s_th = s_th_o(payload['iso']) args = (xv, payload['iso'], pars, s_th) solutioniso = rootfind(a, b, args, funciso) resiso.append(solutioniso) except ValueError: # if brentq function finds no zero point due to plot out of range resiso.append(None) res_interp, res_fit = [], [] for delta_val, res_i in zip(x_val, resiso): # show interpolation if pars['delta_min'] < delta_val < pars[ 'delta_max']: # result within experimentally covered delta range res_fit.append(res_i) res_interp.append(None) else: # result outside this range res_fit.append(None) res_interp.append(res_i) else: res_fit, res_interp = None, None # don't plot any experimental data if it is not available try: # calculate theoretical data for xv in x_val[:: 4]: # use less data points for theoretical graphs to improve speed args_theo = (xv, payload['iso'], pars, pars['td_perov'], pars['td_brownm'], \ pars["dh_min"], pars["dh_max"], pars["act_mat"]) solutioniso_theo = rootfind(a, b, args_theo, funciso_theo) resiso_theo.append(solutioniso_theo) except ValueError: # if brentq function finds no zero point due to plot out of range resiso_theo.append(None) x = list(pd.np.exp(x_val)) x_theo = x[::4] x_exp = None if pars['experimental_data_available']: x_exp = x response = [{'x': x_exp, 'y': res_fit, 'name': "exp_fit", 'line': { 'color': 'rgb(5,103,166)', 'width': 2.5 }}, {'x': x_exp, 'y': res_interp, 'name': "exp_interp", \ 'line': { 'color': 'rgb(5,103,166)', 'width': 2.5, 'dash': 'dot' }}, {'x': x_theo, 'y': resiso_theo, 'name': "theo", 'line': { 'color': 'rgb(217,64,41)', 'width': 2.5}}, [0,0],\ [pars['compstr_disp'], pars['compstr_exp'], pars['tens_avail'], pars["last_updated"]]] except Exception as ex: raise ValueError('"REST Error: "{}"'.format(str(ex))) return {"valid_response": True, 'response': response}
def isoredox(request, cid, db_type=None, mdb=None): try: pars, a, b, response, payload, x_val = init_isographs(request=request, db_type=db_type, cid=cid, mdb=mdb) resiso, resiso_theo = [], [] if pars['experimental_data_available']: # only execute this if experimental data is available for xv in x_val: # calculate experimental data try: s_th = s_th_o(xv) args = (payload['iso'], xv, pars, s_th) solutioniso = brentq(funciso_redox, -300, 300, args=args) resiso.append(pd.np.exp(solutioniso)) except ValueError: # if brentq function finds no zero point due to plot out of range resiso.append(None) res_interp, res_fit = [], [] for delta_val, res_i in zip(x_val, resiso): # show interpolation if pars['delta_min'] < delta_val < pars['delta_max']: # result within experimentally covered delta range res_fit.append(res_i) res_interp.append(None) else: # result outside this range res_fit.append(None) res_interp.append(res_i) else: res_fit, res_interp = None, None # don't plot any experimental data if it is not available try: # calculate theoretical data for xv in x_val[::4]: # use less data points for theoretical graphs to improve speed args_theo = (payload['iso'], xv, pars, pars['td_perov'], pars['td_brownm'], \ pars["dh_min"], pars["dh_max"], pars["act_mat"]) try: solutioniso_theo = brentq(funciso_redox_theo, -300, 300, args=args_theo) except ValueError: solutioniso_theo = brentq(funciso_redox_theo, -100, 100, args=args_theo) resiso_theo.append(pd.np.exp(solutioniso_theo)) except ValueError: # if brentq function finds no zero point due to plot out of range resiso_theo.append(None) x = list(x_val) x_theo = x[::4] x_exp = None if pars['experimental_data_available']: x_exp = x response = [{'x': x_exp, 'y': res_fit, 'name': "exp_fit", 'line': { 'color': 'rgb(5,103,166)', 'width': 2.5 }}, {'x': x_exp, 'y': res_interp, 'name': "exp_interp", \ 'line': { 'color': 'rgb(5,103,166)', 'width': 2.5, 'dash': 'dot' }}, {'x': x_theo, 'y': resiso_theo, 'name': "theo", 'line': { 'color': 'rgb(217,64,41)', 'width': 2.5}}, [0,0],\ [pars['compstr_disp'], pars['compstr_exp'], pars['tens_avail'], pars["last_updated"]]] except Exception as ex: raise ValueError('"REST Error: "{}"'.format(str(ex))) return {"valid_response": True, 'response': response}
def ellingham(request, cid, db_type=None, mdb=None): try: pars, _, _, response, payload, x_val = init_isographs(request=request, db_type=db_type, cid=cid, mdb=mdb) iso = pd.np.log(10**payload['iso']) delt = float(payload['del']) resiso, resiso_theo, ellingiso = [], [], [] if pars['experimental_data_available']: # only execute this if experimental data is available for xv in x_val: # calculate experimental data try: s_th = s_th_o(xv) args = (iso, xv, pars, s_th) solutioniso = ( dh_ds(delt, args[-1], args[-2])[0] - dh_ds(delt, args[-1], args[-2])[1] * xv) / 1000 resiso.append(solutioniso) ellingiso_i = isobar_line_elling(args[0], xv) / 1000 ellingiso.append(ellingiso_i) except ValueError: # if brentq function finds no zero point due to plot out of range resiso.append(None) res_interp, res_fit = [], [] for delta_val, res_i in zip(x_val, resiso): # show interpolation if pars['delta_min'] < delta_val < pars[ 'delta_max']: # result within experimentally covered delta range res_fit.append(res_i) res_interp.append(None) else: # result outside this range res_fit.append(None) res_interp.append(res_i) else: res_fit, res_interp = None, None # don't plot any experimental data if it is not available try: # calculate theoretical data for xv in x_val[:: 4]: # use less data points for theoretical graphs to improve speed dh = d_h_num_dev_calc(delta=delt, dh_1=pars['dh_min'], dh_2=pars['dh_max'], temp=xv, act=pars["act_mat"]) ds = d_s_fundamental(delta=delt, dh_1=pars['dh_min'], dh_2=pars['dh_max'], temp=xv, act=pars["act_mat"], t_d_perov=pars['td_perov'], t_d_brownm=pars['td_brownm']) solutioniso_theo = (dh - ds * xv) / 1000 resiso_theo.append(solutioniso_theo) except ValueError: # if brentq function finds no zero point due to plot out of range resiso_theo.append(None) x = list(x_val) x_theo = x[::4] if pars['experimental_data_available']: x_exp = x response = [{'x': x_exp, 'y': res_fit, 'name': 'exp_fit', 'line': { 'color': 'rgb(5,103,166)', 'width': 2.5 }}, {'x': x_exp, 'y': res_interp, 'name': 'exp_interp', \ 'line': { 'color': 'rgb(5,103,166)', 'width': 2.5, 'dash': 'dot' }}, {'x': x_theo, 'y': resiso_theo, 'name': 'theo', 'line': { 'color': 'rgb(217,64,41)', 'width': 2.5}}, {'x': x_exp, 'y': ellingiso, 'name': 'isobar line', 'line': { 'color': 'rgb(100,100,100)', 'width': 2.5}},\ [pars['compstr_disp'], pars['compstr_exp'], pars['tens_avail'], pars["last_updated"]]] else: x_exp = None for xv in x_theo: ellingiso_i = isobar_line_elling(iso, xv) / 1000 ellingiso.append(ellingiso_i) response = [{'x': x_exp, 'y': res_fit, 'name': 'exp_fit', 'line': { 'color': 'rgb(5,103,166)', 'width': 2.5 }}, {'x': x_exp, 'y': res_interp, 'name': 'exp_interp', \ 'line': { 'color': 'rgb(5,103,166)', 'width': 2.5, 'dash': 'dot' }}, {'x': x_theo, 'y': resiso_theo, 'name': 'theo', 'line': { 'color': 'rgb(217,64,41)', 'width': 2.5}}, {'x': x_theo, 'y': ellingiso, 'name': 'isobar line', 'line': { 'color': 'rgb(100,100,100)', 'width': 2.5}},\ [pars['compstr_disp'], pars['compstr_exp'], pars['tens_avail'], pars["last_updated"]]] except Exception as ex: raise ValueError('"REST Error: "{}"'.format(str(ex))) return {"valid_response": True, 'response': response}
def enthalpy_dH(request, cid, db_type=None, mdb=None): try: pars, _, _, response, payload, x_val = init_isographs(request=request, db_type=db_type, cid=cid, mdb=mdb) resiso, resiso_theo = [], [] if pars['experimental_data_available']: # only execute this if experimental data is available for xv in x_val: # calculate experimental data try: s_th = s_th_o(payload['iso']) args = (payload['iso'], xv, pars, s_th) solutioniso = dh_ds(xv, args[-1], args[-2])[0] / 1000 resiso.append(solutioniso) except ValueError: # if brentq function finds no zero point due to plot out of range resiso.append(None) res_interp, res_fit = [], [] for delta_val, res_i in zip(x_val, resiso): # show interpolation if pars['delta_min'] < delta_val < pars[ 'delta_max']: # result within experimentally covered delta range res_fit.append(res_i) res_interp.append(None) else: # result outside this range res_fit.append(None) res_interp.append(res_i) else: res_fit, res_interp = None, None # don't plot any experimental data if it is not available try: # calculate theoretical data for xv in x_val[:: 4]: # use less data points for theoretical graphs to improve speed args_theo = (payload['iso'], xv, pars, pars['td_perov'], pars['td_brownm'], \ pars["dh_min"], pars["dh_max"], pars["act_mat"]) solutioniso_theo = d_h_num_dev_calc(delta=xv, dh_1=pars["dh_min"], dh_2=pars["dh_max"], temp=payload['iso'], act=pars["act_mat"]) / 1000 resiso_theo.append(solutioniso_theo) except ValueError: # if brentq function finds no zero point due to plot out of range resiso_theo.append(None) x = list(x_val) x_theo = x[::4] x_exp = None if pars['experimental_data_available']: x_exp = x if max(pd.np.append(resiso, resiso_theo)) > ( pars['dh_max'] * 0.0015): # limiting values for the plot y_max = pars['dh_max'] * 0.0015 else: y_max = max(pd.np.append(resiso, resiso_theo)) * 1.2 if min(pd.np.append(resiso, resiso_theo)) < -10: y_min = -10 else: y_min = min(pd.np.append(resiso, resiso_theo)) * 0.8 response = [{'x': x_exp, 'y': res_fit, 'name': "exp_fit", 'line': { 'color': 'rgb(5,103,166)', 'width': 2.5 }}, {'x': x_exp, 'y': res_interp, 'name': "exp_interp", \ 'line': { 'color': 'rgb(5,103,166)', 'width': 2.5, 'dash': 'dot' }}, {'x': x_theo, 'y': resiso_theo, 'name': "theo", \ 'line': { 'color': 'rgb(217,64,41)', 'width': 2.5}}, [y_min,y_max], [pars['compstr_disp'], pars['compstr_exp'], pars['tens_avail'], pars["last_updated"]]] except Exception as ex: raise ValueError('"REST Error: "{}"'.format(str(ex))) return {"valid_response": True, 'response': response}
def calc(self, p_ox, p_red, t_ox, t_red, data_origin="Exp", data_use="combined", enth_steps=30, sample_ident=-1, celsius=True, from_file=True, heat_cap=True, heat_cap_approx=True ): """ Performs an energy analysis using experimental data. :param p_ox: Oxidation partial pressure of oxygen (in bar) or ratio p(H2)/p(H2O) / p(CO)/p(CO2) :param p_red: Oxygen partial pressure for reduction (in bar) :param t_ox: Oxidation temperature :param t_red: Reduction temperature :param data_origin: "Exp": experimental data "Theo": theoretical data ***only relevant if 'data_origin' = "Theo" :param data_use: "endmembers": uses redox members of solid solution endmembers to estimate redox enthalpies of solid solutions "combined": corrects above-mentioned data by the actual redox enthalpies for the solid solutions calcualted via DFT :param enth_steps: number of enthalpy values which are calculated for each material in order to reach a good approximation of the integral over dH vs. delta :param sample_ident: Sample number(s) (experimental data) or composition (theoretical data), default value '-1'-> analyze all samples :param pump_ener: allows to consider the pumping energy required to pump from p_o_2_1 to p_o_2_2 input in kJ per kg of redox material in the oxidized state + the losses This depends on many factors, such as the type of pumps used, the volume of the reaction chamber, the reactor type etc., so the user needs to calculate this value beforehand depending on the individual process conditions In case some of the pumping energy can be recovered, this share needs to be subtracted beforehand, as it is not considered herein. :param celsius: if True, assumes all input temperatures are in °C instead of K :param from_file: if True, takes the enthalpies, Debye temperatures, and materials lists from the file "theo_redenth_debye.json". Much faster than using the MPRester Only works if sample_ident = -1 :param heat_cap: if True, sensible energy to heat the samples is considered :param heat_cap_approx: if True, uses values for SrFeOx in case of missing heat capacity data :return: dict_result: dictonary with results for different materials """ si_first = sample_ident # correct temperature values for Kelvin/Celsius if celsius: temp_1_corr = t_ox + 273.15 temp_2_corr = t_red + 273.15 else: temp_1_corr = t_ox temp_2_corr = t_red if data_origin == "Exp": # currently not in use for updates of existing data # load experimental sample data from file path = os.path.abspath("") filepath = os.path.join(path, "exp_data.json") with open(filepath) as handle: expdata = json.loads(handle.read()) # use equivalent partial pressures for Water Splitting and CO2 splitting if self.process == "Water Splitting": p_ox = WaterSplitting().get_po2(temp=temp_1_corr, h2_h2o=p_ox) elif self.process == "CO2 Splitting": p_ox = CO2Splitting().get_po2(temp=temp_1_corr, co_co2=p_ox) # iterate over samples if isinstance(sample_ident, collections.Sized) and not isinstance(sample_ident, str): no_range = range(len(sample_ident)) sample = None else: no_range = range(1) if data_origin == "Exp": sample = int(sample_ident) else: sample = str(sample_ident) # iterate over all available samples if sample_ident == -1: sample = None if data_origin == "Exp": no_range = range(0, 150) sample_ident = no_range else: if not from_file: filename = os.path.join(os.path.abspath('..'), "datafiles", "perovskite_theo_list.csv") if not os.path.exists(filename): raise ImportError("File 'perovskite_theo_list.csv' not found.") fo = open(filename, "rb") sample_ident = pd.np.genfromtxt(fo, dtype='str', delimiter=",", skip_header=1) fo.close() else: sampledata = views.get_theo_data() sample_ident = sampledata["compstr"] no_range = range(len(sample_ident)) sample_l, chemical_energy_l, sensible_energy_l, mol_mass_ox_l, prodstr_alt_l = [], [], [], [], [] mol_prod_mol_red_l, t_ox_l, t_red_l, p_ox_l, p_red_l, compstr_l = [], [], [], [], [], [] delta_1_l, delta_2_l, mass_redox_l, prodstr_l, l_prod_kg_red_l, g_prod_kg_red_l = [], [], [], [], [], [] for i in no_range: if not sample: sample = sample_ident[i] # this only works if the sample number/data exists try: if data_origin == "Exp": exp_index = -1 for k in range(len(expdata)): if int(expdata["Sample number"][k]) == sample: exp_index = k if exp_index == -1: raise ValueError("Experimental data for this sample not found.") compstr = expdata["theo_compstr"][exp_index] compstr_x = compstr.split("Ox")[0] # this formats the parameters the same way we have them in views.py fit_param_enth = {"a": float(expdata["dH_max"][exp_index]), "b": float(expdata["dH_min"][exp_index]), "c": float(expdata["t"][exp_index]), "d": float(expdata["s"][exp_index])} fit_type_entr = str(expdata["fit type entropy"][exp_index]) if fit_type_entr == "Dilute_Species": fit_par_ent = {"a": float(expdata["entr_dil_s_v"][exp_index]), "b": float(expdata["entr_dil_a"][exp_index]), "c": float(expdata["delta_0"][exp_index])} else: fit_par_ent = {"a": float(expdata["entr_solid_sol_s"][exp_index]), "b": float(expdata["entr_solid_sol_shift"][exp_index]), "c": float(expdata["delta_0"][exp_index])} theo_compstr = compstr splitcomp = split_comp(compstr) delta_0 = float(expdata["delta_0"][exp_index]) actf = find_active(mat_comp=splitcomp)[1] act_mat = {"Material": float(actf)} fit_param_fe = {"a": 231.062, "b": -24.3338, "c": 0.839785, "d": 0.219157} pars = { "fit_par_ent": fit_par_ent, "fit_param_enth": fit_param_enth, "fit_type_entr": fit_type_entr, "delta_0": delta_0, "fit_param_fe": fit_param_fe, "act_mat": act_mat } args_1 = (pd.np.log(p_ox), temp_1_corr, pars, s_th_o(temp_1_corr)) args_2 = (pd.np.log(p_red), temp_2_corr, pars, s_th_o(temp_2_corr)) delta_1 = rootfind(1e-10, 0.5-1e-10, args_1, funciso) delta_2 = rootfind(1e-10, 0.5-1e-10, args_2, funciso) # use theoretical elastic tensors sampledata = views.get_theo_data() for z in range(len(sampledata["compstr"])): if (sampledata["compstr"][z]).split("O3")[0] == compstr.split("Ox")[0]: index_debye = z t_d_perov = float(sampledata["Debye temp perovskite"][index_debye]) t_d_brownm = float(sampledata["Debye temp brownmillerite"][index_debye]) else: # if composition does not contain ones as stoichiometries, add them sample = add_comp_one(compstr=sample) if not from_file or si_first != -1: try: red_active = redenth_act(sample) except TypeError: raise ValueError("Enthalpy data not available for this material.") h_min = red_active[1] h_max = red_active[2] act = red_active[3] else: h_min = float(sampledata["dH_min"][i]) h_max = float(sampledata["dH_max"][i]) act = float(sampledata["act"][i]) compstr = sample compstr_x = compstr.split("O")[0] if not from_file or si_first != -1: try: # get Debye temperatures for vibrational entropy mp_ids = get_mpids_comps_perov_brownm(compstr=compstr) t_d_perov = get_debye_temp(mp_ids[0]) t_d_brownm = get_debye_temp(mp_ids[1]) except Exception as e: # if no elastic tensors or no data for this material is available mp_ids = ("mp-510624", "mp-561589") # using data for SrFeOx if no data is available (close approximation) t_d_perov = get_debye_temp(mp_ids[0]) t_d_brownm = get_debye_temp(mp_ids[1]) else: t_d_perov = float(sampledata["Debye temp perovskite"][i]) t_d_brownm = float(sampledata["Debye temp brownmillerite"][i]) args_theo_1 = (pd.np.log(p_ox), temp_1_corr, None, t_d_perov, t_d_brownm, h_min, h_max, act) delta_1 = rootfind(1e-10, 0.5-1e-10, args_theo_1, funciso_theo) args_theo_2 = (pd.np.log(p_red), temp_2_corr, None, t_d_perov, t_d_brownm, h_min, h_max, act) delta_2 = rootfind(1e-10, 0.5-1e-10, args_theo_2, funciso_theo) # calculate the mass change in % comp_ox = compstr_x + "O" + str(float(3 - delta_1)) comp_red = compstr_x + "O" + str(float(3 - delta_2)) mol_mass_ox = float(Composition(comp_ox).weight) mol_mass_red = float(Composition(comp_red).weight) mass_redox_i = ((mol_mass_ox - mol_mass_red) / mol_mass_ox) * 100 # define reaction products if self.process == "Air Separation": prodstr = "O2" prodstr_alt = "O" elif self.process == "Water Splitting": prodstr = "H2" prodstr_alt = prodstr elif self.process == "CO2 Splitting": prodstr = "CO" prodstr_alt = prodstr else: raise ValueError("Process must be either Air Separation, Water Splitting, or CO2 Splitting!") # only continue if the user-designated reduction step actually leads to reduction # if not, set result to infinite if delta_2 < delta_1: ener_i = pd.np.ones(5) * float('inf') per_kg_redox = pd.np.ones(5) * float('inf') per_kg_wh_redox = pd.np.ones(5) * float('inf') kj_mol_prod = pd.np.ones(5) * float('inf') energy_l = pd.np.ones(5) * float('inf') energy_l_wh = pd.np.ones(5) * float('inf') efficiency = float('inf') mol_prod_mol_red = float('inf') l_prod_kg_red = float('inf') g_prod_kg_red = float('inf') else: # mol product per mol of redox material mol_prod_mol_red = delta_2 - delta_1 # L product per kg of redox material (SATP) l_prod_kg_red = mol_prod_mol_red * (24.465 / (0.001 * mol_mass_ox)) # convert mol O to mol O2 if self.process == "Air Separation": l_prod_kg_red = l_prod_kg_red * 0.5 # g product per kg redox material g_prod_kg_red = float(Composition(prodstr).weight) * (l_prod_kg_red / 24.465) if data_origin == "Exp": d_delta = delta_0 else: d_delta = 0.0 # correct for d_delta d_delta_1 = delta_1 - d_delta d_delta_2 = delta_2 - d_delta # chemical energy if data_origin == "Exp": s_th_mean = (s_th_o(temp_1_corr) + s_th_o(temp_1_corr)) / 2 def dh_func_exp(d_delta_func): return dh_ds(d_delta_func, s_th_mean, pars)[0] energy_integral_dh = quad(dh_func_exp, d_delta_1, d_delta_2)[0] if energy_integral_dh < 0: raise ValueError("negative chemical energy due to insuffiencent experimental data...skipping this sample") else: energy_integral_dh = EnergyAnalysis(process=self.process).energy_integral_theo( celsius=celsius, compstr=compstr, dh_max=h_max, dh_min=h_min, enth_steps=enth_steps, p_o_2_1=p_ox, p_o_2_2=p_red, temp_1=t_ox, temp_2=t_red, t_d_perov=t_d_perov, t_d_brownm = t_d_brownm) # sensible energy energy_sensible = 0 if heat_cap: energy_sensible = EnergyAnalysis().heat_input_linear(temp_1=temp_1_corr, temp_2=temp_2_corr, delta_1=delta_1, delta_2=delta_2, t_d_perov=t_d_perov, t_d_brownm=t_d_brownm, num=40) / 1000 chemical_energy_l.append(energy_integral_dh) sensible_energy_l.append(energy_sensible) mol_mass_ox_l.append(mol_mass_ox) mol_prod_mol_red_l.append(mol_prod_mol_red) t_ox_l.append(temp_1_corr) t_red_l.append(temp_2_corr) p_ox_l.append(p_ox) p_red_l.append(p_red) compstr_l.append(compstr) delta_1_l.append(delta_1) delta_2_l.append(delta_2) mass_redox_l.append(mass_redox_i) prodstr_l.append(prodstr) prodstr_alt_l.append(prodstr_alt) l_prod_kg_red_l.append(l_prod_kg_red) g_prod_kg_red_l.append(g_prod_kg_red) # skip this sample if the sample number does not exist except Exception as e: pass #print("No data for sample " + str(sample) + " found!" + str(e)) sample = None resdict = { "Chemical Energy": chemical_energy_l, "Sensible Energy": sensible_energy_l, "mol_mass_ox": mol_mass_ox_l, "mol_prod_mol_red": mol_prod_mol_red_l, "T_ox": t_ox_l, "T_red": t_red_l, "p_ox": p_ox_l, "p_red": p_red_l, "compstr": compstr_l, "delta_1": delta_1_l, "delta_2": delta_2_l, "mass_redox": mass_redox_l, "prodstr": prodstr_l, "prodstr_alt": prodstr_alt_l, "l_prod_kg_red": l_prod_kg_red_l, "g_prod_kg_red": g_prod_kg_red_l} return resdict
def ellingham(request, cid, db_type=None, mdb=None): try: pars, _, _, response, payload, x_val = init_isographs(request=request, db_type=db_type, cid=cid, mdb=mdb) iso = pd.np.log(10**payload['iso']) delt = float(payload['del']) resiso, resiso_theo, ellingiso = [], [], [] if pars['experimental_data_available']: # only execute this if experimental data is available for xv in x_val: # calculate experimental data try: s_th = s_th_o(xv) args = (iso, xv, pars, s_th) solutioniso = (dh_ds(delt, args[-1], args[-2])[0] - dh_ds(delt, args[-1], args[-2])[1]*xv)/1000 resiso.append(solutioniso) ellingiso_i = isobar_line_elling(args[0], xv)/1000 ellingiso.append(ellingiso_i) except ValueError: # if brentq function finds no zero point due to plot out of range resiso.append(None) res_interp, res_fit = [], [] for delta_val, res_i in zip(x_val, resiso): # show interpolation if pars['delta_min'] < delta_val < pars['delta_max']: # result within experimentally covered delta range res_fit.append(res_i) res_interp.append(None) else: # result outside this range res_fit.append(None) res_interp.append(res_i) else: res_fit, res_interp = None, None # don't plot any experimental data if it is not available try: # calculate theoretical data for xv in x_val[::4]: # use less data points for theoretical graphs to improve speed dh = d_h_num_dev_calc(delta=delt, dh_1=pars['dh_min'], dh_2=pars['dh_max'], temp=xv, act=pars["act_mat"]) ds = d_s_fundamental(delta=delt, dh_1=pars['dh_min'], dh_2=pars['dh_max'], temp=xv, act=pars["act_mat"], t_d_perov=pars['td_perov'], t_d_brownm=pars['td_brownm']) solutioniso_theo = (dh - ds*xv)/1000 resiso_theo.append(solutioniso_theo) except ValueError: # if brentq function finds no zero point due to plot out of range resiso_theo.append(None) x = list(x_val) x_theo = x[::4] if pars['experimental_data_available']: x_exp = x response = [{'x': x_exp, 'y': res_fit, 'name': 'exp_fit', 'line': { 'color': 'rgb(5,103,166)', 'width': 2.5 }}, {'x': x_exp, 'y': res_interp, 'name': 'exp_interp', \ 'line': { 'color': 'rgb(5,103,166)', 'width': 2.5, 'dash': 'dot' }}, {'x': x_theo, 'y': resiso_theo, 'name': 'theo', 'line': { 'color': 'rgb(217,64,41)', 'width': 2.5}}, {'x': x_exp, 'y': ellingiso, 'name': 'isobar line', 'line': { 'color': 'rgb(100,100,100)', 'width': 2.5}},\ [pars['compstr_disp'], pars['compstr_exp'], pars['tens_avail'], pars["last_updated"]]] else: x_exp = None for xv in x_theo: ellingiso_i = isobar_line_elling(iso, xv)/1000 ellingiso.append(ellingiso_i) response = [{'x': x_exp, 'y': res_fit, 'name': 'exp_fit', 'line': { 'color': 'rgb(5,103,166)', 'width': 2.5 }}, {'x': x_exp, 'y': res_interp, 'name': 'exp_interp', \ 'line': { 'color': 'rgb(5,103,166)', 'width': 2.5, 'dash': 'dot' }}, {'x': x_theo, 'y': resiso_theo, 'name': 'theo', 'line': { 'color': 'rgb(217,64,41)', 'width': 2.5}}, {'x': x_theo, 'y': ellingiso, 'name': 'isobar line', 'line': { 'color': 'rgb(100,100,100)', 'width': 2.5}},\ [pars['compstr_disp'], pars['compstr_exp'], pars['tens_avail'], pars["last_updated"]]] except Exception as ex: raise ValueError('"REST Error: "{}"'.format(str(ex))) return {"valid_response": True, 'response': response}