Пример #1
0
 def CheckResidual(self, residual):
     self.iterations += 1
     self.residuals.append(residual)
     if len(self.residuals) == 1:
         if self.tol is None:
             self._final_residual = self.atol
         else:
             self._final_residual = residual * self.tol
             if self.atol is not None:
                 self._final_residual = max(self._final_residual, self.atol)
     else:
         if self.callback is not None:
             self.callback(self.iterations, residual)
         if self.callback_sol is not None:
             self.callback_sol(self.sol)
     if self.residuals[0] != 0:
         logerrstop = log(self._final_residual)
         logerrfirst = log(self.residuals[0])
         _SetThreadPercentage(100. * max(self.iterations / self.maxiter,
                                         (log(residual) - logerrfirst) /
                                         (logerrstop - logerrfirst)))
     if self.printrates:
         print("{} iteration {}, residual = {}".format(
             self.name, self.iterations, residual),
               end="\n"
               if isinstance(self.printrates, bool) else self.printrates)
         if self.iterations == self.maxiter and residual >= self._final_residual:
             print("WARNING: {} did not converge to TOL".format(self.name))
     is_converged = self.iterations == self.maxiter or residual < self._final_residual
     if is_converged and self.printrates == "\r":
         print("{} {}converged in {} iterations to residual {}".format(
             self.name, "NOT " if residual >= self._final_residual else "",
             self.iterations, residual))
     return is_converged
Пример #2
0
 def Solve(self,
           rhs: BaseVector,
           sol: Optional[BaseVector] = None,
           initialize: bool = True) -> BaseVector:
     old_status = _GetStatus()
     _PushStatus(self.name + " Solve")
     _SetThreadPercentage(0)
     if sol is None:
         sol = rhs.CreateVector()
         initialize = True
     if initialize:
         sol[:] = 0
     self.sol = sol
     self._SolveImpl(rhs=rhs, sol=sol)
     if old_status[0] != "idle":
         _PushStatus(old_status[0])
         _SetThreadPercentage(old_status[1])
     return sol
Пример #3
0
    def Solve(self,
              rhs: BaseVector,
              sol: Optional[BaseVector] = None,
              initialize: bool = True) -> None:
        old_status = _GetStatus()
        _PushStatus("CG Solve")
        _SetThreadPercentage(0)
        self.sol = sol if sol is not None else self.mat.CreateRowVector()
        d, w, s = self._tmp_vecs
        u, mat, pre, conjugate, tol, maxsteps, callback = self.sol, self.mat, self.pre, self.conjugate, \
            self.tol, self.maxsteps, self.callback
        if initialize:
            u[:] = 0
        d.data = rhs - mat * u
        w.data = pre * d if pre else d
        s.data = w
        wdn = w.InnerProduct(d, conjugate=conjugate)
        err0 = sqrt(abs(wdn))

        self.errors = [err0]
        if wdn == err0:
            return u
        lwstart = log(err0)
        errstop = err0 * tol
        if self.abstol is not None:
            errstop = max(errstop, self.abstol)
        logerrstop = log(errstop)

        for it in range(maxsteps):
            self.iterations = it + 1
            w.data = mat * s
            wd = wdn
            as_s = s.InnerProduct(w, conjugate=conjugate)
            alpha = wd / as_s
            u.data += alpha * s
            d.data += (-alpha) * w

            w.data = pre * d if pre else d

            wdn = w.InnerProduct(d, conjugate=conjugate)
            beta = wdn / wd

            s *= beta
            s.data += w

            err = sqrt(abs(wd))
            self.errors.append(err)
            self.logger.info("iteration " + str(it) + " error = " + str(err))
            if callback is not None:
                callback(it, err)
            _SetThreadPercentage(
                100. * max(it / maxsteps,
                           (log(err) - lwstart) / (logerrstop - lwstart)))
            if err < errstop: break
        else:
            self.logger.warning("CG did not converge to tol")
        if old_status[0] != "idle":
            _PushStatus(old_status[0])
            _SetThreadPercentage(old_status[1])