<EOL>if type(other) is MaterialPackage:<EOL><INDENT>if self.material == other.material:  <EOL><INDENT>result = MaterialPackage(self.material,<EOL>self._compound_masses +<EOL>other._compound_masses)<EOL>result.H = self._H + other._H<EOL>result.P = self.P<EOL>return result<EOL><DEDENT>else:  <EOL><INDENT>H = self.H + other.H<EOL>result = self.clone()<EOL>for compound in other.material.compounds:<EOL><INDENT>if compound not in self.material.compounds:<EOL><INDENT>raise Exception("<STR_LIT>" + other.material.name +<EOL>"<STR_LIT>" +<EOL>self.material.name +<EOL>"<STR_LIT>" + compound +<EOL>"<STR_LIT>" +<EOL>self.material.name + "<STR_LIT>")<EOL><DEDENT>result = result + (compound,<EOL>other.get_compound_mass(compound))<EOL><DEDENT>result.H = H<EOL>return result<EOL><DEDENT><DEDENT>elif self._is_compound_mass_tuple(other):<EOL><INDENT>compound = other[<NUM_LIT:0>]<EOL>index = self.material.get_compound_index(compound)<EOL>mass = other[<NUM_LIT:1>]<EOL>enthalpy = thermo.H(compound, self._T, mass)<EOL>result = self.clone()<EOL>result._compound_masses[index] = result._compound_masses[index] +mass<EOL>result._H += enthalpy<EOL>result._P = self._P<EOL>return result<EOL><DEDENT>elif self._is_compound_mass_temperature_tuple(other):<EOL><INDENT>compound = other[<NUM_LIT:0>]<EOL>index = self.material.get_compound_index(compound)<EOL>mass = other[<NUM_LIT:1>]<EOL>temperature = other[<NUM_LIT:2>]<EOL>enthalpy = thermo.H(compound, temperature, mass)<EOL>result = self * <NUM_LIT:1.0><EOL>result._compound_masses[index] = result._compound_masses[index] +mass<EOL>result.H = self._H + enthalpy<EOL>result._P = self._P<EOL>return result<EOL><DEDENT>else:<EOL><INDENT>raise TypeError("<STR_LIT>")<EOL><DEDENT>

Addition operator (+).

Add this package (self) and 'other' together, return the result as a
new package, and leave self unchanged.

:param other: Can can be one of the following:
         1. MaterialPackage
            'other' is added to self to create a new package.
         2. tuple: (compound, mass)
            The specified mass of the specified compound is added to \
            self, assuming the added material has the same \
            temperature as self.
         3. tuple: (compound, mass, temperature)
            The specified mass of the specified compound at the \
            specified temperature is added to self.

:returns: A new Material package that is the sum of self and 'other'.


<EOL>if type(scalar) is float or type(scalar) is numpy.float64 ortype(scalar) is numpy.float32:<EOL><INDENT>if scalar < <NUM_LIT:0.0>:<EOL><INDENT>raise Exception("<STR_LIT>"<EOL>"<STR_LIT>")<EOL><DEDENT>result = MaterialPackage(self.material, self._compound_masses *<EOL>scalar, self._P, self._T)<EOL>return result<EOL><DEDENT>else:<EOL><INDENT>raise TypeError("<STR_LIT>")<EOL><DEDENT>

The multiplication operator (*).

Create a new package by multiplying self with scalar.

:param scalar: The result is a new package with its content equal to
  self multiplied by a scalar, leaving self unchanged.

:returns: New MaterialPackage object.


if self.isCoal:<EOL><INDENT>return self._calculate_Hfr_coal(T)<EOL><DEDENT>H = <NUM_LIT:0.0><EOL>for compound in self.material.compounds:<EOL><INDENT>index = self.material.get_compound_index(compound)<EOL>dH = thermo.H(compound, T, self._compound_masses[index])<EOL>H = H + dH<EOL><DEDENT>return H<EOL>

Calculate the enthalpy of the package at the specified temperature.

:param T: Temperature. [°C]

:returns: Enthalpy. [kWh]


m_C = <NUM_LIT:0>  <EOL>m_H = <NUM_LIT:0>  <EOL>m_O = <NUM_LIT:0>  <EOL>m_N = <NUM_LIT:0>  <EOL>m_S = <NUM_LIT:0>  <EOL>T = <NUM_LIT>  <EOL>Hin = <NUM_LIT:0.0>  <EOL>for compound in self.material.compounds:<EOL><INDENT>index = self.material.get_compound_index(compound)<EOL>if stoich.element_mass_fraction(compound, '<STR_LIT:C>') == <NUM_LIT:1.0>:<EOL><INDENT>m_C += self._compound_masses[index]<EOL>Hin = thermo.H(compound, T, self._compound_masses[index])<EOL><DEDENT>elif stoich.element_mass_fraction(compound, '<STR_LIT:H>') == <NUM_LIT:1.0>:<EOL><INDENT>m_H += self._compound_masses[index]<EOL>Hin = thermo.H(compound, T, self._compound_masses[index])<EOL><DEDENT>elif stoich.element_mass_fraction(compound, '<STR_LIT:O>') == <NUM_LIT:1.0>:<EOL><INDENT>m_O += self._compound_masses[index]<EOL>Hin = thermo.H(compound, T, self._compound_masses[index])<EOL><DEDENT>elif stoich.element_mass_fraction(compound, '<STR_LIT:N>') == <NUM_LIT:1.0>:<EOL><INDENT>m_N += self._compound_masses[index]<EOL>Hin = thermo.H(compound, T, self._compound_masses[index])<EOL><DEDENT>elif stoich.element_mass_fraction(compound, '<STR_LIT:S>') == <NUM_LIT:1.0>:<EOL><INDENT>m_S += self._compound_masses[index]<EOL>Hin = thermo.H(compound, T, self._compound_masses[index])<EOL><DEDENT><DEDENT>m_total = m_C + m_H + m_O + m_N + m_S  <EOL>Hout = <NUM_LIT:0.0>  <EOL>Hout += thermo.H('<STR_LIT>', T, cc(m_C, '<STR_LIT:C>', '<STR_LIT>', '<STR_LIT:C>'))<EOL>Hout += thermo.H('<STR_LIT>', T, cc(m_H, '<STR_LIT:H>', '<STR_LIT>', '<STR_LIT:H>'))<EOL>Hout += thermo.H('<STR_LIT>', T, m_O)<EOL>Hout += thermo.H('<STR_LIT>', T, m_N)<EOL>Hout += thermo.H('<STR_LIT>', T, cc(m_S, '<STR_LIT:S>', '<STR_LIT>', '<STR_LIT:S>'))<EOL>if self.HHV is None:<EOL><INDENT>HHV = Hout - Hin / m_total  <EOL><DEDENT>else:<EOL><INDENT>HHV = self.HHV / <NUM_LIT>  <EOL><DEDENT>return HHV + Hout / m_total<EOL>

Calculate the enthalpy of formation of the package at the specified temperature, in
case the material is coal.

:returns: [kWh/kg] enthalpy of formation of daf coal


m_C = <NUM_LIT:0>  <EOL>m_H = <NUM_LIT:0>  <EOL>m_O = <NUM_LIT:0>  <EOL>m_N = <NUM_LIT:0>  <EOL>m_S = <NUM_LIT:0>  <EOL>H = <NUM_LIT:0.0>  <EOL>for compound in self.material.compounds:<EOL><INDENT>index = self.material.get_compound_index(compound)<EOL>if stoich.element_mass_fraction(compound, '<STR_LIT:C>') == <NUM_LIT:1.0>:<EOL><INDENT>m_C += self._compound_masses[index]<EOL><DEDENT>elif stoich.element_mass_fraction(compound, '<STR_LIT:H>') == <NUM_LIT:1.0>:<EOL><INDENT>m_H += self._compound_masses[index]<EOL><DEDENT>elif stoich.element_mass_fraction(compound, '<STR_LIT:O>') == <NUM_LIT:1.0>:<EOL><INDENT>m_O += self._compound_masses[index]<EOL><DEDENT>elif stoich.element_mass_fraction(compound, '<STR_LIT:N>') == <NUM_LIT:1.0>:<EOL><INDENT>m_N += self._compound_masses[index]<EOL><DEDENT>elif stoich.element_mass_fraction(compound, '<STR_LIT:S>') == <NUM_LIT:1.0>:<EOL><INDENT>m_S += self._compound_masses[index]<EOL><DEDENT>else:<EOL><INDENT>dH = thermo.H(compound, T, self._compound_masses[index])<EOL>H += dH<EOL><DEDENT><DEDENT>m_total = y_C + y_H + y_O + y_N + y_S  <EOL>y_C = m_C / m_total<EOL>y_H = m_H / m_total<EOL>y_O = m_O / m_total<EOL>y_N = m_N / m_total<EOL>y_S = m_S / m_total<EOL>hmodel = coals.DafHTy()<EOL>H = hmodel.calculate(T=T+<NUM_LIT>, y_C=y_C, y_H=y_H, y_O=y_O, y_N=y_N,<EOL>y_S=y_S) / <NUM_LIT>  <EOL>H298 = hmodel.calculate(T=<NUM_LIT>, y_C=y_C, y_H=y_H, y_O=y_O, y_N=y_N,<EOL>y_S=y_S) / <NUM_LIT>  <EOL>Hdaf = H - H298 + self._DH298  <EOL>Hdaf *= m_total  <EOL>H += Hdaf<EOL>return H<EOL>

Calculate the enthalpy of the package at the specified temperature, in
case the material is coal.

:param T: [°C] temperature

:returns: [kWh] enthalpy


<EOL>x = list()<EOL>x.append(self._T)<EOL>x.append(self._T + <NUM_LIT>)<EOL>y = list()<EOL>y.append(self._calculate_H(x[<NUM_LIT:0>]) - H)<EOL>y.append(self._calculate_H(x[<NUM_LIT:1>]) - H)<EOL>for i in range(<NUM_LIT:2>, <NUM_LIT:50>):<EOL><INDENT>x.append(x[i-<NUM_LIT:1>] - y[i-<NUM_LIT:1>]*((x[i-<NUM_LIT:1>] - x[i-<NUM_LIT:2>])/(y[i-<NUM_LIT:1>] - y[i-<NUM_LIT:2>])))<EOL>y.append(self._calculate_H(x[i]) - H)<EOL>if abs(y[i-<NUM_LIT:1>]) < <NUM_LIT>:<EOL><INDENT>break<EOL><DEDENT><DEDENT>return x[len(x) - <NUM_LIT:1>]<EOL>

Calculate the temperature of the package given the specified
enthalpy using a secant algorithm.

:param H: Enthalpy. [kWh]

:returns: Temperature. [°C]


if not type(value) is tuple:<EOL><INDENT>return False<EOL><DEDENT>elif not len(value) == <NUM_LIT:2>:<EOL><INDENT>return False<EOL><DEDENT>elif not type(value[<NUM_LIT:0>]) is str:<EOL><INDENT>return False<EOL><DEDENT>elif not type(value[<NUM_LIT:1>]) is float andnot type(value[<NUM_LIT:1>]) is numpy.float64 andnot type(value[<NUM_LIT:1>]) is numpy.float32:<EOL><INDENT>return False<EOL><DEDENT>else:<EOL><INDENT>return True<EOL><DEDENT>

Determines whether value is a tuple of the format
(compound(str), mass(float)).

:param value: The value to be tested.

:returns: True or False


if not type(value) is tuple:<EOL><INDENT>return False<EOL><DEDENT>elif not len(value) == <NUM_LIT:3>:<EOL><INDENT>return False<EOL><DEDENT>elif not type(value[<NUM_LIT:0>]) is str:<EOL><INDENT>return False<EOL><DEDENT>elif not type(value[<NUM_LIT:1>]) is float andnot type(value[<NUM_LIT:1>]) is numpy.float64 andnot type(value[<NUM_LIT:1>]) is numpy.float32:<EOL><INDENT>return False<EOL><DEDENT>elif not type(value[<NUM_LIT:1>]) is float andnot type(value[<NUM_LIT:1>]) is numpy.float64 andnot type(value[<NUM_LIT:1>]) is numpy.float32:<EOL><INDENT>return False<EOL><DEDENT>else:<EOL><INDENT>return True<EOL><DEDENT>

Determines whether value is a tuple of the format
        (compound(str), mass(float), temperature(float)).

        :param value: The value to be tested.

        :returns: True or False


return self._H<EOL>

Get the enthalpy of the package.

:returns: Enthalpy. [kWh]


self._H = H<EOL>self._T = self._calculate_T(H)<EOL>

Set the enthalpy of the package to the specified value, and
recalculate it's temperature.

:param H: The new enthalpy value. [kWh]


return self._T<EOL>

Get the temperature of of the package.

:returns: Temperature. [°C]


self._T = T<EOL>self._H = self._calculate_H(T)<EOL>

Set the temperature of the package to the specified value, and
recalculate it's enthalpy.

:param T: Temperature. [°C]


return self._P<EOL>

Determine the pressure of the package.

        :returns: Pressure. [atm]


self._P = P<EOL>

Set the pressure of the package to the specified value.

        :param P: Pressure. [atm]


result = copy.copy(self)<EOL>result._compound_masses = copy.deepcopy(self._compound_masses)<EOL>return result<EOL>

Create a complete copy of the package.

        :returns: A new MaterialPackage object.


self._compound_masses = self._compound_masses * <NUM_LIT:0.0><EOL>self._P = <NUM_LIT:1.0><EOL>self._T = <NUM_LIT><EOL>self._H = <NUM_LIT:0.0><EOL>

Set all the compound masses in the package to zero.
Set the pressure to 1, the temperature to 25 and the enthalpy to zero.


return self._compound_masses / self._compound_masses.sum()<EOL>

Determine the assay of the package.

:returns: Array of mass fractions.


return self._compound_masses.sum()<EOL>

Get the mass of the package.

:returns: [kg]


if compound in self.material.compounds:<EOL><INDENT>return self._compound_masses[<EOL>self.material.get_compound_index(compound)]<EOL><DEDENT>else:<EOL><INDENT>return <NUM_LIT:0.0><EOL><DEDENT>

Determine the mass of the specified compound in the package.

:param compound: Formula and phase of a compound, e.g. "Fe2O3[S1]".

:returns: Mass. [kg]


result = self._compound_masses * <NUM_LIT:1.0><EOL>for compound in self.material.compounds:<EOL><INDENT>index = self.material.get_compound_index(compound)<EOL>result[index] = stoich.amount(compound, result[index])<EOL><DEDENT>return result<EOL>

Determine the mole amounts of all the compounds.

:returns: List of amounts. [kmol]


index = self.material.get_compound_index(compound)<EOL>return stoich.amount(compound, self._compound_masses[index])<EOL>

Determine the mole amount of the specified compound.

:returns: Amount. [kmol]


return sum(self.get_compound_amount(c) for c in self.material.compounds)<EOL>

Determine the sum of mole amounts of all the compounds.

:returns: Amount. [kmol]


