Skip to content

Commit

Permalink
added picklable stat
Browse files Browse the repository at this point in the history
  • Loading branch information
avdudchenko committed Oct 22, 2024
1 parent 99d6669 commit 041456e
Show file tree
Hide file tree
Showing 12 changed files with 819 additions and 43 deletions.
51 changes: 49 additions & 2 deletions src/reaktoro_pse/core/reaktoro_inputs.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from reaktoro_pse.core.reaktoro_state import ReaktoroState

import idaes.logger as idaeslog
import copy

_log = idaeslog.getLogger(__name__)

Expand All @@ -22,6 +23,24 @@
""" class to setup input constraints, and specs for reaktoro solver class"""


class ReaktoroInputExport:
def __init__(self):
self.ignore_elements_for_constraints = []
self.fixed_solvent_specie = {}
self.fixed_solvent_speciation = {}
self.rkt_chemical_inputs = None
self.assert_charge_neutrality = None
self.neutrality_ion = None
self.dissolve_species_in_rkt = None
self.exact_speciation = None

def copy_chem_inputs(self, chem_inputs):
self.rkt_chemical_inputs = copy.deepcopy(chem_inputs)
for key, obj in self.rkt_chemical_inputs.items():
# self.inputs[key] = copy.deepcopy(obj)
self.rkt_chemical_inputs[key].delete_pyomo_var()


class ReaktoroInputSpec:
def __init__(self, reaktor_state):
# initialize parameters needed to build reaktor solver
Expand Down Expand Up @@ -91,7 +110,6 @@ def register_fixed_solvent_specie(self, phase, specie):
system speciation, so if we want to specify pH, we need to allow system to find eq. H/O and fix
H2O"""
self.fixed_solvent_specie[phase] = specie

self.fixed_solvent_speciation[phase] = {}

def register_free_elements(self, elements):
Expand All @@ -118,12 +136,15 @@ def configure_specs(
"""
self.dissolve_species_in_rkt = dissolve_species_in_rkt
self.exact_speciation = exact_speciation

def build_input_specs(self):
"""function to build all the input specs"""
self.breakdown_species_to_elements()
self.equilibrium_specs = rkt.EquilibriumSpecs(self.state.state.system())
self.add_specs(
self.equilibrium_specs,
self.assert_charge_neutrality,
dissolve_species_in_rkt,
self.dissolve_species_in_rkt,
)

# get input name order!
Expand Down Expand Up @@ -427,3 +448,29 @@ def write_empty_constraints(self, spec_object):
for specie in self.empty_constraints:
spec_object.openTo(specie)
self.write_empty_con(spec_object, specie)

def export_config(self):
export_object = ReaktoroInputExport()
export_object.copy_chem_inputs(self.rkt_chemical_inputs)
export_object.ignore_elements_for_constraints = (
self.ignore_elements_for_constraints
)
export_object.fixed_solvent_specie = self.fixed_solvent_specie
export_object.fixed_solvent_speciation = self.fixed_solvent_speciation
export_object.assert_charge_neutrality = self.assert_charge_neutrality
export_object.neutrality_ion = self.neutrality_ion
export_object.dissolve_species_in_rkt = self.dissolve_species_in_rkt
export_object.exact_speciation = self.exact_speciation
return export_object

def load_from_export_object(self, export_object):
self.ignore_elements_for_constraints = (
export_object.ignore_elements_for_constraints
)
self.fixed_solvent_specie = export_object.fixed_solvent_specie
self.fixed_solvent_speciation = export_object.fixed_solvent_speciation
self.rkt_chemical_inputs = export_object.rkt_chemical_inputs
self.assert_charge_neutrality = export_object.assert_charge_neutrality
self.neutrality_ion = export_object.neutrality_ion
self.dissolve_species_in_rkt = export_object.dissolve_species_in_rkt
self.exact_speciation = export_object.exact_speciation
22 changes: 22 additions & 0 deletions src/reaktoro_pse/core/reaktoro_jacobian.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,13 @@ def display_available(self):
return available_dict


class ReaktoroJacobianExport:
def __init__(self):
self.der_step_size = None
self.jacobian_type = None
self.numerical_order = None


class ReaktoroJacobianSpec:
def __init__(self, reaktor_state, reaktor_outputs):
self.state = reaktor_state
Expand All @@ -188,6 +195,20 @@ def __init__(self, reaktor_state, reaktor_outputs):
self.configure_numerical_jacobian()
self.check_existing_jacobian_props()

def export_config(self):
export_object = ReaktoroJacobianExport()
export_object.der_step_size = self.der_step_size
export_object.jacobian_type = self.jacobian_type
export_object.numerical_order = self.numerical_order
return export_object

def load_from_export_object(self, export_object):
self.configure_numerical_jacobian(
jacobian_type=export_object.jacobian_type,
order=export_object.numerical_order,
step_size=export_object.der_step_size,
)

