Beispiel #1
0
def test_sed_mpi():
    model=base_model()
    
    g=unstructured_grid.UnstructuredGrid(max_sides=4)
    g.add_rectilinear([0,0],[1000,100],101,11)
    g.add_cell_field('depth',-6*np.ones(g.Ncells()))

    model.set_grid(g)

    model.num_procs=4
    model.config['dt']=3.

    # slow down the settling velocities to get some advection mixed in
    model.config['Ws01']= 0.0001     # constant settling velocity for fraction No.1 (m/s)
    model.config['Ws02']= 0.0005     # constant settling velocity for fraction No.2
    model.config['Ws03']=-0.0005     # constant settling velocity for fraction No.3

    geom=np.array([ [1000,0],
                    [1000,100]])
    Q_bc=sun_driver.FlowBC(name="Q_bc",
                           geom=geom,
                           Q=100.0)
    
    model.add_bcs( [Q_bc,
                    sun_driver.ScalarBC(parent=Q_bc,scalar="S",value=2),
                    sun_driver.ScalarBC(parent=Q_bc,scalar="T",value=0)] )

    point_bc=sun_driver.SourceSinkBC(name="bedPoint",
                                     geom=np.array([500,20]),
                                     Q=10)
    model.add_bcs( [point_bc,
                    sun_driver.ScalarBC(parent=point_bc,scalar="S",value=3),
                    sun_driver.ScalarBC(parent=point_bc,scalar="T",value=3)] )
                    
    model.write()

    # leave some dry layers at the surface
    model.ic_ds.eta.values[:]=model.bcs[0].z
    model.ic_ds.salt.values[:]=1.0
    model.ic_ds.temp.values[:]=1.0

    model.write_ic_ds()
        
    for sed_idx in range(3):
        name="sed%d"%(sed_idx+1)
        model.bc_ds['boundary_'+name]=model.bc_ds['boundary_S'].copy()
        model.bc_ds[name]=model.bc_ds['S'].copy()
        model.bc_ds['point_'+name]=model.bc_ds['point_S'].copy()
        
        model.bc_ds['boundary_'+name].values[:]=sed_idx*1.0
        model.bc_ds[name].values[:]=0.0
        model.bc_ds['point_'+name].values[:]=sed_idx*2.0

    model.write_bc_ds()
    
    model.partition()
    model.sun_verbose_flag='-v'
    model.run_simulation()
    return model
Beispiel #2
0
def test_sed_bc():
    """
    basic BC
    """
    model=base_model()

    # slow down the settling velocities to get some advection mixed in
    model.config['Ws01']= 0.0001     # constant settling velocity for fraction No.1 (m/s)
    model.config['Ws02']= 0.0001     # constant settling velocity for fraction No.2
    model.config['Ws03']=-0.0001     # constant settling velocity for fraction No.3

    geom=np.array([ [1000,0],
                    [1000,100]])
    Q_bc=sun_driver.FlowBC(name="Q_bc",
                           geom=geom,
                           Q=100.0)
    
    model.add_bcs( [Q_bc,
                    sun_driver.ScalarBC(parent=Q_bc,scalar="S",value=2),
                    sun_driver.ScalarBC(parent=Q_bc,scalar="T",value=0)] )

    point_bc=sun_driver.SourceSinkBC(name="bedPoint",
                                     geom=np.array([500,20]),
                                     Q=10)
    model.add_bcs( [point_bc,
                    sun_driver.ScalarBC(parent=point_bc,scalar="S",value=3),
                    sun_driver.ScalarBC(parent=point_bc,scalar="T",value=3)] )
                    
    model.write()

    # leave some dry layers at the surface
    model.ic_ds.eta.values[:]=model.bcs[0].z
    model.ic_ds.salt.values[:]=1.0
    model.ic_ds.temp.values[:]=1.0

    model.write_ic_ds()
        
    for sed_idx in range(3):
        name="sed%d"%(sed_idx+1)
        model.bc_ds['boundary_'+name]=model.bc_ds['boundary_S'].copy()
        model.bc_ds[name]=model.bc_ds['S'].copy()
        model.bc_ds['point_'+name]=model.bc_ds['point_S'].copy()
        
        model.bc_ds['boundary_'+name].values[:]=sed_idx*1.0
        model.bc_ds[name].values[:]=0.0
        model.bc_ds['point_'+name].values[:]=sed_idx*2.0

    model.write_bc_ds()
    
    model.partition()
    model.sun_verbose_flag='-v'
    model.run_simulation()
    return model
