Exemplo n.º 1
0
    def recommend(self, evidences, n):

        #BUG : As we expand the number of node to create a convinient Finite State Machine
        #we have to remove those node from the recomended items
        We, h0, hf = self.dummyExtension(evidences)
        We = matrix(We)
        h0 = matrix(h0)
        hf = matrix(hf)
        #Solve equation systems
        #TODO : This need to be done in Cython !
        row, col = We.shape
        I = eye(row, col)
        try:

            zf = spLinalg.cgs(I - We.T, h0)
            #zf = linalg.solve(I-We.T,h0)
            zb = spLinalg.cgs(I - We, hf)
            #zb = linalg.solve(I-We,hf)
        except linalg.LinAlgError:
            print 'Alpha %s and teta %s produce a Singular matrix exception' % (
                self.alpha, self.teta)
            raise linalg.LinAlgError

        zb = matrix(zb[0].reshape(zb[0].shape[0], 1))
        zf = matrix(zf[0].reshape(zf[0].shape[0], 1))

        Z = h0.T * zb - h0.T * hf

        zf = array(zf)
        zb = array(zb)
        h0 = array(h0)
        Z = array(Z)
        b = ((zf - h0) * zb) / Z

        #Removing dummy nodes
        #print 'Betweeness before sorting'
        #print b
        b = sort(b)[:-len(evidences)]
        #print 'Betweeness after sorting'
        #print b
        b[evidences] = 0
        bInd = argsort(b[:, 0])
        #print 'Len(bInd) : %s'%len(bInd)

        #Scores
        self.b = b.flatten()

        if n == -1:
            return bInd
        else:
            return bInd[-n:]
Exemplo n.º 2
0
	def recommend(self, evidences, n):
		
		#BUG : As we expand the number of node to create a convinient Finite State Machine
		#we have to remove those node from the recomended items
		We, h0, hf = self.dummyExtension(evidences)
		We = matrix(We)
		h0 = matrix(h0)
		hf = matrix(hf)
		#Solve equation systems
		#TODO : This need to be done in Cython !
		row, col = We.shape
		I = eye(row,col)
		try :
			
			zf = spLinalg.cgs(I-We.T,h0)
			#zf = linalg.solve(I-We.T,h0)
			zb = spLinalg.cgs(I-We,hf)
			#zb = linalg.solve(I-We,hf)
		except linalg.LinAlgError:
			print 'Alpha %s and teta %s produce a Singular matrix exception'%(self.alpha,self.teta)
			raise linalg.LinAlgError
		
		zb = matrix(zb[0].reshape(zb[0].shape[0],1))
		zf = matrix(zf[0].reshape(zf[0].shape[0],1))
		
		Z = h0.T * zb - h0.T * hf
		
		zf = array(zf)
		zb = array(zb)
		h0 = array(h0)
		Z = array(Z)
		b = ((zf - h0) * zb) / Z
		
		#Removing dummy nodes
		#print 'Betweeness before sorting'
		#print b
		b = sort(b)[:-len(evidences)]
		#print 'Betweeness after sorting'
		#print b
		b[evidences] = 0
		bInd = argsort(b[:,0])
		#print 'Len(bInd) : %s'%len(bInd)
		
		#Scores
		self.b = b.flatten()
		
		if n == -1:
			return bInd
		else:
			return bInd[-n:]
Exemplo n.º 3
0
    def cgs_solver(self, K, f_ext):
        """sadasdsa

        expects K in lil_matrix format
        """

        # convert stiffness matrix to csc format
        K_csc = sp.csc_matrix(K)

        if self.settings["precond"]:
            # perform ILU decomposition stiffness matrix
            pre_cond = linalg.LinearOperator(K.get_shape(),
                                             linalg.spilu(K_csc).solve)
        else:
            pre_cond = None

        (u, exit) = linalg.cgs(K_csc,
                               f_ext,
                               tol=self.settings["tol"],
                               maxiter=self.settings["maxiter"],
                               M=pre_cond)

        if (exit != 0):
            raise FEASolverError("CGS solver did not converge.")

        return u
Exemplo n.º 4
0
def solve(matrix, vector, sym_pos=False):
    """
    Solve a linear system.

    Uses the standard :func:`scipy.linalg.solve` if both *matrix* and *vector*
    are dense.

    If any of the two is sparse (from :mod:`scipy.sparse`) then will use the
    Conjugate Gradient Method (:func:`scipy.sparse.linalg.cgs`).

    Parameters
    ----------
    * matrix : 2d-array
        The matrix defining the linear system.
    * vector : 1d or 2d-array
        The right-side vector of the system.
    * sym_pos : bool
        If the matrix is not sparse and is symmetric positive definite, use
        ``sym_pos=True``.

    Returns
    -------
    * solution : 1d or 2d-array
        The solution of the linear system.

    """
    if sp.sparse.issparse(matrix) or sp.sparse.issparse(vector):
        solution, _ = spla.cgs(matrix, vector)
    else:
        solution = sp.linalg.solve(matrix, vector, sym_pos=sym_pos)
    return solution
Exemplo n.º 5
0
def QuadOptKnownSingle(A,b,known,knownY):

    n = A.shape[0]
    m = known.shape[0]
    unknown = list(set(range(n))-set(known))
    bk = b[known]
    bu = b[unknown]

    def mv(v):
        assert(v.shape[0]==n-m)
        # this trick allows me to compute A_uu * v
        z = np.zeros(n)
        z[unknown] = v
        r = A.matvec(z)
        return r[unknown]

    Linear = SSLA.LinearOperator( shape=(n-m,n-m), matvec=mv, dtype=float)
    # this trick allows me to compute A_uk * x_k
    zk = np.zeros(n)
    zk[known] = knownY
    rhs = bu - A.matvec(zk)[unknown]

    x = np.zeros(n)
    x[known] = knownY
    # cgs solver for non-symmetric system.
    result = SSLA.cgs(Linear, rhs, tol=1e-18)
    if result[1]==0:
        x[unknown] = result[0]
    else:
        print 'cg solver does not converge\n'

    return x
Exemplo n.º 6
0
def get_sol(P, indexes, c):
    R = np.ones((1, P.shape[1]))  # equality restrictions
    xm = P[:, indexes]

    # Building A
    a11 = xm.T.dot(xm)  # np.dot(xm.transpose(), xm)
    a21 = R[:, indexes]
    a12 = a21.transpose()
    a22 = np.zeros((1, 1))

    af1 = np.concatenate((a11, a12), axis=1)
    af2 = np.concatenate((a21, a22), axis=1)
    A = np.concatenate((af1, af2), axis=0)

    # Building B
    b11 = xm.T.dot(c)  # np.dot(xm.transpose(), c)
    b12 = np.ones(
        (1, 1))  # a11.shape[0]+a21.shape[0]-b11.shape[0], b11.shape[1]))
    B = np.concatenate((b11, b12), axis=0)

    A[A < 0.01] = 0
    spA = csr_matrix(A)

    xs = cgs(spA, B, maxiter=200)
    xs = xs[0]  # getting solutions
    xs = xs.reshape(len(xs), 1)
    xs = xs[0:-1, :]  # deleting lagangre multiplicator

    return xs
Exemplo n.º 7
0
def QuadOptSingle(A,b,Aeq,beq):

    n = A.shape[0]
    m = Aeq.shape[0]
    Aeqt = Aeq.transpose()

    def mv(v):
        assert(v.shape[0]==m+n)
        u = v[range(n)]
        l = v[range(n,m+n)]
        r = np.zeros(m+n)
        r[range(n)] = A.matvec(u) + Aeqt.dot(l)
        r[range(n,m+n)] = Aeq.dot(u)
        return r

    Linear = SSLA.LinearOperator( shape=(m+n,m+n), matvec=mv, dtype=float)
    rhs = np.zeros(m+n)
    rhs[range(n)] = b
    rhs[range(n,m+n)] = beq

    result = SSLA.cgs(Linear,rhs,tol=1e-3)
    if result[1]==0:
        x = result[0]
    else:
        print 'cg solver does not converge\n'

    return x
Exemplo n.º 8
0
def solve_cgs_lagrange(k_lg, f, tol=1e-5, m=None):
    """Solves a linear system of equations (Ku = f) using the CGS iterative
    method and the Lagrangian multiplier method.

    :param k: (N+1) x (N+1) Lagrangian multiplier matrix of the linear system
    :type k: :class:`scipy.sparse.csc_matrix`
    :param f: N x 1 right hand side of the linear system
    :type f: :class:`numpy.ndarray`
    :param float tol: Tolerance for the solver to acheieve. The algorithm
        terminates when either the relative or the absolute residual is below
        tol.
    :param m: Preconditioner for the linear matrix approximating the inverse
        of k
    :type m: :class:`scipy.linalg.LinearOperator`

    :return: The solution vector to the linear system of equations
    :rtype: :class:`numpy.ndarray`

    :raises RuntimeError: If the CGS iterative method does not converge or the
        error from the Lagrangian multiplier method exceeds the tolerance
    """

    (u, exit) = linalg.cgs(k_lg, np.append(f, 0), tol=tol, M=m)

    if (exit != 0):
        raise RuntimeError("CGS iterative method did not converge.")

    # compute error
    err = u[-1] / max(np.absolute(u))

    if err > tol:
        err = "Lagrangian multiplier method error exceeds tolerance."
        raise RuntimeError(err)

    return u[:-1]
Exemplo n.º 9
0
def solve_cgs(k, f, m=None, tol=1e-5):
    """Solves a linear system of equations (Ku = f) using the CGS iterative
    method.

    :param k: N x N matrix of the linear system
    :type k: :class:`scipy.sparse.csc_matrix`
    :param f: N x 1 right hand side of the linear system
    :type f: :class:`numpy.ndarray`
    :param float tol: Tolerance for the solver to acheieve. The algorithm
        terminates when either the relative or the absolute residual is below
        tol.
    :param m: Preconditioner for the linear matrix approximating the inverse
        of k
    :type m: :class:`scipy.linalg.LinearOperator`

    :return: The solution vector to the linear system of equations
    :rtype: :class:`numpy.ndarray`

    :raises RuntimeError: If the CGS iterative method does not converge
    """

    (u, exit) = linalg.cgs(k, f, tol=tol, M=m)

    if (exit != 0):
        raise RuntimeError("CGS iterative method did not converge.")

    return u
Exemplo n.º 10
0
    def getUDiff(self):
        """
        Get the value of the derivative of u from the model description
        :return: uDiffNew the derivative of u
        """

        # Calculate the dynamics of the network
        # the dynamics is calculated by solving a linear equation of the form A*uDiff=y
        # calculate the right hand side y
        y1 = np.dot(self.W, self.rho)
        y2 = -1.*self.u
        y3 = np.dot(np.diag(np.dot(self.W.T, self.u - np.dot(self.W, self.rho))), self.rho)
        y4 = self.beta*np.dot(np.diag(self.targetMask), self.targetValue + self.tau*self.targetPrime - self.u)
        y = y1 + y2 + y3 + y4

        # Calculate the right hand side A
        A1 = np.dot(self.W, np.diag(self.rhoPrime))
        A2 = np.dot(np.diag(np.dot(self.W.T, self.u - np.dot(self.W, self.rho))), np.diag(self.rhoPrimePrime))
        A3 = np.dot(np.diag(self.rhoPrime), np.dot(self.W.T, np.identity(self.N)-np.dot(self.W, np.diag(self.rhoPrime))))
        A4 = self.beta * np.diag(self.targetMask)
        A = self.tau * (np.identity(self.N) - A1 - A2 - A3 + A4)

        # Now we look at the dynamics only of the free neurons
        indexFree = np.where(self.inputMask == 0)[0]
        inputPrime = self.inputPrime * self.inputMask
        y = (y - np.dot(A,inputPrime))[indexFree]
        A = A[np.ix_(indexFree, indexFree)]

        # Solve for uDiff
        res = linalg.cgs(A, y, x0=self.uDiff[indexFree])
        uDiff = np.zeros(self.N)
        uDiff[indexFree] = res[0]

        return uDiff
