コード例 #1
0
ファイル: utils.py プロジェクト: MiroK/emi-book-fem
def direct_solve(A, b, W, which='umfpack'):
    '''inv(A)*b'''
    print 'Solving system of size %d' % A.size(0)
    # NOTE: umfpack sometimes blows up, MUMPS produces crap more often than not
    if isinstance(W, list):
        wh = ii_Function(W)
        LUSolver(which).solve(A, wh.vector(), b)
        print('|b-Ax| from direct solver', (A * wh.vector() - b).norm('linf'))

        return wh

    wh = Function(W)
    LUSolver(which).solve(A, wh.vector(), b)
    print('|b-Ax| from direct solver', (A * wh.vector() - b).norm('linf'))

    if isinstance(
            W.ufl_element(),
        (ufl.VectorElement, ufl.TensorElement)) or W.num_sub_spaces() == 1:
        return ii_Function([W], [wh])

    # Now get components
    Wblock = serialize_mixed_space(W)
    wh = wh.split(deepcopy=True)

    return ii_Function(Wblock, wh)
コード例 #2
0
ファイル: run_demo.py プロジェクト: andreavs/fenics_ii
def main(module_name, ncases, params, petsc_params):
    '''
    Run the test case in module with ncases. Optionally store results
    in savedir. For some modules there are multiple (which) choices of 
    preconditioners.
    '''

    # Unpack
    for k, v in params.items():
        exec(k + '=v', locals())

    RED = '\033[1;37;31m%s\033[0m'
    print RED % ('\tRunning %s' % module_name)

    module = __import__(module_name)  # no importlib in python2.7

    # Setup the MMS case
    u_true, rhs_data = module.setup_mms(eps)

    # Setup the convergence monitor
    if log:
        params = [('solver', solver), ('precond', str(precond)),
                  ('eps', str(eps))]

        path = '_'.join([module_name] + ['%s=%s' % pv for pv in params])
        path = os.path.join(save_dir if save_dir else '.', path)
        path = '.'.join([path, 'txt'])
    else:
        path = ''

    memory, residuals = [], []
    monitor = module.setup_error_monitor(u_true, memory, path=path)

    # Sometimes it is usedful to transform the solution before computing
    # the error. e.g. consider subdomains
    if hasattr(module, 'setup_transform'):
        # NOTE: transform take two args for case and the current computed
        # solution
        transform = module.setup_transform
    else:
        transform = lambda i, x: x

    print '=' * 79
    print '\t\t\tProblem eps = %g' % eps
    print '=' * 79
    for i in ncases:
        a, L, W = module.setup_problem(i, rhs_data, eps=eps)

        # Assemble blocks
        t = Timer('assembly')
        t.start()
        AA, bb = map(ii_assemble, (a, L))
        print '\tAssembled blocks in %g s' % t.stop()

        wh = ii_Function(W)

        if solver == 'direct':
            # Turn into a (monolithic) PETScMatrix/Vector
            t = Timer('conversion')
            t.start()
            AAm, bbm = map(ii_convert, (AA, bb))
            print '\tConversion to PETScMatrix/Vector took %g s' % t.stop()

            t = Timer('solve')
            t.start()
            LUSolver('umfpack').solve(AAm, wh.vector(), bbm)
            print '\tSolver took %g s' % t.stop()

            niters = 1
        else:
            # Here we define a Krylov solver using PETSc
            BB = module.setup_preconditioner(W, precond, eps=eps)
            ## AA and BB as block_mat
            ksp = PETSc.KSP().create()

            # Default is minres
            if '-ksp_type' not in petsc_params:
                petsc_params['-ksp_type'] = 'minres'

            opts = PETSc.Options()
            for key, value in petsc_params.iteritems():
                opts.setValue(key, None if value == 'none' else value)

            ksp.setOperators(ii_PETScOperator(AA))

            ksp.setNormType(PETSc.KSP.NormType.NORM_PRECONDITIONED)
            # ksp.setTolerances(rtol=1E-6, atol=None, divtol=None, max_it=300)
            ksp.setConvergenceHistory()
            # We attach the wrapped preconditioner defined by the module
            ksp.setPC(ii_PETScPreconditioner(BB, ksp))

            ksp.setFromOptions()

            print ksp.getTolerances()

            # Want the iterations to start from random
            wh.block_vec().randomize()
            # Solve, note the past object must be PETSc.Vec
            t = Timer('solve')
            t.start()
            ksp.solve(as_petsc_nest(bb), wh.petsc_vec())
            print '\tSolver took %g s' % t.stop()

            niters = ksp.getIterationNumber()

            residuals.append(ksp.getConvergenceHistory())

        # Let's check the final size of the residual
        r_norm = (bb - AA * wh.block_vec()).norm()

        # Convergence?
        monitor.send((transform(i, wh), niters, r_norm))

    # Only send the final
    if save_dir:
        path = os.path.join(save_dir, module_name)
        for i, wh_i in enumerate(wh):
            # Renaming to make it easier to save state in Visit/Pareview
            wh_i.rename('u', str(i))

            File('%s_%d.pvd' % (path, i)) << wh_i

    # Plot relative residual norm
    if plot:
        plt.figure()
        [
            plt.semilogy(res / res[0], label=str(i))
            for i, res in enumerate(residuals, 1)
        ]
        plt.legend(loc='best')
        plt.show()