if elements is None:<EOL><INDENT>elements = self.material.elements<EOL><DEDENT>result = numpy.zeros(len(elements))<EOL>for compound in self.material.compounds:<EOL><INDENT>result += self.get_compound_mass(compound) *numpy.array(stoich.element_mass_fractions(compound, elements))<EOL><DEDENT>return result<EOL>

Determine the masses of elements in the package.

:returns: Array of element masses. [kg]


element_symbols = self.material.elements<EOL>element_masses = self.get_element_masses()<EOL>return {s: m for s, m in zip(element_symbols, element_masses)}<EOL>

Determine the masses of elements in the package and return as a
dictionary.

:returns: Dictionary of element symbols and masses. [kg]


result = numpy.zeros(<NUM_LIT:1>)<EOL>for compound in self.material.compounds:<EOL><INDENT>result += self.get_compound_mass(compound) *numpy.array(stoich.element_mass_fractions(compound, [element]))<EOL><DEDENT>return result[<NUM_LIT:0>]<EOL>

Determine the mass of the specified elements in the package.

:returns: Masses. [kg]


<EOL>if type(other) is float ortype(other) is numpy.float64 ortype(other) is numpy.float32:<EOL><INDENT>return self._extract_mass(other)<EOL><DEDENT>elif self._is_compound_mass_tuple(other):<EOL><INDENT>return self._extract_compound_mass(other[<NUM_LIT:0>], other[<NUM_LIT:1>])<EOL><DEDENT>elif type(other) is str:<EOL><INDENT>return self._extract_compound(other)<EOL><DEDENT>elif type(other) is Material:<EOL><INDENT>return self._extract_material(other)<EOL><DEDENT>else:<EOL><INDENT>raise TypeError("<STR_LIT>")<EOL><DEDENT>

Extract 'other' from this package, modifying this package and
returning the extracted material as a new package.

:param other: Can be one of the following:

  * float: A mass equal to other is extracted from self. Self is
    reduced by other and the extracted package is returned as
    a new package.
  * tuple (compound, mass): The other tuple specifies the mass
    of a compound to be extracted. It is extracted from self and
    the extracted mass is returned as a new package.
  * string: The 'other' string specifies the compound to be
    extracted. All of the mass of that compound will be removed
    from self and a new package created with it.
  * Material: The 'other' material specifies the list of
    compounds to extract.

:returns: New MaterialPackage object.


<EOL>if type(other) is MaterialStream:<EOL><INDENT>if self.material == other.material:  <EOL><INDENT>if self.isCoal or other.isCoal:<EOL><INDENT>HHV = <NUM_LIT:0><EOL>if self.HHV:<EOL><INDENT>HHV += self.HHV * self.mfr<EOL><DEDENT>if other.HHV:<EOL><INDENT>HHV += other.HHV * other.mfr<EOL><DEDENT>HHV /= self.mfr + other.mfr<EOL>isCoal = True<EOL><DEDENT>else:<EOL><INDENT>isCoal = False<EOL>HHV = None<EOL><DEDENT>result = MaterialStream(self.material,<EOL>self._compound_mfrs +<EOL>other._compound_mfrs, isCoal=isCoal, HHV=HHV)<EOL>result.Hfr = self._Hfr + other._Hfr<EOL>result.P = self.P<EOL>return result<EOL><DEDENT>else:  <EOL><INDENT>Hfr = self.Hfr + other.Hfr<EOL>result = self.clone()<EOL>for compound in other.material.compounds:<EOL><INDENT>if compound not in self.material.compounds:<EOL><INDENT>raise Exception("<STR_LIT>" + other.material.name +<EOL>"<STR_LIT>" +<EOL>self.material.name +<EOL>"<STR_LIT>" + compound +<EOL>"<STR_LIT>" +<EOL>self.material.name + "<STR_LIT>")<EOL><DEDENT>result = result + (compound,<EOL>other.get_compound_mfr(compound))<EOL><DEDENT>result.Hfr = Hfr<EOL>return result<EOL><DEDENT><DEDENT>elif self._is_compound_mfr_tuple(other):<EOL><INDENT>compound = other[<NUM_LIT:0>]<EOL>index = self.material.get_compound_index(compound)<EOL>mfr = other[<NUM_LIT:1>]<EOL>enthalpy = thermo.H(compound, self._T, mfr)<EOL>result = self.clone()<EOL>result._compound_mfrs[index] += mfr<EOL>result._update_HHV(compound, mfr)<EOL>result._Hfr += enthalpy<EOL>result._P = self._P<EOL>return result<EOL><DEDENT>elif self._is_compound_mfr_temperature_tuple(other):<EOL><INDENT>compound = other[<NUM_LIT:0>]<EOL>index = self.material.get_compound_index(compound)<EOL>mfr = other[<NUM_LIT:1>]<EOL>temperature = other[<NUM_LIT:2>]<EOL>enthalpy = thermo.H(compound, temperature, mfr)<EOL>result = self * <NUM_LIT:1.0><EOL>result._compound_mfrs[index] += mfr<EOL>result.Hfr = self._Hfr + enthalpy<EOL>result._P = self._P<EOL>return result<EOL><DEDENT>else:<EOL><INDENT>raise TypeError("<STR_LIT>")<EOL><DEDENT>

Addition operator (+).

Add this stream (self) and 'other' together, return the result as a
new stream, and leave self unchanged.

:param other: Can can be one of the following:
         1. MaterialStream
            'other' is added to self to create a new stream.
         2. tuple: (compound, mass flow rate)
            The specified mass flow rate of the specified compound is added to \
            self, assuming the added material has the same \
            temperature as self.
         3. tuple: (compound, mass flow rate, temperature)
            The specified mass flow rate of the specified compound at the \
            specified temperature is added to self.

:returns: A new MaterialStream that is the sum of self and 'other'.


<EOL>if type(scalar) is float or type(scalar) is numpy.float64 ortype(scalar) is numpy.float32:<EOL><INDENT>if scalar < <NUM_LIT:0.0>:<EOL><INDENT>raise Exception("<STR_LIT>"<EOL>"<STR_LIT>")<EOL><DEDENT>result = MaterialStream(self.material, self._compound_mfrs *<EOL>scalar, self._P, self._T, self.isCoal,<EOL>self.HHV)<EOL>return result<EOL><DEDENT>else:<EOL><INDENT>raise TypeError("<STR_LIT>")<EOL><DEDENT>

The multiplication operator (*).

Create a new stream by multiplying self with scalar.

:param scalar: The result is a new stream with its content equal to
  self multiplied by a scalar, leaving self unchanged.

:returns: New MaterialStream object.


if self.isCoal:<EOL><INDENT>return self._calculate_Hfr_coal(T)<EOL><DEDENT>Hfr = <NUM_LIT:0.0><EOL>for compound in self.material.compounds:<EOL><INDENT>index = self.material.get_compound_index(compound)<EOL>dHfr = thermo.H(compound, T, self._compound_mfrs[index])<EOL>Hfr = Hfr + dHfr<EOL><DEDENT>return Hfr<EOL>

Calculate the enthalpy flow rate of the stream at the specified
temperature.

:param T: Temperature. [°C]

:returns: Enthalpy flow rate. [kWh/h]


m_C = <NUM_LIT:0>  <EOL>m_H = <NUM_LIT:0>  <EOL>m_O = <NUM_LIT:0>  <EOL>m_N = <NUM_LIT:0>  <EOL>m_S = <NUM_LIT:0>  <EOL>T = <NUM_LIT>  <EOL>Hin = <NUM_LIT:0.0>  <EOL>for compound in self.material.compounds:<EOL><INDENT>index = self.material.get_compound_index(compound)<EOL>formula = compound.split('<STR_LIT:[>')[<NUM_LIT:0>]<EOL>if stoich.element_mass_fraction(formula, '<STR_LIT:C>') == <NUM_LIT:1.0>:<EOL><INDENT>m_C += self._compound_mfrs[index]<EOL>Hin += thermo.H(compound, T, self._compound_mfrs[index])<EOL><DEDENT>elif stoich.element_mass_fraction(formula, '<STR_LIT:H>') == <NUM_LIT:1.0>:<EOL><INDENT>m_H += self._compound_mfrs[index]<EOL>Hin += thermo.H(compound, T, self._compound_mfrs[index])<EOL><DEDENT>elif stoich.element_mass_fraction(formula, '<STR_LIT:O>') == <NUM_LIT:1.0>:<EOL><INDENT>m_O += self._compound_mfrs[index]<EOL>Hin += thermo.H(compound, T, self._compound_mfrs[index])<EOL><DEDENT>elif stoich.element_mass_fraction(formula, '<STR_LIT:N>') == <NUM_LIT:1.0>:<EOL><INDENT>m_N += self._compound_mfrs[index]<EOL>Hin += thermo.H(compound, T, self._compound_mfrs[index])<EOL><DEDENT>elif stoich.element_mass_fraction(formula, '<STR_LIT:S>') == <NUM_LIT:1.0>:<EOL><INDENT>m_S += self._compound_mfrs[index]<EOL>Hin += thermo.H(compound, T, self._compound_mfrs[index])<EOL><DEDENT><DEDENT>m_total = m_C + m_H + m_O + m_N + m_S  <EOL>Hout = <NUM_LIT:0.0>  <EOL>Hout += thermo.H('<STR_LIT>', T, cc(m_C, '<STR_LIT:C>', '<STR_LIT>', '<STR_LIT:C>'))<EOL>Hout += thermo.H('<STR_LIT>', T, cc(m_H, '<STR_LIT:H>', '<STR_LIT>', '<STR_LIT:H>'))<EOL>Hout += thermo.H('<STR_LIT>', T, m_O)<EOL>Hout += thermo.H('<STR_LIT>', T, m_N)<EOL>Hout += thermo.H('<STR_LIT>', T, cc(m_S, '<STR_LIT:S>', '<STR_LIT>', '<STR_LIT:S>'))<EOL>Hout /= m_total<EOL>if self.HHV is None:<EOL><INDENT>HHV = (Hout - Hin) / m_total  <EOL><DEDENT>else:<EOL><INDENT>HHV = self.HHV / <NUM_LIT>  <EOL>HHV *= self.mfr / m_total  <EOL><DEDENT>return HHV + Hout<EOL>

Calculate the enthalpy of formation of the dry-ash-free (daf) component of the coal.

:returns: [kWh/kg daf] enthalpy of formation of daf coal


m_C = <NUM_LIT:0>  <EOL>m_H = <NUM_LIT:0>  <EOL>m_O = <NUM_LIT:0>  <EOL>m_N = <NUM_LIT:0>  <EOL>m_S = <NUM_LIT:0>  <EOL>Hfr = <NUM_LIT:0.0>  <EOL>for compound in self.material.compounds:<EOL><INDENT>index = self.material.get_compound_index(compound)<EOL>formula = compound.split('<STR_LIT:[>')[<NUM_LIT:0>]<EOL>if stoich.element_mass_fraction(formula, '<STR_LIT:C>') == <NUM_LIT:1.0>:<EOL><INDENT>m_C += self._compound_mfrs[index]<EOL><DEDENT>elif stoich.element_mass_fraction(formula, '<STR_LIT:H>') == <NUM_LIT:1.0>:<EOL><INDENT>m_H += self._compound_mfrs[index]<EOL><DEDENT>elif stoich.element_mass_fraction(formula, '<STR_LIT:O>') == <NUM_LIT:1.0>:<EOL><INDENT>m_O += self._compound_mfrs[index]<EOL><DEDENT>elif stoich.element_mass_fraction(formula, '<STR_LIT:N>') == <NUM_LIT:1.0>:<EOL><INDENT>m_N += self._compound_mfrs[index]<EOL><DEDENT>elif stoich.element_mass_fraction(formula, '<STR_LIT:S>') == <NUM_LIT:1.0>:<EOL><INDENT>m_S += self._compound_mfrs[index]<EOL><DEDENT>else:<EOL><INDENT>dHfr = thermo.H(compound, T, self._compound_mfrs[index])<EOL>Hfr += dHfr<EOL><DEDENT><DEDENT>m_total = m_C + m_H + m_O + m_N + m_S  <EOL>y_C = m_C / m_total<EOL>y_H = m_H / m_total<EOL>y_O = m_O / m_total<EOL>y_N = m_N / m_total<EOL>y_S = m_S / m_total<EOL>hmodel = coals.DafHTy()<EOL>H = hmodel.calculate(T=T+<NUM_LIT>, y_C=y_C, y_H=y_H, y_O=y_O, y_N=y_N,<EOL>y_S=y_S) / <NUM_LIT>  <EOL>H298 = hmodel.calculate(T=<NUM_LIT>, y_C=y_C, y_H=y_H, y_O=y_O, y_N=y_N,<EOL>y_S=y_S) / <NUM_LIT>  <EOL>Hdaf = H - H298 + self._DH298  <EOL>Hdaf *= m_total  <EOL>Hfr += Hdaf<EOL>return Hfr<EOL>

Calculate the enthalpy flow rate of the stream at the specified
temperature, in the case of it being coal.

:param T: Temperature. [°C]

:returns: Enthalpy flow rate. [kWh/h]


<EOL>x = list()<EOL>x.append(self._T)<EOL>x.append(self._T + <NUM_LIT>)<EOL>y = list()<EOL>y.append(self._calculate_Hfr(x[<NUM_LIT:0>]) - Hfr)<EOL>y.append(self._calculate_Hfr(x[<NUM_LIT:1>]) - Hfr)<EOL>for i in range(<NUM_LIT:2>, <NUM_LIT:50>):<EOL><INDENT>x.append(x[i-<NUM_LIT:1>] - y[i-<NUM_LIT:1>]*((x[i-<NUM_LIT:1>] - x[i-<NUM_LIT:2>])/(y[i-<NUM_LIT:1>] - y[i-<NUM_LIT:2>])))<EOL>y.append(self._calculate_Hfr(x[i]) - Hfr)<EOL>if abs(y[i-<NUM_LIT:1>]) < <NUM_LIT>:<EOL><INDENT>break<EOL><DEDENT><DEDENT>return x[len(x) - <NUM_LIT:1>]<EOL>

Calculate the temperature of the stream given the specified
enthalpy flow rate using a secant algorithm.

:param H: Enthalpy flow rate. [kWh/h]

:returns: Temperature. [°C]


if not type(value) is tuple:<EOL><INDENT>return False<EOL><DEDENT>elif not len(value) == <NUM_LIT:2>:<EOL><INDENT>return False<EOL><DEDENT>elif not type(value[<NUM_LIT:0>]) is str:<EOL><INDENT>return False<EOL><DEDENT>elif not type(value[<NUM_LIT:1>]) is float andnot type(value[<NUM_LIT:1>]) is numpy.float64 andnot type(value[<NUM_LIT:1>]) is numpy.float32:<EOL><INDENT>return False<EOL><DEDENT>else:<EOL><INDENT>return True<EOL><DEDENT>

Determines whether value is a tuple of the format
(compound(str), mfr(float)).

:param value: The value to be tested.

:returns: True or False


