Example #1
0
    def _solve_(self, L, x, b):
        diag = L.takeDiagonal()
        maxdiag = max(numerix.absolute(diag))

        L = L * (1 / maxdiag)
        b = b * (1 / maxdiag)

        LU = superlu.factorize(L.matrix.to_csr())

        if DEBUG:
            import sys
            print(L.matrix, file=sys.stderr)

        error0 = numerix.sqrt(numerix.sum((L * x - b)**2))

        for iteration in range(self.iterations):
            errorVector = L * x - b

            if (numerix.sqrt(numerix.sum(errorVector**2)) / error0)  <= self.tolerance:
                break

            xError = numerix.zeros(len(b), 'd')
            LU.solve(errorVector, xError)
            x[:] = x - xError

        if 'FIPY_VERBOSE_SOLVER' in os.environ:
            from fipy.tools.debug import PRINT
            PRINT('iterations: %d / %d' % (iteration+1, self.iterations))
            PRINT('residual:', numerix.sqrt(numerix.sum(errorVector**2)))
Example #2
0
    def _solve_(self, L, x, b):
        diag = L.takeDiagonal()
        maxdiag = max(numerix.absolute(diag))

        L = L * (1 / maxdiag)
        b = b * (1 / maxdiag)

        LU = superlu.factorize(L.matrix.to_csr())

        if DEBUG:
            import sys
            print >> sys.stderr, L.matrix

        error0 = numerix.sqrt(numerix.sum((L * x - b)**2))

        for iteration in range(self.iterations):
            errorVector = L * x - b

            if (numerix.sqrt(numerix.sum(errorVector**2)) / error0)  <= self.tolerance:
                break

            xError = numerix.zeros(len(b),'d')
            LU.solve(errorVector, xError)
            x[:] = x - xError
            
        if 'FIPY_VERBOSE_SOLVER' in os.environ:
            from fipy.tools.debug import PRINT        
            PRINT('iterations: %d / %d' % (iteration+1, self.iterations))
            PRINT('residual:', numerix.sqrt(numerix.sum(errorVector**2)))
Example #3
0
    def fea(self):
        """
        Performs a Finite Element Analysis given the updated global stiffness
        matrix [K] and the load vector {r}, both of which must be in the
        modified state, i.e., [K] and {r} must represent the unconstrained
        system of equations. Return the global displacement vector {d} as a
        NumPy array.

        EXAMPLES:
            >>> t.fea()

        See also: set_top_params

        """
        if not self.topydict:
            raise Exception('You must first load a TPD file!')
        if self.itercount >= MAX_ITERS:
            raise Exception('Maximum internal number of iterations exceeded!')

        Kfree = self._updateK(self.K.copy())

        if self.dofpn < 3 and self.nelz == 0:  # Direct solver
            Kfree = Kfree.to_csr()  # Need CSR for SuperLU factorisation
            lu = superlu.factorize(Kfree)
            lu.solve(self.rfree, self.dfree)
            if self.probtype == 'mech':
                lu.solve(self.rfreeout, self.dfreeout)  # mechanism synthesis
        else:  # Iterative solver for 3D problems
            Kfree = Kfree.to_sss()
            preK = precon.ssor(Kfree)  # Preconditioned Kfree
            (info, numitr, relerr) = itsolvers.pcg(Kfree, self.rfree,
                                                   self.dfree, 1e-8, 8000,
                                                   preK)
            if info < 0:
                logger.error('PySparse error: Type: {}, '
                             'at {} iterations'.format(info, numitr))
                raise Exception('Solution for FEA did not converge.')
            else:
                logger.debug('ToPy: Solution for FEA converged after '
                             '{} iterations'.format(numitr))
            if self.probtype == 'mech':  # mechanism synthesis
                (info, numitr, relerr) = itsolvers.pcg(Kfree, self.rfreeout,
                                                       self.dfreeout, 1e-8,
                                                       8000, preK)
                if info < 0:
                    logger.error('PySparse error: Type: {}, '
                                 'at {} iterations'.format(info, numitr))
                    raise Exception('Solution for FEA of adjoint load '
                                    'case did not converge.')

        # Update displacement vectors:
        self.d[self.freedof] = self.dfree
        if self.probtype == 'mech':  # 'adjoint' vectors
            self.dout[self.freedof] = self.dfreeout
        # Increment internal iteration counter
        self.itercount += 1