コード例 #3
0
ファイル: run_demo.py プロジェクト: HomaiRS/fenics_ii
def main(module_name, ncases, params, petsc_params):
    '''
    Run the test case in module with ncases. Optionally store results
    in savedir. For some modules there are multiple (which) choices of 
    preconditioners.
    '''
    
    # Unpack
    for k, v in params.items(): exec(k + '=v', locals())

    RED = '\033[1;37;31m%s\033[0m'
    print RED % ('\tRunning %s with %d preconditioner' % (module_name, precond))

    module = __import__(module_name)  # no importlib in python2.7

    # Setup the MMS case
    u_true, rhs_data = module.setup_mms(eps)

    # Setup the convergence monitor
    if log:
        params = [('solver', solver), ('precond', str(precond)), ('eps', str(eps))]
        
        path = '_'.join([module_name] + ['%s=%s' % pv for pv in params])
        path = os.path.join(save_dir if save_dir else '.', path)
        path = '.'.join([path, 'txt'])
    else:
        path = ''

    memory, residuals  = [], []
    monitor = module.setup_error_monitor(u_true, memory, path=path)

    # Sometimes it is usedful to transform the solution before computing
    # the error. e.g. consider subdomains
    if hasattr(module, 'setup_transform'):
        # NOTE: transform take two args for case and the current computed
        # solution
        transform = module.setup_transform
    else:
        transform = lambda i, x: x

    print '='*79
    print '\t\t\tProblem eps = %r' % eps
    print '='*79
    for i in ncases:
        a, L, W = module.setup_problem(i, rhs_data, eps=eps)
        
        # Assemble blocks
        t = Timer('assembly'); t.start()
        AA, bb = map(ii_assemble, (a, L))
        print '\tAssembled blocks in %g s' % t.stop()

        # Check the symmetry
        wh = ii_Function(W)

        assert (AA*wh.block_vec() - (AA.T)*wh.block_vec()).norm() < 1E-10

        if solver == 'direct':
            # Turn into a (monolithic) PETScMatrix/Vector
            t = Timer('conversion'); t.start()        
            AAm, bbm = map(ii_convert, (AA, bb))
            print '\tConversion to PETScMatrix/Vector took %g s' % t.stop()

            t = Timer('solve'); t.start()
            LUSolver('umfpack').solve(AAm, wh.vector(), bbm)
            print '\tSolver took %g s' % t.stop()

            niters = 1

        if solver == 'iterative':
            # Here we define a Krylov solver using PETSc
            BB = module.setup_preconditioner(W, precond, eps=eps)

            ## AA and BB as block_mat
            ksp = PETSc.KSP().create()

            # Default is minres
            if '-ksp_type' not in petsc_params: petsc_params['-ksp_type'] = 'minres'
            
            opts = PETSc.Options()
            for key, value in petsc_params.iteritems():
                opts.setValue(key, None if value == 'none' else value)

            ksp.setOperators(ii_PETScOperator(AA))

            ksp.setNormType(PETSc.KSP.NormType.NORM_PRECONDITIONED)
            # ksp.setTolerances(rtol=1E-6, atol=None, divtol=None, max_it=300)
            ksp.setConvergenceHistory()
            # We attach the wrapped preconditioner defined by the module
            ksp.setPC(ii_PETScPreconditioner(BB, ksp))
            
            ksp.setFromOptions()
            
            print ksp.getTolerances()
            
            # Want the iterations to start from random
            wh.block_vec().randomize()

            # Solve, note the past object must be PETSc.Vec
            t = Timer('solve'); t.start()            
            ksp.solve(as_petsc_nest(bb), wh.petsc_vec())
            print '\tSolver took %g s' % t.stop()

            niters = ksp.getIterationNumber()

            residuals.append(ksp.getConvergenceHistory())
            
        # Let's check the final size of the residual
        r_norm = (bb - AA*wh.block_vec()).norm()
        # Convergence?
        monitor.send((transform(i, wh), W, niters, r_norm))
        
    # Only send the final
    if save_dir:
        path = os.path.join(save_dir, module_name)
        for i, wh_i in enumerate(wh):
            # Renaming to make it easier to save state in Visit/Pareview
            wh_i.rename('u', str(i))
            
            File('%s_%d.pvd' % (path, i)) << wh_i

    # Plot relative residual norm
    if plot:
        plt.figure()
        [plt.semilogy(res/res[0], label=str(i)) for i, res in enumerate(residuals, 1)]
        plt.legend(loc='best')
        plt.show()