if not type(value) is tuple:<EOL><INDENT>return False<EOL><DEDENT>elif not len(value) == <NUM_LIT:3>:<EOL><INDENT>return False<EOL><DEDENT>elif not type(value[<NUM_LIT:0>]) is str:<EOL><INDENT>return False<EOL><DEDENT>elif not type(value[<NUM_LIT:1>]) is float andnot type(value[<NUM_LIT:1>]) is numpy.float64 andnot type(value[<NUM_LIT:1>]) is numpy.float32:<EOL><INDENT>return False<EOL><DEDENT>elif not type(value[<NUM_LIT:1>]) is float andnot type(value[<NUM_LIT:1>]) is numpy.float64 andnot type(value[<NUM_LIT:1>]) is numpy.float32:<EOL><INDENT>return False<EOL><DEDENT>else:<EOL><INDENT>return True<EOL><DEDENT>

Determines whether value is a tuple of the format
        (compound(str), mfr(float), temperature(float)).

        :param value: The value to be tested.

        :returns: True or False


return self._Hfr<EOL>

Get the enthalpy flow rate of the stream.

:returns: Enthalpy flow rate. [kWh/h]


self._Hfr = Hfr<EOL>self._T = self._calculate_T(Hfr)<EOL>

Set the enthalpy flow rate of the stream to the specified value, and
recalculate it's temperature.

:param H: The new enthalpy flow rate value. [kWh/h]


return self._T<EOL>

Get the temperature of the stream.

:returns: Temperature. [°C]


self._T = T<EOL>self._Hfr = self._calculate_Hfr(T)<EOL>

Set the temperature of the stream to the specified value, and
recalculate it's enthalpy.

:param T: Temperature. [°C]


return self._HHV<EOL>

Get the higher heating value of the stream.

:returns: MJ/kg coal, higher heating value


self._HHV = HHV  <EOL>if self.isCoal:<EOL><INDENT>self._DH298 = self._calculate_DH298_coal()<EOL><DEDENT>

Set the higher heating value of the stream to the specified value, and
recalculate the formation enthalpy of the daf coal.

:param HHV: MJ/kg coal, higher heating value


return self._P<EOL>

Determine the pressure of the stream.

        :returns: Pressure. [atm]


self._P = P<EOL>

Set the pressure of the stream to the specified value.

        :param P: Pressure. [atm]


result = copy.copy(self)<EOL>result._compound_mfrs = copy.deepcopy(self._compound_mfrs)<EOL>return result<EOL>

Create a complete copy of the stream.

        :returns: A new MaterialStream object.


self._compound_mfrs = self._compound_mfrs * <NUM_LIT:0.0><EOL>self._P = <NUM_LIT:1.0><EOL>self._T = <NUM_LIT><EOL>self._H = <NUM_LIT:0.0><EOL>

Set all the compound mass flow rates in the stream to zero.
Set the pressure to 1, the temperature to 25 and the enthalpy to zero.


return self._compound_mfrs / self._compound_mfrs.sum()<EOL>

Determine the assay of the stream.

:returns: Array of mass fractions.


return self._compound_mfrs.sum()<EOL>

Get the mass flow rate of the stream.

:returns: Mass flow rate. [kg/h]


if compound in self.material.compounds:<EOL><INDENT>return self._compound_mfrs[<EOL>self.material.get_compound_index(compound)]<EOL><DEDENT>else:<EOL><INDENT>return <NUM_LIT:0.0><EOL><DEDENT>

Determine the mass flow rate of the specified compound in the stream.

:param compound: Formula and phase of a compound, e.g. "Fe2O3[S1]".

:returns: Mass flow rate. [kg/h]


result = self._compound_mfrs * <NUM_LIT:1.0><EOL>for compound in self.material.compounds:<EOL><INDENT>index = self.material.get_compound_index(compound)<EOL>result[index] = stoich.amount(compound, result[index])<EOL><DEDENT>return result<EOL>

Determine the amount flow rates of all the compounds.

:returns: List of amount flow rates. [kmol/h]


index = self.material.get_compound_index(compound)<EOL>return stoich.amount(compound, self._compound_mfrs[index])<EOL>

Determine the amount flow rate of the specified compound.

:returns: Amount flow rate. [kmol/h]


result = <NUM_LIT:0.0><EOL>for compound in self.material.compounds:<EOL><INDENT>result += self.get_compound_afr(compound)<EOL><DEDENT>return result<EOL>

Determine the sum of amount flow rates of all the compounds.

:returns: Amount flow rate. [kmol/h]


if elements is None:<EOL><INDENT>elements = self.material.elements<EOL><DEDENT>result = numpy.zeros(len(elements))<EOL>for compound in self.material.compounds:<EOL><INDENT>result += self.get_compound_mfr(compound) *stoich.element_mass_fractions(compound, elements)<EOL><DEDENT>return result<EOL>

Determine the mass flow rates of elements in the stream.

:returns: Array of element mass flow rates. [kg/h]


element_symbols = self.material.elements<EOL>element_mfrs = self.get_element_mfrs()<EOL>result = dict()<EOL>for s, mfr in zip(element_symbols, element_mfrs):<EOL><INDENT>result[s] = mfr<EOL><DEDENT>return result<EOL>

Determine the mass flow rates of elements in the stream and return as
a dictionary.

:returns: Dictionary of element symbols and mass flow rates. [kg/h]


result = <NUM_LIT:0.0><EOL>for compound in self.material.compounds:<EOL><INDENT>formula = compound.split('<STR_LIT:[>')[<NUM_LIT:0>]<EOL>result += self.get_compound_mfr(compound) *stoich.element_mass_fraction(formula, element)<EOL><DEDENT>return result<EOL>

Determine the mass flow rate of the specified elements in the stream.

:returns: Mass flow rates. [kg/h]


<EOL>if type(other) is float ortype(other) is numpy.float64 ortype(other) is numpy.float32:<EOL><INDENT>return self._extract_mfr(other)<EOL><DEDENT>elif self._is_compound_mfr_tuple(other):<EOL><INDENT>return self._extract_compound_mfr(other[<NUM_LIT:0>], other[<NUM_LIT:1>])<EOL><DEDENT>elif type(other) is str:<EOL><INDENT>return self._extract_compound(other)<EOL><DEDENT>elif type(other) is Material:<EOL><INDENT>return self._extract_material(other)<EOL><DEDENT>else:<EOL><INDENT>raise TypeError("<STR_LIT>")<EOL><DEDENT>

Extract 'other' from this stream, modifying this stream and returning
the extracted material as a new stream.

:param other: Can be one of the following:

  * float: A mass flow rate equal to other is extracted from self. Self
    is reduced by other and the extracted stream is returned as
    a new stream.
  * tuple (compound, mass): The other tuple specifies the mass flow
    rate of a compound to be extracted. It is extracted from self and
    the extracted mass flow rate is returned as a new stream.
  * string: The 'other' string specifies the compound to be
    extracted. All of the mass flow rate of that compound will be
    removed from self and a new stream created with it.
  * Material: The 'other' material specifies the list of
    compounds to extract.

:returns: New MaterialStream object.


result = "<STR_LIT>" + self.name + "<STR_LIT>"<EOL>result = result + "<STR_LIT>".ljust(<NUM_LIT:20>)<EOL>assay_names = sorted(self.assays.keys())<EOL>for assay_name in assay_names:<EOL><INDENT>result = result + assay_name.ljust(<NUM_LIT:20>)<EOL><DEDENT>result = result + "<STR_LIT:\n>"<EOL>result = result + "<STR_LIT>".ljust(<NUM_LIT:20>)<EOL>assay_names = sorted(self.assays.keys())<EOL>for assay_name in assay_names:<EOL><INDENT>result = result + str(self.solid_densities[assay_name]).ljust(<NUM_LIT:20>)<EOL><DEDENT>result = result + "<STR_LIT:\n>"<EOL>result = result + "<STR_LIT>".ljust(<NUM_LIT:20>)<EOL>assay_names = sorted(self.assays.keys())<EOL>for assay_name in assay_names:<EOL><INDENT>result = result + str(self.H2O_fractions[assay_name]).ljust(<NUM_LIT:20>)<EOL><DEDENT>result = result + "<STR_LIT:\n>"<EOL>for size_class in self.size_classes:<EOL><INDENT>result = result + str(size_class).ljust(<NUM_LIT:20>)<EOL>compound_index = self.get_size_class_index(size_class)<EOL>for assay_name in assay_names:<EOL><INDENT>result = result + str(<EOL>self.assays[assay_name][compound_index]).ljust(<NUM_LIT:20>)<EOL><DEDENT>result = result + "<STR_LIT:\n>"<EOL><DEDENT>return result<EOL>


result = list()<EOL>for line in lines:<EOL><INDENT>line = line.strip()<EOL>line = line.replace("<STR_LIT:\t>", "<STR_LIT:U+0020>")<EOL>while line.find("<STR_LIT:U+0020>") > -<NUM_LIT:1>:<EOL><INDENT>line = line.replace("<STR_LIT:U+0020>", "<STR_LIT:U+0020>")<EOL><DEDENT>result.append(line)<EOL><DEDENT>return result<EOL>

Prepare the lines read from the text file before starting to process
it.


return self.size_classes.index(size_class)<EOL>

Determine the index of the specified size class.

:param size_class: The formula and phase of the specified size class,
  e.g. 'Fe2O3[S1]'.

:returns: The index of the specified size class.


return numpy.zeros(self.size_class_count)<EOL>

Create an empty array to store an assay. The array's length will be
equal to the number of size classes in the material.

:returns: A floating point array.


def add_assay(self, name, solid_density, H2O_fraction, assay):

if not type(solid_density) is float:<EOL><INDENT>raise Exception("<STR_LIT>")<EOL><DEDENT>self.solid_densities[name] = solid_density<EOL>if not type(H2O_fraction) is float:<EOL><INDENT>raise Exception("<STR_LIT>")<EOL><DEDENT>self.H2O_fractions[name] = H2O_fraction<EOL>if not type(assay) is numpy.ndarray:<EOL><INDENT>raise Exception("<STR_LIT>")<EOL><DEDENT>elif not assay.shape == (self.size_class_count,):<EOL><INDENT>raise Exception(<EOL>"<STR_LIT>"<EOL>"<STR_LIT>")<EOL><DEDENT>elif name in self.assays.keys():<EOL><INDENT>raise Exception(<EOL>"<STR_LIT>")<EOL><DEDENT>self.assays[name] = assay<EOL>

Add an assay to the material.

        :param name: The name of the new assay.
        :param assay: A numpy array containing the size class mass fractions
          for the assay. The sequence of the assay's elements must correspond
          to the sequence of the material's size classes.


return sum(self.assays[name])<EOL>

Calculate the total of the specified assay.

:param name: The name of the assay.

:returns: The total mass fraction of the specified assay.


def create_package(self, assay=None, mass=<NUM_LIT:0.0>, normalise=True):

if assay is None:<EOL><INDENT>return MaterialPackage(self, <NUM_LIT:1.0>, <NUM_LIT:0.0>, self.create_empty_assay())<EOL><DEDENT>if normalise:<EOL><INDENT>assay_total = self.get_assay_total(assay)<EOL>if assay_total == <NUM_LIT:0.0>:<EOL><INDENT>assay_total = <NUM_LIT:1.0><EOL><DEDENT><DEDENT>else:<EOL><INDENT>assay_total = <NUM_LIT:1.0><EOL><DEDENT>H2O_mass = mass * self.H2O_fractions[assay]<EOL>solid_mass = mass - H2O_mass<EOL>return MaterialPackage(self,<EOL>self.solid_densities[assay],<EOL>H2O_mass,<EOL>solid_mass * self.assays[assay] / assay_total)<EOL>

Create a MaterialPackage based on the specified parameters.

:param assay: The name of the assay based on which the package
  must be created.
:param mass: [kg] The mass of the package.
:param normalise: Indicates whether the assay must be normalised
  before creating the package.

:returns: The created MaterialPackage.


result = "<STR_LIT>"<EOL>result = result + "<STR_LIT>".ljust(<NUM_LIT>) + self.material.name + "<STR_LIT:\n>"<EOL>result = result + "<STR_LIT>".ljust(<NUM_LIT>) +str(self.get_mass_fraction_solids()) + "<STR_LIT:\n>"<EOL>result = result + "<STR_LIT>".ljust(<NUM_LIT>) +str(self.get_volume_fraction_solids()) + "<STR_LIT:\n>"<EOL>result = result + "<STR_LIT>".ljust(<NUM_LIT>) +str(self.solid_density) + "<STR_LIT:\n>"<EOL>result = result + "<STR_LIT>".ljust(<NUM_LIT>) +str(self.get_density()) + "<STR_LIT:\n>"<EOL>result = result + "<STR_LIT>".ljust(<NUM_LIT>) + str(self.get_mass()) + "<STR_LIT:\n>"<EOL>result = result + "<STR_LIT>".ljust(<NUM_LIT>) + str(self.H2O_mass) + "<STR_LIT:\n>"<EOL>result = result + "<STR_LIT>".ljust(<NUM_LIT>) + str(self.get_volume()) + "<STR_LIT:\n>"<EOL>result = result + "<STR_LIT>"<EOL>for size_class in self.material.size_classes:<EOL><INDENT>index = self.material.get_size_class_index(size_class)<EOL>result = result + str(size_class).ljust(<NUM_LIT>) + str(<EOL>self.size_class_masses[index]) + "<STR_LIT:\n>"<EOL><DEDENT>return result<EOL>

Create a string representation of the object.


<EOL>if type(other) is MaterialPackage:<EOL><INDENT>solid_mass = self.get_solid_mass()<EOL>other_solid_mass = other.get_solid_mass()<EOL>solid_density = (solid_mass + other_solid_mass) /(solid_mass / self.solid_density +<EOL>other_solid_mass / other.solid_density)<EOL>H2O_mass = self.H2O_mass + other.H2O_mass<EOL>if self.material == other.material:<EOL><INDENT>result = MaterialPackage(<EOL>self.material,<EOL>solid_density,<EOL>H2O_mass,<EOL>self.size_class_masses + other.size_class_masses)<EOL>return result<EOL><DEDENT>else:  <EOL><INDENT>result = self.clone()<EOL>result.solid_density = solid_density<EOL>result.H2O_mass = H2O_mass<EOL>for size_class in other.material.size_classes:<EOL><INDENT>if size_class not in self.material.size_classes:<EOL><INDENT>raise Exception(<EOL>"<STR_LIT>" + other.material.name +<EOL>"<STR_LIT>" +<EOL>self.material.name + "<STR_LIT>" +<EOL>size_class + "<STR_LIT>" +<EOL>self.material.name + "<STR_LIT>")<EOL><DEDENT>result = result + (<EOL>size_class, other.get_size_class_mass(size_class))<EOL><DEDENT>return result<EOL><DEDENT><DEDENT>elif self._is_H2O_mass_tuple(other):<EOL><INDENT>mass = other[<NUM_LIT:1>]<EOL>result = self.clone()<EOL>result.H2O_mass += mass<EOL>return result<EOL><DEDENT>elif self._is_size_class_mass_tuple(other):<EOL><INDENT>size_class = other[<NUM_LIT:0>]<EOL>compound_index = self.material.get_size_class_index(size_class)<EOL>mass = other[<NUM_LIT:1>]<EOL>result = self.clone()<EOL>result.size_class_masses[compound_index] =result.size_class_masses[compound_index] + mass<EOL>return result<EOL><DEDENT>else:<EOL><INDENT>raise TypeError("<STR_LIT>")<EOL><DEDENT>

