コード例 #1
0
ファイル: water_oil_v1.py プロジェクト: amanuel43/chemgymrl
    def reset(self, extraction_vessel):
        '''
        generate empty vessels
        '''

        vessels = [copy.deepcopy(extraction_vessel)]
        for i in range(self.n_empty_vessels):
            temp_vessel = vessel.Vessel(label='beaker_{}'.format(i + 1),
                                        v_max=self.max_vessel_volume,
                                        default_dt=0.05,
                                        n_pixels=self.n_vessel_pixels)
            vessels.append(temp_vessel)

        # generate oil vessel
        oil_vessel = vessel.Vessel(
            label='oil_vessel',
            v_max=self.oil_volume,
            n_pixels=self.n_vessel_pixels,
            settling_switch=False,
            layer_switch=False,
        )

        oil_vessel_material_dict = {}
        C6H14 = material.C6H14
        oil_vessel_material_dict[C6H14().get_name()] = [C6H14, self.oil_volume]
        oil_vessel_material_dict, _, _ = util.check_overflow(
            material_dict=oil_vessel_material_dict,
            solute_dict={},
            v_max=oil_vessel.get_max_volume())
        event = ['update material dict', oil_vessel_material_dict]
        oil_vessel.push_event_to_queue(feedback=[event], dt=0)

        state = util.generate_state(vessels, max_n_vessel=self.n_total_vessels)

        return vessels, oil_vessel, state
コード例 #2
0
def wurtz_vessel():
    """
    Function to generate an input vessel for the oil and water extraction experiment.

    Parameters
    ---------------
    None

    Returns
    ---------------
    `extract_vessel` : `vessel`
        A vessel object containing state variables, materials, solutes, and spectral data.

    Raises
    ---------------
    None
    """

    # initialize extraction vessel
    extraction_vessel = vessel.Vessel(label='boil_vessel')

    # initialize C6H14
    C6H14 = material.C6H14()

    # initialize Dodecane
    Dodecane = material.Dodecane()
    Dodecane.set_solute_flag(True)
    Dodecane.set_color(0.0)
    Dodecane.set_phase('l')

    # material_dict
    material_dict = {
        C6H14.get_name(): [C6H14, 4.0, 'mol'],
        Dodecane.get_name(): [Dodecane, 1.0, 'mol']
    }

    # solute_dict
    solute_dict = {
        Dodecane.get_name(): {
            C6H14.get_name(): [C6H14, 1.0, 'mol']
        }
    }

    material_dict, solute_dict, _ = util.check_overflow(
        material_dict=material_dict,
        solute_dict=solute_dict,
        v_max=extraction_vessel.get_max_volume())

    # set events and push them to the queue
    extraction_vessel.push_event_to_queue(
        events=None,
        feedback=[['update material dict', material_dict],
                  ['update solute dict', solute_dict]],
        dt=0)
    extraction_vessel.push_event_to_queue(events=None,
                                          feedback=None,
                                          dt=-100000)

    return extraction_vessel
コード例 #3
0
    def _update_vessel(self):
        '''
        Method to update the information stored in the vessel upon completing a step.

        Parameters
        ---------------
        None

        Returns
        ---------------
        None

        Raises
        ---------------
        None
        '''

        # get the temperature and pressure from the state variables
        temperature = self.T
        volume = self.V
        pressure = self.P

        # tabulate all the materials used and their new values
        new_material_dict = {}
        for i in range(self.reaction.n.shape[0]):
            material_name = self.reaction.labels[i]
            material_class = self.reaction.material_classes[i]
            amount = self.reaction.n[i]
            new_material_dict[material_name] = [material_class, amount]

        # tabulate all the solutes and their values
        new_solute_dict = {}
        for i in range(self.reaction.initial_solutes.shape[0]):
            solute_name = self.reaction.solute_labels[i]
            solute_class = self.reaction.solute_classes[i]
            amount = self.reaction.initial_solutes[i]

            # create the new solute dictionary to be appended to a new vessel object
            new_solute_dict[solute_name] = [solute_class, amount]

        # create a new vessel and update it with new data
        new_vessel = vessel.Vessel('react_vessel',
                                   temperature=self.Ti,
                                   v_max=self.Vmax,
                                   v_min=self.Vmin,
                                   Tmax=self.Tmax,
                                   Tmin=self.Tmin,
                                   default_dt=self.dt)
        new_vessel.temperature = temperature
        new_vessel._material_dict = new_material_dict
        new_vessel._solute_dict = new_solute_dict
        new_vessel.volume = volume
        new_vessel.pressure = pressure

        # replace the old vessel with the updated version
        self.vessels = new_vessel
コード例 #4
0
 def __init__(self):
     super(ExtractWorld_Wurtz_Ctd_v1,
           self).__init__(extraction='wurtz',
                          extraction_vessel=get_extract_vessel(
                              vessel_path=os.path.join(
                                  os.getcwd(), "react_vessel.pickle"),
                              extract_vessel=vessel.Vessel(label='temp')),
                          solvents=["H2O", "DiEthylEther"],
                          target_material='dodecane',
                          out_vessel_path=os.getcwd())
