Example #1
0
    def init_solvers(self, nls_status=None, ls_conf=None, nls_conf=None, mtx=None, **kwargs):
        ls_conf = get_default(ls_conf, self.ls_conf, "you must set linear solver!")

        nls_conf = get_default(nls_conf, self.nls_conf, "you must set nonlinear solver!")

        ev = self.get_evaluator(**kwargs)
        ls = Solver.any_from_conf(ls_conf, mtx=mtx)
        nls = Solver.any_from_conf(nls_conf, evaluator=ev, lin_solver=ls, status=nls_status)
        self.solvers = Struct(name="solvers", ls=ls, nls=nls)
Example #2
0
 def is_linear(self):
     nls_conf = get_default(None, self.nls_conf, "you must set nonlinear solver!")
     aux = Solver.any_from_conf(nls_conf)
     if aux.conf.problem == "linear":
         return True
     else:
         return False
Example #3
0
    def presolve(self, mtx):
        """Prepare A^{-1} B^T for the Schur complement."""

        mtx_a = mtx['A']
        mtx_bt = mtx['BT']
        output('full A size: %.3f MB' % (8.0 * nm.prod(mtx_a.shape) / 1e6))
        output('full B size: %.3f MB' % (8.0 * nm.prod(mtx_bt.shape) / 1e6))

        ls = Solver.any_from_conf(self.problem.ls_conf,
                                   presolve=True, mtx=mtx_a)
        if self.mode == 'explicit':
            tt = time.clock()
            mtx_aibt = nm.zeros(mtx_bt.shape, dtype=mtx_bt.dtype)
            for ic in xrange(mtx_bt.shape[1]):
                mtx_aibt[:,ic] = ls(mtx_bt[:,ic].toarray().squeeze())
            output('mtx_aibt: %.2f s' % (time.clock() - tt))
            action_aibt = MatrixAction.from_array(mtx_aibt)
        else:
            ##
            # c: 30.08.2007, r: 13.02.2008
            def fun_aibt(vec):
                # Fix me for sparse mtx_bt...
                rhs = sc.dot(mtx_bt, vec)
                out = ls(rhs)
                return out
            action_aibt = MatrixAction.from_function(fun_aibt,
                                                    (mtx_a.shape[0],
                                                     mtx_bt.shape[1]),
                                                    nm.float64)
        mtx['action_aibt'] = action_aibt
Example #4
0
def solve_optimize(conf, options):
    opts = conf.options
    trunk = io.get_trunk(conf.filename_mesh)
    data = {}

    dpb = Problem.from_conf(conf, init_equations=False)
    equations = getattr(conf, '_'.join(('equations_direct', opts.problem)))

    dpb.set_equations(equations)

    dpb.name = 'direct'
    dpb.time_update(None)

    apb = dpb.copy('adjoint')
    equations = getattr(
        conf, '_'.join(
            ('equations_adjoint', opts.problem, opts.objective_function)))

    apb.set_equations(equations)
    apb.time_update(None)
    apb.ebcs.zero_dofs()
    apb.update_equations(None, ebcs=apb.ebcs)

    ls_conf = dpb.get_solver_conf(opts.ls)
    dnls_conf = dpb.get_solver_conf(opts.nls_direct)
    anls_conf = dpb.get_solver_conf(opts.nls_adjoint)
    opt_conf = dpb.get_solver_conf(opts.optimizer)

    dpb.init_solvers(ls_conf=ls_conf, nls_conf=dnls_conf)

    apb.init_solvers(ls_conf=ls_conf, nls_conf=anls_conf)

    shape_opt = so.ShapeOptimFlowCase.from_conf(conf, dpb, apb)
    design0 = shape_opt.dsg_vars.val
    shape_opt.cache = Struct(design=design0 + 100, state=None, i_mesh=-1)

    opt_status = IndexedStruct()
    optimizer = Solver.any_from_conf(opt_conf,
                                     obj_fun=so.obj_fun,
                                     obj_fun_grad=so.obj_fun_grad,
                                     status=opt_status,
                                     obj_args=(shape_opt, opts))

    ##
    # State problem solution for the initial design.
    vec_dp0 = so.solve_problem_for_design(dpb, design0, shape_opt, opts)

    dpb.save_state(trunk + '_direct_initial.vtk', vec_dp0)

    ##
    # Optimize.
    des = optimizer(design0)
    print opt_status

    ##
    # Save final state (for "optimal" design).
    dpb.domain.mesh.write(trunk + '_opt.mesh', io='auto')
    dpb.save_state(trunk + '_direct_current.vtk', shape_opt.cache.state)

    print des
Example #5
0
    def presolve(self, mtx):
        """Prepare A^{-1} B^T for the Schur complement."""

        mtx_a = mtx['A']
        mtx_bt = mtx['BT']
        output('full A size: %.3f MB' % (8.0 * nm.prod(mtx_a.shape) / 1e6))
        output('full B size: %.3f MB' % (8.0 * nm.prod(mtx_bt.shape) / 1e6))

        ls = Solver.any_from_conf(self.problem.ls_conf,
                                  presolve=True,
                                  mtx=mtx_a)
        if self.mode == 'explicit':
            tt = time.clock()
            mtx_aibt = nm.zeros(mtx_bt.shape, dtype=mtx_bt.dtype)
            for ic in xrange(mtx_bt.shape[1]):
                mtx_aibt[:, ic] = ls(mtx_bt[:, ic].toarray().squeeze())
            output('mtx_aibt: %.2f s' % (time.clock() - tt))
            action_aibt = MatrixAction.from_array(mtx_aibt)
        else:
            ##
            # c: 30.08.2007, r: 13.02.2008
            def fun_aibt(vec):
                # Fix me for sparse mtx_bt...
                rhs = sc.dot(mtx_bt, vec)
                out = ls(rhs)
                return out

            action_aibt = MatrixAction.from_function(
                fun_aibt, (mtx_a.shape[0], mtx_bt.shape[1]), nm.float64)
        mtx['action_aibt'] = action_aibt
    def test_eigenvalue_solvers(self):
        eig_confs = self._list_eigenvalue_solvers(self.conf.solvers)

        n_eigs = 5

        ok = True
        tt = []
        for eig_conf in eig_confs:
            self.report(eig_conf.name)

            eig_solver = Solver.any_from_conf(eig_conf)

            t0 = time.clock()
            eigs, vecs = eig_solver(self.mtx, n_eigs=n_eigs, eigenvectors=True)
            tt.append((' '.join((eig_conf.name, eig_conf.kind)),
                       time.clock() - t0))

            self.report(eigs)

            _ok = nm.allclose(eigs.real, eigs_expected, rtol=0.0, atol=1e-8)
            ok = ok and (_ok or (eig_conf.kind in self.can_fail))

        tt.sort(key=lambda x: x[1])
        self.report('solution times:')
        for row in tt:
            self.report('%.2f [s]' % row[1], ':', row[0])

        return ok
Example #7
0
 def is_linear(self):
     nls_conf = get_default(None, self.nls_conf,
                            'you must set nonlinear solver!')
     aux = Solver.any_from_conf(nls_conf)
     if aux.conf.problem == 'linear':
         return True
     else:
         return False
Example #8
0
    def init_solvers(self,
                     nls_status=None,
                     ls_conf=None,
                     nls_conf=None,
                     mtx=None,
                     presolve=False):
        """Create and initialize solvers."""
        ls_conf = get_default(ls_conf, self.ls_conf,
                              'you must set linear solver!')

        nls_conf = get_default(nls_conf, self.nls_conf,
                               'you must set nonlinear solver!')

        if presolve:
            tt = time.clock()
        if ls_conf.get('needs_problem_instance', False):
            extra_args = {'problem': self}
        else:
            extra_args = {}

        ls = Solver.any_from_conf(ls_conf,
                                  mtx=mtx,
                                  presolve=presolve,
                                  **extra_args)
        if presolve:
            tt = time.clock() - tt
            output('presolve: %.2f [s]' % tt)

        if nls_conf.get('needs_problem_instance', False):
            extra_args = {'problem': self}
        else:
            extra_args = {}
        ev = self.get_evaluator()

        if self.conf.options.get('ulf', False):
            self.nls_iter_hook = ev.new_ulf_iteration

        nls = Solver.any_from_conf(nls_conf,
                                   fun=ev.eval_residual,
                                   fun_grad=ev.eval_tangent_matrix,
                                   lin_solver=ls,
                                   iter_hook=self.nls_iter_hook,
                                   status=nls_status,
                                   **extra_args)

        self.solvers = Struct(name='solvers', ls=ls, nls=nls)
Example #9
0
def solve_optimize(conf, options):
    opts = conf.options
    trunk = io.get_trunk(conf.filename_mesh)
    data = {}

    dpb = ProblemDefinition.from_conf(conf, init_equations=False)
    equations = getattr(conf, "_".join(("equations_direct", opts.problem)))

    dpb.set_equations(equations)

    dpb.name = "direct"
    dpb.time_update(None)

    apb = dpb.copy("adjoint")
    equations = getattr(conf, "_".join(("equations_adjoint", opts.problem, opts.objective_function)))

    apb.set_equations(equations)
    apb.time_update(None)
    apb.ebcs.zero_dofs()
    apb.update_equations(None, ebcs=apb.ebcs)

    ls_conf = dpb.get_solver_conf(opts.ls)
    dnls_conf = dpb.get_solver_conf(opts.nls_direct)
    anls_conf = dpb.get_solver_conf(opts.nls_adjoint)
    opt_conf = dpb.get_solver_conf(opts.optimizer)

    dpb.init_solvers(ls_conf=ls_conf, nls_conf=dnls_conf)

    apb.init_solvers(ls_conf=ls_conf, nls_conf=anls_conf)

    shape_opt = so.ShapeOptimFlowCase.from_conf(conf, dpb, apb)
    design0 = shape_opt.dsg_vars.val
    shape_opt.cache = Struct(design=design0 + 100, state=None, i_mesh=-1)

    opt_status = IndexedStruct()
    optimizer = Solver.any_from_conf(
        opt_conf, obj_fun=so.obj_fun, obj_fun_grad=so.obj_fun_grad, status=opt_status, obj_args=(shape_opt, opts)
    )

    ##
    # State problem solution for the initial design.
    vec_dp0 = so.solve_problem_for_design(dpb, design0, shape_opt, opts)

    dpb.save_state(trunk + "_direct_initial.vtk", vec_dp0)

    ##
    # Optimize.
    des = optimizer(design0)
    print opt_status

    ##
    # Save final state (for "optimal" design).
    dpb.domain.mesh.write(trunk + "_opt.mesh", io="auto")
    dpb.save_state(trunk + "_direct_current.vtk", shape_opt.cache.state)

    print des
Example #10
0
    def __init__(self, problem, options):
        self.mtx_mass = problem.evaluate(options.mass, mode='weak',
                                         auto_init=True, dw_mode='matrix')

        if options.lumped:
            raise NotImplementedError

        else:
            # Initialize solvers (and possibly presolve the matrix).
            self.ls = Solver.any_from_conf(problem.ls_conf, mtx=self.mtx_mass,
                                           presolve=True)
Example #11
0
    def init_solvers(self, nls_status=None, ls_conf=None, nls_conf=None,
                     force=False):
        """
        Create and initialize solver instances.

        Parameters
        ----------
        nls_status : dict-like, IndexedStruct, optional
            The user-supplied object to hold nonlinear solver convergence
            statistics.
        ls_conf : Struct, optional
            The linear solver options.
        nls_conf : Struct, optional
            The nonlinear solver options.
        force : bool
            If True, re-create the solver instances even if they already exist
            in `self.nls` attribute.
        """
        if (self.nls is None) or force:
            ls_conf = get_default(ls_conf, self.ls_conf,
                                  'you must set linear solver!')

            nls_conf = get_default(nls_conf, self.nls_conf,
                                   'you must set nonlinear solver!')

            ls = Solver.any_from_conf(ls_conf, problem=self)

            ev = self.get_evaluator()

            if self.conf.options.get('ulf', False):
                self.nls_iter_hook = ev.new_ulf_iteration

            nls = Solver.any_from_conf(nls_conf, fun=ev.eval_residual,
                                       fun_grad=ev.eval_tangent_matrix,
                                       lin_solver=ls,
                                       iter_hook=self.nls_iter_hook,
                                       status=nls_status, problem=self)

            self.set_solver(nls)
Example #12
0
    def get_time_solver(self, ts_conf=None, **kwargs):
        """
        Create and return a TimeSteppingSolver instance.

        Notes
        -----
        Also sets `self.ts` attribute.
        """
        ts_conf = get_default(ts_conf, self.ts_conf, "you must set time-stepping solver!")
        ts_solver = Solver.any_from_conf(ts_conf, problem=self, **kwargs)
        self.ts = ts_solver.ts

        return ts_solver
    def test_eigenvalue_solvers(self):
        from sfepy.base.base import IndexedStruct

        eig_confs = self._list_eigenvalue_solvers(self.conf.solvers)

        all_n_eigs = [5, 0]

        ok = True
        tt = []
        for ii, n_eigs in enumerate(all_n_eigs):
            for eig_conf in eig_confs:
                self.report(eig_conf.name)

                try:
                    eig_solver = Solver.any_from_conf(eig_conf)

                except (ValueError, ImportError):
                    if eig_conf.kind in self.can_fail:
                        continue

                    else:
                        raise

                status = IndexedStruct()
                eigs, vecs = eig_solver(self.mtx,
                                        n_eigs=n_eigs,
                                        eigenvectors=True,
                                        status=status)
                tt.append([
                    ' '.join((eig_conf.name, eig_conf.kind)), status.time,
                    n_eigs
                ])

                self.report(eigs)

                _ok = nm.allclose(eigs.real,
                                  eigs_expected[ii],
                                  rtol=0.0,
                                  atol=1e-8)
                tt[-1].append(_ok)

                ok = ok and (_ok or (eig_conf.kind in self.can_fail) or
                             (eig_conf.name in self.can_miss))

        tt.sort(key=lambda x: x[1])
        self.report('solution times:')
        for row in tt:
            self.report('%.2f [s] : %s (%d) (ok: %s)' %
                        (row[1], row[0], row[2], row[3]))

        return ok
Example #14
0
    def init_solvers(self, nls_status=None, ls_conf=None, nls_conf=None, mtx=None, presolve=False):
        """Create and initialize solvers."""
        ls_conf = get_default(ls_conf, self.ls_conf, "you must set linear solver!")

        nls_conf = get_default(nls_conf, self.nls_conf, "you must set nonlinear solver!")

        if presolve:
            tt = time.clock()
        if ls_conf.get("needs_problem_instance", False):
            extra_args = {"problem": self}
        else:
            extra_args = {}

        ls = Solver.any_from_conf(ls_conf, mtx=mtx, presolve=presolve, **extra_args)
        if presolve:
            tt = time.clock() - tt
            output("presolve: %.2f [s]" % tt)

        if nls_conf.get("needs_problem_instance", False):
            extra_args = {"problem": self}
        else:
            extra_args = {}
        ev = self.get_evaluator()

        if self.conf.options.get("ulf", False):
            self.nls_iter_hook = ev.new_ulf_iteration

        nls = Solver.any_from_conf(
            nls_conf,
            fun=ev.eval_residual,
            fun_grad=ev.eval_tangent_matrix,
            lin_solver=ls,
            iter_hook=self.nls_iter_hook,
            status=nls_status,
            **extra_args
        )

        self.set_solvers_instances(ls=ls, nls=nls)
Example #15
0
File: la.py Project: certik/sfepy
def eig( mtx_a, mtx_b = None, num = None, eigenvectors = True,
         return_time = None, method = 'eig.scipy', **ckwargs ):

    kwargs = {'name' : 'aux', 'kind' : method}
    kwargs.update( ckwargs )
    conf = Struct( **kwargs )
    solver = Solver.any_from_conf( conf )

    status = {}
    out = solver( mtx_a, mtx_b, num, eigenvectors, status )
    if return_time is not None:
        return_time[0] = status['time']
        
    return out
Example #16
0
    def __init__(self, problem, options):
        self.mtx_mass = problem.evaluate(options.mass,
                                         mode='weak',
                                         auto_init=True,
                                         dw_mode='matrix')

        if options.lumped:
            raise NotImplementedError

        else:
            # Initialize solvers (and possibly presolve the matrix).
            self.ls = Solver.any_from_conf(problem.ls_conf,
                                           mtx=self.mtx_mass,
                                           presolve=True)