def solve(A, b, method, tol=1e-3):
    """ General sparse solver interface.

    method can be one of
    - spsolve_umfpack_mmd_ata
    - spsolve_umfpack_colamd
    - spsolve_superlu_mmd_ata
    - spsolve_superlu_colamd
    - bicg
    - bicgstab
    - cg
    - cgs
    - gmres
    - lgmres
    - minres
    - qmr
    - lsqr
    - lsmr
    """

    if method == 'spsolve_umfpack_mmd_ata':
        return spla.spsolve(A, b, use_umfpack=True, permc_spec='MMD_ATA')
    elif method == 'spsolve_umfpack_colamd':
        return spla.spsolve(A, b, use_umfpack=True, permc_spec='COLAMD')
    elif method == 'spsolve_superlu_mmd_ata':
        return spla.spsolve(A, b, use_umfpack=False, permc_spec='MMD_ATA')
    elif method == 'spsolve_superlu_colamd':
        return spla.spsolve(A, b, use_umfpack=False, permc_spec='COLAMD')
    elif method == 'bicg':
        res = spla.bicg(A, b, tol=tol)
        return res[0]
    elif method == 'bicgstab':
        res = spla.bicgstab(A, b, tol=tol)
        return res[0]
    elif method == 'cg':
        res = spla.cg(A, b, tol=tol)
        return res[0]
    elif method == 'cgs':
        res = spla.cgs(A, b, tol=tol)
        return res[0]
    elif method == 'gmres':
        res = spla.gmres(A, b, tol=tol)
        return res[0]
    elif method == 'lgmres':
        res = spla.lgmres(A, b, tol=tol)
        return res[0]
    elif method == 'minres':
        res = spla.minres(A, b, tol=tol)
        return res[0]
    elif method == 'qmr':
        res = spla.qmr(A, b, tol=tol)
        return res[0]
    elif method == 'lsqr':
        res = spla.lsqr(A, b, atol=tol, btol=tol)
        return res[0]
    elif method == 'lsmr':
        res = spla.lsmr(A, b, atol=tol, btol=tol)
        return res[0]
    else:
        raise Exception('UnknownSolverType')
Exemplo n.º 12
0
def main():
    """
    try:
        for i in range(5):
            if i == 3:
                raise ValueError("CV error " + str(i))
            print 'ojala', i
    except ValueError as e:
        print e
    """
    A = np.array([[1, 2, 0], [0, 0, 3], [1, 0, 4]])
    spA = csr_matrix(A)
    spB = spA * spA

    B = spB.todense()
    print B
    print B.shape

    # data = sp.concatenate(spA.data,spB.data) # arreglar aqui
    # rows = sp.concatenate((spA.row,spB.row))
    # cols = sp.concatenate((spA.col,spB.col))
    # nueva = sparse.coo_matrix((data,(rows,cols)), shape=(3,6))
    # print nueva.todense()

    #########

    n = 1250
    A1 = np.random.rand(n, n)
    B1 = np.random.rand(n, 1)

    index = A1 < 0.9
    A1[index] = 0
    B1[B1 < 0.98] = 0

    sp_A1 = csr_matrix(A1)  # coo_matrix(A1)
    #print sp_A1

    t0 = timeit.default_timer()
    x = cgs(sp_A1, B1)
    tf = timeit.default_timer()

    x = cgs(A1, B1)
    tf1 = timeit.default_timer()

    print 'modo sparse(seg)', tf - t0
    print 'modo normal(seg)', tf1 - tf
Exemplo n.º 13
0
 def get_vh(self, density):
     assert isinstance(density, Density)
     density = density.d
     grid = self.grid
     ngrids = grid.shape[0] * grid.shape[1] * grid.shape[2]
     #pdb.set_trace()
     vh = cgs(self.lapn, -4 * pi * (density))[0]
     vh = spdiags(vh, 0, ngrids, ngrids)
     return vh
Exemplo n.º 14
0
    def recommend(self, evidences, n):

        print 'Recommend items'
        We, h0, hf = self.dummyExtension(evidences)
        We = matrix(We)
        h0 = matrix(h0)
        hf = matrix(hf)
        #Solve equation systems
        #TODO : This need to be done in Cython !
        row, col = We.shape
        I = eye(row, col)
        try:

            zf = spLinalg.cgs(I - We.T, h0)
            #zf = linalg.solve(I-We.T,h0)
            zb = spLinalg.cgs(I - We, hf)
            #zb = linalg.solve(I-We,hf)
        except linalg.LinAlgError:
            print 'Alpha %s and teta %s produce a Singular matrix exception' % (
                self.alpha, self.teta)
            raise linalg.LinAlgError

        zb = matrix(zb[0].reshape(zb[0].shape[0], 1))
        zf = matrix(zf[0].reshape(zf[0].shape[0], 1))

        Z = h0.T * zb - h0.T * hf

        zf = array(zf)
        zb = array(zb)
        h0 = array(h0)
        Z = array(Z)
        b = ((zf - h0) * zb) / Z

        b[evidences] = 0
        bInd = argsort(b[:, 0])

        #Scores
        self.b = b.flatten()

        if n == -1:
            return bInd
        else:
            return bInd[-n:]
Exemplo n.º 15
0
	def recommend(self, evidences, n):
		
		print 'Recommend items'	
		We, h0, hf = self.dummyExtension(evidences)
		We = matrix(We)
		h0 = matrix(h0)
		hf = matrix(hf)
		#Solve equation systems
		#TODO : This need to be done in Cython !
		row, col = We.shape
		I = eye(row,col)
		try :
			
			zf = spLinalg.cgs(I-We.T,h0)
			#zf = linalg.solve(I-We.T,h0)
			zb = spLinalg.cgs(I-We,hf)
			#zb = linalg.solve(I-We,hf)
		except linalg.LinAlgError:
			print 'Alpha %s and teta %s produce a Singular matrix exception'%(self.alpha,self.teta)
			raise linalg.LinAlgError
		
		zb = matrix(zb[0].reshape(zb[0].shape[0],1))
		zf = matrix(zf[0].reshape(zf[0].shape[0],1))
		
		Z = h0.T * zb - h0.T * hf
		
		zf = array(zf)
		zb = array(zb)
		h0 = array(h0)
		Z = array(Z)
		b = ((zf - h0) * zb) / Z
		
		b[evidences] = 0
		bInd = argsort(b[:,0])
		
		#Scores
		self.b = b.flatten()
		
		if n == -1:
			return bInd
		else:
			return bInd[-n:]
Exemplo n.º 16
0
 def solve_ls(self, M, M0=None):
     if M0 is None:    M0 = 1E-3 * sp.randn(*M.shape)
     def veKvei(m):
         _M = m.reshape(M.shape, order='F')
         return self.dot(_M).reshape(M.size, order='F')
     Kx_O = sla.LinearOperator((M.size, M.size), matvec=veKvei, rmatvec=veKvei, dtype='float64')
     # vectorize
     m  = M.reshape(M.size, order='F')
     m0 = M0.reshape(M0.size, order='F')
     r, _ = sla.cgs(Kx_O, m, x0=m0, tol=self._tol)
     return r.reshape(M.shape, order='F')
Exemplo n.º 17
0
def fista(A, b, mu, g, prox_g, x_0=False, iter=200, log=stdout):
    """Solves min (1/2)||Ax - b||^2 + mu*g(x) by backtracking FISTA
    prox_g is the proximal function of g,
    prox_g(v,s) = argmin_u (1/2)||u-v||^2 + s*g(u)
    
    x_0 is the initial value (set to 0 by default)
    mu is a regularization parameter"""
    def F(x):
        r = A * x - b
        return 0.5 * np.dot(r, r) + mu * g(x)

    def P(L, y):
        grad_f = A.T * (A * y - b)
        return prox_g(y - 1. / L * grad_f, mu / L)

    n, m = A.shape

    if x_0:
        x = x_0
    else:
        # this might be a terrible idea, but i'm not sure what else to do
        x, _ = cgs(A.T * A + mu * sp.sparse.identity(m), (A.T) * b)

    y = x
    t = 1.0
    L = 1.0
    eta = 2.0

    log.write('L = %f\n' % L)
    for k in range(0, iter):
        log.write('iter. %d\n' % k)

        xold = x
        x = P(L, y)
        r = A * y - b
        f_y = 0.5 * np.dot(r, r)
        grad_f_y = (A.T) * r
        Q = f_y + np.dot(x - y,
                         grad_f_y) + (L / 2) * np.dot(x - y, x - y) + mu * g(x)
        while F(x) > Q:
            L = L * eta
            log.write('L = %f\n' % L)
            x = P(L, y)
            Q = f_y + np.dot(
                x - y, grad_f_y) + (L / 2) * np.dot(x - y, x - y) + mu * g(x)
        told = t
        t = (1 + sqrt(1 + 4 * told * told)) / 2
        y = x + ((told - 1) / t) * (x - xold)

    return x
Exemplo n.º 18
0
def cgs_solve(A, u, b, tol=1e-08):
    print("Solving system using CGS solver")
    """ Solves the linear system A*u = b
        Input
            A: numpy array of NxN components (LHS)
            b: numpy array of Nx1 components (RHS)
            u: numpy array of Nx1 components (Solution)
    """

    # Change RHS representation
    A = sp.csr_matrix(A)

    # Solve system
    u[:] = spla.cgs(A, b, tol=tol)[0]
Exemplo n.º 19
0
    def iterative_solver_list(self, which, rhs, *args):
        """Solves the linear problem Ab = x using the sparse matrix

            Parameters
            ----------
            rhs : ndarray
                the right hand side
            which : string
                choose which solver is used
                    bicg(A, b[, x0, tol, maxiter, xtype, M, ...])
                        Use BIConjugate Gradient iteration to solve A x = b

                    bicgstab(A, b[, x0, tol, maxiter, xtype, M, ...])
                        Use BIConjugate Gradient STABilized iteration to solve A x = b

                    cg(A, b[, x0, tol, maxiter, xtype, M, callback])
                        Use Conjugate Gradient iteration to solve A x = b

                    cgs(A, b[, x0, tol, maxiter, xtype, M, callback])
                        Use Conjugate Gradient Squared iteration to solve A x = b

                    gmres(A, b[, x0, tol, restart, maxiter, ...])
                        Use Generalized Minimal RESidual iteration to solve A x = b.

                    lgmres(A, b[, x0, tol, maxiter, M, ...])
                        Solve a matrix equation using the LGMRES algorithm.

                    minres(A, b[, x0, shift, tol, maxiter, ...])
                        Use MINimum RESidual iteration to solve Ax=b

                    qmr(A, b[, x0, tol, maxiter, xtype, M1, M2, ...])
                        Use Quasi-Minimal Residual iteration to solve A x = b
        """
        if which == 'bicg':
            return spla.bicg(self.sp_matrix, rhs, args)
        elif which == "cg":
            return spla.cg(self.sp_matrix, rhs, args)
        elif which == "bicgstab":
            return spla.bicgstab(self.sp_matrix, rhs, args)
        elif which == "cgs":
            return spla.cgs(self.sp_matrix, rhs, args)
        elif which == "gmres":
            return spla.gmres(self.sp_matrix, rhs, args)
        elif which == "lgmres":
            return spla.lgmres(self.sp_matrix, rhs, args)
        elif which == "qmr":
            return spla.qmr(self.sp_matrix, rhs, args)
        else:
            raise NotImplementedError("this solver is unknown")
