Exemplo n.º 1
0
    def _assign_solvers(self):
        mat, ind = self._obtain_submatrix()
        all_ind = np.arange(self.rhs.size)
        not_ind = [np.setdiff1d(all_ind, i) for i in ind]

        factory = LSFactory()
        num_mat = len(mat)
        solvers = np.empty(num_mat, dtype=np.object)
        for i, A in enumerate(mat):
            sz = A.shape[0]
            if sz < 5000:
                solvers[i] = factory.direct(A)
            else:
                # amg solver is pyamg is installed, if not ilu
                try:
                    solvers[i] = factory.amg(A, as_precond=True)
                except ImportError:
                    solvers[i] = factory.ilu(A)

        return solvers, ind, not_ind
Exemplo n.º 2
0
    def solve(self, max_direct=40000, callback=False, **kwargs):
        """
        This is an adaption of the elliptic solver to the Schur complement
        elimination. The only change can be found in the if self.el statement.
        """
        # Discretize
        tic = time.time()
        logger.info('Discretize')
        self.lhs, self.rhs = self.reassemble()
        if self.el:
            to_be_eliminated = SC.dofs_of_dimension(other.grid(), other.lhs,
                                                    eldim)
            self.lhs, self.rhs, _, _, _ = SC.eliminate_dofs(
                other.lhs, other.rhs, to_be_eliminated)

        logger.info('Done. Elapsed time ' + str(time.time() - tic))

        # Solve
        tic = time.time()
        ls = LSFactory()
        if self.rhs.size < max_direct:
            logger.info('Solve linear system using direct solver')
            self.x = ls.direct(self.lhs, self.rhs)
        else:
            logger.info('Solve linear system using GMRES')
            precond = self._setup_preconditioner()
            #            precond = ls.ilu(self.lhs)
            slv = ls.gmres(self.lhs)
            self.x, info = slv(self.rhs,
                               M=precond,
                               callback=callback,
                               maxiter=10000,
                               restart=1500,
                               tol=1e-8)
            if info == 0:
                logger.info('GMRES succeeded.')
            else:
                logger.error('GMRES failed with status ' + str(info))

        logger.info('Done. Elapsed time ' + str(time.time() - tic))
        return self.x
Exemplo n.º 3
0
    def solve(self, max_direct=40000, callback=False, **kwargs):
        """ Reassemble and solve linear system.

        After the funtion has been called, the attributes lhs and rhs are
        updated according to the parameter states. Also, the attribute x
        gives the pressure given the current state.

        TODO: Provide an option to save solver information if multiple
        systems are to be solved with the same left hand side.

        The function attempts to set up the best linear solver based on the
        system size. The setup and parameter choices here are still
        experimental.

        Parameters:
            max_direct (int): Maximum number of unknowns where a direct solver
                is applied. If a direct solver can be applied this is usually
                the most efficient option. However, if the system size is
                too large compared to available memory, a direct solver becomes
                extremely slow.
            callback (boolean, optional): If True iteration information will be
                output when an iterative solver is applied (system size larger
                than max_direct)

        Returns:
            np.array: Pressure state.

        """
        logger.error("Solve elliptic model")
        # Discretize
        tic = time.time()
        logger.warning("Discretize")
        self.lhs, self.rhs = self.reassemble()
        logger.warning("Done. Elapsed time " + str(time.time() - tic))

        # Solve
        tic = time.time()
        ls = LSFactory()
        if self.rhs.size < max_direct:
            logger.warning("Solve linear system using direct solver")
            self.x = ls.direct(self.lhs, self.rhs)
        else:
            logger.warning("Solve linear system using GMRES")
            precond = self._setup_preconditioner()
            #            precond = ls.ilu(self.lhs)
            slv = ls.gmres(self.lhs)
            self.x, info = slv(
                self.rhs,
                M=precond,
                callback=callback,
                maxiter=10000,
                restart=1500,
                tol=1e-8,
            )
            if info == 0:
                logger.warning("GMRES succeeded.")
            else:
                logger.warning("GMRES failed with status " + str(info))

        logger.warning("Done. Elapsed time " + str(time.time() - tic))
        return self.x
Exemplo n.º 4
0
    def solve(self,
              max_direct=40000,
              callback=False,
              discretize=True,
              **kwargs):
        """ Reassemble and solve linear system.

        After the funtion has been called, the attributes lhs and rhs are
        updated according to the parameter states. Also, the attribute x
        gives the pressure given the current state.

        The function attempts to set up the best linear solver based on the
        system size. The setup and parameter choices here are still
        experimental.

        Parameters:
            max_direct (int): Maximum number of unknowns where a direct solver
                is applied. If a direct solver can be applied this is usually
                the most efficient option. However, if the system size is
                too large compared to available memory, a direct solver becomes
                extremely slow.
            callback (boolean, optional): If True iteration information will be
                output when an iterative solver is applied (system size larger
                than max_direct)

        Returns:
            np.array: Pressure state.

        """
        # Discretize
        tic = time.time()
        if discretize:
            logger.info('Discretize')
            self.lhs, self.rhs = self.reassemble(**kwargs)
            self.is_factorized = False
            logger.info('Done. Elapsed time ' + str(time.time() - tic))
        else:
            self.rhs = self._stress_disc.rhs(self.grid(), self.data())
        # Solve
        tic = time.time()
        ls = LSFactory()

        if self.rhs.size < max_direct:
            logger.info('Solve linear system using direct solver')
            if not self.is_factorized:
                logger.info('Making LU decomposition')
                self.lhs = self.lhs.tocsc()
                self.lhs = sps.linalg.factorized(self.lhs)
                self.is_factorized = True
                logger.info('Done. Elapsed time ' + str(time.time() - tic))
            logger.info('Solve linear system using direct solver')
            tic = time.time()
            self.x = self.lhs(self.rhs)
        else:
            logger.info('Solve linear system using GMRES')
            precond = self._setup_preconditioner()
            #            precond = ls.ilu(self.lhs)
            slv = ls.gmres(self.lhs)
            self.x, info = slv(self.rhs,
                               M=precond,
                               callback=callback,
                               maxiter=10000,
                               restart=1500,
                               tol=1e-8)
            if info == 0:
                logger.info('GMRES succeeded.')
            else:
                logger.error('GMRES failed with status ' + str(info))

        logger.info('Done. Elapsed time ' + str(time.time() - tic))
        return self.x