Ejemplo n.º 1
0
 def __call__(self, days=7):
     self.c.vegetation.LAI = 7
     self.c.vegetation.height = 10
     self.c.vegetation.CanopyClosure = 0.1
     l = self.c.layers[0]
     self.c.surfacewater.depth = 0.05
     l.soil.Ksat = 0.02
     l.volume = 100
     self.c.canopy.volume = self.c.vegetation.LAI * self.c.vegetation.CanopyCapacityPerLAI
     self.c.set_uptakestress(cmf.VolumeStress(10, 0))
     Vc0 = self.c.canopy.volume
     Vl0 = self.c.layers[0].volume
     Vs0 = self.c.surfacewater.volume
     solver = cmf.CVodeIntegrator(self.p, 1e-9)
     vol = []
     flux = []
     resistance = []
     mpot = []
     self.et.refresh(cmf.Time())
     for t in solver.run(cmf.Time(), cmf.day * days, cmf.min * 6):
         #print(f'{t}: {self.c.surfacewater.depth:0.3f}m')
         vol.append(
             (self.c.canopy.volume / Vc0, self.c.surfacewater.volume / Vs0,
              self.c.layers[0].volume / Vl0))
         flux.append((
             self.c.canopy.flux_to(self.c.evaporation, t),
             self.c.surfacewater.flux_to(self.c.evaporation, t),
             self.c.layers[0].flux_to(self.c.evaporation, t),
             self.c.layers[0].flux_to(self.c.transpiration, t),
             self.c.surfacewater.flux_to(self.c.layers[0], t),
         ))
         resistance.append((self.et.RAA, self.et.RAC, self.et.RAS,
                            self.et.RSC, self.et.RSS))
         mpot.append(self.c.surface_water_coverage())
     return vol, flux, resistance, mpot
Ejemplo n.º 2
0
    def solve(self, cmf_project, tolerance):
        """Solves the model"""

        # Create solver, set time and set up results
        solver = cmf.CVodeIntegrator(cmf_project, tolerance)
        solver.t = cmf.Time(1, 1, 2017)
        self.config_outputs(cmf_project)

        # Save initial conditions to results
        self.gather_results(cmf_project, solver.t)

        # Set timer
        start_time = datetime.now()
        step = 0
        last = start_time

        # Run solver and save results at each time step
        for t in solver.run(
                solver.t, solver.t +
                timedelta(hours=self.solver_settings['analysis_length']),
                timedelta(hours=float(self.solver_settings['time_step']))):

            self.gather_results(cmf_project, t)
            last = self.print_solver_time(t, start_time, last, step)
            step += 1

        self.solved = True
        return True
Ejemplo n.º 3
0
    def runmodel(self, verbose=False):
        """
        Runs the model and saves the results
        """
        solver = cmf.CVodeIntegrator(self.project, 1e-9)
        c = self.project[0]

        # result timeseries
        res_q = cmf.timeseries(self.begin, cmf.day)

        tstart = datetime.datetime.now()
        # start solver and calculate in daily steps
        for t in solver.run(self.data.begin, self.end, cmf.day):
            if t > self.begin:
                # append results, when spin up time is over
                res_q.add(self.outlet.waterbalance(t))
            # Give the status the screen to let us know what is going on
            if verbose:
                print(t, 'P={:5.3f}'.format(c.get_rainfall(t)))
            if datetime.datetime.now() - tstart > datetime.timedelta(minutes=self.max_run_minutes):
                print('Cancelled, since it took more than {} minutes'.format(self.max_run_minutes))
                for t in cmf.timerange(solver.t, self.end, cmf.day):
                    res_q.add(np.nan)

        return res_q
    def run_model(self):
        """
        Starts the model. Used by spotpy
        """
        try:
            # Create a solver for differential equations
            solver = cmf.CVodeIntegrator(self.project, 1e-8)

            # New time series for model results
            resQ = cmf.timeseries(self.begin, cmf.day)
            # starts the solver and calculates the daily time steps
            end = self.end
            for t in solver.run(self.project.meteo_stations[0].T.begin, end,
                                cmf.day):

                # Fill the results (first year is included but not used to
                # calculate the NS)
                if t >= self.begin:
                    resQ.add(self.outlet.waterbalance(t))

            return resQ

        # Return an nan - array when a runtime error occurs
        except RuntimeError:
            return np.array(self.Q[self.begin:self.end +
                                   datetime.timedelta(days=1)]) * np.nan