Exemplo n.º 20
0
    def recommend(self, evidences, n):

        I = eye(self.nbItems)
        u = zeros(self.nbItems)
        u[evidences] = 1  #1/nbEvidences ???
        try:
            r = spLinalg.cgs(I - (self.alpha * self.P), (1 - self.alpha) * u)
        except linalg.LinAlgError:
            print 'Linear Algebra Error'
            raise linalg.LinAlgError

        r[0][evidences] = 0
        ind = argsort(r[0])  #Item with highest scores are recommended

        return ind[-n:]
Exemplo n.º 21
0
	def recommend(self, evidences, n):
		
		I = eye(self.nbItems)
		u = zeros(self.nbItems)
		u[evidences] = 1 #1/nbEvidences ???
		try:
			r = spLinalg.cgs(I-(self.alpha * self.P),(1-self.alpha)*u)
		except linalg.LinAlgError:
			print 'Linear Algebra Error'
			raise linalg.LinAlgError
		
		r[0][evidences] = 0
		ind = argsort(r[0]) #Item with highest scores are recommended
		
		return ind[-n:]
Exemplo n.º 22
0
    def solve_ls(self, M, M0=None):
        if M0 is None: M0 = 1E-3 * sp.randn(*M.shape)

        def veKvei(m):
            _M = m.reshape(M.shape, order='F')
            return self.dot(_M).reshape(M.size, order='F')

        Kx_O = sla.LinearOperator((M.size, M.size),
                                  matvec=veKvei,
                                  rmatvec=veKvei,
                                  dtype='float64')
        # vectorize
        m = M.reshape(M.size, order='F')
        m0 = M0.reshape(M0.size, order='F')
        r, _ = sla.cgs(Kx_O, m, x0=m0, tol=self._tol)
        return r.reshape(M.shape, order='F')
Exemplo n.º 23
0
def LinSolve(A,b,x0,method):
    if method=='bicg':
        x,info = bicg(A,b,x0)
    if method=='cgs':
        x,info = cgs(A,b,x0)
    if method=='bicgstab':
        x,info = bicgstab(A,b,x0)
        if (info): print 'INFO=',info
    if method=='superLU':
        x = linsolve.spsolve(A,b,use_umfpack=False) 
    if method=='umfpack':
        x = linsolve.spsolve(A,b,use_umfpack=True) 
    if method=='gmres':
        x,info = gmres(A,b,x0) 
    if method=='lgmres':
        x,info = lgmres(A,b,x0) 
    return x
Exemplo n.º 24
0
def compute_effective_moduli(eps, K4, G, G_K_deps, hx, hy, vol):
    ALPHA4 = np.zeros([dim, dim, dim, dim, Nx, Ny])
    for alpha in range(dim):
        for beta in range(dim):
            delta_epsbar_alpha_beta = 1
            b = -G(K4[:, :, alpha, beta] * delta_epsbar_alpha_beta)
            depsm, _ = sp.cgs(A=sp.LinearOperator(shape=(eps.size, eps.size),
                                                  matvec=G_K_deps,
                                                  dtype='float'),
                              b=b,
                              tol=1e-8,
                              maxiter=50)
            ALPHA4[:, :, alpha, beta, :, :] = depsm.reshape(dim, dim, Nx, Ny)
    F_ALPHA4 = ddot44_v1(K4, (II4 + ALPHA4))
    C_consistent_tangent = zeros((dim, dim, dim, dim))
    for i, j, k, l in itertools.product(range(dim), repeat=4):
        C_consistent_tangent[i, j, k, l] = 1.0 / vol * hx * hy * np.sum(
            F_ALPHA4[i, j, k, l, :, :])
    return C_consistent_tangent
Exemplo n.º 25
0
    def correct_pressure(self, u, p):
        div = self.divergence(u)

        print("completed calculating divergences")

        # construct a sparse matrix representing the system of equations relating pressure with divergence
        nrows = np.sum(self.water_mask)
        index = np.argwhere(self.water_mask)

        row_index = np.zeros(self.water_mask.shape, dtype='int32')
        row_index[self.water_mask == 1] = np.arange(0, nrows)

        rows = array.array('i')
        cols = array.array('i')
        data = array.array('i')

        for cell in range(nrows):
            i, j = index[cell]
            p_ij_coef = self.water_or_air_cell_neighbors[i, j]
            rows.append(cell)
            cols.append(cell)
            data.append(p_ij_coef)
            for (di, dj) in [(-1, 0), (1, 0), (0, -1), (0, 1)]:
                if self.water_mask[i + di, j + dj]:
                    neighboring_cell = row_index[i + di, j + dj]
                    rows.append(cell)
                    cols.append(neighboring_cell)
                    data.append(-self.water_mask[i + di, j + dj])

        rows = np.frombuffer(rows, dtype='int32')
        cols = np.frombuffer(cols, dtype='int32')
        data = np.frombuffer(data, dtype='int32')
        A = sp.coo_matrix((data, (rows, cols)), shape=(nrows, nrows))
        A = A.tocsc().multiply(self.Δt / (self.ρ * self.Δx ** 2))
        M = linalg.LinearOperator((nrows, nrows), linalg.spilu(A).solve)
        sol = linalg.cgs(A=A, b=-div[self.water_mask == 1], M=M, x0=np.zeros(nrows), tol=1.0e-20)

        new_p = np.copy(p)
        new_p[self.water_mask == 1] = sol[0]

        new_u = self.pressure_gradient_update(u.copy(), new_p)

        return FluidState(u=new_u, p=new_p, particles=self.state.particles)
Exemplo n.º 26
0
    def _F(self, flux):
        """Private routine for outer eigenvalue solver method.

        Uses a Krylov subspace method (e.g., GMRES, BICGSTAB) from the
        scipy.linalg package to solve the AX=B fixed scatter source problem.

        Parameters
        ----------
        flux : numpy.ndarray
            The flux array returned from the scipy.linalg.eigs routine

        Returns
        -------
        flux : numpy.ndarray
            The flux computed from the fission/scatter fixed source calculations

        """

        import scipy.sparse.linalg as linalg

        # Apply operator to flux - get updated flux from fission source
        flux = self._M_op * flux

        # Solve AX=B fixed scatter source problem using Krylov subspace method
        if self._inner_method == 'gmres':
            flux, x = linalg.gmres(self._A_op, flux, tol=self._inner_tol)
        elif self._inner_method == 'lgmres':
            flux, x = linalg.lgmres(self._A_op, flux, tol=self._inner_tol)
        elif self._inner_method == 'bicgstab':
            flux, x = linalg.bicgstab(self._A_op, flux, tol=self._inner_tol)
        elif self._inner_method == 'cgs':
            flux, x = linalg.cgs(self._A_op, flux, tol=self._inner_tol)
        else:
            py_printf('ERROR', 'Unable to use %s to solve Ax=b',
                      self._inner_method)

        # Check that solve completed without error before returning new flux
        if x != 0:
            py_printf('ERROR', 'Unable to solve Ax=b with %s',
                      self._inner_method)
        else:
            return flux
Exemplo n.º 27
0
    def cgs_solver(self, K, f_ext):
        """Solves Ku=f_ext for *u* using the cgs method.

        :param K: Global stiffness matrix
        :type K: :class:`scipy.sparse.lil_matrix`
        :param f_ext: External force vector
        :type f_ext: :class:`numpy.ndarray`

        :returns: Displacement vector *u*
        :rtype: :class:`numpy.ndarray`

        :raises Exception: If the cgs solver does not converge or if the preconditioner fails
        """

        # convert stiffness matrix to csc format
        K_csc = sp.csc_matrix(K)

        if self.solver_settings.linear_static.cgs_precond:
            # perform ILU decomposition stiffness matrix
            try:
                precond = linalg.LinearOperator(K.get_shape(),
                                                linalg.spilu(K_csc).solve)
            except RuntimeError:
                raise Exception('Preconditioner could not be constructed.')
        else:
            precond = None

        tol = self.solver_settings.linear_static.cgs_tol
        maxiter = self.solver_settings.linear_static.cgs_maxiter

        (u, exit) = linalg.cgs(K_csc,
                               f_ext,
                               tol=tol,
                               maxiter=maxiter,
                               M=precond)

        if (exit != 0):
            raise Exception('CGS solver did not converge.')

        return u
Exemplo n.º 28
0
def Admm(function_A,u,d1,d2,b1,b2,ATf,lamb,mu,mode='constant',delta=1,ite=8,cg_tol=1e-3):
    b0 = ATf - np.reshape(mu*div(d1-b1,d2-b2,mode=mode),-1)
    u = u.reshape(-1)
    u,infos = linalg.cgs(function_A,b0,x0=u,maxiter=ite,tol=cg_tol)
    u[u>1.0]=1.0
    u[u<0.0]=0
#    u,infos = linalg.cgs(function_A,b0,x0=u,maxiter=ite)
#    u,infos = linalg.cgs(function_A,b0,maxiter=3)
    print(infos)
    print('max_u='+ str(np.max(u)) + '    min_u='+str(np.min(u))) 
#    print(np.linalg.norm(function_A(u)-b0)/np.linalg.norm(b0))
    u = u.reshape(d1.shape)
#    u = (u-np.min(u)) / (np.max(u)-np.min(u))
#    u = u/np.max(abs(u))
#    u[u>1.0]=1.0
#    u[u<0.0]=0
    Wu1,Wu2 = grad(u,mode=mode)
    d1 = Tau(lamb/mu, Wu1+b1)
    d2 = Tau(lamb/mu, Wu2+b2)
    b1 = b1 + delta*(Wu1-d1)
    b2 = b2 + delta*(Wu2-d2)
    return u,d1,d2,b1,b2,Wu1,Wu2
Exemplo n.º 29
0
def sb_itv(g, mu, tol=1e-3, cgs_tol=1e-5, log=stdout):
    """Split Bregman Isotropic Total Variation Denoising
    u = arg min_u 1/2||u-g||_2^2 + mu*ITV(u)"""
    n, m = g.shape
    l = n * m
    Dx, Dy = diff_oper(n, m)
    g = g.flatten()
    B = sp.sparse.bmat([[Dx], [Dy]])

    Bt = B.T
    BtB = Bt * B

    b = np.zeros(2 * l)
    z = np.zeros(l)
    d, u = b, g
    err, k = 1, 1
    lam = 1.0

    M = sp.sparse.identity(l) + BtB

    while err > tol:
        log.write("tv it. %d\n" % k)
        up = u
        # optimize this
        u, _ = cgs(M, g - lam * Bt * (b - d), tol=cgs_tol, maxiter=100)
        Bub = B * u + b

        d = px.prox_l1_2(Bub, mu / lam)
        b = Bub - d
        err = norm(up - u) / norm(u)
        log.write("err=%f\n" % err)
        k = k + 1

    log.write("Stopped because norm(up-u)/norm(u) <= tol=%f\n" % tol)
    z = (B * u - d)[:l].reshape((n, m))
    #u = u.reshape((n,m))
    return z
