コード例 #1
0
    def __init__(self, par):
        cmf.set_parallel_threads(1)

        # run the model
        self.project = cmf.project()
        self.cell = self.project.NewCell(x=0, y=0, z=238.628, area=1000, with_surfacewater=True)
        c = self.cell
        r_curve = cmf.VanGenuchtenMualem(Ksat=10**par.pKsat, phi=par.porosity, alpha=par.alpha, n=par.n)

        # Make the layer boundaries and create soil layers
        lthickness = [.01] * 5 + [0.025] * 6 + [0.05] * 6 + [0.1] * 5
        ldepth = np.cumsum(lthickness)

        # Create soil layers and pick the new soil layers if they are inside of the evaluation depth's

        for d in ldepth:
            c.add_layer(d, r_curve)

        # Use a Richards model
        c.install_connection(cmf.Richards)

        # Use shuttleworth wallace
        self.ET = c.install_connection(cmf.ShuttleworthWallace)

        c.saturated_depth = 0.5

        self.gw = self.project.NewOutlet('groundwater', x=0, y=0, z=.9)
        cmf.Richards(c.layers[-1], self.gw)
        self.gw.potential = c.z - 0.5 #IMPORTANT
        self.gw.is_source = True
        self.gwhead = cmf.timeseries.from_scalar(c.z - 0.5)

        self.solver = cmf.CVodeIntegrator(self.project, 1e-9)
コード例 #2
0
def canopyStorage():
    import cmf
    import pylab as plt

    p = cmf.project()
    c = p.NewCell(0, 0, 0, 1000, True)
    # Add a single layer of 1 m depth
    l = c.add_layer(1.0, cmf.VanGenuchtenMualem())
    # Use GreenAmpt infiltration from surface water
    c.install_connection(cmf.GreenAmptInfiltration)
    # Add a groundwater boundary condition
    gw = p.NewOutlet('gw', 0, 0, -2)
    # Use a free drainage connection to the groundwater
    cmf.FreeDrainagePercolation(l, gw)

    # Add some rainfall
    c.set_rainfall(5.0)

    # Make c.canopy a water storage
    c.add_storage('Canopy', 'C')
    # Split the rainfall from the rain source (RS) between
    # intercepted rainfall (RS->canopy) and throughfall (RS-surface)
    cmf.Rainfall(c.canopy, c, False, True)  # RS->canopy, only intercepted rain
    cmf.Rainfall(c.surfacewater, c, True, False)  # RS->surface, only throughfall
    # Use an overflow mechanism, eg. the famous Rutter-Interception Model
    cmf.RutterInterception(c.canopy, c.surfacewater, c)
    # And now the evaporation from the wet canopy (using a classical Penman equation)
    cmf.CanopyStorageEvaporation(c.canopy, c.evaporation, c)

    solver = cmf.CVodeIntegrator(p, 1e-9)
    res = [l.volume for t in solver.run(solver.t, solver.t + cmf.day, cmf.min * 15)]

    plt.figure()
    plt.plot(res)
    plt.show()
コード例 #3
0
ファイル: fit_retention_curve.py プロジェクト: zutn/cmf
def make_vgm(params):
    try:
        vgm = cmf.VanGenuchtenMualem(1.0)
        vgm.Phi = params[0]
        vgm.alpha = params[1]
        vgm.n = params[2]
        if len(params) > 3:
            vgm.theta_r = params[3]
        return vgm
    except RuntimeError:
        return None
コード例 #4
0
        def retention_curve(r_curve_: dict):
            """
            Converts a dict of retention curve parameters into a CMF van Genuchten-Mualem retention curve.
            :param r_curve_: dict
            :return: CMF retention curve
            """

            curve = cmf.VanGenuchtenMualem(r_curve_['K_sat'], r_curve_['phi'],
                                           r_curve_['alpha'], r_curve_['n'],
                                           r_curve_['m'])
            curve.l = r_curve_['l']

            return curve
コード例 #5
0
 def cell_setup(self):
     """
     Creates a cmf cell with all its layers and DECOMP pools
     :return: decomp.cmfconnector.CmfConnector
     """
     p = self.project
     c = p.NewCell(0, area=1000, with_surfacewater=True)
     vgm = cmf.VanGenuchtenMualem()
     vgm.fit_w0()
     for d in self.depth:
         vgm.Ksat = 10 * 2**-d
         c.add_layer(d, vgm)
     c.install_connection(cmf.Richards)
     c.install_connection(cmf.GreenAmptInfiltration)
     return CmfConnector(c, 5)
