Ejemplo n.º 1
0
    def single_phase_v(self, P, T=None, print_results=True, get_density=False):
        if isinstance(T, float):
            self.temp = T

        if isinstance(P, float) or isinstance(P, int):
            Pv, vle = self.vapour_pressure(temperature=T, get_volume=True)
            v_init = vle[0] if P > Pv else vle[1]
            getv = least_squares(self.__getp, v_init, kwargs={"targetP": P})

            if print_results: print(getv)

            return getv.x[0] if get_density == False else (getv.x[0],
                                                           1 / getv.x[0])

        mt.checkerr(isinstance(P, np.ndarray),
                    "Use float/int or ndarray for pressure inputs")
        varr = np.zeros(np.size(P))
        for i in range(len(P)):
            Pv, vle = self.vapour_pressure(temperature=T, get_volume=True)
            v_init = vle[0] if P[i] > Pv else vle[1]
            getv = least_squares(self.__getp, v_init, kwargs={"targetP": P[i]})

            varr[i] = getv.x[0]

        return varr if get_density == False else (varr, 1. / varr)
Ejemplo n.º 2
0
 def set_angle(self, other, angle):
     mt.checkerr(
         isinstance(angle, tuple) and len(angle) == 3,
         "Use 3d vector tuple to specify angle")
     if other in self.connectedTo:
         self.connectedTo[other] = angle
         other.connectedTo[self] = mt.inv_angle(angle)
Ejemplo n.º 3
0
 def __init__(self, mass, *args):
     self.gtypes = {}
     for group in args:
         mt.checkerr(
             isinstance(group, GroupType),
             "Use GroupType object to specify groups used as optional arguments"
         )
         self.gtypes[group] = 0
     self.groups = {}
     self.mass = mass
Ejemplo n.º 4
0
    def connect(self, other, angle=None):
        mt.checkerr(isinstance(other, Group),
                    "Groups can only connect to other groups")
        mt.checkerr(
            angle == None or (isinstance(angle, tuple) and len(angle) == 3),
            "Either don't specify angle, or use 3d vector tuple")
        self.connections = self.connections + 1
        self.connectedTo[other] = angle

        if not other.connected(self):
            other.connect(self)
Ejemplo n.º 5
0
    def add_moles(self, **kwargs):
        for comp in kwargs:
            mt.checkerr(comp in self.comps,
                        "Component name {} is not in system".format(comp))
            mt.checkerr(isinstance(kwargs[comp], int),
                        "Int values for components only")

        for comp in kwargs:
            self.moles[comp] = self.moles[comp] + kwargs[comp]

        for comp in self.molfrac:
            self.molfrac[comp] = self.moles[comp] / self.__moltol()
Ejemplo n.º 6
0
    def p_rho_isotherm(self, nden, temperature=None):
        '''
        nden in mol/m3
        '''
        if isinstance(temperature, float):
            self.temp = temperature
        mt.checkerr(isinstance(nden, float), "Use floats for rho")
        volume = self.__moltol() / (cst.Na * nden * pow(cst.nmtom, 3))
        self.volume = Var(volume)
        A = self.helmholtz()
        result = -derivative(A, self.volume) / pow(cst.nmtom, 3)

        # Reset system back to float
        self.volume = volume
        return result
Ejemplo n.º 7
0
 def __init__(self, temperature=293, volume=1000, **kwargs):
     for comp in kwargs:
         mt.checkerr(
             isinstance(kwargs[comp], Component),
             "Use Component object to specify groups used, with format CompName = Component obj"
         )
     self.comps = kwargs
     self.moles = {}
     self.molfrac = {}
     for comp in self.comps:
         self.moles[comp] = 0
         self.molfrac[comp] = 0
     self.temp = temperature  # K
     self.volume = volume  # nm^3
     self.pressure = 1  # bar (temporarily useless)
     self.sdt = 1
Ejemplo n.º 8
0
    def add_comp(self, **kwargs):
        for comp in kwargs:
            mt.checkerr(
                isinstance(kwargs[comp], Component),
                "Use Component object to specify groups used, with format CompName = Component obj"
            )

        for comp in kwargs:
            mt.checkwarn(
                kwargs[comp] in self.comps.values(),
                "Component object already exist, {} not added".format(comp))
            mt.checkwarn(comp in self.comps,
                         "Component name taken, {} not added".format(comp))
            if (comp not in self.comps) and (kwargs[comp]
                                             not in self.comps.values()):
                self.comps[comp] = kwargs[comp]
                self.moles[comp] = 0
                self.molfrac[comp] = 0