Exemplo n.º 30
0
while ediff > 10**-6:
    Vtot3 = spdiags(vtot, 0, g3, g3)

    E, psi = eigsh(-0.5 * Lap3 + Vtot3, k=1,
                   which='SA')  #Real eigenval and vectors
    psi = ravel(psi)
    psi = psi / h**(3. / 2)
    n = 2 * psi**2

    #exchange
    vex = -(3. / pi)**(1. / 3) * n**(1. / 3)

    #hartree
    #Lap3 Vh = -4*pi*n
    #pdb.set_trace()
    vh = cgs(Lap3, -4 * pi * (n + ncomp))[0] - vcomp  #Poisson solver

    vtot = vex + vh + vext
    #pdb.set_trace()
    T1 = csr_matrix.dot(-0.5 * Lap3, psi)
    T2 = csc_matrix.dot(csc_matrix(psi), T1)
    T = T2 * 2 * h**3
    T = T[0]

    Eext = sum(n * vext) * h**3
    Eh = 0.5 * sum(n * vh) * h**3
    Ex = sum(-(3. / 4) * (3. / pi)**(1. / 3) * n**(4. / 3)) * h**3

    Etot = T + Eext + Eh + Ex

    ediff = abs(Eprev - Etot)
Exemplo n.º 31
0
tod = pacs.get_tod()
# projector
projection = tm.Projection(pacs, resolution=3.2, 
                           oversampling=True, npixels_per_sample=6)
masking = tm.Masking(tod.mask)
compression = tm.CompressionAverage(pacs.compression_factor)
model = masking * compression * projection
# naive map
naive = model.transpose(tod)
# coverage map
coverage = model.transpose(tod.ones(tod.shape))
# noise covariance
length = 2**np.ceil(np.log2(np.array(tod.nsamples) + 200))
invNtt = tm.InvNtt(length, pacs.get_filter_uncorrelated())
fft = tm.Fft(length)
padding = tm.Padding(left=invNtt.ncorrelations, 
                     right=length - tod.nsamples - invNtt.ncorrelations)
weight = padding.T * fft.T * invNtt * fft * padding
W = lo.aslinearoperator(weight.aslinearoperator())
# transform to lo
P = lo.aslinearoperator(model.aslinearoperator())
# priors
Ds = [lo.diff(naive.shape, axis=axis) for axis in xrange(naive.ndim)]
# inversion
hypers = [1e6, 1e6, ]
y = tod.flatten()
M = P.T * W * P + np.sum([h * D.T * D for h, D in zip(hypers, Ds)])
x, conv = spl.cgs(M, P.T * W * y, callback=lo.CallbackFactory(verbose=True))
sol = naive.zeros(naive.shape)
sol[:] = x.reshape(sol.shape)
Exemplo n.º 32
0
def run_varsat(L, T, dz, tstep, h_init, bc, q, soil_carac, PICmax = 10, CRIT_CONV = 1e-2, Runoff='True'):
    # L : column length
    # T : simulation duration
    # dz : vertical discretization
    # dts : time step, which may be constant or variable. In the latter case, we must have : np.cumsum(dts) = T
    # h_init : initial profile of pressure head, must be of size I = int(round(L/dz))
    # bc : dictionary of boundary conditions : e.g. {'top':['fixed_head',[h_top]*N],'bot':['fixed_head',[h_bot]*N]}
    #      allowed bc at the top : 'fixed_head','fixed_flow',
    #      allowed bc at the bottom : 'fixed_head','fixed_flow','free_drainage'
    # q : source term. May be constant homogeneous (scalar), constant (size I array), variable in space and time (size I*N array)
    # soil_carac : e.g. soil_carac = {'Ksat':1e-4, 'Ss':0, 'eta':0.368, 'theta_r' : 0.102, 'theta_s' : 0.368, 'n':2, 'alpha':3.35}
    # PICmax : maximum number of Picard iteration
    # CRIT_CONV : convergence criteria.
    # Runoff='True' --> Runoff will be calculated instead of a pounding condition
    # -- model initialization
    # init vars
    tmin=1.
    tmax=3600.
    if tstep>T:
        tstep=T
    if tstep>tmax:
        tstep=3600.
    if tstep<tmin:
        tstep=1.

    #if hasattr(dts,"__len__") == False:
        #dts  = np.array( [dts] * int(round(T/dts)) )
    t=np.array(0)
    tt=t
    #t = np.hstack((0,np.cumsum(dts))) # time array
    N = int(round(T/tmin)) # number of time steps
    I = int(round(L/dz)+1) # number of cells
    z = np.linspace(0,L,I) # z coordinates of nodes
    # check h_init
    if len(h_init) != I:
        print('ERROR: check dimension of h_init')
        return(0,0,0)
    #  check q (not fully implemented)
    #if hasattr(q,"__len__") == False: #  constant and homogeneous q
    #    q  = np.array( [ [q] * N] * I  )
    #elif np.array(q).shape == (I,) :  # transient homogeneous q
    #    q = np.transpose(np.array(  [list(q)]*N ) ) 
    # -- check input data
    # check bc : 
    if bc['top'][0] not in ['fixed_head','fixed_flow','free_drainage'] :
        print('ERROR: check top boundary condition')
    if bc['bot'][0] not in ['fixed_head','fixed_flow','free_drainage'] :
        print('ERROR: check bottom boundary condition')
    #initialize Runoff and Infiltration
    RO = np.zeros((1))
    INF = np.zeros((1))
    PER = np.zeros((1))
    TA = np.zeros((1))
    VOL = np.zeros((1))
    # -- run initization
    # initialize output matrices
    S=np.mat(np.zeros(shape=(I,1))) 
    #include the time 0
    # Store initial condition
    S[:,0]= np.transpose(np.mat(h_init))
    h = h0 = h_init 
    h_list = []
    Theta = np.mat(np.zeros(shape=(I,1)))
    theta0 = get_theta(h0,soil_carac)
    Theta[:,0]=np.transpose(np.mat(theta0))
    Ka = np.mat(np.zeros(shape=(I,1))) # util para comparar con Hydrus
    K0 = get_K(h,soil_carac)
    Ka[:,0]=np.transpose(np.mat(K0))
    Flow = np.mat(np.zeros(shape=(I,1)))
    VOL[0] = (get_SUM(theta0,dz,I))*dz
    Ta=0.
    Ro=0.
    Infil=0.
    Per=0.

    # iterate over time
    dts=tstep
    dt=dts
    t=np.zeros([1])
    for n in range(1,N):
        t=np.hstack((t,(t[-1]+dts)))
        for w in range(1,len(bc['time'])):
            if t[-1]<bc['time'][w]:
                ww=w-1
                break
            else:
                ww=w
        gl_val(dts)
        theta0 = get_theta(h0,soil_carac)
        #RO=np.hstack((RO,0.))
        #INF=np.hstack((INF,bc['top'][1][ww]*dt)) #we must choose if we want to calculate the infiltration even with fixed head, now it only calculates to fixed flow
        # Picard iteration 
        h00=h
        for m in range(PICmax):
            Iter=m
            M , B = build_system(h0, h, theta0 , bc, q, soil_carac, ww, bcff='False')
            # solver linear system
            h1 = np.transpose(np.matrix(cgs(csr_matrix(M),B)[0]))
            if np.max(h1-h) < CRIT_CONV:
                print('PIC iteration = '+ str(m))
                break
            h=h1
        if Runoff=='True':
            if h1[-1]> 0 :
                #Include the Runoff Modification                        
                h=h00
                for mm in range (PICmax):
                    Iter=mm
                    M , B = build_system(h0, h, theta0 , bc, q, soil_carac, ww, bcff='True')
                    # solver linear system
                    h1 = np.transpose(np.matrix(cg(csr_matrix(M),B)[0])) # see also cgs, csr, spsolve
                    if np.max(h1-h) < CRIT_CONV:   
                        print( 'Runoff Modification PIC iteration ='+str(mm))
                        break
                    h=h1
        h=h1   
            
        #Infil = Kp[-1]*(((get_m1(I-1,Kp)*h1[-2]+get_b2(I-1,theta,soil_carac)*h0[-1] \
        #    -get_b3(I-2,Kp)-get_b4(I-1,theta0,theta))/(get_m3(I-1,Kp)*dz))-1)
        #Ro=(bc['top'][1][ww]-Infil[0,0])*dt
        #RO=np.hstack((RO, (bc['top'][1][ww]-Infil[0,0])*dt))
        #INF=np.hstack((INF,Infil[0,0]*dt))      
        
        theta = get_theta(h,soil_carac)
        C     = get_C(h,soil_carac)
        K     = get_K(h,soil_carac)
        Kp    = get_Kp(K)
        WU    = w_uptake(theta0, RD, q[ww], soil_carac, dz) # water update
        Ta    = get_SUM(WU,dz,I)*dts*dz+Ta # cumulative transpiration
        Flux  = get_flux(Kp,h,dz,theta,theta0,dts,WU)  # flux in each node 
        Per = Flux[0]*dts+Per # cumulative percolation
        if h[-1]>=0.:
            Infil = Flux[-1]*dts+Infil  # infiltration at the top of the soil column
            Ro = Ro+(bc['top'][1][ww]-Flux[-1])*dts # Runoff 
        else:
            Infil = bc['top'][1][ww]*dts+Infil
            Ro=Ro+0

        if t[-1]==bc['time'][ww] or t[-1]==T:
            Theta = np.c_[Theta,np.zeros(I)]
            Theta[:,-1] = np.transpose(np.mat(theta))
            Ka = np.c_[Ka,np.zeros(I)]
            Ka[:,-1] = np.transpose(np.mat(K))
            S = np.c_[S,np.zeros(I)]
            S[:,-1] = np.mat(h)
            Flow = np.c_[Flow,np.zeros(I)] # matrix, same as S
            Flow[:,-1] = np.transpose(np.mat(Flux))
            TA = np.hstack((TA, Ta)) # useful for mass balance 
            RO = np.hstack((RO, Ro)) # idem
            INF = np.hstack((INF,Infil)) # idem
            PER = np.hstack((PER, Per)) # idem
            VOL = np.hstack((VOL, (get_SUM(theta,dz,I))*dz)) # Volume of water in each cell for each 
            tt = np.hstack((tt,bc['time'][ww]))
            Ro=0.
            Infil=0.
            Per=0.
            Ta=0. 


        if t[-1]==T: #  if last time step is reached
            tt[-1] = 
            break
        h0 = h
        if t[-1]==bc['time'][ww]:
            dts=dts #key feature, if flux input vary variable it would be better to use dts=tmin
        else:
            if t[-1]>bc['time'][(len(bc['time'])-1)]:
                if Iter<=3:
                    dts=max(1.3*dts,tmin)
                    if (T-t[-1])<=(dts+tmin):
                        dts=max(tmin,(T-t[-1]))
                elif Iter>3 and Iter<=7:
                    dts=dts
                    if (T-t[-1])<=(dts+tmin):
                        dts=max(tmin,(T-t[-1]))
                elif Iter>7 and Iter<PICmax:
                    dts=max(0.7*dts,tmin)
                    if (T-t[-1])<=(dts+tmin):
                        dts=max(tmin,(T-t[-1]))
                else:
                    dts=max(dts/3,tmin)
                    if (T-t[-1])<=(dts+tmin):
                        dts=max(tmin,(T-t[-1]))
            else:
                if Iter<=3:
                    dts=max(1.3*dts,tmin)
                    if (bc['time'][ww+1]-t[-1])<=(dts+tmin):
                        dts=max(tmin,(bc['time'][ww+1]-t[-1]))
                elif Iter>3 and Iter<=7:
                    dts=dts
                    if (bc['time'][ww+1]-t[-1])<=(dts+tmin):
                        dts=max(tmin,(bc['time'][ww+1]-t[-1]))
                elif Iter>7 and Iter<PICmax:
                    dts=max(0.7*dts,tmin)
                    if (bc['time'][ww+1]-t[-1])<=(dts+tmin):
                        dts=max(tmin,(bc['time'][ww+1]-t[-1]))
                else:
                    dts=max(dts/3,tmin)
                    if (bc['time'][ww+1]-t[-1])<=(dts+tmin):
                        dts=max(tmin,(bc['time'][ww+1]-t[-1]))
        print('iteration ' + str(n) + ' terminated.')
    # return simulation results

    return(t,tt,z,S,Theta,Ka,Flow,INF,RO,PER,TA,VOL)