Addition operator (+).
Add self and 'other' together, return the result as a new package,
and leave self unchanged.

:param other: Can can be one of the following:
  1. MaterialPackage: 'other' is added to self to create a new package.
  2. tuple: (size class, mass) The specified mass of the specified size
  class is added to self.

:returns: A new Material package that is the sum of self and 'other'.


<EOL>if type(scalar) is float ortype(scalar) is numpy.float64 ortype(scalar) is numpy.float32:<EOL><INDENT>if scalar < <NUM_LIT:0.0>:<EOL><INDENT>raise Exception(<EOL>"<STR_LIT>"<EOL>"<STR_LIT>")<EOL><DEDENT>result = MaterialPackage(<EOL>self.material,<EOL>self.solid_density,<EOL>self.H2O_mass * scalar, self.size_class_masses * scalar)<EOL>return result<EOL><DEDENT>else:<EOL><INDENT>raise TypeError("<STR_LIT>")<EOL><DEDENT>

The multiplication operator (*).
Create a new package by multiplying self with other.

:param scalar: The result is a new package with its content equal to
  self multiplied by a scalar, leaving self unchanged.

:returns: A new MaterialPackage equal to self package multiplied by
  other.


if not type(value) is tuple:<EOL><INDENT>return False<EOL><DEDENT>elif not len(value) == <NUM_LIT:2>:<EOL><INDENT>return False<EOL><DEDENT>elif not type(value[<NUM_LIT:0>]) is float:<EOL><INDENT>return False<EOL><DEDENT>elif not type(value[<NUM_LIT:1>]) is float andnot type(value[<NUM_LIT:1>]) is numpy.float64 andnot type(value[<NUM_LIT:1>]) is numpy.float32:<EOL><INDENT>return False<EOL><DEDENT>else:<EOL><INDENT>return True<EOL><DEDENT>

Determines whether value is a tuple of the format
(size class(float), mass(float)).

:param value: The value to check.

:returns: Whether the value is a tuple in the required format.


if not type(value) is tuple:<EOL><INDENT>return False<EOL><DEDENT>elif not len(value) == <NUM_LIT:2>:<EOL><INDENT>return False<EOL><DEDENT>elif not type(value[<NUM_LIT:0>]) is str and not value[<NUM_LIT:0>] == "<STR_LIT>":<EOL><INDENT>return False<EOL><DEDENT>elif not type(value[<NUM_LIT:1>]) is float andnot type(value[<NUM_LIT:1>]) is numpy.float64 andnot type(value[<NUM_LIT:1>]) is numpy.float32:<EOL><INDENT>return False<EOL><DEDENT>else:<EOL><INDENT>return True<EOL><DEDENT>


result = copy.copy(self)<EOL>result.size_class_masses = copy.deepcopy(self.size_class_masses)<EOL>return result<EOL>

Create a complete copy of self.

:returns: A MaterialPackage that is identical to self.


self.solid_density = <NUM_LIT:1.0><EOL>self.H2O_mass = <NUM_LIT:0.0><EOL>self.size_class_masses = self.size_class_masses * <NUM_LIT:0.0><EOL>

Set all the size class masses and H20_mass in the package to zero
and the solid_density to 1.0


return self.size_class_masses / self.size_class_masses.sum()<EOL>

Determine the assay of self.

:returns: [mass fractions] An array containing the assay of self.


return self.size_class_masses.sum() + self.H2O_mass<EOL>

Determine the mass of self.

:returns: [kg] The mass of self.


return self.size_class_masses.sum()<EOL>

Determine the solid mass of self.

:returns: [kg] The solid mass of self.


return self.size_class_masses[self.material.get_size_class_index(<EOL>size_class)]<EOL>

Determine the mass of the specified size class in self.

:param size_class: The formula and phase of the size class,
  e.g. 'Fe2O3[S1]'

:returns: [kg] The mass of the size class in self.


return self.get_size_class_mass(size_class) / self.get_solid_mass()<EOL>

Determine the mass fraction of the specified size class in self.

:param size_class: The formula and phase of the size class,
  e.g. Fe2O3[S1]

:returns: The mass fraction of the size class in self.


return self.get_mass() / self.get_volume()<EOL>


return self.get_solid_mass() / self.get_mass()<EOL>

Determine the mass fraction of the solids of self.


return self.H2O_mass / <NUM_LIT:1.0> + self.get_solid_mass() / self.solid_density<EOL>


return <NUM_LIT:1.0> - (self.H2O_mass / <NUM_LIT:1.0>) / self.get_volume()<EOL>

Determine the volume fraction of the solids of self.


<EOL>if type(other) is float ortype(other) is numpy.float64 ortype(other) is numpy.float32:<EOL><INDENT>if other > self.get_mass():<EOL><INDENT>raise Exception(<EOL>"<STR_LIT>"<EOL>"<STR_LIT>")<EOL><DEDENT>fraction_to_subtract = other / self.get_mass()<EOL>result = MaterialPackage(<EOL>self.material,<EOL>self.solid_density,<EOL>self.H2O_mass * fraction_to_subtract,<EOL>self.size_class_masses * fraction_to_subtract)<EOL>self.H2O_mass = self.H2O_mass * (<NUM_LIT:1.0> - fraction_to_subtract)<EOL>self.size_class_masses =self.size_class_masses * (<NUM_LIT:1.0> - fraction_to_subtract)<EOL>return result<EOL><DEDENT>elif self._is_H2O_mass_tuple(other):<EOL><INDENT>if other[<NUM_LIT:1>] > self.H2O_mass:<EOL><INDENT>raise Exception(<EOL>"<STR_LIT>"<EOL>"<STR_LIT>"<EOL>"<STR_LIT>")<EOL><DEDENT>self.H2O_mass = self.H2O_mass - other[<NUM_LIT:1>]<EOL>resultarray = self.size_class_masses * <NUM_LIT:0.0><EOL>result = MaterialPackage(<EOL>self.material, self.solid_density, other[<NUM_LIT:1>], resultarray)<EOL>return result<EOL><DEDENT>elif self._is_size_class_mass_tuple(other):<EOL><INDENT>index = self.material.get_size_class_index(other[<NUM_LIT:0>])<EOL>if other[<NUM_LIT:1>] > self.size_class_masses[index]:<EOL><INDENT>raise Exception(<EOL>"<STR_LIT>"<EOL>"<STR_LIT>"<EOL>"<STR_LIT>")<EOL><DEDENT>self.size_class_masses[index] =self.size_class_masses[index] - other[<NUM_LIT:1>]<EOL>resultarray = self.size_class_masses*<NUM_LIT:0.0><EOL>resultarray[index] = other[<NUM_LIT:1>]<EOL>result = MaterialPackage(<EOL>self.material, self.solid_density, <NUM_LIT:0.0>, resultarray)<EOL>return result<EOL><DEDENT>elif type(other) is str:<EOL><INDENT>index = self.material.get_size_class_index(float(other))<EOL>result = self * <NUM_LIT:0.0><EOL>result.size_class_masses[index] = self.size_class_masses[index]<EOL>self.size_class_masses[index] = <NUM_LIT:0.0><EOL>return result<EOL><DEDENT>else:<EOL><INDENT>raise TypeError("<STR_LIT>")<EOL><DEDENT>

Extract 'other' from self, modifying self and returning the extracted
material as a new package.

:param other: Can be one of the following:

  * float: A mass equal to other is extracted from self. Self is
    reduced by other and the extracted package is returned as a new
    package.
  * tuple (size class, mass): The other tuple specifies the mass of a
    size class to be extracted. It is extracted from self and the
    extracted mass is returned as a new package.
  * string: The 'other' string specifies the size class to be
    extracted. All of the mass of that size class will be removed from
    self and a new package created with it.

:returns: A new material package containing the material that was
  extracted from self.


result = "<STR_LIT>" + self.name + "<STR_LIT>"<EOL>result = result + "<STR_LIT>".ljust(<NUM_LIT:20>)<EOL>assay_names = sorted(self.assays.keys())<EOL>for assay_name in assay_names:<EOL><INDENT>result = result + assay_name.ljust(<NUM_LIT:20>)<EOL><DEDENT>result = result + "<STR_LIT:\n>"<EOL>for size_class in self.size_classes:<EOL><INDENT>result = result + str(size_class).ljust(<NUM_LIT:20>)<EOL>compound_index = self.get_size_class_index(size_class)<EOL>for assay_name in assay_names:<EOL><INDENT>result = result + str(<EOL>self.assays[assay_name][compound_index]).ljust(<NUM_LIT:20>)<EOL><DEDENT>result = result + "<STR_LIT:\n>"<EOL><DEDENT>return result<EOL>


result = list()<EOL>for line in lines:<EOL><INDENT>line = line.strip()<EOL>line = line.replace("<STR_LIT:\t>", "<STR_LIT:U+0020>")<EOL>while line.find("<STR_LIT:U+0020>") > -<NUM_LIT:1>:<EOL><INDENT>line = line.replace("<STR_LIT:U+0020>", "<STR_LIT:U+0020>")<EOL><DEDENT>result.append(line)<EOL><DEDENT>return result<EOL>

Prepare the lines read from the text file before starting to process
it.


return self.size_classes.index(size_class)<EOL>

Determine the index of the specified size class.

:param size_class: The formula and phase of the specified size class,
  e.g. 'Fe2O3[S1]'.

:returns: The index of the specified size class.


return numpy.zeros(self.size_class_count)<EOL>

Create an empty array to store an assay. The array's length will be
equal to the number of size classes in the material.

:returns: A floating point array.


if not type(assay) is numpy.ndarray:<EOL><INDENT>raise Exception("<STR_LIT>")<EOL><DEDENT>elif not assay.shape == (self.size_class_count,):<EOL><INDENT>raise Exception(<EOL>"<STR_LIT>"<EOL>"<STR_LIT>")<EOL><DEDENT>elif name in self.assays.keys():<EOL><INDENT>raise Exception(<EOL>"<STR_LIT>")<EOL><DEDENT>self.assays[name] = assay<EOL>

Add an assay to the material.

:param name: The name of the new assay.
:param assay: A numpy array containing the size class mass fractions
  for the assay. The sequence of the assay's elements must correspond
  to the sequence of the material's size classes.


return sum(self.assays[name])<EOL>

Calculate the total of the specified assay.

:param name: The name of the assay.

:returns: The total mass fraction of the specified assay.


if assay is None:<EOL><INDENT>return MaterialPackage(self, self.create_empty_assay())<EOL><DEDENT>if normalise:<EOL><INDENT>assay_total = self.get_assay_total(assay)<EOL><DEDENT>else:<EOL><INDENT>assay_total = <NUM_LIT:1.0><EOL><DEDENT>return MaterialPackage(self, mass * self.assays[assay] / assay_total)<EOL>

Create a MaterialPackage based on the specified parameters.

:param assay: The name of the assay based on which the package must be
  created.
:param mass: [kg] The mass of the package.
:param normalise: Indicates whether the assay must be normalised before
  creating the package.

:returns: The created MaterialPackage.


result = "<STR_LIT>"<EOL>result = result + "<STR_LIT>".ljust(<NUM_LIT:20>) + self.material.name + "<STR_LIT:\n>"<EOL>result = result + "<STR_LIT>".ljust(<NUM_LIT:20>) + str(self.get_mass()) + "<STR_LIT:\n>"<EOL>result = result + "<STR_LIT>"<EOL>for size_class in self.material.size_classes:<EOL><INDENT>index = self.material.get_size_class_index(size_class)<EOL>result = result + str(size_class).ljust(<NUM_LIT:20>) + str(<EOL>self.size_class_masses[index]) + "<STR_LIT:\n>"<EOL><DEDENT>return result<EOL>

Create a string representation of the object.


<EOL>if type(other) is MaterialPackage:<EOL><INDENT>if self.material == other.material:<EOL><INDENT>result = MaterialPackage(<EOL>self.material,<EOL>self.size_class_masses + other.size_class_masses)<EOL>return result<EOL><DEDENT>else:  <EOL><INDENT>result = self.clone()<EOL>for size_class in other.material.size_classes:<EOL><INDENT>if size_class not in self.material.size_classes:<EOL><INDENT>raise Exception(<EOL>"<STR_LIT>" + other.material.name +<EOL>"<STR_LIT>" +<EOL>self.material.name +<EOL>"<STR_LIT>" + size_class +<EOL>"<STR_LIT>" + self.material.name + "<STR_LIT>")<EOL><DEDENT>result = result + (<EOL>size_class,<EOL>other.get_size_class_mass(size_class))<EOL><DEDENT>return result<EOL><DEDENT><DEDENT>elif self._is_size_class_mass_tuple(other):<EOL><INDENT>size_class = other[<NUM_LIT:0>]<EOL>compound_index = self.material.get_size_class_index(size_class)<EOL>mass = other[<NUM_LIT:1>]<EOL>result = self.clone()<EOL>result.size_class_masses[compound_index] =result.size_class_masses[compound_index] + mass<EOL>return result<EOL><DEDENT>else:<EOL><INDENT>raise TypeError("<STR_LIT>")<EOL><DEDENT>

Addition operator (+).
Add self and 'other' together, return the result as a new package, and
leave self unchanged.

:param other: Can can be one of the following:
  1. MaterialPackage: 'other' is added to self to create a new package.
  2. tuple: (size class, mass): The specified mass of the specified
  size class is added to self.

:returns: A new Material package that is the sum of self and 'other'.


<EOL>if type(scalar) is float ortype(scalar) is numpy.float64 ortype(scalar) is numpy.float32:<EOL><INDENT>if scalar < <NUM_LIT:0.0>:<EOL><INDENT>raise Exception(<EOL>"<STR_LIT>"<EOL>"<STR_LIT>")<EOL><DEDENT>result = MaterialPackage(<EOL>self.material, self.size_class_masses * scalar)<EOL>return result<EOL><DEDENT>else:<EOL><INDENT>raise TypeError("<STR_LIT>")<EOL><DEDENT>

The multiplication operator (*).
Create a new package by multiplying self with other.

:param scalar: The result is a new package with its content equal to
  self multiplied by a scalar, leaving self unchanged.

:returns: A new MaterialPackage equal to self package multiplied by
  other.


if not type(value) is tuple:<EOL><INDENT>return False<EOL><DEDENT>elif not len(value) == <NUM_LIT:2>:<EOL><INDENT>return False<EOL><DEDENT>elif not type(value[<NUM_LIT:0>]) is float:<EOL><INDENT>return False<EOL><DEDENT>elif not type(value[<NUM_LIT:1>]) is float andnot type(value[<NUM_LIT:1>]) is numpy.float64 andnot type(value[<NUM_LIT:1>]) is numpy.float32:<EOL><INDENT>return False<EOL><DEDENT>else:<EOL><INDENT>return True<EOL><DEDENT>