Example #4
0
    def fea(self):
        """
        Performs a Finite Element Analysis given the updated global stiffness
        matrix [K] and the load vector {r}, both of which must be in the
        modified state, i.e., [K] and {r} must represent the unconstrained
        system of equations. Return the global displacement vector {d} as a
        NumPy array.

        EXAMPLES:
            >>> t.fea()

        See also: set_top_params

        """
        if not self.topydict:
            raise ToPyError('You must first load a TPD file!')
        if self.itercount >= MAX_ITERS:
            raise ToPyError('Maximum internal number of iterations exceeded!')

        Kfree = self._updateK(self.K.copy())

        if self.dofpn < 3 and self.nelz == 0: #  Direct solver
            Kfree = Kfree.to_csr() #  Need CSR for SuperLU factorisation
            lu = superlu.factorize(Kfree)
            lu.solve(self.rfree, self.dfree)
            if self.probtype == 'mech':
                lu.solve(self.rfreeout, self.dfreeout)  # mechanism synthesis
        else: #  Iterative solver for 3D problems
            Kfree = Kfree.to_sss()
            preK = precon.ssor(Kfree) #  Preconditioned Kfree
            (info, numitr, relerr) = \
            itsolvers.pcg(Kfree, self.rfree, self.dfree, 1e-8, 8000, preK)
            if info < 0:
                print 'PySparse error: Type:', info,', at', numitr, \
'iterations.'
                raise ToPyError('Solution for FEA did not converge.')
            else:
                print 'ToPy: Solution for FEA converged after', numitr, \
'iterations.'
            if self.probtype == 'mech':  # mechanism synthesis
                (info, numitr, relerr) = \
                itsolvers.pcg(Kfree, self.rfreeout, self.dfreeout, 1e-8, \
                8000, preK)
                if info < 0:
                    print 'PySparse error: Type:', info,', at', numitr, \
'iterations.'
                    raise ToPyError('Solution for FEA of adjoint load case \
                    did not converge.')

        # Update displacement vectors:
        self.d[self.freedof] = self.dfree
        if self.probtype == 'mech':  # 'adjoint' vectors
            self.dout[self.freedof] = self.dfreeout
        # Increment internal iteration counter
        self.itercount += 1
Example #5
0
    def __init__(self, A, **kwargs):
        PysparseDirectSolver.__init__(self, A, **kwargs)

        self.type = numpy.float
        self.nrow, self.ncol = A.getShape()
        t = cputime()
        self.LU = superlu.factorize(A.matrix.to_csr(), **kwargs)
        self.factorizationTime = cputime() - t
        self.solutionTime = 0.0
        self.sol = None
        self.L = self.U = None
        return
Example #6
0
    def testTrivial(self):
        luA = superlu.factorize(self.A)
        luA.solve(self.b, self.x)
        self.failUnless(residual(self.A, self.x, self.b) == 0.0)

        luA = superlu.factorize(self.A, diag_pivot_thresh=0.0)
        luA.solve(self.b, self.x)
        self.failUnless(residual(self.A, self.x, self.b) == 0.0)

        luA = superlu.factorize(self.A, relax=20)
        luA.solve(self.b, self.x)
        self.failUnless(residual(self.A, self.x, self.b) == 0.0)

        luA = superlu.factorize(self.A, panel_size=1)
        luA.solve(self.b, self.x)
        self.failUnless(residual(self.A, self.x, self.b) == 0.0)

        for permc_spec in [0, 1, 2, 3]:
            luA = superlu.factorize(self.A, permc_spec=permc_spec)
            luA.solve(self.b, self.x)
            self.failUnless(residual(self.A, self.x, self.b) == 0.0)
Example #7
0
    def staticSolver(self):
        self.solution = np.zeros((self.dofcount, ), dtype=float)
        forces = self.nodalforces

        if SOLVER == 'default':
            spooles = solver.Spooles(self.GK)
            self.solution[:] = forces
            spooles.solve(self.solution)

        elif SOLVER == 'pysparse':
            mat = self.GK.to_csr()
            LU = superlu.factorize(mat, permc_spec=2, diag_pivot_thresh=0.)
            LU.solve(forces, self.solution)

        else:
            raise FEError('unknown solver')
Example #8
0
File: base.py Project: tenko/feapy
    def staticSolver(self):
        self.solution = np.zeros((self.dofcount,), dtype=float)
        forces = self.nodalforces
        
        if SOLVER == 'default':
            spooles = solver.Spooles(self.GK)
            self.solution[:] = forces
            spooles.solve(self.solution)

        elif SOLVER == 'pysparse':
            mat = self.GK.to_csr()
            LU = superlu.factorize(mat, permc_spec=2, diag_pivot_thresh=0.)
            LU.solve(forces, self.solution)
        
        else:
            raise FEError('unknown solver')
