コード例 #1
0
    def __init__(self,
                 nx=100,
                 ny=100,
                 value_left=1.,
                 value_right=0.,
                 value_top=0.,
                 value_bottom=0.,
                 q=None):
        """
        ::param nx:: Number of cells in the x direction.
        ::param ny:: Number of cells in the y direction.
        ::param value_left:: Boundary condition on the left face.
        ::param value_right:: Boundary condition on the right face.
        ::param value_top:: Boundary condition on the top face.
        ::param value_bottom:: Boundary condition on the bottom face.
        ::param q:: Source function. 
        """
        #set domain dimensions
        self.nx = nx
        self.ny = ny
        self.dx = 1. / nx
        self.dy = 1. / ny

        #define mesh
        self.mesh = fipy.Grid2D(nx=self.nx, ny=self.ny, dx=self.dx, dy=self.dy)

        #get the location of the middle of the domain
        #cellcenters=np.array(self.mesh.cellCenters).T
        #x=cellcenters[:, 0]
        #y=cellcenters[:, 1]
        x, y = self.mesh.cellCenters
        x_all = x[:self.nx]
        y_all = y[0:-1:self.ny]
        loc1 = x_all[(self.nx - 1) / 2]
        loc2 = y_all[(self.ny - 1) / 2]
        self.loc = np.intersect1d(
            np.where(x == loc1)[0],
            np.where(y == loc2)[0])[0]

        #get facecenters
        X, Y = self.mesh.faceCenters

        #define cell and face variables
        self.phi = fipy.CellVariable(name='$T(x)$', mesh=self.mesh, value=1.)
        self.C = fipy.CellVariable(name='$C(x)$', mesh=self.mesh, value=1.)
        self.source = fipy.CellVariable(name='$f(x)$',
                                        mesh=self.mesh,
                                        value=0.)

        #apply boundary conditions
        #dirichet
        self.phi.constrain(value_left, self.mesh.facesLeft)
        self.phi.constrain(value_right, self.mesh.facesRight)

        #homogeneous Neumann
        self.phi.faceGrad.constrain(value_top, self.mesh.facesTop)
        self.phi.faceGrad.constrain(value_bottom, self.mesh.facesBottom)

        #setup the diffusion problem
        self.eq = -fipy.DiffusionTerm(coeff=self.C) == self.source
コード例 #2
0
def mesh_and_boundaries(params):
    """Generate a 2D grid appropriate for the parameters

    """
    def fn(f, N):
        '''Root solving kernel for compression factor
        
        Determine f(N), such that $\Delta x \sum_{i=0}^N f^i = 2 \Delta x$
        '''
        return (1 - f**N) / (1 - f) - 2.

    N = 1 + params["compression"]
    compression = fsolve(fn, x0=[.5], args=(N))[0]

    dx = dy = params["cellSize"]
    Nx = int(params["Lx"] / dx)
    Ny = int(params["Ly"] / dx)
    dx_variable = [dx] * (Nx - 2) + [dx * compression**i for i in range(N)]

    dy_variable = [dy] * Ny

    mesh = fp.Grid2D(dx=dx_variable, dy=dy_variable)

    X, Y = mesh.faceCenters

    inlet = mesh.facesLeft
    outlet = mesh.facesRight
    walls = mesh.facesTop | mesh.facesBottom
    top_right = outlet & (Y > params["Ly"] - dy)

    return mesh, inlet, outlet, walls, top_right
コード例 #3
0
ファイル: _forward_advection.py プロジェクト: yxqd/uq-course
 def _eval(self, xs):
     """
     Solves the advection equation for u and its derivatives for a given 
     source location xs. 
     """
     xs = view_as_column(xs)
     assert xs.shape[0] == 2
     nx = 50
     ny = nx
     dx = 0.1
     dy = dx
     mesh = fp.Grid2D(dx=dx, dy=dy, nx=nx, ny=ny)
     vx, vy = make_V_field(mesh)
     u = f(xs[:, 0], mesh, vx, vy)
     du1 = df(xs[:, 0], mesh, vx, vy, 1)
     du2 = df(xs[:, 0], mesh, vx, vy, 2)
     d2u11 = df2(xs[:, 0], mesh, vx, vy, 1, 1)
     d2u22 = df2(xs[:, 0], mesh, vx, vy, 1, 1)
     d2u12 = df2(xs[:, 0], mesh, vx, vy, 1, 2)
     dU = np.hstack([view_as_column(du1), view_as_column(du2)])
     d2U = np.hstack([
         view_as_column(d2u11),
         view_as_column(d2u12),
         view_as_column(d2u12),
         view_as_column(d2u22)
     ])
     d2U = d2U.reshape((d2U.shape[0], 2, 2))
     state = {}
     state['f'] = u  #view_as_column(u)
     state['f_grad'] = dU
     state['f_grad_2'] = d2U
     return state