コード例 #5
0
ファイル: reaction_base.py プロジェクト: chemgymrl/chemgymrl
    def update_vessel(self, temperature, volume):
        """
        Method to update the provided vessel object with materials from the reaction base
        and new thermodynamic variables.

        Parameters
        ---------------
        `temperature` : `float`
            The final temperature of the vessel after all reactions have been completed.
        `volume` : `float`
            The final temperature of the vessel after all reactions have been completed.

        Returns
        ---------------
        `new_vessel` : `float`
            The new vessel containing the final materials and thermodynamic variables.

        Raises
        ---------------
        None
        """

        # tabulate all the materials and solutes used and their new values
        new_material_dict = {}
        new_solute_dict = {}
        for i in range(self.n.shape[0]):
            material_name = self.materials[i]
            material_class = self.material_classes[i]
            amount = self.n[i]
            new_material_dict[material_name] = [
                material_class(), amount, 'mol'
            ]
            if material_class().is_solute():
                # create the new solute dictionary to be appended to a new vessel object
                new_solute_dict[material_name] = {
                    material_name: [material_class(), amount, 'mol']
                }

        # create a new vessel and update it with new data
        new_vessel = vessel.Vessel('react_vessel',
                                   temperature=self.Ti,
                                   v_max=self.Vmax,
                                   v_min=self.Vmin,
                                   Tmax=self.Tmax,
                                   Tmin=self.Tmin,
                                   default_dt=self.dt)
        new_vessel.temperature = temperature
        new_vessel.volume = volume
        new_vessel._material_dict = new_material_dict
        new_vessel._solute_dict = new_solute_dict
        new_vessel.pressure = new_vessel.get_pressure()

        return new_vessel
コード例 #6
0
ファイル: methyl_red.py プロジェクト: chemgymrl/chemgymrl
    def reset(self, extraction_vessel):
        '''
        generate empty vessels
        '''

        vessels = [copy.deepcopy(extraction_vessel)]
        for i in range(self.n_empty_vessels):
            temp_vessel = vessel.Vessel(label='beaker_{}'.format(i + 1),
                                        v_max=self.max_vessel_volume,
                                        default_dt=0.05,
                                        n_pixels=self.n_vessel_pixels)
            vessels.append(temp_vessel)

        # generate oil vessel
        ethyl_vessel = vessel.Vessel(
            label='ethyl_vessel',
            v_max=self.ethyl_volume,
            n_pixels=self.n_vessel_pixels,
            settling_switch=False,
            layer_switch=False,
        )

        ethyl = material.EthylAcetate

        ethyl_vessel_material_dict = {
            ethyl().get_name(): [ethyl, self.ethyl_volume]
        }

        ethyl_vessel_material_dict, _, _ = util.check_overflow(
            material_dict=ethyl_vessel_material_dict,
            solute_dict={},
            v_max=ethyl_vessel.get_max_volume())
        event = ['update material dict', ethyl_vessel_material_dict]
        ethyl_vessel.push_event_to_queue(feedback=[event], dt=0)

        state = util.generate_layers_obs(vessels,
                                         max_n_vessel=self.n_total_vessels,
                                         n_vessel_pixels=self.n_vessel_pixels)

        return vessels, ethyl_vessel, state
コード例 #7
0
    def _prepare_vessel(self, in_vessel_path=None, materials=[], solvents=[]):
        """
        Method to prepare the initial vessel.

        Parameters
        ---------------
        `in_vessel_path` : `str` (default=`None`)
            A string indicating the path to a vessel intended to be loaded into the reaction bench environment.
        `materials` : `list` (default=`None`)
            A list of dictionaries including initial material names and amounts.
        `solvents` : `list` (default=`None`)
            A list of dictionaries including initial solvent names and amounts.

        Returns
        ---------------
        `vessels` : `vessel.Vessel`
            A vessel object containing materials and solvents to be used in the reaction bench.

        Raises
        ---------------
        None
        """
        # initialize vessels by providing a empty default vessel or loading an existing saved vessel
        if in_vessel_path is None:
            # prepare the provided materials into a compatible material dictionary
            material_dict = self._prepare_materials(materials=materials)

            # prepare the solutes that have been provided
            solute_dict = self._prepare_solutes(material_dict=material_dict,
                                                solvents=solvents)

            # add the materials and solutes to an empty vessel
            vessels = vessel.Vessel('default',
                                    materials=material_dict,
                                    solutes=solute_dict,
                                    default_dt=self.dt)

        else:
            with open(in_vessel_path, 'rb') as handle:
                vessels = pickle.load(handle)

        return vessels