def test_point_source_1d():
    """
    Create a 1D water column, with a point source at the bed.
    Verifies that all cells with valid thickness (dzz>0.001m)
    have near unity salinity.
    """
    g=unstructured_grid.UnstructuredGrid(max_sides=4)
    g.add_rectilinear([0,0],[10,10],2,2)

    g.add_cell_field('depth',-6*np.ones(g.Ncells()))

    model=sun_driver.SuntansModel()
    model.load_template('point_source_test.dat')
    model.set_grid(g)
    model.run_start=np.datetime64("2018-01-01 00:00")
    model.run_stop =np.datetime64("2018-01-01 10:00")

    source=sun_driver.SourceSinkBC(name='inflow',geom=np.array([5,5]),
                                   z=-10,Q=1.0)
    model.add_bcs(source)
    model.add_bcs( [sun_driver.ScalarBC(parent=source,scalar="S",value=1),
                    sun_driver.ScalarBC(parent=source,scalar="T",value=1)] )

    model.set_run_dir('rundata_point_1d', mode='pristine')
    model.projection='EPSG:26910'

    model.config['dt']=2.5
    model.config['ntout']=1
    model.config['Cmax']=30
    model.config['Nkmax']=10
    model.config['stairstep']=0
    model.config['mergeArrays']=0

    model.write()

    model.ic_ds.eta.values[:]=-5.999
    model.ic_ds.salt.values[:]=1.0
    model.ic_ds.temp.values[:]=1.0
    model.write_ic_ds()

    model.partition()
    model.sun_verbose_flag='-v'
    model.run_simulation()

    ds=xr.open_dataset(model.map_outputs()[0])

    dzz=ds.dzz.values
    dzz_thresh=0.001
    salt=ds.salt.values
    salt_errors=salt[dzz>=dzz_thresh] - 1.0
    
    assert np.max( np.abs(salt_errors) )<0.001
Beispiel #4
0
def add_potw_bcs(model, cache_dir, temperature=20.0):
    # WWTP discharging into sloughs
    potw_dir = "../sfbay_potw"
    potw_ds = xr.open_dataset(
        os.path.join(potw_dir, "outputs", "sfbay_delta_potw.nc"))

    # the gazetteer uses the same names for potws as the source data
    # omits some of the smaller sources, and this does not include any
    # benthic discharges
    for potw_name in [
            'sunnyvale', 'san_jose', 'palo_alto', 'lg', 'sonoma_valley',
            'petaluma', 'cccsd', 'fs', 'ddsd', 'ebda', 'ebmud', 'sf_southeast'
    ]:
        # This has variously worked and not worked with strings vs bytes.
        # Brute force and try both.
        try:
            Q_da = potw_ds.flow.sel(site=potw_name)
        except KeyError:
            Q_da = potw_ds.flow.sel(site=potw_name.encode())

        # Have to seek back in time to find a year that has data for the
        # whole run
        offset = np.timedelta64(0, 'D')
        while model.run_stop > Q_da.time.values[-1] + offset:
            offset += np.timedelta64(365, 'D')
        if offset:
            log.info("Offset for POTW %s is %s" % (potw_name, offset))

        # use the geometry to decide whether this is a flow BC or a point source
        hits = model.match_gazetteer(name=potw_name)
        if hits[0]['geom'].type == 'LineString':
            log.info("%s: flow bc" % potw_name)
            Q_bc = drv.FlowBC(name=potw_name,
                              flow=Q_da,
                              filters=[hm.Lag(-offset)],
                              dredge_depth=model.dredge_depth)
        else:
            log.info("%s: source bc" % potw_name)
            Q_bc = drv.SourceSinkBC(name=potw_name,
                                    flow=Q_da,
                                    filters=[hm.Lag(-offset)],
                                    dredge_depth=model.dredge_depth)

        salt_bc = drv.ScalarBC(parent=Q_bc, scalar='salinity', value=0.0)
        temp_bc = drv.ScalarBC(parent=Q_bc,
                               scalar='temperature',
                               value=temperature)
        model.add_bcs([Q_bc, salt_bc, temp_bc])