Exemplo n.º 33
0
def run_varsat(L, T, dz, tstep, h_init, bc, q, soil_carac, PICmax = 20, CRIT_CONV = 1.e-2, Runoff='True'):
    # L : column length
    # T : simulation duration
    # dz : vertical discretization
    # tstep : initial time step
    # h_init : initial profile of pressure head, must be of size I = int(round(L/dz))
    # bc : dictionary of boundary conditions : e.g. {'top':['fixed_head',[h_top]*N],'bot':['fixed_head',[h_bot]*N]}
    #      allowed bc at the top : 'fixed_head','fixed_flow',
    #      allowed bc at the bottom : 'fixed_head','fixed_flow','free_drainage'
    # q : source term. in our case is the potential transpiration estimated from the interception model as a flux [m/s]
    #soil_carac is the list of vectors of soil characteristics. Each vector has as the same size as the number of nodes.
    # PICmax : maximum number of Picard iteration
    # CRIT_CONV : convergence criteria.
    # Runoff='True' --> Runoff will be calculated instead of a pounding condition
    # -- model initialization
    # init vars
    start = time()  #estimate time of calculation
    ttmin=100.  #minimum time step
    tmin=ttmin   #minimum time step (variable)
    tmax=900.  #maximum time step
    dtss=tmax
    if tstep>T: #conditions to change the initial time step if necessary
        tstep=T
    if tstep>tmax:
        tstep=900.
    if tstep<tmin:
        tstep=tmin

    t=np.array(0)   #create t, just initial value
    tt=t    #create tt, where time value shoul be changed at each time step of the prescribed boundary conditions.
    #t = np.hstack((0,np.cumsum(dts))) # time array
    N = int(round(T/tmin)) # number of time steps
    I = int(round(L/dz)+1) # number of cells
    z = np.linspace(0,L,I) # z coordinates of nodes
    # check h_init
    if len(h_init) != I:
        print('ERROR: check dimension of h_init')
        return(0,0,0)
    # -- check input data
    # check bc : 
    if bc['top'][0] not in ['fixed_head','fixed_flow','free_drainage'] :
        print('ERROR: check top boundary condition')
    if bc['bot'][0] not in ['fixed_head','fixed_flow','free_drainage'] :
        print('ERROR: check bottom boundary condition')
    #create variables as vectors     #It should be notice that several variables are commented because they are only used for the mass balance.
    # RO = np.zeros((1))    #create vector RO, where runoff will be saved at each time step of the prescribed boundary conditions.
    # INF = np.zeros((1))   #create vector INF, where infiltration will be saved at each time step of the prescribed boundary conditions.
    # PER = np.zeros((1))   #create vector PER, where deep percolation will be saved at each time step of the prescribed boundary conditions.
    # TA = np.zeros((1))    #create vector TA, where actual transpiration will be saved at each time step of the prescribed boundary conditions.
    # VOL = np.zeros((1))   #create vector VOL, where soil water volume will be saved at each time step of the prescribed boundary conditions.
    
    # create matrix of variables
    # Theta = np.mat(np.zeros(shape=(I,1)))
    # Theta[:,0]=np.transpose(np.mat(theta0))
    # Ka = np.mat(np.zeros(shape=(I,1)))
    # K0 = get_K(h,soil_carac)
    # Ka[:,0]=np.transpose(np.mat(K0))
    # Flow = np.mat(np.zeros(shape=(I,1)))

    # -- run initization
    # initialize output matrices and variables
    S=np.mat(np.zeros(shape=(I,1)))
    # VOL[0] = (get_SUM(theta0,dz,I))*dz
    Ta=0.
    # Ro=0.
    # Infil=0.
    # Per=0.

     #include the time 0
    # Store initial condition
    S[:,0]= np.transpose(np.mat(h_init))
    h = h0 = h_init 
    h_list = []
  

# iterate over time
    dts=tstep   #dts: the time step at the current iteration, should change depending of the conditions
    dt=dts      #dt: maybe no longer necessary, not sure
    t=np.zeros([1]) #create vector t, where time will be saved at each iteration.
    tt=t
    www=1
    iterlast=0
    alert=0.
    alert2=0.
    for n in range(1,N):    #range 
        t=np.hstack((t,(t[-1]+dts)))    #add new time step to the vector t
        for w in range(www,len(bc['time'])):  #condition to estimate ww, so the bc used are in accordance to its time interval
            if t[-1]<=bc['time'][w]:
                ww=w-1
                www=w
                break
            else:
                ww=w
        #if t[-1]==bc['time'][ww] or t[-1]==T:   #with this conditions we make sure that at the current time we are using bc and q of the previous time interval
            #www=ww-1
        gl_val(dts) #make dt=dts, maybe no longer necessary, not sure
        BC=bc['top'][1][ww] #choose the appropriate bc at the time t
        theta0 = get_theta(h0,soil_carac)   #get theta0 before the picard iterations
        # Picard iteration 
        h00=h   #save the initial value of h if runoff occurs so the top bc could be changed        
        for m in range(PICmax):
            Iter=m  #save the number of iterations, used for the time optimization
            M , B = build_system(h0, h, theta0 , bc, BC, q, soil_carac, ww, bcff='False')   #first with prescribed bc
            # solver linear system
            h1 = np.transpose(np.matrix(cgs(csr_matrix(M),B)[0]))
            #h1 = inv(M)*B
            if Iter==(PICmax-1):
                alert=1.
            if np.max(abs(h1-h)) < CRIT_CONV:
                break
            h=h1
        if abs((h00[-1]-h1[-1])/min(abs(h1[-1]),abs(h00[-1])))>0.3:
            alert=1.
        if alert==1.:
            print('Interval:' + str(tt[-1]) + '     timestep:' + str(t[-1]) + 'dt:' + str(dts) + '    BC:' + str(BC) + '      htop:' + str(h00[-1]))
            dts=min(1.,dts)
            gl_val(dts)
            #tmin=1.
            t[-1]=t[-2]+dts
            www=www-1
            for w in range(www,len(bc['time'])):  #condition to estimate ww, so the bc used are in accordance to its time interval
                if t[-1]<=bc['time'][w]:
                    ww=w-1
                    www=w
                    break
                else:
                    ww=w
            h=h00
            for mmm in range((PICmax)):
                Iter=mmm
                M , B = build_system(h0, h, theta0 , bc, BC, q, soil_carac, ww, bcff='False')   #first with prescribed bc
                # solver linear system
                h1 = np.transpose(np.matrix(cgs(csr_matrix(M),B)[0]))
                #h1 = inv(M)*B
                if Iter==(PICmax-1):
                    alert2=1.    
                if np.max(abs(h1-h)) < CRIT_CONV:
                    break
                h=h1     
            if alert2==1.:
                print('Interval:' + str(tt[-1]) + '     timestep:' + str(t[-1]) + 'dt:' + str(dts) + '     BC:' + str(BC) + '      htop:' + str(h00[-1])+ 'h:' + str(h[-1]))
                print('valio paloma')
            iterlast=0.          
            h=h1
            alert=0.
            alert2=0.
        if Runoff=='True':  #If runoff should be estimated
            if h1[-1]> 0 :  #if the top node is equal or higher than 0, saturation conditions should be expected and runoff is activated
                #Include the Runoff Modification: these are optional conditions to maintain equilibrium on the solution, not always effective                      
                #dts=tmin
                #dt=dts                        
                h=h00   #in such case the last estimation of runoff is forgot
                print('Runoff modification')
                for mm in range (PICmax):   #and a new estimation starts
                    Iter=mm
                    M , B = build_system(h0, h, theta0 , bc, BC, q, soil_carac, ww, bcff='True')    #the changed bc is used
                    # solver linear system
                    h1 = np.transpose(np.matrix(cgs(csr_matrix(M),B)[0])) # see also cgs, csr, spsolve
                    if np.max(abs(h1-h)) < CRIT_CONV:   
                        #print( 'Runoff Modification PIC iteration ='+str(mm))
                        break
                    h=h1
        h=h1   
            
        #variables estimation    
        #theta = get_theta(h,soil_carac)
        # C     = get_C(h,soil_carac)
        #K     = get_K(h,soil_carac)
        #Kp    = get_Kp(K)
        #WU    = w_uptake(theta0, RD, q[ww], soil_carac, dz, -15.)
        #Ta    = get_SUM(WU,dz,I)*dts*dz+Ta
        #Flux  = get_flux(Kp,h,dz,theta,theta0,dts,WU)
        #Per = Flux[0]*dts+Per     #indirect estimation        
        # Per = ((-(soil_carac['Ksat'][1]*Kr_curve(h[1],soil_carac,1)+soil_carac['Ksat'][0]*Kr_curve(h[0],soil_carac,1))/2.)*((h[1]-h[0])/dz+1.)-dz/2.*((theta_curve(h[0],soil_carac,0)-theta0[0])/dts+WU[0]))*dts+Per    #direct estimation
        # if h[-1]>=0. or BC!=bc['top'][1][ww]:
        #     Infil = Flux[-1]*dts+Infil
        #     Ro = Ro+(bc['top'][1][ww]-Flux[-1])*dts
        # else:
        #     Infil = bc['top'][1][ww]*dts+Infil
        #     Ro=Ro+0

        if t[-1]==bc['time'][www] or t[-1]==T:   #check if time is at a time step of the bc, if yes, all variables estimation are saved for this time step 
            S = np.c_[S,np.zeros(I)]
            S[:,-1] = np.mat(h)
            tt = np.hstack((tt,bc['time'][www]))
            # Theta = np.c_[Theta,np.zeros(I)]
            # Theta[:,-1] = np.transpose(np.mat(theta))
            # Ka = np.c_[Ka,np.zeros(I)]
            # Ka[:,-1] = np.transpose(np.mat(K)) 
            # Flow = np.c_[Flow,np.zeros(I)]
            # Flow[:,-1] = np.transpose(np.mat(Flux))
            # TA = np.hstack((TA, Ta))
            # RO = np.hstack((RO, Ro))
            # INF = np.hstack((INF,Infil))
            #PER = np.hstack((PER, Per))
            # VOL = np.hstack((VOL, (get_SUM(theta,dz,I))*dz)) 
            #initial conditions to the next iteration
            # Ro=0.
            # Infil=0.
            #Per=0.
            # Ta=0. 


       ##Time optimization: 
            #it follows the methodology used in Hydrus
            #change the time step dts from tmin to bc timestep
            #time can be between bc prescribed intervals but it will always have to coincide with the intervals
            #some limitations were made in order to achieve equilibrium
        dts=max(1.,dts)
        tmin=min(dts,ttmin)
        if t[-1]==T:    #first check if time is the total time, in such case the calculation is over
            tt[-1] = T
            break
        h0 = h  #new h0 for next iteration
        if t[-1]==bc['time'][www]:   #check if time is equal to a bc time step
            if (BC-bc['top'][1][www])>0.:    #condition for large flux or large changes in bc
                if BC==0. and abs(bc['top'][1][www])>=3./(1000*15*60):
                    dts=min(dts,100.)
                    tmin=dts
                    iterlast=0.
                elif BC!=0. and abs((BC-bc['top'][1][www])/BC)>=10.:
                    dts=min(dts,100.)
                    tmin=dts
                    iterlast=0.
                else:                
                    if iterlast==1.:
                        dts=dtss
                        iterlast=0.
                        if dts>(tmax-tmin):
                            dts=tmax
                    else:
                        dts=dts 
            else:
                if iterlast==1.:
                    dts=dtss
                    iterlast=0.
                    if dts>(tmax-tmin):
                        dts=tmax
                else:
                    dts=dts
            dts=max(1.,dts)
        else:
            if t[-1]>bc['time'][(len(bc['time'])-1)]:   #this is the case of the bc time step before the total time T
                if Iter<=3:
                    dts=max(1.3*dts,tmin)
                    if (T-t[-1])<=(dts+tmin):
                        dtss=min(tmax,dts)
                        iterlast=1.
                elif Iter>3 and Iter<=7:
                    dts=dts
                    if (T-t[-1])<=(dts+tmin):
                        dts=max(tmin,(T-t[-1]))
                elif Iter>7 and Iter<PICmax:
                    dts=max(0.7*dts,tmin)
                    if (T-t[-1])<=(dts+tmin):
                        dts=max(tmin,(T-t[-1]))
                else:
                    dts=max(dts/3,tmin)
                    if (T-t[-1])<=(dts+tmin):
                        dts=max(tmin,(T-t[-1]))
            else:        #this is the case for any other time step
                if Iter<=3:    
                    dts=max(1.3*dts,tmin)

                    if (bc['time'][www]-t[-1])<=(dts+tmin):
                        dtss=min(tmax,dts)

                        if tmin>=ttmin:
                            dts=max(tmin,(bc['time'][www]-t[-1]))
                        else:
                            dts=(bc['time'][www]-t[-1])
                        iterlast=1.

                        if (dts+tmin)>(bc['time'][www]-t[-1]):
                            dts= (bc['time'][www]-t[-1])

                elif Iter>3 and Iter<=7:
                    dts=dts
                    if (bc['time'][www]-t[-1])<=(dts+tmin):
                        dts=max(tmin,(bc['time'][www]-t[-1]))
                        if (dts+tmin)>(bc['time'][www]-t[-1]):
                            dts= (bc['time'][www]-t[-1])

                elif Iter>7 and Iter<PICmax:
                    dts=max(0.7*dts,tmin)
                    if (bc['time'][www]-t[-1])<=(dts+tmin):
                        dts=max(tmin,(bc['time'][www]-t[-1]))
                        if (dts+tmin)>(bc['time'][www]-t[-1]):
                            dts= (bc['time'][www]-t[-1])
                else:
                    dts=max(dts/3,tmin)
                    if (bc['time'][www]-t[-1])<=(dts+tmin):
                        dts=max(tmin,(bc['time'][www]-t[-1]))
                        if (dts+tmin)>(bc['time'][www]-t[-1]):
                            dts= (bc['time'][www]-t[-1])
        #if t[-1]>=25269300 and t[-1]<=25271100:
        #    dts=1.
        #    tmin=1.
        #    iterlast=0   
        #if t[-1]>=25784100 and t[-1]<=25785900:
        #    dts=1.
        #    tmin=1.
        #    iterlast=0    
        if float(www)%96. ==0 and t[-1]==bc['time'][www]:  #uncomment if print daily values is wanted
            print('time:'+str(www/96)+'    iteration ' + str(n) + ' terminated.')
        #print('iteration ' + str(n) + ' terminated.')
    # return simulation results
    return(S)
