예제 #1
0
    def _end_time_step(self, t, T):
        "Call at end of time step"

        # Record CPU time
        cpu_time = time()
        elapsed_time = cpu_time - self._cpu_time
        self._cpu_time = cpu_time

        # Write some useful information
        s = "Time step %d (t = %g) finished in %g seconds." % (self._time_step,
                                                               t, elapsed_time)
        info("\n" + s + "\n" + len(s) * "-" + "\n")

        # Update progress bar
        if self._progress is None:
            self._progress = Progress("Time-stepping")
        self._progress.update(t / T)

        # Increase time step counter
        self._time_step += 1
예제 #2
0
class CBCSolver:
    "Base class for all solvers"

    def __init__(self):
        "Constructor"
        self._time_step = 1
        self._progress = None
        self._cpu_time = time()

    # --- Functions that must be overloaded by subclasses ---

    def solve():
        error("solve() function not implemented by solver.")

    def __str__():
        error("__str__ not implemented by solver.")

    # --- Useful functions for solvers ---

    def _end_time_step(self, t, T):
        "Call at end of time step"

        # Record CPU time
        cpu_time = time()
        elapsed_time = cpu_time - self._cpu_time
        self._cpu_time = cpu_time

        # Write some useful information
        s = "Time step %d (t = %g) finished in %g seconds." % (self._time_step,
                                                               t, elapsed_time)
        info("\n" + s + "\n" + len(s) * "-" + "\n")

        # Update progress bar
        if self._progress is None:
            self._progress = Progress("Time-stepping")
        self._progress.update(t / T)

        # Increase time step counter
        self._time_step += 1
예제 #3
0
class CBCSolver:
    "Base class for all solvers"

    def __init__(self):
        "Constructor"
        self._time_step = 1
        self._progress = None
        self._cpu_time = time()

    #--- Functions that must be overloaded by subclasses ---

    def solve():
        error("solve() function not implemented by solver.")

    def __str__():
        error("__str__ not implemented by solver.")

    #--- Useful functions for solvers ---

    def _end_time_step(self, t, T):
        "Call at end of time step"

        # Record CPU time
        cpu_time = time()
        elapsed_time = cpu_time - self._cpu_time
        self._cpu_time = cpu_time

        # Write some useful information
        s = "Time step %d (t = %g) finished in %g seconds." % (self._time_step, t, elapsed_time)
        info("\n" + s + "\n" + len(s)*"-" + "\n")

        # Update progress bar
        if self._progress is None:
            self._progress = Progress("Time-stepping")
        self._progress.update(t / T)

        # Increase time step counter
        self._time_step += 1
예제 #4
0
    def matvec(self, b):
        from time import time
        from block.block_vec import block_vec
        from dolfin import log, info, Progress
        TRACE = 13 # dolfin.TRACE

        T = time()

        # If x and initial_guess are block_vecs, some of the blocks may be
        # scalars (although they are normally converted to vectors by bc
        # application). To be sure, call allocate() on them.

        if isinstance(b, block_vec):
            # Create a shallow copy to call allocate() on, to avoid changing the caller's copy of b
            b = block_vec(len(b), b.blocks)
            b.allocate(self.A, dim=0)

        if self.initial_guess:
            # Most (all?) solvers modify x, so make a copy to avoid changing
            # the caller's copy of x
            from block.block_util import copy
            x = copy(self.initial_guess)
            if isinstance(x, block_vec):
                x.allocate(self.A, dim=1)
        else:
            x = self.A.create_vec(dim=1)
            x.zero()

        try:
            log(TRACE, self.__class__.__name__+' solve of '+str(self.A))
            if self.B != 1.0:
                log(TRACE, 'Using preconditioner: '+str(self.B))
            progress = Progress(self.name, self.maxiter)
            if self.tolerance < 0:
                tolerance = -self.tolerance
                relative = True
            else:
                tolerance = self.tolerance
                relative = False
            x = self.method(self.B, self.AR, x, b, tolerance=tolerance,
                            relativeconv=self.relativeconv, maxiter=self.maxiter,
                            progress=progress, callback=self.callback,
                            **self.kwargs)
            del progress # trigger final printout
        except Exception, e:
            from dolfin import warning
            warning("Error solving " + self.name)
            raise