Beispiel #5
0
def add_usgs_stream_bcs(model, cache_dir):
    # USGS gauged creeks
    for station, name in [
        (11172175, "COYOTE"),
        (11169025, "SCLARAVCc"),  # Alviso Sl / Guad river
        (11180700, "UALAMEDA"),  # Alameda flood control
        (11458000, "NAPA")
    ]:
        Q_bc = hm.NwisFlowBC(name=name,
                             station=station,
                             cache_dir=cache_dir,
                             dredge_depth=model.dredge_depth)
        salt_bc = drv.ScalarBC(name=name, scalar='salinity', value=0.0)
        temp_bc = drv.ScalarBC(name=name, scalar='temperature', value=20.0)

        model.add_bcs([Q_bc, salt_bc, temp_bc])
Beispiel #6
0
def base_model():
    """
    Channel
    """
    g=unstructured_grid.UnstructuredGrid(max_sides=4)
    g.add_rectilinear([0,0],[1000,100],21,3)
    
    g.add_cell_field('depth',-6*np.ones(g.Ncells()))

    model=sun_driver.SuntansModel()
    model.load_template('point_source_test.dat')
    model.set_grid(g)
    model.run_start=np.datetime64("2018-01-01 00:00")
    model.run_stop =np.datetime64("2018-01-05 00:00")

    dt=np.timedelta64(600,'s')
    times=np.arange(model.run_start-dt,model.run_stop+2*dt,dt)
    secs=(times-times[0])/np.timedelta64(1,'s')
    eta0=-1
    eta_bc=sun_driver.StageBC(name="eta_bc",
                              geom=np.array([ [0,0],
                                              [0,100]]),
                              z=eta0)

    model.add_bcs(eta_bc)
    model.add_bcs( [sun_driver.ScalarBC(parent=eta_bc,scalar="S",value=34),
                    sun_driver.ScalarBC(parent=eta_bc,scalar="T",value=15)] )

    model.set_run_dir('rundata_met_3d', mode='pristine')
    model.projection='EPSG:26910'
    model.num_procs=1 # test single first
    model.config['dt']=120
    model.config['ntout']=5
    model.config['Cmax']=30
    model.config['Nkmax']=10
    model.config['stairstep']=0
    model.config['mergeArrays']=0

    return model
Beispiel #7
0
def add_delta_bcs(model, cache_dir):
    # Delta inflow
    # SacRiver, SJRiver
    sac_bc = hm.NwisFlowBC(name='SacRiver',
                           station=11455420,
                           cache_dir=cache_dir,
                           filters=[hm.Lowpass(cutoff_hours=3)],
                           dredge_depth=model.dredge_depth)
    tmi_bc = hm.NwisFlowBC(
        name='SacRiver',
        station=11337080,
        cache_dir=cache_dir,
        filters=[hm.Lowpass(cutoff_hours=3),
                 hm.Transform(fn=lambda x: -x)],
        mode='add')

    sj_bc = hm.NwisFlowBC(name='SJRiver',
                          station=11337190,
                          cache_dir=cache_dir,
                          filters=[hm.Lowpass(cutoff_hours=3)],
                          dredge_depth=model.dredge_depth)
    dutch_bc = hm.NwisFlowBC(name='SJRiver',
                             station=11313433,
                             cache_dir=cache_dir,
                             filters=[hm.Lowpass(cutoff_hours=3)],
                             mode='add')

    sac_salt_bc = drv.ScalarBC(name='SacRiver', scalar='salinity', value=0.0)
    sj_salt_bc = drv.ScalarBC(name='SJRiver', scalar='salinity', value=0.0)
    sac_temp_bc = drv.ScalarBC(name='SacRiver',
                               scalar='temperature',
                               value=20.0)
    sj_temp_bc = drv.ScalarBC(name='SJRiver', scalar='temperature', value=20.0)

    model.add_bcs(
        [sac_bc, sj_bc, sac_salt_bc, sj_salt_bc, sac_temp_bc, sj_temp_bc])