Exemplo n.º 34
0
print '----'.rjust(6), '----------'.rjust(10), '----'.rjust(
    8), '-------'.rjust(8), '------'.rjust(8), '------'.rjust(
        8), '-----'.rjust(8), '-----'.rjust(8)
count = 1
diff = 1.
pi = 3.14159
Elast = 0.
const = 27.21
while abs(diff) > tol:
    E, psi = eigsh(-0.5 * L3 + spdiags(Vtot, 0, g3, g3), k=1, which='SA')
    #if count==2:
    #break
    psi = psi / h**(1.5)
    n = 2. * psi**(2.)
    Vx = -(3. / 3.14)**(1. / 3.) * n**(1. / 3.)
    Vh = cgs(L3, -4 * pi *
             (np.ravel(n) + ncomp), tol=1e-7, maxiter=400)[0] - ncomppot
    #break
    Vtot = np.ravel(Vx) + Vh + Vext
    T = 2. * sum(np.dot(np.ravel(psi), (-0.5 * L3) * psi)) * h**3
    Eext = np.dot(np.ravel(n), Vext) * h**3
    Eh = 0.5 * np.dot(np.ravel(n), Vh) * h**3
    Ex = sum(sum((-3. / 4.) * (3. / pi)**(1. / 3.) * n**(4. / 3.))) * h**3.
    Etot = T + Eext + Eh + Ex
    diff = Etot - Elast
    Elast = Etot
    print str(count).rjust(6), ('%.2f' % np.real(E[0] * const)).rjust(10), (
        '%.2f' % np.real(T * const)).rjust(8), ('%.2f' % np.real(
            Ex * const)).rjust(8), ('%.2f' % np.real(Eext * const)).rjust(8), (
                '%.2f' % np.real(Eh * const)).rjust(8), ('%.3f' % np.real(
                    Etot * const)).rjust(8), ('%.3f' %
                                              np.real(diff * const)).rjust(8)
Exemplo n.º 35
0
                row.append(str_num)
                col.append(ind(i, j))
                right[str_num] = y_0(i * dy)
            else:
                data.append(c / (dx**2))
                row.append(str_num)
                col.append(ind(i - 1, j))
                
                data.append(c / (dx**2))
                row.append(str_num)
                col.append(ind(i, j - 1))
                
                data.append(- 4.0*c/(dx**2) - 1.0/dt)
                row.append(str_num)
                col.append(ind(i, j))
                
                data.append(c / (dx**2))
                row.append(str_num)
                col.append(ind(i + 1, j))
                
                data.append(c / (dx**2))
                row.append(str_num)
                col.append(ind(i, j + 1))
                
                right[str_num] = - u_prev[ind(i, j)] / dt
    L = csr_matrix((np.array(data), (np.array(row), np.array(col))), shape=(matr_size, matr_size))
    u, info = cgs(L, right, x0 = u_prev, tol=1e-10)
    # print "residual: %le" % la.norm(np.dot(L, u) - right)
    # print "norm u + u_prev = %le" % la.norm(u - u_prev)
    u_prev = u
Exemplo n.º 36
0
PDE = poisson(geometry=geo, bc_dirichlet=bc_dirichlet, bc_neumann=bc_neumann,
              AllDirichlet=AllDirichlet, metric=Metric)
PDE.assembly()
PDE.solve()

# getting scipy matrix
A = PDE.system.get()

b = np.ones(PDE.size)

print "Using cg."
x = cg(A, b, tol=tol, maxiter=maxiter)

print "Using cgs."
x = cgs(A, b, tol=tol, maxiter=maxiter)

print "Using bicg."
x = bicg(A, b, tol=tol, maxiter=maxiter)

print "Using bicgstab."
x = bicgstab(A, b, tol=tol, maxiter=maxiter)

print "Using gmres."
x = gmres(A, b, tol=tol, maxiter=maxiter)

print "Using splu."
op = splu(A.tocsc())
x = op.solve(b)

PDE.free()
Exemplo n.º 37
0
                  bc_neumann=bc_neumann,
                  AllDirichlet=AllDirichlet,
                  metric=Metric)
    PDE.assembly()
    PDE.solve()

    # getting scipy matrix
    A = PDE.system.get()

    b = np.ones(PDE.size)

    print("Using cg.")
    x = cg(A, b, tol=tol, maxiter=maxiter)

    print("Using cgs.")
    x = cgs(A, b, tol=tol, maxiter=maxiter)

    print("Using bicg.")
    x = bicg(A, b, tol=tol, maxiter=maxiter)

    print("Using bicgstab.")
    x = bicgstab(A, b, tol=tol, maxiter=maxiter)

    print("Using gmres.")
    x = gmres(A, b, tol=tol, maxiter=maxiter)

    print("Using splu.")
    op = splu(A.tocsc())
    x = op.solve(b)

    PDE.free()
Exemplo n.º 38
0
def uncompress(ctod, C, factor):
    uctod = tm.Tod(np.zeros((ctod.shape[0], ctod.shape[1] * factor)))
    y0, t = spl.cgs(C.T * C, C.T * ctod.flatten())
    uctod[:] = y0.reshape(uctod.shape)
    return uctod
Exemplo n.º 39
0
    def solve_linear_system(self,animate=False):
        x0=self.initial_guess()

        if animate:
            plt.figure(1)
            plt.clf()
            for c,v,xy in self.dirichlet_bcs:
                plt.annotate( str(v), xy )
            coll = self.grid.plot_cells(values=self.expand(x0))
            coll.set_lw(0)
            coll.set_clim([0,1])
            plt.axis('equal')
            plt.pause(0.01)

        ctr=itertools.count()
        def plot_progress(xk):
            count=next(ctr)
            log.debug("Count: %d"%count)
            if animate and count%1000==0:
                coll.set_array(self.expand(xk))
                plt.title(str(count))
                plt.pause(0.01)

        # I think that cgs means the matrix doesn't have to be
        # symmetric, which makes boundary conditions easier
        # with only showing progress every 100 steps,
        # this takes maybe a minute on a 28k cell grid.
        # But cgs seems to have more convergence problems with
        # pure diffusion.

        if animate:
            coll.set_clim([0,1])

        maxiter=int(1.5*self.grid.Ncells())
        code = -1
        if 1:
            C_solved=linalg.spsolve(self.A.tocsr(),self.b)
            code=0
        elif 1:
            C_solved,code = linalg.cgs(self.A,self.b,x0=x0,
                                       callback=plot_progress,
                                       tol=self.solve_tol,
                                       maxiter=maxiter)
        elif 0:
            C_solved,code = linalg.cg(self.A,self.b,x0=x0,
                                      callback=plot_progress,
                                      tol=self.tol,
                                      maxiter=maxiter)
        elif 1:
            C_solved,code = linalg.bicgstab(self.A,self.b,x0=x0,
                                            callback=plot_progress,
                                            tol=self.solve_tol,
                                            maxiter=maxiter)
        elif 1:
            log.debug("Time integration")
            x = x0
            for i in range(maxiter):
                x = A.dot(x)
                plot_progress(x)
        else:
            def print_progress(rk):
                count=next(ctr)
                if count%1000==0:
                    log.debug("count=%d rk=%s"%(count,rk))
            C_solved,code = linalg.gmres(self.A,self.b,x0=x0,tol=self.solve_tol,callback=print_progress)

        self.C_solved=self.expand(C_solved)
        for c,v,xy in self.dirichlet_bcs:
            self.C_solved[c]=v

        self.code = code

        if animate:
            evenly_spaced=np.zeros(len(C_solved))
            evenly_spaced[np.argsort(C_solved)] = np.arange(len(C_solved))
            coll.set_array(evenly_spaced)
            coll.set_clim([0,self.grid.Ncells()])
            plt.draw()