def configure_numerical_jacobian(
self, jacobian_type="average", order=4, step_size=1e-8
):
Expand All @@ -200,6 +221,7 @@ def configure_numerical_jacobian(
"""
self.der_step_size = step_size
self.jacobian_type = JacType.average
self.numerical_order = order
if jacobian_type == JacType.average:
self.jacobian_type = JacType.average
assert order % 2 == 0
Expand Down
98 changes: 87 additions & 11 deletions src/reaktoro_pse/core/reaktoro_outputs.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,14 @@
# information, respectively. These files are also available online at the URL
# "https://github.com/watertap-org/reaktoro-pse/"
#################################################################################
from matplotlib.pylab import f
import reaktoro as rkt

import json
from reaktoro_pse.core.reaktoro_state import ReaktoroState
import reaktoro_pse.core.pyomo_property_writer.property_functions as propFuncs
from reaktoro_pse.core.util_classes.rkt_inputs import RktInputTypes

import copy
import idaes.logger as idaeslog

_log = idaeslog.getLogger(__name__)
Expand Down Expand Up @@ -45,13 +46,8 @@ def __init__(
self.property_type = property_type
self.property_name = property_name # properties from which to extract data
self.property_index = property_index # index if any
if property_type != PropTypes.pyomo_built_prop:
# function for getting reaktoro value
self.set_get_function(get_function)
else:
self.set_poyomo_build_option(
get_function
) # class that contains information for building pyomo constraints if any
self.get_function = None
self.set_option_function(property_type, get_function)
# pyomo var to reference if any - will be built if not user provided
self.pyomo_var = pyomo_var
self.value = value # manually specified value
Expand All @@ -70,6 +66,26 @@ def get_value(self, prop_object, update_values=False):
self.value = value
return value

def delete_pyomo_var(self):
# self.update_values()
del self.pyomo_var
self.pyomo_var = None

def remove_unpicklable_data(self):
self.delete_pyomo_var()
if self.property_type == PropTypes.pyomo_built_prop:
del self.pyomo_build_options
# self.get_function = None

def set_option_function(self, property_type, get_function):
if property_type != PropTypes.pyomo_built_prop:
# function for getting reaktoro value
self.set_get_function(get_function)
else:
self.set_poyomo_build_option(
get_function
) # class that contains information for building pyomo constraints if any

def set_poyomo_build_option(self, func):
self.pyomo_build_options = func

Expand All @@ -86,9 +102,11 @@ def get_pyomo_var(self):
return self.pyomo_var

def set_pyomo_var_value(self, value):
self.pyomo_var.set_value(value)
self.value = value
if self.pyomo_var is not None:
self.pyomo_var.set_value(value)

def get_pyomo_var_value(self, value):
def get_pyomo_var_value(self):
return self.pyomo_var.value

def set_jacobian_value(self, value):
Expand Down Expand Up @@ -229,13 +247,47 @@ class PropTypes:
pyomo_built_prop = "pyomoBuiltProperties"


class ReaktoroOutputExport:
def __init__(self):
self.rkt_outputs = None
self.user_outputs = None

def copy_rkt_outputs(self, outputs):
self.rkt_outputs = {}
for key, obj in outputs.items():
self.rkt_outputs[key] = RktOutput(
obj.property_type,
obj.property_name,
obj.property_index,
# get_function=obj.get_function,
value=obj.value,
jacobian_type=obj.jacobian_type,
)
self.rkt_outputs[key].remove_unpicklable_data()

def copy_user_outputs(self, outputs):
self.user_outputs = {} # copy.deepcopy(outputs)
for key, obj in outputs.items():
self.user_outputs[key] = RktOutput(
obj.property_type,
obj.property_name,
obj.property_index,
# get_function=obj.get_function,
value=obj.value,
jacobian_type=obj.jacobian_type,
)
self.user_outputs[key].remove_unpicklable_data()


class ReaktoroOutputSpec:
def __init__(self, reaktor_state):
self.state = reaktor_state
if isinstance(self.state, ReaktoroState) == False:
raise TypeError("Reator outputs require rektoroState class")

self.supported_properties = {}
self.supported_properties[PropTypes.chem_prop] = self.state.state.props()

if RktInputTypes.aqueous_phase in self.state.inputs.registered_phases:
self.supported_properties[PropTypes.aqueous_prop] = rkt.AqueousProps(
self.state.state.props()
Expand Down Expand Up @@ -341,7 +393,7 @@ def process_output(
pyomo_var=pyomo_var,
)
for index, prop in get_function.properties.items():
# chcek if prop already exists if it does ont add it outputs
# chcek if prop already exists if it does nor add it outputs
# otherwise overwrite it
if index not in self.rkt_outputs:
self.rkt_outputs[index] = prop
Expand Down Expand Up @@ -438,6 +490,30 @@ def get_possible_indexes(self):
# ].saturationSpecies()
# ]

def export_config(self):
export_object = ReaktoroOutputExport()
export_object.copy_rkt_outputs(self.rkt_outputs)
export_object.copy_user_outputs(self.user_outputs)
return export_object

def load_from_export_object(self, export_object):
self.rkt_outputs = export_object.rkt_outputs
self.user_outputs = export_object.user_outputs
for key, obj in self.rkt_outputs.items():
property_type, get_function = self.get_prop_type(
obj.property_name,
obj.property_index,
)
assert property_type == obj.property_type
obj.set_option_function(property_type, get_function)
for key, obj in self.user_outputs.items():
property_type, get_function = self.get_prop_type(
obj.property_name,
obj.property_index,
)
assert property_type == obj.property_type
obj.set_option_function(property_type, get_function)

#### start of possible call function to extract values from reactoro properties #####

def _get_prop_phase_name_val(self, prop_type, prop_name, prop_index):
Expand Down
Loading

0 comments on commit 041456e

Please sign in to comment.