Beispiel #8
0
model.set_grid(g)
model.run_start = np.datetime64("2018-01-01 00:00")
model.run_stop = np.datetime64("2018-01-01 10:00")

dt = np.timedelta64(600, 's')
times = np.arange(model.run_start - dt, model.run_stop + 2 * dt, dt)
secs = (times - times[0]) / np.timedelta64(1, 's')
eta_values = -6 + 0.75 * np.cos(secs * np.pi / 7200)
eta_da = xr.DataArray(eta_values, coords=[('time', times)])
eta_bc = sun_driver.StageBC(name="eta_bc",
                            geom=np.array([[0, 0], [0, 500]]),
                            z=eta_da)

model.add_bcs(eta_bc)
model.add_bcs([
    sun_driver.ScalarBC(parent=eta_bc, scalar="S", value=1),
    sun_driver.ScalarBC(parent=eta_bc, scalar="T", value=1)
])

# point source that is typically dry
hill_source = sun_driver.SourceSinkBC(name='inflow',
                                      geom=np.array([150, 150]),
                                      z=-10,
                                      Q=1.0)

# on a saddle
saddle_source = sun_driver.SourceSinkBC(name='inflow',
                                        geom=np.array([220, 225]),
                                        z=-10,
                                        Q=1.0)
def test_point_source_3d():
    """
    A square 3D grid with wetting and drying.
    the bathymetry is a wavy cos(x)*cos(y) function.
    two point sources and an oscillating freesurface.
    one point source at a saddle point, and the other
    on top of a bump which goes dry.

    This currently does pretty well, but it could be
    better -- see the test thresholds near the end which
    have been relaxed somewhat.
    """
    g=unstructured_grid.UnstructuredGrid(max_sides=4)
    g.add_rectilinear([0,0],[500,500],50,50)

    # wavy bed
    half_wave=150
    cc=g.cells_center()
    cell_depth=-6 + np.cos(cc[:,0]*np.pi/half_wave) * np.cos(cc[:,1]*np.pi/half_wave)
    g.add_cell_field('depth',cell_depth)

    model=sun_driver.SuntansModel()
    model.load_template('point_source_test.dat')
    model.set_grid(g)
    model.run_start=np.datetime64("2018-01-01 00:00")
    model.run_stop =np.datetime64("2018-01-01 10:00")

    dt=np.timedelta64(600,'s')
    times=np.arange(model.run_start-dt,model.run_stop+2*dt,dt)
    secs=(times-times[0])/np.timedelta64(1,'s')
    eta_values=-6 + 0.75*np.cos(secs*np.pi/7200)
    eta_da=xr.DataArray(eta_values,coords=[ ('time',times) ])
    eta_bc=sun_driver.StageBC(name="eta_bc",geom=np.array([ [0,0],
                                                            [0,500]]),
                              z=eta_da)

    model.add_bcs(eta_bc)
    model.add_bcs( [sun_driver.ScalarBC(parent=eta_bc,scalar="S",value=1),
                    sun_driver.ScalarBC(parent=eta_bc,scalar="T",value=1)] )

    # point source that is typically dry
    hill_source=sun_driver.SourceSinkBC(name='inflow',geom=np.array([150,150]),
                                        z=-10,Q=1.0)

    # on a saddle
    saddle_source=sun_driver.SourceSinkBC(name='inflow',geom=np.array([220,225]),
                                          z=-10,Q=1.0)

    model.add_bcs(hill_source)
    model.add_bcs(saddle_source)
    model.add_bcs( [sun_driver.ScalarBC(parent=hill_source,scalar="S",value=1),
                    sun_driver.ScalarBC(parent=hill_source,scalar="T",value=1)] )
    model.add_bcs( [sun_driver.ScalarBC(parent=saddle_source,scalar="S",value=1),
                    sun_driver.ScalarBC(parent=saddle_source,scalar="T",value=1)] )

    model.set_run_dir('rundata_point_3d', mode='pristine')
    model.projection='EPSG:26910'
    model.num_procs=4
    model.config['dt']=2.5
    model.config['ntout']=5
    model.config['Cmax']=30
    model.config['Nkmax']=10
    model.config['stairstep']=0
    model.config['mergeArrays']=0

    model.write()

    model.ic_ds.eta.values[:]=eta_da.values[1]
    model.ic_ds.salt.values[:]=1.0
    model.ic_ds.temp.values[:]=1.0
    model.write_ic_ds()

    model.partition()
    model.sun_verbose_flag='-v'
    model.run_simulation()

    for map_fn in model.map_outputs():
        ds=xr.open_dataset(map_fn)

        dzz=ds.dzz.values
        # This is not as strict as it should be.
        # should be 0.001 or less.
        dzz_thresh=0.05
        salt=ds.salt.values
        valid=np.isfinite(dzz) & (dzz>=dzz_thresh)
        salt_errors=salt[valid] - 1.0

        # This is not as strict as it should be.
        # we should be able to get this down to 1e-4 or
        # better.
        assert np.max( np.abs(salt_errors) )<0.01
        ds.close()