def runFastSinkSource(P,
                      positives,
                      negatives=None,
                      max_iters=1000,
                      eps=0.0001,
                      a=0.8,
                      tol=1e-5,
                      solver=None,
                      Milu=None,
                      verbose=False):
    """
    *P*: Network ags a scipy sparse matrix. Should already be normalized
    *positives*: numpy array of node ids to be used as positives
    *negatives*: numpy array of node ids to be used as negatives. 
        If not given, will be run as FastSinkSourcePlus. 
        For FastSinkSourcePlus, if the lambda parameter is desired, it should already have been included in the graph normalization process. 
        See the function normalizeGraphEdgeWeights in alg_utils.py 
    *max_iters*: max # of iterations to run SinkSource. 
        If 0, use spsolve to solve the equation directly 
    """
    num_nodes = P.shape[0]
    if len(positives) == 0:
        print("WARNING: No positive examples given. Skipping.")
        return np.zeros(num_nodes), 0, 0, 0
    # remove the positive and negative nodes from the graph
    # and setup the f vector which contains the influence from positive and negative nodes
    newP, f, = alg_utils.setup_fixed_scores(P,
                                            positives,
                                            negatives,
                                            a=a,
                                            remove_nonreachable=False)

    if solver is None:
        s, process_time, wall_time, num_iters = FastSinkSource(
            newP, f, max_iters=max_iters, eps=eps, a=a, verbose=verbose)
    else:
        # Solve for s directly. Scipy uses the form Ax=b to solve for x
        # SinkSource equation: (I - aP)s = f
        #solvers = ['bicg', 'bicgstab', 'cg', 'cgs', 'gmres', 'lgmres', 'minres', 'qmr', 'gcrotmk']#, 'lsmr']
        # eye is the identity matrix
        #M = eye(P.shape[0]) - a*P
        M = eye(newP.shape[0]) - a * newP

        # keep track of the number of iterations
        def callback(xk):
            # keep the reference to the variable within the callback function (Python 3)
            nonlocal num_iters
            num_iters += 1

        # this measures the amount of time taken by all processors
        start_process_time = time.process_time()
        # this measures the amount of time that has passed
        start_wall_time = time.time()
        num_iters = 0
        # spsolve basically stalls for large or dense networks (e.g., e-value cutoff 0.1)
        if solver == 'spsolve':
            s = linalg.spsolve(M, f)
        elif solver == 'bicg':
            s, info = linalg.bicg(M,
                                  f,
                                  tol=tol,
                                  maxiter=max_iters,
                                  M=Milu,
                                  callback=callback)
        elif solver == 'bicgstab':
            s, info = linalg.bicgstab(M,
                                      f,
                                      tol=tol,
                                      maxiter=max_iters,
                                      M=Milu,
                                      callback=callback)
        elif solver == 'cg':
            s, info = linalg.cg(M,
                                f,
                                tol=tol,
                                maxiter=max_iters,
                                M=Milu,
                                callback=callback)
        elif solver == 'cgs':
            s, info = linalg.cgs(M,
                                 f,
                                 tol=tol,
                                 maxiter=max_iters,
                                 M=Milu,
                                 callback=callback)
        elif solver == 'gmres':
            s, info = linalg.gmres(M,
                                   f,
                                   tol=tol,
                                   maxiter=max_iters,
                                   M=Milu,
                                   callback=callback)
        elif solver == 'lgmres':
            s, info = linalg.lgmres(M,
                                    f,
                                    tol=tol,
                                    maxiter=max_iters,
                                    M=Milu,
                                    callback=callback)
        elif solver == 'minres':
            s, info = linalg.minres(M,
                                    f,
                                    tol=tol,
                                    maxiter=max_iters,
                                    M=Milu,
                                    callback=callback)
        elif solver == 'qmr':
            s, info = linalg.qmr(M,
                                 f,
                                 tol=tol,
                                 maxiter=max_iters,
                                 M=Milu,
                                 callback=callback)
        elif solver == 'gcrotmk':
            s, info = linalg.gcrotmk(M,
                                     f,
                                     tol=tol,
                                     maxiter=max_iters,
                                     M=Milu,
                                     callback=callback)
        #elif solver == 'lsmr':
        #    s, info = linalg.lsmr(M, f, maxiter=max_iters, callback=callback)

        process_time = time.process_time() - start_process_time
        wall_time = time.time() - start_wall_time
        if verbose:
            print("Solved SS using %s (%0.3f sec, %0.3f process time). %s" %
                  (solver, wall_time, process_time,
                   "iters: %d, max_iters: %d, info: %s" %
                   (num_iters, 1000, info) if solver != 'spsolve' else ''))

    # keep the positive examples at 1
    s[positives] = 1

    return s, process_time, wall_time, num_iters
Exemplo n.º 41
0
    time_gj -= time.perf_counter()
    time_gj = abs(time_gj)
    fl_gj.darcyv(case_mesh, pm1)

    # Conjugate Gradient
    fl_cg = dc.fluid(case_mesh, case_current.fl)
    time_cg = time.perf_counter()
    fl_cg.p, info_cg = SLA.cg(A, b, tol=1.0E-9)
    time_cg -= time.perf_counter()
    time_cg = abs(time_cg)
    fl_cg.darcyv(case_mesh, pm1)

    # Conjugate Gradient Squared
    fl_cgs = dc.fluid(case_mesh, case_current.fl)
    time_cgs = time.perf_counter()
    fl_cgs.p, info_cg = SLA.cgs(A, b, tol=1.0E-9)
    time_cgs -= time.perf_counter()
    time_cgs = abs(time_cgs)
    fl_cgs.darcyv(case_mesh, pm1)

    # Cholesky Factorization
    fl_cho = dc.fluid(case_mesh, case_current.fl)
    time_cho = time.perf_counter()
    c_cho, low = cho_factor(A)
    fl_cho.p = cho_solve((c_cho, low), b)
    time_cho -= time.perf_counter()
    time_cho = abs(time_cho)
    fl_cho.darcyv(case_mesh, pm1)

    # Output
