def test_dispersion(oil, temp, num_elems, on): ''' Fuel Oil #6 does not exist... ''' disp = NaturalDispersion(waves, water) (sc, time_step) = weathering_data_arrays(disp.array_types, water)[:2] model_time = (sc.spills[0].release_time + timedelta(seconds=time_step)) disp.on = on disp.prepare_for_model_run(sc) disp.prepare_for_model_step(sc, time_step, model_time) disp.weather_elements(sc, time_step, model_time) if on: # print "sc.mass_balance['natural_dispersion']" # print sc.mass_balance['natural_dispersion'] # print "sc.mass_balance['sedimentation']" # print sc.mass_balance['sedimentation'] assert sc.mass_balance['natural_dispersion'] > 0 assert sc.mass_balance['sedimentation'] > 0 else: assert 'natural_dispersion' not in sc.mass_balance assert 'sedimentation' not in sc.mass_balance
def test_dispersion_not_active(oil, temp, num_elems): ''' Fuel Oil #6 does not exist... ''' disp = NaturalDispersion(waves, water) (sc, time_step) = \ weathering_data_arrays(disp.array_types, water)[:2] sc.amount = 10000 model_time = (sc.spills[0].release_time + timedelta(seconds=time_step)) disp.prepare_for_model_run(sc) assert np.all(sc.mass_balance['natural_dispersion'] == 0) assert np.all(sc.mass_balance['sedimentation'] == 0) new_model_time = (sc.spills[0].release_time + timedelta(seconds=3600)) disp.active_range = (new_model_time, InfDateTime('inf')) disp.prepare_for_model_step(sc, time_step, model_time) assert np.all(sc.mass_balance['natural_dispersion'] == 0) assert np.all(sc.mass_balance['sedimentation'] == 0) disp.weather_elements(sc, time_step, model_time) assert np.all(sc.mass_balance['natural_dispersion'] == 0) assert np.all(sc.mass_balance['sedimentation'] == 0)
def test_serialize_deseriailize(): 'test serialize/deserialize for webapi' wind = constant_wind(15., 0) waves = Waves(wind, Water()) e = NaturalDispersion(waves) json_ = e.serialize() json_['waves'] = waves.serialize() # deserialize and ensure the dict's are correct d_ = NaturalDispersion.deserialize(json_) assert d_['waves'] == Waves.deserialize(json_['waves']) d_['waves'] = waves e.update_from_dict(d_) assert e.waves is waves
def test_dispersion_not_active(oil, temp, num_elems): ''' Fuel Oil #6 does not exist... ''' disp = NaturalDispersion(waves, water) (sc, time_step) = \ weathering_data_arrays(disp.array_types, water, element_type=floating(substance=oil))[:2] sc.amount = 10000 model_time = (sc.spills[0].release_time + timedelta(seconds=time_step)) disp.prepare_for_model_run(sc) assert np.all(sc.mass_balance['natural_dispersion'] == 0) assert np.all(sc.mass_balance['sedimentation'] == 0) new_model_time = (sc.spills[0].release_time + timedelta(seconds=3600)) disp.active_range = (new_model_time, InfDateTime('inf')) disp.prepare_for_model_step(sc, time_step, model_time) assert np.all(sc.mass_balance['natural_dispersion'] == 0) assert np.all(sc.mass_balance['sedimentation'] == 0) disp.weather_elements(sc, time_step, model_time) assert np.all(sc.mass_balance['natural_dispersion'] == 0) assert np.all(sc.mass_balance['sedimentation'] == 0)
def test_dispersion(oil, temp, num_elems, on): ''' Fuel Oil #6 does not exist... ''' et = floating(substance=oil) disp = NaturalDispersion(waves, water) (sc, time_step) = weathering_data_arrays(disp.array_types, water, element_type=et)[:2] model_time = (sc.spills[0].release_time + timedelta(seconds=time_step)) disp.on = on disp.prepare_for_model_run(sc) disp.prepare_for_model_step(sc, time_step, model_time) disp.weather_elements(sc, time_step, model_time) if on: # print "sc.mass_balance['natural_dispersion']" # print sc.mass_balance['natural_dispersion'] # print "sc.mass_balance['sedimentation']" # print sc.mass_balance['sedimentation'] assert sc.mass_balance['natural_dispersion'] > 0 assert sc.mass_balance['sedimentation'] > 0 else: assert 'natural_dispersion' not in sc.mass_balance assert 'sedimentation' not in sc.mass_balance
def test_full_run(sample_model_fcn2, oil, temp, dispersed): ''' test dispersion outputs post step for a full run of model. Dump json for 'weathering_model.json' in dump directory ''' model = sample_model_weathering2(sample_model_fcn2, oil, temp) model.environment += [Water(temp), wind, waves] model.weatherers += Evaporation() model.weatherers += Emulsification(waves) model.weatherers += NaturalDispersion() # set make_default_refs to True for objects contained in model after adding # objects to the model model.set_make_default_refs(True) for step in model: for sc in model.spills.items(): if step['step_num'] > 0: # print ("Dispersed: {0}". # format(sc.mass_balance['natural_dispersion'])) # print ("Sedimentation: {0}". # format(sc.mass_balance['sedimentation'])) # print "Completed step: {0}\n".format(step['step_num']) assert (sc.mass_balance['natural_dispersion'] > 0) assert (sc.mass_balance['sedimentation'] > 0) sc = model.spills.items()[0] print (sc.mass_balance['natural_dispersion'], dispersed) assert np.isclose(sc.mass_balance['natural_dispersion'], dispersed, atol=0.001)
def allWeatherers(timeStep, start_time, duration, weatheringSteps, map, uncertain, data_path, curr_path, wind_path, map_path, reFloatHalfLife, windFile, currFile, tidalFile, num_elements, depths, lat, lon, output_path, wind_scale, save_nc, timestep_outputs, weatherers, td): print 'initializing the model:' model = Model(time_step=timeStep, start_time=start_time, duration=duration) print 'adding the map:' map_folder = os.path.join(data_path, map_path) if not(os.path.exists(map_folder)): print('The map folder is incorrectly set:', map_folder) mapfile = get_datafile( os.path.join(map_folder,map) ) model.map = MapFromBNA(mapfile, refloat_halflife=reFloatHalfLife) print 'adding a renderer' model.outputters += Renderer(mapfile, output_path, size=(800, 600), output_timestep=timedelta(hours=1)) if save_nc: nc_outputter = NetCDFOutput(netcdf_file, which_data='most', output_timestep=timedelta(hours=1)) model.outputters += nc_outputter print 'adding a wind mover:' wind_file = get_datafile(os.path.join(data_path, wind_path, windFile)) wind = GridWindMover(wind_file) wind.wind_scale = wind_scale model.movers += wind print 'adding a current mover: ' curr_file = get_datafile(os.path.join(data_path, curr_path, currFile)) model.movers += GridCurrentMover(curr_file, num_method='RK4') if td: random_mover = RandomMover(diffusion_coef=10000) model.movers += random_mover print 'adding spill' model.spills += point_line_release_spill(num_elements=num_elements, start_position=(lon, lat, 0), release_time=start_time, end_release_time=start_time + duration) print 'adding weatherers' water = Water(280.92) wind = constant_wind(20.0, 117, 'knots') waves = Waves(wind, water) model.weatherers += Evaporation(water, wind) model.weatherers += Emulsification(waves) model.weatherers += NaturalDispersion(waves, water) return model
def test_dissolution_droplet_size(oil, temp, num_elems, drop_size, on): ''' Here we are testing that the molar averaged oil/water partition coefficient (K_ow) is getting calculated with reasonable values ''' et = floating(substance=oil) disp = NaturalDispersion(waves, water) diss = Dissolution(waves) (sc, time_step) = weathering_data_arrays(diss.array_types, water, element_type=et, num_elements=num_elems)[:2] print 'num_spills:', len(sc.spills) print 'spill[0] amount:', sc.spills[0].amount, sc.spills[0].units model_time = (sc.spills[0] .release_time + timedelta(seconds=time_step)) print 'model_time = ', model_time print 'time_step = ', time_step # we don't want to query the oil database, but get the sample oil assert sc.spills[0].element_type.substance.record.id is None disp.on = on diss.on = on disp.prepare_for_model_run(sc) diss.prepare_for_model_run(sc) disp.initialize_data(sc, sc.num_released) diss.initialize_data(sc, sc.num_released) for i in range(3): disp.prepare_for_model_step(sc, time_step, model_time) diss.prepare_for_model_step(sc, time_step, model_time) disp.weather_elements(sc, time_step, model_time) diss.weather_elements(sc, time_step, model_time) print 'droplet_avg_size:', sc._data_arrays['droplet_avg_size'] assert np.allclose(sc._data_arrays['droplet_avg_size'], drop_size[i])
def test_full_run_no_evap(sample_model_fcn2, oil, temp, expected_balance): ''' test dissolution outputs post step for a full run of model. Dump json for 'weathering_model.json' in dump directory ''' low_wind = constant_wind(1., 270, 'knots') low_waves = Waves(low_wind, Water(temp)) model = sample_model_weathering2(sample_model_fcn2, oil, temp) model.environment += [Water(temp), low_wind, low_waves] # model.weatherers += Evaporation(Water(temp), low_wind) model.weatherers += NaturalDispersion(low_waves, Water(temp)) model.weatherers += Dissolution(low_waves, low_wind) print ('Model start time: {}, Duration: {}, Time step: {}' .format(model.start_time, model.duration, model.time_step)) for sc in model.spills.items(): print '\nSpill dict keys: ', sc.__dict__.keys() print '\nSpill data arrays: ', sc._data_arrays print 'num spills:', len(sc.spills) print ('spill[0] amount: {} {} ({})' .format(sc.spills[0].amount, sc.spills[0].units, sc.spills[0].substance.name) ) original_amount = sc.spills[0].amount # set make_default_refs to True for objects contained in model after adding # objects to the model model.set_make_default_refs(True) model.setup_model_run() dissolved = [] for step_num, step in enumerate(model): for sc in model.spills.items(): if step['step_num'] > 0: assert (sc.mass_balance['dissolution'] > 0) assert (sc.mass_balance['natural_dispersion'] > 0) assert (sc.mass_balance['sedimentation'] > 0) dissolved.append(sc.mass_balance['dissolution']) print ('\n#Step: {}'.format(step_num)) print ("Dissolved: {0}". format(sc.mass_balance['dissolution'])) print ("Mass: {0}". format(sc._data_arrays['mass'])) print ("Mass Components: {0}". format(sc._data_arrays['mass_components'])) print ('Fraction dissolved after full run: {}' .format(dissolved[-1] / original_amount)) assert dissolved[0] == 0.0 assert np.isclose(dissolved[-1], expected_balance)
def test_full_run_disp_not_active(sample_model_fcn): 'no water/wind/waves object and no evaporation' model = sample_model_weathering(sample_model_fcn, 'oil_6') model.weatherers += NaturalDispersion(on=False) model.outputters += WeatheringOutput() for step in model: ''' if no weatherers, then no weathering output - need to add on/off switch to WeatheringOutput ''' assert 'natural_dispersion' not in step['WeatheringOutput'] assert 'sedimentation' not in step['WeatheringOutput'] assert ('time_stamp' in step['WeatheringOutput'])
def test_dissolution_k_ow(oil, temp, num_elems, k_ow, on): ''' Here we are testing that the molar averaged oil/water partition coefficient (K_ow) is getting calculated with reasonable values Note: for now droplets are calculated in natural dispersion so natural dispersion is required for the dissolution algorithm ''' et = floating(substance=oil) diss = Dissolution(waves, wind) disp = NaturalDispersion(waves, water) (sc, time_step) = weathering_data_arrays(diss.array_types, water, element_type=et, num_elements=num_elems)[:2] print 'num spills:', len(sc.spills) print 'spill[0] amount:', sc.spills[0].amount # we don't want to query the oil database, but get the sample oil assert sc.spills[0].element_type.substance.record.id is None model_time = (sc.spills[0].release_time + timedelta(seconds=time_step)) disp.on = on diss.on = on disp.prepare_for_model_run(sc) diss.prepare_for_model_run(sc) disp.initialize_data(sc, sc.num_released) diss.initialize_data(sc, sc.num_released) disp.prepare_for_model_step(sc, time_step, model_time) diss.prepare_for_model_step(sc, time_step, model_time) disp.weather_elements(sc, time_step, model_time) diss.weather_elements(sc, time_step, model_time) assert all(np.isclose(sc._data_arrays['partition_coeff'], k_ow))
def test_full_run(sample_model_fcn2, oil, temp, expected_balance): ''' test dissolution outputs post step for a full run of model. Dump json for 'weathering_model.json' in dump directory ''' model = sample_model_weathering2(sample_model_fcn2, oil, temp) model.environment += [Water(temp), wind, waves] model.weatherers += Evaporation() model.weatherers += NaturalDispersion() model.weatherers += Dissolution(waves, wind) for sc in model.spills.items(): print sc.__dict__.keys() print sc._data_arrays print 'num spills:', len(sc.spills) print 'spill[0] amount:', sc.spills[0].amount original_amount = sc.spills[0].amount # we don't want to query the oil database, but get the sample oil #assert sc.spills[0].substance.record.id is None # set make_default_refs to True for objects contained in model after adding # objects to the model model.set_make_default_refs(True) model.setup_model_run() dissolved = [] for step in model: for sc in model.spills.items(): if step['step_num'] > 0: assert (sc.mass_balance['dissolution'] > 0) assert (sc.mass_balance['natural_dispersion'] > 0) assert (sc.mass_balance['sedimentation'] > 0) dissolved.append(sc.mass_balance['dissolution']) # print ("\nDissolved: {0}". # format(sc.mass_balance['dissolution'])) # print ("Mass: {0}". # format(sc._data_arrays['mass'])) # print ("Mass Components: {0}". # format(sc._data_arrays['mass_components'])) print ('Fraction dissolved after full run: {}' .format(dissolved[-1] / original_amount)) assert dissolved[0] == 0.0 assert np.isclose(dissolved[-1], expected_balance, rtol=1e-4)
def test_sort_order(): 'test sort order for Dissolution weatherer' wind = constant_wind(15., 0) waves = Waves(wind, Water()) diss = Dissolution(waves, wind) disp = NaturalDispersion(waves=waves, water=waves.water) weathering_data = WeatheringData(water=waves.water) # dissolution is dependent upon droplet distribution generated by # natural dispersion assert weatherer_sort(disp) < weatherer_sort(diss) # dissolution needs to happen before we treat our weathering data assert weatherer_sort(diss) < weatherer_sort(weathering_data)
def test_full_run_dissolution_not_active(sample_model_fcn): 'no water/wind/waves object and no evaporation' model = sample_model_weathering(sample_model_fcn, 'oil_4') model.environment += [Water(288.7), wind, waves] model.weatherers += Evaporation() model.weatherers += NaturalDispersion() model.weatherers += Dissolution(waves=waves, wind=wind, on=False) model.outputters += WeatheringOutput() for step in model: ''' if no weatherers, then no weathering output - need to add on/off switch to WeatheringOutput ''' assert 'dissolution' not in step['WeatheringOutput'] assert ('time_stamp' in step['WeatheringOutput']) print ("Completed step: {0}".format(step['step_num']))
def test_dispersion_not_active(oil, temp, num_elems): ''' Fuel Oil #6 does not exist... ''' disp = NaturalDispersion(waves, water) (sc, time_step) = \ weathering_data_arrays(disp.array_types, water, element_type=floating(substance=oil))[:2] sc.amount = 10000 model_time = (sc.spills[0].get('release_time') + timedelta(seconds=time_step)) disp.prepare_for_model_run(sc) new_model_time = (sc.spills[0].get('release_time') + timedelta(seconds=3600)) disp.active_start = new_model_time disp.prepare_for_model_step(sc, time_step, model_time) disp.weather_elements(sc, time_step, model_time) assert np.all(sc.mass_balance['natural_dispersion'] == 0) assert np.all(sc.mass_balance['sedimentation'] == 0)
def test_bio_degradation_full_run(sample_model_fcn2, oil, temp, expected_balance): ''' test bio degradation outputs post step for a full run of model. Dump json for 'weathering_model.json' in dump directory ''' model = sample_model_weathering2(sample_model_fcn2, oil, temp) # model.duration = timedelta(days=5) model.environment += [Water(temp), wind, waves] model.weatherers += Evaporation() model.weatherers += NaturalDispersion() # model.weatherers += Dissolution(waves) model.weatherers += Biodegradation() for sc in model.spills.items(): print(sc.__dict__.keys()) print(sc._data_arrays) print('num spills:', len(sc.spills)) print('spill[0] amount:', sc.spills[0].amount) original_amount = sc.spills[0].amount # set make_default_refs to True for objects contained in model after adding # objects to the model model.set_make_default_refs(True) model.setup_model_run() bio_degradated = [] for step in model: for sc in model.spills.items(): if step['step_num'] > 0: assert (sc.mass_balance['bio_degradation'] > 0) if 'bio_degradation' in sc.mass_balance: bio_degradated.append(sc.mass_balance['bio_degradation']) print('Bio degradated amount: {}'.format(bio_degradated[-1])) print('Fraction bio degradated after full run: {}'.format( bio_degradated[-1] / original_amount)) assert bio_degradated[0] == 0.0
def make_modelF(timeStep, start_time, duration, weatheringSteps, map, uncertain, data_path, curr_path, wind_path, map_path, reFloatHalfLife, windFile, currFile, num_elements, depths, lat, lon, output_path, wind_scale, save_nc, timestep_outputs, weatherers, td, dif_coef,temp_water): print 'initializing the model:' model = Model(time_step=timeStep, start_time=start_time, duration=duration, uncertain=uncertain) print 'adding the map:' mapfile = get_datafile(os.path.join(data_path, map_path, map)) model.map = MapFromBNA(mapfile, refloat_halflife=reFloatHalfLife) print 'adding a renderer' if save_nc: scripting.remove_netcdf(output_path+'/'+'output.nc') nc_outputter = NetCDFOutput(output_path+'/'+'output.nc', which_data='standard', output_timestep=timedelta(hours=timestep_outputs)) model.outputters += nc_outputter print 'adding a wind mover:' wind_file = get_datafile(os.path.join(data_path, wind_path, windFile)) wind = GridWindMover(wind_file) # wind.wind_scale = wind_scale model.movers += wind print 'adding a current mover:' curr_file = get_datafile(os.path.join(data_path, curr_path, currFile)) model.movers += GridCurrentMover(curr_file, num_method='RK4') if td: random_mover = RandomMover(diffusion_coef=dif_coef) model.movers += random_mover print 'adding spill' model.spills += point_line_release_spill(num_elements=num_elements, start_position=(lon, lat, 0), release_time=start_time, end_release_time=start_time + duration)#, substance='AD04001', amount=9600000, units='kg') if weatherers: print 'adding weatherers' water = Water(temp_water) wind = constant_wind(0.0001, 0, 'knots') waves = Waves(wind, water) model.weatherers += Evaporation(water, wind) # model.weatherers += Emulsification(waves) model.weatherers += NaturalDispersion(waves, water) return model
def make_model(images_dir=os.path.join(base_dir, 'images')): print ('initializing the model') #print (start_date) start_time = start_date model = Model(start_time=start_time, duration=timedelta(days=30), #weathering_substeps = 6, time_step=24 * 3600, uncertain=True) mapfile = get_datafile(os.path.join(base_dir,'gulf.bna')) #mapfile='gulf.bna' print ('adding the map') model.map = MapFromBNA(mapfile, refloat_halflife=6) # hours # # Add the outputters -- render to images, and save out as netCDF # print ('adding renderer') #model.outputters += Renderer(mapfile, # images_dir, #size=(800, 600), #draw_back_to_fore=True) #print ("adding netcdf output") # netcdf_output_file = os.path.join(base_dir,'gulf_output.nc') #scripting.remove_netcdf(netcdf_output_file) # model.outputters += NetCDFOutput(netcdf_output_file, which_data='all', # output_timestep=timedelta(hours=24)) print ("adding shapefile output") # with open("Result {}".format(spill_num), "w") as fp: # fp.write("text") dir_name = "Result {}".format(spill_num) if not os.path.exists(dir_name): os.mkdir(dir_name) for b in range(1, 31, 1): model.outputters += ShapeOutput(os.path.join(base_dir, dir_name, 'gnome_result{id}'.format(id=b)), zip_output=False, output_timestep=timedelta(days=b)) # # Set up the movers: # print ('adding a RandomMover:') model.movers += RandomMover(diffusion_coef=10000) print ('adding a simple wind mover:') # model.movers += constant_wind_mover(5, 315, units='m/s') wind_file = get_datafile(os.path.join(base_dir, 'nc3ECMWF2016.nc')) model.movers += GridWindMover(wind_file) print ('adding a current mover:') # # this is NEMO currents curr_file = get_datafile(os.path.join(base_dir, 'current2016nc3.nc')) model.movers += GridCurrentMover(curr_file, num_method='Euler'); # # # # Add some spills (sources of elements) # # print ('adding one spill') spill = point_line_release_spill(num_elements=1000, amount=4000 * spilldur, units='m^3', start_position = position, release_time = start_time, substance =( u'BAHRGANSAR, OIL & GAS')) model.spills += spill print ('adding weatherers and cleanup options:') model.environment += [water, wind, waves] model.weatherers += Evaporation(water, wind) model.weatherers += Emulsification(waves) model.weatherers += NaturalDispersion(waves, water) model.full_run() return model
def test_dissolution_mass_balance(oil, temp, wind_speed, num_elems, expected_mb, on): ''' Test a single dissolution step. - for this, we need a dispersion weatherer to give us a droplet size distribution. Fuel Oil #6 does not exist... ''' waves = build_waves_obj(wind_speed, 'knots', 270, temp) wind = waves.wind water = waves.water disp = NaturalDispersion(waves, water) diss = Dissolution(waves, wind) all_array_types = diss.array_types.union(disp.array_types) (sc, time_step) = weathering_data_arrays(all_array_types, water, num_elements=num_elems, units='kg', amount_per_element=1.0 )[:2] print 'time_step: {}'.format(time_step) print 'num spills:', len(sc.spills) print 'spill[0] amount: {} {}'.format(sc.spills[0].amount, sc.spills[0].units) print 'temperature = ', temp print 'wind = ', print '\n'.join(['\t{} {}'.format(ts[1][0], waves.wind.units) for ts in waves.wind.timeseries]) print # we don't want to query the oil database, but get the sample oil #assert sc.spills[0].substance.record.id is None initial_amount = sc.spills[0].amount model_time = (sc.spills[0].release_time + timedelta(seconds=time_step)) disp.on = on disp.prepare_for_model_run(sc) disp.initialize_data(sc, sc.num_released) diss.on = on diss.prepare_for_model_run(sc) diss.initialize_data(sc, sc.num_released) disp.prepare_for_model_step(sc, time_step, model_time) diss.prepare_for_model_step(sc, time_step, model_time) disp.weather_elements(sc, time_step, model_time) diss.weather_elements(sc, time_step, model_time) if on: print ('fraction dissolved: {}' .format(sc.mass_balance['dissolution'] / initial_amount) ) print ('fraction dissolved: {:.2%}' .format(sc.mass_balance['dissolution'] / initial_amount) ) print sc.mass_balance['dissolution'], expected_mb assert np.isclose(sc.mass_balance['dissolution'], expected_mb, rtol=1e-4) else: assert 'dissolution' not in sc.mass_balance
def test_dissolution_droplet_size(oil, temp, num_elems, drop_size, on): ''' Here we are testing that the molar averaged oil/water partition coefficient (K_ow) is getting calculated with reasonable values ''' disp = NaturalDispersion(waves, water) diss = Dissolution(waves, wind) (sc, time_step) = weathering_data_arrays(diss.array_types, water, num_elements=num_elems)[:2] print 'num_spills:', len(sc.spills) print 'spill[0] amount:', sc.spills[0].amount, sc.spills[0].units model_time = (sc.spills[0] .release_time + timedelta(seconds=time_step)) print 'model_time = ', model_time print 'time_step = ', time_step # we don't want to query the oil database, but get the sample oil #assert sc.spills[0].substance.record.id is None disp.on = on diss.on = on disp.prepare_for_model_run(sc) diss.prepare_for_model_run(sc) disp.initialize_data(sc, sc.num_released) diss.initialize_data(sc, sc.num_released) for i in range(3): disp.prepare_for_model_step(sc, time_step, model_time) diss.prepare_for_model_step(sc, time_step, model_time) disp.weather_elements(sc, time_step, model_time) diss.weather_elements(sc, time_step, model_time) print 'droplet_avg_size:', sc._data_arrays['droplet_avg_size'] assert np.allclose(sc._data_arrays['droplet_avg_size'], drop_size[i])
def test_dissolution_k_ow(oil, temp, num_elems, k_ow, on): ''' Here we are testing that the molar averaged oil/water partition coefficient (K_ow) is getting calculated with reasonable values Note: for now droplets are calculated in natural dispersion so natural dispersion is required for the dissolution algorithm ''' diss = Dissolution(waves, wind) disp = NaturalDispersion(waves, water) (sc, time_step) = weathering_data_arrays(diss.array_types, water, substance=oil, num_elements=num_elems)[:2] print 'num spills:', len(sc.spills) print 'spill[0] amount:', sc.spills[0].amount # we don't want to query the oil database, but get the sample oil #assert sc.spills[0].substance.record.id is None model_time = (sc.spills[0].release_time + timedelta(seconds=time_step)) disp.on = on diss.on = on disp.prepare_for_model_run(sc) diss.prepare_for_model_run(sc) disp.initialize_data(sc, sc.num_released) diss.initialize_data(sc, sc.num_released) disp.prepare_for_model_step(sc, time_step, model_time) diss.prepare_for_model_step(sc, time_step, model_time) disp.weather_elements(sc, time_step, model_time) diss.weather_elements(sc, time_step, model_time) assert all(np.isclose(sc._data_arrays['partition_coeff'], k_ow))
def test_dissolution_mass_balance(oil, temp, wind_speed, num_elems, expected_mb, on): ''' Test a single dissolution step. - for this, we need a dispersion weatherer to give us a droplet size distribution. Fuel Oil #6 does not exist... ''' et = floating(substance=oil) waves = build_waves_obj(wind_speed, 'knots', 270, temp) water = waves.water disp = NaturalDispersion(waves, water) diss = Dissolution(waves) all_array_types = diss.array_types.union(disp.array_types) (sc, time_step) = weathering_data_arrays(all_array_types, water, element_type=et, num_elements=num_elems, units='kg', amount_per_element=1.0 )[:2] print 'time_step: {}'.format(time_step) print 'num spills:', len(sc.spills) print 'spill[0] amount: {} {}'.format(sc.spills[0].amount, sc.spills[0].units) print 'temperature = ', temp print 'wind = ', print '\n'.join(['\t{} {}'.format(ts[1][0], waves.wind.units) for ts in waves.wind.timeseries]) print # we don't want to query the oil database, but get the sample oil assert sc.spills[0].element_type.substance.record.id is None initial_amount = sc.spills[0].amount model_time = (sc.spills[0].release_time + timedelta(seconds=time_step)) disp.on = on disp.prepare_for_model_run(sc) disp.initialize_data(sc, sc.num_released) diss.on = on diss.prepare_for_model_run(sc) diss.initialize_data(sc, sc.num_released) disp.prepare_for_model_step(sc, time_step, model_time) diss.prepare_for_model_step(sc, time_step, model_time) disp.weather_elements(sc, time_step, model_time) diss.weather_elements(sc, time_step, model_time) if on: print ('fraction dissolved: {}' .format(sc.mass_balance['dissolution'] / initial_amount) ) print ('fraction dissolved: {:.2%}' .format(sc.mass_balance['dissolution'] / initial_amount) ) print sc.mass_balance['dissolution'], expected_mb assert np.isclose(sc.mass_balance['dissolution'], expected_mb) else: assert 'dissolution' not in sc.mass_balance
def make_model(): print ('initializing the model') #print (start_date) start_time = startday model = Model(start_time=start_time, duration=timedelta(days=30), #weathering_substeps = 6, time_step=24 * 3600, uncertain=False) mapfile = get_datafile(os.path.join(base_dir,'gulf.bna')) #mapfile='gulf.bna' print ('adding the map') model.map = MapFromBNA(mapfile, refloat_halflife=6) # hours # # Add the outputters -- render to images, and save out as netCDF # print ("adding shapefile output") # with open("Result {}".format(spill_num), "w") as fp: # fp.write("text") dir_name = os.path.join (base_dir, season, str(position), "Spillnum {}".format(spill_num)) if not os.path.exists(dir_name): os.makedirs(dir_name) #os.makedirs(dir_name, exist_ok =True) for i in range(1, 31, 1): model.outputters += ShapeOutput(os.path.join(dir_name, 'gnome_result {id}'.format(id=i)), zip_output=False, output_timestep=timedelta(days=i)) images_dir = os.path.join(dir_name, 'image') # print 'adding renderer' # model.outputters += Renderer(mapfile, # images_dir, # image_size=(800, 600)) # print ('adding renderer') # dir_image = os.path.join(dir_name) # model.outputters += Renderer(mapfile, # dir_image, # size=(800, 600)) # # Set up the movers: # print ('adding a RandomMover:') model.movers += RandomMover(diffusion_coef=10000) print ('adding a simple wind mover:') wind_file = get_datafile(os.path.join(base_dir, 'ECMWF.nc')) model.movers += GridWindMover(wind_file) print ('adding a current mover:') # # this is NEMO currents curr_file = get_datafile(os.path.join(base_dir, Currents)) model.movers += GridCurrentMover(curr_file, num_method='Euler'); # # Add some spills (sources of elements) print ('adding one spill') spill = point_line_release_spill(num_elements=1000, amount= 3200000000 * spilldur , units='grams', start_position = position, release_time = start_time, substance = (sub)) model.spills += spill ####### open excel file print ('adding Excel file') workbook = xlsxwriter.Workbook(os.path.join(dir_name, 'Result {}_{}.xlsx'.format(spill_num, position))) worksheet = workbook.add_worksheet () a = ((spilldur*3200)**(-0.3))*0.000069 worksheet.write ('A1', a) workbook.close() print ('adding weatherers and cleanup options:') model.environment += [water,wind,waves] model.weatherers += Evaporation() model.weatherers += Emulsification() model.weatherers += NaturalDispersion() print ('model full run:') model.full_run() return model
def make_model(images_dir=os.path.join(base_dir, 'images')): print 'initializing the model' start_time = datetime(2015, 5, 14, 0, 0) # 1 day of data in file # 1/2 hr in seconds model = Model(start_time=start_time, duration=timedelta(days=1.75), time_step=60 * 60, uncertain=True) # mapfile = get_datafile(os.path.join(base_dir, './ak_arctic.bna')) # # print 'adding the map' # model.map = MapFromBNA(mapfile, refloat_halflife=1) # seconds # # # draw_ontop can be 'uncertain' or 'forecast' # # 'forecast' LEs are in black, and 'uncertain' are in red # # default is 'forecast' LEs draw on top # renderer = Renderer(mapfile, images_dir, size=(800, 600), # output_timestep=timedelta(hours=2), # draw_ontop='forecast') # # print 'adding outputters' # model.outputters += renderer model.outputters += WeatheringOutput() netcdf_file = os.path.join(base_dir, 'script_weatherers.nc') scripting.remove_netcdf(netcdf_file) model.outputters += NetCDFOutput(netcdf_file, which_data='all', output_timestep=timedelta(hours=1)) print 'adding a spill' # for now subsurface spill stays on initial layer # - will need diffusion and rise velocity # - wind doesn't act # - start_position = (-76.126872, 37.680952, 5.0), end_time = start_time + timedelta(hours=24) spill = point_line_release_spill( num_elements=100, start_position=(-164.791878561, 69.6252597267, 0.0), release_time=start_time, end_release_time=end_time, amount=1000, substance='ALASKA NORTH SLOPE (MIDDLE PIPELINE)', units='bbl') # set bullwinkle to .303 to cause mass goes to zero bug at 24 hours (when continuous release ends) spill.element_type._substance._bullwinkle = .303 model.spills += spill print 'adding a RandomMover:' #model.movers += RandomMover(diffusion_coef=50000) print 'adding a wind mover:' series = np.zeros((2, ), dtype=datetime_value_2d) series[0] = (start_time, (20, 0)) series[1] = (start_time + timedelta(hours=23), (20, 0)) wind2 = Wind(timeseries=series, units='knot') w_mover = WindMover(wind) model.movers += w_mover print 'adding weatherers and cleanup options:' # define skimmer/burn cleanup options skim1_start = start_time + timedelta(hours=15.58333) skim2_start = start_time + timedelta(hours=16) units = spill.units skimmer1 = Skimmer(80, units=units, efficiency=0.36, active_start=skim1_start, active_stop=skim1_start + timedelta(hours=8)) skimmer2 = Skimmer(120, units=units, efficiency=0.2, active_start=skim2_start, active_stop=skim2_start + timedelta(hours=12)) burn_start = start_time + timedelta(hours=36) burn = Burn(1000., .1, active_start=burn_start, efficiency=.2) chem_start = start_time + timedelta(hours=24) c_disp = ChemicalDispersion(0.5, efficiency=0.4, active_start=chem_start, active_stop=chem_start + timedelta(hours=8)) model.environment += [Water(280.928), wind, waves] model.weatherers += Evaporation(water, wind) model.weatherers += Emulsification(waves) model.weatherers += NaturalDispersion(waves, water) model.weatherers += skimmer1 model.weatherers += skimmer2 model.weatherers += burn model.weatherers += c_disp return model
inputs = b_class[1] obj = class_(*inputs, name=name) assert obj.name == name obj.name = obj.__class__.__name__ assert obj.name == obj.__class__.__name__ t = datetime(2015, 1, 1, 12, 0) @pytest.mark.parametrize( ("obj", "make_default_refs", "objvalid"), [(Wind(timeseries=[(t, (0, 1)), (t + timedelta(10), (0, 2))], units='m/s'), False, True), (Evaporation(), False, False), (NaturalDispersion(), False, False), (Evaporation(), True, True)]) def test_base_validate(obj, make_default_refs, objvalid): ''' base validate checks wind/water/waves objects are not None. Check these primarily for weatherers. ''' obj.make_default_refs = make_default_refs (out, isvalid) = obj.validate() print out print isvalid assert isvalid is objvalid assert len(out) > 0 def test_make_default_refs():
print 'adding a WindMover (Euler):' g_wind = GridWind.from_netCDF( filename=file_list_w, # dataset=ds_w, grid_topology={ 'node_lon': 'lonc', 'node_lat': 'latc' }) w_mover = PyWindMover(wind=g_wind, default_num_method='Euler') model.movers += w_mover model.environment += g_wind water = Water(temperature=290.0, salinity=33.0) waves = Waves(g_wind) model.weatherers += Evaporation(water=water, wind=g_wind) model.weatherers += NaturalDispersion(waves=waves) # print 'adding a CurrentMover (Trapeziod/RK4):' # c_mover = GridCurrentMover(os.path.join(setup.Data_Dir,setup.CurrCatFile), # os.path.join(setup.Data_Dir,setup.CurrTopoFile), # num_method='RK4' # ) # model.movers += c_mover # print 'adding a WindMover (Euler):' # w_mover = GridWindMover(os.path.join(setup.Data_DirW,setup.WindCatFile), # os.path.join(setup.Data_DirW,setup.WindTopoFile) # ) # model.movers += w_mover print 'adding a RandomMover:'
def test_sort_order(): assert weatherer_sort(Dissolution()) > weatherer_sort(NaturalDispersion())
obj = class_(*inputs, name=name) assert obj.name == name obj.name = obj.__class__.__name__ assert obj.name == obj.__class__.__name__ t = datetime(2015, 1, 1, 12, 0) @pytest.mark.parametrize(("obj", "make_default_refs", "objvalid"), [(Wind(timeseries=[(t, (0, 1)), (t + timedelta(10), (0, 2))], units='m/s'), False, True), (Evaporation(), False, False), (NaturalDispersion(), False, False), (Evaporation(), True, True)]) def test_base_validate(obj, make_default_refs, objvalid): ''' base validate checks wind/water/waves objects are not None. Check these primarily for weatherers. ''' obj.make_default_refs = make_default_refs (out, isvalid) = obj.validate() print out print isvalid assert isvalid is objvalid assert len(out) > 0 def test_make_default_refs():