Example #17
0
    def get_time_solver(self, ts_conf=None, **kwargs):
        """
        Create and return a TimeSteppingSolver instance.

        Notes
        -----
        Also sets `self.ts` attribute.
        """
        ts_conf = get_default(ts_conf, self.ts_conf,
                              'you must set time-stepping solver!')
        ts_solver = Solver.any_from_conf(ts_conf, problem=self, **kwargs)
        self.ts = ts_solver.ts

        return ts_solver
Example #18
0
    def init_solvers(self, nls_status=None, ls_conf=None, nls_conf=None,
                     mtx=None, presolve=False):
        """Create and initialize solvers."""
        ls_conf = get_default( ls_conf, self.ls_conf,
                               'you must set linear solver!' )

        nls_conf = get_default( nls_conf, self.nls_conf,
                              'you must set nonlinear solver!' )

        if presolve:
            tt = time.clock()
        if get_default_attr(ls_conf, 'needs_problem_instance', False):
            extra_args = {'problem' : self}
        else:
            extra_args = {}

        ls = Solver.any_from_conf(ls_conf, mtx=mtx, presolve=presolve,
                                  **extra_args)
        if presolve:
            tt = time.clock() - tt
            output('presolve: %.2f [s]' % tt)

        if get_default_attr(nls_conf, 'needs_problem_instance', False):
            extra_args = {'problem' : self}
        else:
            extra_args = {}
        ev = self.get_evaluator()

        if get_default_attr(self.conf.options, 'ulf', False):
            self.nls_iter_hook = ev.new_ulf_iteration

        nls = Solver.any_from_conf(nls_conf, fun=ev.eval_residual,
                                   fun_grad=ev.eval_tangent_matrix,
                                   lin_solver=ls, iter_hook=self.nls_iter_hook,
                                   status=nls_status, **extra_args)

        self.solvers = Struct( name = 'solvers', ls = ls, nls = nls )
Example #19
0
    def prepare_matrices(self, problem):
        """
        A = K + B^T D^{-1} B
        """
        equations = problem.equations
        mtx = equations.eval_tangent_matrices(None,
                                              problem.mtx_a,
                                              by_blocks=True)

        ls = Solver.any_from_conf(problem.ls_conf, presolve=True, mtx=mtx['D'])

        mtx_b, mtx_m = mtx['B'], mtx['M']
        mtx_dib = nm.empty(mtx_b.shape, dtype=mtx_b.dtype)
        for ic in xrange(mtx_b.shape[1]):
            mtx_dib[:, ic] = ls(mtx_b[:, ic].toarray().squeeze())
        mtx_a = mtx['K'] + mtx_b.T * mtx_dib

        return mtx_a, mtx_m, mtx_dib
Example #20
0
    def prepare_matrices(self, problem):
        """
        A = K + B^T D^{-1} B
        """
        equations = problem.equations
        mtx = equations.eval_tangent_matrices(None, problem.mtx_a,
                                              by_blocks=True)

        ls = Solver.any_from_conf(problem.ls_conf,
                                  presolve=True, mtx=mtx['D'])

        mtx_b, mtx_m = mtx['B'], mtx['M']
        mtx_dib = nm.empty(mtx_b.shape, dtype=mtx_b.dtype)
        for ic in xrange(mtx_b.shape[1]):
            mtx_dib[:,ic] = ls(mtx_b[:,ic].toarray().squeeze())
        mtx_a = mtx['K'] + mtx_b.T * mtx_dib

        return mtx_a, mtx_m, mtx_dib
Example #21
0
    def solve_eigen_problem(self):
        opts = self.app_options
        pb = self.problem

        pb.set_equations(pb.conf.equations)
        pb.time_update()

        output('assembling lhs...')
        tt = time.clock()
        mtx_a = pb.evaluate(pb.conf.equations['lhs'],
                            mode='weak',
                            auto_init=True,
                            dw_mode='matrix')
        output('...done in %.2f s' % (time.clock() - tt))

        if 'rhs' in pb.conf.equations:
            output('assembling rhs...')
            tt = time.clock()
            mtx_b = pb.evaluate(pb.conf.equations['rhs'],
                                mode='weak',
                                dw_mode='matrix')
            output('...done in %.2f s' % (time.clock() - tt))

        else:
            mtx_b = None

        n_eigs = get_default(opts.n_eigs, mtx_a.shape[0])

        output('solving eigenvalue problem for {} values...'.format(n_eigs))
        eig = Solver.any_from_conf(pb.get_solver_conf(opts.evps))
        if opts.eigs_only:
            eigs = eig(mtx_a, mtx_b, n_eigs, eigenvectors=False)
            svecs = None

        else:
            eigs, svecs = eig(mtx_a, mtx_b, n_eigs, eigenvectors=True)

        output('...done')

        vecs = self.make_full(svecs)
        self.save_results(eigs, vecs)

        return Struct(pb=pb, eigs=eigs, vecs=vecs)
Example #22
0
    def solve_eigen_problem(self):
        opts = self.app_options
        pb = self.problem

        pb.set_equations(pb.conf.equations)
        pb.time_update()

        output('assembling lhs...')
        tt = time.clock()
        mtx_a = pb.evaluate(pb.conf.equations['lhs'], mode='weak',
                            auto_init=True, dw_mode='matrix')
        output('...done in %.2f s' % (time.clock() - tt))

        if 'rhs' in pb.conf.equations:
            output('assembling rhs...')
            tt = time.clock()
            mtx_b = pb.evaluate(pb.conf.equations['rhs'], mode='weak',
                                dw_mode='matrix')
            output('...done in %.2f s' % (time.clock() - tt))

        else:
            mtx_b = None

        _n_eigs = get_default(opts.n_eigs, mtx_a.shape[0])

        output('solving eigenvalue problem for {} values...'.format(_n_eigs))
        eig = Solver.any_from_conf(pb.get_solver_conf(opts.evps))
        if opts.eigs_only:
            eigs = eig(mtx_a, mtx_b, opts.n_eigs, eigenvectors=False)
            svecs = None

        else:
            eigs, svecs = eig(mtx_a, mtx_b, opts.n_eigs, eigenvectors=True)

        output('...done')

        vecs = self.make_full(svecs)
        self.save_results(eigs, vecs)

        return Struct(pb=pb, eigs=eigs, vecs=vecs)
    def test_eigenvalue_solvers(self):
        eig_confs = self._list_eigenvalue_solvers(self.conf.solvers)

        n_eigs = 5

        ok = True
        tt = []
        for eig_conf in eig_confs:
            self.report(eig_conf.name)

            try:
                eig_solver = Solver.any_from_conf(eig_conf)

            except (ValueError, ImportError):
                if eig_conf.kind in self.can_fail:
                    continue

                else:
                    raise

            t0 = time.clock()
            eigs, vecs = eig_solver(self.mtx, n_eigs=n_eigs, eigenvectors=True)
            tt.append(
                [' '.join((eig_conf.name, eig_conf.kind)),
                 time.clock() - t0])

            self.report(eigs)

            _ok = nm.allclose(eigs.real, eigs_expected, rtol=0.0, atol=1e-8)
            tt[-1].append(_ok)

            ok = ok and (_ok or (eig_conf.kind in self.can_fail) or
                         (eig_conf.name in self.can_miss))

        tt.sort(key=lambda x: x[1])
        self.report('solution times:')
        for row in tt:
            self.report('%.2f [s] : %s (ok: %s)' % (row[1], row[0], row[2]))

        return ok
    def test_eigenvalue_solvers(self):
        eig_confs = self._list_eigenvalue_solvers(self.conf.solvers)

        n_eigs = 5

        ok = True
        tt = []
        for eig_conf in eig_confs:
            self.report(eig_conf.name)

            try:
                eig_solver = Solver.any_from_conf(eig_conf)

            except (ValueError, ImportError):
                if eig_conf.kind in self.can_fail:
                    continue

                else:
                    raise

            t0 = time.clock()
            eigs, vecs = eig_solver(self.mtx, n_eigs=n_eigs, eigenvectors=True)
            tt.append([' '.join((eig_conf.name, eig_conf.kind)),
                       time.clock() - t0])

            self.report(eigs)

            _ok = nm.allclose(eigs.real, eigs_expected, rtol=0.0, atol=1e-8)
            tt[-1].append(_ok)

            ok = ok and (_ok or (eig_conf.kind in self.can_fail)
                         or (eig_conf.name in self.can_miss))

        tt.sort(key=lambda x: x[1])
        self.report('solution times:')
        for row in tt:
            self.report('%.2f [s] : %s (ok: %s)' % (row[1], row[0], row[2]))

        return ok
Example #25
0
    def test_ls_reuse(self):
        import numpy as nm
        from sfepy.solvers import Solver
        from sfepy.discrete.state import State

        self.problem.init_solvers(ls_conf=self.problem.solver_confs['d00'])
        nls = self.problem.get_nls()

        state0 = State(self.problem.equations.variables)
        state0.apply_ebc()
        vec0 = state0.get_reduced()

        self.problem.update_materials()

        rhs = nls.fun(vec0)
        mtx = nls.fun_grad(vec0)

        ok = True
        for name in ['i12', 'i01']:
            solver_conf = self.problem.solver_confs[name]
            method = solver_conf.get('method', '')
            precond = solver_conf.get('precond', '')
            name = ' '.join((solver_conf.name, solver_conf.kind, method,
                             precond)).rstrip()
            self.report(name)
            try:
                ls = Solver.any_from_conf(solver_conf)

            except:
                self.report('skipped!')
                continue

            conf = ls.conf.copy()
            conf.force_reuse = True

            sol00 = ls(rhs, mtx=mtx, conf=conf)
            digest00 = ls.mtx_digest

            sol0 = ls(rhs, mtx=mtx)
            digest0 = ls.mtx_digest

            sol1 = ls(rhs, mtx=2 * mtx, conf=conf)
            digest1 = ls.mtx_digest

            sol2 = ls(rhs, mtx=2 * mtx)
            digest2 = ls.mtx_digest
            ls(rhs, mtx=2 * mtx)
            digest3 = ls.mtx_digest

            _ok = digest00 != digest0
            self.report(digest00, '!=', digest0, ':', _ok)
            ok = ok and _ok
            _ok = digest0 == digest1
            self.report(digest0, '==', digest1, ':', _ok)
            ok = ok and _ok
            _ok = digest1 != digest2
            self.report(digest1, '!=', digest2, ':', _ok)
            ok = ok and _ok
            _ok = digest2[1] == digest3[1]
            self.report(digest2[1], '==', digest3[1], ':', _ok)
            ok = ok and _ok
            _ok = nm.allclose(sol00, sol0, atol=1e-12, rtol=0.0)
            self.report('sol00 == sol0:', _ok)
            ok = ok and _ok
            _ok = nm.allclose(sol0, sol1, atol=1e-12, rtol=0.0)
            self.report('sol0 == sol1:', _ok)
            ok = ok and _ok
            _ok = nm.allclose(sol0, 2 * sol2, atol=1e-12, rtol=0.0)
            self.report('sol0 == 2 * sol2:', _ok)
            ok = ok and _ok

        return ok
Example #26
0
    def solve_eigen_problem( self, ofn_trunk = None, post_process_hook = None ):

        if self.cached_evp is not None:
            return self.cached_evp

        problem = self.problem
        ofn_trunk = get_default( ofn_trunk, problem.ofn_trunk,
                                 'output file name trunk missing!' )
        post_process_hook = get_default( post_process_hook,
                                         self.post_process_hook )
 
        conf = self.conf
        
        eig_problem = self.app_options.eig_problem
        if eig_problem in ['simple', 'simple_liquid']:
            problem.set_equations( conf.equations )
            problem.time_update()

            mtx_a = problem.evaluate(conf.equations['lhs'], mode='weak',
                                     auto_init=True, dw_mode='matrix')

            mtx_m = problem.evaluate(conf.equations['rhs'], mode='weak',
                                     dw_mode='matrix')

        elif eig_problem == 'schur':
            # A = K + B^T D^{-1} B.
            mtx = assemble_by_blocks( conf.equations, self.problem,
                                      ebcs = conf.ebcs,
                                      epbcs = conf.epbcs )
            problem.set_equations( conf.equations )
            problem.time_update()

            ls = Solver.any_from_conf( problem.ls_conf,
                                       presolve = True, mtx = mtx['D'] )

            mtx_b, mtx_m = mtx['B'], mtx['M']
            mtx_dib = nm.empty( mtx_b.shape, dtype = mtx_b.dtype )
            for ic in xrange( mtx_b.shape[1] ):
                mtx_dib[:,ic] = ls( mtx_b[:,ic].toarray().squeeze() )
            mtx_a = mtx['K'] + mtx_b.T * mtx_dib

        else:
            raise NotImplementedError

##     from sfepy.base.plotutils import spy, plt
##     spy( mtx_b, eps = 1e-12 )
##     plt.show()
##     mtx_a.save( 'a.txt', format='%d %d %.12f\n' )
##     mtx_b.save( 'b.txt', format='%d %d %.12f\n' )
##     pause()

        output( 'computing resonance frequencies...' )
        tt = [0]

        if isinstance( mtx_a, sc.sparse.spmatrix ):
            mtx_a = mtx_a.toarray()
        if isinstance( mtx_m, sc.sparse.spmatrix ):
            mtx_m = mtx_m.toarray()

        eigs, mtx_s_phi = eig(mtx_a, mtx_m, return_time=tt,
                              method=self.app_options.eigensolver)
        eigs[eigs<0.0] = 0.0
        output( '...done in %.2f s' % tt[0] )
        output( 'original eigenfrequencies:' )        
        output( eigs )
        opts = self.app_options
        epsilon2 = opts.scale_epsilon * opts.scale_epsilon
        eigs_rescaled = (opts.elasticity_contrast / epsilon2)  * eigs
        output( 'rescaled eigenfrequencies:' )        
        output( eigs_rescaled )
        output( 'number of eigenfrequencies: %d' % eigs.shape[0] )

        try:
            assert_( nm.isfinite( eigs ).all() )
        except ValueError:
            debug()

        # B-orthogonality check.
##         print nm.dot( mtx_s_phi[:,5], nm.dot( mtx_m, mtx_s_phi[:,5] ) )
##         print nm.dot( mtx_s_phi[:,5], nm.dot( mtx_m, mtx_s_phi[:,0] ) )
##         debug()

        n_eigs = eigs.shape[0]

        variables = problem.get_variables()

        mtx_phi = nm.empty( (variables.di.ptr[-1], mtx_s_phi.shape[1]),
                           dtype = nm.float64 )

        make_full = variables.make_full_vec
        if eig_problem in ['simple', 'simple_liquid']:
            for ii in xrange( n_eigs ):
                mtx_phi[:,ii] = make_full( mtx_s_phi[:,ii] )
            eig_vectors = mtx_phi
            
        elif eig_problem == 'schur':
            # Update also eliminated variables.
            schur = self.app_options.schur
            primary_var = schur['primary_var']
            eliminated_var = schur['eliminated_var']

            mtx_s_phi_schur = - sc.dot( mtx_dib, mtx_s_phi )
            aux = nm.empty( (variables.adi.ptr[-1],),
                            dtype = nm.float64 )
            set = variables.set_state_part
            for ii in xrange( n_eigs ):
                set( aux, mtx_s_phi[:,ii], primary_var, stripped = True )
                set( aux, mtx_s_phi_schur[:,ii], eliminated_var,
                     stripped = True )

                mtx_phi[:,ii] = make_full( aux )

            indx = variables.get_indx( primary_var )
            eig_vectors = mtx_phi[indx,:]

        save = self.app_options.save
        out = {}
        for ii in xrange( n_eigs ):
            if (ii >= save[0]) and (ii < (n_eigs - save[1])): continue
            aux = problem.state_to_output( mtx_phi[:,ii] )
            for name, val in aux.iteritems():
                out[name+'%03d' % ii] = val

        if post_process_hook is not None:
            out = post_process_hook( out, problem, mtx_phi )

        problem.domain.mesh.write( ofn_trunk + '.vtk', io = 'auto', out = out )

        fd = open( ofn_trunk + '_eigs.txt', 'w' )
        eigs.tofile( fd, ' ' )
        fd.close()

        evp = Struct( kind = eig_problem,
                      eigs = eigs, eigs_rescaled = eigs_rescaled,
                      eig_vectors = eig_vectors )
        self.cached_evp = evp

        return evp