コード例 #6
0
 def set_parameters(self, par):
     """
     Sets the parameters of the model
     :param par: The parameter value object (named tuple)
     :return:
     """
     try:
         for l in self.cell.layers:
             r_curve = cmf.VanGenuchtenMualem(Ksat=10**par.pKsat, phi=par.porosity, alpha=par.alpha, n=par.n)
             r_curve.w0 = r_curve.fit_w0()
             l.soil = r_curve
         self.cell.saturated_depth = 0.5
         self.gw.potential = self.cell.z - 0.5
     except RuntimeError as e:
         sys.stderr.write('Set parameters failed with:\n' + str(par) + '\n' + str(e))
         raise
コード例 #7
0
ファイル: hydrology.py プロジェクト: livestock3d/livestock
def create_retention_curve(retention_curve: dict) -> cmf.VanGenuchtenMualem:
    """
    Converts a dict of retention curve parameters into a CMF van
    Genuchten-Mualem retention curve.

    :param retention_curve: dict
    :return: CMF retention curve
    """

    curve = cmf.VanGenuchtenMualem(retention_curve['k_sat'],
                                   retention_curve['phi'],
                                   retention_curve['alpha'],
                                   retention_curve['n'], retention_curve['m'])
    curve.l = retention_curve['l']

    logger.debug(f'Created retention curve.')

    return curve
コード例 #8
0
def fit_vgm(pF,
            theta,
            variable_m=False,
            count=20,
            fitlevel=None,
            verbose=False):
    """Fits a Van Genuchten / Mualem retention curve into data
    pF: a sequence of pF values
    theta: an array of water contents
    alpha_range: a 2-sequence holding the range for alpha values
    n_range: a 2-sequence holding the range for n values
    """
    theta_mean = np.mean(theta)
    ns_denom = np.sum((theta - theta_mean)**2)

    best_f = 1e120
    vgm = None
    for i in range(count):
        x0 = [
            random.uniform(0.01, 0.99),
            random.uniform(0.0001, 1.9),
            random.uniform(1.01, 3.9),
            random.uniform()
        ]
        x0[-1] *= x0[0]
        if variable_m: x0.append(1 - 1 / random.uniform(1.01, 5))
        x_opt, f_opt, n_iter, n_eval, warn = opt.fmin(get_error_vgm,
                                                      x0=np.array(x0),
                                                      args=(pF, theta),
                                                      full_output=True,
                                                      disp=False)
        if f_opt < best_f:
            if verbose:
                print("%i: x=%s f=%0.12g iter=%i, eval=%i" %
                      (i, x_opt, f_opt, n_iter, n_eval))
            vgm = cmf.VanGenuchtenMualem(1, *x_opt)
            best_f = f_opt
            if fitlevel and best_f < fitlevel:
                break
    theta_mean = np.mean(theta)
    return vgm, best_f
コード例 #9
0
def soiltype(depth):
    return cmf.VanGenuchtenMualem(Ksat=15 * exp(-d),
                                  phi=0.5,
                                  n=1.5,
                                  alpha=0.3
                                  )