Exemplo n.º 42
0
def run_varsat(L,
               T,
               dz,
               tstep,
               h_init,
               bc,
               q,
               soil_carac,
               PICmax=20,
               CRIT_CONV=1.e-2,
               Runoff='True'):
    # L : column length
    # T : simulation duration
    # dz : vertical discretization
    # tstep : initial time step
    # h_init : initial profile of pressure head, must be of size I = int(round(L/dz))
    # bc : dictionary of boundary conditions : e.g. {'top':['fixed_head',[h_top]*N],'bot':['fixed_head',[h_bot]*N]}
    #      allowed bc at the top : 'fixed_head','fixed_flow',
    #      allowed bc at the bottom : 'fixed_head','fixed_flow','free_drainage'
    # q : source term. in our case is the potential transpiration estimated from the interception model as a flux [m/s]
    #soil_carac is the list of vectors of soil characteristics. Each vector has as the same size as the number of nodes.
    # PICmax : maximum number of Picard iteration
    # CRIT_CONV : convergence criteria.
    # Runoff='True' --> Runoff will be calculated instead of a pounding condition
    # -- model initialization
    # init vars
    start = time()  #estimate time of calculation
    ttmin = 100.  #minimum time step
    tmin = ttmin  #minimum time step (variable)
    tmax = 900.  #maximum time step
    dtss = tmax
    if tstep > T:  #conditions to change the initial time step if necessary
        tstep = T
    if tstep > tmax:
        tstep = 900.
    if tstep < tmin:
        tstep = tmin

    t = np.array(0)  #create t, just initial value
    tt = t  #create tt, where time value shoul be changed at each time step of the prescribed boundary conditions.
    #t = np.hstack((0,np.cumsum(dts))) # time array
    N = int(round(T / tmin))  # number of time steps
    I = int(round(L / dz) + 1)  # number of cells
    z = np.linspace(0, L, I)  # z coordinates of nodes
    # check h_init
    if len(h_init) != I:
        print('ERROR: check dimension of h_init')
        return (0, 0, 0)
    # -- check input data
    # check bc :
    if bc['top'][0] not in ['fixed_head', 'fixed_flow', 'free_drainage']:
        print('ERROR: check top boundary condition')
    if bc['bot'][0] not in ['fixed_head', 'fixed_flow', 'free_drainage']:
        print('ERROR: check bottom boundary condition')
    #create variables as vectors     #It should be notice that several variables are commented because they are only used for the mass balance.
    # RO = np.zeros((1))    #create vector RO, where runoff will be saved at each time step of the prescribed boundary conditions.
    # INF = np.zeros((1))   #create vector INF, where infiltration will be saved at each time step of the prescribed boundary conditions.
    # PER = np.zeros((1))   #create vector PER, where deep percolation will be saved at each time step of the prescribed boundary conditions.
    # TA = np.zeros((1))    #create vector TA, where actual transpiration will be saved at each time step of the prescribed boundary conditions.
    # VOL = np.zeros((1))   #create vector VOL, where soil water volume will be saved at each time step of the prescribed boundary conditions.

    # create matrix of variables
    # Theta = np.mat(np.zeros(shape=(I,1)))
    # Theta[:,0]=np.transpose(np.mat(theta0))
    # Ka = np.mat(np.zeros(shape=(I,1)))
    # K0 = get_K(h,soil_carac)
    # Ka[:,0]=np.transpose(np.mat(K0))
    # Flow = np.mat(np.zeros(shape=(I,1)))

    # -- run initization
    # initialize output matrices and variables
    S = np.mat(np.zeros(shape=(I, 1)))
    # VOL[0] = (get_SUM(theta0,dz,I))*dz
    Ta = 0.
    # Ro=0.
    # Infil=0.
    # Per=0.

    #include the time 0
    # Store initial condition
    S[:, 0] = np.transpose(np.mat(h_init))
    h = h0 = h_init
    h_list = []

    # iterate over time
    dts = tstep  #dts: the time step at the current iteration, should change depending of the conditions
    dt = dts  #dt: maybe no longer necessary, not sure
    t = np.zeros(
        [1])  #create vector t, where time will be saved at each iteration.
    tt = t
    www = 1
    iterlast = 0
    alert = 0.
    alert2 = 0.
    for n in range(1, N):  #range
        t = np.hstack((t, (t[-1] + dts)))  #add new time step to the vector t
        for w in range(
                www, len(bc['time'])
        ):  #condition to estimate ww, so the bc used are in accordance to its time interval
            if t[-1] <= bc['time'][w]:
                ww = w - 1
                www = w
                break
            else:
                ww = w
        #if t[-1]==bc['time'][ww] or t[-1]==T:   #with this conditions we make sure that at the current time we are using bc and q of the previous time interval
        #www=ww-1
        gl_val(dts)  #make dt=dts, maybe no longer necessary, not sure
        BC = bc['top'][1][ww]  #choose the appropriate bc at the time t
        theta0 = get_theta(
            h0, soil_carac)  #get theta0 before the picard iterations
        # Picard iteration
        h00 = h  #save the initial value of h if runoff occurs so the top bc could be changed
        for m in range(PICmax):
            Iter = m  #save the number of iterations, used for the time optimization
            M, B = build_system(h0,
                                h,
                                theta0,
                                bc,
                                BC,
                                q,
                                soil_carac,
                                ww,
                                bcff='False')  #first with prescribed bc
            # solver linear system
            h1 = np.transpose(np.matrix(cgs(csr_matrix(M), B)[0]))
            #h1 = inv(M)*B
            if Iter == (PICmax - 1):
                alert = 1.
            if np.max(abs(h1 - h)) < CRIT_CONV:
                break
            h = h1
        if abs((h00[-1] - h1[-1]) / min(abs(h1[-1]), abs(h00[-1]))) > 0.3:
            alert = 1.
        if alert == 1.:
            print('Interval:' + str(tt[-1]) + '     timestep:' + str(t[-1]) +
                  'dt:' + str(dts) + '    BC:' + str(BC) + '      htop:' +
                  str(h00[-1]))
            dts = min(1., dts)
            gl_val(dts)
            #tmin=1.
            t[-1] = t[-2] + dts
            www = www - 1
            for w in range(
                    www, len(bc['time'])
            ):  #condition to estimate ww, so the bc used are in accordance to its time interval
                if t[-1] <= bc['time'][w]:
                    ww = w - 1
                    www = w
                    break
                else:
                    ww = w
            h = h00
            for mmm in range((PICmax)):
                Iter = mmm
                M, B = build_system(h0,
                                    h,
                                    theta0,
                                    bc,
                                    BC,
                                    q,
                                    soil_carac,
                                    ww,
                                    bcff='False')  #first with prescribed bc
                # solver linear system
                h1 = np.transpose(np.matrix(cgs(csr_matrix(M), B)[0]))
                #h1 = inv(M)*B
                if Iter == (PICmax - 1):
                    alert2 = 1.
                if np.max(abs(h1 - h)) < CRIT_CONV:
                    break
                h = h1
            if alert2 == 1.:
                print('Interval:' + str(tt[-1]) + '     timestep:' +
                      str(t[-1]) + 'dt:' + str(dts) + '     BC:' + str(BC) +
                      '      htop:' + str(h00[-1]) + 'h:' + str(h[-1]))
                print('valio paloma')
            iterlast = 0.
            h = h1
            alert = 0.
            alert2 = 0.
        if Runoff == 'True':  #If runoff should be estimated
            if h1[-1] > 0:  #if the top node is equal or higher than 0, saturation conditions should be expected and runoff is activated
                #Include the Runoff Modification: these are optional conditions to maintain equilibrium on the solution, not always effective
                #dts=tmin
                #dt=dts
                h = h00  #in such case the last estimation of runoff is forgot
                print('Runoff modification')
                for mm in range(PICmax):  #and a new estimation starts
                    Iter = mm
                    M, B = build_system(h0,
                                        h,
                                        theta0,
                                        bc,
                                        BC,
                                        q,
                                        soil_carac,
                                        ww,
                                        bcff='True')  #the changed bc is used
                    # solver linear system
                    h1 = np.transpose(np.matrix(cgs(
                        csr_matrix(M), B)[0]))  # see also cgs, csr, spsolve
                    if np.max(abs(h1 - h)) < CRIT_CONV:
                        #print( 'Runoff Modification PIC iteration ='+str(mm))
                        break
                    h = h1
        h = h1

        #variables estimation
        #theta = get_theta(h,soil_carac)
        # C     = get_C(h,soil_carac)
        #K     = get_K(h,soil_carac)
        #Kp    = get_Kp(K)
        #WU    = w_uptake(theta0, RD, q[ww], soil_carac, dz, -15.)
        #Ta    = get_SUM(WU,dz,I)*dts*dz+Ta
        #Flux  = get_flux(Kp,h,dz,theta,theta0,dts,WU)
        #Per = Flux[0]*dts+Per     #indirect estimation
        # Per = ((-(soil_carac['Ksat'][1]*Kr_curve(h[1],soil_carac,1)+soil_carac['Ksat'][0]*Kr_curve(h[0],soil_carac,1))/2.)*((h[1]-h[0])/dz+1.)-dz/2.*((theta_curve(h[0],soil_carac,0)-theta0[0])/dts+WU[0]))*dts+Per    #direct estimation
        # if h[-1]>=0. or BC!=bc['top'][1][ww]:
        #     Infil = Flux[-1]*dts+Infil
        #     Ro = Ro+(bc['top'][1][ww]-Flux[-1])*dts
        # else:
        #     Infil = bc['top'][1][ww]*dts+Infil
        #     Ro=Ro+0

        if t[-1] == bc['time'][www] or t[
                -1] == T:  #check if time is at a time step of the bc, if yes, all variables estimation are saved for this time step
            S = np.c_[S, np.zeros(I)]
            S[:, -1] = np.mat(h)
            tt = np.hstack((tt, bc['time'][www]))
            # Theta = np.c_[Theta,np.zeros(I)]
            # Theta[:,-1] = np.transpose(np.mat(theta))
            # Ka = np.c_[Ka,np.zeros(I)]
            # Ka[:,-1] = np.transpose(np.mat(K))
            # Flow = np.c_[Flow,np.zeros(I)]
            # Flow[:,-1] = np.transpose(np.mat(Flux))
            # TA = np.hstack((TA, Ta))
            # RO = np.hstack((RO, Ro))
            # INF = np.hstack((INF,Infil))
            #PER = np.hstack((PER, Per))
            # VOL = np.hstack((VOL, (get_SUM(theta,dz,I))*dz))
            #initial conditions to the next iteration
            # Ro=0.
            # Infil=0.
            #Per=0.
            # Ta=0.

    ##Time optimization:
    #it follows the methodology used in Hydrus
    #change the time step dts from tmin to bc timestep
    #time can be between bc prescribed intervals but it will always have to coincide with the intervals
    #some limitations were made in order to achieve equilibrium
        dts = max(1., dts)
        tmin = min(dts, ttmin)
        if t[-1] == T:  #first check if time is the total time, in such case the calculation is over
            tt[-1] = T
            break
        h0 = h  #new h0 for next iteration
        if t[-1] == bc['time'][www]:  #check if time is equal to a bc time step
            if (BC - bc['top'][1][www]
                ) > 0.:  #condition for large flux or large changes in bc
                if BC == 0. and abs(
                        bc['top'][1][www]) >= 3. / (1000 * 15 * 60):
                    dts = min(dts, 100.)
                    tmin = dts
                    iterlast = 0.
                elif BC != 0. and abs((BC - bc['top'][1][www]) / BC) >= 10.:
                    dts = min(dts, 100.)
                    tmin = dts
                    iterlast = 0.
                else:
                    if iterlast == 1.:
                        dts = dtss
                        iterlast = 0.
                        if dts > (tmax - tmin):
                            dts = tmax
                    else:
                        dts = dts
            else:
                if iterlast == 1.:
                    dts = dtss
                    iterlast = 0.
                    if dts > (tmax - tmin):
                        dts = tmax
                else:
                    dts = dts
            dts = max(1., dts)
        else:
            if t[-1] > bc['time'][(
                    len(bc['time']) - 1
            )]:  #this is the case of the bc time step before the total time T
                if Iter <= 3:
                    dts = max(1.3 * dts, tmin)
                    if (T - t[-1]) <= (dts + tmin):
                        dtss = min(tmax, dts)
                        iterlast = 1.
                elif Iter > 3 and Iter <= 7:
                    dts = dts
                    if (T - t[-1]) <= (dts + tmin):
                        dts = max(tmin, (T - t[-1]))
                elif Iter > 7 and Iter < PICmax:
                    dts = max(0.7 * dts, tmin)
                    if (T - t[-1]) <= (dts + tmin):
                        dts = max(tmin, (T - t[-1]))
                else:
                    dts = max(dts / 3, tmin)
                    if (T - t[-1]) <= (dts + tmin):
                        dts = max(tmin, (T - t[-1]))
            else:  #this is the case for any other time step
                if Iter <= 3:
                    dts = max(1.3 * dts, tmin)

                    if (bc['time'][www] - t[-1]) <= (dts + tmin):
                        dtss = min(tmax, dts)

                        if tmin >= ttmin:
                            dts = max(tmin, (bc['time'][www] - t[-1]))
                        else:
                            dts = (bc['time'][www] - t[-1])
                        iterlast = 1.

                        if (dts + tmin) > (bc['time'][www] - t[-1]):
                            dts = (bc['time'][www] - t[-1])

                elif Iter > 3 and Iter <= 7:
                    dts = dts
                    if (bc['time'][www] - t[-1]) <= (dts + tmin):
                        dts = max(tmin, (bc['time'][www] - t[-1]))
                        if (dts + tmin) > (bc['time'][www] - t[-1]):
                            dts = (bc['time'][www] - t[-1])

                elif Iter > 7 and Iter < PICmax:
                    dts = max(0.7 * dts, tmin)
                    if (bc['time'][www] - t[-1]) <= (dts + tmin):
                        dts = max(tmin, (bc['time'][www] - t[-1]))
                        if (dts + tmin) > (bc['time'][www] - t[-1]):
                            dts = (bc['time'][www] - t[-1])
                else:
                    dts = max(dts / 3, tmin)
                    if (bc['time'][www] - t[-1]) <= (dts + tmin):
                        dts = max(tmin, (bc['time'][www] - t[-1]))
                        if (dts + tmin) > (bc['time'][www] - t[-1]):
                            dts = (bc['time'][www] - t[-1])
        #if t[-1]>=25269300 and t[-1]<=25271100:
        #    dts=1.
        #    tmin=1.
        #    iterlast=0
        #if t[-1]>=25784100 and t[-1]<=25785900:
        #    dts=1.
        #    tmin=1.
        #    iterlast=0
        if float(www) % 96. == 0 and t[-1] == bc['time'][
                www]:  #uncomment if print daily values is wanted
            print('time:' + str(www / 96) + '    iteration ' + str(n) +
                  ' terminated.')
        #print('iteration ' + str(n) + ' terminated.')
    # return simulation results
    return (S)
Exemplo n.º 43
0
			phi1 = spla.solve(CayleyP,CayleyN.dot(phi0))
			mu = math.sqrt(phi1.dot(phi1))
			phi1 = phi1/mu  
			err = math.sqrt(2)*math.sqrt(abs(phi1.dot(int_H.dot(int_H)).dot(phi1)- (phi1.dot(int_H).dot(phi1))**2))
			phi0 = phi1
	elapsed_scipysolver = (time.clock() - start)
	
	
	# Conjugate Gradient Squared
	err = 1
	start = time.clock()
	phi0 = np.random.rand(n)
	CayleyN = (np.identity(n)-0.5*int_H)
	CayleyP = (np.identity(n)+0.5*int_H)
	while(err > eps):
			phi1 = spsla.cgs(CayleyP,CayleyN.dot(phi0))
			phi1=phi1[0]
			mu = math.sqrt(phi1.dot(phi1))
			phi1 = phi1/mu  
			err = math.sqrt(2)*math.sqrt(abs(phi1.dot(int_H.dot(int_H)).dot(phi1)- (phi1.dot(int_H).dot(phi1))**2))
			phi0 = phi1
	elapsed_cgs = (time.clock() - start)
	
	# Cholesky Factorization
	err = 1
	phi0 = np.random.rand(n)
	CayleyN = (np.identity(n)-0.5*int_H)
	CayleyP = (np.identity(n)+0.5*int_H)
	cho = spla.cho_factor(CayleyP)
	while(err > eps):
			phi1 = spla.cho_solve(cho, CayleyN.dot(phi0))