Example #27
0
def solve_navier_stokes(conf, options):
    opts = conf.options

    dpb = Problem.from_conf(conf, init_equations=False)
    equations = getattr(conf, '_'.join(('equations_direct', opts.problem)))
    dpb.set_equations(equations)

    ls_conf = dpb.get_solver_conf(opts.ls)
    nls_conf = dpb.get_solver_conf(opts.nls_direct)

    method = opts.direct_method
    if method == 'stationary':
        data = {}
        dpb.time_update(None)
        state_dp = dpb.solve(nls_conf=nls_conf)

    elif method == 'transient':
        ls = Solver.any_from_conf(ls_conf)
        ts_conf = dpb.get_solver_conf(opts.ts_direct)

        data = {'ts': Struct(dt=ts_conf.dt)}

        # Plug in mass term.
        mequations = {}
        for key, eq in equations.iteritems():
            if 'dw_div_grad' in eq:
                eq = '+'.join((ts_conf.mass_term, eq)).replace('++', '+')
            mequations[key] = eq

        if ts_conf.stokes_init:
            state_dp0 = solve_stokes(dpb, conf.equations_direct_stokes,
                                     nls_conf)
            dpb.set_equations(mequations)
        else:
            dpb.set_equations(mequations)
            state_dp0 = dpb.create_state()
            dpb.time_update(None)
            state_dp0.apply_ebc()

        from sfepy.base.log import Log

        log = Log.from_conf(Struct(is_plot=True), ([r'$||u||$'], [r'$||p||$']))

        output('Navier-Stokes...')
        ev = BasicEvaluator(dpb, ts=Struct(dt=ts_conf.dt))
        nls = Solver.any_from_conf(nls_conf, evaluator=ev, lin_solver=ls)

        n_step = ts_conf.n_step
        step = 0
        while 1:
            for ii in xrange(n_step):
                output(step)

                vec_u = state_dp0('w')
                vec_p = state_dp0('r')
                log(nm.linalg.norm(vec_u), nm.linalg.norm(vec_p))

                dpb.variables.set_data_from_state('w_0', state_dp0(), 'w')
                vec_dp = nls(state_dp0())

                step += 1
                state_dp = state_dp0.copy()
                state_dp.set_reduced(vec_dp)

                state_dp0 = state_dp

            if ts_conf.interactive:
                try:
                    n_step = int(raw_input('continue: '))
                    if n_step <= 0: break
                except:
                    break

        vec_u = state_dp('w')
        vec_p = state_dp('r')
        log(nm.linalg.norm(vec_u), nm.linalg.norm(vec_p), finished=True)

    else:
        raise 'unknown Navier-Stokes solution method (%s)!' % method

    return dpb, state_dp, data
Example #28
0
def solve_navier_stokes(conf, options):
    opts = conf.options

    dpb = ProblemDefinition.from_conf(conf, init_equations=False)
    equations = getattr(conf, '_'.join(('equations_direct', opts.problem)))
    dpb.set_equations(equations)

    ls_conf = dpb.get_solver_conf( opts.ls )
    nls_conf = dpb.get_solver_conf(opts.nls_direct)

    method = opts.direct_method
    if method == 'stationary':
        data = {}
        dpb.time_update(None)
        vec_dp = dpb.solve(nls_conf=nls_conf)

    elif method == 'transient':
        ls = Solver.any_from_conf( ls_conf )
        ts_conf = dpb.get_solver_conf( opts.ts_direct )

        data = {'ts' : Struct( dt = ts_conf.dt )}

        # Plug in mass term.
        mequations = {}
        for key, eq in equations.iteritems():
            if 'dw_div_grad' in eq:
                eq = '+'.join( (ts_conf.mass_term, eq) ).replace( '++', '+')
            mequations[key] = eq

        if ts_conf.stokes_init:
            vec_dp0 = solve_stokes( dpb, conf.equations_direct_stokes, nls_conf )
            dpb.set_equations( mequations )
        else:
            dpb.set_equations( mequations )
            vec_dp0 = dpb.create_state_vector()
            dpb.time_update( None )
            dpb.apply_ebc( vec_dp0 )

        from sfepy.base.log import Log

        log = Log.from_conf( Struct( is_plot = True ),
                            ([r'$||u||$'], [r'$||p||$']) )

        output( 'Navier-Stokes...' )
        ev = BasicEvaluator( dpb, ts = Struct( dt = ts_conf.dt ) )
        nls = Solver.any_from_conf( nls_conf, evaluator = ev, lin_solver = ls )

        n_step = ts_conf.n_step
        step = 0
        while 1:
            for ii in xrange( n_step ):
                output( step )

                vec_u = dpb.variables.get_state_part_view( vec_dp0, 'w' )
                vec_p = dpb.variables.get_state_part_view( vec_dp0, 'r' )
                log( nm.linalg.norm( vec_u ), nm.linalg.norm( vec_p ) )

                dpb.variables.non_state_data_from_state( 'w_0', vec_dp0, 'w' )
                vec_dp = nls( vec_dp0 )

                step += 1
                vec_dp0 = vec_dp.copy()

            if ts_conf.interactive:
                try:
                    n_step = int( raw_input( 'continue: ' ) )
                    if n_step <= 0: break
                except:
                    break

        vec_u = dpb.variables.get_state_part_view( vec_dp, 'w' )
        vec_p = dpb.variables.get_state_part_view( vec_dp, 'r' )
        log( nm.linalg.norm( vec_u ), nm.linalg.norm( vec_p ), finished = True )

    else:
        raise 'unknown Navier-Stokes solution method (%s)!'  % method
    
    return dpb, vec_dp, data
Example #29
0
def setup_precond(mtx, problem):
    """
    Setup a preconditioner for `mtx`.
    """
    import scipy.sparse.linalg as spla
    from sfepy.solvers import Solver

    # Get active DOF indices for u, p.
    adi = problem.get_variables().adi
    iu = adi.indx['u']
    ip = adi.indx['p']

    # Get the diagonal blocks of the linear system matrix.
    K = mtx[iu, iu]
    M = mtx[ip, ip]

    # Create solvers for K, M blocks to be used in matvec_bj(). A different
    # solver for each block could be used.
    conf = problem.solver_confs['direct']
    # conf = problem.solver_confs['cg-s']
    # conf = problem.solver_confs['cg-p']
    # conf = problem.solver_confs['pyamg']
    ls1 = Solver.any_from_conf(conf, mtx=K, context=problem)
    ls2 = Solver.any_from_conf(conf, mtx=M, context=problem)

    def matvec_bj(vec):
        """
        The application of the Block Jacobi preconditioner.

        The exact version (as with the `'direct'` solver) can be obtained also
        by using the following PETSs command-line options, together with the
        `'iterative-p'` solver::

          -ksp_monitor -pc_type fieldsplit -pc_fieldsplit_type additive -fieldsplit_u_ksp_type preonly -fieldsplit_u_pc_type lu -fieldsplit_p_ksp_type preonly -fieldsplit_p_pc_type lu

        The inexact version (20 iterations of a CG solver for each block, as
        with the `'cg-s'` or `'cg-p'` solvers) can be obtained also by using
        the following PETSs command-line options, together with the
        `'iterative-p'` solver::

          -ksp_monitor -pc_type fieldsplit -pc_fieldsplit_type additive -fieldsplit_u_ksp_type cg -fieldsplit_u_pc_type none -fieldsplit_p_ksp_type cg -fieldsplit_p_pc_type none -fieldsplit_u_ksp_max_it 20 -fieldsplit_p_ksp_max_it 20
        """
        vu = ls1(vec[iu])
        vp = ls2(vec[ip])

        return nm.r_[vu, vp]

    def matvec_j(vec):
        """
        The application of the Jacobi (diagonal) preconditioner.

        The same effect can be obtained also by using the following PETSs
        command-line options, together with the `'iterative-p'` solver::

          -ksp_monitor -pc_type jacobi
        """
        D = mtx.diagonal()

        return vec / D

    # Create the preconditioner, using one of matvec_bj() or matvec_j().
    precond = Struct(name='precond', shape=mtx.shape, matvec=matvec_bj)
    precond = spla.aslinearoperator(precond)

    return precond
Example #30
0
    def solve_eigen_problem(self):
        options = self.options
        opts = self.app_options
        pb = self.problem

        dim = pb.domain.mesh.dim

        pb.set_equations(pb.conf.equations)
        pb.time_update()

        output('assembling lhs...')
        tt = time.clock()
        mtx_a = pb.evaluate(pb.conf.equations['lhs'],
                            mode='weak',
                            auto_init=True,
                            dw_mode='matrix')
        output('...done in %.2f s' % (time.clock() - tt))

        output('assembling rhs...')
        tt = time.clock()
        mtx_b = pb.evaluate(pb.conf.equations['rhs'],
                            mode='weak',
                            dw_mode='matrix')
        output('...done in %.2f s' % (time.clock() - tt))

        n_eigs = get_default(opts.n_eigs, mtx_a.shape[0])

        output('computing resonance frequencies...')
        eig = Solver.any_from_conf(pb.get_solver_conf(opts.eigen_solver))
        eigs, mtx_s_phi = eig(mtx_a, mtx_b, n_eigs)
        output('...done')

        bounding_box = pb.domain.mesh.get_bounding_box()
        # this assumes a box (3D), or a square (2D):
        a = bounding_box[1][0] - bounding_box[0][0]
        E_exact = None
        if options.hydrogen or options.boron:
            if options.hydrogen:
                Z = 1
            elif options.boron:
                Z = 5
            if dim == 2:
                E_exact = [
                    -float(Z)**2 / 2 / (n - 0.5)**2 / 4
                    for n in [1] + [2] * 3 + [3] * 5 + [4] * 8 + [5] * 15
                ]
            elif dim == 3:
                E_exact = [
                    -float(Z)**2 / 2 / n**2
                    for n in [1] + [2] * 2**2 + [3] * 3**2
                ]
        if options.well:
            if dim == 2:
                E_exact = [
                    pi**2 / (2 * a**2) * x
                    for x in [2, 5, 5, 8, 10, 10, 13, 13, 17, 17, 18, 20, 20]
                ]
            elif dim == 3:
                E_exact = [
                    pi**2 / (2 * a**2) * x for x in [
                        3, 6, 6, 6, 9, 9, 9, 11, 11, 11, 12, 14, 14, 14, 14,
                        14, 14, 17, 17, 17
                    ]
                ]
        if options.oscillator:
            if dim == 2:
                E_exact = [1] + [2] * 2 + [3] * 3 + [4] * 4 + [5] * 5 + [6] * 6
            elif dim == 3:
                E_exact = [
                    float(1) / 2 + x
                    for x in [1] + [2] * 3 + [3] * 6 + [4] * 10
                ]
        if E_exact is not None:
            output("a=%f" % a)
            output("Energies:")
            output("n      exact         FEM      error")

            for i, e in enumerate(eigs):
                from numpy import NaN
                if i < len(E_exact):
                    exact = E_exact[i]
                    err = 100 * abs((exact - e) / exact)
                else:
                    exact = NaN
                    err = NaN
                output("%d:  %.8f   %.8f  %5.2f%%" % (i, exact, e, err))
        else:
            output(eigs)

        mtx_phi = self.make_full(mtx_s_phi)
        self.save_results(eigs, mtx_phi)

        return Struct(pb=pb, eigs=eigs, mtx_phi=mtx_phi)
Example #31
0
def main():
    parser = ArgumentParser(description=__doc__,
                            formatter_class=RawDescriptionHelpFormatter)
    parser.add_argument('--version', action='version', version='%(prog)s')
    parser.add_argument('-d', '--dims', metavar='dims',
                        action='store', dest='dims',
                        default='[1.0, 1.0]', help=helps['dims'])
    parser.add_argument('-c', '--centre', metavar='centre',
                        action='store', dest='centre',
                        default='[0.0, 0.0]', help=helps['centre'])
    parser.add_argument('-s', '--shape', metavar='shape',
                        action='store', dest='shape',
                        default='[11, 11]', help=helps['shape'])
    parser.add_argument('-b', '--bc-kind', metavar='kind',
                        action='store', dest='bc_kind',
                        choices=['free', 'cantilever', 'fixed'],
                        default='free', help=helps['bc_kind'])
    parser.add_argument('-a', '--axis', metavar='0, ..., dim, or -1',
                        type=int, action='store', dest='axis',
                        default=-1, help=helps['axis'])
    parser.add_argument('--young', metavar='float', type=float,
                        action='store', dest='young',
                        default=6.80e+10, help=helps['young'])
    parser.add_argument('--poisson', metavar='float', type=float,
                        action='store', dest='poisson',
                        default=0.36, help=helps['poisson'])
    parser.add_argument('--density', metavar='float', type=float,
                        action='store', dest='density',
                        default=2700.0, help=helps['density'])
    parser.add_argument('--order', metavar='int', type=int,
                        action='store', dest='order',
                        default=1, help=helps['order'])
    parser.add_argument('-n', '--n-eigs', metavar='int', type=int,
                        action='store', dest='n_eigs',
                        default=6, help=helps['n_eigs'])
    parser.add_argument('-i', '--ignore', metavar='int', type=int,
                        action='store', dest='ignore',
                        default=None, help=helps['ignore'])
    parser.add_argument('--solver', metavar='solver', action='store',
                        dest='solver',
                        default= \
                        "eig.scipy,method:'eigh',tol:1e-5,maxiter:1000",
                        help=helps['solver'])
    parser.add_argument('--show',
                        action="store_true", dest='show',
                        default=False, help=helps['show'])
    parser.add_argument('filename', nargs='?', default=None)
    options = parser.parse_args()

    aux = options.solver.split(',')
    kwargs = {}
    for option in aux[1:]:
        key, val = option.split(':')
        kwargs[key.strip()] = eval(val)
    eig_conf = Struct(name='evp', kind=aux[0], **kwargs)

    output('using values:')
    output("  Young's modulus:", options.young)
    output("  Poisson's ratio:", options.poisson)
    output('  density:', options.density)
    output('displacement field approximation order:', options.order)
    output('requested %d eigenvalues' % options.n_eigs)
    output('using eigenvalue problem solver:', eig_conf.kind)
    output.level += 1
    for key, val in six.iteritems(kwargs):
        output('%s: %r' % (key, val))
    output.level -= 1

    assert_((0.0 < options.poisson < 0.5),
            "Poisson's ratio must be in ]0, 0.5[!")
    assert_((0 < options.order),
            'displacement approximation order must be at least 1!')

    filename = options.filename
    if filename is not None:
        mesh = Mesh.from_file(filename)
        dim = mesh.dim
        dims = nm.diff(mesh.get_bounding_box(), axis=0)

    else:
        dims = nm.array(eval(options.dims), dtype=nm.float64)
        dim = len(dims)

        centre = nm.array(eval(options.centre), dtype=nm.float64)[:dim]
        shape = nm.array(eval(options.shape), dtype=nm.int32)[:dim]

        output('dimensions:', dims)
        output('centre:    ', centre)
        output('shape:     ', shape)

        mesh = gen_block_mesh(dims, shape, centre, name='mesh')

    output('axis:      ', options.axis)
    assert_((-dim <= options.axis < dim), 'invalid axis value!')

    eig_solver = Solver.any_from_conf(eig_conf)

    # Build the problem definition.
    domain = FEDomain('domain', mesh)

    bbox = domain.get_mesh_bounding_box()
    min_coor, max_coor = bbox[:, options.axis]
    eps = 1e-8 * (max_coor - min_coor)
    ax = 'xyz'[:dim][options.axis]

    omega = domain.create_region('Omega', 'all')
    bottom = domain.create_region('Bottom',
                                  'vertices in (%s < %.10f)'
                                  % (ax, min_coor + eps),
                                  'facet')
    bottom_top = domain.create_region('BottomTop',
                                      'r.Bottom +v vertices in (%s > %.10f)'
                                      % (ax, max_coor - eps),
                                      'facet')

    field = Field.from_args('fu', nm.float64, 'vector', omega,
                            approx_order=options.order)

    u = FieldVariable('u', 'unknown', field)
    v = FieldVariable('v', 'test', field, primary_var_name='u')

    mtx_d = stiffness_from_youngpoisson(dim, options.young, options.poisson)

    m = Material('m', D=mtx_d, rho=options.density)

    integral = Integral('i', order=2*options.order)

    t1 = Term.new('dw_lin_elastic(m.D, v, u)', integral, omega, m=m, v=v, u=u)
    t2 = Term.new('dw_volume_dot(m.rho, v, u)', integral, omega, m=m, v=v, u=u)
    eq1 = Equation('stiffness', t1)
    eq2 = Equation('mass', t2)
    lhs_eqs = Equations([eq1, eq2])

    pb = Problem('modal', equations=lhs_eqs)

    if options.bc_kind == 'free':
        pb.time_update()
        n_rbm = dim * (dim + 1) / 2

    elif options.bc_kind == 'cantilever':
        fixed = EssentialBC('Fixed', bottom, {'u.all' : 0.0})
        pb.time_update(ebcs=Conditions([fixed]))
        n_rbm = 0

    elif options.bc_kind == 'fixed':
        fixed = EssentialBC('Fixed', bottom_top, {'u.all' : 0.0})
        pb.time_update(ebcs=Conditions([fixed]))
        n_rbm = 0

    else:
        raise ValueError('unsupported BC kind! (%s)' % options.bc_kind)

    if options.ignore is not None:
        n_rbm = options.ignore

    pb.update_materials()

    # Assemble stiffness and mass matrices.
    mtx_k = eq1.evaluate(mode='weak', dw_mode='matrix', asm_obj=pb.mtx_a)
    mtx_m = mtx_k.copy()
    mtx_m.data[:] = 0.0
    mtx_m = eq2.evaluate(mode='weak', dw_mode='matrix', asm_obj=mtx_m)

    try:
        eigs, svecs = eig_solver(mtx_k, mtx_m, options.n_eigs + n_rbm,
                                 eigenvectors=True)

    except sla.ArpackNoConvergence as ee:
        eigs = ee.eigenvalues
        svecs = ee.eigenvectors
        output('only %d eigenvalues converged!' % len(eigs))

    output('%d eigenvalues converged (%d ignored as rigid body modes)' %
           (len(eigs), n_rbm))

    eigs = eigs[n_rbm:]
    svecs = svecs[:, n_rbm:]

    omegas = nm.sqrt(eigs)
    freqs = omegas / (2 * nm.pi)

    output('number |         eigenvalue |  angular frequency '
           '|          frequency')
    for ii, eig in enumerate(eigs):
        output('%6d | %17.12e | %17.12e | %17.12e'
               % (ii + 1, eig, omegas[ii], freqs[ii]))

    # Make full eigenvectors (add DOFs fixed by boundary conditions).
    variables = pb.get_variables()

    vecs = nm.empty((variables.di.ptr[-1], svecs.shape[1]),
                    dtype=nm.float64)
    for ii in range(svecs.shape[1]):
        vecs[:, ii] = variables.make_full_vec(svecs[:, ii])

    # Save the eigenvectors.
    out = {}
    state = pb.create_state()
    for ii in range(eigs.shape[0]):
        state.set_full(vecs[:, ii])
        aux = state.create_output_dict()
        strain = pb.evaluate('ev_cauchy_strain.i.Omega(u)',
                             integrals=Integrals([integral]),
                             mode='el_avg', verbose=False)
        out['u%03d' % ii] = aux.popitem()[1]
        out['strain%03d' % ii] = Struct(mode='cell', data=strain)

    pb.save_state('eigenshapes.vtk', out=out)
    pb.save_regions_as_groups('regions')

    if len(eigs) and options.show:
        # Show the solution. If the approximation order is greater than 1, the
        # extra DOFs are simply thrown away.
        from sfepy.postprocess.viewer import Viewer
        from sfepy.postprocess.domain_specific import DomainSpecificPlot

        scaling = 0.05 * dims.max() / nm.abs(vecs).max()

        ds = {}
        for ii in range(eigs.shape[0]):
            pd = DomainSpecificPlot('plot_displacements',
                                    ['rel_scaling=%s' % scaling,
                                     'color_kind="tensors"',
                                     'color_name="strain%03d"' % ii])
            ds['u%03d' % ii] = pd

        view = Viewer('eigenshapes.vtk')
        view(domain_specific=ds, only_names=sorted(ds.keys()),
             is_scalar_bar=False, is_wireframe=True)
