def setup_test(self, end_time_delay, num_les, ts=900.): stime = datetime(2015, 1, 1, 12, 0) etime = stime + end_time_delay st_pos = (0, 0, 0) oil = test_oil m1 = Model(start_time=stime, time_step=ts) m1.environment += [constant_wind(0, 0), Water()] m1.weatherers += Evaporation() m1.spills += point_line_release_spill(num_les[0], st_pos, stime, end_release_time=etime, substance=oil, amount=36000, units='kg') m1.outputters += WeatheringOutput() m2 = Model(start_time=stime, time_step=ts) m2.environment += [constant_wind(0, 0), Water()] m2.weatherers += Evaporation() m2.spills += point_line_release_spill(num_les[1], st_pos, stime, end_release_time=etime, substance=oil, amount=36000, units='kg') m2.outputters += WeatheringOutput() return (m1, m2)
def test_weathering_data_attr(): ''' mass_balance is initialized/written if we have weatherers ''' ts = 900 s1_rel = datetime.now().replace(microsecond=0) s2_rel = s1_rel + timedelta(seconds=ts) s = [point_line_release_spill(10, (0, 0, 0), s1_rel), point_line_release_spill(10, (0, 0, 0), s2_rel)] model = Model(time_step=ts, start_time=s1_rel) model.spills += s model.step() for sc in model.spills.items(): assert len(sc.mass_balance) == 2 for key in ('beached', 'off_maps'): assert key in sc.mass_balance model.environment += [Water(), constant_wind(0., 0)] model.weatherers += [Evaporation(model.environment[0], model.environment[1])] # use different element_type and initializers for both spills s[0].amount = 10.0 s[0].units = 'kg' model.rewind() model.step() for sc in model.spills.items(): # since no substance is defined, all the LEs are marked as # nonweathering assert sc.mass_balance['non_weathering'] == sc['mass'].sum() assert sc.mass_balance['non_weathering'] == s[0].amount s[1].amount = 5.0 s[1].units = 'kg' model.rewind() exp_rel = 0.0 for ix in range(2): model.step() exp_rel += s[ix].amount for sc in model.spills.items(): assert sc.mass_balance['non_weathering'] == sc['mass'].sum() assert sc.mass_balance['non_weathering'] == exp_rel model.rewind() assert sc.mass_balance == {} # weathering data is now empty for all steps del model.weatherers[0] for ix in xrange(2): model.step() for sc in model.spills.items(): assert len(sc.mass_balance) == 2 assert (len(set(sc.mass_balance.keys()) - {'beached', 'off_maps'}) == 0)
def mk_objs(cls, sample_model_fcn2): model = sample_model_weathering2(sample_model_fcn2, test_oil, 333.0) model.set_make_default_refs(True) model.environment += [waves, wind, water] model.weatherers += Evaporation(wind=wind, water=water) model.weatherers += Emulsification(waves=waves) return (model.spills.items()[0], model)
def test_full_run(sample_model_fcn, oil, temp): ''' test evaporation outputs for a full run of model. This contains a mover so at some point several elements end up on_land. This test also checks the evap_decay_constant for elements that are not in water is 0 so mass is unchanged. ''' model = sample_model_weathering(sample_model_fcn, oil, temp, 10) model.environment += [Water(temp), constant_wind(1., 0)] model.weatherers += [ Evaporation(model.environment[-2], model.environment[-1]) ] released = 0 init_rho = model.spills[0].substance.density_at_temp(temp) init_vis = model.spills[0].substance.kvis_at_temp(temp) for step in model: for sc in model.spills.items(): assert_helper(sc, sc.num_released - released) released = sc.num_released if sc.num_released > 0: assert np.all(sc['density'] >= init_rho) assert np.all(sc['viscosity'] >= init_vis) mask = sc['status_codes'] == oil_status.in_water assert sc.mass_balance['floating'] == np.sum(sc['mass'][mask]) print("Amount released: {0}".format( sc.mass_balance['amount_released'])) print "Mass floating: {0}".format(sc.mass_balance['floating']) print "Mass evap: {0}".format(sc.mass_balance['evaporated']) print "LEs in water: {0}".format(sum(mask)) print "Mass on land: {0}".format(np.sum(sc['mass'][~mask])) print "Completed step: {0}\n".format(step['step_num'])
def model(sample_model_fcn, output_filename): """ Use fixture model_surface_release_spill and add a few things to it for the test """ model = sample_model_fcn['model'] model.cache_enabled = True model.spills += \ point_line_release_spill(num_elements=5, start_position=sample_model_fcn['release_start_pos'], release_time=model.start_time, end_release_time=model.start_time + model.duration, substance=test_oil, amount=1000, units='kg') water = Water() model.movers += RandomMover(diffusion_coef=100000) model.movers += constant_wind_mover(1.0, 0.0) model.weatherers += Evaporation(water=water, wind=model.movers[-1].wind) model.outputters += NetCDFOutput(output_filename) model.rewind() return model
def model(sample_model, output_dir): model = sample_model_weathering(sample_model, test_oil) rel_start_pos = sample_model['release_start_pos'] rel_end_pos = sample_model['release_end_pos'] model.cache_enabled = True model.uncertain = True water, wind = Water(), constant_wind(1., 0) model.environment += [water, wind] model.weatherers += Evaporation(water, wind) et = floating(substance=model.spills[0].substance.name) N = 10 # a line of ten points line_pos = np.zeros((N, 3), dtype=np.float64) line_pos[:, 0] = np.linspace(rel_start_pos[0], rel_end_pos[0], N) line_pos[:, 1] = np.linspace(rel_start_pos[1], rel_end_pos[1], N) # print start_points model.spills += point_line_release_spill(1, start_position=rel_start_pos, release_time=model.start_time, end_position=rel_end_pos, element_type=et, amount=100, units='tons') model.outputters += TrajectoryGeoJsonOutput(output_dir=output_dir) model.rewind() return model
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_setup_model_run(model): 'turn of movers/weatherers and ensure data_arrays change' model.environment += Water() model.rewind() model.step() exp_keys = { 'windages', 'windage_range', 'mass_components', 'windage_persist' } # no exp_keys in model data_arrays assert not exp_keys.intersection(model.spills.LE_data) cwm = gnome.movers.constant_wind_mover(1., 0.) model.weatherers += [HalfLifeWeatherer(), Evaporation()] model.movers += cwm model.rewind() model.step() assert exp_keys.issubset(model.spills.LE_data) cwm.on = False for w in xrange(2): model.weatherers[w].on = False model.rewind() model.step() assert not exp_keys.intersection(model.spills.LE_data)
def test_load_location_file(self, saveloc_, model): ''' create a model load save file from script_boston which contains a spill. Then merge the created model into the model loaded from save file ''' m = Model() m.environment += [Water(), constant_wind(1., 0.)] m.weatherers += Evaporation(m.environment[0], m.environment[-1]) m.spills += point_line_release_spill(10, (0, 0, 0), datetime(2014, 1, 1, 12, 0)) # create save model sample_save_file = os.path.join(saveloc_, 'SampleSaveModel.zip') model.save(saveloc_, name='SampleSaveModel.zip') if os.path.exists(sample_save_file): model = load(sample_save_file) model.merge(m) for oc in m._oc_list: for item in getattr(m, oc): model_oc = getattr(model, oc) assert item is model_oc[item.id] for spill in m.spills: assert spill is model.spills[spill.id] # merge the other way and ensure model != m m.merge(model) assert model != m
def test_serialize_deseriailize(): 'test serialize/deserialize for webapi' e = Evaporation() wind = constant_wind(1., 0) water = Water() json_ = e.serialize() json_['wind'] = wind.serialize() json_['water'] = water.serialize() # deserialize and ensure the dict's are correct d_ = Evaporation.deserialize(json_) assert d_['wind'] == Wind.deserialize(json_['wind']) assert d_['water'] == Water.deserialize(json_['water']) d_['wind'] = wind d_['water'] = water e.update_from_dict(d_) assert e.wind is wind assert e.water is water
def test_evaporation_no_wind(): evap = Evaporation(Water(), wind=constant_wind(0., 0)) (sc, time_step) = weathering_data_arrays(evap.array_types, evap.water)[:2] model_time = (sc.spills[0].release_time + timedelta(seconds=time_step)) evap.prepare_for_model_run(sc) evap.prepare_for_model_step(sc, time_step, model_time) evap.weather_elements(sc, time_step, model_time) for spill in sc.spills: mask = sc.get_spill_mask(spill) assert np.all(sc['evap_decay_constant'][mask, :] < 0.0)
def test_contains_object(sample_model_fcn): ''' Test that we can find all contained object types with a model. ''' model = sample_model_weathering(sample_model_fcn, test_oil) gnome_map = model.map = gnome.map.GnomeMap() # make it all water rel_time = model.spills[0].get('release_time') model.start_time = rel_time - timedelta(hours=1) model.duration = timedelta(days=1) water, wind = Water(), constant_wind(1., 0) model.environment += [water, wind] et = floating(substance=model.spills[0].get('substance').name) sp = point_line_release_spill(500, (0, 0, 0), rel_time + timedelta(hours=1), element_type=et, amount=100, units='tons') rel = sp.release initializers = et.initializers model.spills += sp movers = [m for m in model.movers] evaporation = Evaporation() skim_start = sp.get('release_time') + timedelta(hours=1) skimmer = Skimmer(.5 * sp.amount, units=sp.units, efficiency=0.3, active_start=skim_start, active_stop=skim_start + timedelta(hours=1)) burn = burn_obj(sp) disp_start = skim_start + timedelta(hours=1) dispersion = ChemicalDispersion(0.1, active_start=disp_start, active_stop=disp_start + timedelta(hours=1)) model.weatherers += [evaporation, dispersion, burn, skimmer] renderer = Renderer(images_dir='junk', size=(400, 300)) model.outputters += renderer for o in (gnome_map, sp, rel, et, water, wind, evaporation, dispersion, burn, skimmer, renderer): assert model.contains_object(o.id) for o in initializers: assert model.contains_object(o.id) for o in movers: assert model.contains_object(o.id)
def model(sample_model): model = sample_model['model'] model.make_default_refs = True rel_start_pos = sample_model['release_start_pos'] rel_end_pos = sample_model['release_end_pos'] model.cache_enabled = True model.uncertain = False model.environment += Water(311.15) print 'adding a Weatherer' model.environment += constant_wind(1.0, 0.0) N = 10 # a line of ten points line_pos = np.zeros((N, 3), dtype=np.float64) line_pos[:, 0] = np.linspace(rel_start_pos[0], rel_end_pos[0], N) line_pos[:, 1] = np.linspace(rel_start_pos[1], rel_end_pos[1], N) # print start_points model.duration = timedelta(hours=6) end_time = model.start_time + timedelta(hours=1) spill = point_line_release_spill(1000, start_position=rel_start_pos, release_time=model.start_time, end_release_time=end_time, end_position=rel_end_pos, substance=test_oil, amount=1000, units='kg') model.spills += spill # figure out mid-run save for weathering_data attribute, then add this in rel_time = model.spills[0].get('release_time') skim_start = rel_time + timedelta(hours=1) amount = model.spills[0].amount units = model.spills[0].units skimmer = Skimmer(.3 * amount, units=units, efficiency=0.3, active_start=skim_start, active_stop=skim_start + timedelta(hours=1)) # thickness = 1m so area is just 20% of volume volume = spill.get_mass() / spill.get('substance').get_density() burn = Burn(0.2 * volume, 1.0, active_start=skim_start, efficiency=0.9) c_disp = ChemicalDispersion(.1, efficiency=0.5, active_start=skim_start, active_stop=skim_start + timedelta(hours=1)) model.weatherers += [Evaporation(), c_disp, burn, skimmer] model.outputters += WeatheringOutput() model.rewind() return model
def make_model(timeStep,start_time, duration, weatheringSteps, map, uncertain, data_path, reFloatHalfLife, windFile, currFile, tidalFile, num_elements, depths, lat, lon, output_path, evaporation): #initalizing the model print 'initializing the model:' # model = Model(time_step = timeStep, start_time= start_time, duration=duration, uncertain = uncertain) model = Model(time_step = timeStep, start_time= start_time, duration=duration) #adding the map print 'adding the map:' print 'pinche path', data_path mapfile = get_datafile(os.path.join(data_path, map)) model.map = MapFromBNA(mapfile, refloat_halflife = reFloatHalfLife) #model.map = GnomeMap() print 'adding a renderer' # renderer is a class that writes map images for GNOME results model.outputters += Renderer(mapfile, output_path, size=(800, 600), output_timestep=timedelta(hours=1)) ##scripting.remove_netcdf(netcdf_file) #nc_outputter = NetCDFOutput(netcdf_file, which_data='most', output_timestep=timedelta(hours=1)) #model.outputters += nc_outputter #adding the movers print 'adding a wind mover:' wind_file = get_datafile(os.path.join(data_path, windFile)) wind = GridWindMover(wind_file) wind.wind_scale = 2 model.movers += wind print 'adding a current mover: ' curr_file = get_datafile(os.path.join(data_path,currFile)) model.movers+= GridCurrentMover(curr_file, num_method='RK4') #random_mover = RandomMover(diffusion_coef=10000) #in cm/sdfd #model.movers += random_mover if evaporation: #wind for evaporation print'adding evaporation' wind = constant_wind(1, 0, 'knots') water = Water(temperature=300.0, salinity=35.0) model.weatherers += Evaporation(wind=wind, water=water) # print 'adding a spill' # for i in depths: # model.spills+= point_line_release_spill(num_elements=num_elements, start_position=(lon,lat,i), release_time=start_time) model.spills+= point_line_release_spill(num_elements=num_elements, start_position=(lon,lat,0), release_time=start_time, end_release_time=start_time+timedelta(days=93)) return model
def test_weatherer_sort(): ''' Sample model with weatherers - only tests sorting of weathereres. The Model will likely not run ''' model = Model() skimmer = Skimmer(100, 'kg', efficiency=0.3, active_start=datetime(2014, 1, 1, 0, 0), active_stop=datetime(2014, 1, 1, 0, 3)) burn = Burn(100, 1, active_start=datetime(2014, 1, 1, 0, 0)) c_disp = ChemicalDispersion(.3, active_start=datetime(2014, 1, 1, 0, 0), active_stop=datetime(2014, 1, 1, 0, 3), efficiency=0.2) weatherers = [Emulsification(), Evaporation(Water(), constant_wind(1, 0)), burn, c_disp, skimmer] exp_order = [weatherers[ix] for ix in (3, 4, 2, 1, 0)] model.environment += [Water(), constant_wind(5, 0), Waves()] model.weatherers += weatherers # WeatheringData and FayGravityViscous automatically get added to # weatherers. Only do assertion on weatherers contained in list above assert model.weatherers.values()[:len(exp_order)] != exp_order model.setup_model_run() assert model.weatherers.values()[:len(exp_order)] == exp_order # check second time around order is kept model.rewind() assert model.weatherers.values()[:len(exp_order)] == exp_order # Burn, ChemicalDispersion are at same sorting level so appending # another Burn to the end of the list will sort it to be just after # ChemicalDispersion so index 2 burn = Burn(50, 1, active_start=datetime(2014, 1, 1, 0, 0)) exp_order.insert(3, burn) model.weatherers += exp_order[3] # add this and check sorting still works assert model.weatherers.values()[:len(exp_order)] != exp_order model.setup_model_run() assert model.weatherers.values()[:len(exp_order)] == exp_order
def test_full_run_evap_not_active(sample_model_fcn): 'no water/wind object' model = sample_model_weathering(sample_model_fcn, 'oil_6') model.weatherers += Evaporation(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 'evaporated' not in step['WeatheringOutput'] assert ('time_stamp' in step['WeatheringOutput']) print("Completed step: {0}".format(step['step_num']))
def test_evaporation(oil, temp, num_elems, on): ''' still working on tests .. ''' et = floating(substance=oil) time_step = 15. * 60 evap = Evaporation(Water(), wind=constant_wind(1., 0)) evap.on = on sc = weathering_data_arrays(evap.array_types, evap.water, time_step, et)[0] model_time = (sc.spills[0].release_time + timedelta(seconds=time_step)) evap.prepare_for_model_run(sc) evap.prepare_for_model_step(sc, time_step, model_time) init_mass = sc['mass_components'].copy() evap.weather_elements(sc, time_step, model_time) if on: assert np.all(sc['frac_lost'] > 0) and np.all(sc['frac_lost'] < 1.0) # all elements experience the same evaporation assert np.all(sc['frac_lost'][0] == sc['frac_lost']) for spill in sc.spills: mask = sc.get_spill_mask(spill) if on: assert np.all(sc['evap_decay_constant'][mask, :] < 0.0) else: assert np.all(sc['evap_decay_constant'][mask, :] == 0.0) print '\nevap_decay_const', sc['evap_decay_constant'] print 'frac_lost', sc['frac_lost'] if on: assert sc.mass_balance['evaporated'] > 0.0 print 'total evaporated', sc.mass_balance['evaporated'] else: assert 'evaporated' not in sc.mass_balance assert np.all(sc['mass_components'] == init_mass)
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_evaporation_no_wind(): evap = Evaporation(Water(), wind=constant_wind(0., 0)) (sc, time_step) = weathering_data_arrays(evap.array_types, evap.water)[:2] model_time = (sc.spills[0].get('release_time') + timedelta(seconds=time_step)) evap.prepare_for_model_run(sc) evap.prepare_for_model_step(sc, time_step, model_time) evap.weather_elements(sc, time_step, model_time) for spill in sc.spills: mask = sc.get_spill_mask(spill) assert np.all(sc['evap_decay_constant'][mask, :] < 0.0)
def test_callback_add_weather(): ''' Test callback when weatherer is added ''' model = Model() water = Water() wind = constant_wind(1, 30) assert len(model.environment) == 0 model.weatherers += Evaporation(water, wind) # wind and water added to environment collection assert len(model.environment) == 2 assert wind in model.environment assert water in model.environment
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_evaporation(oil, temp, num_elems, on): ''' still working on tests .. ''' et = floating(substance=oil) time_step = 15. * 60 evap = Evaporation(Water(), wind=constant_wind(1., 0)) evap.on = on sc = weathering_data_arrays(evap.array_types, evap.water, time_step, et)[0] model_time = (sc.spills[0].get('release_time') + timedelta(seconds=time_step)) evap.prepare_for_model_run(sc) evap.prepare_for_model_step(sc, time_step, model_time) init_mass = sc['mass_components'].copy() evap.weather_elements(sc, time_step, model_time) if on: assert np.all(sc['frac_lost'] > 0) and np.all(sc['frac_lost'] < 1.0) # all elements experience the same evaporation assert np.all(sc['frac_lost'][0] == sc['frac_lost']) for spill in sc.spills: mask = sc.get_spill_mask(spill) if on: assert np.all(sc['evap_decay_constant'][mask, :] < 0.0) else: assert np.all(sc['evap_decay_constant'][mask, :] == 0.0) print '\nevap_decay_const', sc['evap_decay_constant'] print 'frac_lost', sc['frac_lost'] if on: assert sc.mass_balance['evaporated'] > 0.0 print 'total evaporated', sc.mass_balance['evaporated'] else: assert 'evaporated' not in sc.mass_balance assert np.all(sc['mass_components'] == init_mass)
def test_full_run(sample_model_fcn, oil, temp): ''' test emulsification outputs post step for a full run of model. Dump json for 'weathering_model.json' in dump directory ''' model = sample_model_weathering2(sample_model_fcn, oil, temp) model.environment += [Waves(), wind, Water(temp)] model.weatherers += Evaporation() model.weatherers += Emulsification() model.set_make_default_refs(True) for step in model: for sc in model.spills.items(): # need or condition to account for water_content = 0.9000000000012 # or just a little bit over 0.9 assert (sc.mass_balance['water_content'] <= .9 or np.isclose(sc.mass_balance['water_content'], 0.9)) print("Water fraction: {0}".format( sc.mass_balance['water_content'])) print "Completed step: {0}\n".format(step['step_num'])
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(uncertain=False, mode='gnome'): ''' Create a model from the data in sample_data/boston_data It contains: - the GeoProjection - wind mover - random mover - cats shio mover - cats ossm mover - plain cats mover ''' start_time = datetime(2013, 2, 13, 9, 0) model = Model(start_time=start_time, duration=timedelta(days=2), time_step=timedelta(minutes=30).total_seconds(), uncertain=uncertain, map=MapFromBNA(testdata['boston_data']['map'], refloat_halflife=1), mode=mode) print 'adding a spill' start_position = (144.664166, 13.441944, 0.0) end_release_time = start_time + timedelta(hours=6) spill_amount = 1000.0 spill_units = 'kg' model.spills += point_line_release_spill(num_elements=1000, start_position=start_position, release_time=start_time, end_release_time=end_release_time, amount=spill_amount, units=spill_units, substance=test_oil) spill = model.spills[-1] spill_volume = spill.get_mass() / spill.substance.density_at_temp() # need a scenario for SimpleMover # model.movers += SimpleMover(velocity=(1.0, -1.0, 0.0)) print 'adding a RandomMover:' model.movers += RandomMover(diffusion_coef=100000) print 'adding a wind mover:' series = np.zeros((2, ), dtype=datetime_value_2d) series[0] = (start_time, (5, 180)) series[1] = (start_time + timedelta(hours=18), (5, 180)) w_mover = WindMover(Wind(timeseries=series, units='m/s')) model.movers += w_mover model.environment += w_mover.wind print 'adding a cats shio mover:' c_mover = CatsMover(testdata['boston_data']['cats_curr2'], tide=Tide(testdata['boston_data']['cats_shio'])) # c_mover.scale_refpoint should automatically get set from tide object c_mover.scale = True # default value c_mover.scale_value = -1 # tide object automatically gets added by model model.movers += c_mover print 'adding a cats ossm mover:' c_mover = CatsMover(testdata['boston_data']['cats_curr2'], tide=Tide(testdata['boston_data']['cats_ossm'])) c_mover.scale = True # but do need to scale (based on river stage) c_mover.scale_refpoint = (-70.65, 42.58333, 0.0) c_mover.scale_value = 1. print 'adding a cats mover:' c_mover = CatsMover(testdata['boston_data']['cats_curr3']) c_mover.scale = True # but do need to scale (based on river stage) c_mover.scale_refpoint = (-70.78333, 42.39333, 0.0) # the scale factor is 0 if user inputs no sewage outfall effects c_mover.scale_value = .04 model.movers += c_mover # TODO: seg faulting for component mover - comment test for now # print "adding a component mover:" # comp_mover = ComponentMover(testdata['boston_data']['component_curr1'], # testdata['boston_data']['component_curr2'], # w_mover.wind) # TODO: callback did not work correctly below - fix! # comp_mover = ComponentMover(component_file1, # component_file2, # Wind(timeseries=series, units='m/s')) # comp_mover.ref_point = (-70.855, 42.275) # comp_mover.pat1_angle = 315 # comp_mover.pat1_speed = 19.44 # comp_mover.pat1_speed_units = 1 # comp_mover.pat1ScaleToValue = .138855 # comp_mover.pat2_angle = 225 # comp_mover.pat2_speed = 19.44 # comp_mover.pat2_speed_units = 1 # comp_mover.pat2ScaleToValue = .05121 # model.movers += comp_mover print 'adding a Weatherer' model.environment += Water(311.15) skim_start = start_time + timedelta(hours=3) model.weatherers += [ Evaporation(), Skimmer(spill_amount * .5, spill_units, efficiency=.3, active_range=(skim_start, skim_start + timedelta(hours=2))), Burn(0.2 * spill_volume, 1.0, (skim_start, InfDateTime('inf')), efficiency=0.9) ] model.outputters += \ CurrentJsonOutput(model.find_by_attr('_ref_as', 'current_movers', model.movers, allitems=True)) 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
def make_model(uncertain=False, geojson_output=False): print 'initializing the model' start_time = datetime(2012, 9, 15, 12, 0) mapfile = testdata["lis"]["map"] gnome_map = MapFromBNA(mapfile, refloat_halflife=6) # hours # # the image output renderer # global renderer # one hour timestep model = Model(start_time=start_time, duration=timedelta(hours=48), time_step=3600, map=gnome_map, uncertain=uncertain, cache_enabled=False) print 'adding a spill' spill = point_line_release_spill(num_elements=1000, start_position=(-72.419992, 41.202120, 0.0), release_time=start_time, amount=1000, substance=test_oil, units='kg') spill.amount_uncertainty_scale = 1.0 model.spills += spill print 'adding a RandomMover:' model.movers += RandomMover(diffusion_coef=500000, uncertain_factor=2) print 'adding a wind mover:' series = np.zeros((5, ), dtype=datetime_value_2d) series[0] = (start_time, (20, 45)) series[1] = (start_time + timedelta(hours=18), (20, 90)) series[2] = (start_time + timedelta(hours=30), (20, 135)) series[3] = (start_time + timedelta(hours=42), (20, 180)) series[4] = (start_time + timedelta(hours=54), (20, 225)) wind = Wind(timeseries=series, units='m/s', speed_uncertainty_scale=0.05) model.movers += WindMover(wind) print 'adding a cats mover:' c_mover = CatsMover(testdata["lis"]["cats_curr"], tide=Tide(testdata["lis"]["cats_tide"])) model.movers += c_mover model.environment += c_mover.tide print 'adding Weatherers' rel_time = model.spills[0].get('release_time') skim_start = rel_time + timedelta(hours=4) amount = spill.amount units = spill.units # define skimmer/burn cleanup options skimmer = Skimmer(0.3 * amount, units=units, efficiency=0.3, active_start=skim_start, active_stop=skim_start + timedelta(hours=4)) # thickness = 1m so area is just 20% of volume volume = spill.get_mass() / spill.get('substance').get_density() burn = Burn(0.2 * volume, 1.0, active_start=skim_start, efficiency=.9) c_disp = ChemicalDispersion(0.1, efficiency=0.5, active_start=skim_start, active_stop=skim_start + timedelta(hours=1)) water_env = Water(311.15) model.environment += water_env model.weatherers += [Evaporation(water_env, wind), c_disp, burn, skimmer] print 'adding outputters' model.outputters += WeatheringOutput() if geojson_output: model.outputters += TrajectoryGeoJsonOutput() return model
'test save/load functionality' _json_, zipfile_, _refs = obj.save(saveloc_) obj2 = obj.__class__.load(zipfile_) assert obj == obj2 # Wind objects need more work - the data is being written out to file in # 'r-theta' format accurate to 2 decimal places and in knots. # All the conversions mean the allclose() check on timeseries fails - xfail # for now. When loading for a file it works fine, no decimal places stored # in file for magnitude @pytest.mark.parametrize("obj", ( Wind(timeseries=(sec_to_date(24 * 3600), (1, 30)), units='meters per second'), Evaporation(wind=constant_wind(1., 30.), water=Water(333.0)), )) def test_serialize_deserialize_wind_objs(saveloc_, obj): 'test serialize/deserialize functionality' json_ = obj.serialize() obj2 = obj.__class__.deserialize(json_) assert obj == obj2 @pytest.mark.parametrize("obj", ( Wind(timeseries=(sec_to_date(24 * 3600), (1, 30)), units='meters per second'), Evaporation(wind=constant_wind(1., 30.), water=Water(333.0)), )) def test_save_load_wind_objs(saveloc_, obj):
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():
def make_model(images_dir=os.path.join(base_dir, 'images')): print 'initializing the model' start_time = datetime(2012, 9, 15, 12, 0) mapfile = get_datafile(os.path.join(base_dir, './LongIslandSoundMap.BNA')) gnome_map = MapFromBNA(mapfile, refloat_halflife=6) # hours # # the image output renderer # global renderer # one hour timestep model = Model(start_time=start_time, duration=timedelta(hours=48), time_step=3600, map=gnome_map, uncertain=False, cache_enabled=False) print 'adding a spill' et = floating_weathering(substance='FUEL OIL NO.6') spill = point_line_release_spill(num_elements=1000, start_position=(-72.419992, 41.202120, 0.0), release_time=start_time, amount=1000, units='kg', element_type=et) spill.amount_uncertainty_scale = 1.0 model.spills += spill print 'adding a RandomMover:' model.movers += RandomMover(diffusion_coef=500000, uncertain_factor=2) print 'adding a wind mover:' series = np.zeros((5, ), dtype=datetime_value_2d) series[0] = (start_time, (10, 45)) series[1] = (start_time + timedelta(hours=18), (10, 90)) series[2] = (start_time + timedelta(hours=30), (10, 135)) series[3] = (start_time + timedelta(hours=42), (10, 180)) series[4] = (start_time + timedelta(hours=54), (10, 225)) wind = Wind(timeseries=series, units='m/s', speed_uncertainty_scale=0.5) model.movers += WindMover(wind) print 'adding a cats mover:' curr_file = get_datafile(os.path.join(base_dir, r"./LI_tidesWAC.CUR")) tide_file = get_datafile(os.path.join(base_dir, r"./CLISShio.txt")) c_mover = CatsMover(curr_file, tide=Tide(tide_file)) model.movers += c_mover model.environment += c_mover.tide print 'adding Weatherers' water_env = Water(311.15) model.environment += water_env model.weatherers += [Evaporation(water_env, wind), Dispersion(), Burn(), Skimmer()] print 'adding outputters' model.outputters += WeatheringOutput() return model