Beispiel #1
0
def flash_t_p(compounds, mole_fractions, flash_from_pressure,
              flash_from_temperature, flash_to_pressure, flash_to_temperature,
              volume, plus_mw, plus_spec_grav, plus_nbp, viscosity_data,
              standard_pressure, standard_temperature):
    overall_composition = list(zip(compounds, mole_fractions))
    n_pseudos = settings.OIL_CHARACTERIZATION_NUMBER_OF_PSEUDOCOMPONENTS
    adjustAf = settings.OIL_CHARACTERIZATION_ADJUST_ACENTRIC_FACTORS
    adjustZR = settings.OIL_CHARACTERIZATION_ADJUST_RACKETT_PARAMETERS
    assay_name = settings.OIL_CHARACTERIZATION_ASSAY_NAME
    temperatures = [viscosity_data[0], viscosity_data[1]]
    viscosities = [viscosity_data[2], viscosity_data[3]]
    v_t_curve = list(zip(temperatures, viscosities))
    # DWSIM works on the basis of steady-state flow rates.  We calculate all results on a unit time basis here.
    overall_volumetric_flow_rate = volume
    light_ends_composition, heavy_ends_composition = PropertyPackage.split_crude_oil_composition(
        overall_composition)
    oil_characterization = DWSIMWrapper.generate_oil_characterization(
        assay_name, n_pseudos, adjustAf, adjustZR, plus_mw, plus_spec_grav,
        plus_nbp, v_t_curve)
    light_ends_molar_flow_rate_fraction = 1.0
    if ("Heptane plus" in heavy_ends_composition[0]):
        light_ends_molar_flow_rate_fraction -= heavy_ends_composition[0][1]
    results = DWSIMWrapper.flash_t_p(
        flash_from_temperature, flash_from_pressure, flash_to_temperature,
        flash_to_pressure, overall_volumetric_flow_rate,
        light_ends_composition, light_ends_molar_flow_rate_fraction,
        oil_characterization, standard_pressure, standard_temperature)
    # Returns an array that will translate to a 2x1 cell array in Excel
    reformatted_results = np.array([[results[0]], [results[1]]])
    return reformatted_results
Beispiel #2
0
 def test_real_residue_gas_dry_heating_value(self):
     self.compounds = [
         'methane', 'ethane', 'propane', 'i_butane', 'n_butane',
         'i_pentane', 'n_pentane', 'hexane_plus', 'hydrogen_sulfide'
     ]
     self.mole_fractions = [0.2, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1]
     self.recovery_factors = [
         0.0, 0.75, 0.98, 0.98, 0.98, 0.98, 0.98, 0.98, 0.0
     ]
     self.composition = list(
         zip(self.compounds, self.mole_fractions, self.recovery_factors))
     self.property_package = PropertyPackage(self.library, self.composition)
     results = Mixture(self.property_package, self.temperature,
                       self.pressure,
                       self.volume).real_residue_gas_dry_heating_value(
                           self.hydrogen_sulfide)
     self.assertTrue(
         abs(results - 1163.9761) < settings.FLOAT_COMPARE_TOLERANCE)
     results = Mixture(
         self.property_package, self.temperature, self.pressure,
         self.volume).real_residue_gas_dry_heating_value(False)
     self.assertTrue(
         abs(results - 1369.9023) < settings.FLOAT_COMPARE_TOLERANCE)
     results = Mixture(
         self.property_package, self.temperature, 14.65,
         self.volume).real_residue_gas_dry_heating_value(False)
     self.assertTrue(
         abs(results - 1365.1853) < settings.FLOAT_COMPARE_TOLERANCE)
     return
Beispiel #3
0
def liquid_shrinkage_energy(compounds, mole_fractions, recovery_factors,
                            pressure, temperature, volume, component):
    composition = list(zip(compounds, mole_fractions, recovery_factors))
    property_package = PropertyPackage(settings.FLUID_PROPERTY_LIBRARY,
                                       composition)
    results = Mixture(property_package, temperature, pressure,
                      volume).liquid_shrinkage_energy(component)
    return results