コード例 #4
0
def main():
    """
	NAME		2DFPE.py
	
	PURPOSE		Integrate time-dependent FPE
	
	EXECUTION	python 2DFPE.py
	
	STARTED		CS 24/09/2015
	"""

    nx = 20
    ny = nx
    dx = 1.
    dy = dx
    L = dx * nx
    mesh = fp.Grid2D(dx=dx, dy=dy, nx=nx, ny=ny)
    y = np.linspace(-ny * dy * 0.5, +ny * dy * 0.5, ny,
                    endpoint=True)[:, np.newaxis]
    X, Y = mesh.faceCenters

    ## phi is pdf; psi is y*pdf for convenience
    phi = fp.CellVariable(mesh=mesh, value=1 / (dx * nx * dy * ny))
    psi = fp.CellVariable(mesh=mesh,
                          value=(y * phi.value.reshape((nx, ny))).flatten())

    diffCoeff = 1.
    diffMatri = [[0., 0.], [0., diffCoeff]]
    convCoeff = np.array([-1., +1.])
    eq = fp.TransientTerm(var=phi) == fp.DiffusionTerm(
        coeff=[diffMatri],
        var=phi) + 0 * fp.ExponentialConvectionTerm(coeff=convCoeff, var=psi)

    ##---------------------------------------------------------------------------------------------------------
    ## BCs
    phi = BC_value_at_boundary(phi, mesh)

    ## Evolution
    timeStepDuration = 0.5 * min(dy**2 / (2. * diffCoeff), dy / (nx * dx))
    steps = 10
    for step in range(steps):
        print np.trapz(np.trapz(phi.value.reshape([nx, ny]), dx=dx), dx=dy)
        psi.value = (y * phi.value.reshape((nx, ny))).flatten()
        eq.solve(var=phi, dt=timeStepDuration)
        print phi.value[5]

    # plot_pdf(phi.value.reshape([nx,ny]),step+1)
    plt.contourf(phi.value.reshape([nx, ny]), extent=(-1, 1, -1, 1))
    plt.colorbar()
    plt.title("Density at timestep " + str(steps))
    plt.xlabel("$x$", fontsize=18)
    plt.ylabel("$\eta$", fontsize=18)
    plt.savefig("fig_FPE/Imp" + str(steps) + ".png")
    plt.show()

    return
コード例 #5
0
ファイル: quad_eval.py プロジェクト: tsilifis/chaos_basispy3
def forward(xs):

    nx = 21
    ny = nx
    dx = 1. / 51
    dy = dx
    rho = 0.05
    q0 = 1. / (np.pi * rho**2)
    T = 0.3
    mesh = fp.Grid2D(dx=dx, dy=dy, nx=nx, ny=ny)

    time = fp.Variable()
    sourceTerm_1 = fp.CellVariable(name="Source term", mesh=mesh, value=0.)

    for i in range(sourceTerm_1().shape[0]):
        sourceTerm_1()[i] = q0 * np.exp(-(
            (mesh.cellCenters[0]()[i] - xs[0])**2 +
            (mesh.cellCenters[1]()[i] - xs[1])**2) /
                                        (2 * rho**2)) * (time() < T)

    # The equation
    eq = fp.TransientTerm() == fp.DiffusionTerm(
        coeff=1.) + sourceTerm_1  # + sourceTerm_2

    # The solution variable
    phi = fp.CellVariable(name="Concentration", mesh=mesh, value=0.)

    #if __name__ == '__main__':
    #    viewer = fp.Viewer(vars=phi, datamin=0., datamax=3.)
    #    viewer.plot()

    x = np.arange(0, nx) / nx
    y = x

    data = []
    dt = 0.005
    steps = 60
    for step in range(steps):
        time.setValue(time() + dt)
        eq.solve(var=phi, dt=dt)
        #if __name__ == '__main__':
        #    viewer.plot()
        #if step == 14 or step == 29 or step == 44 or  step == 59:
        #    dl = phi()[0]
        #    dr = phi()[nx-1]
        #    ul = phi()[nx**2 - nx]
        #    ur = phi()[nx**2 - 1]
        #    print phi().shape
        #    data = np.hstack([data, np.array([dl, dr, ul, ur])])

    #if __name__ == '__main__':
    #    raw_input("Transient diffusion with source term. Press <return> to proceed")

    return phi().reshape(nx, nx)
 def _eval_u(self, xs):
     """
     Solves only the diffusion equation for u for a given 
     source location xs. 
     """
     xs = view_as_column(xs)
     assert xs.shape[0] == 2
     nx = 25
     ny = nx
     dx = 0.04
     dy = dx
     mesh = fp.Grid2D(dx=dx, dy=dy, nx=nx, ny=ny)
     u = f(xs[:,0], mesh)
     return u
コード例 #7
0
ファイル: model.py プロジェクト: eddiejessup/chemopore
 def initialise_mesh(self):
     if self.has_obstacles():
         self.mesh = make_porous_mesh(self.rc, self.Rc, self.dx, self.L)
     elif self.dim == 1:
         self.mesh = fipy.Grid1D(Lx=self.L[0],
                                 dx=self.dx[0],
                                 origin=(-self.L[0] / 2.0, ))
     elif self.dim == 2:
         self.mesh = fipy.Grid2D(Lx=self.L[0],
                                 Ly=self.L[1],
                                 dx=self.dx[0],
                                 dy=self.dx[1],
                                 origin=((-self.L[0] / 2.0, ),
                                         (-self.L[1] / 2.0, )))
コード例 #8
0
ファイル: fipy_module.py プロジェクト: wd15/sfepy-bm4
def get_mesh(params):
    """Create the mesh

    Args:
      params: the parameter dict

    Returns:
      the fipy mesh
    """
    return pipe(
        fp.Grid2D(Lx=params["lx"],
                  Ly=params["lx"],
                  nx=params["nx"],
                  ny=params["nx"]),
        lambda x: x - np.array(
            (params["lx"] / 2., params["lx"] / 2.))[:, None],
    )
コード例 #9
0
def df2(xs, mesh, i, j):
    """
    Evaluate the model for the 2nd derivatives at the four corners of the domain
    at times ``t``.

    It returns a flatten version of the system, i.e.:
    y_1(t_1)
    ...
    y_4(t_1)
    ...
    y_1(t_4)
    ...
    y_4(t_4)
    """
    assert i == 1 or i == 2
    assert j == 1 or j == 2
    nx = 25
    ny = nx
    dx = 0.04
    dy = dx
    mesh = fp.Grid2D(dx=dx, dy=dy, nx=nx, ny=ny)
    time = fp.Variable()
    q0 = make_source_der_2(xs, mesh, time, i, j)
    D = 1.
    # Define the equation
    eq = fp.TransientTerm() == fp.DiffusionTerm(coeff=D) + q0
    # Boundary conditions

    # The solution variable
    phi = fp.CellVariable(name="Concentraion", mesh=mesh, value=0.)

    # Solve
    dt = 0.005
    steps = 60
    d2U = []
    for step in range(steps):
        eq.solve(var=phi, dt=dt)
        if step == 14 or step == 29 or step == 44 or step == 59:
            dl = phi()[0]
            #dr = phi()[24]
            ul = phi()[600]
            #ur = phi()[624]
            #d2U = np.hstack([d2U, np.array([dl, dr, ul, ur])])
            d2U = np.hstack([d2U, np.array([dl, ul])])

    return d2U