Ejemplo n.º 5
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)
Ejemplo n.º 6
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()
Ejemplo n.º 7
0
 def run_model(self):
     """
     Starts the model. Used by spotpy
     """
     print("Start running model")
     try:
         # Create a solver for differential equations
         solver = cmf.CVodeIntegrator(self.project, 1e-9)
         solver.LinearSolver = 0
         self.solver = solver
         # New time series for model results
         resQ = cmf.timeseries(self.begin, cmf.day)
         # starts the solver and calculates the daily time steps
         end = self.end  # datetime.datetime(1979,1,7,9)
         tstart = time.time()
         tmax = 300
         for t in solver.run(self.project.meteo_stations[0].T.begin, end,
                             cmf.day):
             # Fill the results (first year is included but not used to
             # calculate the NS)
             print(t)
             if t >= self.begin:
                 resQ.add(self.outlet.waterbalance(t))
             if time.time() - tstart > tmax:
                 raise RuntimeError(
                     'Took more than {:0.1f}min to run'.format(tmax / 60))
         print("Finished running model")
         return resQ
     # Return an nan - array when a runtime error occurs
     except RuntimeError as error:
         print(error)
         print("FInished running model")
         return np.array(self.Q[self.begin:self.end +
                                datetime.timedelta(days=1)]) * np.nan
Ejemplo n.º 8
0
    def runmodel(self, verbose=False):
        """
        starts the model
        if verboose = True --> give something out for every day
        """
        try:
            # Creates a solver for the differential equations
            solver = cmf.CVodeIntegrator(self.project, 1e-8)
            solver.LinearSolver = 0
            solver.max_step = cmf.h

            # New time series for model results (res - result)
            sim_dis = cmf.timeseries(self.begin, cmf.day)
            # starts the solver and calculates the daily time steps
            end = self.end
            if verbose:
                print("Start running")
            for t in solver.run(self.project.meteo_stations[0].T.begin, end,
                                cmf.day):
                # Fill the results
                # print(t)
                if t >= self.begin:
                    sim_dis.add(self.outlet.waterbalance(t))

            # Return the filled result time series
            if verbose:
                print("Finished running")
            return sim_dis
        except RuntimeError:
            return np.array(self.Q[self.begin:self.end]) * np.nan
Ejemplo n.º 9
0
 def make_integrator(self):
     """
     Create the solver
     :return:
     """
     winteg = cmf.CVodeIntegrator(1e-9)
     sinteg = cmf.HeunIntegrator()
     integ = cmf.SoluteWaterIntegrator(self.project.solutes, winteg, sinteg,
                                       self.project)
     return integ
Ejemplo n.º 10
0
    def iterate(self, p=None):
        """
        Calls `create_connections` and `inital_values` to shape
        the model using the parameter set `p` and returns an
        iterator that advances the model over the whole data period
        """
        self.create_connections(p)
        self.initial_values(p)

        solver = cmf.CVodeIntegrator(self.project, 1e-9)
        solver.use_OpenMP = False
        return solver.run(self.data.begin, self.data.end, cmf.day)
    def run(self, begin=None, end=None):
        begin = begin or self.rainstation.data.begin
        end = end or self.rainstation.data.end

        solver = cmf.CVodeIntegrator(self.project, 1e-9)
        outlet = cmf.timeseries(begin, cmf.day)
        outlet.add(self.outlet(begin))
        for t in solver.run(begin, end, cmf.day):
            outlet.add(self.outlet.add)
            print(t)

        return outlet