Beispiel #4
0
def compressibility_factor(compounds, mole_fractions, recovery_factors,
                           pressure, temperature, volume):
    composition = list(zip(compounds, mole_fractions, recovery_factors))
    property_package = PropertyPackage(settings.FLUID_PROPERTY_LIBRARY,
                                       composition)
    results = Mixture(property_package, temperature, pressure,
                      volume).compressibility_factor()
    return results
Beispiel #5
0
def ideal_gas_dry_heating_value(compounds, mole_fractions, recovery_factors,
                                pressure, temperature, volume):
    composition = list(zip(compounds, mole_fractions, recovery_factors))
    property_package = PropertyPackage(settings.FLUID_PROPERTY_LIBRARY,
                                       composition)
    results = Mixture(property_package, temperature, pressure,
                      volume).ideal_gas_dry_heating_value()
    return results
Beispiel #6
0
 def setUp(self):
     self.compounds = ['methane', 'ethane', 'hydrogen_sulfide']
     self.mole_fractions = [0.5, 0.4, 0.1]
     self.recovery_factors = [0.0, 0.98, 0.0]
     self.library = "GPA_2145"
     self.composition = list(
         zip(self.compounds, self.mole_fractions, self.recovery_factors))
     self.property_package = PropertyPackage(self.library, self.composition)
     self.temperature = 60.0  # F
     self.pressure = 14.696  # psia
     self.volume = 1000.0  # Mcf
     self.hydrogen_sulfide = True
     return
Beispiel #7
0
def residue_gas_energy(compounds,
                       mole_fractions,
                       recovery_factors,
                       pressure,
                       temperature,
                       volume,
                       hydrogen_sulfide=True):
    composition = list(zip(compounds, mole_fractions, recovery_factors))
    property_package = PropertyPackage(settings.FLUID_PROPERTY_LIBRARY,
                                       composition)
    results = Mixture(property_package, temperature, pressure,
                      volume).residue_gas_energy(hydrogen_sulfide)
    return results
Beispiel #8
0
def residue_gas_volume(compounds,
                       mole_fractions,
                       recovery_factors,
                       pressure,
                       temperature,
                       volume,
                       component_name="mixture"):
    composition = list(zip(compounds, mole_fractions, recovery_factors))
    property_package = PropertyPackage(settings.FLUID_PROPERTY_LIBRARY,
                                       composition)
    results = Mixture(property_package, temperature, pressure,
                      volume).residue_gas_volume(component_name)
    return results
Beispiel #9
0
 def _residue_mixture(self, hydrogen_sulfide):
     residue_composition = self._residue_gas_composition()
     h2s_mole_fraction = 0.0
     property_package = PropertyPackage(self.property_package.library, [])
     for name, mole_fraction, recovery_factor in residue_composition:
         package_component = PureComponent((name, mole_fraction, recovery_factor), property_package.library)
         property_package.package_components.append(deepcopy(package_component))
         if name == "hydrogen_sulfide":
             h2s_mole_fraction = mole_fraction
             if hydrogen_sulfide == False:
                 property_package.package_components.pop()
     if hydrogen_sulfide == False:
         for package_component in property_package.package_components:
             package_component.mole_fraction *= (1.0/(1.0 - h2s_mole_fraction))
     residue_mixture = Mixture(property_package, self.temperature_base, self.pressure_base, self.residue_gas_volume())
     return residue_mixture
Beispiel #10
0
 def test_residue_gas_volume(self):
     self.compounds = [
         'methane', 'ethane', 'propane', 'i_butane', 'n_butane',
         'i_pentane', 'n_pentane', 'hexane_plus', 'hydrogen_sulfide'
     ]
     self.mole_fractions = [0.2, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1]
     self.recovery_factors = [
         0.0, 0.75, 0.98, 0.98, 0.98, 0.98, 0.98, 0.98, 0.0
     ]
     self.composition = list(
         zip(self.compounds, self.mole_fractions, self.recovery_factors))
     self.property_package = PropertyPackage(self.library, self.composition)
     results = Mixture(self.property_package, self.temperature,
                       self.pressure, self.volume).residue_gas_volume()
     self.assertTrue(
         abs(results - 337.0000) < settings.FLOAT_COMPARE_TOLERANCE)
     return