コード例 #10
0
ファイル: problemIII-1a.py プロジェクト: guyer/hackathonIII
    '''Root solving kernel for compression factor
    
    Determine f(N), such that $\Delta x \sum_{i=0}^N f^i = 2 \Delta x$
    '''
    return (1 - f**N) / (1 - f) - 2.
    
N = 1 + args.compression
compression = fsolve(fn, x0=[.5], args=(N))[0]

Nx = int(Lx / dx)
Ny = int(Ly / dy)
dx_variable = [dx] * (Nx - 2) + [dx * compression**i for i in range(N+1)]

dy_variable = [dy] * Ny

mesh = fp.Grid2D(dx=dx_variable, dy=dy_variable)
volumes = fp.CellVariable(mesh=mesh, value=mesh.cellVolumes)

pressure = fp.CellVariable(mesh=mesh, name="$p$")
pressureCorrection = fp.CellVariable(mesh=mesh, name="$p'$")
xVelocity = fp.CellVariable(mesh=mesh, name="$u_x$")
yVelocity = fp.CellVariable(mesh=mesh, name="$u_y$")

velocity = fp.FaceVariable(mesh=mesh, name=r"$\vec{u}$", rank=1)

xVelocityEq = fp.DiffusionTerm(coeff=viscosity) - pressure.grad.dot([1.,0.]) + density * gravity[0]
yVelocityEq = fp.DiffusionTerm(coeff=viscosity) - pressure.grad.dot([0.,1.]) + density * gravity[1]

ap = fp.CellVariable(mesh=mesh, value=1.)
coeff = 1./ ap.arithmeticFaceValue*mesh._faceAreas * mesh._cellDistances
pressureCorrectionEq = fp.DiffusionTerm(coeff=coeff) - velocity.divergence
コード例 #11
0
    os.makedirs(pathStr + 'ForwardEvo/')
if (not os.path.exists(pathStr + 'ReverseEvoUnupdated/')):
    os.makedirs(pathStr + 'ReverseEvoUnupdated/')
if (not os.path.exists(pathStr + 'ReverseEvoUpdated/')):
    os.makedirs(pathStr + 'ReverseEvoUpdated/')

# Initialize phase-space lattice
# Nx, Dx, XMax, Np, Dp, PMax, and Mesh are Global
Nx = n1 * n2
Np = Nx
Dx = 1. / n1
Dp = Dx
XMax = Dx * Nx
PMax = Dp * Np
comm = fipy.tools.serial
Mesh = fipy.Grid2D(dx=Dx, dy=Dp, nx=2*Nx, ny=2*Np, communicator=comm)\
                + [[-XMax], [-PMax]]
fipy.dump.write(Mesh, filename=pathStr + 'mesh.gz')

# Create and save initial distribution
phi = distributionInitial()
phiInitial = fipy.CellVariable(mesh=Mesh, name=r"\LARGE $\rho_{0}(x,p)$")
phiInitial.setValue(phi.value)
del phi
if (saveResults):
    fipy.tools.dump.write(phiInitial, \
                                filename=pathStr+'initialDistribution.gz')

# Plot initial distribution
genPlots(phiInitial, tStart, saveResults, 'initialDistribution.pdf', pathStr)
コード例 #12
0
import fipy as fp
import glob
import json
import numpy as np
import os
import sys
from fipy.solvers.pysparse import LinearLUSolver as Solver

problem = '1'
domain = 'b'
nx = 200
dx = 1.0

# The first step in implementing any problem in FiPy is to define the mesh. For [Problem 1b]({{ site.baseurl }}/hackathon1/#a.-Square-Periodic) the solution domain is just a square domain with fixed boundary conditions, so a `Grid2D` object is used. No other boundary conditions are required.

mesh = fp.Grid2D(nx=nx, ny=nx, dx=dx, dy=dx)

# The next step is to define the parameters and create a solution variable.
# Constants and initial conditions:
# $c_{\alpha}$ and $c_{\beta}$ are concentrations at which the bulk free energy has minima.
# $\kappa$ is the gradient energy coefficient.
# $\varrho_s$ controls the height of the double-well barrier.