Ejemplo n.º 12
0
    def __init__(self,
                 subsurface_lateral_connection,
                 surface_lateral_connection=None,
                 layercount=0):
        """
        Creates the cmf project

        :param subsurface_lateral_connection: Type of lateral subsurface connection, eg. cmf.Darcy
        :param surface_lateral_connection:  Type of lateral surface flux connection, eg. cmf.KinematicSurfaceRunoff or None
        :param layercount: Number of layers in the subsurface
        :return:
        """

        p = cmf.project()
        shp = Shapefile('data/vollnkirchner_bach_cells.shp')

        # Create cells
        self.outlet_cells = []
        for feature in shp:
            # Create a cell for each feature in the shape file
            c = cmf.geometry.create_cell(p,
                                         feature.shape,
                                         feature.HEIGHT,
                                         feature.OID,
                                         with_surfacewater=False)

            # If it is an outlet feature, add cell to the list of outletcells
            if feature.LANDUSE_CU.startswith('outlet'):
                self.outlet_cells.append(c)
            else:
                # If it is a normal upload cell, add layers
                self.build_cell(c, layercount)

        # Build topology
        cmf.geometry.mesh_project(p, verbose=True)

        # Connect cells with fluxes
        cmf.connect_cells_with_flux(p, subsurface_lateral_connection)
        if surface_lateral_connection:
            cmf.connect_cells_with_flux(p, surface_lateral_connection)

        # Connect outlets with neighbor cells
        for o_cell in self.outlet_cells:
            self.connect_outlet_cell(o_cell, subsurface_lateral_connection,
                                     surface_lateral_connection)
        # Load driver data
        load_meteo(p)
        self.project = p
        self.solver = cmf.CVodeIntegrator(p, 1e-9)
        self.solver.t = p.meteo_stations[0].T.begin
Ejemplo n.º 13
0
    def runmodel(self, verbose=False):
        """
        starts the model
        if verboose = True --> give something out for every day    
        """
        try:
            # Creates a solver for the differential equations
            #solver = cmf.ImplicitEuler(self.project,1e-8)
            solver = cmf.CVodeIntegrator(self.project, 1e-8)
            # usually the CVodeIntegrator computes the jakobi matrix only
            # partially to save computation time. But in models with low spatial
            # complexity this leads to a longer computational time
            # therefore the jakob matrix is computed completely to speed things up
            # this is done by LinearSolver = 0
            solver.LinearSolver = 0
            c = self.project[0]
            solver.max_step = cmf.h

            # New time series for model results (res - result)
            resQ = cmf.timeseries(self.begin, cmf.day)
            # starts the solver and calculates the daily time steps
            end = self.end
            if self.with_valid_data:
                end = datetime.datetime(1988, 12, 31)

            for t in solver.run(self.project.meteo_stations[0].T.begin, end,
                                cmf.day):
                # Fill the results
                if t >= self.begin:
                    resQ.add(self.outlet.waterbalance(t))
                # Print a status report
                if verbose:
                    print(t, 'Q=%5.3f, P=%5.3f' % (resQ[t], c.get_rainfall(t)))

                # Print that one year was calculated, so one knows the model is still working
                #### comment this out if run on supercomputer to avoid spam ######
                #if t % cmf.year ==  cmf.year - cmf.year:
                #   print("Finished one year")

            # Return the filled result time series
            return resQ
        except RuntimeError:
            return np.array(self.Q[self.begin:self.end +
                                   datetime.timedelta(days=1)]) * np.nan
Ejemplo n.º 14
0
    def plot_Vt(self, label=None):
        """
        Plots an integration of the Volume over 1 week
        starting with a volume of 2 m³ in W1 and an empty W2
        """
        self.w1.volume = 2.0
        self.w2.volume = 0.0
        label = label or self.con.to_string()
        solver = cmf.CVodeIntegrator(self.p, 1e-9)
        V0 = self.w1.volume
        t, vol = zip(*[(0, V0)] +
                     [(t / cmf.day, self.w1.volume)
                      for t in solver.run(cmf.Time(), cmf.week, cmf.h)])

        plt.plot(t, vol, label=label)
        plt.xlabel(r'$t\ in\ days$')
        plt.ylabel(r'$V\ in\ m^3$')
        plt.yticks([0, 1, 2], ['0', '$V_0$', '$V(t_0)$'])
        plt.grid(True)