Determines whether value is a tuple of the format
(size class(float), mass(float)).

:param value: The value to check.

:returns: Whether the value is a tuple in the required format.


result = copy.copy(self)<EOL>result.size_class_masses = copy.deepcopy(self.size_class_masses)<EOL>return result<EOL>

Create a complete copy of self.

:returns: A MaterialPackage that is identical to self.


self.size_class_masses = self.size_class_masses * <NUM_LIT:0.0><EOL>

Set all the size class masses in the package to zero.


return self.size_class_masses / self.size_class_masses.sum()<EOL>

Determine the assay of self.

:returns: [mass fractions] An array containing the assay of self.


return self.size_class_masses.sum()<EOL>

Determine the mass of self.

returns: [kg] The mass of self.


return self.size_class_masses[self.material.get_size_class_index(<EOL>size_class)]<EOL>

Determine the mass of the specified size class in self.

:param size_class: The formula and phase of the size class,
  e.g. 'Fe2O3[S1]'

:returns: [kg] The mass of the size class in self.


return self.get_size_class_mass(size_class) / self.get_mass()<EOL>

Determine the mass fraction of the specified size class in self.

:param size_class: The formula and phase of the size class,
  e.g. 'Fe2O3[S1]'

:returns: The mass fraction of the size class in self.


<EOL>if type(other) is float ortype(other) is numpy.float64 ortype(other) is numpy.float32:<EOL><INDENT>if other > self.get_mass():<EOL><INDENT>raise Exception(<EOL>"<STR_LIT>"<EOL>"<STR_LIT>")<EOL><DEDENT>fraction_to_subtract = other / self.get_mass()<EOL>result = MaterialPackage(<EOL>self.material, self.size_class_masses * fraction_to_subtract)<EOL>self.size_class_masses = self.size_class_masses * (<EOL><NUM_LIT:1.0> - fraction_to_subtract)<EOL>return result<EOL><DEDENT>elif self._is_size_class_mass_tuple(other):<EOL><INDENT>index = self.material.get_size_class_index(other[<NUM_LIT:0>])<EOL>if other[<NUM_LIT:1>] > self.size_class_masses[index]:<EOL><INDENT>raise Exception(<EOL>"<STR_LIT>"<EOL>"<STR_LIT>"<EOL>"<STR_LIT>")<EOL><DEDENT>self.size_class_masses[index] =self.size_class_masses[index] - other[<NUM_LIT:1>]<EOL>resultarray = self.size_class_masses*<NUM_LIT:0.0><EOL>resultarray[index] = other[<NUM_LIT:1>]<EOL>result = MaterialPackage(self.material, resultarray)<EOL>return result<EOL><DEDENT>elif type(other) is str:<EOL><INDENT>index = self.material.get_size_class_index(float(other))<EOL>result = self * <NUM_LIT:0.0><EOL>result.size_class_masses[index] = self.size_class_masses[index]<EOL>self.size_class_masses[index] = <NUM_LIT:0.0><EOL>return result<EOL><DEDENT>else:<EOL><INDENT>raise TypeError("<STR_LIT>")<EOL><DEDENT>

Extract 'other' from self, modifying self and returning the extracted
material as a new package.

:param other: Can be one of the following:

  * float: A mass equal to other is extracted from self. Self is
    reduced by other and the extracted package is returned as a new
    package.
  * tuple (size class, mass): The other tuple specifies the mass
    of a size class to be extracted. It is extracted from self and
    the extracted mass is returned as a new package.
  * string: The 'other' string specifies the size class to be
    extracted. All of the mass of that size class will be removed
    from self and a new package created with it.

:returns: A new material package containing the material that was
  extracted from self.


<EOL>if type(other) is MaterialPackage:<EOL><INDENT>if self.material == other.material:<EOL><INDENT>self.size_class_masses =self.size_class_masses + other.size_class_masses<EOL><DEDENT>else:  <EOL><INDENT>for size_class in other.material.size_classes:<EOL><INDENT>if size_class not in self.material.size_classes:<EOL><INDENT>raise Exception(<EOL>"<STR_LIT>" + other.material.name +<EOL>"<STR_LIT>" +<EOL>self.material.name +<EOL>"<STR_LIT>" + size_class +<EOL>"<STR_LIT>" + self.material.name + "<STR_LIT>")<EOL><DEDENT>self.add_to(<EOL>(size_class, other.get_size_class_mass(size_class)))<EOL><DEDENT><DEDENT><DEDENT>elif self._is_size_class_mass_tuple(other):<EOL><INDENT>size_class = other[<NUM_LIT:0>]<EOL>compound_index = self.material.get_size_class_index(size_class)<EOL>mass = other[<NUM_LIT:1>]<EOL>self.size_class_masses[compound_index] =self.size_class_masses[compound_index] + mass<EOL><DEDENT>else:<EOL><INDENT>raise TypeError("<STR_LIT>")<EOL><DEDENT>

Add another psd material package to this material package.

:param other: The other material package.


return self.k(**state) / self.rho(**state) / self.Cp(**state)<EOL>

Calculate the alpha value given the material state.

:param **state: material state

:returns: float


raise NotImplementedError()<EOL>


raise NotImplementedError()<EOL>

Calculate the Cp value given the material state.

:param **state: material state

:returns: float


raise NotImplementedError()<EOL>

Calculate the k value given the material state.

:param **state: material state

:returns: float


raise NotImplementedError()<EOL>

Calculate the mu value given the material state.

:param **state: material state

:returns: float


return self.mu(**state) / self.rho(**state)<EOL>

Calculate the nu value given the material state.

:param **state: material state

:returns: float


raise NotImplementedError()<EOL>

Calculate the rho value given the material state.

:param **state: material state

:returns: float


result = []<EOL>for line in lines:<EOL><INDENT>line = line.strip()<EOL>line = line.replace('<STR_LIT:\t>', '<STR_LIT:U+0020>')<EOL>while line.find('<STR_LIT:U+0020>') > -<NUM_LIT:1>:<EOL><INDENT>line = line.replace('<STR_LIT:U+0020>', '<STR_LIT:U+0020>')<EOL><DEDENT>result.append(line)<EOL><DEDENT>return result<EOL>

Prepare the lines read from the text file before starting to process
it.


element_set = stoich.elements(self.compounds)<EOL>return sorted(list(element_set))<EOL>

Extract an alphabetically sorted list of elements from the compounds of
the material.

:returns: An alphabetically sorted list of elements.


return self.compounds.index(compound)<EOL>

Determine the index of the specified compound.

:param compound: The formula and phase of the specified compound, e.g.
  'Fe2O3[S1]'.

:returns: The index of the specified compound.


return [<NUM_LIT:0>] * self.compound_count<EOL>

Create an empty array to store an assay. The array's length will be
equal to the number of compounds in the material.

:returns: A floating point array.


if not type(assay) is list:<EOL><INDENT>raise Exception('<STR_LIT>')<EOL><DEDENT>elif not len(assay) == self.compound_count:<EOL><INDENT>raise Exception('<STR_LIT>'<EOL>'<STR_LIT>')<EOL><DEDENT>elif name in self.assays:<EOL><INDENT>raise Exception('<STR_LIT>'<EOL>'<STR_LIT>')<EOL><DEDENT>self.assays[name] = assay<EOL>

Add an assay to the material.

:param name: The name of the new assay.
:param assay: A list containing the compound mass fractions for
  the assay. The sequence of the assay's elements must correspond to
  the sequence of the material's compounds.


return sum(self.assays[name])<EOL>

Calculate the total of the specified assay.

:param name: The name of the assay.

:returns: The total mass fraction of the specified assay.


if assay is None:<EOL><INDENT>return MaterialPackage(self, self.create_empty_assay())<EOL><DEDENT>if normalise:<EOL><INDENT>assay_total = self.get_assay_total(assay)<EOL><DEDENT>else:<EOL><INDENT>assay_total = <NUM_LIT:1.0><EOL><DEDENT>masses = [(mass * m) / assay_total for m in self.assays[assay]]<EOL>return MaterialPackage(self, masses)<EOL>

Create a MaterialPackage based on the specified parameters.

:param assay: The name of the assay based on which the package must be
  created.
:param mass: [kg] The mass of the package.
:param normalise: Indicates whether the assay must be normalised before
  creating the package.

:returns: The created MaterialPackage.


<EOL>if type(other) is MaterialPackage:<EOL><INDENT>if self.material == other.material:<EOL><INDENT>result = MaterialPackage(<EOL>self.material,<EOL>self.compound_masses + other.compound_masses)<EOL>return result<EOL><DEDENT>else:  <EOL><INDENT>result = self.clone()<EOL>for compound in other.material.compounds:<EOL><INDENT>if compound not in self.material.compounds:<EOL><INDENT>raise Exception(<EOL>"<STR_LIT>" + other.material.name +<EOL>"<STR_LIT>" +<EOL>self.material.name +<EOL>"<STR_LIT>" + compound +<EOL>"<STR_LIT>" + self.material.name + "<STR_LIT>")<EOL><DEDENT>result += (compound, other.get_compound_mass(compound))<EOL><DEDENT>return result<EOL><DEDENT><DEDENT>elif self._is_compound_mass_tuple(other):<EOL><INDENT>compound = other[<NUM_LIT:0>]<EOL>compound_index = self.material.get_compound_index(compound)<EOL>mass = other[<NUM_LIT:1>]<EOL>result = self.clone()<EOL>result.compound_masses[compound_index] += mass<EOL>return result<EOL><DEDENT>else:<EOL><INDENT>raise TypeError('<STR_LIT>')<EOL><DEDENT>

Add self and 'other' together, return the result as a new package, and
leave self unchanged.

:param other: Can can be one of the following:
  1. MaterialPackage: 'other' is added to self to create a new package.
  2. tuple: (compound, mass): The specified mass of the specified
  compound is added to self.

:returns: A new Material package that is the sum of self and 'other'.


<EOL>if type(scalar) is float:<EOL><INDENT>if scalar < <NUM_LIT:0.0>:<EOL><INDENT>raise Exception(<EOL>'<STR_LIT>'<EOL>'<STR_LIT>')<EOL><DEDENT>result = MaterialPackage(<EOL>self.material, [c * scalar for c in self.compound_masses])<EOL>return result<EOL><DEDENT>else:<EOL><INDENT>raise TypeError('<STR_LIT>')<EOL><DEDENT>

The multiplication operator (*).

Create a new package by multiplying self with scalar.

:param scalar: The result is a new package with its content equal to
  self multiplied by a scalar, leaving self unchanged.

:returns: A new MaterialPackage equal to self package multiplied by
  other.


if not type(value) is tuple:<EOL><INDENT>return False<EOL><DEDENT>elif not len(value) == <NUM_LIT:2>:<EOL><INDENT>return False<EOL><DEDENT>elif not type(value[<NUM_LIT:0>]) is str:<EOL><INDENT>return False<EOL><DEDENT>elif not type(value[<NUM_LIT:1>]) is float:<EOL><INDENT>return False<EOL><DEDENT>else:<EOL><INDENT>return True<EOL><DEDENT>

Determines whether value is a tuple of the format (compound(str),
mass(float)).


result = copy.copy(self)<EOL>result.compound_masses = copy.deepcopy(self.compound_masses)<EOL>return result<EOL>

Create a complete copy of self.

:returns: A MaterialPackage that is identical to self.


self.compound_masses *= <NUM_LIT:0.0><EOL>

Set all the compound masses in the package to zero.


masses_sum = sum(self.compound_masses)<EOL>return [m / masses_sum for m in self.compound_masses]<EOL>

Determine the assay of self.

:returns: [mass fractions] An array containing the assay of self.


return sum(self.compound_masses)<EOL>

Get the mass of the package.

:returns: [kg]


return self.compound_masses[self.material.get_compound_index(compound)]<EOL>

Get the mass of the specified compound in the package.

:param compound: The formula of the compound, e.g. Fe2O3.

:returns: [kg]


return self.get_compound_mass(compound) / self.get_mass()<EOL>

Get the mass fraction of the specified compound in self.

:param compound: The formula and phase of the compound, e.g. Fe2O3.

:returns: []


result = [<NUM_LIT:0>] * len(self.material.elements)<EOL>for compound in self.material.compounds:<EOL><INDENT>c = self.get_compound_mass(compound)<EOL>f = [c * x for x in emf(compound, self.material.elements)]<EOL>result = [v+f[ix] for ix, v in enumerate(result)]<EOL><DEDENT>return result<EOL>

Get the masses of elements in the package.

:returns: [kg] An array of element masses. The sequence of the elements
  in the result corresponds with the sequence of elements in the
  element list of the material.


element_symbols = self.material.elements<EOL>element_masses = self.get_element_masses()<EOL>result = {}<EOL>for s, m in zip(element_symbols, element_masses):<EOL><INDENT>result[s] = m<EOL><DEDENT>return result<EOL>

Determine the masses of elements in the package and return as a
dictionary.

:returns: [kg] A dictionary of element symbols and masses.


result = [<NUM_LIT:0>]<EOL>for compound in self.material.compounds:<EOL><INDENT>c = self.get_compound_mass(compound)<EOL>f = [c * x for x in emf(compound, [element])]<EOL>result = [v+f[ix] for ix, v in enumerate(result)]<EOL><DEDENT>return result[<NUM_LIT:0>]<EOL>

Determine the masses of elements in the package.

:returns: [kg] An array of element masses. The sequence of the elements
  in the result corresponds with the sequence of elements in the
  element list of the material.


<EOL>if type(other) is float:<EOL><INDENT>if other > self.get_mass():<EOL><INDENT>raise Exception('<STR_LIT>'<EOL>'<STR_LIT>')<EOL><DEDENT>fraction_to_subtract = other / self.get_mass()<EOL>result = MaterialPackage(<EOL>self.material,<EOL>[m * fraction_to_subtract for m in self.compound_masses])<EOL>self.compound_masses = [m * (<NUM_LIT:1.0> - fraction_to_subtract)<EOL>for m in self.compound_masses]<EOL>return result<EOL><DEDENT>elif self._is_compound_mass_tuple(other):<EOL><INDENT>index = self.material.get_compound_index(other[<NUM_LIT:0>])<EOL>if other[<NUM_LIT:1>] > self.compound_masses[index]:<EOL><INDENT>raise Exception('<STR_LIT>'<EOL>'<STR_LIT>'<EOL>'<STR_LIT>')<EOL><DEDENT>self.compound_masses[index] -= other[<NUM_LIT:1>]<EOL>resultarray = [<NUM_LIT:0.0>] * len(self.compound_masses)<EOL>resultarray[index] = other[<NUM_LIT:1>]<EOL>result = MaterialPackage(self.material, resultarray)<EOL>return result<EOL><DEDENT>elif type(other) is str:<EOL><INDENT>index = self.material.get_compound_index(other)<EOL>result = self * <NUM_LIT:0.0><EOL>result.compound_masses[index] = self.compound_masses[index]<EOL>self.compound_masses[index] = <NUM_LIT:0.0><EOL>return result<EOL><DEDENT>else:<EOL><INDENT>raise TypeError('<STR_LIT>')<EOL><DEDENT>