Example #9
0
    def _solve_(self, L, x, b):
        diag = L.takeDiagonal()
        maxdiag = max(numerix.absolute(diag))

        L = L * (1 / maxdiag)
        b = b * (1 / maxdiag)

        LU = superlu.factorize(L._getMatrix().to_csr())

        error0 = numerix.sqrt(numerix.sum((L * x - b)**2))

        for iteration in range(self.iterations):
            errorVector = L * x - b

            if (numerix.sqrt(numerix.sum(errorVector**2)) / error0)  <= self.tolerance:
                break

            xError = numerix.zeros(len(b),'d')
            LU.solve(errorVector, xError)
            x[:] = x - xError
Example #10
0
    def staticSolver(self, solver_arg):
        self.solution = np.zeros((self.dofcount,), dtype=float)
        forces = self.nodalforces
        
        if solver_arg == 'default':
            spooles = solver.Spooles(self.GK)
            self.solution[:] = forces
            spooles.solve(self.solution)

        elif solver_arg == 'pysparse':
            print 'solver used: ', solver_arg
            mat = self.GK.to_csr()
            LU = superlu.factorize(mat, permc_spec=2, diag_pivot_thresh=0.)
            LU.solve(forces, self.solution)
        
        elif solver_arg == 'sparse':
            print 'solver used: ', solver_arg
            mat = self.GK
            LU = linalg.splu(mat, permc_spec='MMD_AT_PLUS_A',
                    diag_pivot_thresh=0)
            self.solution = LU.solve(forces)

        else:
            raise FEError('unknown solver')
def PoissonSolveFem(xmax,nelx,no,bval,dens):
    bdcon=array([1,1,1,1,1,1]) # these bc's to for non zero Dirichlet   
    tx=linspace(0.0,1.0,nelx+1)
    # nodes quadratically scaled around origin!
    t2=tx**2
    tm=(-t2).tolist()
    tm.reverse()
    t=array(tm[:-1]+t2.tolist())
    print t
    x=y=z=t*xmax
    print x
    print y
    print z
    box=fem3d(x,y,z,no,bdcon)
    def v(xx,yy,zz):
        val=0.0
        return val
    def w(xx,yy,zz):
        return 1.0
    def IsOnBoundary(x,y,z):
        # this function returns True if (x,y,z) is on the Boundary
        if (abs(x) == xmax or abs(y) ==xmax or abs(z) == xmax):
            val= True
        else:
            val= False
        return val
    def bval1(x,y,z):
        # returns  phi (x,y,z) for (x,y,z) on the boundary 
        # but otherwise zero 
        if IsOnBoundary(x,y,z):
            return bval(x,y,z)
        else:
            return 0.0
    box.calc_mat(v,w)
    nodes=box.gn
    # 
    K=box.All # Matrix representing negative Laplace operator
    U=box.Mll # Overlap matrix between basis functions
    N0=K.shape[0] # Order of matrix including boundary DOF
    # rho is density at points of FEM grid
    rho=array([dens(x,y,z) for (x,y,z) in nodes])
    # mask is needed for pysparse 
    mask=array([1-IsOnBoundary(x,y,z) for (x,y,z) in nodes]) 
    bcv=array([bval1(x,y,z) for (x,y,z) in nodes])
    K0bcv=empty(N0)
    # convert K to sparse skyline format
    K0=K.to_sss()
    # calculate ( K_{01}+K_{11}) c_1 
    K0.matvec(bcv,K0bcv)
    # modify matrix K to implement Boundary Condition
    # all rows and columns corresponding to boundary nodes are deleted from the matrix 
    K.delete_rowcols(mask) 
    N1=K.shape[0] # Order of matrix without boundary dof's
    print K.shape
    # create new list of global nodes as 
    newnodes=array([nodes[i] for i in range(N0) if mask[i] ==1 ])
    # create indices for new nodes in old nodes
    ii=zeros(N1,"i")
    j=0
    for i in range(N0):
        if mask[i] == 1:
            ii[j]=i
            j=j+1
    # convert K to compressed sparse row format 
    K1=K.to_csr()
    # convert U to sparse skyline format 
    M=U.to_sss()
    b=empty(N0)
    # calculate U rho on whole domain including boundary
    M.matvec(rho,b)
    b=b-K0bcv
    # project on interior space yielding RHS of (8)
    b1=array([ b[i] for i in range(N0) if mask[i] == 1 ]) 
    pot=empty(N1)
    t0=time()
    # calculate LU factorization using the superlu module from pysparse
    LU=superlu.factorize(K1)  
    t1=time()
    print "time taken for factorization of K1:", t1-t0
    t0=time()
    LU.solve(b1,pot)
    t1=time()
    print "time taken to solve Laplace equation using LU Decomposition :", t1-t0
    pot0=empty(N0)
    # the following code fills the vector pot0 with the boundary values
    # of the potential at the corresponding positions
    for i in range(N0):
        if mask[i] ==0:
            x,y,z=nodes[i]
            pot0[i]=bval(x,y,z)
    pot0[ii]=pot
    # making use of the interpolation functionality provided by fem3d
    # define a function that returns the values at of the resulting potential
    # at the points defined by (xi[k],yi[k],zi[k])
    def potf(xi,yi,zi):
        return box.wave(xi,yi,zi,pot0)
    # the following lines define xi,yi,zi along a line with constant y and z-values
    # from -xmax to xmax 
    xi=linspace(-xmax,xmax,1001)
    yi=zi=zeros(1001,"i")
    poti=potf(xi,yi,zi)
    #open file to write potential values to
    pfile=open("pot_direct_xmax=%f_nel=%d_no=%d.dat" %  (xmax,2*nelx,no), "w")
    print >> pfile, "# N0=",N0, "N1=",N1
    for x,p in zip(xi,poti):
        print >> pfile, x,p,p-exactpot(x,0,0)
    pfile.close()