コード例 #8
0
    def reset(self, init_boil_vessel):
        '''
        Method to reset the environment.
        Parameters
        ---------------
        `boil_vessel` : `vessel` (default=`None`)
            A vessel object containing state variables, materials, solutes, and spectral data.
        Returns
        ---------------
        `vessels` : `list`
            A list of all the vessel objects that contain materials and solutes.
        `state` : `np.array`
            An array containing state variables, material concentrations, and spectral data.
        Raises
        ---------------
        None
        '''

        # delete the solute dictionary from the boil vessel
        boil_vessel = deepcopy(init_boil_vessel)

        # set the unit of the boil vessel
        boil_vessel.unit = 'l'

        # append wait to boil vessel (needed if using old pickle file)
        boil_vessel._event_dict['wait'] = vessel.Vessel._wait

        # add the inputted boil vessel to the list of all vessels
        vessels = [boil_vessel]

        # create the empty beaker vessels, set variables to default values
        for i in range(self.n_empty_vessels):
            beaker = vessel.Vessel(
                label="beaker_{}".format(i),
                temperature=293.15,  # room temp in Kelvin
                v_max=self.max_vessel_volume,
                default_dt=self.dt,
                materials={},
                solutes={})
            vessels.append(beaker)

        return vessels
コード例 #9
0
def oil_vessel():
    '''
    Function to generate an input vessel for the oil and water extraction experiment.

    Parameters
    ---------------
    None

    Returns
    ---------------
    `extract_vessel` : `vessel`
        A vessel object containing state variables, materials, solutes, and spectral data.

    Raises
    ---------------
    None
    '''

    # initialize extraction vessel
    extraction_vessel = vessel.Vessel(label='extraction_vessel')

    # initialize H2O
    H2O = material.H2O

    # initialize Na
    Na = material.Na
    Na().set_charge(1.0)
    Na().set_solute_flag(True)
    Na().set_polarity(2.0)

    # initialize Cl
    Cl = material.Cl
    Cl().set_charge(-1.0)
    Cl().set_solute_flag(True)
    Cl().set_polarity(2.0)

    # material_dict
    material_dict = {
        H2O().get_name(): [H2O, 30.0],
        Na().get_name(): [Na, 1.0],
        Cl().get_name(): [Cl, 1.0]
    }

    # solute_dict
    solute_dict = {
        Na().get_name(): [H2O().get_name(), 1.0],
        Cl().get_name(): [H2O().get_name(), 1.0],
    }

    material_dict, solute_dict, _ = util.check_overflow(
        material_dict=material_dict,
        solute_dict=solute_dict,
        v_max=extraction_vessel.get_max_volume())

    # set events and push them to the queue
    extraction_vessel.push_event_to_queue(
        events=None,
        feedback=[['update material dict', material_dict],
                  ['update solute dict', solute_dict], ['fully mix']],
        dt=0)

    return extraction_vessel
コード例 #10
0
    def reset(self, extraction_vessel):
        # generate empty vessels
        vessels = [copy.deepcopy(extraction_vessel)]
        for i in range(self.n_empty_vessels):
            temp_vessel = vessel.Vessel(label='beaker_{}'.format(i + 1),
                                        v_max=self.max_vessel_volume,
                                        default_dt=0.05,
                                        n_pixels=self.n_vessel_pixels)
            vessels.append(temp_vessel)

        # generate solution vessel2
        solution_1_vessel = vessel.Vessel(
            label='solution_1_vessel',
            v_max=self.solution_volume,
            n_pixels=self.n_vessel_pixels,
            settling_switch=False,
            layer_switch=False,
        )

        solution_2_vessel = vessel.Vessel(
            label='solution_2_vessel',
            v_max=self.solution_volume,
            n_pixels=self.n_vessel_pixels,
            settling_switch=False,
            layer_switch=False,
        )

        H2O = material.H2O
        Na = material.Na
        Cl = material.Cl
        Li = material.Li
        F = material.F

        solution_1_vessel_material_dict = {
            H2O().get_name(): [H2O, 30.0],
            Na().get_name(): [Na, 1.0],
            Cl().get_name(): [Cl, 1.0]
        }
        solution_1_solute_dict = {
            Na().get_name(): {
                H2O().get_name(): 1.0
            },
            Cl().get_name(): {
                H2O().get_name(): 1.0
            },
        }

        solution_2_vessel_material_dict = {
            H2O().get_name(): [H2O, 30.0],
            Li().get_name(): [Li, 1.0],
            F().get_name(): [F, 1.0]
        }
        solution_2_solute_dict = {
            Li().get_name(): {
                H2O().get_name(): 1.0
            },
            F().get_name(): {
                H2O().get_name(): 1.0
            },
        }

        solution_1_vessel_material_dict, solution_1_solute_dict, _ = util.check_overflow(
            material_dict=solution_1_vessel_material_dict,
            solute_dict=solution_1_solute_dict,
            v_max=solution_1_vessel.get_max_volume(),
        )

        solution_2_vessel_material_dict, solution_2_solute_dict, _ = util.check_overflow(
            material_dict=solution_2_vessel_material_dict,
            solute_dict=solution_2_solute_dict,
            v_max=solution_2_vessel.get_max_volume(),
        )

        event_s1_m = ['update material dict', solution_1_vessel_material_dict]
        event_s1_s = ['update solute dict', solution_1_solute_dict]

        event_s2_m = ['update material dict', solution_2_vessel_material_dict]
        event_s2_s = ['update solute dict', solution_2_solute_dict]

        solution_1_vessel.push_event_to_queue(feedback=[event_s1_m], dt=0)
        solution_1_vessel.push_event_to_queue(feedback=[event_s1_s], dt=0)

        solution_2_vessel.push_event_to_queue(feedback=[event_s2_m], dt=0)
        solution_2_vessel.push_event_to_queue(feedback=[event_s2_s], dt=0)

        return vessels, [solution_1_vessel,
                         solution_2_vessel], util.generate_state(
                             vessels, max_n_vessel=self.n_total_vessels)