コード例 #4
0
    def get_iters(A, b, B, W, Z=None, params=params):
        ''' Solution and iters A: W->W', B:W'->W, b\in W' '''
        ## AA and BB as block_mat
        ksp = PETSc.KSP().create()
        ksp.setConvergenceHistory()
        ksp.setNormType(PETSc.KSP.NormType.NORM_PRECONDITIONED)

        compute_eigs = params['-ksp_type'] == 'cg'
        if compute_eigs:
            ksp.setComputeEigenvalues(1)
        else:
            ksp.setComputeEigenvalues(0)

        if isinstance(W, list):
            # The problem should always be symmetric
            y = A.create_vec()
            y = randomize(y)

            if params['-ksp_type'] == 'minres':
                Ay = A * y
            #    At_y = (A.T)*y
            #    assert (Ay - At_y).norm() < 1E-6*sum(yi.size() for yi in y), (Ay - At_y).norm()

            ksp.setOperators(ii_PETScOperator(A, Z))  # Wrap block_mat
            ksp.setPC(ii_PETScPreconditioner(B, ksp))  # Wrapped block_op

            wh = ii_Function(W)
            # Want the iterations to start from random
            wh.block_vec().randomize()
            # User configs
            opts = PETSc.Options()
            for key, value in params.iteritems():
                opts.setValue(key, None if value == 'none' else value)
                ksp.setFromOptions()

            Z is not None and Z.orthogonalize(wh.block_vec())

            # Time the solver
            timer = Timer('solver')

            Z is not None and Z.orthogonalize(b)

            ksp.solve(as_petsc_nest(b), wh.petsc_vec())
            ksp_time = timer.stop()

        else:
            pc_config, Bmat = B
            # A for syste, B for preconditioner
            ksp.setOperators(as_backend_type(A).mat(), Bmat)
            # Now config
            pc = ksp.getPC()
            pc_options = pc_config(pc)

            params.update(pc_options)

            opts = PETSc.Options()
            # Database + user options
            for key, value in params.iteritems():
                opts.setValue(key, None if value == 'none' else value)
            # Apply
            pc.setFromOptions()
            ksp.setFromOptions()

            wh = Function(W)
            x = as_backend_type(wh.vector())
            x.set_local(np.random.rand(x.local_size()))

            timer = Timer('solver')
            ksp.solve(as_backend_type(b).vec(), x.vec())
            ksp_time = timer.stop()

            if isinstance(W.ufl_element(),
                          (ufl.VectorElement,
                           ufl.TensorElement)) or W.num_sub_spaces() == 1:
                wh = ii_Function([W], [wh])
            else:
                # Now get components
                Wblock = serialize_mixed_space(W)
                wh = wh.split(deepcopy=True)

                wh = ii_Function(Wblock, wh)
        # Done
        niters = ksp.getIterationNumber()
        residuals = ksp.getConvergenceHistory()

        if compute_eigs:
            eigs = np.abs(ksp.computeEigenvalues())
            cond = np.max(eigs) / np.min(eigs)
        else:
            cond = -1

        return cond, ksp_time, niters, residuals, wh