Ejemplo n.º 15
0
    def run(self, verbose=False):
        """
        Runs the model.

        Parameters
        ----------
        verbose : bool, optional
            Whether progress is printed. The default is False.

        Returns
        -------
        resdf : pd.DataFrame
            Model results provided as time series (DatetimeIndex)
            Column 0 ('Darcy flow'): Modelled outflow (Darcy flow) [mm/min].
            Column 1 ('Surface runoff'): Modelled outflow (Surface runoff) [mm/min].
            Column 2 ('Water level'): Time series of lists including the water level along horizontal axis [m].
            Column 3 ('Ponding'): Time series of lists including the ponding on the surface along horizontal axis [m].

        """
        solver = cmf.CVodeIntegrator(self, 1e-9)
        list_t = list()
        list_q = list()
        list_qs = list()
        list_wlevel = list()
        list_sd = list()
        for t in solver.run(self.tstart, self.tstart + self.duration, self.dt):
            if verbose: print(t)
            list_q.append(self._to_liters_per_timestep(self.outlet(t)))
            list_qs.append(self._to_liters_per_timestep(self.outlet_s(t)))
            list_t.append(t.as_datetime())
            wlevel = np.zeros(self.ncell)
            sd = np.zeros(self.ncell)
            for ii in range(len(self.cells)):
                wlevel[ii] = self.bottom[ii]+max(0,self.depth-self.cells[ii].layers[0].get_saturated_depth())
                sd[ii]     = self.cells[ii].surfacewater.depth
            list_wlevel.append(wlevel)
            list_sd.append(sd)
        resdf = pd.DataFrame(index=list_t, data={'Darcy flow':list_q,
                                                'Surface runoff':list_qs,
                                                'Water level':list_wlevel,
                                                'Ponding':list_sd})
        return resdf
    def test_Q_t(self):
        """
        Tests if the linear storage connection behaves similar to the analytical solution
        """
        p, w1, w2 = create_project_with_2_storages()

        q = cmf.LinearStorageConnection(w1, w2, 1)

        # Loop over several scales for residence time
        for res_t in 10**np.arange(-3, 3, 0.5):

            q.residencetime = res_t
            w1.volume = 1.0
            w2.volume = 0.0
            solver = cmf.CVodeIntegrator(p, 1e-9)
            solver.integrate_until(cmf.day)
            self.assertAlmostEqual(
                w1.volume, np.exp(-1 / res_t), 5,
                'LinearStorage fails to reproduce analytical solution for t_r={:0.5g}'
                .format(res_t))
Ejemplo n.º 17
0
    def runmodel(self):
        """
        Runs the models and saves the results.

        :return: Simulated discharge
        """
        solver = cmf.CVodeIntegrator(self.project, 1e-9)

        # Result timeseries
        res_q = cmf.timeseries(self.begin, cmf.day)

        try:
            # Start solver and calculate in daily steps
            for t in solver.run(self.data.begin, self.end, cmf.day):
                res_q.add(self.outlet.waterbalance(t))
        except RuntimeError:
            return np.array(self.data.Q[self.data.begin:self.data.end +
                                        datetime.timedelta(days=1)]) * np.nan

        return res_q
Ejemplo n.º 18
0
def solve_project(cmf_project: cmf.project, solver_settings: dict,
                  outputs: dict) -> dict:
    """Solves the model"""

    logger.info('Initializing solving of CMF project')

    # Create solver, set time and set up results
    solver = cmf.CVodeIntegrator(cmf_project, solver_settings['tolerance'])
    solver.t = cmf.Time(solver_settings['start_time']['day'],
                        solver_settings['start_time']['month'],
                        solver_settings['start_time']['year'])

    logger.debug(f'Solver start time: {solver.t}')

    results = config_outputs(cmf_project, outputs)

    # Save initial conditions to results
    gather_results(cmf_project, results, solver.t)

    analysis_length = get_analysis_length(solver_settings['analysis_length'])
    time_step = get_time_step(solver_settings['time_step'])
    number_of_steps = analysis_length.total_seconds(
    ) / time_step.total_seconds()

    # Run solver and save results at each time step
    widgets = [
        ' [',
        progressbar.Timer(), '] ',
        progressbar.Bar(), ' [',
        progressbar.AdaptiveETA(), ' ]'
    ]
    bar = progressbar.ProgressBar(max_value=number_of_steps, widgets=widgets)
    for index, time_ in enumerate(
            solver.run(solver.t, solver.t + analysis_length, time_step)):
        gather_results(cmf_project, results, time_)
        bar.update(index)

    logger.info('Solved CMF project!')

    return results