Example #12
0
 def testPoisson1dMMD_AplusA(self):
     luA = superlu.factorize(self.B, permc_spec=2)
     luA.solve(self.b, self.x)
     print error(self.x, self.x_exact), self.tol, luA.nnz
     self.failUnless(error(self.x, self.x_exact) < self.tol)
Example #13
0
 def __init__(self, A, n11):
     n = A.shape[0]
     self.n11 = n11
     self.lu11 = superlu.factorize(A[:n11,:n11].to_csr(), diag_pivot_thresh=0)
     self.K22 = precon.ssor(A[n11:,n11:].to_sss())
     self.shape = (n, n)
Example #14
0
 def testPoisson2dCOLAMD(self):
     luA = superlu.factorize(self.B, permc_spec=3)
     luA.solve(self.b, self.x)
     print error(self.x, self.x_exact), self.tol, luA.nnz
     self.failUnless(error(self.x, self.x_exact) < self.tol)
Example #15
0
 def testPoisson1dDefault(self):
     luA = superlu.factorize(self.B)
     luA.solve(self.b, self.x)
     print error(self.x, self.x_exact), self.tol, luA.nnz
     self.failUnless(error(self.x, self.x_exact) < self.tol)
Example #16
0
def analyze(vxg, loads, boundary, iter):
    """
    main analysis function
       - vxg: voxel grid (3d list)
       - loads: each consisting of
           * points [point set #1, point set #2 ...]
           * value [value #1, value #2, ...]
       - boundary
           * points
       - iter: whether to use iterative or direct solver
        (points are element numbers)
    output:
       - displacement vector
       - von Mises stress vector
    """
    global Ke, B, C

    nz = len(vxg)
    ny = len(vxg[0])
    nx = len(vxg[0][0])
    _log('voxelization')
    print('voxel grid: ' + str(nx) + ' x ' + str(ny) + ' x ' + str(nz))

    # compute stiffness matrix for individual elements
    DOF = 3
    ksize = DOF * (nx + 1) * (ny + 1) * (nz + 1)
    kall = spmatrix.ll_mat_sym(ksize, ksize)

    SOLID = 1.000
    VOID = 0.001
    for i in range(0, nz):
        for j in range(0, ny):
            for k in range(0, nx):
                xe = SOLID if vxg[i][j][k] == 1 else VOID
                nodes = _node_nums_3d(nx, ny, nz, k + 1, j + 1, i + 1)
                ind = []
                for n in nodes:
                    ind.extend([(n - 1) * DOF, (n - 1) * DOF + 1,
                                (n - 1) * DOF + 2])
                mask = np.ones(len(ind), dtype=int)
                kall.update_add_mask_sym(Ke * xe, ind, mask)

    _log('updated stiffness matrix for all elements')

    # formulate loading scenario
    rall = [0] * ksize
    indicesset = loads['points']
    values = loads['values']

    for i in range(0, len(indicesset)):
        indices = indicesset[i]
        value = values[i]
        for idx in indices:
            nodes = _node_nums_3d(nx, ny, nz, idx[0] + 1, idx[1] + 1,
                                  idx[2] + 1)
            for j in range(0, DOF):
                for k in range(0, len(nodes)):
                    rall[DOF * (nodes[k] - 1) + j] = value[j]

    # formulate boundary condition
    elemmask = [1] * (nx + 1) * (ny + 1) * (nz + 1)
    for idx in boundary:
        nodes = _node_nums_3d(nx, ny, nz, idx[0] + 1, idx[1] + 1, idx[2] + 1)
        for j in range(0, len(nodes)):
            elemmask[nodes[j] - 1] = 0

    freedofs = []
    fixeddofs = []
    for i in range(0, len(elemmask)):
        if elemmask[i] == 1:
            freedofs.extend((DOF * i, DOF * i + 1, DOF * i + 2))
        else:
            fixeddofs.extend((DOF * i, DOF * i + 1, DOF * i + 2))

    _log('formulated loading scenario and boundary condition')

    # solve KU=F
    rfree = np.take(rall, freedofs)
    dfree = np.empty(len(freedofs))

    alldofs = np.arange(ksize)
    rcfixed = np.where(np.in1d(alldofs, fixeddofs), 0, 1)
    kfree = kall
    kfree.delete_rowcols(rcfixed)

    _log('removed constrained elements')

    if iter:
        kfree = kfree.to_sss()
        prek = precon.ssor(kfree)
        (info, numitr, relerr) = itsolvers.pcg(kfree, rfree, dfree, 1e-8, 8000,
                                               prek)
        if info >= 0:
            print('converged after ' + str(numitr) +
                  ' iterations with error of ' + str(relerr))
        else:
            print('PySparse error: Type:' + info + ', at' + str(numitr) +
                  'iterations.')
    else:
        kfree = kfree.to_csr()
        lu = superlu.factorize(kfree)
        lu.solve(rfree, dfree)

    _log('solved KU=F')

    dall = np.zeros_like(rall)
    for i in range(0, len(freedofs)):
        dall[freedofs[i]] = dfree[i]

    # compute stress
    cb = C * B
    vonmises = []
    for i in range(0, nz):
        vmplane = []
        for j in range(0, ny):
            vmrow = []
            for k in range(0, nx):
                nodes = _node_nums_3d(nx, ny, nz, k + 1, j + 1, i + 1)
                disps = []
                for n in nodes:
                    disps.extend([
                        dall[DOF * (n - 1)], dall[DOF * (n - 1) + 1],
                        dall[DOF * (n - 1) + 2]
                    ])
                d = np.matrix(disps).transpose()
                sigma = cb * d

                s11 = sigma.item(0, 0)
                s22 = sigma.item(1, 0)
                s33 = sigma.item(2, 0)
                s12 = sigma.item(3, 0) * 0.5  # DOUBLE CHECK THIS
                s23 = sigma.item(4, 0) * 0.5
                s31 = sigma.item(5, 0) * 0.5

                # von Mises stress, cf. Strava et al.'s Stress Relief paper (SIGGRAPH '12)
                vmrow.append(
                    sqrt(0.5 *
                         ((s11 - s22)**2 + (s22 - s33)**2 +
                          (s33 - s11)**2 + 6 * (s12**2 + s23**2 + s31**2))))
            vmplane.append(vmrow)
        vonmises.append(vmplane)

    t1 = _log('computed stress')

    global t0
    print('total time:' + str(t1 - t0) + ' ms')

    return {'displacements': dall.tolist(), 'stress': vonmises}
Example #17
0
 def testPoisson1dNoPivot(self):
     luA = superlu.factorize(self.B, diag_pivot_thresh=0.0)
     luA.solve(self.b, self.x)
     print error(self.x, self.x_exact), self.tol, luA.nnz
     self.failUnless(error(self.x, self.x_exact) < self.tol)
Example #18
0
 def testPoisson1dOrigOrdering(self):
     luA = superlu.factorize(self.B, permc_spec=0)
     luA.solve(self.b, self.x)
     print error(self.x, self.x_exact), self.tol, luA.nnz
     self.failUnless(error(self.x, self.x_exact) < self.tol)
Example #19
0
 def testPoisson1dSmallPanel(self):
     luA = superlu.factorize(self.B, panel_size=1)
     luA.solve(self.b, self.x)
     print error(self.x, self.x_exact), self.tol, luA.nnz
     self.failUnless(error(self.x, self.x_exact) < self.tol)
Example #20
0
 def testPoisson1dRelax(self):
     luA = superlu.factorize(self.B, relax=20)
     luA.solve(self.b, self.x)
     print error(self.x, self.x_exact), self.tol, luA.nnz
     self.failUnless(error(self.x, self.x_exact) < self.tol)