diff --git a/docs/_build/doctrees/environment.pickle b/docs/_build/doctrees/environment.pickle index bfa0d33..9aea328 100644 Binary files a/docs/_build/doctrees/environment.pickle and b/docs/_build/doctrees/environment.pickle differ diff --git a/docs/_build/doctrees/guide/about.doctree b/docs/_build/doctrees/guide/about.doctree new file mode 100644 index 0000000..ef90f74 Binary files /dev/null and b/docs/_build/doctrees/guide/about.doctree differ diff --git a/docs/_build/doctrees/guide/install.doctree b/docs/_build/doctrees/guide/install.doctree index 46eb899..88d39c3 100644 Binary files a/docs/_build/doctrees/guide/install.doctree and b/docs/_build/doctrees/guide/install.doctree differ diff --git a/docs/_build/doctrees/guide/quickstart.doctree b/docs/_build/doctrees/guide/quickstart.doctree index 3f643f7..bfd9bfb 100644 Binary files a/docs/_build/doctrees/guide/quickstart.doctree and b/docs/_build/doctrees/guide/quickstart.doctree differ diff --git a/docs/_build/doctrees/index.doctree b/docs/_build/doctrees/index.doctree index 9a0fc6a..9d5c4ce 100644 Binary files a/docs/_build/doctrees/index.doctree and b/docs/_build/doctrees/index.doctree differ diff --git a/docs/_build/doctrees/modules/LLEPE.doctree b/docs/_build/doctrees/modules/LLEPE.doctree new file mode 100644 index 0000000..9b52f4a Binary files /dev/null and b/docs/_build/doctrees/modules/LLEPE.doctree differ diff --git a/docs/_build/doctrees/modules/reeps.doctree b/docs/_build/doctrees/modules/reeps.doctree index e316e1a..87fd4d1 100644 Binary files a/docs/_build/doctrees/modules/reeps.doctree and b/docs/_build/doctrees/modules/reeps.doctree differ diff --git a/docs/_build/html/.buildinfo b/docs/_build/html/.buildinfo index d0738d2..51dc31b 100644 --- a/docs/_build/html/.buildinfo +++ b/docs/_build/html/.buildinfo @@ -1,4 +1,4 @@ # Sphinx build info version 1 # This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. -config: 09c8b5742a1f96cda53a1848d8ac9ec1 +config: fdde7da710e99305b2f90b2ffb8f91ce tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/docs/_build/html/_modules/index.html b/docs/_build/html/_modules/index.html index ca853b9..d96106f 100644 --- a/docs/_build/html/_modules/index.html +++ b/docs/_build/html/_modules/index.html @@ -85,10 +85,11 @@

Searchers

@@ -151,7 +152,6 @@

All modules for which code is available

@@ -164,7 +164,7 @@

- © Copyright 2020, Titus Quah, Nwike Iloeje + © Copyright 2020, UChicago Argonne, LLC.

diff --git a/docs/_build/html/_modules/llepe/llepe.html b/docs/_build/html/_modules/llepe/llepe.html index bf78f9b..13e2620 100644 --- a/docs/_build/html/_modules/llepe/llepe.html +++ b/docs/_build/html/_modules/llepe/llepe.html @@ -85,10 +85,11 @@

Searchers

