def simulate(self): """ docstring for simulate """ # Iteratively run the bent plume model # Create a list for storing model solutions bpm = [] # Create and run the fundamental solution bpm.append(bent_plume_model.Model(self.profile)) bpm[0].simulate(self.X, self.D, self.Vj, self.phi_0, self.theta_0, self.Sj, self.Tj, 1., 'tracer', self.particles, track=False, dt_max=60., sd_max=4*self.X[2]/self.D) # Sort the particles into potential new simulations (p_lists, X, D, T) = sort_particles(bpm[0].particles) # Run each of those simulations for i in range(len(p_lists)): bpm.append(bent_plume_model.Model(self.profile)) bpm[-1].simulate(X[i,:], D[i], None, -np.pi / 2., 0., T[i], 1., 'tracer', p_lists[i], track=False, dt_max=60., sd_max=4*X[i,2]/D[i])
def test_files(): """ Test the input and output of model simulation data Test the methods `save_sim`, `save_txt`, and `load_sim` of the Bent Plume Model `Model` object. """ # Get the model parameters profile, X0, D, Vj, phi_0, theta_0, Sj, Tj, cj, tracers, particles, \ dt_max, sd_max = get_sim_data() # Initialize a stratified plume model `Model` object bpm = bent_plume_model.Model(profile) # Run the simulation bpm.simulate(X0, D, Vj, phi_0, theta_0, Sj, Tj, cj, tracers, particles, track=True, dt_max=dt_max, sd_max=sd_max) # Save the simulation to a netCDF file fname = './output/bpm_data.nc' profile_path = './test_BM54.nc' profile_info = 'Results of ./test_bpm.py script' bpm.save_sim(fname, profile_path, profile_info) # Save the simulation to a text file base_name = './output/bpm_data' bpm.save_txt(base_name, profile_path, profile_info) # Load the simulation data from the netCDF file bpm.load_sim(fname) check_sim(X0, D, Vj, phi_0, theta_0, Sj, Tj, cj, tracers, particles, dt_max, sd_max, bpm) # Initialize a Model object from the netCDF file bpm_load = bent_plume_model.Model(simfile=fname) check_sim(X0, D, Vj, phi_0, theta_0, Sj, Tj, cj, tracers, particles, dt_max, sd_max, bpm)
def test_simulate(): """ Test the `Model.simulate()` method of the Bent Plume Model Run a simulation to test the operation of the `Model.simulate()` method of the Bent Plume Model. """ # Get the model parameters profile, X0, D, Vj, phi_0, theta_0, Sj, Tj, cj, tracers, particles, \ dt_max, sd_max = get_sim_data() # Initialize a stratified plume model `Model` object bpm = bent_plume_model.Model(profile) # Run the simulation bpm.simulate(X0, D, Vj, phi_0, theta_0, Sj, Tj, cj, tracers, particles, track=True, dt_max=dt_max, sd_max=sd_max) # Check that the results are correct check_sim(X0, D, Vj, phi_0, theta_0, Sj, Tj, cj, tracers, particles, dt_max, sd_max, bpm)
def crossflow_plume(fig): """ Define, run, and plot the simulations for a pure bubble plume in crossflow for validation to data in Socolofsky and Adams (2002). """ # Jet initial conditions z0 = 0.64 U0 = 0. phi_0 = -np.pi / 2. theta_0 = 0. D = 0.01 Tj = 21. + 273.15 Sj = 0. cj = 1. chem_name = 'tracer' # Ambient conditions ua = 0.15 T = 0. F = 0. H = 1.0 # Create the correct ambient profile data uj = U0 * np.cos(phi_0) * np.cos(theta_0) vj = U0 * np.cos(phi_0) * np.sin(theta_0) wj = U0 * np.sin(phi_0) profile_fname = './crossflow_plume.nc' profile = get_profile(profile_fname, z0, D, uj, vj, wj, Tj, Sj, ua, T, F, 1., H) # Create a bent plume model simulation object jlm = bpm.Model(profile) # Define the dispersed phase input to the model composition = ['nitrogen', 'oxygen', 'argon', 'carbon_dioxide'] mol_frac = np.array([0.78084, 0.20946, 0.009340, 0.00036]) air = dbm.FluidParticle(composition) particles = [] # Large bubbles Q_N = 0.5 / 60. / 1000. de0 = 0.008 T0 = Tj lambda_1 = 1. (m0, T0, nb0, P, Sa, Ta) = dispersed_phases.initial_conditions(profile, z0, air, mol_frac, Q_N, 1, de0, T0) particles.append( bpm.Particle(0., 0., z0, air, m0, T0, nb0, lambda_1, P, Sa, Ta, K=1., K_T=1., fdis=1.e-6)) # Small bubbles Q_N = 0.5 / 60. / 1000. de0 = 0.0003 T0 = Tj lambda_1 = 1. (m0, T0, nb0, P, Sa, Ta) = dispersed_phases.initial_conditions(profile, z0, air, mol_frac, Q_N, 1, de0, T0) particles.append( bpm.Particle(0., 0., z0, air, m0, T0, nb0, lambda_1, P, Sa, Ta, K=1., K_T=1., fdis=1.e-6)) # Run the simulation jlm.simulate(np.array([0., 0., z0]), D, U0, phi_0, theta_0, Sj, Tj, cj, chem_name, particles, track=True, dt_max=60., sd_max=100.) # Perpare variables for plotting xp = jlm.q[:, 7] / jlm.D yp = jlm.q[:, 9] / jlm.D plt.figure(fig) plt.clf() plt.show() ax1 = plt.subplot(111) ax1.plot(xp, yp, 'b-') ax1.set_xlabel('x / D') ax1.set_ylabel('z / D') ax1.invert_yaxis() ax1.grid(b=True, which='major', color='0.65', linestyle='-') plt.draw() return jlm
def _run_tamoc(self): """ this is the code that actually calls and runs tamoc_output it returns a list of TAMOC droplet objects """ # Release conditions tp = self.tamoc_parameters # Release depth (m) z0 = tp['depth'] # Release diameter (m) D = tp['diameter'] # Release flowrate (bpd) Q = tp['release_flowrate'] # Release temperature (K) T0 = tp['release_temp'] # Release angles of the plume (radians) phi_0 = tp['release_phi'] theta_0 = tp['release_theta'] # Salinity of the continuous phase fluid in the discharge (psu) S0 = tp['discharge_salinity'] # Concentration of passive tracers in the discharge (user-defined) c0 = tp['tracer_concentration'] # List of passive tracers in the discharge chem_name = 'tracer' # Presence or abscence of hydrates in the particles hydrate = tp['hydrate'] # Prescence or abscence of dispersant dispersant = tp['dispersant'] # Reduction in interfacial tension due to dispersant sigma_fac = tp['sigma_fac'] # sigma_fac[0] - for gas; sigma_fac[1] - for liquid # Define liquid phase as inert inert_drop = tp['inert_drop'] # d_50 of gas particles (m) d50_gas = tp['d50_gas'] # d_50 of oil particles (m) d50_oil = tp['d50_oil'] # number of bins in the particle size distribution nbins = tp['nbins'] # Create the ambient profile needed for TAMOC # name of the nc file nc_file = tp['nc_file'] # Define and input the ambient ctd profiles fname_ctd = tp['fname_ctd'] # Define and input the ambient velocity profile ua = tp['ua'] va = tp['va'] wa = tp['wa'] depths = tp['depths'] profile = self.get_profile(nc_file, fname_ctd, ua, va, wa, depths) # Get the release fluid composition fname_composition = './Input/API_2000.csv' composition, mass_frac = self.get_composition(fname_composition) # Read in the user-specified properties for the chemical data data, units = chem.load_data('./Input/API_ChemData.csv') oil = dbm.FluidMixture(composition, user_data=data) # Get the release rates of gas and liquid phase md_gas, md_oil = self.release_flux(oil, mass_frac, profile, T0, z0, Q) print 'md_gas, md_oil', np.sum(md_gas), np.sum(md_oil) # Get the particle list for this composition particles = self.get_particles(composition, data, md_gas, md_oil, profile, d50_gas, d50_oil, nbins, T0, z0, dispersant, sigma_fac, oil, mass_frac, hydrate, inert_drop) print len(particles) print particles # Run the simulation jlm = bpm.Model(profile) jlm.simulate(np.array([0., 0., z0]), D, None, phi_0, theta_0, S0, T0, c0, chem_name, particles, track=False, dt_max=60., sd_max=6000.) # Update the plume object with the nearfiled terminal level answer jlm.q_local.update(jlm.t[-1], jlm.q[-1], jlm.profile, jlm.p, jlm.particles) Mp = np.zeros((len(jlm.particles), len(jlm.q_local.M_p[0]))) gnome_particles = [] gnome_diss_components = [] # print jlm.particles m_tot_nondiss = 0. for i in range(len(jlm.particles)): nb0 = jlm.particles[i].nb0 Tp = jlm.particles[i].T Mp[i, 0:len(jlm.q_local.M_p[i])] = jlm.q_local.M_p[i][:] / jlm.particles[i].nbe mass_flux = np.sum(Mp[i, :] * jlm.particles[i].nb0) density = jlm.particles[i].rho_p radius = (jlm.particles[i].diameter(Mp[i, 0:len(jlm.particles[i].m)], Tp, jlm.q_local.Pa, jlm.q_local.S, jlm.q_local.T)) / 2. position = np.array([jlm.particles[i].x, jlm.particles[i].y, jlm.particles[i].z]) # Calculate the equlibrium and get the particle phase Eq_parti = dbm.FluidMixture(composition=jlm.particles[i].composition[:], user_data=data) # Get the particle equilibrium at the plume termination conditions print 'Insitu' flag_phase_insitu = self.get_phase(jlm.profile, Eq_parti, Mp[i, :]/np.sum(Mp[i, :]), Tp, jlm.particles[i].z) # Get the particle equilibrium at the 15 C and 1 atm print 'Surface' flag_phase_surface = self.get_phase(jlm.profile, Eq_parti, Mp[i, :]/np.sum(Mp[i, :]), 273.15 + 15. , 0.) gnome_particles.append(TamocDroplet(mass_flux, radius, density, position)) for p in gnome_particles: print p m_tot_diss = 0. # Calculate the dissolved particle flux for j in range(len(jlm.chem_names)): diss_mass_flux = jlm.q_local.c_chems[j] * np.pi * jlm.q_local.b**2 * jlm.q_local.V m_tot_diss += diss_mass_flux # print diss_mass_flux position = np.array([jlm.q_local.x, jlm.q_local.y, jlm.q_local.z]) # print position chem_name = jlm.q_local.chem_names[j] # print chem_name gnome_diss_components.append(TamocDissMasses(diss_mass_flux, position,chem_name)) print 'total dissolved mass flux at plume termination' ,m_tot_diss print 'total non ddissolved mass flux at plume termination', m_tot_nondiss print 'total mass flux tracked at plume termination',m_tot_diss+m_tot_nondiss print 'total mass flux released at the orifice',np.sum(md_gas)+ np.sum(md_oil) print 'perccentsge_error', (np.sum(md_gas)+ np.sum(md_oil)-m_tot_diss-m_tot_nondiss)/(np.sum(md_gas)+ np.sum(md_oil))*100. return gnome_particles, gnome_diss_components
comments = ['measured', 'arbitrary crossflow velocity'] ctd.append(data, symbols, units, comments, 0) # Jet initial conditions z0 = 1000. U0 = 0. phi_0 = -np.pi / 2. theta_0 = 0. D = 0.3 Tj = 273.15 + 35. Sj = 0. cj = 1. chem_name = 'tracer' # Create the stratified plume model object bpm = bent_plume_model.Model(ctd) # Create the gas phase particles composition = ['methane', 'ethane', 'propane', 'oxygen'] yk = np.array([0.93, 0.05, 0.02, 0.0]) gas = dbm.FluidParticle(composition) disp_phases = [] # Larger free gas bubbles mb0 = 5. # total mass flux in kg/s de = 0.005 # bubble diameter in m lambda_1 = 0.85 (m0, T0, nb0, P, Sa, Ta) = dispersed_phases.initial_conditions(ctd, z0, gas, yk, mb0, 2, de, Tj) disp_phases.append(
def _update(self): """ Initialize bent_plume_model for simulation run Set up the ambient profile, initial conditions, and model parameters for a new simulation run of the `bent_plume_model`. """ # Get an ambient Profile object self.profile = get_ambient_profile(self.water, self.current, ca=self.ca) # Import the oil with the desired gas-to-oil ratio if self.new_oil: self.oil, self.mass_flux = dbm_utilities.get_oil( self.substance, self.q_oil, self.gor, self.ca, self.q_type) self.new_oil = False # Find the ocean conditions at the release self.T0, self.S0, self.P0 = self.profile.get_values( self.z0, ['temperature', 'salinity', 'pressure']) # Define some of the constant initial conditions self.Sj = 0. self.Tj = self.T0 self.cj = 1. self.tracers = ['tracer'] # Compute the equilibrium mixture properties at the release m, xi, K = self.oil.equilibrium(self.mass_flux, self.Tj, self.P0) # Create the discrete bubble model objects for gas and liquid self.gas = dbm.FluidParticle(self.oil.composition, fp_type=0, delta=self.oil.delta, user_data=self.oil.user_data) self.liq = dbm.FluidParticle(self.oil.composition, fp_type=1, delta=self.oil.delta, user_data=self.oil.user_data) # Compute the bubble and droplet volume size distributions breakup_model = psm.Model(self.profile, self.oil, self.mass_flux, self.z0, self.Tj) breakup_model.simulate(self.d0, model_gas='wang_etal', model_oil='sintef') self.d_gas, self.vf_gas, self.d_liq, self.vf_liq = \ breakup_model.get_distributions(self.num_gas_elements, self.num_oil_elements) # Create the `bent_plume_model` particle list self.disp_phases = [] self.disp_phases += particles(np.sum(m[0, :]), self.d_gas, self.vf_gas, self.profile, self.gas, xi[0, :], 0., 0., self.z0, self.Tj, 0.9, False) self.disp_phases += particles(np.sum(m[1, :]), self.d_liq, self.vf_liq, self.profile, self.liq, xi[1, :], 0., 0., self.z0, self.Tj, 0.98, False) # Set some of the hidden model parameters # TODO: consider which of these should be editable by the user self.track = True self.dt_max = 5. * 3600. self.sd_max = 3. * self.z0 / self.d0 # Create the initialized `bent_plume_model` object self.bpm = bent_plume_model.Model(self.profile) # Set the flag to indicate the model is ready to run self.update = True
spill.plot_all_variables(10) # Change the oil and gas flow rate spill.update_q_oil(30000.) spill.update_gor(1500.) # Re-run the simulation and re-plot the results spill.simulate() spill.plot_state_space(100) spill.plot_all_variables(110) # Try saving the bent plume model solution to the disk save_file = './output/blowout_obj.nc' ctd_file = '../../../test/output/test_BM54.nc' ctd_data = 'Default data in the BM54.nc dataset distributed with TAMOC' print('\nSaving present simulation to: ', save_file) spill.save_sim(save_file, ctd_file, ctd_data) # Try saving an ascii text file for output text_file = './output/blowout_obj.dat' print('\nSaving text output...') spill.save_txt(text_file, ctd_file, ctd_data) # We cannot load a saved simulation back into a Blowout object, but # we could load it into a bent_plume_model.Model object...try this now print('\nLoading saved simulation file...') sim = bpm.Model(simfile=save_file) sim.plot_state_space(200) print('\nDone.')