Ejemplo n.º 19
0
    def run_model(self, verbose = True):
        """
        Starts the model. Used by spotpy
        """
        cell = self.project[0]
        try:
            # Create a solver for differential equations
            solver = cmf.CVodeIntegrator(self.project, 1e-8)

            # New time series for model results
            resQ = cmf.timeseries(self.begin_calibration, cmf.day)
            # starts the solver and calculates the daily time steps
            end = self.end_validation
            for t in solver.run(self.project.meteo_stations[0].T.begin, end,
                                cmf.day):
                # Fill the results (first year is included but not used to
                # calculate the NS)
                if verbose:
                    print(t)
                    print("storages")
                    storages = get_storages_and_fluxes.storages_of_cell(
                        cell.rain_source, cell)
                    fluxes = get_storages_and_fluxes.flux_of_all_nodes_of_cell(
                        cell.rain_source, cell, t)
                    fluxes = \
                        get_storages_and_fluxes.convert_fluxes_for_fluxogram(
                            fluxes)
                    print(storages)
                    print("Fluxes")
                    print(fluxes)
                    print("\n")
                if t >= self.begin_calibration:
                    resQ.add(self.outlet.waterbalance(t))
            return resQ
        # Return an nan - array when a runtime error occurs
        except RuntimeError:
            print("Runtime Error")
            return np.array(self.obs_discharge[
                            self.begin_calibration:self.end_validation +
                            datetime.timedelta(days=1)])*np.nan
Ejemplo n.º 20
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)
Ejemplo n.º 21
0
    cmf.kinematic_wave(c.layers[0], outlet, 3)

    # create artificial rain data
    begin = datetime.datetime(1979, 1, 1)
    end = begin + 15 * datetime.timedelta(days=1)
    step = datetime.timedelta(days=1)

    P = cmf.timeseries(begin, step)
    P.extend(prec for prec in np.random.randint(0, high=30, size=15))

    # add a rainstation
    rainstation = p.rainfall_stations.add("Rain", P, (0, 0, 0))
    p.use_nearest_rainfall()

    # create a solver
    solver = cmf.CVodeIntegrator(p, 1e-8)

    # create lists to store the results of the fluxes and storages
    timeseries_fluxes = []
    timeseries_storages = []

    # let the solver run for our timeperiod
    for t in solver.run(begin, end, cmf.day):
        fluxes_raw = flux_of_all_nodes_of_cell(c.rain_source, c, t)
        # to get an easier to grasp of the output of the fluxes it can be
        # converted using the following function
        fluxes_nicer = convert_fluxes_for_fluxogram(fluxes_raw)
        timeseries_fluxes.append(fluxes_nicer)
        timeseries_storages.append(storages_of_cell(c.rain_source, c))

    # due to the way CMF constructs models and how this program searches
Ejemplo n.º 22
0
        cmf.FreundlichAdsorbtion(2., .5, 1.0, 1e-9))
    l.Solute(Y).state = 1.

    # Tracer Y has a Langmuir isotherm xa/m=Kc/(1+Kc),
    # with K = 1 and sorbent mass m = 1
    l.Solute(Z).set_adsorption(cmf.LangmuirAdsorption(1., 5.))
    l.Solute(Z).state = 1.

# Use Richards equation
c.install_connection(cmf.Richards)
# 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)
# Creating the SWI, the storage objects of the project are internally assigned to the correct solver
solver = cmf.SoluteWaterIntegrator(p.solutes, wsolver, ssolver, p)

c.saturated_depth = 1.5

# Now we put a constant clean water flux into the storage
inflow = cmf.NeumannBoundary.create(c.surfacewater)
inflow.flux = 100.0  # 100 mm/day
for s in p.solutes:
    inflow.concentration[s] = 0.0

# Save wetness and concentration of all layers
conc = []
Ejemplo n.º 23
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