Ejemplo n.º 9
0
    def p_v_isotherm(self, volume, temperature=None, gibbs=False):
        '''
        Get pressure profile from volume inputs. Volume in m3 per mol
        '''
        if isinstance(temperature, float) or isinstance(temperature, int):
            self.temp = temperature

        mt.checkerr(
            isinstance(volume, float) or isinstance(volume, np.ndarray),
            "Use floats or numpy array for volume")
        volume = self.__moltol() * volume / (cst.Na * pow(cst.nmtom, 3))
        Var.set_order(1)
        # Case single volume value
        if isinstance(volume, float):
            self.volume = Var(volume)
            A = self.helmholtz()
            result = -derivative(A, self.volume, order=1) / pow(cst.nmtom, 3)

            # Reset system back to float
            self.volume = volume
            return result

        # Case numpy array
        old_v = self.volume
        vlen = np.size(volume)
        P = np.zeros(vlen)
        if gibbs: G = np.zeros(vlen)
        print('=' * 5, f'Pv Isotherm data from {vlen:5d} points', '=' * 5)
        tenp = vlen // 10
        for i in range(vlen):
            self.volume = Var(volume[i])
            A = self.helmholtz()
            P[i] = -derivative(A, self.volume) / pow(cst.nmtom, 3)

            if gibbs:
                G[i] = (A.value + P[i] * self.volume.value *
                        pow(cst.nmtom, 3)) / self.__moltol()
            if (i + 1) % tenp == 0:
                print(f'Progress at {(i+1)//tenp * 10:3d}%')
        # Reset system back to float
        self.volume = old_v
        return (P, G) if gibbs else P
Ejemplo n.º 10
0
    def add_group(self, name, gtype):
        mt.checkerr(isinstance(gtype, GroupType),
                    "Group type invalid, use GroupType object")
        mt.checkerr(isinstance(name, str), "Use str for name")
        mt.checkerr(name not in self.groups, "Group name taken")
        if (gtype not in self.gtypes):
            self.gtypes[gtype] = 0
        self.groups[name] = Group(gtype)
        self.gtypes[gtype] = self.gtypes[gtype] + 1

        return self.groups[name]
Ejemplo n.º 11
0
    def quick_set(self, *args):
        gtypel = []
        numl = []
        for arg in args:
            mt.checkerr(
                isinstance(arg, tuple) or isinstance(arg, list),
                "Use iterable tuple or list for components and no. of molecules"
            )
            mt.checkerr(isinstance(arg[0], GroupType),
                        "First element of iterable must be of GroupType")
            mt.checkerr(isinstance(arg[1], int),
                        "Second element of iterable must be of int")
            gtypel.append(arg[0])
            numl.append(arg[1])

        names = []
        count = 1
        groupsAdding = sum(numl)

        for i in range(groupsAdding):
            name = 'G{:03d}'.format(count)
            while (name in self.groups) or (name in names):
                count = count + 1
                name = 'G{:03d}'.format(count)
            names.append(name)

        faults = 0
        for i in range(len(gtypel)):
            if isinstance(gtypel[i], GroupType):
                for j in range(numl[i]):
                    self.add_group(names[sum(numl[0:i]) + j - faults],
                                   gtypel[i])
            else:
                print("Not GroupType obj error, groups not added")
                faults = faults + numl[i]
        print('{:3d} groups were to be added, {:3d} groups were added'.format(
            groupsAdding, groupsAdding - faults))

        return self
Ejemplo n.º 12
0
    def quick_set(self, *args):
        complist = []
        molelist = []
        for arg in args:
            mt.checkerr(
                isinstance(arg, tuple) or isinstance(arg, list),
                "Use iterable tuple or list for quick_set")
            mt.checkerr(isinstance(arg[0], Component),
                        "First element of iterable must be of Component type")
            mt.checkerr(isinstance(arg[1], int),
                        "Second element of iterable must be of int type")
            complist.append(arg[0])
            molelist.append(arg[1])

        num = []
        count = 1
        for i in range(len(complist)):
            name = 'COMP{:03d}'.format(count)
            while (name in self.comps) or (name in num):
                count = count + 1
                name = 'COMP{:03d}'.format(count)
            num.append(name)

        faults = 0
        for i in range(len(complist)):
            if (complist[i] not in self.comps.values()):
                self.comps[num[i - faults]] = complist[i]
                self.moles[num[i - faults]] = molelist[i]
                self.molfrac[num[i - faults]] = 0
            else:
                print("Component already in system, molecules not added")
                faults = faults + 1

        for comp in self.molfrac:
            self.molfrac[comp] = self.moles[comp] / self.__moltol()

        return self
Ejemplo n.º 13
0
    def connect(self, name1, name2, angle=None):
        mt.checkerr(name1 in self.groups and name2 in self.groups,
                    "Name missing from list of groups")

        self.groups[name1].connect(self.groups[name2], angle)