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
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
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
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
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
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
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
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
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
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
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
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 ""
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
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
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