Beispiel #10
0
    if utils.is_stale(dest_grid, [src_grid, "bathy.py"]):
        set_bathy(src_grid, dest_grid)

    g = unstructured_grid.UnstructuredGrid.from_ugrid(dest_grid)
    g.cells['z_bed'] += z_offset_manual
    g.edges['edge_z_bed'] += z_offset_manual
    model.set_grid(g)
else:
    print("Grid comes from restart")
    model.dredge_depth = None  # no need to dredge grid if a restart

model.add_gazetteer("grid-lsb/linear_features.shp")

##

ocean_salt_bc = drv.ScalarBC(name='ocean', scalar='salinity', value=25)
ocean_temp_bc = drv.ScalarBC(name='ocean', scalar='temperature', value=10)
msl_navd88 = 0.94  # m

ocean_bc = drv.NOAAStageBC(
    name='ocean',
    station=9414575,  # Coyote - will come in as MSL
    # station=9414750, # Alameda.
    cache_dir=cache_dir,
    filters=[dfm.Lowpass(cutoff_hours=1.5)])
ocean_offset_bc = drv.StageBC(name='ocean',
                              mode='add',
                              z=z_offset_manual + msl_navd88)

model.add_bcs([ocean_bc, ocean_salt_bc, ocean_temp_bc, ocean_offset_bc])
Beispiel #11
0
# eta_da=xr.DataArray(eta_values,coords=[ ('time',times) ])
# eta_bc=sun_driver.StageBC(name="eta_bc",geom=np.array([ [0,0],
#                                                         [0,500]]),
#                           z=eta_da)
# model.add_bcs(eta_bc)
#model.add_bcs( [sun_driver.ScalarBC(parent=eta_bc,scalar="S",value=1),
#                sun_driver.ScalarBC(parent=eta_bc,scalar="T",value=1)] )

# on a saddle
source = sun_driver.SourceSinkBC(name='inflow',
                                 geom=np.array([5, 5]),
                                 z=-10,
                                 Q=1.0)
model.add_bcs(source)
model.add_bcs([
    sun_driver.ScalarBC(parent=source, scalar="S", value=1),
    sun_driver.ScalarBC(parent=source, scalar="T", value=1)
])

model.set_run_dir('rundata_1d', mode='pristine')
model.projection = 'EPSG:26910'
model.sun_bin_dir = "/home/rusty/src/suntans/main"

model.config['dt'] = 2.5
model.config['ntout'] = 1
model.config['Cmax'] = 30
model.config['Nkmax'] = 10
model.config['stairstep'] = 0
model.config['mergeArrays'] = 0