Beispiel #11
0
 def test_normalize_mole_fractions(self):
     self.compounds = [
         'methane', 'ethane', 'propane', 'i_butane', 'n_butane',
         'i_pentane', 'n_pentane', 'hexane_plus', 'hydrogen_sulfide'
     ]
     self.mole_fractions = [
         0.65, 0.1, 0.05, 0.025, 0.025, 0.025, 0.025, 0.1, 0.005
     ]
     self.recovery_factors = [
         0.0, 0.75, 0.98, 0.98, 0.98, 0.98, 0.98, 0.98, 0.0
     ]
     self.composition = list(
         zip(self.compounds, self.mole_fractions, self.recovery_factors))
     normalized_mole_fractions = PropertyPackage.normalize_mole_fractions(
         self.composition)
     self.assertTrue(
         abs(normalized_mole_fractions[0] -
             0.6468) < settings.FLOAT_COMPARE_TOLERANCE)
     self.assertTrue(
         abs(normalized_mole_fractions[1] -
             0.0995) < settings.FLOAT_COMPARE_TOLERANCE)
     self.assertTrue(
         abs(normalized_mole_fractions[2] -
             0.0498) < settings.FLOAT_COMPARE_TOLERANCE)
     self.assertTrue(
         abs(normalized_mole_fractions[3] -
             0.0249) < settings.FLOAT_COMPARE_TOLERANCE)
     self.assertTrue(
         abs(normalized_mole_fractions[4] -
             0.0249) < settings.FLOAT_COMPARE_TOLERANCE)
     self.assertTrue(
         abs(normalized_mole_fractions[5] -
             0.0249) < settings.FLOAT_COMPARE_TOLERANCE)
     self.assertTrue(
         abs(normalized_mole_fractions[6] -
             0.0249) < settings.FLOAT_COMPARE_TOLERANCE)
     self.assertTrue(
         abs(normalized_mole_fractions[7] -
             0.0995) < settings.FLOAT_COMPARE_TOLERANCE)
     self.assertTrue(
         abs(normalized_mole_fractions[8] -
             0.0050) < settings.FLOAT_COMPARE_TOLERANCE)
     return
Beispiel #12
0
 def test_ideal_gas_dry_heating_value(self):
     results = Mixture(self.property_package, self.temperature,
                       self.pressure,
                       self.volume).ideal_gas_dry_heating_value()
     self.assertTrue(
         abs(results - 1276.5900) < settings.FLOAT_COMPARE_TOLERANCE)
     results = Mixture(self.property_package, self.temperature, 14.65,
                       self.volume).ideal_gas_dry_heating_value()
     self.assertTrue(
         abs(results - 1272.5941) < settings.FLOAT_COMPARE_TOLERANCE)
     results = Mixture(
         PropertyPackage(self.library, [('methane', 0.5, 0.0),
                                        ('hexane_plus', 0.4, 0.98),
                                        ('hydrogen_sulfide', 0.1, 0.0)]),
         self.temperature, self.pressure,
         self.volume).ideal_gas_dry_heating_value()
     self.assertTrue(
         abs(results - 2620.3980) < settings.FLOAT_COMPARE_TOLERANCE)
     return
 def serialize(cls, material_stream):
     encoded_material_stream = {}
     if isinstance(material_stream, MaterialStream):
         encoded_material_stream["pressure"] = material_stream.pressure
         encoded_material_stream[
             "temperature"] = material_stream.temperature
         encoded_material_stream[
             "composition"] = material_stream.composition
         encoded_material_stream["volume"] = material_stream.volume
         encoded_material_stream[
             "data_source"] = material_stream.data_source
         encoded_material_stream[
             "recovery_factors"] = material_stream.recovery_factors
         encoded_material_stream[
             "property_package"] = PropertyPackage.serialize(
                 material_stream.property_package)
         encoded_components = []
         for component in material_stream.components:
             encoded_components.append(PureComponent.serialize(component))
         encoded_material_stream["components"] = encoded_components
         return json.dumps(encoded_material_stream)
     return ""