c_alpha = 0.3
c_beta = 0.7
kappa = 2.0
M = 5.0
c_0 = 0.5
epsilon = 0.01
rho_s = 5.0
コード例 #13
0
ファイル: hydro.py プロジェクト: Txart/dosan_daily_map
def hydrology(solve_mode,
              nx,
              ny,
              dx,
              dy,
              days,
              ele,
              phi_initial,
              catchment_mask,
              wt_canal_arr,
              boundary_arr,
              peat_type_mask,
              httd,
              tra_to_cut,
              sto_to_cut,
              diri_bc=0.0,
              neumann_bc=None,
              plotOpt=False,
              remove_ponding_water=True,
              P=0.0,
              ET=0.0,
              dt=1.0):
    """
    INPUT:
        - ele: (nx,ny) sized NumPy array. Elevation in m above c.r.p.
        - Hinitial: (nx,ny) sized NumPy array. Initial water table in m above c.r.p.
        - catchment mask: (nx,ny) sized NumPy array. Boolean array = True where the node is inside the computation area. False if outside.
        - wt_can_arr: (nx,ny) sized NumPy array. Zero everywhere except in nodes that contain canals, where = wl of the canal.
        - value_for_masked: DEPRECATED. IT IS NOW THE SAME AS diri_bc.
        - diri_bc: None or float. If None, Dirichlet BC will not be implemented. If float, this number will be the BC.
        - neumann_bc: None or float. If None, Neumann BC will not be implemented. If float, this is the value of grad phi.
        - P: Float. Constant precipitation. mm/day.
        - ET: Float. Constant evapotranspiration. mm/day.
    """
    #    dneg = []

    track_WT_drained_area = (239, 166)
    track_WT_notdrained_area = (522, 190)

    ele[~catchment_mask] = 0.
    ele = ele.flatten()
    phi_initial = (phi_initial + 0.0 * np.zeros((ny, nx))) * catchment_mask
    #    phi_initial = phi_initial * catchment_mask
    phi_initial = phi_initial.flatten()

    if len(ele) != nx * ny or len(phi_initial) != nx * ny:
        raise ValueError("ele or Hinitial are not of dim nx*ny")

    mesh = fp.Grid2D(dx=dx, dy=dy, nx=nx, ny=ny)
    phi = fp.CellVariable(
        name='computed H', mesh=mesh, value=phi_initial,
        hasOld=True)  #response variable H in meters above reference level

    if diri_bc != None and neumann_bc == None:
        phi.constrain(diri_bc, mesh.exteriorFaces)

    elif diri_bc == None and neumann_bc != None:
        phi.faceGrad.constrain(neumann_bc * mesh.faceNormals,
                               where=mesh.exteriorFaces)

    else:
        raise ValueError(
            "Cannot apply Dirichlet and Neumann boundary values at the same time. Contradictory values."
        )

    #*******omit areas outside the catchment. c is input
    cmask = fp.CellVariable(mesh=mesh, value=np.ravel(catchment_mask))
    cmask_not = fp.CellVariable(mesh=mesh,
                                value=np.array(~cmask.value, dtype=int))

    # *** drain mask or canal mask
    dr = np.array(wt_canal_arr, dtype=bool)
    dr[np.array(wt_canal_arr, dtype=bool) * np.array(
        boundary_arr, dtype=bool
    )] = False  # Pixels cannot be canals and boundaries at the same time. Everytime a conflict appears, boundaries win. This overwrites any canal water level info if the canal is in the boundary.
    drmask = fp.CellVariable(mesh=mesh, value=np.ravel(dr))
    drmask_not = fp.CellVariable(
        mesh=mesh, value=np.array(~drmask.value, dtype=int)
    )  # Complementary of the drains mask, but with ints {0,1}

    # mask away unnecesary stuff
    #    phi.setValue(np.ravel(H)*cmask.value)
    #    ele = ele * cmask.value

    source = fp.CellVariable(mesh=mesh,
                             value=0.)  # cell variable for source/sink

    #    CC=fp.CellVariable(mesh=mesh, value=C(phi.value-ele))                   # differential water capacity

    def D_value(phi, ele, tra_to_cut, cmask, drmask_not):
        # Some inputs are in fipy CellVariable type
        gwt = phi.value * cmask.value - ele

        d = hydro_utils.peat_map_h_to_tra(
            soil_type_mask=peat_type_mask, gwt=gwt,
            h_to_tra_and_C_dict=httd) - tra_to_cut

        # d <0 means tra_to_cut is greater than the other transmissivity, which in turn means that
        # phi is below the impermeable bottom. We allow phi to have those values, but
        # the transmissivity is in those points is equal to zero (as if phi was exactly at the impermeable bottom).
        d[d < 0] = 1e-3  # Small non-zero value not to wreck the computation

        dcell = fp.CellVariable(
            mesh=mesh, value=d
        )  # diffusion coefficient, transmissivity. As a cell variable.
        dface = fp.FaceVariable(mesh=mesh,
                                value=dcell.arithmeticFaceValue.value
                                )  # THe correct Face variable.

        return dface.value

    def C_value(phi, ele, sto_to_cut, cmask, drmask_not):
        # Some inputs are in fipy CellVariable type
        gwt = phi.value * cmask.value - ele

        c = hydro_utils.peat_map_h_to_sto(
            soil_type_mask=peat_type_mask, gwt=gwt,
            h_to_tra_and_C_dict=httd) - sto_to_cut
        c[c < 0] = 1e-3  # Same reasons as for D

        ccell = fp.CellVariable(
            mesh=mesh, value=c
        )  # diffusion coefficient, transmissivity. As a cell variable.
        return ccell.value

    D = fp.FaceVariable(
        mesh=mesh, value=D_value(phi, ele, tra_to_cut, cmask,
                                 drmask_not))  # THe correct Face variable.
    C = fp.CellVariable(
        mesh=mesh, value=C_value(phi, ele, sto_to_cut, cmask,
                                 drmask_not))  # differential water capacity

    largeValue = 1e20  # value needed in implicit source term to apply internal boundaries

    if plotOpt:
        big_4_raster_plot(
            title='Before the computation',
            raster1=(
                (hydro_utils.peat_map_h_to_tra(soil_type_mask=peat_type_mask,
                                               gwt=(phi.value - ele),
                                               h_to_tra_and_C_dict=httd) -
                 tra_to_cut) * cmask.value * drmask_not.value).reshape(ny, nx),
            raster2=(ele.reshape(ny, nx) - wt_canal_arr) * dr * catchment_mask,
            raster3=ele.reshape(ny, nx),
            raster4=(ele - phi.value).reshape(ny, nx))
        # for later cross-section plots
        y_value = 270

#        print "first cross-section plot"
#        ele_with_can = copy.copy(ele).reshape(ny,nx)
#        ele_with_can = ele_with_can * catchment_mask
#        ele_with_can[wt_canal_arr > 0] = wt_canal_arr[wt_canal_arr > 0]
#        plot_line_of_peat(ele_with_can, y_value=y_value, title="cross-section", color='green', nx=nx, ny=ny, label="ele")