Extract 'other' from self, modifying self and returning the extracted
material as a new package.

:param other: Can be one of the following:

  * float: A mass equal to other is extracted from self. Self is
    reduced by other and the extracted package is returned as a
    new package.
  * tuple (compound, mass): The other tuple specifies the mass of
    a compound to be extracted. It is extracted from self and the
    extracted mass is returned as a new package.
  * string: The 'other' string specifies the compound to be extracted.
    All of the mass of that compound will be removed from self and a
    new package created with it.

:returns: A new material package containing the material that was
  extracted from self.


<EOL>if type(other) is MaterialPackage:<EOL><INDENT>if self.material == other.material:<EOL><INDENT>self.compound_masses += other.compound_masses<EOL><DEDENT>else:<EOL><INDENT>for compound in other.material.compounds:<EOL><INDENT>if compound not in self.material.compounds:<EOL><INDENT>raise Exception("<STR_LIT>" + other.material.name +<EOL>"<STR_LIT>" +<EOL>self.material.name +<EOL>"<STR_LIT>" + compound +<EOL>"<STR_LIT>" +<EOL>self.material.name + "<STR_LIT>")<EOL><DEDENT>self.add_to((compound, other.get_compound_mass(compound)))<EOL><DEDENT><DEDENT><DEDENT>elif self._is_compound_mass_tuple(other):<EOL><INDENT>compound = other[<NUM_LIT:0>]<EOL>compound_index = self.material.get_compound_index(compound)<EOL>mass = other[<NUM_LIT:1>]<EOL>self.compound_masses[compound_index] += mass<EOL><DEDENT>else:<EOL><INDENT>raise TypeError('<STR_LIT>')<EOL><DEDENT>

Add another chem material package to this material package.

:param other: The other material package.


if not self._meet_execution_criteria(clock.timestep_ix):<EOL><INDENT>return<EOL><DEDENT>generalLedger.create_transaction(<EOL>self.description if self.description is not None else self.name,<EOL>description='<STR_LIT>',<EOL>tx_date=clock.get_datetime(),<EOL>dt_account=self.dt_account,<EOL>cr_account=self.cr_account,<EOL>source=self.path,<EOL>amount=self.amount)<EOL>

Execute the activity at the current clock cycle.

:param clock: The clock containing the current execution time and
  period information.
:param generalLedger: The general ledger into which to create the
  transactions.


return [self.dt_account, self.cr_account]<EOL>

Retrieve the general ledger accounts referenced in this instance.

:returns: The referenced accounts.


def prepare_to_run(self, clock, period_count):

super(BasicLoanActivity, self).prepare_to_run(clock, period_count)<EOL>self._months_executed = <NUM_LIT:0><EOL>self._amount_left = self.amount<EOL>

Prepare the activity for execution.

:param clock: The clock containing the execution start time and
  execution period information.
:param period_count: The total amount of periods this activity will be
  requested to be run for.


if not self._meet_execution_criteria(clock.timestep_ix):<EOL><INDENT>return<EOL><DEDENT>if self.description is None:<EOL><INDENT>tx_name = self.name<EOL><DEDENT>else:<EOL><INDENT>tx_name = self.description<EOL><DEDENT>if self._months_executed == <NUM_LIT:0>:<EOL><INDENT>generalLedger.create_transaction(<EOL>tx_name,<EOL>description='<STR_LIT>',<EOL>tx_date=clock.get_datetime(),<EOL>dt_account=self.bank_account,<EOL>cr_account=self.loan_account,<EOL>source=self.path,<EOL>amount=self.amount)<EOL><DEDENT>else:<EOL><INDENT>curr_interest_amount = (self._amount_left *<EOL>self.interest_rate) / <NUM_LIT><EOL>generalLedger.create_transaction(<EOL>tx_name,<EOL>description='<STR_LIT>',<EOL>tx_date=clock.get_datetime(),<EOL>dt_account=self.interest_account,<EOL>cr_account=self.loan_account,<EOL>source=self.path,<EOL>amount=curr_interest_amount)<EOL>generalLedger.create_transaction(<EOL>tx_name,<EOL>description='<STR_LIT>',<EOL>tx_date=clock.get_datetime(),<EOL>dt_account=self.loan_account,<EOL>cr_account=self.bank_account,<EOL>source=self.path,<EOL>amount=self._monthly_payment)<EOL>self._amount_left += curr_interest_amount - self._monthly_payment<EOL><DEDENT>self._months_executed += self.interval<EOL>


return [<EOL>self.bank_account,<EOL>self.loan_account,<EOL>self.interest_account]<EOL>


self._parent_path = value<EOL>self.path = value + r'<STR_LIT:/>' + self.name<EOL>

Set the parent path and the path from the new parent path.

:param value: The path to the object's parent


if self.start_period_ix == -<NUM_LIT:1> and self.start_datetime != datetime.min:<EOL><INDENT>for i in range(<NUM_LIT:0>, period_count):<EOL><INDENT>if clock.get_datetime_at_period_ix(i) > self.start_datetime:<EOL><INDENT>self.start_period_ix = i<EOL>break<EOL><DEDENT><DEDENT><DEDENT>if self.start_period_ix == -<NUM_LIT:1>:<EOL><INDENT>self.start_period_ix = <NUM_LIT:0><EOL><DEDENT>if self.period_count == -<NUM_LIT:1> and self.end_datetime != datetime.max:<EOL><INDENT>for i in range(<NUM_LIT:0>, period_count):<EOL><INDENT>if clock.get_datetime_at_period_ix(i) > self.end_datetime:<EOL><INDENT>self.period_count = i - self.start_period_ix<EOL>break<EOL><DEDENT><DEDENT><DEDENT>if self.period_count != -<NUM_LIT:1>:<EOL><INDENT>self.end_period_ix = self.start_period_ix + self.period_count<EOL><DEDENT>else:<EOL><INDENT>self.end_period_ix = self.start_period_ix + period_count<EOL><DEDENT>


return []<EOL>


self._parent_path = value<EOL>self.path = value + r'<STR_LIT:/>' + self.name<EOL>self._update_childrens_parent_path()<EOL>

Set the parent path and the path from the new parent path.

:param value: The path to the object's parent.


def create_component(self, name, description=None):

new_comp = Component(name, self.gl, description=description)<EOL>new_comp.set_parent_path(self.path)<EOL>self.components.append(new_comp)<EOL>return new_comp<EOL>

Create a sub component in the business component.

:param name: The new component's name.
:param description: The new component's description.

:returns: The created component.


component_to_remove = None<EOL>for c in self.components:<EOL><INDENT>if c.name == name:<EOL><INDENT>component_to_remove = c<EOL><DEDENT><DEDENT>if component_to_remove is not None:<EOL><INDENT>self.components.remove(component_to_remove)<EOL><DEDENT>

Remove a sub component from the component.

:param name: The name of the component to remove.


return [c for c in self.components if c.name == name][<NUM_LIT:0>]<EOL>

Retrieve a child component given its name.

:param name: The name of the component.

:returns: The component.


self.gl.structure.validate_account_names(<EOL>activity.get_referenced_accounts())<EOL>self.activities.append(activity)<EOL>activity.set_parent_path(self.path)<EOL>

Add an activity to the component.

:param activity: The activity.


return [a for a in self.activities if a.name == name][<NUM_LIT:0>]<EOL>

Retrieve an activity given its name.

:param name: The name of the activity.

:returns: The activity.


for c in self.components:<EOL><INDENT>c.prepare_to_run(clock, period_count)<EOL><DEDENT>for a in self.activities:<EOL><INDENT>a.prepare_to_run(clock, period_count)<EOL><DEDENT>

Prepare the component for execution.

:param clock: The clock containing the execution start time and
  execution period information.
:param period_count: The total amount of periods this activity will be
  requested to be run for.


for c in self.components:<EOL><INDENT>c.run(clock, generalLedger)<EOL><DEDENT>for a in self.activities:<EOL><INDENT>a.run(clock, generalLedger)<EOL><DEDENT>

Execute the component at the current clock cycle.

:param clock: The clock containing the current execution time and
  period information.
:param generalLedger: The general ledger into which to create the
  transactions.


Create a component in the business entity.

:param name: The component's name.
:param description: The component's description.

:returns: The created component.


Remove a component from the entity.

:param name: The name of the component to remove.


self.period_count = period_count<EOL>self._exec_year_end_datetime = clock.get_datetime_at_period_ix(<EOL>period_count)<EOL>self._prev_year_end_datetime = clock.start_datetime<EOL>self._curr_year_end_datetime = clock.start_datetime + relativedelta(<EOL>years=<NUM_LIT:1>)<EOL>del self.gl.transactions[:]<EOL>for c in self.components:<EOL><INDENT>c.prepare_to_run(clock, period_count)<EOL><DEDENT>self.negative_income_tax_total = <NUM_LIT:0><EOL>

Prepare the entity for execution.

:param clock: The clock containing the execution start time and
  execution period information.
:param period_count: The total amount of periods this activity will be
  requested to be run for.


if clock.timestep_ix >= self.period_count:<EOL><INDENT>return<EOL><DEDENT>for c in self.components:<EOL><INDENT>c.run(clock, self.gl)<EOL><DEDENT>self._perform_year_end_procedure(clock)<EOL>

Execute the entity at the current clock cycle.

:param clock: The clock containing the current execution time and
  period information.


def create_entity(self, name, gl_structure, description=None):

new_entity = Entity(name, gl_structure, description=description)<EOL>self.entities.append(new_entity)<EOL>return new_entity<EOL>

Create an entity and add it to the model.

:param name: The entity name.
:param gl_structure: The entity's general ledger structure.
:param description: The entity description.

:returns: The created entity.


entity_to_remove = None<EOL>for e in self.entities:<EOL><INDENT>if e.name == name:<EOL><INDENT>entity_to_remove = e<EOL><DEDENT><DEDENT>if entity_to_remove is not None:<EOL><INDENT>self.entities.remove(entity_to_remove)<EOL><DEDENT>

Remove an entity from the model.

:param name: The name of the entity to remove.


self.clock.reset()<EOL>for e in self.entities:<EOL><INDENT>e.prepare_to_run(self.clock, self.period_count)<EOL><DEDENT>


self.prepare_to_run()<EOL>for i in range(<NUM_LIT:0>, self.period_count):<EOL><INDENT>for e in self.entities:<EOL><INDENT>e.run(self.clock)<EOL><DEDENT>self.clock.tick()<EOL><DEDENT>


T = state['<STR_LIT:T>']<EOL>x = state['<STR_LIT:x>']<EOL>x_total = sum(x.values())<EOL>x = {compound: x[compound]/x_total for compound in x.keys()}<EOL>xg = x.get('<STR_LIT>', <NUM_LIT>) + x.get('<STR_LIT>', <NUM_LIT:0.0>)<EOL>xm = x.get('<STR_LIT>', <NUM_LIT:0.0>) + x.get('<STR_LIT>', <NUM_LIT:0.0>) + x.get('<STR_LIT>', <NUM_LIT:0.0>) +x.get('<STR_LIT>', <NUM_LIT:0.0>) + <NUM_LIT>*x.get('<STR_LIT>', <NUM_LIT:0.0>) + x.get('<STR_LIT>', <NUM_LIT:0.0>) +x.get('<STR_LIT>', <NUM_LIT:0.0>) + <NUM_LIT>*x.get('<STR_LIT>', <NUM_LIT:0.0>) + <NUM_LIT>*x.get('<STR_LIT>', <NUM_LIT:0.0>)<EOL>xa = x.get('<STR_LIT>', <NUM_LIT:0.0>) + x.get('<STR_LIT>', <NUM_LIT:0.0>) + x.get('<STR_LIT>', <NUM_LIT:0.0>)<EOL>norm = <NUM_LIT:1.0> + x.get('<STR_LIT>', <NUM_LIT:0.0>) + x.get('<STR_LIT>', <NUM_LIT:0.0>) +x.get('<STR_LIT>', <NUM_LIT:0.0>) + x.get('<STR_LIT>', <NUM_LIT:0.0>)<EOL>xg_norm = xg / norm<EOL>xm_norm = xm / norm<EOL>xa_norm = xa / norm<EOL>alpha = xm_norm / (xm_norm + xa_norm)<EOL>B0 = <NUM_LIT> + <NUM_LIT>*alpha - <NUM_LIT>*alpha**<NUM_LIT><EOL>B1 = <NUM_LIT> - <NUM_LIT>*alpha + <NUM_LIT>*alpha**<NUM_LIT><EOL>B2 = -<NUM_LIT> + <NUM_LIT>*alpha - <NUM_LIT>*alpha**<NUM_LIT><EOL>B3 = <NUM_LIT> - <NUM_LIT>*alpha + <NUM_LIT>*alpha**<NUM_LIT><EOL>B = B0 + B1*xg_norm + B2*xg_norm**<NUM_LIT> + B3*xg_norm**<NUM_LIT><EOL>A = exp(-<NUM_LIT>*B - <NUM_LIT>)<EOL>result = A*T*exp(<NUM_LIT>*B/T)  <EOL>return result / <NUM_LIT><EOL>

Calculate dynamic viscosity at the specified temperature and
composition:

:param T: [K] temperature
:param x: [mole fraction] composition dictionary , e.g. \
{'SiO2': 0.25, 'CaO': 0.25, 'MgO': 0.25, 'FeO': 0.25}

:returns: [Pa.s] dynamic viscosity

The **state parameter contains the keyword argument(s) specified above\
that are used to describe the state of the material.


T = state['<STR_LIT:T>']<EOL>y = state['<STR_LIT:y>']<EOL>x = amount_fractions(y)<EOL>return super().calculate(T=T, x=x)<EOL>

Calculate dynamic viscosity at the specified temperature and
composition:

:param T: [K] temperature
:param y: [mass fraction] composition dictionary , e.g. \
{'SiO2': 0.25, 'CaO': 0.25, 'MgO': 0.25, 'FeO': 0.25}

:returns: [Pa.s] dynamic viscosity

The **state parameter contains the keyword argument(s) specified above\
that are used to describe the state of the material.