@@ -169,7 +170,7 @@ from .utils import set_size -
[docs]class LLEPE: +
[docs]class LLEPE: r""" Liquid-Liquid Extraction Parameter estimator @@ -180,7 +181,7 @@ must be the same order as they appear in the xml, complex_names and extracted_species_ion_names. - For example, say in exp_csv_filename's csv, ES_1 is Nd ES_2 is Pr, + For example, say in exp_data, ES_1 is Nd ES_2 is Pr, and .. code-block:: python @@ -191,7 +192,7 @@ Then: - The csvs column ordering must be: + The exp_data column ordering must be (names do not matter): [h_i, h_eq, z_i, z_eq, Nd_aq_i, Nd_aq_eq, Nd_d_eq, Pr_aq_i, Pr_aq_eq, Pr_d_eq] @@ -526,7 +527,8 @@ self._predicted_dict = None self.update_predicted_dict() -
[docs] @staticmethod + # TODO: move scipy_minimize to optimizers +
[docs] @staticmethod def scipy_minimize(objective, x_guess, optimizer_kwargs=None): """ The default optimizer for LLEPE @@ -560,7 +562,8 @@ est_parameters = res.x return est_parameters, res.fun
-
[docs] def log_mean_squared_error(self, predicted_dict, meas_df): + # TODO: move log_mean_squared_error to objectives +
[docs] def log_mean_squared_error(self, predicted_dict, meas_df): """Default objective function for LLEPE Returns the log mean squared error of @@ -584,14 +587,14 @@ obj = np.sum(log_diff) return obj
-
[docs] def get_exp_df(self) -> pd.DataFrame: +
[docs] def get_exp_df(self) -> pd.DataFrame: """Returns the experimental DataFrame :return: (pd.DataFrame) Experimental data """ return self._exp_df
-
[docs] def set_exp_df(self, exp_data): +
[docs] def set_exp_df(self, exp_data): """Changes the experimental DataFrame to input exp_csv_filename data and renames columns to internal LLEPE names @@ -632,7 +635,7 @@ self.update_predicted_dict() return None
-
[docs] def get_phases(self) -> list: +
[docs] def get_phases(self) -> list: """ Returns the list of Cantera solutions @@ -640,7 +643,7 @@ """ return self._phases
-
[docs] def set_phases(self, phases_xml_filename, phase_names): +
[docs] def set_phases(self, phases_xml_filename, phase_names): """Change list of Cantera solutions by inputting new xml file name and phase names @@ -673,7 +676,7 @@ self.update_predicted_dict() return None
-
[docs] def get_opt_dict(self) -> dict: +
[docs] def get_opt_dict(self) -> dict: """ Returns the dictionary containing optimization information @@ -682,7 +685,7 @@ """ return self._opt_dict
-
[docs] def set_opt_dict(self, opt_dict): +
[docs] def set_opt_dict(self, opt_dict): """ Change the dictionary to input opt_dict. @@ -698,14 +701,14 @@ self._opt_dict = opt_dict return None
-
[docs] def get_aq_solvent_name(self) -> str: +
[docs] def get_aq_solvent_name(self) -> str: """Returns aq_solvent_name :return: aq_solvent_name: (str) name of aqueous solvent in xml file """ return self._aq_solvent_name
-
[docs] def set_aq_solvent_name(self, aq_solvent_name): +
[docs] def set_aq_solvent_name(self, aq_solvent_name): """ Change aq_solvent_name to input aq_solvent_name :param aq_solvent_name: (str) name of aqueous solvent in xml file @@ -713,14 +716,14 @@ self._aq_solvent_name = aq_solvent_name return None
-
[docs] def get_extractant_name(self) -> str: +
[docs] def get_extractant_name(self) -> str: """Returns extractant name :return: extractant_name: (str) name of extractant in xml file """ return self._extractant_name
-
[docs] def set_extractant_name(self, extractant_name): +
[docs] def set_extractant_name(self, extractant_name): """ Change extractant_name to input extractant_name :param extractant_name: (str) name of extractant in xml file @@ -728,13 +731,13 @@ self._extractant_name = extractant_name return None
-
[docs] def get_diluant_name(self) -> str: +
[docs] def get_diluant_name(self) -> str: """ Returns diluant name :return: diluant_name: (str) name of diluant in xml file """ return self._diluant_name
-
[docs] def set_diluant_name(self, diluant_name): +
[docs] def set_diluant_name(self, diluant_name): """ Change diluant_name to input diluant_name @@ -743,14 +746,14 @@ self._diluant_name = diluant_name return None
-
[docs] def get_complex_names(self) -> list: +
[docs] def get_complex_names(self) -> list: """Returns list of complex names :return: complex_names: (list) names of complexes in xml file. """ return self._complex_names
-
[docs] def set_complex_names(self, complex_names): +
[docs] def set_complex_names(self, complex_names): """Change complex names list to input complex_names :param complex_names: (list) names of complexes in xml file. @@ -758,7 +761,7 @@ self._complex_names = complex_names return None
-
[docs] def get_extracted_species_ion_names(self) -> list: +
[docs] def get_extracted_species_ion_names(self) -> list: """Returns list of extracted species ion names :return: extracted_species_ion_names: (list) names of @@ -766,7 +769,7 @@ """ return self._extracted_species_ion_names
-
[docs] def set_extracted_species_ion_names(self, extracted_species_ion_names): +
[docs] def set_extracted_species_ion_names(self, extracted_species_ion_names): """Change list of extracted species ion names to input extracted_species_ion_names @@ -776,7 +779,7 @@ self._extracted_species_ion_names = extracted_species_ion_names return None
-
[docs] def get_extracted_species_list(self) -> list: +
[docs] def get_extracted_species_list(self) -> list: """Returns list of extracted species names :return: extracted_species_list: (list) names of extracted species in @@ -784,7 +787,7 @@ """ return self._extracted_species_list
-
[docs] def set_extracted_species_list(self, extracted_species_list): +
[docs] def set_extracted_species_list(self, extracted_species_list): """Change list of extracted species ion names to input extracted_species_ion_names @@ -794,14 +797,14 @@ self._extracted_species_list = extracted_species_list return None
-
[docs] def get_aq_solvent_rho(self) -> str: +
[docs] def get_aq_solvent_rho(self) -> str: """Returns aqueous solvent density (g/L) :return: aq_solvent_rho: (float) density of aqueous solvent """ return self._aq_solvent_rho
-
[docs] def set_aq_solvent_rho(self, aq_solvent_rho): +
[docs] def set_aq_solvent_rho(self, aq_solvent_rho): """Changes aqueous solvent density (g/L) to input aq_solvent_rho :param aq_solvent_rho: (float) density of aqueous solvent @@ -809,14 +812,14 @@ self._aq_solvent_rho = aq_solvent_rho return None
-
[docs] def get_extractant_rho(self) -> str: +
[docs] def get_extractant_rho(self) -> str: """Returns extractant density (g/L) :return: extractant_rho: (float) density of extractant """ return self._extractant_rho
-
[docs] def set_extractant_rho(self, extractant_rho): +
[docs] def set_extractant_rho(self, extractant_rho): """Changes extractant density (g/L) to input extractant_rho :param extractant_rho: (float) density of extractant @@ -824,14 +827,14 @@ self._extractant_rho = extractant_rho return None
-
[docs] def get_diluant_rho(self) -> str: +
[docs] def get_diluant_rho(self) -> str: """Returns diluant density (g/L) :return: diluant_rho: (float) density of diluant """ return self._diluant_rho
-
[docs] def set_diluant_rho(self, diluant_rho): +
[docs] def set_diluant_rho(self, diluant_rho): """Changes diluant density (g/L) to input diluant_rho :param diluant_rho: (float) density of diluant @@ -839,7 +842,12 @@ self._diluant_rho = diluant_rho return None
-
[docs] def set_in_moles(self, feed_vol): + # TODO: Change input DataFrame structure to contain information about + # other species like NaCl + # TODO: Change DataFrame structure to contain info about O/A ratio + # TODO: Generalize code to more than just org and aq phase (3+ phases) + # TODO: Handle multiple electrolytes ie. NO3- with Cl- +
[docs] def set_in_moles(self, feed_vol): """Function that initializes mole fractions to input feed_vol This function is called at initialization @@ -922,7 +930,7 @@ for extracted_species in extracted_species_list]) extracted_species_charge_sum = np.sum( extracted_species_charges * extracted_species_moles) - chlorine_moles = extracted_species_charge_sum + h_plus_moles + anion_moles = extracted_species_charge_sum + h_plus_moles extractant_moles = feed_vol * row['z_i'] extractant_vol = extractant_moles * extractant_mw / extractant_rho diluant_vol = feed_vol - extractant_vol @@ -932,7 +940,7 @@ species_moles_aq = [aq_phase_solvent_moles, h_plus_moles, hydroxide_ions, - chlorine_moles] + anion_moles] species_moles_aq.extend(list(extracted_species_moles)) species_moles_org = [extractant_moles, diluant_moles] species_moles_org.extend(list(complex_moles)) @@ -946,7 +954,7 @@ self.update_predicted_dict() return None
-
[docs] def get_in_moles(self) -> pd.DataFrame: +
[docs] def get_in_moles(self) -> pd.DataFrame: """Returns the in_moles DataFrame which contains the initial mole fractions of each species for each experiment @@ -954,7 +962,7 @@ """ return self._in_moles
-
[docs] def set_objective_function(self, objective_function): +
[docs] def set_objective_function(self, objective_function): """Change objective function to input objective_function. See class docstring on "objective_function" for instructions @@ -979,7 +987,7 @@ self._objective_function = objective_function return None
-
[docs] def get_objective_function(self): +
[docs] def get_objective_function(self): """Returns objective function :return: objective_function: (func) Objective function to quantify @@ -987,7 +995,7 @@ """ return self._objective_function
-
[docs] def set_optimizer(self, optimizer): +
[docs] def set_optimizer(self, optimizer): """Change optimizer function to input optimizer. See class docstring on "optimizer" for instructions @@ -1012,7 +1020,7 @@ self._optimizer = optimizer return None
-
[docs] def get_optimizer(self): +
[docs] def get_optimizer(self): """Returns objective function :return: optimizer: (func) Optimizer function to minimize objective @@ -1020,7 +1028,7 @@ """ return self._optimizer
-
[docs] def get_temp_xml_file_path(self): +
[docs] def get_temp_xml_file_path(self): """Returns path to temporary xml file. This xml file is a duplicate of the phases_xml_file name and is @@ -1031,7 +1039,7 @@ """ return self._temp_xml_file_path
-
[docs] def set_temp_xml_file_path(self, temp_xml_file_path): +
[docs] def set_temp_xml_file_path(self, temp_xml_file_path): """Changes temporary xml file path to input temp_xml_file_path. This xml file is a duplicate of the phases_xml_file name and is @@ -1043,7 +1051,7 @@ self._temp_xml_file_path = temp_xml_file_path return None
-
[docs] def get_dependant_params_dict(self): +
[docs] def get_dependant_params_dict(self): """ Returns the dependant_params_dict @@ -1052,7 +1060,7 @@ """ return self._dependant_params_dict
-
[docs] def set_dependant_params_dict(self, dependant_params_dict): +
[docs] def set_dependant_params_dict(self, dependant_params_dict): """ Sets the dependant_params_dict @@ -1062,7 +1070,7 @@ self._dependant_params_dict = dependant_params_dict return None
-
[docs] def get_custom_objects_dict(self): +
[docs] def get_custom_objects_dict(self): """ Returns the custom_objects_dict @@ -1071,7 +1079,7 @@ """ return self._custom_objects_dict
-
[docs] def set_custom_objects_dict(self, custom_objects_dict): +
[docs] def set_custom_objects_dict(self, custom_objects_dict): """ Sets the custom_objects_dict @@ -1081,7 +1089,11 @@ self._custom_objects_dict = custom_objects_dict return None
-
[docs] def update_predicted_dict(self, + # TODO: Change DataFrame strucutre to contain info whether to set + # equilibrium pH to measured value. Will be useful for saponification + # TODO: Find way to add saponification to model. + # Maybe use fsolve to match experimental equilibrium pH +
[docs] def update_predicted_dict(self, phases_xml_filename=None, phase_names=None): """Function that computes the predicted equilibrium concentrations @@ -1148,7 +1160,7 @@ self._predicted_dict = predicted_dict return None
-
[docs] def get_predicted_dict(self): +
[docs] def get_predicted_dict(self): """Returns predicted dictionary of species concentrations that xml parameters predicts given current in_moles @@ -1212,7 +1224,7 @@ objective_values = objective_values[0] return objective_values -
[docs] def fit(self, +
[docs] def fit(self, objective_function=None, optimizer=None, objective_kwargs=None, @@ -1255,7 +1267,7 @@ return opt_dict, obj_value
-
[docs] def update_xml(self, +
[docs] def update_xml(self, info_dict, phases_xml_filename=None, dependant_params_dict=None): @@ -1362,7 +1374,7 @@ self.set_phases(self._phases_xml_filename, self._phase_names) return None
-
[docs] def update_custom_objects_dict(self, info_dict): +
[docs] def update_custom_objects_dict(self, info_dict): """ updates internal custom_objects_dict with info_dict @@ -1387,7 +1399,7 @@ self._custom_objects_dict = custom_objects_dict return None
-
[docs] def parity_plot(self, +
[docs] def parity_plot(self, compared_value=None, c_data=None, c_label=None, @@ -1496,7 +1508,9 @@ filtered_meas = filtered_data['meas'] filtered_pred = filtered_data['pred'] if len(filtered_pred) != 0: - ax.scatter(filtered_meas, filtered_pred, label=label) + ax.scatter(filtered_meas, + filtered_pred, + label=label) if legend: ax.legend(loc='best') @@ -1531,7 +1545,7 @@ plt.savefig(save_path, bbox_inches='tight') return fig, ax
-
[docs] def r_squared(self, compared_value=None): +
[docs] def r_squared(self, compared_value=None): """r-squared value comparing measured and predicted compared value Closer to 1, the better the model's predictions. @@ -1571,7 +1585,7 @@ r_2 = (1 - num / den) return r_2
-
[docs] @staticmethod +
[docs] @staticmethod def plot_3d_data(x_data, y_data, z_data, @@ -1581,6 +1595,8 @@ z_label=None, c_label=None): """ + THis is for plotting 3d scatter plots. + We suggest use matplotlib's ax.scatter to make 3d plots. :param x_data: (list) list of data for x axis :param y_data: (list) list of data for y axis @@ -1631,7 +1647,7 @@

- © Copyright 2020, Titus Quah, Nwike Iloeje + © Copyright 2020, UChicago Argonne, LLC.

diff --git a/docs/_build/html/_modules/reeps/reeps.html b/docs/_build/html/_modules/reeps/reeps.html deleted file mode 100644 index bb9a06e..0000000 --- a/docs/_build/html/_modules/reeps/reeps.html +++ /dev/null @@ -1,1735 +0,0 @@ - - - - - - - - - - - reeps.reeps — LLEPE 1.0.0 documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - -
- - - - - -
- -
- - - - - - - - - - - - - - - - - -
- - - - -
-
-
-
- -

Source code for reeps.reeps

-from datetime import datetime
-import cantera as ct
-import pandas as pd
-import numpy as np
-from scipy.optimize import minimize
-# noinspection PyPep8Naming
-import xml.etree.ElementTree as ET
-import seaborn as sns
-import matplotlib.pyplot as plt
-import shutil
-import copy
-from inspect import signature
-import os
-import re
-import pkg_resources
-from .utils import set_size
-
-sns.set()
-sns.set(font_scale=1.6)
-
-
-
[docs]class REEPS: - r""" - Rare earth elements (REE or RE) Takes in experimental data - Returns parameters for GEM - - .. note:: - - The order in which the REEs appear in the csv file must be the same - order as they appear in the xml, complex_names and - rare_earth_ion_names. - - For example, say in exp_csv_filename's csv, RE_1 is Nd RE_2 is Pr, - and - - .. code-block:: python - - aq_solvent_name = 'H2O(L)' - extractant_name = '(HA)2(org)' - diluent_name = 'dodecane' - - Then: - - The csvs column ordering must be: - - [h_i, h_eq, z_i, z_eq, Nd_aq_i, Nd_aq_eq, Nd_d_eq, - Pr_aq_i, Pr_aq_eq, Pr_d_eq] - - The aqueous speciesArray must be - "H2O(L) H+ OH- Cl- Nd+++ Pr+++" - - The organic speciesArray must be - "(HA)2(org) dodecane Nd(H(A)2)3(org) Pr(H(A)2)3(org)" - - .. code-block:: python - - complex_names = ['Nd(H(A)2)3(org)', 'Pr(H(A)2)3(org)'] - rare_earth_ion_names = ['Nd+++', 'Pr+++'] - - - :param exp_data: (str) csv file name with experimental data - - In the .csv file, the rows are different experiments and - columns are the measured quantities. - - The ordering of the columns needs to be: - - [h_i, h_eq, z_i, z_eq, - {RE_1}_aq_i, {RE_1}_aq_eq, {RE_1}_d_eq, - {RE_2}_aq_i, {RE_2}_aq_eq, {RE_2}_d_eq,... - {RE_N}_aq_i, {RE_N}_aq_eq, {RE_N}_d_eq] - - Naming does not matter, just the order. - - Where {RE_1}-{RE_N} are the rare earth element names of interest - i.e. Nd, Pr, La, etc. - - Below is an explanation of the columns. - - +-------+------------+------------------------------------------+ - | Index | Column | Meaning | - +=======+============+==========================================+ - | 0 | h_i | Initial Concentration of | - | | | H+ ions (mol/L) | - +-------+------------+------------------------------------------+ - | 1 | h_eq | Equilibrium concentration of | - | | | H+ ions (mol/L) | - +-------+------------+------------------------------------------+ - | 2 | z_i | Initial concentration of | - | | | extractant (mol/L) | - +-------+------------+------------------------------------------+ - | 3 | z_eq | Equilibrium concentration of | - | | | extractant (mol/L) | - +-------+------------+------------------------------------------+ - | 4 | {RE}_aq_i | Initial concentration of RE ions (mol/L) | - +-------+------------+------------------------------------------+ - | 5 | {RE}_aq_eq | Equilibrium concentration of RE ions | - | | | in aqueous phase (mol/L) | - +-------+------------+------------------------------------------+ - | 6 | {RE}_d_eq | Equilibrium Ratio between amount of | - | | | RE atoms in organic to aqueous | - +-------+------------+------------------------------------------+ - :param phases_xml_filename: (str) xml file with parameters - for equilibrium calc - - Would recommend copying and modifying xmls located in data/xmls - or in Cantera's "data" folder - - speciesArray fields need specific ordering. - - In aqueous phase: aq_solvent_name, H+, OH-, Cl-, RE_1, RE_2, ..., RE_N - - For aqueous phase, RE_1-RE_N represent RE ion names i.e. Nd+++, Pr+++ - - In organic phase : extractant_name, diluant_name, RE_1, RE_2, ..., RE_N - - For organic phase, RE_1-RE_N represent RE complex names - i.e. Nd(H(A)2)3(org), Pr(H(A)2)3(org) - - :param phase_names: (list) names of phases in xml file - - Found in the xml file under <phase ... id={phase_name}> - - :param aq_solvent_name: (str) name of aqueous solvent in xml file - :param extractant_name: (str) name of extractant in xml file - :param diluant_name: (str) name of diluant in xml file - :param complex_names: (list) names of complexes in xml file. - - Ensure the ordering is correct - :param rare_earth_ion_names: (list) names of rare earth ions in xml file - - Ensure the ordering is correct - :param re_species_list: (list) names of rare earth elements. - - If ``None``, re_species_list will be rare_earth_ion_names without '+' - i.e. 'Nd+++'->'Nd' - - Ensure the ordering is correct - :param aq_solvent_rho: (float) density of solvent (g/L) - - If ``None``, molar volume/molecular weight is used from xml - :param extractant_rho: (float) density of extractant (g/L) - - If ``None``, molar volume/molecular weight is used from xml - :param diluant_rho: (float) density of diluant (g/L) - - If ``None``, molar volume/molecular weight is used from xml - :param opt_dict: (dict) dictionary containing info about which - species parameters are updated to fit model to experimental data - - Should have the format as below. Dictionary keys under user defined - parameter name must be named as shown below ('upper_element_name', - 'upper_attrib_name', etc.). 'attrib_name's and 'attrib_value's can - be None. {} denotes areas for user to fill in. - - .. code-block:: python - - opt_dict = {"{user_defined_name_for_parameter_1}": - {'upper_element_name': {param_upper_element}, - 'upper_attrib_name': {param_upper_attrib_name}, - 'upper_attrib_value': {param_upper_attrib_value}, - 'lower_element_name': {param_lower_element}, - 'lower_attrib_name': {param_lower_attrib_name}, - 'lower_attrib_value': {param_lower_attrib_value}, - 'input_format': {str format to input input_value} - 'input_value': {guess_value}}, - "{user_defined_name_for_parameter_2}": - ... - ... - } - :param objective_function: (function or str) function to compute objective - - By default, the objective function is log mean squared error - of distribution ratio - - .. code-block:: python - - np.sum((np.log10(d_pred)-np.log10(d_meas))^2) - - Function needs to take inputs: - - .. code-block:: python - - objective_function(predicted_dict, measured_df, kwargs) - - ``kwargs`` is optional - - Function needs to return: (float) value computed by objective function - - Below is the guide for referencing predicted values - - +---------------------------+--------------------------------+ - | To access | Use | - +===========================+================================+ - | hydrogen ion conc in aq | predicted_dict['h_eq'] | - +---------------------------+--------------------------------+ - | extractant conc in org | predicted_dict['z_eq'] | - +---------------------------+--------------------------------+ - | RE ion eq conc in aq | predicted_dict['{RE}_aq_eq'] | - +---------------------------+--------------------------------+ - | RE complex eq conc in org | predicted_dict['{RE}_org_eq'] | - +---------------------------+--------------------------------+ - | RE distribution ratio | predicted_dict['{RE}_d_eq'] | - +---------------------------+--------------------------------+ - - Replace "{RE}" with rare earth element i.e. Nd, La, etc. - - For measured values, use the same names, but - replace ``predicted_dict`` with ``measured_df`` - :param optimizer: (function or str) function to perform optimization - - .. note:: - - The optimized variables are not directly the species parameters, - but instead are first multiplied by the initial guess before - sending becoming the species parameters. - - For example, say - - .. code-block:: python - - opt_dict = {'Nd(H(A)2)3(org):'h0':-4.7e6} - - If the bounds on h0 need to be [-4.7e7,-4.7e5], then - divide the bounds by the guess and get - - .. code-block:: python - - "bounds": [(1e-1, 1e1)] - - By default, the optimizer is scipy's optimize function with - - .. code-block:: python - - default_kwargs= {"method": 'SLSQP', - "bounds": [(1e-1, 1e1)] * len(x_guess), - "constraints": (), - "options": {'disp': True, - 'maxiter': 1000, - 'ftol': 1e-6}} - - Function needs to take inputs: - ``optimizer(objective_function, x_guess, kwargs)`` - - ``kwargs`` is optional - - Function needs to return: ((np.ndarray, float)) Optimized parameters, - objective_function value - - :param temp_xml_file_path: (str) path to temporary xml file. - - This xml file is a duplicate of the phases_xml_file name and is - modified during the optimization process to avoid changing the original - xml file - - default is local temp folder - - :param dependant_params_dict: (dict) dictionary containing information - about parameters dependant on opt_dict - """ - - def __init__(self, - exp_data, - phases_xml_filename, - phase_names, - aq_solvent_name, - extractant_name, - diluant_name, - complex_names, - rare_earth_ion_names, - re_species_list=None, - aq_solvent_rho=None, - extractant_rho=None, - diluant_rho=None, - opt_dict=None, - objective_function='Log-MSE', - optimizer='SLSQP', - temp_xml_file_path=None, - dependant_params_dict=None, - ): - self._built_in_obj_list = ['Log-MSE'] - self._built_in_opt_list = ['SLSQP'] - self._exp_data = exp_data - self._phases_xml_filename = phases_xml_filename - self._opt_dict = opt_dict - self._phase_names = phase_names - self._aq_solvent_name = aq_solvent_name - self._extractant_name = extractant_name - self._diluant_name = diluant_name - self._complex_names = complex_names - self._rare_earth_ion_names = rare_earth_ion_names - self._aq_solvent_rho = aq_solvent_rho - self._extractant_rho = extractant_rho - self._diluant_rho = diluant_rho - self._objective_function = None - self.set_objective_function(objective_function) - self._optimizer = None - self._re_species_list = re_species_list - self.set_optimizer(optimizer) - if temp_xml_file_path is None: - temp_xml_file_path = r'{0}/temp.xml'.format(os.getenv('TEMP')) - self._temp_xml_file_path = temp_xml_file_path - self._dependant_params_dict = dependant_params_dict - # Try and except for adding package data to path. - # This only works for sdist, not bdist - # If bdist is needed, research "manifest.in" python setup files - try: - shutil.copyfile(self._phases_xml_filename, - self._temp_xml_file_path) - self._phases = ct.import_phases(self._phases_xml_filename, - phase_names) - except FileNotFoundError: - self._phases_xml_filename = \ - pkg_resources.resource_filename('reeps', - r'..\data\xmls\{0}'.format( - phases_xml_filename)) - shutil.copyfile(self._phases_xml_filename, - self._temp_xml_file_path) - self._phases = ct.import_phases(self._phases_xml_filename, - phase_names) - if isinstance(self._exp_data, str): - try: - self._exp_df = pd.read_csv(self._exp_data) - except FileNotFoundError: - self._exp_data = pkg_resources.resource_filename( - 'reeps', r'..\data\csvs\{0}'.format(self._exp_data)) - self._exp_df = pd.read_csv(self._exp_data) - else: - self._exp_df = self._exp_data.copy() - - self._exp_df_columns = ['h_i', 'h_eq', 'z_i', 'z_eq'] - if self._re_species_list is None: - self._re_species_list = [] - for name in self._rare_earth_ion_names: - species = name.replace('+', '') - self._re_species_list.append(species) - for species in self._re_species_list: - self._exp_df_columns.append('{0}_aq_i'.format(species)) - self._exp_df_columns.append('{0}_aq_eq'.format(species)) - self._exp_df_columns.append('{0}_d_eq'.format(species)) - - self._exp_df.columns = self._exp_df_columns - for species in self._re_species_list: - self._exp_df['{0}_org_eq'.format(species)] = \ - self._exp_df['{0}_aq_eq'.format(species)] \ - * self._exp_df['{0}_d_eq'.format(species)] - - self._in_moles = None - - self._aq_ind = None - self._org_ind = None - self._re_charges = None - - self.set_in_moles(feed_vol=1) - self._predicted_dict = None - self.update_predicted_dict() - -
[docs] @staticmethod - def scipy_minimize(objective, x_guess, optimizer_kwargs=None): - """ The default optimizer for REEPS - - Uses scipy.minimize - - By default, options are - - .. code-block:: python - - default_kwargs= {"method": 'SLSQP', - "bounds": [(1e-1, 1e1)]*len(x_guess), - "constraints": (), - "options": {'disp': True, - 'maxiter': 1000, - 'ftol': 1e-6}} - - :param objective: (func) the objective function - :param x_guess: (np.ndarray) the initial guess (always 1) - :param optimizer_kwargs: (dict) dictionary of options for minimize - :returns: ((np.ndarray, float)) Optimized parameters, - objective_function value - """ - if optimizer_kwargs is None: - optimizer_kwargs = {"method": 'SLSQP', - "bounds": [(1e-1, 1e1)] * len(x_guess), - "constraints": (), - "options": {'disp': True, - 'maxiter': 1000, - 'ftol': 1e-6}} - res = minimize(objective, x_guess, **optimizer_kwargs) - est_parameters = res.x - return est_parameters, res.fun
- -
[docs] def log_mean_squared_error(self, predicted_dict, meas_df): - """Default objective function for REEPS - - Returns the log mean squared error of - predicted distribution ratios (d=n_org/n_aq) - to measured d. - - np.sum((np.log10(d_pred)-np.log10(d_meas))\**2) - - :param predicted_dict: (dict) contains predicted data - :param meas_df: (pd.DataFrame) contains experimental data - :return: (float) log mean squared error between predicted and measured - """ - meas = np.concatenate([meas_df['{0}_d_eq'.format(species)].values - for species in self._re_species_list]) - pred = np.concatenate([ - predicted_dict['{0}_d_eq'.format(species)] - for species in self._re_species_list]) - log_pred = np.log10(pred) - log_meas = np.log10(meas) - log_diff = (log_pred - log_meas) ** 2 - obj = np.sum(log_diff) - return obj
- -
[docs] def get_exp_df(self) -> pd.DataFrame: - """Returns the experimental DataFrame - - :return: (pd.DataFrame) Experimental data - """ - return self._exp_df
- -
[docs] def set_exp_df(self, exp_data): - """Changes the experimental DataFrame to input exp_csv_filename data - and renames columns to internal REEPS names - - - h_i, h_eq, z_i, z_eq, {RE}_aq_i, {RE}_aq_eq, {RE}_d - - See class docstring on "exp_csv_filename" for further explanations. - - :param exp_data: (str or pd.DataFrame) - file name/path or DataFrame for experimental data csv - """ - self._exp_data = exp_data - if isinstance(self._exp_data, str): - try: - self._exp_df = pd.read_csv(self._exp_data) - except FileNotFoundError: - self._exp_data = pkg_resources.resource_filename( - 'reeps', r'..\data\csvs\{0}'.format(self._exp_data)) - self._exp_df = pd.read_csv(self._exp_data) - else: - self._exp_df = exp_data.copy() - self._exp_df_columns = ['h_i', 'h_eq', 'z_i', 'z_eq'] - if self._re_species_list is None: - self._re_species_list = [] - for name in self._rare_earth_ion_names: - species = name.replace('+', '') - self._re_species_list.append(species) - for species in self._re_species_list: - self._exp_df_columns.append('{0}_aq_i'.format(species)) - self._exp_df_columns.append('{0}_aq_eq'.format(species)) - self._exp_df_columns.append('{0}_d_eq'.format(species)) - self._exp_df.columns = self._exp_df_columns - for species in self._re_species_list: - self._exp_df['{0}_org_eq'.format(species)] = \ - self._exp_df['{0}_aq_eq'.format(species)] \ - * self._exp_df['{0}_d_eq'.format(species)] - self.set_in_moles(feed_vol=1) - self.update_predicted_dict() - return None
- -
[docs] def get_phases(self) -> list: - """ - Returns the list of Cantera solutions - - :return: (list) list of Cantera solutions/phases - """ - return self._phases
- -
[docs] def set_phases(self, phases_xml_filename, phase_names): - """Change list of Cantera solutions by inputting - new xml file name and phase names - - Also runs set_in_moles to set feed volume to 1 L - - :param phases_xml_filename: (str) xml file with parameters - for equilibrium calc - :param phase_names: (list) names of phases in xml file - """ - self._phases_xml_filename = phases_xml_filename - self._phase_names = phase_names - # Try and except for adding package data to path. - # This only works for sdist, not bdist - # If bdist is needed, research "manifest.in" python setup files - try: - shutil.copyfile(self._phases_xml_filename, - self._temp_xml_file_path) - self._phases = ct.import_phases(self._phases_xml_filename, - phase_names) - except FileNotFoundError: - self._phases_xml_filename = \ - pkg_resources.resource_filename('reeps', - r'..\data\xmls\{0}'.format( - phases_xml_filename)) - shutil.copyfile(self._phases_xml_filename, - self._temp_xml_file_path) - self._phases = ct.import_phases(self._phases_xml_filename, - phase_names) - self.set_in_moles(feed_vol=1) - self.update_predicted_dict() - return None
- -
[docs] def get_opt_dict(self) -> dict: - """ - Returns the dictionary containing optimization information - - :return: (dict) dictionary containing info about which - species parameters are updated to fit model to experimental data - """ - return self._opt_dict
- -
[docs] def set_opt_dict(self, opt_dict): - """ - Change the dictionary to input opt_dict. - - opt_dict specifies species parameters to be updated to - fit model to data - - See class docstring on "opt_dict" for more information. - - :param opt_dict: (dict) dictionary containing info about which - species parameters are updated to fit model to experimental data - """ - - self._opt_dict = opt_dict - return None
- -
[docs] def get_aq_solvent_name(self) -> str: - """Returns aq_solvent_name - - :return: aq_solvent_name: (str) name of aqueous solvent in xml file - """ - return self._aq_solvent_name
- -
[docs] def set_aq_solvent_name(self, aq_solvent_name): - """ Change aq_solvent_name to input aq_solvent_name - - :param aq_solvent_name: (str) name of aqueous solvent in xml file - """ - self._aq_solvent_name = aq_solvent_name - return None
- -
[docs] def get_extractant_name(self) -> str: - """Returns extractant name - - :return: extractant_name: (str) name of extractant in xml file - """ - return self._extractant_name
- -
[docs] def set_extractant_name(self, extractant_name): - """ - Change extractant_name to input extractant_name - :param extractant_name: (str) name of extractant in xml file - """ - self._extractant_name = extractant_name - return None
- -
[docs] def get_diluant_name(self) -> str: - """ Returns diluant name - :return: diluant_name: (str) name of diluant in xml file - """ - return self._diluant_name
- -
[docs] def set_diluant_name(self, diluant_name): - """ - Change diluant_name to input diluant_name - - :param diluant_name: (str) name of diluant in xml file - """ - self._diluant_name = diluant_name - return None
- -
[docs] def get_complex_names(self) -> list: - """Returns list of complex names - - :return: complex_names: (list) names of complexes in xml file. - """ - return self._complex_names
- -
[docs] def set_complex_names(self, complex_names): - """Change complex names list to input complex_names - - :param complex_names: (list) names of complexes in xml file. - """ - self._complex_names = complex_names - return None
- -
[docs] def get_rare_earth_ion_names(self) -> list: - """Returns list of rare earth ion names - - :return: rare_earth_ion_names: (list) names of rare earth ions in - xml file - """ - return self._rare_earth_ion_names
- -
[docs] def set_rare_earth_ion_names(self, rare_earth_ion_names): - """Change list of rare earth ion names to input - rare_earth_ion_names - - :param rare_earth_ion_names: (list) names of rare earth ions in - xml file - """ - self._rare_earth_ion_names = rare_earth_ion_names - return None
- -
[docs] def get_re_species_list(self) -> list: - """Returns list of rare earth element names - - :return: re_species_list: (list) names of rare earth elements in - xml file - """ - return self._re_species_list
- -
[docs] def set_re_species_list(self, re_species_list): - """Change list of rare earth ion names to input - rare_earth_ion_names - - :param re_species_list: (list) names of rare earth elements in - xml file - """ - self._re_species_list = re_species_list - return None
- -
[docs] def get_aq_solvent_rho(self) -> str: - """Returns aqueous solvent density (g/L) - - :return: aq_solvent_rho: (float) density of aqueous solvent - """ - return self._aq_solvent_rho
- -
[docs] def set_aq_solvent_rho(self, aq_solvent_rho): - """Changes aqueous solvent density (g/L) to input aq_solvent_rho - - :param aq_solvent_rho: (float) density of aqueous solvent - """ - self._aq_solvent_rho = aq_solvent_rho - return None
- -
[docs] def get_extractant_rho(self) -> str: - """Returns extractant density (g/L) - - :return: extractant_rho: (float) density of extractant - """ - return self._extractant_rho
- -
[docs] def set_extractant_rho(self, extractant_rho): - """Changes extractant density (g/L) to input extractant_rho - - :param extractant_rho: (float) density of extractant - """ - self._extractant_rho = extractant_rho - return None
- -
[docs] def get_diluant_rho(self) -> str: - """Returns diluant density (g/L) - - :return: diluant_rho: (float) density of diluant - """ - return self._diluant_rho
- -
[docs] def set_diluant_rho(self, diluant_rho): - """Changes diluant density (g/L) to input diluant_rho - - :param diluant_rho: (float) density of diluant - """ - self._diluant_rho = diluant_rho - return None
- -
[docs] def set_in_moles(self, feed_vol): - """Function that initializes mole fractions to input feed_vol - - This function is called at initialization - - Sets in_moles to a pd.DataFrame containing initial mole fractions - - Columns for species and rows for different experiments - - This function also calls update_predicted_dict - - :param feed_vol: (float) feed volume of mixture (L) - """ - phases_copy = self._phases.copy() - exp_df = self._exp_df.copy() - solvent_name = self._aq_solvent_name - extractant_name = self._extractant_name - diluant_name = self._diluant_name - solvent_rho = self._aq_solvent_rho - extractant_rho = self._extractant_rho - diluant_rho = self._diluant_rho - re_names = self._rare_earth_ion_names - re_species_list = self._re_species_list - - mixed = ct.Mixture(phases_copy) - aq_ind = None - solvent_ind = None - for ind, phase in enumerate(phases_copy): - if solvent_name in phase.species_names: - aq_ind = ind - solvent_ind = phase.species_names.index(solvent_name) - if aq_ind is None: - raise Exception('Solvent "{0}" not found \ - in xml file'.format(solvent_name)) - - if aq_ind == 0: - org_ind = 1 - else: - org_ind = 0 - self._aq_ind = aq_ind - self._org_ind = org_ind - extractant_ind = phases_copy[org_ind].species_names.index( - extractant_name) - diluant_ind = phases_copy[org_ind].species_names.index(diluant_name) - - re_ind_list = [phases_copy[aq_ind].species_names.index(re_name) - for re_name in re_names] - re_charges = np.array([phases_copy[aq_ind].species(re_ind).charge - for re_ind in re_ind_list]) - self._re_charges = re_charges - - mix_aq = mixed.phase(aq_ind) - mix_org = mixed.phase(org_ind) - solvent_mw = mix_aq.molecular_weights[solvent_ind] # g/mol - extractant_mw = mix_org.molecular_weights[extractant_ind] - diluant_mw = mix_org.molecular_weights[diluant_ind] - if solvent_rho is None: - solvent_rho = mix_aq(aq_ind).partial_molar_volumes[ - solvent_ind] / solvent_mw * 1e6 # g/L - self._aq_solvent_rho = solvent_rho - if extractant_rho is None: - extractant_rho = mix_org(org_ind).partial_molar_volumes[ - extractant_ind] / extractant_mw * 1e6 - self._extractant_rho = extractant_rho - if diluant_rho is None: - diluant_rho = mix_org(org_ind).partial_molar_volumes[ - extractant_ind] / extractant_mw * 1e6 - self._diluant_rho = diluant_rho - - in_moles_data = [] - aq_phase_solvent_moles = feed_vol * solvent_rho / solvent_mw - for index, row in exp_df.iterrows(): - h_plus_moles = feed_vol * row['h_i'] - hydroxide_ions = 0 - rare_earth_moles = np.array([feed_vol * row[ - '{0}_aq_i'.format(re_species)] - for re_species in re_species_list]) - re_charge_sum = np.sum(re_charges * rare_earth_moles) - chlorine_moles = re_charge_sum + h_plus_moles - extractant_moles = feed_vol * row['z_i'] - extractant_vol = extractant_moles * extractant_mw / extractant_rho - diluant_vol = feed_vol - extractant_vol - diluant_moles = diluant_vol * diluant_rho / diluant_mw - complex_moles = np.zeros(len(re_species_list)) - - species_moles_aq = [aq_phase_solvent_moles, - h_plus_moles, - hydroxide_ions, - chlorine_moles] - species_moles_aq.extend(list(rare_earth_moles)) - species_moles_org = [extractant_moles, diluant_moles] - species_moles_org.extend(list(complex_moles)) - if aq_ind == 0: - species_moles = species_moles_aq + species_moles_org - else: - species_moles = species_moles_org + species_moles_aq - in_moles_data.append(species_moles) - self._in_moles = pd.DataFrame( - in_moles_data, columns=mixed.species_names) - self.update_predicted_dict() - return None
- -
[docs] def get_in_moles(self) -> pd.DataFrame: - """Returns the in_moles DataFrame which contains the initial mole - fractions of each species for each experiment - - :return: in_moles: (pd.DataFrame) DataFrame with initial mole fractions - """ - return self._in_moles
- -
[docs] def set_objective_function(self, objective_function): - """Change objective function to input objective_function. - - See class docstring on "objective_function" for instructions - - :param objective_function: (func) Objective function to quantify - error between model and experimental data - """ - if not callable(objective_function) \ - and objective_function not in self._built_in_obj_list: - raise Exception( - "objective_function must be a function " - "or in this strings list: {0}".format( - self._built_in_obj_list)) - if callable(objective_function): - if len(signature(objective_function).parameters) < 2: - raise Exception( - "objective_function must be a function " - "with at least 3 arguments:" - " f(predicted_dict, experimental_df, kwargs)") - if objective_function == 'Log-MSE': - objective_function = self.log_mean_squared_error - self._objective_function = objective_function - return None
- -
[docs] def get_objective_function(self): - """Returns objective function - - :return: objective_function: (func) Objective function to quantify - error between model and experimental data - """ - return self._objective_function
- -
[docs] def set_optimizer(self, optimizer): - """Change optimizer function to input optimizer. - - See class docstring on "optimizer" for instructions - - :param optimizer: (func) Optimizer function to minimize objective - function - """ - if not callable(optimizer) \ - and optimizer not in self._built_in_opt_list: - raise Exception( - "optimizer must be a function " - "or in this strings list: {0}".format( - self._built_in_opt_list)) - if callable(optimizer): - if len(signature(optimizer).parameters) < 2: - raise Exception( - "optimizer must be a function " - "with at least 2 arguments: " - "f(objective_func,x_guess, kwargs)") - if optimizer == 'SLSQP': - optimizer = self.scipy_minimize - self._optimizer = optimizer - return None
- -
[docs] def get_optimizer(self): - """Returns objective function - - :return: optimizer: (func) Optimizer function to minimize objective - function - """ - return self._optimizer
- -
[docs] def get_temp_xml_file_path(self): - """Returns path to temporary xml file. - - This xml file is a duplicate of the phases_xml_file name and is - modified during the optimization process to avoid changing the original - xml file. - - :return: temp_xml_file_path: (str) path to temporary xml file. - """ - return self._temp_xml_file_path
- -
[docs] def set_temp_xml_file_path(self, temp_xml_file_path): - """Changes temporary xml file path to input temp_xml_file_path. - - This xml file is a duplicate of the phases_xml_file name and is - modified during the optimization process to avoid changing the original - xml file. - - :param temp_xml_file_path: (str) path to temporary xml file. - """ - self._temp_xml_file_path = temp_xml_file_path - return None
- -
[docs] def get_dependant_params_dict(self): - """ - Returns the dependant_params_dict - :return: dependant_params_dict: (dict) dictionary containing - information about parameters dependant on opt_dict - """ - return self._dependant_params_dict
- -
[docs] def set_dependant_params_dict(self, dependant_params_dict): - """ - Sets the dependant_params_dict - :param dependant_params_dict: (dict) dictionary containing information - about parameters dependant on opt_dict - """ - self._dependant_params_dict = dependant_params_dict - return None
- -
[docs] def update_predicted_dict(self, - phases_xml_filename=None, - phase_names=None): - """Function that computes the predicted equilibrium concentrations - the fed phases_xml_filename parameters predicts given the initial - mole fractions set by in_moles() - - :param phases_xml_filename: (str)xml file with parameters - for equilibrium calc. If ``None``, the - current phases_xml_filename is used. - :param phase_names: (list) names of phases in xml file. - If ``None``, the current phases_names is used. - """ - if phases_xml_filename is None: - phases_xml_filename = self._phases_xml_filename - if phase_names is None: - phase_names = self._phase_names - aq_ind = self._aq_ind - org_ind = self._org_ind - complex_names = self._complex_names - extractant_name = self._extractant_name - rare_earth_ion_names = self._rare_earth_ion_names - in_moles = self._in_moles - re_species_list = self._re_species_list - - phases_copy = ct.import_phases(phases_xml_filename, phase_names) - mix = ct.Mixture(phases_copy) - key_names = ['h_eq', 'z_eq'] - for re_species in re_species_list: - key_names.append('{0}_aq_eq'.format(re_species)) - key_names.append('{0}_org_eq'.format(re_species)) - key_names.append('{0}_d_eq'.format(re_species)) - - predicted_dict = {'{0}'.format(key_name): [] - for key_name in key_names} - - for row in in_moles.values: - mix.species_moles = row - mix.equilibrate('TP', log_level=0) - re_org_array = np.array([mix.species_moles[mix.species_index( - org_ind, complex_name)] for complex_name in complex_names]) - re_aq_array = np.array([mix.species_moles[mix.species_index( - aq_ind, re_ion_name)] for re_ion_name in rare_earth_ion_names]) - d_array = re_org_array / re_aq_array - hydrogen_ions = mix.species_moles[mix.species_index(aq_ind, 'H+')] - extractant = mix.species_moles[mix.species_index( - org_ind, extractant_name)] - for index, re_species in enumerate(re_species_list): - predicted_dict['{0}_aq_eq'.format( - re_species)].append(re_aq_array[index]) - predicted_dict['{0}_org_eq'.format( - re_species)].append(re_org_array[index]) - predicted_dict['{0}_d_eq'.format( - re_species)].append(d_array[index]) - predicted_dict['h_eq'].append(hydrogen_ions) - predicted_dict['z_eq'].append(extractant) - for key, value in predicted_dict.items(): - predicted_dict[key] = np.array(value) - self._predicted_dict = predicted_dict - return None
- -
[docs] def get_predicted_dict(self): - """Returns predicted dictionary of species concentrations - that xml parameters predicts given current in_moles - - :return: predicted_dict: (dict) dictionary of species concentrations - """ - return self._predicted_dict
- - def _internal_objective(self, x, kwargs=None): - """ - Internal objective function. Uses objective function to compute value - If the optimizer requires vectorized variables ie pso, this function - takes care of it - - :param x: (list) thermo properties varied to minimize objective func - :param kwargs: (list) arguments for objective_function - """ - temp_xml_file_path = self._temp_xml_file_path - exp_df = self._exp_df - objective_function = self._objective_function - opt_dict = copy.deepcopy(self._opt_dict) - dep_dict = copy.deepcopy(self._dependant_params_dict) - x = np.array(x) - - if len(x.shape) == 1: - xs = np.array([x]) - vectorized_x = False - else: - vectorized_x = True - xs = x - objective_values = [] - for x in xs: - i = 0 - for species_name in opt_dict.keys(): - for thermo_prop in opt_dict[species_name].keys(): - if not np.isnan( - x[i]): # if nan, do not update xml with nan - opt_dict[species_name][thermo_prop] *= x[i] - i += 1 - - self.update_xml(opt_dict, - temp_xml_file_path, - dependant_params_dict=dep_dict) - - self.update_predicted_dict(temp_xml_file_path) - predicted_dict = self.get_predicted_dict() - self.update_predicted_dict() - - if kwargs is None: - # noinspection PyCallingNonCallable - obj = objective_function(predicted_dict, exp_df) - else: - # noinspection PyCallingNonCallable - obj = objective_function(predicted_dict, exp_df, **kwargs) - objective_values.append(obj) - if vectorized_x: - objective_values = np.array(objective_values) - else: - objective_values = objective_values[0] - return objective_values - -
[docs] def fit(self, - objective_function=None, - optimizer=None, - objective_kwargs=None, - optimizer_kwargs=None) -> tuple: - """Fits experimental to modeled data by minimizing objective function - with optimizer. Returns dictionary with opt_dict structure - - :param objective_function: (function) function to compute objective - If 'None', last set objective or default function is used - :param optimizer: (function) function to perform optimization - If 'None', last set optimizer or default is used - :param optimizer_kwargs: (dict) optional arguments for optimizer - :param objective_kwargs: (dict) optional arguments - for objective function - :returns tuple: (opt_dict (dict), opt_value (float)) - optimized opt_dict: Has identical structure as opt_dict - """ - if objective_function is not None: - self.set_objective_function(objective_function) - if optimizer is not None: - self.set_optimizer(optimizer) - - def objective(x): - return self._internal_objective(x, objective_kwargs) - - optimizer = self._optimizer - opt_dict = copy.deepcopy(self._opt_dict) - i = 0 - for species_name in opt_dict.keys(): - for _ in opt_dict[species_name].keys(): - i += 1 - x_guess = np.ones(i) - - if optimizer_kwargs is None: - # noinspection PyCallingNonCallable - est_parameters, obj_value = optimizer(objective, x_guess) - else: - # noinspection PyCallingNonCallable - est_parameters, obj_value = optimizer(objective, - x_guess, - optimizer_kwargs) - - i = 0 - for species_name in opt_dict.keys(): - for thermo_prop in opt_dict[species_name].keys(): - opt_dict[species_name][thermo_prop] *= est_parameters[i] - i += 1 - return opt_dict, obj_value
- -
[docs] def update_xml(self, - info_dict, - phases_xml_filename=None, - dependant_params_dict=None): - """updates xml file with info_dict - - :param info_dict: (dict) info in {species_names:{thermo_prop:val}} - Requires an identical structure to opt_dict - :param phases_xml_filename: (str) xml filename if editing other xml - If ``None``, the current xml will be modified and the internal - Cantera phases will be refreshed to the new values. - :param dependant_params_dict: (dict) dictionary containing information - about parameters dependant on info_dict - """ - if phases_xml_filename is None: - phases_xml_filename = self._phases_xml_filename - new_dict = copy.deepcopy(info_dict) - dep_dict = dependant_params_dict - if dep_dict is not None: - for species_name in dep_dict.keys(): - for thermo_prop in dep_dict[species_name]: - mod_func = \ - dep_dict[species_name][thermo_prop]['function'] - mod_kwargs = \ - dep_dict[species_name][thermo_prop]['kwargs'] - ind_vars = \ - dep_dict[species_name][thermo_prop]['ind_vars'] - ind_vals = [new_dict[ind_var[0]][ind_var[1]] - for ind_var in ind_vars] - - new_dict[species_name] = {} - new_dict[species_name][thermo_prop] = {} - new_dict[species_name][thermo_prop] = \ - mod_func(ind_vals, **mod_kwargs) - # print(mod_func(ind_vals, **mod_kwargs)) - # print(new_dict) - - tree = ET.parse(phases_xml_filename) - root = tree.getroot() - # Update xml file - for species_name in new_dict.keys(): - for thermo_prop in new_dict[species_name].keys(): - for species in root.iter('species'): - if species.attrib['name'] == species_name: - for changed_prop in species.iter(thermo_prop): - changed_prop.text = str( - new_dict[species_name][thermo_prop]) - now = datetime.now() - changed_prop.set('updated', - 'Updated at {0}:{1} {2}-{3}-{4}' - .format(now.hour, now.minute, - now.month, now.day, - now.year)) - - tree.write(phases_xml_filename) - if phases_xml_filename == self._phases_xml_filename: - self.set_phases(self._phases_xml_filename, self._phase_names) - return None
- - def _internal_objective_ver2(self, x, kwargs=None): - """ - ver2 generalizes to handle accessing parameters. ver1 assumes species - parameter is modified. ver2 assumes parameter is accessed by going - through two levels: upper and lower - Internal objective function. Uses objective function to compute value - If the optimizer requires vectorized variables ie pso, this function - takes care of it - - :param x: (list) thermo properties varied to minimize objective func - :param kwargs: (list) arguments for objective_function - """ - temp_xml_file_path = self._temp_xml_file_path - exp_df = self._exp_df - objective_function = self._objective_function - opt_dict = copy.deepcopy(self._opt_dict) - dep_dict = copy.deepcopy(self._dependant_params_dict) - x = np.array(x) - - if len(x.shape) == 1: - xs = np.array([x]) - vectorized_x = False - else: - vectorized_x = True - xs = x - objective_values = [] - for x in xs: - for ind, param_name in enumerate(opt_dict.keys()): - if not np.isnan( - x[ind]): # if nan, do not update xml with nan - opt_dict[param_name]['input_value'] *= x[ind] - - self.update_xml_ver2(opt_dict, - temp_xml_file_path, - dependant_params_dict=dep_dict) - - self.update_predicted_dict(temp_xml_file_path) - predicted_dict = self.get_predicted_dict() - self.update_predicted_dict() - - if kwargs is None: - # noinspection PyCallingNonCallable - obj = objective_function(predicted_dict, exp_df) - else: - # noinspection PyCallingNonCallable - obj = objective_function(predicted_dict, exp_df, **kwargs) - objective_values.append(obj) - if vectorized_x: - objective_values = np.array(objective_values) - else: - objective_values = objective_values[0] - return objective_values - -
[docs] def fit_ver2(self, - objective_function=None, - optimizer=None, - objective_kwargs=None, - optimizer_kwargs=None) -> tuple: - """Fits experimental to modeled data by minimizing objective function - with optimizer. Returns dictionary with opt_dict structure - - :param objective_function: (function) function to compute objective - If 'None', last set objective or default function is used - :param optimizer: (function) function to perform optimization - If 'None', last set optimizer or default is used - :param optimizer_kwargs: (dict) optional arguments for optimizer - :param objective_kwargs: (dict) optional arguments - for objective function - :returns tuple: (opt_dict (dict), opt_value (float)) - optimized opt_dict: Has identical structure as opt_dict - """ - if objective_function is not None: - self.set_objective_function(objective_function) - if optimizer is not None: - self.set_optimizer(optimizer) - - def objective(x): - return self._internal_objective_ver2(x, objective_kwargs) - - optimizer = self._optimizer - opt_dict = copy.deepcopy(self._opt_dict) - x_guess = np.ones(len(list(opt_dict.keys()))) - - if optimizer_kwargs is None: - # noinspection PyCallingNonCallable - est_parameters, obj_value = optimizer(objective, x_guess) - else: - # noinspection PyCallingNonCallable - est_parameters, obj_value = optimizer(objective, - x_guess, - optimizer_kwargs) - for ind, param_name in enumerate(opt_dict.keys()): - opt_dict[param_name]['input_value'] *= est_parameters[ind] - - return opt_dict, obj_value
- -
[docs] def update_xml_ver2(self, - info_dict, - phases_xml_filename=None, - dependant_params_dict=None): - """updates xml file with info_dict - - :param info_dict: (dict) info in {species_names:{thermo_prop:val}} - Requires an identical structure to opt_dict - :param phases_xml_filename: (str) xml filename if editing other xml - If ``None``, the current xml will be modified and the internal - Cantera phases will be refreshed to the new values. - :param dependant_params_dict: (dict) dictionary containing information - about parameters dependant on info_dict - """ - if phases_xml_filename is None: - phases_xml_filename = self._phases_xml_filename - new_dict = copy.deepcopy(info_dict) - dep_dict = dependant_params_dict - - if dep_dict is not None: - new_dict.update(dep_dict) - for param_name in dep_dict.keys(): - mod_func = \ - dep_dict[param_name]['function'] - mod_kwargs = \ - dep_dict[param_name]['kwargs'] - if isinstance(dep_dict[param_name]['independent_params'], str): - ind_param_names = [dep_dict[ - param_name]['independent_params']] - else: - ind_param_names = \ - dep_dict[param_name]['independent_params'] - ind_vals = [new_dict[ind_param_name]['input_value'] - for ind_param_name in ind_param_names] - if mod_kwargs is None: - new_dict[param_name]['input_value'] = mod_func(ind_vals) - else: - new_dict[param_name]['input_value'] = \ - mod_func(ind_vals, - **mod_kwargs) - tree = ET.parse(phases_xml_filename) - root = tree.getroot() - # Update xml file - for key in list(new_dict.keys()): - d = new_dict[key] - now = datetime.now() - if (d['upper_attrib_name'] is not None - and d['lower_attrib_name'] is not None): - for child1 in root.iter(d['upper_element_name']): - if (child1.attrib[d['upper_attrib_name']] - == d['upper_attrib_value']): - for child2 in child1.iter(d['lower_element_name']): - if (child1.attrib[d['lower_attrib_name']] - == d['lower_attrib_value']): - child2.text = d['input_format'].format( - d['input_value']) - child2.set('updated', - 'Updated at {0}:{1} {2}-{3}-{4}' - .format(now.hour, now.minute, - now.month, now.day, - now.year)) - elif (d['upper_attrib_name'] is None - and d['lower_attrib_name'] is not None): - for child1 in root.iter(d['upper_element_name']): - for child2 in child1.iter(d['lower_element_name']): - if (child1.attrib[d['lower_attrib_name']] - == d['lower_attrib_value']): - child2.text = d['input_format'].format( - d['input_value']) - child2.set('updated', - 'Updated at {0}:{1} {2}-{3}-{4}' - .format(now.hour, now.minute, - now.month, now.day, - now.year)) - elif (d['upper_attrib_name'] is not None - and d['lower_attrib_name'] is None): - for child1 in root.iter(d['upper_element_name']): - if (child1.attrib[d['upper_attrib_name']] - == d['upper_attrib_value']): - for child2 in child1.iter(d['lower_element_name']): - child2.text = d['input_format'].format( - d['input_value']) - child2.set('updated', - 'Updated at {0}:{1} {2}-{3}-{4}' - .format(now.hour, now.minute, - now.month, now.day, - now.year)) - else: - for child1 in root.iter(d['upper_element_name']): - for child2 in child1.iter(d['lower_element_name']): - child2.text = d['input_format'].format( - d['input_value']) - child2.set('updated', 'Updated at {0}:{1} {2}-{3}-{4}' - .format(now.hour, now.minute, - now.month, now.day, - now.year)) - - tree.write(phases_xml_filename) - if phases_xml_filename == self._phases_xml_filename: - self.set_phases(self._phases_xml_filename, self._phase_names) - return None
- -
[docs] def parity_plot(self, - compared_value=None, - c_data=None, - c_label=None, - plot_title=None, - save_path=None, - print_r_squared=False, - data_labels=None, - legend=True): - """ - Parity plot between measured and predicted compared_value. - Default compared value is {RE_1}_aq_eq - - :param compared_value: (str) Quantity to compare predicted and - experimental data. Can be any column containing "eq" in exp_df i.e. - h_eq, z_eq, {RE}_d_eq, etc. - :param plot_title: (str or boolean) - - If None (default): Plot title will be generated from compared_value - Recommend to just explore. If h_eq, plot_title is - "H^+ eq conc". - - If str: Plot title will be plot_title string - - If "False": No plot title - :param c_data: (list or np.ndarray) data for color axis - :param c_label: (str) label for color axis - :param save_path: (str) save path for parity plot - :param print_r_squared: (boolean) To plot or not to plot r-squared - value. Prints 2 places past decimal - :param data_labels: labels for the data such as paper's name where - experiment is pulled from. - :param legend: whether to display legend for data_labels. Has no - effect if data_labels is None - :return fig, ax: returns the figure and axes objects - """ - exp_df = self.get_exp_df() - predicted_dict = self.get_predicted_dict() - re_species_list = self._re_species_list - extractant_name = self.get_extractant_name() - re_charges = self._re_charges - if compared_value is None: - compared_value = '{0}_aq_eq'.format(re_species_list[0]) - pred = pd.DataFrame(predicted_dict)[compared_value].fillna(0).values - meas = exp_df[compared_value].fillna(0).values - name_breakdown = re.findall('[^_\W]+', compared_value) - compared_species = name_breakdown[0] - if compared_species == 'h': - feed_molarity = exp_df['h_i'].fillna(0).values - elif compared_species == 'z': - feed_molarity = exp_df['z_i'].fillna(0).values - else: - feed_molarity = exp_df[ - '{0}_aq_i'.format(compared_species)].fillna(0).values - if isinstance(data_labels, list): - combined_df = pd.DataFrame({'pred': pred, - 'meas': meas, - 'label': data_labels, - 'feed_molarity': feed_molarity}) - elif isinstance(c_data, str): - combined_df = pd.DataFrame({'pred': pred, - 'meas': meas, - c_data: exp_df[c_data].values, - 'feed_molarity': feed_molarity}) - else: - combined_df = pd.DataFrame({'pred': pred, - 'meas': meas, - 'feed_molarity': feed_molarity}) - - combined_df = combined_df[(combined_df['feed_molarity'] != 0)] - meas = combined_df['meas'].values - pred = combined_df['pred'].values - - min_data = np.min([pred, meas]) - max_data = np.max([pred, meas]) - min_max_data = np.array([min_data, max_data]) - - if compared_species == 'h': - default_title = '$H^+$ eq. conc. (mol/L)' - elif compared_species == 'z': - default_title = '{0} eq. conc. (mol/L)'.format(extractant_name) - else: - phase = name_breakdown[1] - if phase == 'aq': - re_charge = re_charges[re_species_list.index(compared_species)] - default_title = '$%s^{%d+}$ eq. conc. (mol/L)' \ - % (compared_species, re_charge) - elif phase == 'd': - default_title = '{0} distribution ratio'.format( - compared_species) - else: - default_title = '{0} complex eq. conc. (mol/L)'.format( - compared_species) - fig, ax = plt.subplots() - if isinstance(data_labels, list): - unique_labels = list(set(data_labels)) - for label in unique_labels: - filtered_data = combined_df[combined_df['label'] == label] - filtered_meas = filtered_data['meas'] - filtered_pred = filtered_data['pred'] - ax.scatter(filtered_meas, filtered_pred, label=label) - if legend: - ax.legend(loc='best') - - elif c_data is not None: - if isinstance(c_data, str): - c_data = combined_df[c_data].values - p1 = ax.scatter(meas, pred, c=c_data, alpha=1, cmap='viridis') - c_bar = fig.colorbar(p1, format='%.2f') - if c_label is not None: - c_bar.set_label(c_label, rotation=270, labelpad=20) - else: - sns.scatterplot(meas, pred, color="r", - legend=False) - ax.plot(min_max_data, min_max_data, color="b", label="") - - if print_r_squared: - ax.text(min_max_data[0], - min_max_data[1] * 0.9, - '$R^2$={0:.2f}'.format(self.r_squared(compared_value))) - # plt.legend(loc='lower right') - # else: - # plt.legend() - - ax.set(xlabel='Measured', ylabel='Predicted') - if plot_title is None: - ax.set_title(default_title) - elif isinstance(plot_title, str): - ax.set_title(plot_title) - set_size(8, 6) - plt.tight_layout() - plt.show() - if save_path is not None: - plt.savefig(save_path, bbox_inches='tight') - return fig, ax
- -
[docs] def r_squared(self, compared_value=None): - """r-squared value comparing measured and predicted compared value - - Closer to 1, the better the model's predictions. - - :param compared_value: (str) Quantity to compare predicted and - experimental data. Can be any column containing "eq" in exp_df i.e. - h_eq, z_eq, {RE}_d_eq, etc. default is {RE}_aq_eq - """ - exp_df = self.get_exp_df() - predicted_dict = self.get_predicted_dict() - re_species_list = self._re_species_list - if compared_value is None: - compared_value = '{0}_aq_eq'.format(re_species_list[0]) - pred = pd.DataFrame(predicted_dict)[compared_value].fillna(0).values - predicted_y = np.array(pred) - actual_y = exp_df[compared_value].fillna(0).values - name_breakdown = re.findall('[^_\W]+', compared_value) - compared_species = name_breakdown[0] - if compared_species == 'h': - feed_molarity = exp_df['h_i'].fillna(0).values - elif compared_species == 'z': - feed_molarity = exp_df['z_i'].fillna(0).values - else: - feed_molarity = exp_df[ - '{0}_aq_i'.format(compared_species)].fillna(0).values - combined_df = pd.DataFrame({'pred': predicted_y, - 'meas': actual_y, - 'in_moles': feed_molarity}) - combined_df = combined_df[(combined_df['in_moles'] != 0)] - actual_y = combined_df['meas'].values - predicted_y = combined_df['pred'].values - num = sum((actual_y - predicted_y) ** 2) - den = sum((actual_y - np.mean(actual_y)) ** 2) - if den == 0: - r_2 = 0 - else: - r_2 = (1 - num / den) - return r_2
- -
[docs] @staticmethod - def plot_3d_data(x_data, - y_data, - z_data, - c_data=None, - x_label=None, - y_label=None, - z_label=None, - c_label=None): - """ - - :param x_data: (list) list of data for x axis - :param y_data: (list) list of data for y axis - :param z_data: (list) list of data for z axis - :param c_data: (list) list of data for color axis - :param x_label: (str) label for x axis - :param y_label: (str) label for y axis - :param z_label: (str) label for z axis - :param c_label: (str) label for color axis - :return: - """ - - fig = plt.figure() - ax = fig.add_subplot(111, projection='3d') - if c_data is None: - ax.plot(x_data, y_data, z_data, 'o') - else: - p1 = ax.scatter(x_data, - y_data, - z_data, 'o', c=c_data, - cmap='viridis', alpha=1) - c_bar = fig.colorbar(p1) - if c_label is not None: - c_bar.set_label(c_label, rotation=270, labelpad=20) - if x_label is None: - ax.set_xlabel('x', labelpad=15) - else: - ax.set_xlabel(x_label, labelpad=15) - if y_label is None: - ax.set_ylabel('y', labelpad=15) - else: - ax.set_ylabel(y_label, labelpad=15) - if z_label is None: - ax.set_zlabel('z', labelpad=15) - else: - ax.set_zlabel(z_label, labelpad=15) - plt.show() - return fig, ax
-
- -
- -
-
- - -
- -
-

- © Copyright 2020, Titus Quah, Nwike Iloeje - -

-
- Built with Sphinx using a theme provided by Read the Docs. - -
- -
-
- -
- -
- - - - - - - - - - - - \ No newline at end of file diff --git a/docs/_build/html/_sources/guide/about.rst.txt b/docs/_build/html/_sources/guide/about.rst.txt new file mode 100644 index 0000000..dbd1116 --- /dev/null +++ b/docs/_build/html/_sources/guide/about.rst.txt @@ -0,0 +1,61 @@ +.. _about: + +************ +About +************ + +Authors +============= +Titus Quah, University of Utah, + +Nwike Iloeje, Argonne National Laboratory, + +Acknowledgements +================ +Based upon work supported by funding from Argonne National Laboratory provided by the U.S. Department of Energy, Office of Energy Efficiency and Renewable Energy (EERE), under contract DE-AC02-06CH11357 + +References +========== + +If you use LLEPE in your research , we kindly request that you cite the package as follows: + +T. Quah and C. O. Iloeje, “Liquid--Liquid Extraction Thermodynamic Parameter Estimator (LLEPE) for Multicomponent Separation Systems,” in Materials Processing Fundamentals 2021, 2021, pp. 107–120, doi: https://doi.org/10.1007/978-3-030-65253-1_9. + +License +======= + +:: + + Copyright © 2020, UChicago Argonne, LLC + All Rights Reserved + Software Name: LLEPE + By: Argonne National Laboratory, University of Utah + OPEN SOURCE LICENSE + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + + ****************************************************************************************************** + DISCLAIMER + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + OF SUCH DAMAGE. + *************************************************************************************************** diff --git a/docs/_build/html/_sources/guide/install.rst.txt b/docs/_build/html/_sources/guide/install.rst.txt index ce1a1f9..e7306d7 100644 --- a/docs/_build/html/_sources/guide/install.rst.txt +++ b/docs/_build/html/_sources/guide/install.rst.txt @@ -24,17 +24,17 @@ To install the latest master version: .. code-block:: bash - pip install git+https://xgitlab.cels.anl.gov/summer-2020/parameter-estimation.git + pip install git+https://github.com/ANL-CEEESA/LLEPE.git Development version =================== -To contribute to Stable-Baselines, with support for running tests and building the documentation. +To contribute to LLEPE, with support for running tests and building the documentation. .. code-block:: bash - git clone https://xgitlab.cels.anl.gov/summer-2020/parameter-estimation.git && cd parameter-estimation + git clone https://github.com/ANL-CEEESA/LLEPE.git pip install -e .[docs,tests] diff --git a/docs/_build/html/_sources/index.rst.txt b/docs/_build/html/_sources/index.rst.txt index 9a973a9..a0c905b 100644 --- a/docs/_build/html/_sources/index.rst.txt +++ b/docs/_build/html/_sources/index.rst.txt @@ -1,9 +1,8 @@ -.. reeps documentation master file, created by Titus Quah - sphinx-quickstart on Tue Jun 9 10:13:23 2020. - You can adapt this file completely to your liking, but it should at least - contain the root `toctree` directive. +.. LLEPE: Liquid-Liquid Equilibrium Parameter Estimator + Copyright (C) 2020, UChicago Argonne, LLC. All rights reserved. + Released under the modified BSD license. See LICENSE for more details. -Welcome to llepe's docs! - the Liquid-Liquid Extraction Parameter Estimator +Welcome to LLEPE's docs! - the Liquid-Liquid Extraction Parameter Estimator =========================================================================== LLEPE is a package for thermodynamic parameter estimation for liquid-liquid extraction modeling @@ -19,12 +18,13 @@ Error between predicted and experimental data is then minimized. guide/install guide/quickstart + guide/about .. toctree:: :maxdepth: 1 :caption: Searchers - modules/reeps + modules/LLEPE diff --git a/docs/_source/modules/reeps.rst b/docs/_build/html/_sources/modules/LLEPE.rst.txt similarity index 74% rename from docs/_source/modules/reeps.rst rename to docs/_build/html/_sources/modules/LLEPE.rst.txt index bba5c13..41daa9d 100644 --- a/docs/_source/modules/reeps.rst +++ b/docs/_build/html/_sources/modules/LLEPE.rst.txt @@ -1,4 +1,4 @@ -.. _reeps: +.. _LLEPE: .. automodule:: llepe diff --git a/docs/_build/html/_sources/modules/reeps.rst.txt b/docs/_build/html/_sources/modules/reeps.rst.txt index bba5c13..41daa9d 100644 --- a/docs/_build/html/_sources/modules/reeps.rst.txt +++ b/docs/_build/html/_sources/modules/reeps.rst.txt @@ -1,4 +1,4 @@ -.. _reeps: +.. _LLEPE: .. automodule:: llepe diff --git a/docs/_build/html/_static/alabaster.css b/docs/_build/html/_static/alabaster.css deleted file mode 100644 index 0eddaeb..0000000 --- a/docs/_build/html/_static/alabaster.css +++ /dev/null @@ -1,701 +0,0 @@ -@import url("basic.css"); - -/* -- page layout ----------------------------------------------------------- */ - -body { - font-family: Georgia, serif; - font-size: 17px; - background-color: #fff; - color: #000; - margin: 0; - padding: 0; -} - - -div.document { - width: 940px; - margin: 30px auto 0 auto; -} - -div.documentwrapper { - float: left; - width: 100%; -} - -div.bodywrapper { - margin: 0 0 0 220px; -} - -div.sphinxsidebar { - width: 220px; - font-size: 14px; - line-height: 1.5; -} - -hr { - border: 1px solid #B1B4B6; -} - -div.body { - background-color: #fff; - color: #3E4349; - padding: 0 30px 0 30px; -} - -div.body > .section { - text-align: left; -} - -div.footer { - width: 940px; - margin: 20px auto 30px auto; - font-size: 14px; - color: #888; - text-align: right; -} - -div.footer a { - color: #888; -} - -p.caption { - font-family: inherit; - font-size: inherit; -} - - -div.relations { - display: none; -} - - -div.sphinxsidebar a { - color: #444; - text-decoration: none; - border-bottom: 1px dotted #999; -} - -div.sphinxsidebar a:hover { - border-bottom: 1px solid #999; -} - -div.sphinxsidebarwrapper { - padding: 18px 10px; -} - -div.sphinxsidebarwrapper p.logo { - padding: 0; - margin: -10px 0 0 0px; - text-align: center; -} - -div.sphinxsidebarwrapper h1.logo { - margin-top: -10px; - text-align: center; - margin-bottom: 5px; - text-align: left; -} - -div.sphinxsidebarwrapper h1.logo-name { - margin-top: 0px; -} - -div.sphinxsidebarwrapper p.blurb { - margin-top: 0; - font-style: normal; -} - -div.sphinxsidebar h3, -div.sphinxsidebar h4 { - font-family: Georgia, serif; - color: #444; - font-size: 24px; - font-weight: normal; - margin: 0 0 5px 0; - padding: 0; -} - -div.sphinxsidebar h4 { - font-size: 20px; -} - -div.sphinxsidebar h3 a { - color: #444; -} - -div.sphinxsidebar p.logo a, -div.sphinxsidebar h3 a, -div.sphinxsidebar p.logo a:hover, -div.sphinxsidebar h3 a:hover { - border: none; -} - -div.sphinxsidebar p { - color: #555; - margin: 10px 0; -} - -div.sphinxsidebar ul { - margin: 10px 0; - padding: 0; - color: #000; -} - -div.sphinxsidebar ul li.toctree-l1 > a { - font-size: 120%; -} - -div.sphinxsidebar ul li.toctree-l2 > a { - font-size: 110%; -} - -div.sphinxsidebar input { - border: 1px solid #CCC; - font-family: Georgia, serif; - font-size: 1em; -} - -div.sphinxsidebar hr { - border: none; - height: 1px; - color: #AAA; - background: #AAA; - - text-align: left; - margin-left: 0; - width: 50%; -} - -div.sphinxsidebar .badge { - border-bottom: none; -} - -div.sphinxsidebar .badge:hover { - border-bottom: none; -} - -/* To address an issue with donation coming after search */ -div.sphinxsidebar h3.donation { - margin-top: 10px; -} - -/* -- body styles ----------------------------------------------------------- */ - -a { - color: #004B6B; - text-decoration: underline; -} - -a:hover { - color: #6D4100; - text-decoration: underline; -} - -div.body h1, -div.body h2, -div.body h3, -div.body h4, -div.body h5, -div.body h6 { - font-family: Georgia, serif; - font-weight: normal; - margin: 30px 0px 10px 0px; - padding: 0; -} - -div.body h1 { margin-top: 0; padding-top: 0; font-size: 240%; } -div.body h2 { font-size: 180%; } -div.body h3 { font-size: 150%; } -div.body h4 { font-size: 130%; } -div.body h5 { font-size: 100%; } -div.body h6 { font-size: 100%; } - -a.headerlink { - color: #DDD; - padding: 0 4px; - text-decoration: none; -} - -a.headerlink:hover { - color: #444; - background: #EAEAEA; -} - -div.body p, div.body dd, div.body li { - line-height: 1.4em; -} - -div.admonition { - margin: 20px 0px; - padding: 10px 30px; - background-color: #EEE; - border: 1px solid #CCC; -} - -div.admonition tt.xref, div.admonition code.xref, div.admonition a tt { - background-color: #FBFBFB; - border-bottom: 1px solid #fafafa; -} - -div.admonition p.admonition-title { - font-family: Georgia, serif; - font-weight: normal; - font-size: 24px; - margin: 0 0 10px 0; - padding: 0; - line-height: 1; -} - -div.admonition p.last { - margin-bottom: 0; -} - -div.highlight { - background-color: #fff; -} - -dt:target, .highlight { - background: #FAF3E8; -} - -div.warning { - background-color: #FCC; - border: 1px solid #FAA; -} - -div.danger { - background-color: #FCC; - border: 1px solid #FAA; - -moz-box-shadow: 2px 2px 4px #D52C2C; - -webkit-box-shadow: 2px 2px 4px #D52C2C; - box-shadow: 2px 2px 4px #D52C2C; -} - -div.error { - background-color: #FCC; - border: 1px solid #FAA; - -moz-box-shadow: 2px 2px 4px #D52C2C; - -webkit-box-shadow: 2px 2px 4px #D52C2C; - box-shadow: 2px 2px 4px #D52C2C; -} - -div.caution { - background-color: #FCC; - border: 1px solid #FAA; -} - -div.attention { - background-color: #FCC; - border: 1px solid #FAA; -} - -div.important { - background-color: #EEE; - border: 1px solid #CCC; -} - -div.note { - background-color: #EEE; - border: 1px solid #CCC; -} - -div.tip { - background-color: #EEE; - border: 1px solid #CCC; -} - -div.hint { - background-color: #EEE; - border: 1px solid #CCC; -} - -div.seealso { - background-color: #EEE; - border: 1px solid #CCC; -} - -div.topic { - background-color: #EEE; -} - -p.admonition-title { - display: inline; -} - -p.admonition-title:after { - content: ":"; -} - -pre, tt, code { - font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; - font-size: 0.9em; -} - -.hll { - background-color: #FFC; - margin: 0 -12px; - padding: 0 12px; - display: block; -} - -img.screenshot { -} - -tt.descname, tt.descclassname, code.descname, code.descclassname { - font-size: 0.95em; -} - -tt.descname, code.descname { - padding-right: 0.08em; -} - -img.screenshot { - -moz-box-shadow: 2px 2px 4px #EEE; - -webkit-box-shadow: 2px 2px 4px #EEE; - box-shadow: 2px 2px 4px #EEE; -} - -table.docutils { - border: 1px solid #888; - -moz-box-shadow: 2px 2px 4px #EEE; - -webkit-box-shadow: 2px 2px 4px #EEE; - box-shadow: 2px 2px 4px #EEE; -} - -table.docutils td, table.docutils th { - border: 1px solid #888; - padding: 0.25em 0.7em; -} - -table.field-list, table.footnote { - border: none; - -moz-box-shadow: none; - -webkit-box-shadow: none; - box-shadow: none; -} - -table.footnote { - margin: 15px 0; - width: 100%; - border: 1px solid #EEE; - background: #FDFDFD; - font-size: 0.9em; -} - -table.footnote + table.footnote { - margin-top: -15px; - border-top: none; -} - -table.field-list th { - padding: 0 0.8em 0 0; -} - -table.field-list td { - padding: 0; -} - -table.field-list p { - margin-bottom: 0.8em; -} - -/* Cloned from - * https://github.com/sphinx-doc/sphinx/commit/ef60dbfce09286b20b7385333d63a60321784e68 - */ -.field-name { - -moz-hyphens: manual; - -ms-hyphens: manual; - -webkit-hyphens: manual; - hyphens: manual; -} - -table.footnote td.label { - width: .1px; - padding: 0.3em 0 0.3em 0.5em; -} - -table.footnote td { - padding: 0.3em 0.5em; -} - -dl { - margin: 0; - padding: 0; -} - -dl dd { - margin-left: 30px; -} - -blockquote { - margin: 0 0 0 30px; - padding: 0; -} - -ul, ol { - /* Matches the 30px from the narrow-screen "li > ul" selector below */ - margin: 10px 0 10px 30px; - padding: 0; -} - -pre { - background: #EEE; - padding: 7px 30px; - margin: 15px 0px; - line-height: 1.3em; -} - -div.viewcode-block:target { - background: #ffd; -} - -dl pre, blockquote pre, li pre { - margin-left: 0; - padding-left: 30px; -} - -tt, code { - background-color: #ecf0f3; - color: #222; - /* padding: 1px 2px; */ -} - -tt.xref, code.xref, a tt { - background-color: #FBFBFB; - border-bottom: 1px solid #fff; -} - -a.reference { - text-decoration: none; - border-bottom: 1px dotted #004B6B; -} - -/* Don't put an underline on images */ -a.image-reference, a.image-reference:hover { - border-bottom: none; -} - -a.reference:hover { - border-bottom: 1px solid #6D4100; -} - -a.footnote-reference { - text-decoration: none; - font-size: 0.7em; - vertical-align: top; - border-bottom: 1px dotted #004B6B; -} - -a.footnote-reference:hover { - border-bottom: 1px solid #6D4100; -} - -a:hover tt, a:hover code { - background: #EEE; -} - - -@media screen and (max-width: 870px) { - - div.sphinxsidebar { - display: none; - } - - div.document { - width: 100%; - - } - - div.documentwrapper { - margin-left: 0; - margin-top: 0; - margin-right: 0; - margin-bottom: 0; - } - - div.bodywrapper { - margin-top: 0; - margin-right: 0; - margin-bottom: 0; - margin-left: 0; - } - - ul { - margin-left: 0; - } - - li > ul { - /* Matches the 30px from the "ul, ol" selector above */ - margin-left: 30px; - } - - .document { - width: auto; - } - - .footer { - width: auto; - } - - .bodywrapper { - margin: 0; - } - - .footer { - width: auto; - } - - .github { - display: none; - } - - - -} - - - -@media screen and (max-width: 875px) { - - body { - margin: 0; - padding: 20px 30px; - } - - div.documentwrapper { - float: none; - background: #fff; - } - - div.sphinxsidebar { - display: block; - float: none; - width: 102.5%; - margin: 50px -30px -20px -30px; - padding: 10px 20px; - background: #333; - color: #FFF; - } - - div.sphinxsidebar h3, div.sphinxsidebar h4, div.sphinxsidebar p, - div.sphinxsidebar h3 a { - color: #fff; - } - - div.sphinxsidebar a { - color: #AAA; - } - - div.sphinxsidebar p.logo { - display: none; - } - - div.document { - width: 100%; - margin: 0; - } - - div.footer { - display: none; - } - - div.bodywrapper { - margin: 0; - } - - div.body { - min-height: 0; - padding: 0; - } - - .rtd_doc_footer { - display: none; - } - - .document { - width: auto; - } - - .footer { - width: auto; - } - - .footer { - width: auto; - } - - .github { - display: none; - } -} - - -/* misc. */ - -.revsys-inline { - display: none!important; -} - -/* Make nested-list/multi-paragraph items look better in Releases changelog - * pages. Without this, docutils' magical list fuckery causes inconsistent - * formatting between different release sub-lists. - */ -div#changelog > div.section > ul > li > p:only-child { - margin-bottom: 0; -} - -/* Hide fugly table cell borders in ..bibliography:: directive output */ -table.docutils.citation, table.docutils.citation td, table.docutils.citation th { - border: none; - /* Below needed in some edge cases; if not applied, bottom shadows appear */ - -moz-box-shadow: none; - -webkit-box-shadow: none; - box-shadow: none; -} - - -/* relbar */ - -.related { - line-height: 30px; - width: 100%; - font-size: 0.9rem; -} - -.related.top { - border-bottom: 1px solid #EEE; - margin-bottom: 20px; -} - -.related.bottom { - border-top: 1px solid #EEE; -} - -.related ul { - padding: 0; - margin: 0; - list-style: none; -} - -.related li { - display: inline; -} - -nav#rellinks { - float: right; -} - -nav#rellinks li+li:before { - content: "|"; -} - -nav#breadcrumbs li+li:before { - content: "\00BB"; -} - -/* Hide certain items when printing */ -@media print { - div.related { - display: none; - } -} \ No newline at end of file diff --git a/docs/_build/html/_static/classic.css b/docs/_build/html/_static/classic.css deleted file mode 100644 index b4fd80f..0000000 --- a/docs/_build/html/_static/classic.css +++ /dev/null @@ -1,266 +0,0 @@ -/* - * classic.css_t - * ~~~~~~~~~~~~~ - * - * Sphinx stylesheet -- classic theme. - * - * :copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS. - * :license: BSD, see LICENSE for details. - * - */ - -@import url("basic.css"); - -/* -- page layout ----------------------------------------------------------- */ - -html { - /* CSS hack for macOS's scrollbar (see #1125) */ - background-color: #FFFFFF; -} - -body { - font-family: sans-serif; - font-size: 100%; - background-color: #11303d; - color: #000; - margin: 0; - padding: 0; -} - -div.document { - background-color: #1c4e63; -} - -div.documentwrapper { - float: left; - width: 100%; -} - -div.bodywrapper { - margin: 0 0 0 230px; -} - -div.body { - background-color: #ffffff; - color: #000000; - padding: 0 20px 30px 20px; -} - -div.footer { - color: #ffffff; - width: 100%; - padding: 9px 0 9px 0; - text-align: center; - font-size: 75%; -} - -div.footer a { - color: #ffffff; - text-decoration: underline; -} - -div.related { - background-color: #133f52; - line-height: 30px; - color: #ffffff; -} - -div.related a { - color: #ffffff; -} - -div.sphinxsidebar { -} - -div.sphinxsidebar h3 { - font-family: 'Trebuchet MS', sans-serif; - color: #ffffff; - font-size: 1.4em; - font-weight: normal; - margin: 0; - padding: 0; -} - -div.sphinxsidebar h3 a { - color: #ffffff; -} - -div.sphinxsidebar h4 { - font-family: 'Trebuchet MS', sans-serif; - color: #ffffff; - font-size: 1.3em; - font-weight: normal; - margin: 5px 0 0 0; - padding: 0; -} - -div.sphinxsidebar p { - color: #ffffff; -} - -div.sphinxsidebar p.topless { - margin: 5px 10px 10px 10px; -} - -div.sphinxsidebar ul { - margin: 10px; - padding: 0; - color: #ffffff; -} - -div.sphinxsidebar a { - color: #98dbcc; -} - -div.sphinxsidebar input { - border: 1px solid #98dbcc; - font-family: sans-serif; - font-size: 1em; -} - - - -/* -- hyperlink styles ------------------------------------------------------ */ - -a { - color: #355f7c; - text-decoration: none; -} - -a:visited { - color: #355f7c; - text-decoration: none; -} - -a:hover { - text-decoration: underline; -} - - - -/* -- body styles ----------------------------------------------------------- */ - -div.body h1, -div.body h2, -div.body h3, -div.body h4, -div.body h5, -div.body h6 { - font-family: 'Trebuchet MS', sans-serif; - background-color: #f2f2f2; - font-weight: normal; - color: #20435c; - border-bottom: 1px solid #ccc; - margin: 20px -20px 10px -20px; - padding: 3px 0 3px 10px; -} - -div.body h1 { margin-top: 0; font-size: 200%; } -div.body h2 { font-size: 160%; } -div.body h3 { font-size: 140%; } -div.body h4 { font-size: 120%; } -div.body h5 { font-size: 110%; } -div.body h6 { font-size: 100%; } - -a.headerlink { - color: #c60f0f; - font-size: 0.8em; - padding: 0 4px 0 4px; - text-decoration: none; -} - -a.headerlink:hover { - background-color: #c60f0f; - color: white; -} - -div.body p, div.body dd, div.body li, div.body blockquote { - text-align: justify; - line-height: 130%; -} - -div.admonition p.admonition-title + p { - display: inline; -} - -div.admonition p { - margin-bottom: 5px; -} - -div.admonition pre { - margin-bottom: 5px; -} - -div.admonition ul, div.admonition ol { - margin-bottom: 5px; -} - -div.note { - background-color: #eee; - border: 1px solid #ccc; -} - -div.seealso { - background-color: #ffc; - border: 1px solid #ff6; -} - -div.topic { - background-color: #eee; -} - -div.warning { - background-color: #ffe4e4; - border: 1px solid #f66; -} - -p.admonition-title { - display: inline; -} - -p.admonition-title:after { - content: ":"; -} - -pre { - padding: 5px; - background-color: #eeffcc; - color: #333333; - line-height: 120%; - border: 1px solid #ac9; - border-left: none; - border-right: none; -} - -code { - background-color: #ecf0f3; - padding: 0 1px 0 1px; - font-size: 0.95em; -} - -th, dl.field-list > dt { - background-color: #ede; -} - -.warning code { - background: #efc2c2; -} - -.note code { - background: #d6d6d6; -} - -.viewcode-back { - font-family: sans-serif; -} - -div.viewcode-block:target { - background-color: #f4debf; - border-top: 1px solid #ac9; - border-bottom: 1px solid #ac9; -} - -div.code-block-caption { - color: #efefef; - background-color: #1c4e63; -} \ No newline at end of file diff --git a/docs/_build/html/_static/custom.css b/docs/_build/html/_static/custom.css deleted file mode 100644 index 2a924f1..0000000 --- a/docs/_build/html/_static/custom.css +++ /dev/null @@ -1 +0,0 @@ -/* This file intentionally left blank. */ diff --git a/docs/_build/html/_static/default.css b/docs/_build/html/_static/default.css deleted file mode 100644 index 81b9363..0000000 --- a/docs/_build/html/_static/default.css +++ /dev/null @@ -1 +0,0 @@ -@import url("classic.css"); diff --git a/docs/_build/html/_static/sidebar.js b/docs/_build/html/_static/sidebar.js deleted file mode 100644 index 657f8be..0000000 --- a/docs/_build/html/_static/sidebar.js +++ /dev/null @@ -1,159 +0,0 @@ -/* - * sidebar.js - * ~~~~~~~~~~ - * - * This script makes the Sphinx sidebar collapsible. - * - * .sphinxsidebar contains .sphinxsidebarwrapper. This script adds - * in .sphixsidebar, after .sphinxsidebarwrapper, the #sidebarbutton - * used to collapse and expand the sidebar. - * - * When the sidebar is collapsed the .sphinxsidebarwrapper is hidden - * and the width of the sidebar and the margin-left of the document - * are decreased. When the sidebar is expanded the opposite happens. - * This script saves a per-browser/per-session cookie used to - * remember the position of the sidebar among the pages. - * Once the browser is closed the cookie is deleted and the position - * reset to the default (expanded). - * - * :copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS. - * :license: BSD, see LICENSE for details. - * - */ - -$(function() { - - - - - - - - - // global elements used by the functions. - // the 'sidebarbutton' element is defined as global after its - // creation, in the add_sidebar_button function - var bodywrapper = $('.bodywrapper'); - var sidebar = $('.sphinxsidebar'); - var sidebarwrapper = $('.sphinxsidebarwrapper'); - - // for some reason, the document has no sidebar; do not run into errors - if (!sidebar.length) return; - - // original margin-left of the bodywrapper and width of the sidebar - // with the sidebar expanded - var bw_margin_expanded = bodywrapper.css('margin-left'); - var ssb_width_expanded = sidebar.width(); - - // margin-left of the bodywrapper and width of the sidebar - // with the sidebar collapsed - var bw_margin_collapsed = '.8em'; - var ssb_width_collapsed = '.8em'; - - // colors used by the current theme - var dark_color = $('.related').css('background-color'); - var light_color = $('.document').css('background-color'); - - function sidebar_is_collapsed() { - return sidebarwrapper.is(':not(:visible)'); - } - - function toggle_sidebar() { - if (sidebar_is_collapsed()) - expand_sidebar(); - else - collapse_sidebar(); - } - - function collapse_sidebar() { - sidebarwrapper.hide(); - sidebar.css('width', ssb_width_collapsed); - bodywrapper.css('margin-left', bw_margin_collapsed); - sidebarbutton.css({ - 'margin-left': '0', - 'height': bodywrapper.height() - }); - sidebarbutton.find('span').text('»'); - sidebarbutton.attr('title', _('Expand sidebar')); - document.cookie = 'sidebar=collapsed'; - } - - function expand_sidebar() { - bodywrapper.css('margin-left', bw_margin_expanded); - sidebar.css('width', ssb_width_expanded); - sidebarwrapper.show(); - sidebarbutton.css({ - 'margin-left': ssb_width_expanded-12, - 'height': bodywrapper.height() - }); - sidebarbutton.find('span').text('«'); - sidebarbutton.attr('title', _('Collapse sidebar')); - document.cookie = 'sidebar=expanded'; - } - - function add_sidebar_button() { - sidebarwrapper.css({ - 'float': 'left', - 'margin-right': '0', - 'width': ssb_width_expanded - 28 - }); - // create the button - sidebar.append( - '
«
' - ); - var sidebarbutton = $('#sidebarbutton'); - light_color = sidebarbutton.css('background-color'); - // find the height of the viewport to center the '<<' in the page - var viewport_height; - if (window.innerHeight) - viewport_height = window.innerHeight; - else - viewport_height = $(window).height(); - sidebarbutton.find('span').css({ - 'display': 'block', - 'margin-top': (viewport_height - sidebar.position().top - 20) / 2 - }); - - sidebarbutton.click(toggle_sidebar); - sidebarbutton.attr('title', _('Collapse sidebar')); - sidebarbutton.css({ - 'color': '#FFFFFF', - 'border-left': '1px solid ' + dark_color, - 'font-size': '1.2em', - 'cursor': 'pointer', - 'height': bodywrapper.height(), - 'padding-top': '1px', - 'margin-left': ssb_width_expanded - 12 - }); - - sidebarbutton.hover( - function () { - $(this).css('background-color', dark_color); - }, - function () { - $(this).css('background-color', light_color); - } - ); - } - - function set_position_from_cookie() { - if (!document.cookie) - return; - var items = document.cookie.split(';'); - for(var k=0; k
  • Installation
  • Getting Started
  • +
  • About
  • Searchers

    @@ -169,7 +170,7 @@

    F

    @@ -177,45 +178,45 @@

    G

    @@ -227,14 +228,14 @@ llepe @@ -246,7 +247,7 @@ module @@ -255,11 +256,11 @@

    P

    @@ -267,7 +268,7 @@

    R

    @@ -275,45 +276,45 @@

    S

    @@ -321,13 +322,13 @@

    U

    @@ -344,7 +345,7 @@

    - © Copyright 2020, Titus Quah, Nwike Iloeje + © Copyright 2020, UChicago Argonne, LLC.

    diff --git a/docs/_build/html/guide/about.html b/docs/_build/html/guide/about.html new file mode 100644 index 0000000..67be0bd --- /dev/null +++ b/docs/_build/html/guide/about.html @@ -0,0 +1,272 @@ + + + + + + + + + + + About — LLEPE 1.0.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + +
    + + + + + +
    + +
    + + + + + + + + + + + + + + + + + +
    + + + + +
    +
    +
    +
    + +
    +

    About

    +
    +

    Authors

    +

    Titus Quah, University of Utah, <titus{dot}quah{at}gmail{dot}com>

    +

    Nwike Iloeje, Argonne National Laboratory, <ciloeje{at}anl{dot}gov>

    +
    +
    +

    Acknowledgements

    +

    Based upon work supported by funding from Argonne National Laboratory provided by the U.S. Department of Energy, Office of Energy Efficiency and Renewable Energy (EERE), under contract DE-AC02-06CH11357

    +
    +
    +

    References

    +

    If you use LLEPE in your research , we kindly request that you cite the package as follows:

    +
      +
    1. Quah and C. O. Iloeje, “Liquid--Liquid Extraction Thermodynamic Parameter Estimator (LLEPE) for Multicomponent Separation Systems,” in Materials Processing Fundamentals 2021, 2021, pp. 107–120, doi: https://doi.org/10.1007/978-3-030-65253-1_9.

    2. +
    +
    +
    +

    License

    +
    Copyright © 2020, UChicago Argonne, LLC
    +All Rights Reserved
    + Software Name: LLEPE
    +By: Argonne National Laboratory, University of Utah
    +OPEN SOURCE LICENSE
    +
    +Redistribution and use in source and binary forms, with or without
    +modification, are permitted provided that the following conditions are met:
    +
    +1. Redistributions of source code must retain the above copyright notice,
    +   this list of conditions and the following disclaimer.
    +2. Redistributions in binary form must reproduce the above copyright notice,
    +   this list of conditions and the following disclaimer in the documentation
    +   and/or other materials provided with the distribution.
    +3. Neither the name of the copyright holder nor the names of its contributors
    +   may be used to endorse or promote products derived from this software without
    +   specific prior written permission.
    +
    +
    +******************************************************************************************************
    +DISCLAIMER
    +
    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
    +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
    +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
    +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
    +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
    +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
    +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
    +OF SUCH DAMAGE.
    +***************************************************************************************************
    +
    +
    +
    +
    + + +
    + +
    + + +
    +
    + +
    + +
    + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/_build/html/guide/install.html b/docs/_build/html/guide/install.html index f28dddc..17e566e 100644 --- a/docs/_build/html/guide/install.html +++ b/docs/_build/html/guide/install.html @@ -36,7 +36,7 @@ - + @@ -97,7 +97,7 @@

    Searchers

    @@ -175,14 +175,14 @@

    Bleeding-edge version

    To install the latest master version:

    -
    pip install git+https://xgitlab.cels.anl.gov/summer-2020/parameter-estimation.git
    +
    pip install git+https://github.com/ANL-CEEESA/LLEPE.git
     

    Development version

    -

    To contribute to Stable-Baselines, with support for running tests and building the documentation.

    -
    git clone https://xgitlab.cels.anl.gov/summer-2020/parameter-estimation.git && cd parameter-estimation
    +

    To contribute to LLEPE, with support for running tests and building the documentation.

    +
    git clone https://github.com/ANL-CEEESA/LLEPE.git
     pip install -e .[docs,tests]
     
    @@ -204,7 +204,7 @@ pip install -e .[docs,tests] - +
    @@ -213,7 +213,7 @@ pip install -e .[docs,tests]

    - © Copyright 2020, Titus Quah, Nwike Iloeje + © Copyright 2020, UChicago Argonne, LLC.

    diff --git a/docs/_build/html/guide/quickstart.html b/docs/_build/html/guide/quickstart.html index 948381e..72b8974 100644 --- a/docs/_build/html/guide/quickstart.html +++ b/docs/_build/html/guide/quickstart.html @@ -218,7 +218,7 @@ aqueous phase.

    - © Copyright 2020, Titus Quah, Nwike Iloeje + © Copyright 2020, UChicago Argonne, LLC.

    diff --git a/docs/_build/html/index.html b/docs/_build/html/index.html index 7f6af8e..9cee7a4 100644 --- a/docs/_build/html/index.html +++ b/docs/_build/html/index.html @@ -8,7 +8,7 @@ - Welcome to llepe's docs! - the Liquid-Liquid Extraction Parameter Estimator — LLEPE 1.0.0 documentation + Welcome to LLEPE's docs! - the Liquid-Liquid Extraction Parameter Estimator — LLEPE 1.0.0 documentation @@ -86,10 +86,11 @@

    Searchers

    @@ -135,7 +136,7 @@
  • Docs »
  • -
  • Welcome to llepe's docs! - the Liquid-Liquid Extraction Parameter Estimator
  • +
  • Welcome to LLEPE's docs! - the Liquid-Liquid Extraction Parameter Estimator
  • @@ -155,7 +156,7 @@
    -

    Welcome to llepe's docs! - the Liquid-Liquid Extraction Parameter Estimator

    +

    Welcome to LLEPE's docs! - the Liquid-Liquid Extraction Parameter Estimator

    LLEPE is a package for thermodynamic parameter estimation for liquid-liquid extraction modeling

    LLEPE takes experimental data in a csv and system data in a xml.

    The package then uses Cantera, another python package, to simulate equilibrium.

    @@ -172,12 +173,19 @@
  • Getting Started
  • +
  • About +
  • Searchers

    @@ -208,7 +216,7 @@

    - © Copyright 2020, Titus Quah, Nwike Iloeje + © Copyright 2020, UChicago Argonne, LLC.

    diff --git a/docs/_build/html/modules/LLEPE.html b/docs/_build/html/modules/LLEPE.html new file mode 100644 index 0000000..4f1ff3b --- /dev/null +++ b/docs/_build/html/modules/LLEPE.html @@ -0,0 +1,1123 @@ + + + + + + + + + + + LLEPE — LLEPE 1.0.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + +
    + + + + + +
    + +
    + + + + + + + + + + + + + + + + + +
    + + + + +
    +
    +
    +
    + +
    +

    LLEPE

    +
    +

    Parameters

    +
    +
    +class llepe.LLEPE(exp_data, phases_xml_filename, phase_names, aq_solvent_name, extractant_name, diluant_name, complex_names, extracted_species_ion_names, extracted_species_list=None, aq_solvent_rho=None, extractant_rho=None, diluant_rho=None, opt_dict=None, objective_function='Log-MSE', optimizer='scipy_minimize', temp_xml_file_path=None, dependant_params_dict=None, custom_objects_dict=None)[source]
    +

    Liquid-Liquid Extraction Parameter estimator

    +
    +

    Note

    +

    The order in which the extracted species (ES) appear in the csv file +must be the same order as they appear in the xml, complex_names and +extracted_species_ion_names.

    +

    For example, say in exp_data, ES_1 is Nd ES_2 is Pr, +and

    +
    aq_solvent_name = 'H2O(L)'
    +extractant_name = '(HA)2(org)'
    +diluent_name = 'dodecane'
    +
    +
    +

    Then:

    +

    The exp_data column ordering must be (names do not matter):

    +

    [h_i, h_eq, z_i, z_eq, Nd_aq_i, Nd_aq_eq, Nd_d_eq, +Pr_aq_i, Pr_aq_eq, Pr_d_eq]

    +

    The aqueous speciesArray must be +"H2O(L) H+ OH- Cl- Nd+++ Pr+++"

    +

    The organic speciesArray must be +"(HA)2(org) dodecane Nd(H(A)2)3(org) Pr(H(A)2)3(org)"

    +
    complex_names = ['Nd(H(A)2)3(org)', 'Pr(H(A)2)3(org)']
    +extracted_species_ion_names = ['Nd+++', 'Pr+++']
    +
    +
    +
    +
    +
    Parameters
    +
      +
    • exp_data --

      (str or pd.DataFrame) csv file name +or DataFrame with experimental data

      +

      In the .csv file, the rows are different experiments and +columns are the measured quantities.

      +

      The ordering of the columns needs to be:

      +

      [h_i, h_eq, z_i, z_eq, +{ES_1}_aq_i, {ES_1}_aq_eq, {ES_1}_d_eq, +{ES_2}_aq_i, {ES_2}_aq_eq, {ES_2}_d_eq,... +{ES_N}_aq_i, {ES_N}_aq_eq, {ES_N}_d_eq]

      +

      Naming does not matter, just the order.

      +

      Where {ES_1}-{ES_N} are the extracted species names of interest +i.e. Nd, Pr, La, etc.

      +

      Below is an explanation of the columns.

      + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

      Index

      Column

      Meaning

      0

      h_i

      Initial Concentration of +H+ ions (mol/L)

      1

      h_eq

      Equilibrium concentration of +H+ ions (mol/L)

      2

      z_i

      Initial concentration of +extractant (mol/L)

      3

      z_eq

      Equilibrium concentration of +extractant (mol/L)

      4

      {ES}_aq_i

      Initial concentration of ES ions (mol/L)

      5

      {ES}_aq_eq

      Equilibrium concentration of ES ions +in aqueous phase (mol/L)

      6

      {ES}_d_eq

      Equilibrium Ratio between amount of +ES atoms in organic to aqueous

      +

    • +
    • phases_xml_filename --

      (str) xml file with parameters +for equilibrium calc

      +

      Would recommend copying and modifying xmls located in data/xmls +or in Cantera's "data" folder

      +

      speciesArray fields need specific ordering.

      +

      In aqueous phase: aq_solvent_name, H+, OH-, Cl-, ES_1, ES_2, ..., ES_N

      +

      (ES_1-ES_N) represent ES ion names i.e. Nd+++, Pr+++

      +

      In organic phase : extractant_name, diluant_name, ES_1, ES_2, ..., ES_N

      +

      (ES_1-ES_N) represent ES complex names +i.e. Nd(H(A)2)3(org), Pr(H(A)2)3(org)

      +

    • +
    • phase_names --

      (list) names of phases in xml file

      +

      Found in the xml file under <phase ... id={phase_name}>

      +

    • +
    • aq_solvent_name -- (str) name of aqueous solvent in xml file

    • +
    • extractant_name -- (str) name of extractant in xml file

    • +
    • diluant_name -- (str) name of diluant in xml file

    • +
    • complex_names -- (list) names of complexes in xml file.

    • +
    • extracted_species_ion_names -- (list) names of extracted species ions +in xml file

    • +
    • extracted_species_list --

      (list) names of extracted species elements.

      +

      If None, extracted_species_list will be extracted_species_ion_names +without '+' i.e. 'Nd+++'->'Nd'

      +

    • +
    • aq_solvent_rho --

      (float) density of solvent (g/L)

      +

      If None, molar volume/molecular weight is used from xml

      +

    • +
    • extractant_rho --

      (float) density of extractant (g/L)

      +

      If None, molar volume/molecular weight is used from xml

      +

    • +
    • diluant_rho --

      (float) density of diluant (g/L)

      +

      If None, molar volume/molecular weight is used from xml

      +

    • +
    • opt_dict --

      (dict) dictionary containing info about which +species parameters are updated to fit model to experimental data

      +

      Should have the format as below. Dictionary keys under user defined +parameter name must be named as shown below ('upper_element_name', +'upper_attrib_name', etc.). 'attrib_name's and 'attrib_value's can +be None. {} denotes areas for user to fill in.

      +
      opt_dict = {"{user_defined_name_for_parameter_1}":
      +                {'upper_element_name': {param_upper_element},
      +                'upper_attrib_name': {param_upper_attrib_name},
      +                'upper_attrib_value': {param_upper_attrib_value},
      +                'lower_element_name': {param_lower_element},
      +                'lower_attrib_name': {param_lower_attrib_name},
      +                'lower_attrib_value': {param_lower_attrib_value},
      +                'input_format': {str format to input input_value}
      +                'input_value': {guess_value}},
      +            "{user_defined_name_for_parameter_2}":
      +                            ...
      +            ...
      +            }
      +
      +
      +

      See example files for more examples.

      +

    • +
    • objective_function --

      (function or str) function to compute objective

      +

      By default, the objective function is log mean squared error +of distribution ratio

      +
      np.sum((np.log10(d_pred)-np.log10(d_meas))^2)
      +
      +
      +

      Function needs to take inputs:

      +
      objective_function(predicted_dict, measured_df, kwargs)
      +
      +
      +

      kwargs is optional

      +

      Function needs to return: (float) value computed by objective function

      +

      Below is the guide for referencing predicted values

      + ++++ + + + + + + + + + + + + + + + + + + + + + + +

      To access

      Use

      hydrogen ion conc in aq

      predicted_dict['h_eq']

      extractant conc in org

      predicted_dict['z_eq']

      ES ion eq conc in aq

      predicted_dict['{ES}_aq_eq']

      ES complex eq conc in org

      predicted_dict['{ES}_org_eq']

      ES distribution ratio

      predicted_dict['{ES}_d_eq']

      +

      Replace "{ES}" with extracted species element i.e. Nd, La, etc.

      +

      For measured values, use the same names, but +replace predicted_dict with measured_df

      +

    • +
    • optimizer --

      (function or str) function to perform optimization

      +
      +

      Note

      +

      The optimized variables are not directly the species parameters, +but instead are first multiplied by the initial guess before +sending becoming the species parameters.

      +

      For example, say

      +
      opt_dict = {'Nd(H(A)2)3(org):'h0':-4.7e6}
      +
      +
      +

      If the bounds on h0 need to be [-4.7e7,-4.7e5], then +divide the bounds by the guess and get

      +
      "bounds": [(1e-1, 1e1)]
      +
      +
      +
      +

      By default, the optimizer is scipy's optimize function with

      +
      default_kwargs= {"method": 'SLSQP',
      +                 "bounds": [(1e-1, 1e1)] * len(x_guess),
      +                 "constraints": (),
      +                 "options": {'disp': True,
      +                             'maxiter': 1000,
      +                             'ftol': 1e-6}}
      +
      +
      +

      Function needs to take inputs: +optimizer(objective_function, x_guess, kwargs)

      +

      kwargs is optional

      +
      +
      Function needs to return: ((np.ndarray, float)) Optimized parameters,

      objective_function value

      +
      +
      +

    • +
    • temp_xml_file_path --

      (str) path to temporary xml file.

      +

      This xml file is a duplicate of the phases_xml_file name and is +modified during the optimization process to avoid changing the original +xml file

      +

      default is local temp folder

      +

    • +
    • dependant_params_dict --

      (dict) dictionary containing information +about parameters dependant on opt_dict. Has a similar structure to +opt_dict except instead of input values, it has 3 other fields: +'function', 'kwargs', and 'independent_params.

      +

      'function' is a function of the form

      +

      function(independent_param__value_list, custom_objects_dict, +**kwargs)

      +

      'kwargs' are the extra arguments to pass to function

      +

      'independent_params' is a list of parameter names in opt_dict that the +dependent_param is a function of.

      +

      'custom_objects_dict' is for accessing the estimator's internal +custom_objects_dict and must be included in the arguments, even if the +custom_objects_dict is not set and is None.

      +

      See example code for usage.

      +

    • +
    • custom_objects_dict -- (dict) dictionary containing custom objects +format: {<object_name_string>: <object>,...}

    • +
    +
    +
    +
    +
    +fit(objective_function=None, optimizer=None, objective_kwargs=None, optimizer_kwargs=None) → tuple[source]
    +

    Fits experimental to modeled data by minimizing objective function +with optimizer. Returns dictionary with opt_dict structure

    +
    +
    Parameters
    +
      +
    • objective_function -- (function) function to compute objective +If 'None', last set objective or default function is used

    • +
    • optimizer -- (function) function to perform optimization +If 'None', last set optimizer or default is used

    • +
    • optimizer_kwargs -- (dict) optional arguments for optimizer

    • +
    • objective_kwargs -- (dict) optional arguments +for objective function

    • +
    +
    +
    Returns tuple
    +

    (opt_dict (dict), opt_value (float)) +optimized opt_dict: Has identical structure as opt_dict

    +
    +
    +
    + +
    +
    +get_aq_solvent_name() → str[source]
    +

    Returns aq_solvent_name

    +
    +
    Returns
    +

    aq_solvent_name: (str) name of aqueous solvent in xml file

    +
    +
    +
    + +
    +
    +get_aq_solvent_rho() → str[source]
    +

    Returns aqueous solvent density (g/L)

    +
    +
    Returns
    +

    aq_solvent_rho: (float) density of aqueous solvent

    +
    +
    +
    + +
    +
    +get_complex_names() → list[source]
    +

    Returns list of complex names

    +
    +
    Returns
    +

    complex_names: (list) names of complexes in xml file.

    +
    +
    +
    + +
    +
    +get_custom_objects_dict()[source]
    +

    Returns the custom_objects_dict

    +
    +
    Returns
    +

    custom_objects_dict: (dict) dictionary containing +information about custom objects from user

    +
    +
    +
    + +
    +
    +get_dependant_params_dict()[source]
    +

    Returns the dependant_params_dict

    +
    +
    Returns
    +

    dependant_params_dict: (dict) dictionary containing +information about parameters dependant on opt_dict

    +
    +
    +
    + +
    +
    +get_diluant_name() → str[source]
    +

    Returns diluant name +:return: diluant_name: (str) name of diluant in xml file

    +
    + +
    +
    +get_diluant_rho() → str[source]
    +

    Returns diluant density (g/L)

    +
    +
    Returns
    +

    diluant_rho: (float) density of diluant

    +
    +
    +
    + +
    +
    +get_exp_df() → pandas.core.frame.DataFrame[source]
    +

    Returns the experimental DataFrame

    +
    +
    Returns
    +

    (pd.DataFrame) Experimental data

    +
    +
    +
    + +
    +
    +get_extractant_name() → str[source]
    +

    Returns extractant name

    +
    +
    Returns
    +

    extractant_name: (str) name of extractant in xml file

    +
    +
    +
    + +
    +
    +get_extractant_rho() → str[source]
    +

    Returns extractant density (g/L)

    +
    +
    Returns
    +

    extractant_rho: (float) density of extractant

    +
    +
    +
    + +
    +
    +get_extracted_species_ion_names() → list[source]
    +

    Returns list of extracted species ion names

    +
    +
    Returns
    +

    extracted_species_ion_names: (list) names of +extracted species ions in xml file

    +
    +
    +
    + +
    +
    +get_extracted_species_list() → list[source]
    +

    Returns list of extracted species names

    +
    +
    Returns
    +

    extracted_species_list: (list) names of extracted species in +xml file

    +
    +
    +
    + +
    +
    +get_in_moles() → pandas.core.frame.DataFrame[source]
    +

    Returns the in_moles DataFrame which contains the initial mole +fractions of each species for each experiment

    +
    +
    Returns
    +

    in_moles: (pd.DataFrame) DataFrame with initial mole fractions

    +
    +
    +
    + +
    +
    +get_objective_function()[source]
    +

    Returns objective function

    +
    +
    Returns
    +

    objective_function: (func) Objective function to quantify +error between model and experimental data

    +
    +
    +
    + +
    +
    +get_opt_dict() → dict[source]
    +

    Returns the dictionary containing optimization information

    +
    +
    Returns
    +

    (dict) dictionary containing info about which +species parameters are updated to fit model to experimental data

    +
    +
    +
    + +
    +
    +get_optimizer()[source]
    +

    Returns objective function

    +
    +
    Returns
    +

    optimizer: (func) Optimizer function to minimize objective +function

    +
    +
    +
    + +
    +
    +get_phases() → list[source]
    +

    Returns the list of Cantera solutions

    +
    +
    Returns
    +

    (list) list of Cantera solutions/phases

    +
    +
    +
    + +
    +
    +get_predicted_dict()[source]
    +

    Returns predicted dictionary of species concentrations +that xml parameters predicts given current in_moles

    +
    +
    Returns
    +

    predicted_dict: (dict) dictionary of species concentrations

    +
    +
    +
    + +
    +
    +get_temp_xml_file_path()[source]
    +

    Returns path to temporary xml file.

    +

    This xml file is a duplicate of the phases_xml_file name and is +modified during the optimization process to avoid changing the original +xml file.

    +
    +
    Returns
    +

    temp_xml_file_path: (str) path to temporary xml file.

    +
    +
    +
    + +
    +
    +log_mean_squared_error(predicted_dict, meas_df)[source]
    +

    Default objective function for LLEPE

    +

    Returns the log mean squared error of +predicted distribution ratios (d=n_org/n_aq) +to measured d.

    +

    np.sum((np.log10(d_pred)-np.log10(d_meas))**2)

    +
    +
    Parameters
    +
      +
    • predicted_dict -- (dict) contains predicted data

    • +
    • meas_df -- (pd.DataFrame) contains experimental data

    • +
    +
    +
    Returns
    +

    (float) log mean squared error between predicted and measured

    +
    +
    +
    + +
    +
    +parity_plot(compared_value=None, c_data=None, c_label=None, plot_title=None, save_path=None, print_r_squared=False, data_labels=None, legend=True)[source]
    +

    Parity plot between measured and predicted compared_value. +Default compared value is {ES_1}_aq_eq

    +
    +
    Parameters
    +
      +
    • compared_value -- (str) Quantity to compare predicted and +experimental data. Can be any column containing "eq" in exp_df i.e. +h_eq, z_eq, {ES}_d_eq, etc.

    • +
    • plot_title --

      (str or boolean)

      +
      +
      If None (default): Plot title will be generated from compared_value

      Recommend to just explore. If h_eq, plot_title is +"H^+ eq conc".

      +
      +
      +

      If str: Plot title will be plot_title string

      +

      If "False": No plot title

      +

    • +
    • c_data -- (list or np.ndarray) data for color axis

    • +
    • c_label -- (str) label for color axis

    • +
    • save_path -- (str) save path for parity plot

    • +
    • print_r_squared -- (boolean) To plot or not to plot r-squared +value. Prints 2 places past decimal

    • +
    • data_labels -- labels for the data such as paper's name where +experiment is pulled from.

    • +
    • legend -- whether to display legend for data_labels. Has no +effect if data_labels is None

    • +
    +
    +
    Return fig, ax
    +

    returns the figure and axes objects

    +
    +
    +
    + +
    +
    +static plot_3d_data(x_data, y_data, z_data, c_data=None, x_label=None, y_label=None, z_label=None, c_label=None)[source]
    +

    THis is for plotting 3d scatter plots. +We suggest use matplotlib's ax.scatter to make 3d plots.

    +
    +
    Parameters
    +
      +
    • x_data -- (list) list of data for x axis

    • +
    • y_data -- (list) list of data for y axis

    • +
    • z_data -- (list) list of data for z axis

    • +
    • c_data -- (list) list of data for color axis

    • +
    • x_label -- (str) label for x axis

    • +
    • y_label -- (str) label for y axis

    • +
    • z_label -- (str) label for z axis

    • +
    • c_label -- (str) label for color axis

    • +
    +
    +
    Returns
    +

    +
    +
    +
    + +
    +
    +r_squared(compared_value=None)[source]
    +

    r-squared value comparing measured and predicted compared value

    +

    Closer to 1, the better the model's predictions.

    +
    +
    Parameters
    +

    compared_value -- (str) Quantity to compare predicted and +experimental data. Can be any column containing "eq" in exp_df i.e. +h_eq, z_eq, {ES}_d_eq, etc. default is {ES}_aq_eq

    +
    +
    +
    + +
    +
    +static scipy_minimize(objective, x_guess, optimizer_kwargs=None)[source]
    +

    The default optimizer for LLEPE

    +

    Uses scipy.minimize

    +

    By default, options are

    +
    default_kwargs= {"method": 'SLSQP',
    +                "bounds": [(1e-1, 1e1)]*len(x_guess),
    +                "constraints": (),
    +                "options": {'disp': True,
    +                            'maxiter': 1000,
    +                            'ftol': 1e-6}}
    +
    +
    +
    +
    Parameters
    +
      +
    • objective -- (func) the objective function

    • +
    • x_guess -- (np.ndarray) the initial guess (always 1)

    • +
    • optimizer_kwargs -- (dict) dictionary of options for minimize

    • +
    +
    +
    Returns
    +

    ((np.ndarray, float)) Optimized parameters, +objective_function value

    +
    +
    +
    + +
    +
    +set_aq_solvent_name(aq_solvent_name)[source]
    +

    Change aq_solvent_name to input aq_solvent_name

    +
    +
    Parameters
    +

    aq_solvent_name -- (str) name of aqueous solvent in xml file

    +
    +
    +
    + +
    +
    +set_aq_solvent_rho(aq_solvent_rho)[source]
    +

    Changes aqueous solvent density (g/L) to input aq_solvent_rho

    +
    +
    Parameters
    +

    aq_solvent_rho -- (float) density of aqueous solvent

    +
    +
    +
    + +
    +
    +set_complex_names(complex_names)[source]
    +

    Change complex names list to input complex_names

    +
    +
    Parameters
    +

    complex_names -- (list) names of complexes in xml file.

    +
    +
    +
    + +
    +
    +set_custom_objects_dict(custom_objects_dict)[source]
    +

    Sets the custom_objects_dict

    +
    +
    Parameters
    +

    custom_objects_dict -- (dict) dictionary containing information +about about custom objects from user

    +
    +
    +
    + +
    +
    +set_dependant_params_dict(dependant_params_dict)[source]
    +

    Sets the dependant_params_dict

    +
    +
    Parameters
    +

    dependant_params_dict -- (dict) dictionary containing information +about parameters dependant on opt_dict

    +
    +
    +
    + +
    +
    +set_diluant_name(diluant_name)[source]
    +

    Change diluant_name to input diluant_name

    +
    +
    Parameters
    +

    diluant_name -- (str) name of diluant in xml file

    +
    +
    +
    + +
    +
    +set_diluant_rho(diluant_rho)[source]
    +

    Changes diluant density (g/L) to input diluant_rho

    +
    +
    Parameters
    +

    diluant_rho -- (float) density of diluant

    +
    +
    +
    + +
    +
    +set_exp_df(exp_data)[source]
    +

    Changes the experimental DataFrame to input exp_csv_filename data +and renames columns to internal LLEPE names

    +

    h_i, h_eq, z_i, z_eq, {ES}_aq_i, {ES}_aq_eq, {ES}_d

    +

    See class docstring on "exp_csv_filename" for further explanations.

    +
    +
    Parameters
    +

    exp_data -- (str or pd.DataFrame) +file name/path or DataFrame for experimental data csv

    +
    +
    +
    + +
    +
    +set_extractant_name(extractant_name)[source]
    +

    Change extractant_name to input extractant_name +:param extractant_name: (str) name of extractant in xml file

    +
    + +
    +
    +set_extractant_rho(extractant_rho)[source]
    +

    Changes extractant density (g/L) to input extractant_rho

    +
    +
    Parameters
    +

    extractant_rho -- (float) density of extractant

    +
    +
    +
    + +
    +
    +set_extracted_species_ion_names(extracted_species_ion_names)[source]
    +
    +
    Change list of extracted species ion names to input

    extracted_species_ion_names

    +
    +
    +
    +
    Parameters
    +

    extracted_species_ion_names -- (list) names of extracted species +ions in xml file

    +
    +
    +
    + +
    +
    +set_extracted_species_list(extracted_species_list)[source]
    +
    +
    Change list of extracted species ion names to input

    extracted_species_ion_names

    +
    +
    +
    +
    Parameters
    +

    extracted_species_list -- (list) names of extracted species in +xml file

    +
    +
    +
    + +
    +
    +set_in_moles(feed_vol)[source]
    +

    Function that initializes mole fractions to input feed_vol

    +

    This function is called at initialization

    +

    Sets in_moles to a pd.DataFrame containing initial mole fractions

    +

    Columns for species and rows for different experiments

    +

    This function also calls update_predicted_dict

    +
    +
    Parameters
    +

    feed_vol -- (float) feed volume of mixture (L)

    +
    +
    +
    + +
    +
    +set_objective_function(objective_function)[source]
    +

    Change objective function to input objective_function.

    +
    +

    See class docstring on "objective_function" for instructions

    +
    +
    +
    Parameters
    +

    objective_function -- (func) Objective function to quantify +error between model and experimental data

    +
    +
    +
    + +
    +
    +set_opt_dict(opt_dict)[source]
    +

    Change the dictionary to input opt_dict.

    +

    opt_dict specifies species parameters to be updated to +fit model to data

    +

    See class docstring on "opt_dict" for more information.

    +
    +
    Parameters
    +

    opt_dict -- (dict) dictionary containing info about which +species parameters are updated to fit model to experimental data

    +
    +
    +
    + +
    +
    +set_optimizer(optimizer)[source]
    +

    Change optimizer function to input optimizer.

    +
    +

    See class docstring on "optimizer" for instructions

    +
    +
    +
    Parameters
    +

    optimizer -- (func) Optimizer function to minimize objective +function

    +
    +
    +
    + +
    +
    +set_phases(phases_xml_filename, phase_names)[source]
    +

    Change list of Cantera solutions by inputting +new xml file name and phase names

    +

    Also runs set_in_moles to set feed volume to 1 L

    +
    +
    Parameters
    +
      +
    • phases_xml_filename -- (str) xml file with parameters +for equilibrium calc

    • +
    • phase_names -- (list) names of phases in xml file

    • +
    +
    +
    +
    + +
    +
    +set_temp_xml_file_path(temp_xml_file_path)[source]
    +

    Changes temporary xml file path to input temp_xml_file_path.

    +

    This xml file is a duplicate of the phases_xml_file name and is +modified during the optimization process to avoid changing the original +xml file.

    +
    +
    Parameters
    +

    temp_xml_file_path -- (str) path to temporary xml file.

    +
    +
    +
    + +
    +
    +update_custom_objects_dict(info_dict)[source]
    +

    updates internal custom_objects_dict with info_dict

    +
    +
    Parameters
    +

    info_dict -- Requires an identical structure to opt_dict +Ignores items with keys containing "custom_object_name"

    +
    +
    Returns
    +

    None

    +
    +
    +
    + +
    +
    +update_predicted_dict(phases_xml_filename=None, phase_names=None)[source]
    +

    Function that computes the predicted equilibrium concentrations +the fed phases_xml_filename parameters predicts given the initial +mole fractions set by in_moles()

    +
    +
    Parameters
    +
      +
    • phases_xml_filename -- (str)xml file with parameters +for equilibrium calc. If None, the +current phases_xml_filename is used.

    • +
    • phase_names -- (list) names of phases in xml file. +If None, the current phases_names is used.

    • +
    +
    +
    +
    + +
    +
    +update_xml(info_dict, phases_xml_filename=None, dependant_params_dict=None)[source]
    +

    updates xml file with info_dict

    +
    +
    Parameters
    +
      +
    • info_dict -- (dict) Requires an identical structure to opt_dict +Ignores items with keys containing "custom_object_name"

    • +
    • phases_xml_filename -- (str) xml filename if editing other xml +If None, the current xml will be modified and the internal +Cantera phases will be refreshed to the new values.

    • +
    • dependant_params_dict -- (dict) dictionary containing information +about parameters dependant on info_dict

    • +
    +
    +
    +
    + +
    + +
    +
    + + +
    + +
    + + +
    +
    + +
    + +
    + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/_build/html/modules/reeps.html b/docs/_build/html/modules/reeps.html index 9275abb..8f4ad8e 100644 --- a/docs/_build/html/modules/reeps.html +++ b/docs/_build/html/modules/reeps.html @@ -34,8 +34,7 @@ - - + @@ -87,13 +86,6 @@
  • Installation
  • Getting Started
  • -

    Searchers

    - @@ -157,8 +149,8 @@
    -
    -

    LLEPE

    +
    +

    LLEPE

    Parameters

    @@ -170,7 +162,7 @@

    The order in which the extracted species (ES) appear in the csv file must be the same order as they appear in the xml, complex_names and extracted_species_ion_names.

    -

    For example, say in exp_csv_filename's csv, ES_1 is Nd ES_2 is Pr, +

    For example, say in exp_data, ES_1 is Nd ES_2 is Pr, and

    aq_solvent_name = 'H2O(L)'
     extractant_name = '(HA)2(org)'
    @@ -178,7 +170,7 @@ and

    Then:

    -

    The csvs column ordering must be:

    +

    The exp_data column ordering must be (names do not matter):

    [h_i, h_eq, z_i, z_eq, Nd_aq_i, Nd_aq_eq, Nd_d_eq, Pr_aq_i, Pr_aq_eq, Pr_d_eq]

    The aqueous speciesArray must be @@ -718,7 +710,9 @@ effect if data_labels is None

    static plot_3d_data(x_data, y_data, z_data, c_data=None, x_label=None, y_label=None, z_label=None, c_label=None)[source]
    -
    +

    THis is for plotting 3d scatter plots. +We suggest use matplotlib's ax.scatter to make 3d plots.

    +
    Parameters
    • x_data -- (list) list of data for x axis

    • @@ -1077,19 +1071,12 @@ about parameters dependant on info_dict