# ********************************** PDE, STEADY STATE **********************************
    if solve_mode == 'steadystate':
        if diri_bc != None:
            #        diri_boundary = fp.CellVariable(mesh=mesh, value= np.ravel(diri_boundary_value(boundary_mask, ele2d, diri_bc)))

            eq = 0. == (
                fp.DiffusionTerm(coeff=D) + source * cmask * drmask_not -
                fp.ImplicitSourceTerm(cmask_not * largeValue) +
                cmask_not * largeValue * np.ravel(boundary_arr) -
                fp.ImplicitSourceTerm(drmask * largeValue) +
                drmask * largeValue * (np.ravel(wt_canal_arr))
                #                    - fp.ImplicitSourceTerm(bmask_not*largeValue) + bmask_not*largeValue*(boundary_arr)
            )

        elif neumann_bc != None:
            raise NotImplementedError("Neumann BC not implemented yet!")
            cmask_face = fp.FaceVariable(mesh=mesh,
                                         value=np.array(
                                             cmask.arithmeticFaceValue.value,
                                             dtype=bool))
            D[cmask_face.value] = 0.
            eq = 0. == (
                fp.DiffusionTerm(coeff=D) + source * cmask * drmask_not -
                fp.ImplicitSourceTerm(cmask_not * largeValue) +
                cmask_not * largeValue * (diri_bc) -
                fp.ImplicitSourceTerm(drmask * largeValue) +
                drmask * largeValue * (np.ravel(wt_canal_arr))
                #                + fp.DiffusionTerm(coeff=largeValue * bmask_face)
                #                - fp.ImplicitSourceTerm((bmask_face * largeValue *neumann_bc * mesh.faceNormals).divergence)
            )

    elif solve_mode == 'transient':
        if diri_bc != None:
            #        diri_boundary = fp.CellVariable(mesh=mesh, value= np.ravel(diri_boundary_value(boundary_mask, ele2d, diri_bc)))

            eq = fp.TransientTerm(coeff=C) == (
                fp.DiffusionTerm(coeff=D) + source * cmask * drmask_not -
                fp.ImplicitSourceTerm(cmask_not * largeValue) +
                cmask_not * largeValue * np.ravel(boundary_arr) -
                fp.ImplicitSourceTerm(drmask * largeValue) +
                drmask * largeValue * (np.ravel(wt_canal_arr))
                #                        - fp.ImplicitSourceTerm(bmask_not*largeValue) + bmask_not*largeValue*(boundary_arr)
            )
        elif neumann_bc != None:
            raise NotImplementedError("Neumann BC not implemented yet!")

    #********************************************************

    max_sweeps = 10  # inner loop.

    avg_wt = []
    wt_track_drained = []
    wt_track_notdrained = []

    cumulative_Vdp = 0.

    #********Finite volume computation******************
    for d in range(days):
        source.setValue(
            (P[d] - ET[d]) * .001 * np.ones(ny * nx)
        )  # source/sink. P and ET are in mm/day. The factor of 10^-3 converst to m/day. It does not matter that there are 100 x 100 m^2 in one pixel
        print("(d, P - ET) = ", (d, (P[d] - ET[d])))
        if plotOpt and d != 0:
            # print "one more cross-section plot"
            plot_line_of_peat(phi.value.reshape(ny, nx),
                              y_value=y_value,
                              title="cross-section",
                              color='cornflowerblue',
                              nx=nx,
                              ny=ny,
                              label=d)

        res = 0.0

        phi.updateOld()

        D.setValue(D_value(phi, ele, tra_to_cut, cmask, drmask_not))
        C.setValue(C_value(phi, ele, tra_to_cut, cmask, drmask_not))

        for r in range(max_sweeps):
            resOld = res

            res = eq.sweep(var=phi, dt=dt)  # solve linearization of PDE

            #print "sum of Ds: ", np.sum(D.value)/1e8
            #print "average wt: ", np.average(phi.value-ele)

            #print 'residue diference:    ', res - resOld

            if abs(res - resOld) < 1e-7:
                break  # it has reached to the solution of the linear system

        if solve_mode == 'transient':  #solving in steadystate will remove water only at the very end
            if remove_ponding_water:
                s = np.where(
                    phi.value > ele, ele, phi.value
                )  # remove the surface water. This also removes phi in those masked values (for the plot only)
                phi.setValue(s)  # set new values for water table

        if (D.value < 0.).any():
            print("Some value in D is negative!")

        # For some plots
        avg_wt.append(np.average(phi.value - ele))
        wt_track_drained.append(
            (phi.value - ele).reshape(ny, nx)[track_WT_drained_area])
        wt_track_notdrained.append(
            (phi.value - ele).reshape(ny, nx)[track_WT_notdrained_area])
        """ Volume of dry peat calc."""
        not_peat = np.ones(shape=peat_type_mask.shape)  # Not all soil is peat!
        not_peat[peat_type_mask == 4] = 0  # NotPeat
        not_peat[peat_type_mask == 5] = 0  # OpenWater
        peat_vol_weights = utilities.PeatV_weight_calc(
            np.array(~dr * catchment_mask * not_peat, dtype=int))
        dry_peat_volume = utilities.PeatVolume(peat_vol_weights,
                                               (ele - phi.value).reshape(
                                                   ny, nx))
        cumulative_Vdp = cumulative_Vdp + dry_peat_volume
        print("avg_wt  = ", np.average(phi.value - ele))
        #        print "wt drained = ", (phi.value - ele).reshape(ny,nx)[track_WT_drained_area]
        #        print "wt not drained = ", (phi.value - ele).reshape(ny,nx)[track_WT_notdrained_area]
        print("Cumulative vdp = ", cumulative_Vdp)

    if solve_mode == 'steadystate':  #solving in steadystate we remove water only at the very end
        if remove_ponding_water:
            s = np.where(
                phi.value > ele, ele, phi.value
            )  # remove the surface water. This also removes phi in those masked values (for the plot only)
            phi.setValue(s)  # set new values for water table

        # Areas with WT <-1.0; areas with WT >0