コード例 #11
0
def boil_vessel():
    """
    Function to generate an input vessel for distillation.

    Parameters
    ---------------
    None

    Returns
    ---------------
    `extract_vessel` : `vessel`
        A vessel object containing state variables, materials, solutes, and spectral data.

    Raises
    ---------------
    None
    """

    # initialize boiling vessel
    boil_vessel = vessel.Vessel(label='boil_vessel')

    # initialize materials
    OneChlorohexane = material.OneChlorohexane
    TwoChlorohexane = material.TwoChlorohexane
    ThreeChlorohexane = material.ThreeChlorohexane
    Na = material.Na
    Dodecane = material.Dodecane
    FiveMethylundecane = material.FiveMethylundecane
    FourEthyldecane = material.FourEthyldecane
    FiveSixDimethyldecane = material.FiveSixDimethyldecane
    FourEthylFiveMethylnonane = material.FourEthylFiveMethylnonane
    FourFiveDiethyloctane = material.FourFiveDiethyloctane
    NaCl = material.NaCl
    H2O = material.H2O

    # material_dict
    material_dict = {
        OneChlorohexane().get_name(): [OneChlorohexane, 0.62100387, 'mol'],
        TwoChlorohexane().get_name(): [TwoChlorohexane, 0.71239483, 'mol'],
        ThreeChlorohexane().get_name(): [ThreeChlorohexane, 0.6086047, 'mol'],
        Na().get_name(): [Na, 0.028975502, 'mol'],
        Dodecane().get_name(): [Dodecane, 0.10860507, 'mol'],
        FiveMethylundecane().get_name():
        [FiveMethylundecane, 0.07481375, 'mol'],
        FourEthyldecane().get_name(): [FourEthyldecane, 0.08697271, 'mol'],
        FiveSixDimethyldecane().get_name():
        [FiveSixDimethyldecane, 0.07173399, 'mol'],
        FourEthylFiveMethylnonane().get_name():
        [FourEthylFiveMethylnonane, 0.069323435, 'mol'],
        FourFiveDiethyloctane().get_name():
        [FourFiveDiethyloctane, 0.07406321, 'mol'],
        NaCl().get_name(): [NaCl, 0.9710248, 'mol'],
        H2O().get_name(): [H2O, 0.2767138495698029, 'mol']
    }

    # solute_dict
    solute_dict = {}

    material_dict, solute_dict, _ = util.check_overflow(
        material_dict=material_dict,
        solute_dict=solute_dict,
        v_max=boil_vessel.get_max_volume())

    # set events and push them to the queue
    boil_vessel.push_event_to_queue(
        events=None,
        feedback=[['update material dict', material_dict],
                  ['update solute dict', solute_dict]],
        dt=0)

    return boil_vessel