Example #32
0
def solve_navier_stokes(conf, options):
    opts = conf.options

    dpb = ProblemDefinition.from_conf(conf, init_equations=False)
    equations = getattr(conf, "_".join(("equations_direct", opts.problem)))
    dpb.set_equations(equations)

    ls_conf = dpb.get_solver_conf(opts.ls)
    nls_conf = dpb.get_solver_conf(opts.nls_direct)

    method = opts.direct_method
    if method == "stationary":
        data = {}
        dpb.time_update(None)
        state_dp = dpb.solve(nls_conf=nls_conf)

    elif method == "transient":
        ls = Solver.any_from_conf(ls_conf)
        ts_conf = dpb.get_solver_conf(opts.ts_direct)

        data = {"ts": Struct(dt=ts_conf.dt)}

        # Plug in mass term.
        mequations = {}
        for key, eq in equations.iteritems():
            if "dw_div_grad" in eq:
                eq = "+".join((ts_conf.mass_term, eq)).replace("++", "+")
            mequations[key] = eq

        if ts_conf.stokes_init:
            state_dp0 = solve_stokes(dpb, conf.equations_direct_stokes, nls_conf)
            dpb.set_equations(mequations)
        else:
            dpb.set_equations(mequations)
            state_dp0 = dpb.create_state()
            dpb.time_update(None)
            state_dp0.apply_ebc()

        from sfepy.base.log import Log

        log = Log.from_conf(Struct(is_plot=True), ([r"$||u||$"], [r"$||p||$"]))

        output("Navier-Stokes...")
        ev = BasicEvaluator(dpb, ts=Struct(dt=ts_conf.dt))
        nls = Solver.any_from_conf(nls_conf, evaluator=ev, lin_solver=ls)

        n_step = ts_conf.n_step
        step = 0
        while 1:
            for ii in xrange(n_step):
                output(step)

                vec_u = state_dp0("w")
                vec_p = state_dp0("r")
                log(nm.linalg.norm(vec_u), nm.linalg.norm(vec_p))

                dpb.variables.set_data_from_state("w_0", state_dp0(), "w")
                vec_dp = nls(state_dp0())

                step += 1
                state_dp = state_dp0.copy()
                state_dp.set_reduced(vec_dp)

                state_dp0 = state_dp

            if ts_conf.interactive:
                try:
                    n_step = int(raw_input("continue: "))
                    if n_step <= 0:
                        break
                except:
                    break

        vec_u = state_dp("w")
        vec_p = state_dp("r")
        log(nm.linalg.norm(vec_u), nm.linalg.norm(vec_p), finished=True)

    else:
        raise "unknown Navier-Stokes solution method (%s)!" % method

    return dpb, state_dp, data
Example #33
0
def main():
    # Aluminium and epoxy.
    default_pars = '70e9,0.35,2.799e3, 3.8e9,0.27,1.142e3'
    default_solver_conf = ("kind='eig.scipy',method='eigsh',tol=1.0e-5,"
                           "maxiter=1000,which='LM',sigma=0.0")

    parser = ArgumentParser(description=__doc__,
                            formatter_class=RawDescriptionHelpFormatter)
    parser.add_argument('--pars', metavar='young1,poisson1,density1'
                        ',young2,poisson2,density2',
                        action='store', dest='pars',
                        default=default_pars, help=helps['pars'])
    parser.add_argument('--conf', metavar='filename',
                        action='store', dest='conf',
                        default=None, help=helps['conf'])
    parser.add_argument('--mesh-size', type=float, metavar='float',
                        action='store', dest='mesh_size',
                        default=None, help=helps['mesh_size'])
    parser.add_argument('--unit-multipliers',
                        metavar='c_time,c_length,c_mass',
                        action='store', dest='unit_multipliers',
                        default='1.0,1.0,1.0', help=helps['unit_multipliers'])
    parser.add_argument('--plane', action='store', dest='plane',
                        choices=['strain', 'stress'],
                        default='strain', help=helps['plane'])
    parser.add_argument('--wave-dir', metavar='float,float[,float]',
                        action='store', dest='wave_dir',
                        default='1.0,0.0,0.0', help=helps['wave_dir'])
    parser.add_argument('--mode', action='store', dest='mode',
                        choices=['omega', 'kappa'],
                        default='omega', help=helps['mode'])
    parser.add_argument('--range', metavar='start,stop,count',
                        action='store', dest='range',
                        default='0,6.4,33', help=helps['range'])
    parser.add_argument('--order', metavar='int', type=int,
                        action='store', dest='order',
                        default=1, help=helps['order'])
    parser.add_argument('--refine', metavar='int', type=int,
                        action='store', dest='refine',
                        default=0, help=helps['refine'])
    parser.add_argument('-n', '--n-eigs', metavar='int', type=int,
                        action='store', dest='n_eigs',
                        default=6, help=helps['n_eigs'])
    group = parser.add_mutually_exclusive_group()
    group.add_argument('--eigs-only',
                       action='store_true', dest='eigs_only',
                       default=False, help=helps['eigs_only'])
    group.add_argument('--post-process',
                       action='store_true', dest='post_process',
                       default=False, help=helps['post_process'])
    parser.add_argument('--solver-conf', metavar='dict-like',
                        action='store', dest='solver_conf',
                        default=default_solver_conf, help=helps['solver_conf'])
    parser.add_argument('--save-regions',
                        action='store_true', dest='save_regions',
                        default=False, help=helps['save_regions'])
    parser.add_argument('--save-materials',
                        action='store_true', dest='save_materials',
                        default=False, help=helps['save_materials'])
    parser.add_argument('--log-std-waves',
                        action='store_true', dest='log_std_waves',
                        default=False, help=helps['log_std_waves'])
    parser.add_argument('--no-legends',
                        action='store_false', dest='show_legends',
                        default=True, help=helps['no_legends'])
    parser.add_argument('--no-show',
                        action='store_false', dest='show',
                        default=True, help=helps['no_show'])
    parser.add_argument('--silent',
                        action='store_true', dest='silent',
                        default=False, help=helps['silent'])
    parser.add_argument('-c', '--clear',
                        action='store_true', dest='clear',
                        default=False, help=helps['clear'])
    parser.add_argument('-o', '--output-dir', metavar='path',
                        action='store', dest='output_dir',
                        default='output', help=helps['output_dir'])
    parser.add_argument('mesh_filename', default='',
                        help=helps['mesh_filename'])
    options = parser.parse_args()

    output_dir = options.output_dir

    output.set_output(filename=os.path.join(output_dir,'output_log.txt'),
                      combined=options.silent == False)

    if options.conf is not None:
        mod = import_file(options.conf)

    else:
        mod = sys.modules[__name__]

    apply_units = mod.apply_units
    define = mod.define
    set_wave_dir = mod.set_wave_dir
    setup_n_eigs = mod.setup_n_eigs
    build_evp_matrices = mod.build_evp_matrices
    save_materials = mod.save_materials
    get_std_wave_fun = mod.get_std_wave_fun
    get_stepper = mod.get_stepper
    process_evp_results = mod.process_evp_results

    options.pars = [float(ii) for ii in options.pars.split(',')]
    options.unit_multipliers = [float(ii)
                                for ii in options.unit_multipliers.split(',')]
    options.wave_dir = [float(ii)
                        for ii in options.wave_dir.split(',')]
    aux = options.range.split(',')
    options.range = [float(aux[0]), float(aux[1]), int(aux[2])]
    options.solver_conf = dict_from_string(options.solver_conf)

    if options.clear:
        remove_files_patterns(output_dir,
                              ['*.h5', '*.vtk', '*.txt'],
                              ignores=['output_log.txt'],
                              verbose=True)

    filename = os.path.join(output_dir, 'options.txt')
    ensure_path(filename)
    save_options(filename, [('options', vars(options))],
                 quote_command_line=True)

    pars = apply_units(options.pars, options.unit_multipliers)
    output('material parameters with applied unit multipliers:')
    output(pars)

    if options.mode == 'omega':
        rng = copy(options.range)
        rng[:2] = apply_unit_multipliers(options.range[:2],
                                         ['wave_number', 'wave_number'],
                                         options.unit_multipliers)
        output('wave number range with applied unit multipliers:', rng)

    else:
        rng = copy(options.range)
        rng[:2] = apply_unit_multipliers(options.range[:2],
                                         ['frequency', 'frequency'],
                                         options.unit_multipliers)
        output('frequency range with applied unit multipliers:', rng)

    pb, wdir, bzone, mtxs = assemble_matrices(define, mod, pars, set_wave_dir,
                                              options)
    dim = pb.domain.shape.dim

    if dim != 2:
        options.plane = 'strain'

    if options.save_regions:
        pb.save_regions_as_groups(os.path.join(output_dir, 'regions'))

    if options.save_materials:
        save_materials(output_dir, pb, options)

    conf = pb.solver_confs['eig']
    eig_solver = Solver.any_from_conf(conf)

    n_eigs, options.n_eigs = setup_n_eigs(options, pb, mtxs)

    get_color = lambda ii: plt.cm.viridis((float(ii) / (options.n_eigs - 1)))
    plot_kwargs = [{'color' : get_color(ii), 'ls' : '', 'marker' : 'o'}
                  for ii in range(options.n_eigs)]

    log_names = []
    log_plot_kwargs = []
    if options.log_std_waves:
        std_wave_fun, log_names, log_plot_kwargs = get_std_wave_fun(
            pb, options)

    else:
        std_wave_fun = None

    stepper = get_stepper(rng, pb, options)

    if options.mode == 'omega':
        eigenshapes_filename = os.path.join(output_dir,
                                            'frequency-eigenshapes-%s.vtk'
                                            % stepper.suffix)

        log = Log([[r'$\lambda_{%d}$' % ii for ii in range(options.n_eigs)],
                   [r'$\omega_{%d}$'
                    % ii for ii in range(options.n_eigs)] + log_names],
                  plot_kwargs=[plot_kwargs, plot_kwargs + log_plot_kwargs],
                  formats=[['{:.5e}'] * options.n_eigs,
                           ['{:.5e}'] * (options.n_eigs + len(log_names))],
                  yscales=['linear', 'linear'],
                  xlabels=[r'$\kappa$', r'$\kappa$'],
                  ylabels=[r'eigenvalues $\lambda_i$',
                           r'frequencies $\omega_i$'],
                  show_legends=options.show_legends,
                  is_plot=options.show,
                  log_filename=os.path.join(output_dir, 'frequencies.txt'),
                  aggregate=1000, sleep=0.1)

        for iv, wmag in stepper:
            output('step %d: wave vector %s' % (iv, wmag * wdir))

            evp_mtxs = build_evp_matrices(mtxs, wmag, options.mode, pb)

            if options.eigs_only:
                eigs = eig_solver(*evp_mtxs, n_eigs=n_eigs,
                                  eigenvectors=False)
                svecs = None

            else:
                eigs, svecs = eig_solver(*evp_mtxs, n_eigs=n_eigs,
                                         eigenvectors=True)

            omegas, svecs, out = process_evp_results(
                eigs, svecs, wmag, options.mode,
                wdir, bzone, pb, mtxs, std_wave_fun=std_wave_fun
            )
            log(*out, x=[wmag, wmag])

            save_eigenvectors(eigenshapes_filename % iv, svecs, wmag, wdir, pb)

            gc.collect()

        log(save_figure=os.path.join(output_dir, 'frequencies.png'))
        log(finished=True)

    else:
        eigenshapes_filename = os.path.join(output_dir,
                                            'wave-number-eigenshapes-%s.vtk'
                                            % stepper.suffix)

        log = Log([[r'$\kappa_{%d}$' % ii for ii in range(options.n_eigs)]
                   + log_names],
                  plot_kwargs=[plot_kwargs + log_plot_kwargs],
                  formats=[['{:.5e}'] * (options.n_eigs + len(log_names))],
                  yscales=['linear'],
                  xlabels=[r'$\omega$'],
                  ylabels=[r'wave numbers $\kappa_i$'],
                  show_legends=options.show_legends,
                  is_plot=options.show,
                  log_filename=os.path.join(output_dir, 'wave-numbers.txt'),
                  aggregate=1000, sleep=0.1)
        for io, omega in stepper:
            output('step %d: frequency %s' % (io, omega))

            evp_mtxs = build_evp_matrices(mtxs, omega, options.mode, pb)

            if options.eigs_only:
                eigs = eig_solver(*evp_mtxs, n_eigs=n_eigs,
                                  eigenvectors=False)
                svecs = None

            else:
                eigs, svecs = eig_solver(*evp_mtxs, n_eigs=n_eigs,
                                         eigenvectors=True)

            kappas, svecs, out = process_evp_results(
                eigs, svecs, omega, options.mode,
                wdir, bzone, pb, mtxs, std_wave_fun=std_wave_fun
            )
            log(*out, x=[omega])

            save_eigenvectors(eigenshapes_filename % io, svecs, kappas, wdir,
                              pb)

            gc.collect()

        log(save_figure=os.path.join(output_dir, 'wave-numbers.png'))
        log(finished=True)