#        plot_raster_by_value((ele-phi.value).reshape(ny,nx), title="ele-phi in the end, colour keys", bottom_value=0.5, top_value=0.01)

    if plotOpt:
        big_4_raster_plot(
            title='After the computation',
            raster1=(
                (hydro_utils.peat_map_h_to_tra(soil_type_mask=peat_type_mask,
                                               gwt=(phi.value - ele),
                                               h_to_tra_and_C_dict=httd) -
                 tra_to_cut) * cmask.value * drmask_not.value).reshape(ny, nx),
            raster2=(ele.reshape(ny, nx) - wt_canal_arr) * dr * catchment_mask,
            raster3=ele.reshape(ny, nx),
            raster4=(ele - phi.value).reshape(ny, nx))

        fig, axes = plt.subplots(nrows=2, ncols=2, figsize=(12, 9), dpi=80)
        x = np.arange(-21, 1, 0.1)
        axes[0, 0].plot(httd[1]['hToTra'](x), x)
        axes[0, 0].set(title='hToTra', ylabel='depth')
        axes[0, 1].plot(httd[1]['C'](x), x)
        axes[0, 1].set(title='C')
        axes[1, 0].plot()
        axes[1, 0].set(title="Nothing")
        axes[1, 1].plot(avg_wt)
        axes[1, 1].set(title="avg_wt_over_time")

        # plot surface in cross-section
        ele_with_can = copy.copy(ele).reshape(ny, nx)
        ele_with_can = ele_with_can * catchment_mask
        ele_with_can[wt_canal_arr > 0] = wt_canal_arr[wt_canal_arr > 0]
        plot_line_of_peat(ele_with_can,
                          y_value=y_value,
                          title="cross-section",
                          nx=nx,
                          ny=ny,
                          label="surface",
                          color='peru',
                          linewidth=2.0)

        plt.show()

#    change_in_canals = (ele-phi.value).reshape(ny,nx)*(drmask.value.reshape(ny,nx)) - ((ele-H)*drmask.value).reshape(ny,nx)
#    resulting_phi = phi.value.reshape(ny,nx)

    phi.updateOld()

    return (phi.value - ele).reshape(ny, nx)
コード例 #14
0
ファイル: problemIII-2a.py プロジェクト: guyer/hackathonIII
else:

    class dummyTreant(object):
        categories = dict()

    data = dummyTreant()

data.categories['problem'] = "III-2a"
data.categories['args'] = " ".join(sys.argv)
data.categories['step'] = args.step
data.categories['sweeps'] = args.sweeps
data.categories['dx'] = args.dx
data.categories['commit'] = os.popen('git log --pretty="%H" -1').read().strip()
data.categories['diff'] = os.popen('git diff').read()

mesh = fp.Grid2D(Lx=100., dx=args.dx, Ly=100., dy=args.dx)
volumes = fp.CellVariable(mesh=mesh, value=mesh.cellVolumes)

c = fp.CellVariable(mesh=mesh, name="$c$", hasOld=True)
psi = fp.CellVariable(mesh=mesh, name=r"$\psi$", hasOld=True)
Phi = fp.CellVariable(mesh=mesh, name=r"$\Phi$", hasOld=True)

calpha = 0.3
cbeta = 0.7
kappa = 2.
rho = 5.
M = 5.
k = 0.09
epsilon = 90.