コード例 #12
0
    def __init__(self,
                 reaction=Reaction,
                 in_vessel_path=None,
                 out_vessel_path=None,
                 materials=None,
                 solutes=None,
                 desired="",
                 n_steps=50,
                 dt=0.01,
                 Ti=300.0,
                 Tmin=250.0,
                 Tmax=500.0,
                 dT=50.0,
                 Vi=0.002,
                 Vmin=0.001,
                 Vmax=0.005,
                 dV=0.0005,
                 overlap=False):
        '''
        Constructor class method to pass thermodynamic variables to class methods.

        Parameters
        ---------------
        `reaction` : `class`
            A reaction class containing various methods that
            properly define a reaction to be carried out.
        `in_vessel_path` : `str` (default=`None`)
            A string indicating the path to a vessel intended to be loaded into this module.
        `out_vessel_path` : `str` (default=`None`)
            A string indicating the path to a directory where the final output vessel is saved.
        `materials` : `list` (default=`None`)
            A list of dictionaries including initial material names, classes, and amounts.
        `solutes` : `list` (default=`None`)
            A list of dictionaries including initial solute names, classes, and amounts.
        `desired` : `str` (default="")
            A string indicating the desired output material.
        `n_steps` : `int` (default=`50`)
            The number of time steps to be taken during each action.
        `dt` : `float` (default=`0.01`)
            The amount of time taken in each time step.
        `Ti` : `float` (default=`300.0`)
            The initial temperature of the system in Kelvin.
        `Tmin` : `float` (default=`250.0`)
            The minimal temperature of the system in Kelvin.
        `Tmax` : `float` (default=`500.0`)
            The maximal temperature of the system in Kelvin.
        `dT` : `float` (default=`50.0`)
            The maximal allowed temperature change, in Kelvin, for a single action.
        `Vi` : `float` (default=`0.002`)
            The initial volume of the system in litres.
        `Vmin` : `float` (default=`0.001`)
            The minimal volume of the system in litres.
        `Vmax` : `float` (default=`0.005`)
            The maximal volume of the system in litres.
        `dV` : `float` (default=`0.0005`)
            The maximal allowed volume change, in litres, for a single action.
        `overlap` : `boolean` (default=`False`)
            Indicates if the spectral plots show overlapping signatures.

        Returns
        ---------------
        None

        Raises
        ---------------
        None
        '''

        # assign an identifier to this bench
        self.name = "react_bench"

        # validate the parameters inputted to the reaction bench engine
        input_parameters = self._validate_parameters(
            reaction=reaction,
            in_vessel_path=in_vessel_path,
            out_vessel_path=out_vessel_path,
            materials=materials,
            solutes=solutes,
            desired=desired,
            n_steps=n_steps,
            dt=dt,
            Ti=Ti,
            Tmin=Tmin,
            Tmax=Tmax,
            dT=dT,
            Vi=Vi,
            Vmin=Vmin,
            Vmax=Vmax,
            dV=dV,
            overlap=overlap)

        # set the input vessel path
        self.in_vessel_path = input_parameters["in_vessel_path"]

        # set the output vessel path
        self.out_vessel_path = input_parameters["out_vessel_path"]

        # set initial material, solute, and overlap parameters
        materials = input_parameters["materials"]
        solutes = input_parameters["solutes"]
        overlap = input_parameters["overlap"]

        # set the remaining input parameters
        self.desired = input_parameters["desired"]  # the desired material
        self.n_steps = input_parameters["n_steps"]  # Time steps per action
        self.dt = input_parameters["dt"]  # Time step of reaction (s)
        self.Ti = input_parameters["Ti"]  # Initial temperature (K)
        self.Tmin = input_parameters[
            "Tmin"]  # Minimum temperature of the system (K)
        self.Tmax = input_parameters[
            "Tmax"]  # Maximum temperature of the system (K)
        self.dT = input_parameters[
            "dT"]  # Maximum change in temperature per action (K)
        self.Vi = input_parameters["Vi"]  # Initial Volume (L)
        self.Vmin = input_parameters[
            "Vmin"]  # Minimum Volume of the system (L)
        self.Vmax = input_parameters[
            "Vmax"]  # Maximum Volume of the system (L)
        self.dV = input_parameters[
            "dV"]  # Maximum change in Volume per action (L)

        # initialize the reaction
        self.reaction = input_parameters["reaction"](overlap=overlap,
                                                     materials=materials,
                                                     solutes=solutes,
                                                     desired=self.desired)

        # Maximum time (s) (20 is the registered max_episode_steps)
        self.tmax = self.n_steps * dt * 20

        # initialize a step counter
        self.step_num = 1

        # initialize vessels by providing a empty default vessel or loading an existing saved vessel
        self.n_init = np.zeros(self.reaction.nmax.shape[0], dtype=np.float32)
        if self.in_vessel_path is None:
            self.vessels = vessel.Vessel('default',
                                         temperature=self.Ti,
                                         v_max=self.Vmax,
                                         v_min=self.Vmin,
                                         Tmax=self.Tmax,
                                         Tmin=self.Tmin,
                                         default_dt=self.dt)
        else:
            with open(self.in_vessel_path, 'rb') as handle:
                v = pickle.load(handle)
                self.vessels = v

        # set up a state variable
        self.state = None

        # reset the inputted reaction before performing any steps
        self.reaction.reset(n_init=self.n_init)

        # Defining action and observation space for OpenAI Gym framework
        # shape[0] is the change in amount of each reactant
        # + 2 is for the change in T and V
        # all actions range between 0 () and 1 ()
        # 0 = no reactant added and T, V are decreased by the maximum amount (-dT and -dV)
        # 1 = all reactant added and T, V are increased by the maximum amount (dT and dV)
        act_low = np.zeros(self.reaction.initial_in_hand.shape[0] + 2,
                           dtype=np.float32)
        act_high = np.ones(self.reaction.initial_in_hand.shape[0] + 2,
                           dtype=np.float32)
        self.action_space = gym.spaces.Box(low=act_low, high=act_high)

        # this an array denoting spectral signatures (varying
        # between 0.0 and 1.0) for a wide range of wavelengths
        absorb = self.reaction.get_spectra(Vi)

        # Observations have several attributes
        # + 4 indicates state variables time, temperature, volume, and pressure
        # initial_in_hand.shape[0] indicates the amount of each reactant
        # absorb.shape[0] indicates the numerous spectral signatures from get_spectra
        obs_low = np.zeros(self.reaction.initial_in_hand.shape[0] + 4 +
                           absorb.shape[0],
                           dtype=np.float32)
        obs_high = np.ones(self.reaction.initial_in_hand.shape[0] + 4 +
                           absorb.shape[0],
                           dtype=np.float32)
        self.observation_space = gym.spaces.Box(low=obs_low, high=obs_high)

        # Reset the environment upon calling the class
        self.reset()