Example #34
0
def main():
    # Aluminium and epoxy.
    default_pars = '70e9,0.35,2.799e3, 3.8e9,0.27,1.142e3'
    default_solver_conf = ("kind='eig.scipy',method='eigh',tol=1.0e-5,"
                           "maxiter=1000,which='LM',sigma=0.0")

    parser = ArgumentParser(description=__doc__,
                            formatter_class=RawDescriptionHelpFormatter)
    parser.add_argument('--pars',
                        metavar='young1,poisson1,density1'
                        ',young2,poisson2,density2',
                        action='store',
                        dest='pars',
                        default=default_pars,
                        help=helps['pars'])
    parser.add_argument('--conf',
                        metavar='filename',
                        action='store',
                        dest='conf',
                        default=None,
                        help=helps['conf'])
    parser.add_argument('--mesh-size',
                        type=float,
                        metavar='float',
                        action='store',
                        dest='mesh_size',
                        default=None,
                        help=helps['mesh_size'])
    parser.add_argument('--unit-multipliers',
                        metavar='c_time,c_length,c_mass',
                        action='store',
                        dest='unit_multipliers',
                        default='1.0,1.0,1.0',
                        help=helps['unit_multipliers'])
    parser.add_argument('--plane',
                        action='store',
                        dest='plane',
                        choices=['strain', 'stress'],
                        default='strain',
                        help=helps['plane'])
    parser.add_argument('--wave-dir',
                        metavar='float,float[,float]',
                        action='store',
                        dest='wave_dir',
                        default='1.0,0.0,0.0',
                        help=helps['wave_dir'])
    parser.add_argument('--mode',
                        action='store',
                        dest='mode',
                        choices=['omega', 'kappa'],
                        default='omega',
                        help=helps['mode'])
    parser.add_argument('--range',
                        metavar='start,stop,count',
                        action='store',
                        dest='range',
                        default='10,100,10',
                        help=helps['range'])
    parser.add_argument('--order',
                        metavar='int',
                        type=int,
                        action='store',
                        dest='order',
                        default=1,
                        help=helps['order'])
    parser.add_argument('--refine',
                        metavar='int',
                        type=int,
                        action='store',
                        dest='refine',
                        default=0,
                        help=helps['refine'])
    parser.add_argument('-n',
                        '--n-eigs',
                        metavar='int',
                        type=int,
                        action='store',
                        dest='n_eigs',
                        default=6,
                        help=helps['n_eigs'])
    parser.add_argument('--eigs-only',
                        action='store_true',
                        dest='eigs_only',
                        default=False,
                        help=helps['eigs_only'])
    parser.add_argument('--solver-conf',
                        metavar='dict-like',
                        action='store',
                        dest='solver_conf',
                        default=default_solver_conf,
                        help=helps['solver_conf'])
    parser.add_argument('--save-materials',
                        action='store_true',
                        dest='save_materials',
                        default=False,
                        help=helps['save_materials'])
    parser.add_argument('--log-std-waves',
                        action='store_true',
                        dest='log_std_waves',
                        default=False,
                        help=helps['log_std_waves'])
    parser.add_argument('--silent',
                        action='store_true',
                        dest='silent',
                        default=False,
                        help=helps['silent'])
    parser.add_argument('-c',
                        '--clear',
                        action='store_true',
                        dest='clear',
                        default=False,
                        help=helps['clear'])
    parser.add_argument('-o',
                        '--output-dir',
                        metavar='path',
                        action='store',
                        dest='output_dir',
                        default='output',
                        help=helps['output_dir'])
    parser.add_argument('mesh_filename',
                        default='',
                        help=helps['mesh_filename'])
    options = parser.parse_args()

    output_dir = options.output_dir

    output.set_output(filename=os.path.join(output_dir, 'output_log.txt'),
                      combined=options.silent == False)

    if options.conf is not None:
        mod = import_file(options.conf)
        apply_units = mod.apply_units
        define = mod.define
        set_wave_dir = mod.set_wave_dir

    else:
        apply_units = apply_units_le
        define = define_le
        set_wave_dir = set_wave_dir_le

    options.pars = [float(ii) for ii in options.pars.split(',')]
    options.unit_multipliers = [
        float(ii) for ii in options.unit_multipliers.split(',')
    ]
    options.wave_dir = [float(ii) for ii in options.wave_dir.split(',')]
    aux = options.range.split(',')
    options.range = [float(aux[0]), float(aux[1]), int(aux[2])]
    options.solver_conf = dict_from_string(options.solver_conf)

    if options.clear:
        remove_files_patterns(output_dir, ['*.h5', '*.vtk', '*.txt'],
                              ignores=['output_log.txt'],
                              verbose=True)

    filename = os.path.join(output_dir, 'options.txt')
    ensure_path(filename)
    save_options(filename, [('options', vars(options))])

    pars = apply_units(options.pars, options.unit_multipliers)
    output('material parameters with applied unit multipliers:')
    output(pars)

    if options.mode == 'omega':
        rng = copy(options.range)
        rng[:2] = apply_unit_multipliers(options.range[:2],
                                         ['wave_number', 'wave_number'],
                                         options.unit_multipliers)
        output('wave number range with applied unit multipliers:', rng)

    else:
        rng = copy(options.range)
        rng[:2] = apply_unit_multipliers(options.range[:2],
                                         ['frequency', 'frequency'],
                                         options.unit_multipliers)
        output('frequency range with applied unit multipliers:', rng)

    define_problem = functools.partial(define,
                                       filename_mesh=options.mesh_filename,
                                       pars=pars,
                                       approx_order=options.order,
                                       refinement_level=options.refine,
                                       solver_conf=options.solver_conf,
                                       plane=options.plane)

    conf = ProblemConf.from_dict(define_problem(), sys.modules[__name__])

    pb = Problem.from_conf(conf)
    dim = pb.domain.shape.dim

    if dim != 2:
        options.plane = 'strain'

    wdir = nm.asarray(options.wave_dir[:dim], dtype=nm.float64)
    wdir = wdir / nm.linalg.norm(wdir)

    stepper = TimeStepper(rng[0], rng[1], dt=None, n_step=rng[2])

    bbox = pb.domain.mesh.get_bounding_box()
    size = (bbox[1] - bbox[0]).max()
    scaling0 = apply_unit_multipliers([1.0], ['length'],
                                      options.unit_multipliers)[0]
    scaling = scaling0
    if options.mesh_size is not None:
        scaling *= options.mesh_size / size
    output('scaling factor of periodic cell mesh coordinates:', scaling)
    output('new mesh size with applied unit multipliers:', scaling * size)
    pb.domain.mesh.coors[:] *= scaling
    pb.set_mesh_coors(pb.domain.mesh.coors, update_fields=True)

    bzone = 2.0 * nm.pi / (scaling * size)
    output('1. Brillouin zone size:', bzone * scaling0)
    output('1. Brillouin zone size with applied unit multipliers:', bzone)

    pb.time_update()
    pb.update_materials()

    if options.save_materials or options.log_std_waves:
        stiffness = pb.evaluate('ev_integrate_mat.2.Omega(m.D, u)',
                                mode='el_avg',
                                copy_materials=False,
                                verbose=False)
        young, poisson = mc.youngpoisson_from_stiffness(stiffness,
                                                        plane=options.plane)
        density = pb.evaluate('ev_integrate_mat.2.Omega(m.density, u)',
                              mode='el_avg',
                              copy_materials=False,
                              verbose=False)

    if options.save_materials:
        out = {}
        out['young'] = Struct(name='young',
                              mode='cell',
                              data=young[..., None, None])
        out['poisson'] = Struct(name='poisson',
                                mode='cell',
                                data=poisson[..., None, None])
        out['density'] = Struct(name='density', mode='cell', data=density)
        materials_filename = os.path.join(output_dir, 'materials.vtk')
        pb.save_state(materials_filename, out=out)

    # Set the normalized wave vector direction to the material(s).
    set_wave_dir(pb.get_materials(), wdir)

    conf = pb.solver_confs['eig']
    eig_solver = Solver.any_from_conf(conf)

    # Assemble the matrices.
    mtx_m = pb.mtx_a.copy()
    eq_m = pb.equations['M']
    mtx_m = eq_m.evaluate(mode='weak', dw_mode='matrix', asm_obj=mtx_m)
    mtx_m.eliminate_zeros()

    mtx_k = pb.mtx_a.copy()
    eq_k = pb.equations['K']
    mtx_k = eq_k.evaluate(mode='weak', dw_mode='matrix', asm_obj=mtx_k)
    mtx_k.eliminate_zeros()

    mtx_s = pb.mtx_a.copy()
    eq_s = pb.equations['S']
    mtx_s = eq_s.evaluate(mode='weak', dw_mode='matrix', asm_obj=mtx_s)
    mtx_s.eliminate_zeros()

    mtx_r = pb.mtx_a.copy()
    eq_r = pb.equations['R']
    mtx_r = eq_r.evaluate(mode='weak', dw_mode='matrix', asm_obj=mtx_r)
    mtx_r.eliminate_zeros()

    output('symmetry checks of real blocks:')
    output('M - M^T:', _max_diff_csr(mtx_m, mtx_m.T))
    output('K - K^T:', _max_diff_csr(mtx_k, mtx_k.T))
    output('S - S^T:', _max_diff_csr(mtx_s, mtx_s.T))
    output('R + R^T:', _max_diff_csr(mtx_r, -mtx_r.T))

    n_eigs = options.n_eigs
    if options.n_eigs > mtx_k.shape[0]:
        options.n_eigs = mtx_k.shape[0]
        n_eigs = None

    if options.mode == 'omega':
        eigenshapes_filename = os.path.join(
            output_dir, 'frequency-eigenshapes-%s.vtk' % stepper.suffix)

        extra = []
        extra_plot_kwargs = []
        if options.log_std_waves:
            lam, mu = mc.lame_from_youngpoisson(young,
                                                poisson,
                                                plane=options.plane)
            alam = nm.average(lam)
            amu = nm.average(mu)
            adensity = nm.average(density)

            cp = nm.sqrt((alam + 2.0 * amu) / adensity)
            cs = nm.sqrt(amu / adensity)
            output('average p-wave speed:', cp)
            output('average shear wave speed:', cs)

            extra = [r'$\omega_p$', r'$\omega_s$']
            extra_plot_kwargs = [{
                'ls': '--',
                'color': 'k'
            }, {
                'ls': '--',
                'color': 'gray'
            }]

        log = Log(
            [[r'$\lambda_{%d}$' % ii for ii in range(options.n_eigs)],
             [r'$\omega_{%d}$' % ii for ii in range(options.n_eigs)] + extra],
            plot_kwargs=[{}, [{}] * options.n_eigs + extra_plot_kwargs],
            yscales=['linear', 'linear'],
            xlabels=[r'$\kappa$', r'$\kappa$'],
            ylabels=[r'eigenvalues $\lambda_i$', r'frequencies $\omega_i$'],
            log_filename=os.path.join(output_dir, 'frequencies.txt'),
            aggregate=1000,
            sleep=0.1)

        for iv, wmag in stepper:
            output('step %d: wave vector %s' % (iv, wmag * wdir))

            mtx_a = mtx_k + wmag**2 * mtx_s + (1j * wmag) * mtx_r
            mtx_b = mtx_m

            output('A - A^H:', _max_diff_csr(mtx_a, mtx_a.H))

            if options.eigs_only:
                eigs = eig_solver(mtx_a,
                                  mtx_b,
                                  n_eigs=n_eigs,
                                  eigenvectors=False)
                svecs = None

            else:
                eigs, svecs = eig_solver(mtx_a,
                                         mtx_b,
                                         n_eigs=options.n_eigs,
                                         eigenvectors=True)
            omegas = nm.sqrt(eigs)

            output('eigs, omegas:\n', nm.c_[eigs, omegas])

            out = tuple(eigs) + tuple(omegas)
            if options.log_std_waves:
                out = out + (cp * wmag, cs * wmag)
            log(*out, x=[wmag, wmag])

            save_eigenvectors(eigenshapes_filename % iv, svecs, pb)

        log(save_figure=os.path.join(output_dir, 'frequencies.png'))
        log(finished=True)

    else:
        import scipy.sparse as sps
        from sksparse.cholmod import cholesky

        eigenshapes_filename = os.path.join(
            output_dir, 'wave-number-eigenshapes-%s.vtk' % stepper.suffix)

        factor = cholesky(mtx_s)
        perm = factor.P()
        ir = nm.arange(len(perm))
        mtx_p = sps.coo_matrix((nm.ones_like(perm), (ir, perm)))
        mtx_l = mtx_p.T * factor.L()
        mtx_eye = sps.eye(mtx_l.shape[0], dtype=nm.float64)

        output('S - LL^T:', _max_diff_csr(mtx_s, mtx_l * mtx_l.T))

        log = Log([[r'$\kappa_{%d}$' % ii for ii in range(options.n_eigs)]],
                  plot_kwargs=[{
                      'ls': 'None',
                      'marker': 'o'
                  }],
                  yscales=['linear'],
                  xlabels=[r'$\omega$'],
                  ylabels=[r'wave numbers $\kappa_i$'],
                  log_filename=os.path.join(output_dir, 'wave-numbers.txt'),
                  aggregate=1000,
                  sleep=0.1)
        for io, omega in stepper:
            output('step %d: frequency %s' % (io, omega))

            mtx_a = sps.bmat([[mtx_k - omega**2 * mtx_m, None],
                              [None, mtx_eye]])
            mtx_b = sps.bmat([[1j * mtx_r, mtx_l], [mtx_l.T, None]])

            output('A - A^T:', _max_diff_csr(mtx_a, mtx_a.T))
            output('A - A^H:', _max_diff_csr(mtx_a, mtx_a.T))
            output('B - B^H:', _max_diff_csr(mtx_b, mtx_b.H))

            if options.eigs_only:
                eigs = eig_solver(mtx_a,
                                  mtx_b,
                                  n_eigs=n_eigs,
                                  eigenvectors=False)
                svecs = None

            else:
                eigs, svecs = eig_solver(mtx_a,
                                         mtx_b,
                                         n_eigs=options.n_eigs,
                                         eigenvectors=True)
            kappas = eigs

            output('kappas:\n', kappas[:, None])

            out = tuple(kappas)
            log(*out, x=[omega])

            save_eigenvectors(eigenshapes_filename % io, svecs, pb)

        log(save_figure=os.path.join(output_dir, 'wave-numbers.png'))
        log(finished=True)
Example #35
0
    def test_semismooth_newton(self):
        import numpy as nm
        from sfepy.solvers import Solver

        ns = [0, 6, 2, 2]

        offsets = nm.cumsum(ns)
        nx = offsets[-1]

        iw = slice(offsets[0], offsets[1])
        ig = slice(offsets[1], offsets[2])
        il = slice(offsets[2], offsets[3])

        def fun_smooth(vec_x):
            xw = vec_x[iw]
            xg = vec_x[ig]
            xl = vec_x[il]

            m = self.ms
            rw = m['A'] * xw - m['Bb'].T * xg - self.m['fs']
            rg = m['Bb'] * xw + xl * xg

            rwg = nm.r_[rw, rg]

            return rwg

        def fun_smooth_grad(vec_x):
            xw = vec_x[iw]
            xl = vec_x[il]
            xg = vec_x[ig]

            m = self.m

            mzl = nm.zeros((6, 2), dtype=nm.float64)

            mw = nm.c_[m['A'], -m['Bb'].T, mzl]
            mg = nm.c_[m['Bb'], nm.diag(xl), nm.diag(xg)]

            mx = nm.r_[mw, mg]

            mx = sps.csr_matrix(mx)
            return mx

        def fun_a(vec_x):
            xw = vec_x[iw]
            xg = vec_x[ig]

            subsd = {}
            for ii, key in enumerate(self.w_names):
                subsd[key] = xw[ii]

            sn = eval_matrix(self.m['sn'], **subsd).squeeze()

            ra = nm.abs(xg) - fc * nm.abs(sn)

            return -ra

        def fun_a_grad(vec_x):
            xw = vec_x[iw]
            xg = vec_x[ig]
            xl = vec_x[il]

            subsd = {}
            for ii, key in enumerate(self.w_names):
                subsd[key] = xw[ii]

            md = eval_matrix(self.m['D'], **subsd)
            sn = eval_matrix(self.m['sn'], **subsd).squeeze()

            ma = nm.zeros((xl.shape[0], nx), dtype=nm.float64)
            ma[:, iw] = -fc * nm.sign(sn)[:, None] * md
            ma[:, ig] = nm.sign(xg)[:, None] * self.m['C']

            return -sps.csr_matrix(ma)

        def fun_b(vec_x):
            xl = vec_x[il]

            return xl

        def fun_b_grad(vec_x):
            xl = vec_x[il]

            mb = nm.zeros((xl.shape[0], nx), dtype=nm.float64)
            mb[:, il] = self.m['C']

            return sps.csr_matrix(mb)

        vec_x0 = 0.1 * nm.ones((nx, ), dtype=nm.float64)

        lin_solver = Solver.any_from_conf(dict_to_struct(ls_conf))
        status = {}
        solver = Solver.any_from_conf(dict_to_struct(conf),
                                      fun_smooth=fun_smooth,
                                      fun_smooth_grad=fun_smooth_grad,
                                      fun_a=fun_a,
                                      fun_a_grad=fun_a_grad,
                                      fun_b=fun_b,
                                      fun_b_grad=fun_b_grad,
                                      lin_solver=lin_solver,
                                      status=status)

        vec_x = solver(vec_x0)

        xw = vec_x[iw]
        xg = vec_x[ig]
        xl = vec_x[il]

        self.report('x:', xw)
        self.report('g:', xg)
        self.report('l:', xl)

        subsd = {}
        for ii, key in enumerate(self.w_names):
            subsd[key] = xw[ii]

        sn = eval_matrix(self.m['sn'], **subsd).squeeze()
        self.report('sn:', sn)

        ok = status['condition'] == 0

        return ok