ceq = fp.TransientTerm(var=c) == fp.DiffusionTerm(coeff=M, var=psi)
コード例 #15
0
ファイル: hydro.py プロジェクト: Txart/blopti_dev
def hydrology(mode,
              sensor_positions,
              nx,
              ny,
              dx,
              dy,
              days,
              ele,
              phi_initial,
              catchment_mask,
              wt_canal_arr,
              boundary_arr,
              peat_type_mask,
              peat_bottom_arr,
              transmissivity,
              t0,
              t1,
              t2,
              t_sapric_coef,
              storage,
              s0,
              s1,
              s2,
              s_sapric_coef,
              diri_bc=0.0,
              plotOpt=False,
              remove_ponding_water=True,
              P=0.0,
              ET=0.0,
              dt=1.0):
    """
    INPUT:
        - ele: (nx,ny) sized NumPy array. Elevation in m above c.r.p.
        - Hinitial: (nx,ny) sized NumPy array. Initial water table in m above c.r.p.
        - catchment mask: (nx,ny) sized NumPy array. Boolean array = True where the node is inside the computation area. False if outside.
        - wt_can_arr: (nx,ny) sized NumPy array. Zero everywhere except in nodes that contain canals, where = wl of the canal.
        - value_for_masked: DEPRECATED. IT IS NOW THE SAME AS diri_bc.
        - diri_bc: None or float. If None, Dirichlet BC will not be implemented. If float, this number will be the BC.
        - neumann_bc: None or float. If None, Neumann BC will not be implemented. If float, this is the value of grad phi.
        - P: Float. Constant precipitation. mm/day.
        - ET: Float. Constant evapotranspiration. mm/day.
    """
    #    dneg = []

    # track_WT_drained_area = (239,166)
    # track_WT_notdrained_area = (522,190)

    ele[~catchment_mask] = 0.
    ele = ele.flatten()
    phi_initial = (phi_initial + 0.0 * np.zeros((ny, nx))) * catchment_mask
    #    phi_initial = phi_initial * catchment_mask
    phi_initial = phi_initial.flatten()

    if len(ele) != nx * ny or len(phi_initial) != nx * ny:
        raise ValueError("ele or Hinitial are not of dim nx*ny")

    mesh = fp.Grid2D(dx=dx, dy=dy, nx=nx, ny=ny)
    phi = fp.CellVariable(
        name='computed H', mesh=mesh, value=phi_initial,
        hasOld=True)  #response variable H in meters above reference level

    if diri_bc != None:
        phi.constrain(diri_bc, mesh.exteriorFaces)

    else:
        raise ValueError("Dirichlet boundary conditions must have a value")

    #*******omit areas outside the catchment. c is input
    cmask = fp.CellVariable(mesh=mesh, value=np.ravel(catchment_mask))
    cmask_not = fp.CellVariable(mesh=mesh,
                                value=np.array(~cmask.value, dtype=int))

    # *** drain mask or canal mask
    dr = np.array(wt_canal_arr, dtype=bool)
    dr[np.array(wt_canal_arr, dtype=bool) * np.array(
        boundary_arr, dtype=bool
    )] = False  # Pixels cannot be canals and boundaries at the same time. Everytime a conflict appears, boundaries win. This overwrites any canal water level info if the canal is in the boundary.
    drmask = fp.CellVariable(mesh=mesh, value=np.ravel(dr))
    drmask_not = fp.CellVariable(
        mesh=mesh, value=np.array(~drmask.value, dtype=int)
    )  # Complementary of the drains mask, but with ints {0,1}

    # mask away unnecesary stuff
    #    phi.setValue(np.ravel(H)*cmask.value)
    #    ele = ele * cmask.value

    source = fp.CellVariable(mesh=mesh,
                             value=0.)  # cell variable for source/sink

    #    CC=fp.CellVariable(mesh=mesh, value=C(phi.value-ele))                   # differential water capacity

    def T_value(phi, ele, cmask, peat_bottom_arr):
        # Some inputs are in fipy CellVariable type
        gwt = (phi.value * cmask.value - ele).reshape(ny, nx)

        # T(h) - T(bottom)
        T = transmissivity(gwt, t0, t1, t2, t_sapric_coef) - transmissivity(
            peat_bottom_arr, t0, t1, t2, t_sapric_coef)

        # d <0 means tra_to_cut is greater than the other transmissivity, which in turn means that
        # phi is below the impermeable bottom. We allow phi to have those values, but
        # the transmissivity is in those points is equal to zero (as if phi was exactly at the impermeable bottom).
        T[T < 0] = 1e-3  # Small non-zero value not to wreck the computation

        Tcell = fp.CellVariable(mesh=mesh, value=T.flatten(
        ))  # diffusion coefficient, transmissivity. As a cell variable.
        Tface = fp.FaceVariable(mesh=mesh,
                                value=Tcell.arithmeticFaceValue.value
                                )  # THe correct Face variable.

        return Tface.value

    def S_value(phi, ele, cmask, peat_bottom_arr):
        # Some inputs are in fipy CellVariable type
        gwt = (phi.value * cmask.value - ele).reshape(ny, nx)

        S = storage(gwt, s0, s1, s2, s_sapric_coef) - storage(
            peat_bottom_arr, s0, s1, s2, s_sapric_coef)
        S[S < 0] = 1e-3  # Same reasons as for D

        Scell = fp.CellVariable(mesh=mesh, value=S.flatten(
        ))  # diffusion coefficient, transmissivity. As a cell variable.
        return Scell.value

    T = fp.FaceVariable(mesh=mesh,
                        value=T_value(
                            phi, ele, cmask,
                            peat_bottom_arr))  # THe correct Face variable.
    S = fp.CellVariable(mesh=mesh,
                        value=S_value(
                            phi, ele, cmask,
                            peat_bottom_arr))  # differential water capacity

    largeValue = 1e20  # value needed in implicit source term to apply internal boundaries

    if plotOpt:
        big_4_raster_plot(
            title='Before the computation',
            # raster1=((hydro_utils.peat_map_h_to_tra(soil_type_mask=peat_type_mask, gwt=(phi.value - ele), h_to_tra_and_C_dict=httd) - tra_to_cut)*cmask.value *drmask_not.value ).reshape(ny,nx),
            raster2=(ele.reshape(ny, nx) - wt_canal_arr) * dr * catchment_mask,
            raster3=ele.reshape(ny, nx),
            raster4=(ele - phi.value).reshape(ny, nx))
        # for later cross-section plots
        y_value = 270
    """
    ###### PDE ######
    """

    if mode == 'steadystate':
        temp = 0.
    elif mode == 'transient':
        temp = fp.TransientTerm(coeff=S)

    if diri_bc != None:
        #        diri_boundary = fp.CellVariable(mesh=mesh, value= np.ravel(diri_boundary_value(boundary_mask, ele2d, diri_bc))
        eq = temp == (
            fp.DiffusionTerm(coeff=T) + source * cmask * drmask_not -
            fp.ImplicitSourceTerm(cmask_not * largeValue) +
            cmask_not * largeValue * np.ravel(boundary_arr) -
            fp.ImplicitSourceTerm(drmask * largeValue) + drmask * largeValue *
            (np.ravel(wt_canal_arr))
            #                        - fp.ImplicitSourceTerm(bmask_not*largeValue) + bmask_not*largeValue*(boundary_arr)
        )

    #********************************************************

    max_sweeps = 10  # inner loop.

    avg_wt = []
    # wt_track_drained = []
    # wt_track_notdrained = []

    cumulative_Vdp = 0.

    #********Finite volume computation******************
    for d in range(days):

        if type(P) == type(ele):  # assume it is a numpy array
            source.setValue(
                (P[d] - ET[d]) * .001 * np.ones(ny * nx)
            )  # source/sink, in mm/day. The factor of 10^-3 takes into account that there are 100 x 100 m^2 in one pixel
            # print("(d,P) = ", (d, (P[d]-ET[d])* 10.))
        else:
            source.setValue((P - ET) * 10. * np.ones(ny * nx))
            # print("(d,P) = ", (d, (P-ET)* 10.))

        if plotOpt and d != 0:
            # print "one more cross-section plot"
            plot_line_of_peat(phi.value.reshape(ny, nx),
                              y_value=y_value,
                              title="cross-section",
                              color='cornflowerblue',
                              nx=nx,
                              ny=ny,
                              label=d)

        res = 0.0

        phi.updateOld()

        T.setValue(T_value(phi, ele, cmask, peat_bottom_arr))
        S.setValue(S_value(phi, ele, cmask, peat_bottom_arr))

        for r in range(max_sweeps):
            resOld = res

            res = eq.sweep(var=phi, dt=dt)  # solve linearization of PDE

            #print "sum of Ds: ", np.sum(D.value)/1e8
            #print "average wt: ", np.average(phi.value-ele)

            #print 'residue diference:    ', res - resOld

            if abs(res - resOld) < 1e-7:
                break  # it has reached to the solution of the linear system

        if remove_ponding_water:
            s = np.where(
                phi.value > ele, ele, phi.value
            )  # remove the surface water. This also removes phi in those masked values (for the plot only)
            phi.setValue(s)  # set new values for water table

        if (T.value < 0.).any():
            print("Some value in D is negative!")

        # For some plots
        avg_wt.append(np.average(phi.value - ele))
        # wt_track_drained.append((phi.value - ele).reshape(ny,nx)[track_WT_drained_area])
        # wt_track_notdrained.append((phi.value - ele).reshape(ny,nx)[track_WT_notdrained_area])
        """ Volume of dry peat calc."""
        not_peat = np.ones(shape=peat_type_mask.shape)  # Not all soil is peat!
        not_peat[peat_type_mask == 4] = 0  # NotPeat
        not_peat[peat_type_mask == 5] = 0  # OpenWater
        peat_vol_weights = utilities.PeatV_weight_calc(
            np.array(~dr * catchment_mask * not_peat, dtype=int))
        dry_peat_volume = utilities.PeatVolume(peat_vol_weights,
                                               (ele - phi.value).reshape(
                                                   ny, nx))
        cumulative_Vdp = cumulative_Vdp + dry_peat_volume

    if plotOpt:
        big_4_raster_plot(
            title='After the computation',
            # raster1=((hydro_utils.peat_map_h_to_tra(soil_type_mask=peat_type_mask, gwt=(phi.value - ele), h_to_tra_and_C_dict=httd) - tra_to_cut)*cmask.value *drmask_not.value ).reshape(ny,nx),
            raster2=(ele.reshape(ny, nx) - wt_canal_arr) * dr * catchment_mask,
            raster3=ele.reshape(ny, nx),
            raster4=(ele - phi.value).reshape(ny, nx))

        # fig, axes = plt.subplots(nrows=2, ncols=2, figsize=(12,9), dpi=80)
        # x = np.arange(-21,1,0.1)
        # axes[0,0].plot(httd[1]['hToTra'](x),x)
        # axes[0,0].set(title='hToTra', ylabel='depth')
        # axes[0,1].plot(httd[1]['C'](x),x)
        # axes[0,1].set(title='C')
        # axes[1,0].plot()
        # axes[1,0].set(title="Nothing")
        # axes[1,1].plot(avg_wt)
        # axes[1,1].set(title="avg_wt_over_time")

        # # plot surface in cross-section
        # ele_with_can = copy.copy(ele).reshape(ny,nx)
        # ele_with_can = ele_with_can * catchment_mask
        # ele_with_can[wt_canal_arr > 0] = wt_canal_arr[wt_canal_arr > 0]
        # plot_line_of_peat(ele_with_can, y_value=y_value, title="cross-section", nx=nx, ny=ny, label="surface", color='peru', linewidth=2.0)

        # plt.show()