Beispiel #14
0
 def real_gas_dry_heating_value(self, hydrogen_sulfide):    # Btu/ft3
     z = 0.0
     ideal_ghv_dry = 0.0
     h2s_mole_fraction = 0.0
     if hydrogen_sulfide == True:
         z = self.compressibility_factor()
         ideal_ghv_dry = self.ideal_gas_dry_heating_value()
     else:
         property_package_without_h2s = PropertyPackage(self.property_package.library, [])
         for package_component in self.property_package.package_components:
             if package_component.name != "hydrogen_sulfide":
                 property_package_without_h2s.package_components.append(deepcopy(package_component))
             else:
                 h2s_mole_fraction = package_component.mole_fraction
         for package_wihtout_h2s_component in property_package_without_h2s.package_components:
             package_wihtout_h2s_component.mole_fraction *= (1.0/(1.0 - h2s_mole_fraction))
         mixture_without_h2s = Mixture(property_package_without_h2s, self.temperature_base, self.pressure_base, self.volume)
         z = mixture_without_h2s.compressibility_factor()
         ideal_ghv_dry = mixture_without_h2s.ideal_gas_dry_heating_value()
     if z > 0.0:
         return ideal_ghv_dry/z
     else:
         return 0.0
Beispiel #15
0
 def test_validate_property_package(self):
     package = PropertyPackage(self.library, self.composition)
     # TODO test for misaligned columns of compounds and mole fractions
     # TODO test for invalid composition (sum(mole_fractions) != 1.0)
     self.assertTrue(package is not None)
     return
Beispiel #16
0
    def post(self):
        form = GasStreamInputForm()
        error = None
        pressure = 0.0
        temperature = 0.0
        composition = {}
        volume = 0.0
        data_source = settings.FLUID_PROPERTY_DATA_SOURCE
        recovery_factors = {}
        input_data_as_json_string = ""

        elif form.is_submitted() == True:
            name = ""
            for key in form.data:
                match_mole_fraction = re.search(r'(\D.+)_mole_fraction', key)
                match_recovery_factor = re.search(r'(\D.+)_recovery_factor', key)
                if match_mole_fraction:
                    name = match_mole_fraction.group(1)
                elif match_recovery_factor:
                    name = match_recovery_factor.group(1)
                if key == 'pressure':
                    pressure = form.data[key]
                elif key == 'temperature':
                    temperature = form.data[key]
                elif key == 'volume':
                    volume = form.data[key]
                elif match_mole_fraction:
                    # filter out entries that are not valid compounds
                    property_package = PropertyPackage(data_source)
                    if name in property_package.compound_names:
                        composition[name] = form.data[key]
                    elif name == "hexane_plus":
                        # Assume 60/30/10 n_hexane, n_heptane, n_octane split
                        # Gas Processors Association Standard 2261, “Analysis for Natural Gas and Similar 
                        # Gaseous Mixtures by Gas Chromatography,” 2000.
                        if property_package.library["name"] == "GPA_2145":
                            composition['n_hexane'] = settings.HEXANE_PLUS_N_HEXANE_FRACTION*form.data[key]
                            composition['n_heptane'] = settings.HEXANE_PLUS_N_HEPTANE_FRACTION*form.data[key]
                            composition['n_octane'] = settings.HEXANE_PLUS_N_OCTANE_FRACTION*form.data[key]
                elif match_recovery_factor:
                    property_package = PropertyPackage(data_source)
                    if name in property_package.compound_names:
                        recovery_factors[name] = form.data[key]
                    elif name == "hexane_plus":
                        if property_package.library["name"] == "GPA_2145":
                            recovery_factors['n_hexane'] = form.data[key]
                            recovery_factors['n_heptane'] = form.data[key]
                            recovery_factors['n_octane'] = form.data[key]
            mole_fraction_sum = 0.0
            for compound in composition:
                mole_fraction_sum += composition[compound]
            if abs(mole_fraction_sum - 1.0) > settings.FLOAT_COMPARE_TOLERANCE:
                return render_template('thermo/gas_stream_input.html', form=form, error=error)
            gas_stream = MaterialStream(pressure, temperature, composition, volume, data_source, recovery_factors)
            input_data_as_json_string = MaterialStream.serialize(gas_stream)
            # TODO Add pricing input data (manual or else automatic from free Quandl stream)
            # Add input data to session as cookie
            session["gas_stream"] = input_data_as_json_string
            if form.validate() == True:
                return redirect('/results')
            else:
                return render_template('thermo/gas_stream_input.html', form=form, error=error)
 def _set_property_package(self):
     self.property_package = PropertyPackage(self.data_source)
     return