コード例 #13
0
import numpy as np
import gym
import gym.spaces
from chemistrylab.extractworldgym.extractworld_v1_engine import ExtractWorldEnv
from chemistrylab.chem_algorithms import material, util, vessel

# initialize extraction vessel
extraction_vessel = vessel.Vessel(label='extraction_vessel', )

# initialize materials
H2O = material.H2O()
Na = material.Na()
Cl = material.Cl()
Na.set_charge(1.0)
Na.set_solute_flag(True)
Na.set_polarity(2.0)
Cl.set_charge(-1.0)
Cl.set_solute_flag(True)
Cl.set_polarity(2.0)

# material_dict
material_dict = {
    H2O.get_name(): [H2O, 30.0],
    Na.get_name(): [Na, 1.0],
    Cl.get_name(): [Cl, 1.0]
}
solute_dict = {
    Na.get_name(): {
        H2O.get_name(): 1.0
    },
    Cl.get_name(): {
コード例 #14
0
    def __init__(self,
                 reaction=Reaction,
                 materials=None,
                 solutes=None,
                 desired="",
                 n_steps=50,
                 dt=0.01,
                 Ti=300,
                 Tmin=250,
                 Tmax=500,
                 dT=50,
                 Vi=0.002,
                 Vmin=0.001,
                 Vmax=0.005,
                 dV=0.0005,
                 overlap=False,
                 vessel_path=None):
        '''
        Constructor class method to pass thermodynamic variables to class methods.

        Parameters
        ---------------
        `reaction` : `class`
            A reaction class containing various methods that
            properly define a reaction to be carried out.
        `materials` : `list` (default=`None`)
            A list of dictionaries including initial material names, classes, and amounts.
        `solutes` : `list` (default=`None`)
            A list of dictionaries including initial solute names, classes, and amounts.
        `desired` : `str` (default="")
            A string indicating the desired output material.
        `n_steps` : `int` (default=`50`)
            The number of time steps to be taken during each action.
        `dt` : `float` (default=`0.01`)
            The amount of time taken in each time step.
        `Ti` : `int` (default=`300`)
            The initial temperature of the system in Kelvin.
        `Tmin` : `int` (default=`250`)
            The minimal temperature of the system in Kelvin.
        `Tmax` : `int` (default=`500`)
            The maximal temperature of the system in Kelvin.
        `dT` : `int` (default=`50`)
            The maximal allowed temperature change, in Kelvin, for a single action.
        `Vi` : `float` (default=`0.002`)
            The initial volume of the system in litres.
        `Vmin` : `float` (default=`0.001`)
            The minimal volume of the system in litres.
        `Vmax` : `float` (default=`0.005`)
            The maximal volume of the system in litres.
        `dV` : `float` (default=`0.0005`)
            The maximal allowed volume change, in litres, for a single action.
        `overlap` : `boolean` (default=`False`)
            Indicates if the spectral plots show overlapping signatures.
        `vessel_path` : `str` (default=`None`)
            A string indicating the path to a vessel intended to be loaded into this module.

        Returns
        ---------------
        None

        Raises
        ---------------
        None
        '''

        self.name = "experiment_0"
        self.step_num = 1

        self.n_steps = n_steps  # Time steps per action
        self.dt = dt  # Time step of reaction (s)
        self.tmax = n_steps * dt * 20  # Maximum time (s) (20 is the registered max_episode_steps)
        self.Ti = Ti  # Initial temperature (K)
        self.Tmin = Tmin  # Minimum temperature of the system (K)
        self.Tmax = Tmax  # Maximum temperature of the system (K)
        self.dT = dT  # Maximum change in temperature per action (K)

        self.Vi = Vi  # Initial Volume (m**3)
        self.Vmin = Vmin  # Minimum Volume of the system (m**3)
        self.Vmax = Vmax  # Maximum Volume of the system (m**3)
        self.dV = dV  # Maximum change in Volume per action (m**3)

        # initialize the reaction
        self.reaction = reaction(overlap=overlap,
                                 materials=materials,
                                 solutes=solutes,
                                 desired=desired)

        # set the maximum pressure
        Pmax = self.reaction.max_mol * R * Tmax / Vmin
        self.Pmax = Pmax

        # initialize vessels by providing a empty default vessel or loading an existing saved vessel
        self.n_init = np.zeros(self.reaction.nmax.shape[0], dtype=np.float32)
        self.vessel_path = vessel_path
        if vessel_path == None:
            self.vessels = vessel.Vessel('default',
                                         temperature=Ti,
                                         p_max=Pmax,
                                         v_max=Vmax * 1000,
                                         v_min=Vmin * 1000,
                                         Tmax=Tmax,
                                         Tmin=Tmin,
                                         default_dt=dt)
        else:
            with open(vessel_path, 'rb') as handle:
                b = pickle.load(handle)
                self.vessels = b

            for i in range(self.n_init.shape[0]):
                material_name = self.reaction.labels[i]
                material_class = self.reaction.material_classes[i]
                self.n_init[i] = self.vessels._material_dict[material_name][1]

        # reset the inputted reaction before performing any steps
        self.reaction.reset(n_init=self.n_init)

        # Defining action and observation space for OpenAI Gym framework
        # shape[0] is the change in amount of each reactant
        # + 2 is for the change in T and V
        # all actions range between 0 () and 1 ()
        # 0 = no reactant added and T, V are decreased by the maximum amount (-dT and -dV)
        # 1 = all reactant added and T, V are increased by the maximum amount (dT and dV)
        act_low = np.zeros(self.reaction.initial_in_hand.shape[0] + 2,
                           dtype=np.float32)
        act_high = np.ones(self.reaction.initial_in_hand.shape[0] + 2,
                           dtype=np.float32)
        self.action_space = gym.spaces.Box(low=act_low, high=act_high)

        # this an array denoting spectral signatures (varying
        # between 0.0 and 1.0) for a wide range of wavelengths
        absorb = self.reaction.get_spectra(Vi)

        # Observations have several attributes
        # + 4 indicates state variables time, temperature, volume, and pressure
        # initial_in_hand.shape[0] indicates the amount of each reactant
        # absorb.shape[0] indicates the numerous spectral signatures from get_spectra
        obs_low = np.zeros(self.reaction.initial_in_hand.shape[0] + 4 +
                           absorb.shape[0],
                           dtype=np.float32)
        obs_high = np.ones(self.reaction.initial_in_hand.shape[0] + 4 +
                           absorb.shape[0],
                           dtype=np.float32)
        self.observation_space = gym.spaces.Box(low=obs_low, high=obs_high)

        # Reset the environment upon calling the class
        self.reset()
コード例 #15
0
ファイル: wurtz_v0.py プロジェクト: amanuel43/chemgymrl
    def reset(self, extraction_vessel):
        '''
        Method to reset the environment.

        Parameters
        ---------------
        `extraction_vessel` : `vessel` (default=`None`)
            A vessel object containing state variables, materials, solutes, and spectral data.

        Returns
        ---------------
        `vessels` : `list`
            A list of all the vessel objects that contain materials and solutes.
        `external_vessels` : `list`
            A list of the external vessels, beakers, to be used in the extraction.
        `state` : `np.array`
            An array containing state variables, material concentrations, and spectral data.

        Raises
        ---------------
        None
        '''

        # delete the extraction vessel's solute_dict and copy it into a list of vessels
        solute_dict = extraction_vessel._solute_dict
        extraction_vessel._solute_dict = {}
        vessels = [copy.deepcopy(extraction_vessel)]

        # create all the necessary beakers and add them to the list
        for i in range(self.n_empty_vessels):
            temp_vessel = vessel.Vessel(label='beaker_{}'.format(i + 1),
                                        v_max=self.max_vessel_volume,
                                        default_dt=0.05,
                                        n_pixels=self.n_vessel_pixels)
            vessels.append(temp_vessel)

        # generate a list of external vessels to contain solutes
        external_vessels = []

        # generate a vessel to contain the main solute
        solute_vessel = vessel.Vessel(
            label='solute_vessel0',
            v_max=self.solute_volume,
            n_pixels=self.n_vessel_pixels,
            settling_switch=False,
            layer_switch=False,
        )

        # create the material dictionary for the solute vessel
        solute_material_dict = {}
        solute_class = convert_to_class(materials=[self.solute])[0]
        solute_material_dict[self.solute] = [solute_class, self.solute_volume]

        # check for overflow
        solute_material_dict, _, _ = util.check_overflow(
            material_dict=solute_material_dict,
            solute_dict={},
            v_max=solute_vessel.get_max_volume())

        # instruct the vessel to update its material dictionary
        event = ['update material dict', solute_material_dict]
        solute_vessel.push_event_to_queue(feedback=[event], dt=0)

        # add the main solute vessel to the list of external vessels
        external_vessels.append(solute_vessel)

        # generate vessels for each solute in the extraction vessel
        for solute_name in solute_dict:
            # generate an empty vessel to be filled with a single solute
            solute_vessel = vessel.Vessel(label='solute_vessel{}'.format(
                len(external_vessels)),
                                          v_max=extraction_vessel.v_max,
                                          n_pixels=self.n_vessel_pixels,
                                          settling_switch=False,
                                          layer_switch=False)
            solute_material_dict = {}
            solute_material_dict[solute_name] = solute_dict[solute_name]

            # check for overflow
            solute_material_dict, _, _ = util.check_overflow(
                material_dict=solute_material_dict,
                solute_dict={},
                v_max=solute_vessel.get_max_volume())

            # instruct the vessel to update its material dictionary
            event = ['update material dict', solute_material_dict]
            solute_vessel.push_event_to_queue(feedback=[event], dt=0)

            # add this solute vessel to the list of external vessels
            external_vessels.append(solute_vessel)

        # generate the state
        state = util.generate_state(vessel_list=vessels,
                                    max_n_vessel=self.n_total_vessels)

        return vessels, external_vessels, state
コード例 #16
0
ファイル: reaction_base.py プロジェクト: chemgymrl/chemgymrl
    def reset(self, vessels, initial_in_hand):
        """
        Method to reset the environment and vessel back to its initial state.
        Empty the initial n array and reset the vessel's thermodynamic properties.
        Parameters
        ---------------
        `vessels` : `vessel.Vessel`
            A vessel containing initial materials.

        Returns
        ---------------
        `vessels` : `vessel.Vessel`
            A vessel that has been updated to have the proper thermodynamic properties.

        Raises
        ---------------
        None
        """

        # open the provided vessel to get the material and solute dictionaries
        material_dict = vessels.get_material_dict()
        solute_dict = vessels.get_solute_dict()

        # acquire the amounts of reactant materials
        for i, material in enumerate(initial_in_hand):
            material_name = material['Material']
            if material_name in self.reactants:
                self.initial_in_hand[i] = initial_in_hand[i]['Initial']

        for i, material_name in enumerate(self.materials):
            if material_name in material_dict.keys():
                self.initial_materials[i] = material_dict[material_name][1]

        # acquire the amounts of solute materials
        for i, solute_name in enumerate(solute_dict.keys()):
            if solute_name in self.solutes:
                self.initial_solutes[i] = solute_dict[solute_name][1]

        vessels = vessel.Vessel('react_vessel',
                                materials=material_dict,
                                solutes=solute_dict,
                                temperature=self.Ti,
                                v_max=self.Vmax,
                                v_min=self.Vmin,
                                Tmax=self.Tmax,
                                Tmin=self.Tmin,
                                default_dt=self.dt)

        # ensure the entire initial materials in hand array is available
        self.cur_in_hand = 1.0 * self.initial_in_hand

        # set the n array to contain initial values
        for i, material_amount in enumerate(self.initial_materials):
            self.n[i] = material_amount

        # reset the vessel parameters to their original values as specified in the reaction file
        vessels.set_v_min(self.Vmin, unit="l")
        vessels.set_v_max(self.Vmax, unit="l")
        vessels.set_volume(self.Vi, unit="l", override=True)
        vessels.temperature = self.Ti
        vessels.Tmin = self.Tmin
        vessels.Tmax = self.Tmax
        vessels.default_dt = self.dt

        return vessels
コード例 #17
0
def wurtz_vessel():
    """
    Function to generate an input vessel for the wurtz extraction experiment.

    Parameters
    ---------------
    None

    Returns
    ---------------
    `extract_vessel` : `vessel`
        A vessel object containing state variables, materials, solutes, and spectral data.

    Raises
    ---------------
    None
    """

    # initialize extraction vessel
    extraction_vessel = vessel.Vessel(label='extraction_vessel')

    # initialize DiEthylEther
    DiEthylEther = material.DiEthylEther()

    # initialize Na
    Na = material.Na()
    Na.set_charge(1.0)
    Na.set_solute_flag(True)
    Na.set_color(0.0)
    Na.set_polarity(2.0)
    Na.set_phase('l')

    # initialize Cl
    Cl = material.Cl()
    Cl.set_charge(-1.0)
    Cl.set_solute_flag(True)
    Cl.set_color(0.0)
    Cl.set_polarity(2.0)
    Cl.set_phase('l')

    # initialize Dodecane
    Dodecane = material.Dodecane()
    Dodecane.set_solute_flag(True)
    Dodecane.set_color(0.0)
    Dodecane.set_phase('l')

    # material_dict
    material_dict = {
        DiEthylEther.get_name(): [DiEthylEther, 4.0, 'mol'],
        Na.get_name(): [Na, 1.0, 'mol'],
        Cl.get_name(): [Cl, 1.0, 'mol'],
        Dodecane.get_name(): [Dodecane, 1.0, 'mol']
    }

    # solute_dict
    solute_dict = {
        Na.get_name(): {
            DiEthylEther.get_name(): [DiEthylEther, 1.0, 'mol']
        },
        Cl.get_name(): {
            DiEthylEther.get_name(): [DiEthylEther, 1.0, 'mol']
        },
        Dodecane.get_name(): {
            DiEthylEther.get_name(): [DiEthylEther, 1.0, 'mol']
        }
    }

    material_dict, solute_dict, _ = util.check_overflow(
        material_dict=material_dict,
        solute_dict=solute_dict,
        v_max=extraction_vessel.get_max_volume())

    # set events and push them to the queue
    extraction_vessel.push_event_to_queue(
        events=None,
        feedback=[['update material dict', material_dict],
                  ['update solute dict', solute_dict]],
        dt=0)
    extraction_vessel.push_event_to_queue(events=None,
                                          feedback=None,
                                          dt=-100000)

    return extraction_vessel