T = state['<STR_LIT:T>']<EOL>x = state['<STR_LIT:x>']<EOL>compounds_sio2 = ['<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>']<EOL>compounds_cao = ['<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>']<EOL>compounds_al2o3 = ['<STR_LIT>']<EOL>compounds_caf2 = ['<STR_LIT>']<EOL>compounds_na2o = ['<STR_LIT>', '<STR_LIT>']<EOL>compounds_all = (compounds_sio2 + compounds_cao + compounds_al2o3 +<EOL>compounds_caf2 + compounds_na2o)<EOL>if '<STR_LIT>' in x:<EOL><INDENT>x['<STR_LIT>'] = <NUM_LIT> * x['<STR_LIT>']<EOL><DEDENT>if '<STR_LIT>' in x:<EOL><INDENT>x['<STR_LIT>'] = <NUM_LIT> * x['<STR_LIT>']<EOL><DEDENT>if '<STR_LIT>' in x:<EOL><INDENT>x['<STR_LIT>'] = <NUM_LIT> * x['<STR_LIT>']<EOL><DEDENT>x_total = sum([x.get(c, <NUM_LIT:0.0>) for c in compounds_all])<EOL>x = {c: x.get(c, <NUM_LIT:0.0>)/x_total for c in compounds_all}<EOL>x1 = sum([x.get(c, <NUM_LIT:0.0>) for c in compounds_sio2])<EOL>x2 = sum([x.get(c, <NUM_LIT:0.0>) for c in compounds_cao])<EOL>x3 = sum([x.get(c, <NUM_LIT:0.0>) for c in compounds_al2o3])<EOL>x4 = sum([x.get(c, <NUM_LIT:0.0>) for c in compounds_caf2])<EOL>x5 = sum([x.get(c, <NUM_LIT:0.0>) for c in compounds_na2o])<EOL>A = exp(-<NUM_LIT> + <NUM_LIT>*x2 + <NUM_LIT>*x4 + <NUM_LIT>*x5 - <NUM_LIT>*x3)<EOL>B = <NUM_LIT> - <NUM_LIT>*x2 - <NUM_LIT>*x4 - <NUM_LIT>*x5 + <NUM_LIT>*x3<EOL>result = A*T*exp(B/T)  <EOL>return result / <NUM_LIT><EOL>


def _calc_a(self, y_C, y_H, y_O, y_N, y_S):

return <NUM_LIT:1> / (y_C/mm("<STR_LIT:C>") + y_H/mm("<STR_LIT:H>") + y_O/mm("<STR_LIT:O>") + y_N/mm("<STR_LIT:N>") +<EOL>y_S/mm("<STR_LIT:S>"))<EOL>

Calculate the mean atomic weight for the specified element mass
fractions.

:param y_C: Carbon mass fraction
:param y_H: Hydrogen mass fraction
:param y_O: Oxygen mass fraction
:param y_N: Nitrogen mass fraction
:param y_S: Sulphur mass fraction

:returns: [kg/kmol] mean atomic weight

See equation at bottom of page 538 of Merrick1983a.


return exp(z) / ((exp(z) - <NUM_LIT:1.0>) / z) ** <NUM_LIT><EOL>

Calculate the g1 parameter.

:param z: dimensionless temperature


T = state['<STR_LIT:T>']<EOL>y_C = state['<STR_LIT>']<EOL>y_H = state['<STR_LIT>']<EOL>y_O = state['<STR_LIT>']<EOL>y_N = state['<STR_LIT>']<EOL>y_S = state['<STR_LIT>']<EOL>a = self._calc_a(y_C, y_H, y_O, y_N, y_S) / <NUM_LIT:1000>  <EOL>result = (R/a) * (self._calc_g1(<NUM_LIT>/T) + <NUM_LIT:2>*self._calc_g1(<NUM_LIT>/T))<EOL>return result<EOL>

Calculate the heat capacity at the specified temperature and
composition using equation 10 in Merrick1983b.

:param T: [K] temperature
:param y_C: Carbon mass fraction
:param y_H: Hydrogen mass fraction
:param y_O: Oxygen mass fraction
:param y_N: Nitrogen mass fraction
:param y_S: Sulphur mass fraction

:returns: [J/kg/K] heat capacity

The **state parameter contains the keyword argument(s) specified above
that are used to describe the state of the material.


return <NUM_LIT:1> / (exp(z) - <NUM_LIT:1>)<EOL>

Calculate the g0 parameter.

:param z: dimensionless temperature


T = state['<STR_LIT:T>']<EOL>y_C = state['<STR_LIT>']<EOL>y_H = state['<STR_LIT>']<EOL>y_O = state['<STR_LIT>']<EOL>y_N = state['<STR_LIT>']<EOL>y_S = state['<STR_LIT>']<EOL>a = self._calc_a(y_C, y_H, y_O, y_N, y_S) / <NUM_LIT:1000>  <EOL>result = (R/a) * (<NUM_LIT>*self._calc_g0(<NUM_LIT>/T) + <NUM_LIT>*self._calc_g0(<NUM_LIT>/T))<EOL>return result<EOL>

Calculate the enthalpy at the specified temperature and composition
using equation 9 in Merrick1983b.

:param T: [K] temperature
:param y_C: Carbon mass fraction
:param y_H: Hydrogen mass fraction
:param y_O: Oxygen mass fraction
:param y_N: Nitrogen mass fraction
:param y_S: Sulphur mass fraction

:returns: [J/kg] enthalpy

The **state parameter contains the keyword argument(s) specified above
that are used to describe the state of the material.


@staticmethod<EOL><INDENT>def create(dataset, symbol, degree):<DEDENT>

x_vals = dataset.data['<STR_LIT:T>'].tolist()<EOL>y_vals = dataset.data[symbol].tolist()<EOL>coeffs = np.polyfit(x_vals, y_vals, degree)<EOL>result = PolynomialModelT(dataset.material,<EOL>dataset.names_dict[symbol],<EOL>symbol, dataset.display_symbols_dict[symbol],<EOL>dataset.units_dict[symbol],<EOL>None, [dataset.name], coeffs)<EOL>result.state_schema['<STR_LIT:T>']['<STR_LIT>'] = float(min(x_vals))<EOL>result.state_schema['<STR_LIT:T>']['<STR_LIT>'] = float(max(x_vals))<EOL>return result<EOL>

Create a model object from the data set for the property specified by
the supplied symbol, using the specified polynomial degree.

:param dataset: a DataSet object
:param symbol: the symbol of the property to be described, e.g. 'rho'
:param degree: the polynomial degree to use

:returns: a new PolynomialModelT object


super().calculate(**state)<EOL>return np.polyval(self._coeffs, state['<STR_LIT:T>'])<EOL>

Calculate the material physical property at the specified temperature
in the units specified by the object's 'property_units' property.

:param T: [K] temperature

:returns: physical property value


@staticmethod<EOL><INDENT>def create_template(material, path, show=False):<DEDENT>

file_name = '<STR_LIT>' % material.lower()<EOL>file_path = os.path.join(path, file_name)<EOL>with open(file_path, '<STR_LIT:w>', newline='<STR_LIT>') as csvfile:<EOL><INDENT>writer = csv.writer(csvfile, delimiter='<STR_LIT:U+002C>',<EOL>quotechar='<STR_LIT:">', quoting=csv.QUOTE_MINIMAL)<EOL>writer.writerow(['<STR_LIT:Name>', material])<EOL>writer.writerow(['<STR_LIT>', '<STR_LIT>'<EOL>'<STR_LIT>'])<EOL>writer.writerow(['<STR_LIT>', '<STR_LIT>'<EOL>'<STR_LIT>'])<EOL>writer.writerow(['<STR_LIT>', '<STR_LIT>',<EOL>'<STR_LIT>', '<STR_LIT>'])<EOL>writer.writerow(['<STR_LIT:T>', '<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>'])<EOL>writer.writerow(['<STR_LIT>', '<STR_LIT>',<EOL>'<STR_LIT>', '<STR_LIT>'])<EOL>writer.writerow(['<STR_LIT:T>', '<STR_LIT>',<EOL>'<STR_LIT>', '<STR_LIT>'])<EOL>for i in range(<NUM_LIT:10>):<EOL><INDENT>writer.writerow([<NUM_LIT> + i*<NUM_LIT:50>, float(i), <NUM_LIT> + i, <NUM_LIT> + i])<EOL><DEDENT><DEDENT>if show is True:<EOL><INDENT>webbrowser.open_new(file_path)<EOL><DEDENT>

Create a template csv file for a data set.

:param material: the name of the material
:param path: the path of the directory where the file must be written
:param show: a boolean indicating whether the created file should be \
displayed after creation


return self.calculate(**state)<EOL>

For details about this method, please refer to the calculate method.


if not self.state_validator.validate(state):<EOL><INDENT>msg = f"<STR_LIT>"<EOL>msg += f"<STR_LIT>"<EOL>for key, value in self.state_validator.errors.items():<EOL><INDENT>msg += '<STR_LIT>' % (key, value)<EOL><DEDENT>msg = msg[<NUM_LIT:0>:-<NUM_LIT:1>]+'<STR_LIT:.>'<EOL>raise ValidationError(msg)<EOL><DEDENT>

Base calculate method for models.
Validates the material state parameter(s).

:param **state: The material state


super().calculate(**state)<EOL>return <NUM_LIT:1.0> / state["<STR_LIT:T>"]<EOL>

Calculate the thermal expansion coefficient at the specified
temperature:

:param T: [K] temperature

:returns: [1/K] thermal expansion coefficient

The **state parameter contains the keyword argument(s) specified above
that are used to describe the state of the material.


super().calculate(**state)<EOL>return self.mm * self.P / R / state["<STR_LIT:T>"]<EOL>

Calculate the density at the specified temperature.

:param T: [K] temperature

:returns: [kg/m3] density

The **state parameter contains the keyword argument(s) specified above\
that are used to describe the state of the material.


super().calculate(**state)<EOL>return self.mm * state["<STR_LIT:P>"] / R / state["<STR_LIT:T>"]<EOL>

Calculate the density at the specified temperature and pressure.

:param T: [K] temperature
:param P: [Pa] pressure

:returns: [kg/m3] density

The **state parameter contains the keyword argument(s) specified above\
that are used to describe the state of the material.


super().calculate(**state)<EOL>mm_average = <NUM_LIT:0.0><EOL>for compound, molefraction in state["<STR_LIT:x>"].items():<EOL><INDENT>mm_average += molefraction * mm(compound)<EOL><DEDENT>mm_average /= <NUM_LIT><EOL>return mm_average * state["<STR_LIT:P>"] / R / state["<STR_LIT:T>"]<EOL>

Calculate the density at the specified temperature, pressure, and
composition.

:param T: [K] temperature
:param P: [Pa] pressure
:param x: [mole fraction] dictionary of compounds and mole fractions

:returns: [kg/m3] density

The **state parameter contains the keyword argument(s) specified above\
that are used to describe the state of the material.


path = modules[__name__].__file__<EOL>path = realpath(path)<EOL>path = dirname(path)<EOL>return join(path, relative_path)<EOL>

Calculate the full path of the provided relative path.

:param relative_path: relative path (str).
:return: str


return {n: DataSet(_path(f"<STR_LIT>")) for n in namelist}<EOL>

Create a data set dictionary from the provided list of data set names.

:param namelist: list of data set names (str).
:return: {str: DataSet}


def _create_polynomial_model(<EOL>name: str,<EOL>symbol: str,<EOL>degree: int,<EOL>ds: DataSet,<EOL>dss: dict):

ds_name = ds.name.split("<STR_LIT:.>")[<NUM_LIT:0>].lower()<EOL>file_name = f"<STR_LIT>"<EOL>newmod = PolynomialModelT.create(ds, symbol, degree)<EOL>newmod.plot(dss, _path(f"<STR_LIT>"), False)<EOL>newmod.write(_path(f"<STR_LIT>"))<EOL>

Create a polynomial model to describe the specified property based on the
specified data set, and save it to a .json file.

:param name: material name.
:param symbol: property symbol.
:param degree: polynomial degree.
:param ds: the source data set.
:param dss: dictionary of all datasets.


name = "<STR_LIT>"<EOL>namel = name.lower()<EOL>mm = <NUM_LIT>  <EOL>ds_dict = _create_ds_dict([<EOL>"<STR_LIT>",<EOL>"<STR_LIT>"])<EOL>active_ds = "<STR_LIT>"<EOL>model_dict = {<EOL>"<STR_LIT>": IgRhoT(mm, <NUM_LIT>),<EOL>"<STR_LIT>": IgBetaT()}<EOL>model_type = "<STR_LIT>"<EOL>for property in ["<STR_LIT>", "<STR_LIT>", "<STR_LIT:k>"]:<EOL><INDENT>name = f"<STR_LIT>"<EOL>model_dict[property] = PolynomialModelT.read(_path(name))<EOL><DEDENT>material = Material(name, StateOfMatter.gas, model_dict)<EOL>return material, ds_dict<EOL>

Create a dictionary of datasets and a material object for air.

:return: (Material, {str, DataSet})


name = "<STR_LIT>"<EOL>namel = name.lower()<EOL>mm = M("<STR_LIT>")  <EOL>ds_dict = _create_ds_dict([<EOL>"<STR_LIT>"])<EOL>active_ds = "<STR_LIT>"<EOL>model_dict = {<EOL>"<STR_LIT>": IgRhoT(mm, <NUM_LIT>),<EOL>"<STR_LIT>": IgBetaT()}<EOL>model_type = "<STR_LIT>"<EOL>for property in ["<STR_LIT>", "<STR_LIT>", "<STR_LIT:k>"]:<EOL><INDENT>name = f"<STR_LIT>"<EOL>model_dict[property] = PolynomialModelT.read(_path(name))<EOL><DEDENT>material = Material(name, StateOfMatter.gas, model_dict)<EOL>return material, ds_dict<EOL>

Create a dictionary of datasets and a material object for argon.

:return: (Material, {str, DataSet})


name = "<STR_LIT>"<EOL>namel = name.lower()<EOL>mm = M("<STR_LIT>")  <EOL>ds_dict = _create_ds_dict([<EOL>f"<STR_LIT>"])<EOL>active_ds = f"<STR_LIT>"<EOL>model_dict = {<EOL>"<STR_LIT>": IgBetaT()}<EOL>model_type = "<STR_LIT>"<EOL>for property in ["<STR_LIT>", "<STR_LIT>", "<STR_LIT>", "<STR_LIT:k>"]:<EOL><INDENT>name = f"<STR_LIT>"<EOL>model_dict[property] = PolynomialModelT.read(_path(name))<EOL><DEDENT>material = Material(name, StateOfMatter.gas, model_dict)<EOL>return material, ds_dict<EOL>

Create a dictionary of datasets and a material object for ammonia.

:return: (Material, {str, DataSet})


name = "<STR_LIT>"<EOL>namel = name.lower().replace("<STR_LIT:U+0020>", "<STR_LIT:->")<EOL>mm = M("<STR_LIT>")  <EOL>ds_dict = _create_ds_dict([<EOL>f"<STR_LIT>"])<EOL>active_ds = f"<STR_LIT>"<EOL>model_dict = {<EOL>"<STR_LIT>": IgBetaT()}<EOL>model_type = "<STR_LIT>"<EOL>for property in ["<STR_LIT>", "<STR_LIT>", "<STR_LIT>", "<STR_LIT:k>"]:<EOL><INDENT>name = f"<STR_LIT>"<EOL>model_dict[property] = PolynomialModelT.read(_path(name))<EOL><DEDENT>material = Material(name, StateOfMatter.gas, model_dict)<EOL>return material, ds_dict<EOL>

Create a dictionary of datasets and a material object for carbon dioxide.

:return: (Material, {str, DataSet})