Example #36
0
def setup_precond(mtx, problem):
    """
    Setup a preconditioner for `mtx`.
    """
    import scipy.sparse.linalg as spla
    from sfepy.solvers import Solver

    # Get active DOF indices for u, p.
    adi = problem.get_variables().adi
    iu = adi.indx['u']
    ip = adi.indx['p']

    # Get the diagonal blocks of the linear system matrix.
    K = mtx[iu, iu]
    M = mtx[ip, ip]

    # Create solvers for K, M blocks to be used in matvec_bj(). A different
    # solver for each block could be used.
    conf = problem.solver_confs['direct']
    # conf = problem.solver_confs['cg-s']
    # conf = problem.solver_confs['cg-p']
    # conf = problem.solver_confs['pyamg']
    ls1 = Solver.any_from_conf(conf, mtx=K, context=problem)
    ls2 = Solver.any_from_conf(conf, mtx=M, context=problem)

    def matvec_bj(vec):
        """
        The application of the Block Jacobi preconditioner.

        The exact version (as with the `'direct'` solver) can be obtained also
        by using the following PETSs command-line options, together with the
        `'iterative-p'` solver::

          -ksp_monitor -pc_type fieldsplit -pc_fieldsplit_type additive -fieldsplit_u_ksp_type preonly -fieldsplit_u_pc_type lu -fieldsplit_p_ksp_type preonly -fieldsplit_p_pc_type lu

        The inexact version (20 iterations of a CG solver for each block, as
        with the `'cg-s'` or `'cg-p'` solvers) can be obtained also by using
        the following PETSs command-line options, together with the
        `'iterative-p'` solver::

          -ksp_monitor -pc_type fieldsplit -pc_fieldsplit_type additive -fieldsplit_u_ksp_type cg -fieldsplit_u_pc_type none -fieldsplit_p_ksp_type cg -fieldsplit_p_pc_type none -fieldsplit_u_ksp_max_it 20 -fieldsplit_p_ksp_max_it 20
        """
        vu = ls1(vec[iu])
        vp = ls2(vec[ip])

        return nm.r_[vu, vp]

    def matvec_j(vec):
        """
        The application of the Jacobi (diagonal) preconditioner.

        The same effect can be obtained also by using the following PETSs
        command-line options, together with the `'iterative-p'` solver::

          -ksp_monitor -pc_type jacobi
        """
        D = mtx.diagonal()

        return vec / D

    # Create the preconditioner, using one of matvec_bj() or matvec_j().
    precond = Struct(name='precond', shape=mtx.shape, matvec=matvec_bj)
    precond = spla.aslinearoperator(precond)

    return precond
Example #37
0
def main():
    # Aluminium and epoxy.
    default_pars = '70e9,0.35,2.799e3, 3.8e9,0.27,1.142e3'
    default_solver_conf = ("kind='eig.scipy',method='eigsh',tol=1.0e-5,"
                           "maxiter=1000,which='LM',sigma=0.0")

    parser = ArgumentParser(description=__doc__,
                            formatter_class=RawDescriptionHelpFormatter)
    parser.add_argument('--pars', metavar='young1,poisson1,density1'
                        ',young2,poisson2,density2',
                        action='store', dest='pars',
                        default=default_pars, help=helps['pars'])
    parser.add_argument('--conf', metavar='filename',
                        action='store', dest='conf',
                        default=None, help=helps['conf'])
    parser.add_argument('--define-kwargs', metavar='dict-like',
                        action='store', dest='define_kwargs',
                        default=None, help=helps['define_kwargs'])
    parser.add_argument('--mesh-size', type=float, metavar='float',
                        action='store', dest='mesh_size',
                        default=None, help=helps['mesh_size'])
    parser.add_argument('--unit-multipliers',
                        metavar='c_time,c_length,c_mass',
                        action='store', dest='unit_multipliers',
                        default='1.0,1.0,1.0', help=helps['unit_multipliers'])
    parser.add_argument('--plane', action='store', dest='plane',
                        choices=['strain', 'stress'],
                        default='strain', help=helps['plane'])
    parser.add_argument('--wave-dir', metavar='float,float[,float]',
                        action='store', dest='wave_dir',
                        default='1.0,0.0,0.0', help=helps['wave_dir'])
    parser.add_argument('--mode', action='store', dest='mode',
                        choices=['omega', 'kappa'],
                        default='omega', help=helps['mode'])
    parser.add_argument('--stepper', action='store', dest='stepper',
                        choices=['linear', 'brillouin'],
                        default='linear', help=helps['stepper'])
    parser.add_argument('--range', metavar='start,stop,count',
                        action='store', dest='range',
                        default='0,6.4,33', help=helps['range'])
    parser.add_argument('--order', metavar='int', type=int,
                        action='store', dest='order',
                        default=1, help=helps['order'])
    parser.add_argument('--refine', metavar='int', type=int,
                        action='store', dest='refine',
                        default=0, help=helps['refine'])
    parser.add_argument('-n', '--n-eigs', metavar='int', type=int,
                        action='store', dest='n_eigs',
                        default=6, help=helps['n_eigs'])
    group = parser.add_mutually_exclusive_group()
    group.add_argument('--eigs-only',
                       action='store_true', dest='eigs_only',
                       default=False, help=helps['eigs_only'])
    group.add_argument('--post-process',
                       action='store_true', dest='post_process',
                       default=False, help=helps['post_process'])
    parser.add_argument('--solver-conf', metavar='dict-like',
                        action='store', dest='solver_conf',
                        default=default_solver_conf, help=helps['solver_conf'])
    parser.add_argument('--save-regions',
                        action='store_true', dest='save_regions',
                        default=False, help=helps['save_regions'])
    parser.add_argument('--save-materials',
                        action='store_true', dest='save_materials',
                        default=False, help=helps['save_materials'])
    parser.add_argument('--log-std-waves',
                        action='store_true', dest='log_std_waves',
                        default=False, help=helps['log_std_waves'])
    parser.add_argument('--no-legends',
                        action='store_false', dest='show_legends',
                        default=True, help=helps['no_legends'])
    parser.add_argument('--no-show',
                        action='store_false', dest='show',
                        default=True, help=helps['no_show'])
    parser.add_argument('--silent',
                        action='store_true', dest='silent',
                        default=False, help=helps['silent'])
    parser.add_argument('-c', '--clear',
                        action='store_true', dest='clear',
                        default=False, help=helps['clear'])
    parser.add_argument('-o', '--output-dir', metavar='path',
                        action='store', dest='output_dir',
                        default='output', help=helps['output_dir'])
    parser.add_argument('mesh_filename', default='',
                        help=helps['mesh_filename'])
    options = parser.parse_args()

    output_dir = options.output_dir

    output.set_output(filename=os.path.join(output_dir,'output_log.txt'),
                      combined=options.silent == False)

    if options.conf is not None:
        mod = import_file(options.conf)

    else:
        mod = sys.modules[__name__]

    apply_units = mod.apply_units
    define = mod.define
    set_wave_dir = mod.set_wave_dir
    setup_n_eigs = mod.setup_n_eigs
    build_evp_matrices = mod.build_evp_matrices
    save_materials = mod.save_materials
    get_std_wave_fun = mod.get_std_wave_fun
    get_stepper = mod.get_stepper
    process_evp_results = mod.process_evp_results

    options.pars = [float(ii) for ii in options.pars.split(',')]
    options.unit_multipliers = [float(ii)
                                for ii in options.unit_multipliers.split(',')]
    options.wave_dir = [float(ii)
                        for ii in options.wave_dir.split(',')]
    aux = options.range.split(',')
    options.range = [float(aux[0]), float(aux[1]), int(aux[2])]
    options.solver_conf = dict_from_string(options.solver_conf)
    options.define_kwargs = dict_from_string(options.define_kwargs)

    if options.clear:
        remove_files_patterns(output_dir,
                              ['*.h5', '*.vtk', '*.txt'],
                              ignores=['output_log.txt'],
                              verbose=True)

    filename = os.path.join(output_dir, 'options.txt')
    ensure_path(filename)
    save_options(filename, [('options', vars(options))],
                 quote_command_line=True)

    pars = apply_units(options.pars, options.unit_multipliers)
    output('material parameters with applied unit multipliers:')
    output(pars)

    if options.mode == 'omega':
        rng = copy(options.range)
        rng[:2] = apply_unit_multipliers(options.range[:2],
                                         ['wave_number', 'wave_number'],
                                         options.unit_multipliers)
        output('wave number range with applied unit multipliers:', rng)

    else:
        if options.stepper == 'brillouin':
            raise ValueError('Cannot use "brillouin" stepper in kappa mode!')

        rng = copy(options.range)
        rng[:2] = apply_unit_multipliers(options.range[:2],
                                         ['frequency', 'frequency'],
                                         options.unit_multipliers)
        output('frequency range with applied unit multipliers:', rng)

    pb, wdir, bzone, mtxs = assemble_matrices(define, mod, pars, set_wave_dir,
                                              options)
    dim = pb.domain.shape.dim

    if dim != 2:
        options.plane = 'strain'

    if options.save_regions:
        pb.save_regions_as_groups(os.path.join(output_dir, 'regions'))

    if options.save_materials:
        save_materials(output_dir, pb, options)

    conf = pb.solver_confs['eig']
    eig_solver = Solver.any_from_conf(conf)

    n_eigs, options.n_eigs = setup_n_eigs(options, pb, mtxs)

    get_color = lambda ii: plt.cm.viridis((float(ii) / (options.n_eigs - 1)))
    plot_kwargs = [{'color' : get_color(ii), 'ls' : '', 'marker' : 'o'}
                  for ii in range(options.n_eigs)]
    get_color_dim = lambda ii: plt.cm.viridis((float(ii) / (dim-1)))
    plot_kwargs_dim = [{'color' : get_color_dim(ii), 'ls' : '', 'marker' : 'o'}
                       for ii in range(dim)]

    log_names = []
    log_plot_kwargs = []
    if options.log_std_waves:
        std_wave_fun, log_names, log_plot_kwargs = get_std_wave_fun(
            pb, options)

    else:
        std_wave_fun = None

    stepper = get_stepper(rng, pb, options)

    if options.mode == 'omega':
        eigenshapes_filename = os.path.join(output_dir,
                                            'frequency-eigenshapes-%s.vtk'
                                            % stepper.suffix)

        if options.stepper == 'linear':
            log = Log([[r'$\lambda_{%d}$' % ii for ii in range(options.n_eigs)],
                   [r'$\omega_{%d}$'
                    % ii for ii in range(options.n_eigs)] + log_names],
                  plot_kwargs=[plot_kwargs, plot_kwargs + log_plot_kwargs],
                  formats=[['{:.5e}'] * options.n_eigs,
                           ['{:.5e}'] * (options.n_eigs + len(log_names))],
                  yscales=['linear', 'linear'],
                  xlabels=[r'$\kappa$', r'$\kappa$'],
                  ylabels=[r'eigenvalues $\lambda_i$',
                           r'frequencies $\omega_i$'],
                  show_legends=options.show_legends,
                  is_plot=options.show,
                  log_filename=os.path.join(output_dir, 'frequencies.txt'),
                  aggregate=1000, sleep=0.1)

        else:
            log = Log([[r'$\kappa_{%d}$'% ii for ii in range(dim)],
                       [r'$\omega_{%d}$'
                        % ii for ii in range(options.n_eigs)] + log_names],
                      plot_kwargs=[plot_kwargs_dim,
                                   plot_kwargs + log_plot_kwargs],
                      formats=[['{:.5e}'] * dim,
                               ['{:.5e}'] * (options.n_eigs + len(log_names))],
                      yscales=['linear', 'linear'],
                      xlabels=[r'', r''],
                      ylabels=[r'wave vector $\kappa$',
                               r'frequencies $\omega_i$'],
                      show_legends=options.show_legends,
                      is_plot=options.show,
                      log_filename=os.path.join(output_dir, 'frequencies.txt'),
                      aggregate=1000, sleep=0.1)

        for aux in stepper:
            if options.stepper == 'linear':
                iv, wmag = aux

            else:
                iv, wmag, wdir = aux

            output('step %d: wave vector %s' % (iv, wmag * wdir))

            if options.stepper == 'brillouin':
                pb, _, bzone, mtxs = assemble_matrices(
                    define, mod, pars, set_wave_dir, options, wdir=wdir)

            evp_mtxs = build_evp_matrices(mtxs, wmag, options.mode, pb)

            if options.eigs_only:
                eigs = eig_solver(*evp_mtxs, n_eigs=n_eigs,
                                  eigenvectors=False)
                svecs = None

            else:
                eigs, svecs = eig_solver(*evp_mtxs, n_eigs=n_eigs,
                                         eigenvectors=True)

            omegas, svecs, out = process_evp_results(
                eigs, svecs, wmag, wdir, bzone, pb, mtxs, options,
                std_wave_fun=std_wave_fun
            )
            if options.stepper == 'linear':
                log(*out, x=[wmag, wmag])

            else:
                log(*out, x=[iv, iv])

            save_eigenvectors(eigenshapes_filename % iv, svecs, wmag, wdir, pb)

            gc.collect()

        log(save_figure=os.path.join(output_dir, 'frequencies.png'))
        log(finished=True)

    else:
        eigenshapes_filename = os.path.join(output_dir,
                                            'wave-number-eigenshapes-%s.vtk'
                                            % stepper.suffix)

        log = Log([[r'$\kappa_{%d}$' % ii for ii in range(options.n_eigs)]
                   + log_names],
                  plot_kwargs=[plot_kwargs + log_plot_kwargs],
                  formats=[['{:.5e}'] * (options.n_eigs + len(log_names))],
                  yscales=['linear'],
                  xlabels=[r'$\omega$'],
                  ylabels=[r'wave numbers $\kappa_i$'],
                  show_legends=options.show_legends,
                  is_plot=options.show,
                  log_filename=os.path.join(output_dir, 'wave-numbers.txt'),
                  aggregate=1000, sleep=0.1)
        for io, omega in stepper:
            output('step %d: frequency %s' % (io, omega))

            evp_mtxs = build_evp_matrices(mtxs, omega, options.mode, pb)

            if options.eigs_only:
                eigs = eig_solver(*evp_mtxs, n_eigs=n_eigs,
                                  eigenvectors=False)
                svecs = None

            else:
                eigs, svecs = eig_solver(*evp_mtxs, n_eigs=n_eigs,
                                         eigenvectors=True)

            kappas, svecs, out = process_evp_results(
                eigs, svecs, omega, wdir, bzone, pb, mtxs, options,
                std_wave_fun=std_wave_fun
            )
            log(*out, x=[omega])

            save_eigenvectors(eigenshapes_filename % io, svecs, kappas, wdir,
                              pb)

            gc.collect()

        log(save_figure=os.path.join(output_dir, 'wave-numbers.png'))
        log(finished=True)