#    change_in_canals = (ele-phi.value).reshape(ny,nx)*(drmask.value.reshape(ny,nx)) - ((ele-H)*drmask.value).reshape(ny,nx)
#    resulting_phi = phi.value.reshape(ny,nx)

    wtd = (phi.value - ele).reshape(ny, nx)
    wtd_sensors = [wtd[i] for i in sensor_positions]

    return np.array(wtd_sensors)
コード例 #16
0
ファイル: demo.py プロジェクト: siri-ius/pyamg-examples
# This example solves a diffusion problem and demonstrates the use of
# applying boundary condition patches.
try:
    import fipy
except ImportError:
    raise ImportError('Problem with FiPy Installation')

from PyAMGSolver import PyAMGSolver

nx = 20
ny = nx
dx = 1.0
dy = dx
L = dx * nx
mesh = fipy.Grid2D(dx=dx, dy=dy, nx=nx, ny=ny)
phi = fipy.CellVariable(name="solution variable", mesh=mesh, value=0.)

# Apply Dirichlet boundary conditions (else Neumann by default)
valueTopLeft = 0
valueBottomRight = 1
x, y = mesh.getFaceCenters()
facesTopLeft = ((mesh.getFacesLeft() & (y > L / 2)) | (mesh.getFacesTop() &
                                                       (x < L / 2)))
facesBottomRight = ((mesh.getFacesRight() & (y < L / 2)) |
                    (mesh.getFacesBottom() & (x > L / 2)))
BCs = (fipy.FixedValue(faces=facesTopLeft, value=valueTopLeft),
       fipy.FixedValue(faces=facesBottomRight, value=valueBottomRight))

# set solver
# solver = LinearLUSolver(tolerance = 1.e-6, iterations = 100)
MGSetupOpts = {'max_coarse': 10}
コード例 #17
0
import fipy as fp
import glob
import json
import numpy as np
import os
import sys
from fipy.solvers.pysparse import LinearLUSolver as Solver

problem = '1'
domain = 'c'
nx = 100
dx = 1.0

# The first step in implementing any problem in FiPy is to define the mesh. In this case, the T-shaped domain is constructed out of two rectangular `Grid2D` objects. No other boundary conditions are required.

mesh = fp.Grid2D(Lx=20., Ly=100.0, dx=dx, dy=dx) + (
    fp.Grid2D(Ly=20.0, Lx=100.0, dx=dx, dy=dx) + [[-40], [100]])

# The next step is to define the parameters and create a solution variable.
# Constants and initial conditions:
# $c_{\alpha}$ and $c_{\beta}$ are concentrations at which the bulk free energy has minima.
# $\kappa$ is the gradient energy coefficient.
# $\varrho_s$ controls the height of the double-well barrier.

c_alpha = 0.3
c_beta = 0.7
kappa = 2.0
M = 5.0
c_0 = 0.5
epsilon = 0.01
rho_s = 5.0