name = "<STR_LIT>"<EOL>namel = name.lower().replace("<STR_LIT:U+0020>", "<STR_LIT:->")<EOL>mm = M("<STR_LIT>")  <EOL>ds_dict = _create_ds_dict([<EOL>f"<STR_LIT>"])<EOL>active_ds = f"<STR_LIT>"<EOL>model_dict = {<EOL>"<STR_LIT>": IgRhoT(mm, <NUM_LIT>),<EOL>"<STR_LIT>": IgBetaT()}<EOL>model_type = "<STR_LIT>"<EOL>for property in ["<STR_LIT>", "<STR_LIT>", "<STR_LIT:k>"]:<EOL><INDENT>name = f"<STR_LIT>"<EOL>model_dict[property] = PolynomialModelT.read(_path(name))<EOL><DEDENT>material = Material(name, StateOfMatter.gas, model_dict)<EOL>return material, ds_dict<EOL>

Create a dictionary of datasets and a material object for carbon monoxide.

:return: (Material, {str, DataSet})


Create a dictionary of datasets and a material object for nitrogen.

:return: (Material, {str, DataSet})


Create a dictionary of datasets and a material object for oxygen.

:return: (Material, {str, DataSet})


Create a dictionary of datasets and a material object for water vapour.

:return: (Material, {str, DataSet})


def phi(i, j, mu_i, mu_j):<EOL><INDENT>M_i = M(i)<EOL>M_j = M(j)<EOL>result = (<NUM_LIT:1.0> + (mu_i / mu_j)**<NUM_LIT:0.5> * (M_j / M_i)**<NUM_LIT>)**<NUM_LIT><EOL>result /= (<NUM_LIT> / sqrt(<NUM_LIT>))<EOL>result /= (<NUM_LIT:1.0> + M_i / M_j)**<NUM_LIT:0.5><EOL>return result<EOL><DEDENT>T = state['<STR_LIT:T>']<EOL>x = state['<STR_LIT:x>']<EOL>x_total = sum([<EOL>x for compound, x in x.items()<EOL>if compound in materials])<EOL>x = {<EOL>compound: x[compound]/x_total<EOL>for compound in x.keys()<EOL>if compound in materials}<EOL>result = <NUM_LIT:0.0>  <EOL>mu = {i: materials[i].mu(T=T) for i in x.keys()}<EOL>for i in x.keys():<EOL><INDENT>sum_i = <NUM_LIT:0.0><EOL>for j in x.keys():<EOL><INDENT>if j == i: continue<EOL>sum_i += x[j] * phi(i, j, mu[i], mu[j])<EOL><DEDENT>result += x[i] * mu[i] / (x[i] + sum_i)<EOL><DEDENT>return result<EOL>

Calculate dynamic viscosity at the specified temperature and
composition:

:param T: [K] temperature
:param x: [mole fraction] composition dictionary , e.g.
  {'CO': 0.25, 'CO2': 0.25, 'N2': 0.25, 'O2': 0.25}

:returns: [Pa.s] dynamic viscosity

The **state parameter contains the keyword argument(s) specified above
that are used to describe the state of the material.


T = state['<STR_LIT:T>']<EOL>x = state['<STR_LIT:x>']<EOL>x_total = sum([<EOL>x for compound, x in x.items()<EOL>if compound in materials])<EOL>x = {<EOL>compound: x[compound]/x_total<EOL>for compound in x.keys()<EOL>if compound in materials}<EOL>mu = {i: materials[i].mu(T=T) for i in x.keys()}<EOL>result = sum([mu[i] * x[i] * sqrt(M(i)) for i in x.keys()])<EOL>result /= sum([x[i] * sqrt(M(i)) for i in x.keys()])<EOL>return result<EOL>


T = state["<STR_LIT:T>"]<EOL>x = state["<STR_LIT:x>"]<EOL>x_total = sum([<EOL>x for compound, x in x.items()<EOL>if compound in materials])<EOL>x = {<EOL>compound: x[compound]/x_total<EOL>for compound in x.keys()<EOL>if compound in materials}<EOL>Cp = {i: materials[i].Cp(T=T) for i in x.keys()}<EOL>result = sum([Cp[i] * x[i] * M(i) for i in x.keys()])<EOL>result /= sum([x[i] * M(i) for i in x.keys()])<EOL>return result<EOL>

Calculate dynamic viscosity at the specified temperature and
composition:

:param T: [K] temperature
:param x: [mole fraction] composition dictionary , e.g.
  {"CO": 0.25, "CO2": 0.25, "N2": 0.25, "O2": 0.25}

:returns: [J/kg/K] heat capacity

The **state parameter contains the keyword argument(s) specified above
that are used to describe the state of the material.


return <NUM_LIT:64> / Re_D<EOL>

Calculate the friction factor of laminar flow (l).

:param Re_D: Reynolds number for the specified hydraulic diameter.
:return: Friction factor.

Source: lienhard2018, Fig. 7.6.


return <NUM_LIT:1> / (<NUM_LIT> * log10(Re_D) - <NUM_LIT>)**<NUM_LIT:2><EOL>

Calculate the friction factor of turbulent flow (t) in a smooth duct (s)
for the provided conditions.

:param Re_D: Reynolds number for the specified hydraulic diameter.
:return: Friction factor.

Source: lienhard2018, Eq. 7.42.


def f_tr_Haaland(Re_D, ɛ, D, warn=True):

if warn:<EOL><INDENT>try:<EOL><INDENT>if (ɛ / D) < <NUM_LIT:0.0> or (ɛ / D) > <NUM_LIT>:<EOL><INDENT>raise Warning(<EOL>f"<STR_LIT>")<EOL><DEDENT><DEDENT>except Warning as w:<EOL><INDENT>ex_type, ex_value, ex_traceback = sys.exc_info()<EOL>print(color_warn("<STR_LIT>"), ex_value)<EOL><DEDENT>try:<EOL><INDENT>if Re_D < <NUM_LIT> or Re_D > <NUM_LIT>:<EOL><INDENT>raise Warning(<EOL>f"<STR_LIT>"<EOL>"<STR_LIT>")<EOL><DEDENT><DEDENT>except Warning as w:<EOL><INDENT>ex_type, ex_value, ex_traceback = sys.exc_info()<EOL>print(color_warn("<STR_LIT>"), ex_value)<EOL><DEDENT><DEDENT>return <NUM_LIT:1> / (<NUM_LIT> * log10((<NUM_LIT> / Re_D) + (ɛ / D / <NUM_LIT>)**<NUM_LIT>))**<NUM_LIT:2><EOL>

Calculate the friction factor of turbulent flow (t) in a rough duct (r) for
the provided conditions with Haaland's equation.

:param Re_D: Reynolds number for the specified hydraulic diameter.
:param ɛ: [m] Surface roughness.
:param D: [m] Duct hydraulic diameter.
:return: Friction factor.

Source: lienhard2018, Eq. 7.50.


def cb(f, Re_D, ɛ, D):<EOL><INDENT>"""<STR_LIT>"""<EOL>term1 = ɛ / D / <NUM_LIT><EOL>term2 = <NUM_LIT> / Re_D / sqrt(f)<EOL>return -<NUM_LIT:2> * log10(term1 + term2) - <NUM_LIT:1> / sqrt(f)<EOL><DEDENT>return root(cb, <NUM_LIT>, args=(Re_D, ɛ, D)).x[<NUM_LIT:0>]<EOL>

Calculate the friction factor of turbulent flow (t) a rough duct (r) for
the provided conditions with Colebrook's equation.

:param Re_D: Reynolds number for the specified hydraulic diameter.
:param ɛ: [m] Surface roughness.
:param D: [m] Duct hydraulic diameter.
:return: Friction factor.


return <NUM_LIT:4> * A / P<EOL>

Calculate the hydraulic diameter of a duct.

:param A: [m2] Internal cross sectional area of duct.
:param P: [m] Internal perimeter of duct.
:return: [m] Hydraulic diameter of duct.


return f * (L / D) * (ρ * v**<NUM_LIT:2> / <NUM_LIT:2>)<EOL>

Calculate the pressure drop for turbulent flow in a duct.

:param f: Duct Darcy friction factor.
:param L: [m] Duct length.
:param D: [m] Duct hydraulic diameter.
:param ρ: [kg/m3] Fluid density.
:param v: [m/s] Average fluid velocity.
:return: [Pa] Pressure drop.

Source: lienhard2018, Eq. 3.25.


Tf = statef['<STR_LIT:T>']<EOL>thetar = radians(theta)<EOL>if self._isgas:<EOL><INDENT>self.Tr = Ts - <NUM_LIT> * (Ts - Tf)<EOL>beta = self._fluid.beta(T=Tf)<EOL><DEDENT>else:  <EOL><INDENT>self.Tr = Ts - <NUM_LIT:0.5> * (Ts - Tf)<EOL>beta = self._fluid.beta(T=self.Tr)<EOL><DEDENT>if Ts > Tf:  <EOL><INDENT>if <NUM_LIT:0.0> < theta < <NUM_LIT>:<EOL><INDENT>g = const.g*cos(thetar)<EOL><DEDENT>else:<EOL><INDENT>g = const.g<EOL><DEDENT><DEDENT>else:  <EOL><INDENT>if -<NUM_LIT> < theta < <NUM_LIT:0.0>:<EOL><INDENT>g = const.g*cos(thetar)<EOL><DEDENT>else:<EOL><INDENT>g = const.g<EOL><DEDENT><DEDENT>nu = self._fluid.nu(T=self.Tr)<EOL>alpha = self._fluid.alpha(T=self.Tr)<EOL>Gr = dq.Gr(L, Ts, Tf, beta, nu, g)<EOL>Pr = dq.Pr(nu, alpha)<EOL>Ra = Gr * Pr<EOL>eq = [self.equation_dict[r]<EOL>for r in self.regions if r.contains_point(theta, Ra)][<NUM_LIT:0>]<EOL>return eq(self, Ra, Pr)<EOL>

Calculate the local Nusselt number.

:param L: [m] characteristic length of the heat transfer surface
:param theta: [°] angle of the surface with the vertical
:param Ts: [K] heat transfer surface temperature
:param Tf: [K] bulk fluid temperature

:returns: float


return self.Nu_x(L, theta, Ts, **statef) / <NUM_LIT><EOL>

Calculate the average Nusselt number.

:param L: [m] characteristic length of the heat transfer surface
:param theta: [°] angle of the surface with the vertical
:param Ts: [K] heat transfer surface temperature
:param **statef: [K] bulk fluid temperature

:returns: float


Nu_x = self.Nu_x(L, theta, Ts, **statef)<EOL>k = self._fluid.k(T=self.Tr)<EOL>return Nu_x * k / L<EOL>

Calculate the local heat transfer coefficient.

:param L: [m] characteristic length of the heat transfer surface
:param theta: [°] angle of the surface with the vertical
:param Ts: [K] heat transfer surface temperature
:param Tf: [K] bulk fluid temperature

:returns: [W/m2/K] float


Nu_L = self.Nu_L(L, theta, Ts, **statef)<EOL>k = self._fluid.k(T=self.Tr)<EOL>return Nu_L * k / L<EOL>

Calculate the average heat transfer coefficient.

:param L: [m] characteristic length of the heat transfer surface
:param theta: [°] angle of the surface with the vertical
:param Ts: [K] heat transfer surface temperature
:param Tf: [K] bulk fluid temperature

:returns: [W/m2/K] float


for region in self.regions:<EOL><INDENT>region.plot_region()<EOL><DEDENT>plt.show()<EOL>


def Gr(L: float, Ts: float, Tf: float, beta: float, nu: float, g: float):

return g * beta * (Ts - Tf) * L**<NUM_LIT> / nu**<NUM_LIT><EOL>

Calculate the Grashof number.

:param L: [m] heat transfer surface characteristic length.
:param Ts: [K] heat transfer surface temperature.
:param Tf: [K] bulk fluid temperature.
:param beta: [1/K] fluid coefficient of thermal expansion.
:param nu: [m2/s] fluid kinematic viscosity.

:returns: float

.. math::
    \\mathrm{Gr} = \\frac{g \\beta (Ts - Tinf ) L^3}{\\nu ^2}

Characteristic dimensions:
    * vertical plate: vertical length
    * pipe: diameter
    * bluff body: diameter


def Pr(nu: float, alpha: float) -> float:

return nu / alpha<EOL>

Calculate the Prandtl number.

:param nu: [m2/s] fluid kinematic viscosity / momentum diffusivity.
:param alpha: [m2/s] fluid thermal diffusivity.

:returns: float


def Re(L: float, v: float, nu: float) -> float:

return v * L / nu<EOL>

Calculate the Reynolds number.

:param L: [m] surface characteristic length.
:param v: [m/s] fluid velocity relative to the object.
:param nu: [m2/s] fluid kinematic viscosity.

:returns: float


def Ra(L: float, Ts: float, Tf: float, alpha: float, beta: float, nu: float<EOL>) -> float:

return g * beta * (Ts - Tinf) * L**<NUM_LIT> / (nu * alpha)<EOL>

Calculate the Ralleigh number.

:param L: [m] heat transfer surface characteristic length.
:param Ts: [K] heat transfer surface temperature.
:param Tf: [K] bulk fluid temperature.
:param alpha: [m2/s] fluid thermal diffusivity.
:param beta: [1/K] fluid coefficient of thermal expansion.
:param nu: [m2/s] fluid kinematic viscosity.

:returns: float

Ra = Gr*Pr

Characteristic dimensions:
    * vertical plate: vertical length
    * pipe: diameter
    * bluff body: diameter


def Nu(L: float, h: float, k: float) -> float:

return h * L / k<EOL>

Calculate the Nusselt number.

:param L: [m] heat transfer surface characteristic length.
:param h: [W/K/m2] convective heat transfer coefficient.
:param k: [W/K/m] fluid thermal conductivity.

:returns: float


def Sh(L: float, h: float, D: float) -> float:

return h * L / D<EOL>

Calculate the Sherwood number.

:param L: [m] mass transfer surface characteristic length.
:param h: [m/s] mass transfer coefficient.
:param D: [m2/s] fluid mass diffusivity.

:returns: float


counts = collections.defaultdict(float)<EOL>for group in groups:<EOL><INDENT>for element, count in group.count().items():<EOL><INDENT>counts[element] += count*multiplier<EOL><DEDENT><DEDENT>return counts<EOL>

Update group counts with multiplier

    This is for handling atom counts on groups like (OH)2

    :param groups: iterable of Group/Element
    :param multiplier: the number to multiply by


return mass / molar_mass(compound)<EOL>

Calculate the number of moles in the specified mass of a chemical compound.

:param compound: Formula and phase of a compound, e.g. 'Fe2O3[S1]'. The
  phase may be omitted.
:param mass: [kg]

:returns: Amount. [kmol]


return {compound: amount(compound, masses[compound])<EOL>for compound in masses.keys()}<EOL>

Calculate the amounts from the specified compound masses.

:param masses: [kg] dictionary, e.g. {'SiO2': 3.0, 'FeO': 1.5}

:returns: [kmol] dictionary


n = amounts(masses)<EOL>n_total = sum(n.values())<EOL>return {compound: n[compound]/n_total for compound in n.keys()}<EOL>

Calculate the mole fractions from the specified compound masses.

:param masses: [kg] dictionary, e.g. {'SiO2': 3.0, 'FeO': 1.5}

:returns: [mole fractions] dictionary