def main():
    parser = ArgumentParser(description=__doc__,
                            formatter_class=RawDescriptionHelpFormatter)
    parser.add_argument('--version', action='version', version='%(prog)s')
    parser.add_argument('-d',
                        '--dims',
                        metavar='dims',
                        action='store',
                        dest='dims',
                        default='[1.0, 1.0]',
                        help=helps['dims'])
    parser.add_argument('-c',
                        '--centre',
                        metavar='centre',
                        action='store',
                        dest='centre',
                        default='[0.0, 0.0]',
                        help=helps['centre'])
    parser.add_argument('-s',
                        '--shape',
                        metavar='shape',
                        action='store',
                        dest='shape',
                        default='[11, 11]',
                        help=helps['shape'])
    parser.add_argument('-b',
                        '--bc-kind',
                        metavar='kind',
                        action='store',
                        dest='bc_kind',
                        choices=['free', 'cantilever', 'fixed'],
                        default='free',
                        help=helps['bc_kind'])
    parser.add_argument('-a',
                        '--axis',
                        metavar='0, ..., dim, or -1',
                        type=int,
                        action='store',
                        dest='axis',
                        default=-1,
                        help=helps['axis'])
    parser.add_argument('--young',
                        metavar='float',
                        type=float,
                        action='store',
                        dest='young',
                        default=200e+9,
                        help=helps['young'])
    parser.add_argument('--poisson',
                        metavar='float',
                        type=float,
                        action='store',
                        dest='poisson',
                        default=0.3,
                        help=helps['poisson'])
    parser.add_argument('--density',
                        metavar='float',
                        type=float,
                        action='store',
                        dest='density',
                        default=7800.0,
                        help=helps['density'])
    parser.add_argument('--order',
                        metavar='int',
                        type=int,
                        action='store',
                        dest='order',
                        default=1,
                        help=helps['order'])
    parser.add_argument('-n',
                        '--n-eigs',
                        metavar='int',
                        type=int,
                        action='store',
                        dest='n_eigs',
                        default=6,
                        help=helps['n_eigs'])
    parser.add_argument('-i',
                        '--ignore',
                        metavar='int',
                        type=int,
                        action='store',
                        dest='ignore',
                        default=None,
                        help=helps['ignore'])
    parser.add_argument('--solver', metavar='solver', action='store',
                        dest='solver',
                        default= \
                        "eig.scipy,method:'eigh',tol:1e-5,maxiter:1000",
                        help=helps['solver'])
    parser.add_argument('--show',
                        action="store_true",
                        dest='show',
                        default=False,
                        help=helps['show'])
    #parser.add_argument('filename', nargs='?', default=None)
    #read block.mesh
    #parser.add_argument('filename', nargs='?', default="platehexat200mm.mesh")
    parser.add_argument('filename', nargs='?', default="block_1m.mesh")
    options = parser.parse_args()

    aux = options.solver.split(',')
    kwargs = {}
    for option in aux[1:]:
        key, val = option.split(':')
        kwargs[key.strip()] = eval(val)
    eig_conf = Struct(name='evp', kind=aux[0], **kwargs)

    output('using values:')
    output("  Young's modulus:", options.young)
    output("  Poisson's ratio:", options.poisson)
    output('  density:', options.density)
    output('displacement field approximation order:', options.order)
    output('requested %d eigenvalues' % options.n_eigs)
    output('using eigenvalue problem solver:', eig_conf.kind)
    output.level += 1
    for key, val in six.iteritems(kwargs):
        output('%s: %r' % (key, val))
    output.level -= 1

    assert_((0.0 < options.poisson < 0.5),
            "Poisson's ratio must be in ]0, 0.5[!")
    assert_((0 < options.order),
            'displacement approximation order must be at least 1!')

    filename = options.filename
    if filename is not None:
        mesh = Mesh.from_file(filename)
        dim = mesh.dim
        dims = nm.diff(mesh.get_bounding_box(), axis=0)

    else:
        dims = nm.array(eval(options.dims), dtype=nm.float64)
        dim = len(dims)

        centre = nm.array(eval(options.centre), dtype=nm.float64)[:dim]
        shape = nm.array(eval(options.shape), dtype=nm.int32)[:dim]

        output('dimensions:', dims)
        output('centre:    ', centre)
        output('shape:     ', shape)

        mesh = gen_block_mesh(dims, shape, centre, name='mesh')

    output('axis:      ', options.axis)
    assert_((-dim <= options.axis < dim), 'invalid axis value!')

    eig_solver = Solver.any_from_conf(eig_conf)

    # Build the problem definition.
    domain = FEDomain('domain', mesh)

    bbox = domain.get_mesh_bounding_box()
    min_coor, max_coor = bbox[:, options.axis]
    eps = 1e-8 * (max_coor - min_coor)
    ax = 'xyz'[:dim][options.axis]

    omega = domain.create_region('Omega', 'all')
    """
    bottom = domain.create_region('Bottom',
                                  'vertices in (%s < %.10f)'
                                  % (ax, min_coor + eps),
                                  'facet')

    bottom_top = domain.create_region('BottomTop',
                                      'r.Bottom +v vertices in (%s > %.10f)'
                                      % (ax, max_coor - eps),
                                      'facet')
    """
    #import pdb; pdb.set_trace()
    left = domain.create_region('left', 'vertices in (x < -0.49)', 'facet')

    field = Field.from_args('fu',
                            nm.float64,
                            'vector',
                            omega,
                            approx_order=options.order)

    u = FieldVariable('u', 'unknown', field)
    v = FieldVariable('v', 'test', field, primary_var_name='u')

    mtx_d = stiffness_from_youngpoisson(dim, options.young, options.poisson)

    m = Material('m', D=mtx_d, rho=options.density)

    integral = Integral('i', order=2 * options.order)

    t1 = Term.new('dw_lin_elastic(m.D, v, u)', integral, omega, m=m, v=v, u=u)
    t2 = Term.new('dw_volume_dot(m.rho, v, u)', integral, omega, m=m, v=v, u=u)
    eq1 = Equation('stiffness', t1)
    eq2 = Equation('mass', t2)
    lhs_eqs = Equations([eq1, eq2])

    pb = Problem('modal', equations=lhs_eqs)
    """
    if options.bc_kind == 'free':
        pb.time_update()
        n_rbm = dim * (dim + 1) // 2

    elif options.bc_kind == 'cantilever':
        fixed = EssentialBC('Fixed', bottom, {'u.all' : 0.0})
        pb.time_update(ebcs=Conditions([fixed]))
        n_rbm = 0

    elif options.bc_kind == 'fixed':
        fixed = EssentialBC('Fixed', bottom_top, {'u.all' : 0.0})
        pb.time_update(ebcs=Conditions([fixed]))
        n_rbm = 0

    else:
        raise ValueError('unsupported BC kind! (%s)' % options.bc_kind)

    if options.ignore is not None:
        n_rbm = options.ignore
    """
    fixed = EssentialBC('Fixed', left, {'u.all': 0.0})
    pb.time_update(ebcs=Conditions([fixed]))
    n_rbm = 0

    pb.update_materials()

    # Assemble stiffness and mass matrices.
    mtx_k = eq1.evaluate(mode='weak', dw_mode='matrix', asm_obj=pb.mtx_a)
    mtx_m = mtx_k.copy()
    mtx_m.data[:] = 0.0
    mtx_m = eq2.evaluate(mode='weak', dw_mode='matrix', asm_obj=mtx_m)

    try:
        eigs, svecs = eig_solver(mtx_k,
                                 mtx_m,
                                 options.n_eigs + n_rbm,
                                 eigenvectors=True)

    except sla.ArpackNoConvergence as ee:
        eigs = ee.eigenvalues
        svecs = ee.eigenvectors
        output('only %d eigenvalues converged!' % len(eigs))

    output('%d eigenvalues converged (%d ignored as rigid body modes)' %
           (len(eigs), n_rbm))

    eigs = eigs[n_rbm:]
    svecs = svecs[:, n_rbm:]

    omegas = nm.sqrt(eigs)
    freqs = omegas / (2 * nm.pi)

    output('number |         eigenvalue |  angular frequency '
           '|          frequency')
    for ii, eig in enumerate(eigs):
        output('%6d | %17.12e | %17.12e | %17.12e' %
               (ii + 1, eig, omegas[ii], freqs[ii]))

    # Make full eigenvectors (add DOFs fixed by boundary conditions).
    variables = pb.get_variables()

    vecs = nm.empty((variables.di.ptr[-1], svecs.shape[1]), dtype=nm.float64)
    for ii in range(svecs.shape[1]):
        vecs[:, ii] = variables.make_full_vec(svecs[:, ii])

    # Save the eigenvectors.
    out = {}
    state = pb.create_state()
    for ii in range(eigs.shape[0]):
        state.set_full(vecs[:, ii])
        aux = state.create_output_dict()
        strain = pb.evaluate('ev_cauchy_strain.i.Omega(u)',
                             integrals=Integrals([integral]),
                             mode='el_avg',
                             verbose=False)
        out['u%03d' % ii] = aux.popitem()[1]
        out['strain%03d' % ii] = Struct(mode='cell', data=strain)

    pb.save_state('eigenshapes.vtk', out=out)
    pb.save_regions_as_groups('regions')

    if len(eigs) and options.show:
        # Show the solution. If the approximation order is greater than 1, the
        # extra DOFs are simply thrown away.
        from sfepy.postprocess.viewer import Viewer
        from sfepy.postprocess.domain_specific import DomainSpecificPlot

        scaling = 0.05 * dims.max() / nm.abs(vecs).max()

        ds = {}
        for ii in range(eigs.shape[0]):
            pd = DomainSpecificPlot('plot_displacements', [
                'rel_scaling=%s' % scaling, 'color_kind="tensors"',
                'color_name="strain%03d"' % ii
            ])
            ds['u%03d' % ii] = pd

        view = Viewer('eigenshapes.vtk')
        view(domain_specific=ds,
             only_names=sorted(ds.keys()),
             is_scalar_bar=False,
             is_wireframe=True)
Example #39
0
aux = "eig.scipy,method:'eigh',tol:1e-7,maxiter:10000".split(',')
kwargs = {}
for option in aux[1:]:
    key, val = option.split(':')
    kwargs[key.strip()] = eval(val)
eig_conf = Struct(name='evp', kind=aux[0], **kwargs)

dims = nm.array([1.0, 1.5], dtype=nm.float64)
dim = len(dims)

centre = nm.array([0.0, 0.0], dtype=nm.float64)[:dim]
shape = nm.array([11, 16], dtype=nm.int32)[:dim]

mesh = gen_block_mesh(dims, shape, centre, name='mesh')

eig_solver = Solver.any_from_conf(eig_conf)

# Build the problem definition.
domain = FEDomain('domain', mesh)

bbox = domain.get_mesh_bounding_box()
min_coor, max_coor = bbox[:, -1]
eps = 1e-8 * (max_coor - min_coor)
ax = 'xyz'[:dim][-1]

omega = domain.create_region('Omega', 'all')
bottom = domain.create_region('Bottom', 'vertices in (%s < %.10f)' % (ax, min_coor + eps), 'facet')
bottom_top = domain.create_region('BottomTop', 'r.Bottom +v vertices in (%s > %.10f)' % (ax, max_coor - eps), 'facet')

field = Field.from_args('fu', nm.float64, 'vector', omega, approx_order=1)
Example #40
0
def solve_eigen_problem1( conf, options ):


    pb = ProblemDefinition.from_conf( conf )
    dim = pb.domain.mesh.dim

    pb.time_update()

    dummy = pb.create_state_vector()

    output( 'assembling lhs...' )
    tt = time.clock()
    mtx_a = eval_term_op( dummy, conf.equations['lhs'], pb,
                       dw_mode = 'matrix', tangent_matrix = pb.mtx_a )
    output( '...done in %.2f s' % (time.clock() - tt) )

    output( 'assembling rhs...' )
    tt = time.clock()
    mtx_b = eval_term_op( dummy, conf.equations['rhs'], pb,
                       dw_mode = 'matrix', tangent_matrix = pb.mtx_a.copy() )
    output( '...done in %.2f s' % (time.clock() - tt) )

    #mtxA.save( 'tmp/a.txt', format='%d %d %.12f\n' )
    #mtxB.save( 'tmp/b.txt', format='%d %d %.12f\n' )
    try:
        n_eigs = conf.options.n_eigs
    except AttributeError:
        n_eigs = mtx_a.shape[0]

    if n_eigs is None:
        n_eigs = mtx_a.shape[0]

##     mtx_a.save( 'a.txt', format='%d %d %.12f\n' )
##     mtx_b.save( 'b.txt', format='%d %d %.12f\n' )
    print 'computing resonance frequencies...'
    eig = Solver.any_from_conf( pb.get_solver_conf( conf.options.eigen_solver ) )
    eigs, mtx_s_phi = eig( mtx_a, mtx_b, conf.options.n_eigs )
    from sfepy.fem.mesh import Mesh
    bounding_box = Mesh.from_file("tmp/mesh.vtk").get_bounding_box()
    # this assumes a box (3D), or a square (2D):
    a = bounding_box[1][0] - bounding_box[0][0]
    E_exact = None
    if options.hydrogen or options.boron:
        if options.hydrogen:
            Z = 1
        elif options.boron:
            Z = 5
        if options.dim == 2:
            E_exact = [-float(Z)**2/2/(n-0.5)**2/4 for n in [1]+[2]*3+[3]*5 +\
                    [4]*8 + [5]*15]
        elif options.dim == 3:
            E_exact = [-float(Z)**2/2/n**2 for n in [1]+[2]*2**2+[3]*3**2 ]
    if options.well:
        if options.dim == 2:
            E_exact = [pi**2/(2*a**2)*x for x in [2, 5, 5, 8, 10, 10, 13, 13,
                17, 17, 18, 20, 20 ] ]
        elif options.dim == 3:
            E_exact = [pi**2/(2*a**2)*x for x in [3, 6, 6, 6, 9, 9, 9, 11, 11,
                11, 12, 14, 14, 14, 14, 14, 14, 17, 17, 17] ]
    if options.oscillator:
        if options.dim == 2:
            E_exact = [1] + [2]*2 + [3]*3 + [4]*4 + [5]*5 + [6]*6
        elif options.dim == 3:
            E_exact = [float(1)/2+x for x in [1]+[2]*3+[3]*6+[4]*10 ]
    if E_exact is not None:
        print "a=%f" % a
        print "Energies:"
        print     "n      exact         FEM      error"

        for i, e in enumerate(eigs):
            from numpy import NaN
            if i < len(E_exact):
                exact = E_exact[i]
                err = 100*abs((exact - e)/exact)
            else:
                exact = NaN
                err = NaN
            print "%d:  %.8f   %.8f  %5.2f%%" % (i, exact, e, err)
    else:
        print eigs
##     import sfepy.base.plotutils as plu
##     plu.spy( mtx_b, eps = 1e-12 )
##     plu.pylab.show()
##     pause()
    n_eigs = eigs.shape[0]

    mtx_phi = nm.empty( (pb.variables.di.ptr[-1], mtx_s_phi.shape[1]),
                       dtype = nm.float64 )
    for ii in xrange( n_eigs ):
        mtx_phi[:,ii] = pb.variables.make_full_vec( mtx_s_phi[:,ii] )

    save = get_default_attr( conf.options, 'save_eig_vectors', None )
    out = {}
    for ii in xrange( n_eigs ):
        if save is not None:
            if (ii > save[0]) and (ii < (n_eigs - save[1])): continue
        aux = pb.state_to_output( mtx_phi[:,ii] )
        key = aux.keys()[0]
        out[key+'%03d' % ii] = aux[key]

    ofn_trunk = options.output_filename_trunk
    pb.domain.mesh.write( ofn_trunk + '.vtk', io = 'auto', out = out )

    fd = open( ofn_trunk + '_eigs.txt', 'w' )
    eigs.tofile( fd, ' ' )
    fd.close()

    return Struct( pb = pb, eigs = eigs, mtx_phi = mtx_phi )