model.write()
Beispiel #12
0
def base_model():
    """
    A channel, uniform bathy.
    """
    g=unstructured_grid.UnstructuredGrid(max_sides=4)
    g.add_rectilinear([0,0],[1000,100],21,3)
    g.add_cell_field('depth',-6*np.ones(g.Ncells()))

    model=sun_driver.SuntansModel()
    model.load_template('point_source_test.dat')
    model.set_grid(g)
    model.run_start=np.datetime64("2018-01-01 00:00")
    model.run_stop =np.datetime64("2018-01-01 10:00")

    dt=np.timedelta64(600,'s')
    times=np.arange(model.run_start-dt,model.run_stop+2*dt,dt)
    secs=(times-times[0])/np.timedelta64(1,'s')
    eta0=-2
    eta_bc=sun_driver.StageBC(name="eta_bc",
                              geom=np.array([ [0,0],
                                              [0,100]]),
                              z=eta0)

    model.add_bcs(eta_bc)
    model.add_bcs( [sun_driver.ScalarBC(parent=eta_bc,scalar="S",value=1),
                    sun_driver.ScalarBC(parent=eta_bc,scalar="T",value=1)] )

    model.set_run_dir('rundata_sedi_3d', mode='pristine')
    model.projection='EPSG:26910'
    model.num_procs=1 # test single first
    model.config['dt']=30
    model.config['ntout']=5
    model.config['Cmax']=30
    model.config['Nkmax']=10
    model.config['stairstep']=0
    model.config['mergeArrays']=0

    # Sediment:
    model.config['computeSediments']=1   # whether include sediment model
    
    model.config['Nlayer']=0 # Number of bed layers (MAX = 5)
    model.config['Nsize']=3  # Number of sediment fractions (Max = 3)
    model.config['TBMAX']=1  # whether to output tb for each cell
    model.config['SETsediment']=0       # When Nlayer>5 or Nsize>3, SETsediment=1 to use SetSediment 
    model.config['WSconstant']=1       # if 1, ws for sediment = ws0
    model.config['readSediment']=0       # if 1, read sediment concentration data as IC. only work with Nsize==1
    model.config['bedInterval']=150     # the interval steps to update bed change
    model.config['bedComplex']=0       # whether to consider the possibility to flush away a whole layer
    model.config['ParabolKappa']=0       # whether to use parabolic tubulent diffusivity
    model.config['Ds90']=0.000008    # ds90 for calculation of erosion taub
    model.config['Ds1']=0.00000057   # sediment diameter for fraction No.1 (m)
    model.config['Ds2']=0.0002    # sediment diameter for fraction No.2                   
    model.config['Ds3']=0.0002    # sediment diameter for fraction No.3
    model.config['Ws01']= 0.0001     # constant settling velocity for fraction No.1 (m/s)
    model.config['Ws02']= 0.01     # constant settling velocity for fraction No.2
    model.config['Ws03']=-0.01     # constant settling velocity for fraction No.3
    model.config['Gsedi1']=2.65      # relative density for fraction No.1
    model.config['Gsedi2']=2.65      # relative density for fraction No.2
    model.config['Gsedi3']=2.65      # relative density for fraction No.3
    model.config['Prt1']=1       # Prandtl Number for fraction No.1
    model.config['Prt2']=1       # Prandtl Number for fraction No.2
    model.config['Prt3']=1       # Prandtl Number for fraction No.3
    model.config['Consolid1']=0.00    # Consolidation rate (g/m^2/s) for layer No.1
    model.config['E01']=0.1      # Basic Erosion Rate Constant (g/m^2/s) for layer No.1
    model.config['Taue1']=0.0       # Erosion Critical Shear Stress (N/m^2) for layer No.1
    # Taud1 isn't actually used in current code.  Deposition always occurs at the rate
    # of w_s.
    model.config['Taud1']=0.0       # Deposition Critical Shear Stress (N/m^2) for layer No.1
    model.config['Drydensity1']=530000    # Dry density (g/m^3) for layer No.1
    model.config['Thickness1']=0.0      # Thickness (m) for layer No.1
    model.config['softhard1']=1         # 0 soft or hard for layer No.1 to decide how to calculate erosion
    model.config['Bedmudratio1']=0.8       # Bed mud ratio for layer No.1
    model.config['Chind']=1000000   # Concentration (in volumetric fraction) criterion for hindered settling velocity
    model.config['Cfloc']=500000    # Concentration (in volumetric fraction) criterion for flocculated settling velcoity
    model.config['k']=0.0002    # Constant coefficient for settling velocity as a function of conc.

    model.config['Sediment1File']='sedi1.dat'
    model.config['Sediment2File']='sedi2.dat'
    model.config['Sediment3File']='sedi3.dat'
    model.config['LayerFile']='sedilayer.dat'
    model.config['tbFile']='Seditb.dat'
    model.config['tbmaxFile']='Seditbmax.dat'
    return model