コード例 #10
0
@author: kraft-p
"""

import cmf
# Create project with space delimited tracer names
p = cmf.project('X Y Z')
# Get the tracers as variables
X, Y, Z = p.solutes

# Create a single cell c with a surfacewater storage, which references 3 solute storages
c = p.NewCell(0, 0, 0, 1000, with_surfacewater=True)
# Create 50 layers with 2cm thickness
for i in range(50):
    # Add a layer. Each layer will reference 3 solute storages
    l = c.add_layer((i + 1) * 0.02, cmf.VanGenuchtenMualem())
    # Add a 10% decay per day for Tracer z
    l.Solute(Z).decay = 0.25

# Use Richards equation
c.install_connection(cmf.Richards)
# Use a constant rainfall of 50 mm
c.set_rainfall(100.)
# Make a groundwater boundary condition
gw = p.NewOutlet('gw', 0, 0, -1.5)
cmf.Richards(c.layers[-1], gw)

# Template for the water solver
#wsolver = cmf.CVodeIntegrator(1e-9)
# Template for the solute solver
#ssolver = cmf.ImplicitEuler(1e-9)
コード例 #11
0
    def create_layers(self, soil_horizons, params, based_on_spotpy=False):
        """
        Creates a list of layers with attributes taken from a csv file (created via Brook90).

        :param params: class containing all parameters
        :param based_on_spotpy:
        :param soil_horizons: data frame including Van-Genuchten-Mualem soil parameters
        :return: A list of the lower boundaries of all created layer
        """
        layer_boundary = []
        layer_type = []

        for i, row in soil_horizons.iterrows():
            depth = -soil_horizons['Depth(m)'][i]  # for positive values
            if depth > 0:
                layer_boundary.append(depth)
                layer_type.append(row['HorId'])

                if row['HorId'] == 'Ah':
                    phi = params.porosity_mx_ah
                    w0 = params.w0_ah
                elif row['HorId'] == 'Bv1':
                    phi = params.porosity_mx_bv1
                    w0 = params.w0_bv1
                elif row['HorId'] == 'Bv2':
                    phi = params.porosity_mx_bv2
                    w0 = params.w0_bv2
                else:
                    phi = (params.porosity_mx_ah + params.porosity_mx_bv1 +
                           params.porosity_mx_bv2) / 3
                    w0 = (params.w0_ah + params.w0_bv1 + params.w0_bv2) / 3

                if based_on_spotpy:
                    if row['HorId'] == 'Ah':
                        k = params.ksat_mx_ah
                        alpha = params.alpha_ah
                        n = params.n_ah
                        m = params.m_ah
                    elif row['HorId'] == 'Bv1':
                        k = params.ksat_mx_bv1
                        alpha = params.alpha_bv1
                        n = params.n_bv1
                        m = params.m_bv1
                    elif row['HorId'] == 'Bv2':
                        k = params.ksat_mx_bv2
                        alpha = params.alpha_bv2
                        n = params.n_bv2
                        m = params.m_bv2
                    else:
                        k = (params.ksat_mx_ah + params.ksat_mx_bv1 +
                             params.ksat_mx_bv2) / 3
                        alpha = (params.alpha_ah + params.alpha_bv1 +
                                 params.alpha_bv2) / 3
                        n = (params.n_ah + params.n_bv1 + params.n_bv2) / 3
                        m = (params.m_ah + params.m_bv1 + params.m_bv2) / 3
                else:
                    k = row['KS/KF[m/d]']
                    alpha = row['Alfa/PsiF[m-1]/[kPa]'] / 100
                    n = row['n/b']
                    m = 1 - 1 / n

                vgm = cmf.VanGenuchtenMualem(Ksat=k,
                                             phi=phi,
                                             alpha=alpha,
                                             n=n,
                                             m=m,
                                             w0=w0)
                self.c.add_layer(depth, vgm)

        return layer_boundary, layer_type
コード例 #12
0
import cmf
from cmf.geos_shapereader import Shapefile as cmf_shape

p = cmf.project()
r_curve = cmf.VanGenuchtenMualem()

# Load cell polygons from file
path = r'C:\Users\Christian\Desktop\Livestock\shapefiles\shape_mesh.shp'
polygons = cmf_shape(path)

# create cell mesh from polygons
cells = p.cells_from_polygons(polygons)

for c in p.cells:
    # Add ten layers
    for i in range(10):
        c.AddLayer((i + 1) * 0.1, r_curve)
    cmf.Richards.use_for_cell(c)
    c.surfacewater_as_storage()
# subsurface flow
cmf.connect_cells_with_flux(p, cmf.Richards_lateral)
# surface runoff
cmf.connect_cells_with_flux(p, cmf.Manning_Kinematic)
コード例 #13
0
# create a project
p = cmf.project()

for i in range(20):
    x = i * 10.
    # create a cell with surface storage
    c = p.NewCell(x,0,z(x),100,True)

for c_upper, c_lower in zip(p[:-1], p[1:]):
    c_upper.topology.AddNeighbor(c_lower, 10.)

# Customize cells
for c in p:
    # create layers
    for d in [0.02,0.05,0.1,0.2,0.3,0.5,0.75,1.0,1.25,1.5,1.75,2.]:
        rc = cmf.VanGenuchtenMualem(Ksat=50*np.exp(-d),alpha=0.1,n=2.0,phi=0.5)
        rc.w0 = 0.9996
        c.add_layer(d,rc)
    # set initial conditions
    c.saturated_depth=2.
    # use Richards connection
    c.install_connection(cmf.Richards)
    c.install_connection(cmf.GreenAmptInfiltration)
    # Add more connections here... (eg. ET, snowmelt, canopy overflow)

cmf.connect_cells_with_flux(p,cmf.Darcy)
cmf.connect_cells_with_flux(p,cmf.KinematicSurfaceRunoff)

for c in p:
    c.set_rainfall(10.)
コード例 #14
0
    def aggregate_infiltration(self, t):
        return np.array([mp.flux_to(mp.layer, t) for mp in self])


# Create project and a cell with surfacewater
if 'X' in sys.argv:
    p = cmf.project('X')
    X, = p.solutes
else:
    p = cmf.project()
    X = None
c = p.NewCell(0, 0, 0, 1000, True)

# Add some layers
vgm = cmf.VanGenuchtenMualem(Ksat=Ksat_mx, phi=0.5)
for d in np.arange(0, 1, 0.02):
    c.add_layer(d + .02, vgm)

# Use Richards equation for matrix transport
c.install_connection(cmf.Richards)
c.install_connection(cmf.MatrixInfiltration)

# Create Macropore storages for each layer
macropores = MacroPoreList(
    cmf.MacroPore.create(
        l, porefraction=porefraction, Ksat=Ksat_mp, density=0.1)
    for l in c.layers)
# Macro pore infiltration
cmf.KinematicMacroFlow(c.surfacewater, macropores[0])
# Macro pore percolation
コード例 #15
0
        if i:
            c.topology.AddNeighbor(cells[i-1,j],length*.75)
        if j:
            c.topology.AddNeighbor(cells[i,j-1],length*.75)
        #if i and j:
            #c.topology.AddNeighbor(cells[i,j-1],length*.5)
            
            
for c in p:
    c.surfacewater_as_storage()
    # 1mm puddle depth
    c.surfacewater.puddledepth = 0.001 #np.random.uniform(0.0,0.001)
    #c.surfacewater.depth = 0.002
    # Asphalt        
    c.surfacewater.nManning = 0.015 
    c.add_layer(0.1, cmf.VanGenuchtenMualem(Ksat=0.005))
    c.install_connection(cmf.GreenAmptInfiltration)

cmf.DiffusiveSurfaceRunoff.set_linear_slope(1e-8)
cmf.connect_cells_with_flux(p, cmf.DiffusiveSurfaceRunoff)
outlet = p.NewOutlet('outlet',-length,0,-slope*length)
#for j in range(size[1]):
#    for i in range(size[0]):
#        is_border = i in [0,size[0]-1] or j in [0, size[1]-1]
#        if is_border:
#            cmf.waterbalance_connection(cells[i,j].surfacewater,outlet)
cmf.DiffusiveSurfaceRunoff(cells[0,0].surfacewater, outlet,length)

def setrain(rainfall):
    for c in p:
        c.set_rainfall(rainfall)
コード例 #16
0
def simple1D():
    from matplotlib import pyplot as plt
    import cmf
    from datetime import datetime, timedelta

    project = cmf.project()

    # Add one cell at position (0,0,0), Area=1000m2
    cell = project.NewCell(0, 0, 0, 1000, with_surfacewater=True)

    # Create a retention curve
    r_curve = cmf.VanGenuchtenMualem(Ksat=1, phi=0.5, alpha=0.01, n=2.0)

    # Add ten layers of 10cm thickness
    for i in range(10):
        depth = (i + 1) * 0.1
        cell.add_layer(depth, r_curve)

    # Connect layers with Richards perc.
    # this can be shorten as
    cell.install_connection(cmf.Richards)

    # Create solver
    solver = cmf.CVodeIntegrator(project, 1e-6)
    solver.t = cmf.Time(1, 1, 2011)

    # Create groundwater boundary (uncomment to use it)
    # Create the boundary condition
    gw = project.NewOutlet('groundwater', x=0, y=0, z=-1.1)

    # Set the potential
    gw.potential = -2

    # Connect the lowest layer to the groundwater using Richards percolation
    gw_flux=cmf.Richards(cell.layers[-1],gw)


    # Set inital conditions
    # Set all layers to a potential of -2 m
    cell.saturated_depth = 2.

    # 100 mm water in the surface water storage
    cell.surfacewater.depth = 0.1

    # The run time loop, run for 72 hours
    # Save potential and soil moisture for each layer
    potential = [cell.layers.potential]
    moisture = [cell.layers.theta]

    for t in solver.run(solver.t, solver.t + timedelta(days=7), timedelta(hours=1)):
        potential.append(cell.layers.potential)
        moisture.append(cell.layers.theta)
    """
    # Plot results
    plt.subplot(211)
    plt.plot(moisture)
    plt.ylabel(r'Soil moisture $\theta [m^3/m^3]$')
    plt.xlabel(r'$time [h]$')
    plt.grid()
    plt.subplot(212)
    plt.plot(potential)
    plt.ylabel(r'Water head $\Psi_{tot} [m]$')
    plt.xlabel(r'$time [h]$')
    plt.grid()
    plt.show()
    """

    print(cell.vegetation)
コード例 #17
0
 def _run(self, alpha=None, n=None, porosity=None, ksat=None):
     #return alpha,n,porosity,ksat
     '''
     Runs the model instance
     
     Input: Parameter set (in this case VAN-Genuchten Parameter alpha,n,porosity,ksat)
     Output: Simulated values on given observation days
     '''
     #Check if given parameter set is in realistic boundaries
     if alpha<self.bound[0][0] or alpha>self.bound[0][1] or ksat<self.bound[1][0] \
     or ksat>self.bound[1][1] or n<self.bound[2][0] or n>self.bound[2][1] or \
     porosity<self.bound[3][0] or porosity>self.bound[3][1]:
         print('The following combination was ignored')
         text = 'n= ' + str(n)
         print(text)
         text = 'alpha=' + str(alpha)
         print(text)
         text = 'ksat= ' + str(ksat)
         print(text)
         text = 'porosity= ' + str(porosity)
         print(text)
         print('##############################')
         return self.observations * -np.inf
     else:
         project = cmf.project()
         cell = project.NewCell(x=0,
                                y=0,
                                z=0,
                                area=1000,
                                with_surfacewater=True)
         text = 'n= ' + str(n)
         print(text)
         text = 'alpha=' + str(alpha)
         print(text)
         text = 'ksat= ' + str(ksat)
         print(text)
         text = 'porosity= ' + str(porosity)
         print(text)
         print('##############################')
         r_curve = cmf.VanGenuchtenMualem(Ksat=ksat,
                                          phi=porosity,
                                          alpha=alpha,
                                          n=n)
         layers = 5
         ldepth = .01
         for i in range(layers):
             depth = (i + 1) * ldepth
             cell.add_layer(depth, r_curve)
         cell.install_connection(cmf.Richards)
         cell.install_connection(cmf.ShuttleworthWallace)
         cell.saturated_depth = .5
         solver = cmf.CVodeIntegrator(project, 1e-6)
         self._load_meteo(project)
         gw = project.NewOutlet('groundwater', x=0, y=0,
                                z=.9)  #layers*ldepth)
         cmf.Richards(cell.layers[-1], gw)
         gw.potential = -.5  #IMPORTANT
         gw.is_source = True
         solver.t = self.datastart
         Evalstep, evallist = 0, []
         rundays = (self.dataend - self.datastart).days
         for t in solver.run(solver.t, solver.t + timedelta(days=rundays),
                             timedelta(hours=1)):
             if self.gw_array['Date'].__contains__(t) == True:
                 Gw_Index = np.where(self.gw_array['Date'] == t)
                 gw.potential = self.gw_array[self.piezometer][Gw_Index]
                 print(gw.potential
                       )  #TO DO: CHECK IF SOMETHING HAPPENS HERE!!!!
             if t > self.analysestart:
                 if Evalstep != len(self.eval_dates
                                    ) and t == self.eval_dates[Evalstep]:
                     evallist.append(cell.layers.wetness[0] *
                                     cell.layers.porosity[0] * 100)
                     Evalstep += 1
         return evallist