Example #41
0
    def test_semismooth_newton(self):
        import numpy as nm
        from sfepy.solvers import Solver

        ns = [0, 6, 2, 2]

        offsets = nm.cumsum(ns)
        nx = offsets[-1]

        iw = slice(offsets[0], offsets[1])
        ig = slice(offsets[1], offsets[2])
        il = slice(offsets[2], offsets[3])

        def fun_smooth(vec_x):
            xw = vec_x[iw]
            xg = vec_x[ig]
            xl = vec_x[il]

            m = self.ms
            rw = m['A'] * xw - m['Bb'].T * xg - self.m['fs'] 
            rg = m['Bb'] * xw + xl * xg

            rwg = nm.r_[rw, rg]

            return rwg

        def fun_smooth_grad(vec_x):
            xw = vec_x[iw]
            xl = vec_x[il]
            xg = vec_x[ig]

            m = self.m

            mzl = nm.zeros((6, 2), dtype=nm.float64)

            mw = nm.c_[m['A'], -m['Bb'].T, mzl]
            mg = nm.c_[m['Bb'], nm.diag(xl), nm.diag(xg)]

            mx = nm.r_[mw, mg]

            mx = sps.csr_matrix(mx)
            return mx

        def fun_a(vec_x):
            xw = vec_x[iw]
            xg = vec_x[ig]

            subsd = {}
            for ii, key in enumerate(self.w_names):
                subsd[key] = xw[ii]

            sn = eval_matrix(self.m['sn'], **subsd).squeeze()

            ra = nm.abs(xg) - fc * nm.abs(sn)

            return -ra

        def fun_a_grad(vec_x):
            xw = vec_x[iw]
            xg = vec_x[ig]
            xl = vec_x[il]

            subsd = {}
            for ii, key in enumerate(self.w_names):
                subsd[key] = xw[ii]

            md = eval_matrix(self.m['D'], **subsd)
            sn = eval_matrix(self.m['sn'], **subsd).squeeze()

            ma = nm.zeros((xl.shape[0], nx), dtype=nm.float64)
            ma[:,iw] = - fc * nm.sign(sn)[:,None] * md
            ma[:,ig] = nm.sign(xg)[:,None] * self.m['C']

            return -sps.csr_matrix(ma)

        def fun_b(vec_x):
            xl = vec_x[il]

            return xl

        def fun_b_grad(vec_x):
            xl = vec_x[il]

            mb = nm.zeros((xl.shape[0], nx), dtype=nm.float64)
            mb[:,il] = self.m['C']

            return sps.csr_matrix(mb)

        vec_x0 = 0.1 * nm.ones((nx,), dtype=nm.float64)

        lin_solver = Solver.any_from_conf(dict_to_struct(ls_conf))
        status = {}
        solver = Solver.any_from_conf(dict_to_struct(conf),
                                      fun_smooth=fun_smooth,
                                      fun_smooth_grad=fun_smooth_grad,
                                      fun_a=fun_a,
                                      fun_a_grad=fun_a_grad,
                                      fun_b=fun_b,
                                      fun_b_grad=fun_b_grad,
                                      lin_solver=lin_solver,
                                      status=status)

        vec_x = solver(vec_x0)

        xw = vec_x[iw]
        xg = vec_x[ig]
        xl = vec_x[il]

        self.report('x:', xw)
        self.report('g:', xg)
        self.report('l:', xl)


        subsd = {}
        for ii, key in enumerate(self.w_names):
            subsd[key] = xw[ii]

        sn = eval_matrix(self.m['sn'], **subsd).squeeze()
        self.report('sn:', sn)

        ok = status['condition'] == 0

        return ok
Example #42
0
    def get_time_solver(self, ts_conf=None, **kwargs):
        ts_conf = get_default(ts_conf, self.ts_conf, "you must set time-stepping solver!")

        return Solver.any_from_conf(ts_conf, **kwargs)
Example #43
0
    def solve_eigen_problem_n( self ):
        opts = self.app_options
        pb = self.problem

        dim = pb.domain.mesh.dim

        pb.set_equations( pb.conf.equations )
        pb.select_bcs( ebc_names = ['ZeroSurface'] )

        output( 'assembling rhs...' )
        tt = time.clock()
        mtx_b = pb.evaluate(pb.conf.equations['rhs'], mode='weak',
                            auto_init=True, dw_mode='matrix')
        output( '...done in %.2f s' % (time.clock() - tt) )
        assert_( nm.alltrue( nm.isfinite( mtx_b.data ) ) )

        ## mtx_b.save( 'b.txt', format='%d %d %.12f\n' )

        aux = pb.create_evaluable(pb.conf.equations['lhs'], mode='weak',
                                  dw_mode='matrix')
        mtx_a_equations, mtx_a_variables = aux

        if self.options.plot:
            log_conf = {
                'is_plot' : True,
                'aggregate' : 1,
                'yscales' : ['linear', 'log'],
            }
        else:
            log_conf = {
                'is_plot' : False,
            }
        log =  Log.from_conf( log_conf, ([r'$|F(x)|$'], [r'$|F(x)-x|$']) )

        file_output = Output('', opts.log_filename, combined = True)

        eig_conf = pb.get_solver_conf( opts.eigen_solver )
        eig_solver = Solver.any_from_conf( eig_conf )

        # Just to get the shape. Assumes one element group only!!!
        v_hxc_qp = pb.evaluate('dq_state_in_volume_qp.i1.Omega(Psi)')
        v_hxc_qp.fill(0.0)
        self.qp_shape = v_hxc_qp.shape
        vec_v_hxc = self._interp_to_nodes(v_hxc_qp)

        self.norm_v_hxc0 = nla.norm(vec_v_hxc)
        self.itercount = 0
        aux = wrap_function(self.iterate,
                            (eig_solver,
                             mtx_a_equations, mtx_a_variables,
                             mtx_b, log, file_output))
        ncalls, times, nonlin_v, results = aux

        # Create and call the DFT solver.
        dft_conf = pb.get_solver_conf(opts.dft_solver)
        dft_status = {}
        dft_solver = Solver.any_from_conf(dft_conf,
                                          fun = nonlin_v,
                                          status = dft_status)
        v_hxc_qp = dft_solver(v_hxc_qp.ravel())

        v_hxc_qp = nm.array(v_hxc_qp, dtype=nm.float64)
        v_hxc_qp.shape = self.qp_shape
        eigs, mtx_s_phi, vec_n, vec_v_h, v_ion_qp, v_xc_qp, v_hxc_qp = results
        output( 'DFT iteration time [s]:', dft_status['time_stats'] )

        fun = pb.materials['mat_v'].function
        variable = self.problem.create_variables(['scalar'])['scalar']
        vec_v_ion = fun(None, variable.field.get_coor(),
                        mode='qp')['V_ion'].squeeze()

        vec_v_xc = self._interp_to_nodes(v_xc_qp)
        vec_v_hxc = self._interp_to_nodes(v_hxc_qp)
        vec_v_sum = self._interp_to_nodes(v_hxc_qp + v_ion_qp)

        coor = pb.domain.get_mesh_coors()
        r2 = norm_l2_along_axis(coor, squared=True)
        vec_nr2 = vec_n * r2

        pb.select_bcs( ebc_names = ['ZeroSurface'] )
        mtx_phi = self.make_full( mtx_s_phi )

        out = {}
        update_state_to_output(out, pb, vec_n, 'n')
        update_state_to_output(out, pb, vec_nr2, 'nr2')
        update_state_to_output(out, pb, vec_v_h, 'V_h')
        update_state_to_output(out, pb, vec_v_xc, 'V_xc')
        update_state_to_output(out, pb, vec_v_ion, 'V_ion')
        update_state_to_output(out, pb, vec_v_hxc, 'V_hxc')
        update_state_to_output(out, pb, vec_v_sum, 'V_sum')
        self.save_results(eigs, mtx_phi, out=out)

        if self.options.plot:
            log( save_figure = opts.iter_fig_name )
            pause()
            log(finished=True)

        return Struct( pb = pb, eigs = eigs, mtx_phi = mtx_phi,
                       vec_n = vec_n, vec_nr2 = vec_nr2,
                       vec_v_h = vec_v_h, vec_v_xc = vec_v_xc )
Example #44
0
    def test_ls_reuse(self):
        import numpy as nm
        from sfepy.solvers import Solver
        from sfepy.discrete.state import State

        self.problem.init_solvers(ls_conf=self.problem.solver_confs['d00'])
        nls = self.problem.get_nls()

        state0 = State(self.problem.equations.variables)
        state0.apply_ebc()
        vec0 = state0.get_reduced()

        self.problem.update_materials()

        rhs = nls.fun(vec0)
        mtx = nls.fun_grad(vec0)

        ok = True
        for name in ['i12', 'i01']:
            solver_conf = self.problem.solver_confs[name]
            method = solver_conf.get('method', '')
            precond = solver_conf.get('precond', '')
            name = ' '.join((solver_conf.name, solver_conf.kind,
                             method, precond)).rstrip()
            self.report(name)
            try:
                ls = Solver.any_from_conf(solver_conf)

            except:
                self.report('skipped!')
                continue

            conf = ls.conf.copy()
            conf.force_reuse = True

            sol00 = ls(rhs, mtx=mtx, conf=conf)
            digest00 = ls.mtx_digest

            sol0 = ls(rhs, mtx=mtx)
            digest0 = ls.mtx_digest

            sol1 = ls(rhs, mtx=2*mtx, conf=conf)
            digest1 = ls.mtx_digest

            sol2 = ls(rhs, mtx=2*mtx)
            digest2 = ls.mtx_digest
            ls(rhs, mtx=2*mtx)
            digest3 = ls.mtx_digest

            _ok = digest00 != digest0
            self.report(digest00, '!=', digest0, ':', _ok); ok = ok and _ok
            _ok = digest0 == digest1
            self.report(digest0, '==', digest1, ':', _ok); ok = ok and _ok
            _ok = digest1 != digest2
            self.report(digest1, '!=', digest2, ':', _ok); ok = ok and _ok
            _ok = digest2[1] == digest3[1]
            self.report(digest2[1], '==', digest3[1], ':', _ok); ok = ok and _ok
            _ok = nm.allclose(sol00, sol0, atol=1e-12, rtol=0.0)
            self.report('sol00 == sol0:', _ok); ok = ok and _ok
            _ok = nm.allclose(sol0, sol1, atol=1e-12, rtol=0.0)
            self.report('sol0 == sol1:', _ok); ok = ok and _ok
            _ok = nm.allclose(sol0, 2 * sol2, atol=1e-12, rtol=0.0)
            self.report('sol0 == 2 * sol2:', _ok); ok = ok and _ok

        return ok
Example #45
0
    def solve_eigen_problem(self):
        options = self.options
        opts = self.app_options
        pb = self.problem

        dim = pb.domain.mesh.dim

        pb.set_equations(pb.conf.equations)
        pb.time_update()

        output('assembling lhs...')
        tt = time.clock()
        mtx_a = pb.evaluate(pb.conf.equations['lhs'], mode='weak',
                            auto_init=True, dw_mode='matrix')
        output('...done in %.2f s' % (time.clock() - tt))

        output('assembling rhs...')
        tt = time.clock()
        mtx_b = pb.evaluate(pb.conf.equations['rhs'], mode='weak',
                            dw_mode='matrix')
        output('...done in %.2f s' % (time.clock() - tt))

        n_eigs = get_default(opts.n_eigs, mtx_a.shape[0])

        output('computing resonance frequencies...')
        eig = Solver.any_from_conf(pb.get_solver_conf(opts.eigen_solver))
        eigs, mtx_s_phi = eig(mtx_a, mtx_b, n_eigs, eigenvectors=True)
        output('...done')

        bounding_box = pb.domain.mesh.get_bounding_box()
        # this assumes a box (3D), or a square (2D):
        a = bounding_box[1][0] - bounding_box[0][0]
        E_exact = None
        if options.hydrogen or options.boron:
            if options.hydrogen:
                Z = 1
            elif options.boron:
                Z = 5
            if dim == 2:
                E_exact = [-float(Z)**2/2/(n-0.5)**2/4
                           for n in [1]+[2]*3+[3]*5 + [4]*8 + [5]*15]
            elif dim == 3:
                E_exact = [-float(Z)**2/2/n**2 for n in [1]+[2]*2**2+[3]*3**2 ]
        if options.well:
            if dim == 2:
                E_exact = [pi**2/(2*a**2)*x
                           for x in [2, 5, 5, 8, 10, 10, 13, 13,
                                     17, 17, 18, 20, 20 ] ]
            elif dim == 3:
                E_exact = [pi**2/(2*a**2)*x
                           for x in [3, 6, 6, 6, 9, 9, 9, 11, 11,
                                     11, 12, 14, 14, 14, 14, 14,
                                     14, 17, 17, 17] ]
        if options.oscillator:
            if dim == 2:
                E_exact = [1] + [2]*2 + [3]*3 + [4]*4 + [5]*5 + [6]*6
            elif dim == 3:
                E_exact = [float(1)/2+x for x in [1]+[2]*3+[3]*6+[4]*10 ]
        if E_exact is not None:
            output("a=%f" % a)
            output("Energies:")
            output("n      exact         FEM      error")

            for i, e in enumerate(eigs):
                from numpy import NaN
                if i < len(E_exact):
                    exact = E_exact[i]
                    err = 100*abs((exact - e)/exact)
                else:
                    exact = NaN
                    err = NaN
                output("%d:  %.8f   %.8f  %5.2f%%" % (i, exact, e, err))
        else:
            output(eigs)

        mtx_phi = self.make_full(mtx_s_phi)
        self.save_results(eigs, mtx_phi)

        return Struct(pb=pb, eigs=eigs, mtx_phi=mtx_phi)
Example #46
0
def solve_eigen_problem_n( conf, options ):

    pb = ProblemDefinition.from_conf( conf )
    dim = pb.domain.mesh.dim

    pb.time_update()

    dummy = pb.create_state_vector()

    output( 'assembling rhs...' )
    tt = time.clock()
    mtx_b = eval_term_op( dummy, conf.equations['rhs'], pb,
                       dw_mode = 'matrix', tangent_matrix = pb.mtx_a.copy() )
    output( '...done in %.2f s' % (time.clock() - tt) )

    #mtxA.save( 'tmp/a.txt', format='%d %d %.12f\n' )
    #mtxB.save( 'tmp/b.txt', format='%d %d %.12f\n' )

    try:
        n_eigs = conf.options.n_eigs
    except AttributeError:
        n_eigs = mtx_a.shape[0]

    if n_eigs is None:
        n_eigs = mtx_a.shape[0]

##     mtx_a.save( 'a.txt', format='%d %d %.12f\n' )
##     mtx_b.save( 'b.txt', format='%d %d %.12f\n' )

    if options.plot:
        log_conf = {
            'is_plot' : True,
            'aggregate' : 1,
            'yscales' : ['linear', 'log'],
        }
    else:
        log_conf = {
            'is_plot' : False,
        }
    log =  Log.from_conf( log_conf, ([r'$|F(x)|$'], [r'$|F(x)|$']) )

    eig_conf = pb.get_solver_conf( conf.options.eigen_solver )
    eig_solver = Solver.any_from_conf( eig_conf )
    vec_vhxc = nm.zeros( (pb.variables.di.ptr[-1],), dtype = nm.float64 )
    aux = wrap_function( iterate,
                         (pb, conf, eig_solver, n_eigs, mtx_b, log) )
    ncalls, times, nonlin_v = aux
    vec_vhxc = broyden3( nonlin_v, vec_vhxc, verbose = True )
    out = iterate( vec_vhxc, pb, conf, eig_solver, n_eigs, mtx_b )
    eigs, mtx_s_phi, vec_n, vec_vh, vec_vxc = out

    if options.plot:
        log( finished = True )
        pause()
        
    coor = pb.domain.get_mesh_coors()
    r = coor[:,0]**2 + coor[:,1]**2 + coor[:,2]**2
    vec_nr2 = vec_n * r

    n_eigs = eigs.shape[0]

    mtx_phi = nm.empty( (pb.variables.di.ptr[-1], mtx_s_phi.shape[1]),
                       dtype = nm.float64 )
    for ii in xrange( n_eigs ):
        mtx_phi[:,ii] = pb.variables.make_full_vec( mtx_s_phi[:,ii] )

    save = get_default_attr( conf.options, 'save_eig_vectors', None )
    out = {}
    for ii in xrange( n_eigs ):
        if save is not None:
            if (ii >= save[0]) and (ii < (n_eigs - save[1])): continue
        aux = pb.state_to_output( mtx_phi[:,ii] )
        key = aux.keys()[0]
        out[key+'%03d' % ii] = aux[key]

    update_state_to_output( out, pb, vec_n, 'n' )
    update_state_to_output( out, pb, vec_nr2, 'nr2' )
    update_state_to_output( out, pb, vec_vh, 'vh' )
    update_state_to_output( out, pb, vec_vxc, 'vxc' )

    ofn_trunk = options.output_filename_trunk
    pb.domain.mesh.write( ofn_trunk + '.vtk', io = 'auto', out = out )

    fd = open( ofn_trunk + '_eigs.txt', 'w' )
    eigs.tofile( fd, ' ' )
    fd.close()

    return Struct( pb = pb, eigs = eigs, mtx_phi = mtx_phi )