예제 #5
0
    def _end_time_step(self, t, T):
        "Call at end of time step"

        # Record CPU time
        cpu_time = time()
        elapsed_time = cpu_time - self._cpu_time
        self._cpu_time = cpu_time

        # Write some useful information
        s = "Time step %d (t = %g) finished in %g seconds." % (self._time_step, t, elapsed_time)
        info("\n" + s + "\n" + len(s)*"-" + "\n")

        # Update progress bar
        if self._progress is None:
            self._progress = Progress("Time-stepping")
        self._progress.update(t / T)

        # Increase time step counter
        self._time_step += 1
예제 #6
0
    def matvec(self, b):
        from time import time
        from block.block_vec import block_vec
        from dolfin import info, Progress
        from ffc.log import log
        TRACE = 13  # dolfin.TRACE

        T = time()

        # If x and initial_guess are block_vecs, some of the blocks may be
        # scalars (although they are normally converted to vectors by bc
        # application). To be sure, call allocate() on them.

        if isinstance(b, block_vec):
            # Create a shallow copy to call allocate() on, to avoid changing the caller's copy of b
            b = block_vec(len(b), b.blocks)
            b.allocate(self.A, dim=0)

        if self.initial_guess:
            # Most (all?) solvers modify x, so make a copy to avoid changing
            # the caller's copy of x
            from block.block_util import copy
            x = copy(self.initial_guess)
            if isinstance(x, block_vec):
                x.allocate(self.A, dim=1)
        else:
            x = self.A.create_vec(dim=1)
            x.zero()

        try:
            log(TRACE, self.__class__.__name__ + ' solve of ' + str(self.A))
            if self.B != 1.0:
                log(TRACE, 'Using preconditioner: ' + str(self.B))
            progress = Progress(self.name, self.maxiter)
            if self.tolerance < 0:
                tolerance = -self.tolerance
                relative = True
            else:
                tolerance = self.tolerance
                relative = False
            x = self.method(self.B,
                            self.AR,
                            x,
                            b,
                            tolerance=tolerance,
                            relativeconv=self.relativeconv,
                            maxiter=self.maxiter,
                            progress=progress,
                            callback=self.callback,
                            **self.kwargs)
            del progress  # trigger final printout
        except Exception as e:
            from dolfin import warning
            warning("Error solving " + self.name)
            raise
        x, self.residuals, self.alphas, self.betas = x

        if self.tolerance == 0:
            msg = "done"
        elif self.converged:
            msg = "converged"
        else:
            msg = "NOT CONV."

        if self.show == 1:
            info('%s %s [iter=%2d, time=%.2fs, res=%.1e]' \
                % (self.name, msg, self.iterations, time()-T, self.residuals[-1]))
        elif self.show >= 2:
            info('%s %s [iter=%2d, time=%.2fs, res=%.1e, true res=%.1e]' \
                % (self.name, msg, self.iterations, time()-T, self.residuals[-1], (self.A*x-b).norm('l2')))
        if self.show == 3:
            from dolfin import MPI
            if MPI.rank(None) == 0:
                try:
                    from matplotlib import pyplot
                    pyplot.figure('%s convergence (show=3)' % self.name)
                    pyplot.semilogy(self.residuals)
                    pyplot.show(block=True)
                except:
                    pass

        if self.R is not None:
            x = self.R * x

        if self.retain_guess:
            self.initial_guess = x

        if not self.converged and self.nonconvergence_is_fatal:
            raise RuntimeError('Not converged')

        return x