Пример #1
0
def assemble_matrices(define, mod, pars, set_wave_dir, options, wdir=None):
    """
    Assemble the blocks of dispersion eigenvalue problem matrices.
    """
    define_dict = define(filename_mesh=options.mesh_filename,
                         pars=pars,
                         approx_order=options.order,
                         refinement_level=options.refine,
                         solver_conf=options.solver_conf,
                         plane=options.plane,
                         post_process=options.post_process,
                         **options.define_kwargs)

    conf = ProblemConf.from_dict(define_dict, mod)

    pb = Problem.from_conf(conf)
    pb.dispersion_options = options
    pb.set_output_dir(options.output_dir)
    dim = pb.domain.shape.dim

    # Set the normalized wave vector direction to the material(s).
    if wdir is None:
        wdir = nm.asarray(options.wave_dir[:dim], dtype=nm.float64)
        wdir = wdir / nm.linalg.norm(wdir)
    set_wave_dir(pb, wdir)

    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()

    # Assemble the matrices.
    mtxs = {}
    for key, eq in pb.equations.iteritems():
        mtxs[key] = mtx = pb.mtx_a.copy()
        mtx = eq.evaluate(mode='weak', dw_mode='matrix', asm_obj=mtx)
        mtx.eliminate_zeros()
        output_array_stats(mtx.data, 'nonzeros in %s' % key)

        output('symmetry checks:')
        output('%s - %s^T:' % (key, key), max_diff_csr(mtx, mtx.T))
        output('%s - %s^H:' % (key, key), max_diff_csr(mtx, mtx.H))

    return pb, wdir, bzone, mtxs
Пример #2
0
def assemble_matrices(define, mod, pars, set_wave_dir, options):
    """
    Assemble the blocks of dispersion eigenvalue problem matrices.
    """
    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,
                                       post_process=options.post_process)

    conf = ProblemConf.from_dict(define_problem(), mod)

    pb = Problem.from_conf(conf)
    pb.dispersion_options = options
    pb.set_output_dir(options.output_dir)
    dim = pb.domain.shape.dim

    # Set the normalized wave vector direction to the material(s).
    wdir = nm.asarray(options.wave_dir[:dim], dtype=nm.float64)
    wdir = wdir / nm.linalg.norm(wdir)
    set_wave_dir(pb, wdir)

    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()

    # Assemble the matrices.
    mtxs = {}
    for key, eq in pb.equations.iteritems():
        mtxs[key] = mtx = pb.mtx_a.copy()
        mtx = eq.evaluate(mode='weak', dw_mode='matrix', asm_obj=mtx)
        mtx.eliminate_zeros()
        output_array_stats(mtx.data, 'nonzeros in %s' % key)

        output('symmetry checks:')
        output('%s - %s^T:' % (key, key), max_diff_csr(mtx, mtx.T))
        output('%s - %s^H:' % (key, key), max_diff_csr(mtx, mtx.H))

    return pb, wdir, bzone, mtxs
Пример #3
0
def build_evp_matrices(mtxs, val, mode, pb):
    """
    Build the matrices of the dispersion eigenvalue problem.
    """
    if mode == 'omega':
        mtx_a = mtxs['K'] + val**2 * mtxs['S'] + val * mtxs['R']
        output('A - A^H:', max_diff_csr(mtx_a, mtx_a.H))

        evp_mtxs = (mtx_a, mtxs['M'])

    else:
        evp_mtxs = (mtxs['S'], mtxs['R'], mtxs['K'] - val**2 * mtxs['M'])

    return evp_mtxs
Пример #4
0
def build_evp_matrices(mtxs, val, mode, pb):
    """
    Build the matrices of the dispersion eigenvalue problem.
    """
    if mode == 'omega':
        mtx_a = mtxs['K'] + val**2 * mtxs['S'] + val * mtxs['R']
        output('A - A^H:', max_diff_csr(mtx_a, mtx_a.H))

        evp_mtxs = (mtx_a, mtxs['M'])

    else:
        evp_mtxs = (mtxs['S'], mtxs['R'], mtxs['K'] - val**2 * mtxs['M'])

    return evp_mtxs
Пример #5
0
    def __call__(self,
                 mtx_m,
                 mtx_d,
                 mtx_k,
                 n_eigs=None,
                 eigenvectors=None,
                 status=None,
                 conf=None):
        if conf.debug:
            ssym = status['matrix_info'] = {}
            ssym['|M - M^T|'] = max_diff_csr(mtx_m, mtx_m.T)
            ssym['|D - D^T|'] = max_diff_csr(mtx_d, mtx_d.T)
            ssym['|K - K^T|'] = max_diff_csr(mtx_k, mtx_k.T)
            ssym['|M - M^H|'] = max_diff_csr(mtx_m, mtx_m.H)
            ssym['|D - D^H|'] = max_diff_csr(mtx_d, mtx_d.H)
            ssym['|K - K^H|'] = max_diff_csr(mtx_k, mtx_k.H)

        if conf.method == 'companion':
            mtx_eye = -sps.eye(mtx_m.shape[0], dtype=mtx_m.dtype)

            mtx_a = sps.bmat([[mtx_d, mtx_k], [mtx_eye, None]])
            mtx_b = sps.bmat([[-mtx_m, None], [None, mtx_eye]])

        elif conf.method == 'cholesky':
            from sksparse.cholmod import cholesky

            factor = cholesky(mtx_m)
            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()

            if conf.debug:
                ssym['|S - LL^T|'] = max_diff_csr(mtx_m, mtx_l * mtx_l.T)

            mtx_eye = sps.eye(mtx_l.shape[0], dtype=nm.float64)

            mtx_a = sps.bmat([[-mtx_k, None], [None, mtx_eye]])
            mtx_b = sps.bmat([[mtx_d, mtx_l], [mtx_l.T, None]])

        else:
            raise ValueError('unknown method! (%s)' % conf.method)

        if conf.debug:
            ssym['|A - A^T|'] = max_diff_csr(mtx_a, mtx_a.T)
            ssym['|A - A^H|'] = max_diff_csr(mtx_a, mtx_a.H)
            ssym['|B - B^T|'] = max_diff_csr(mtx_b, mtx_b.T)
            ssym['|B - B^H|'] = max_diff_csr(mtx_b, mtx_b.H)

            for key, val in sorted(ssym.items()):
                output('{}: {}'.format(key, val))

        if conf.mode == 'normal':
            out = self.solver(mtx_a,
                              mtx_b,
                              n_eigs=n_eigs,
                              eigenvectors=eigenvectors,
                              status=status)

            if eigenvectors:
                eigs, vecs = out
                out = (eigs, vecs[:mtx_m.shape[0], :])

                if conf.debug:
                    res = mtx_a.dot(vecs) - eigs * mtx_b.dot(vecs)
                    status['lin. error'] = nm.linalg.norm(res, nm.inf)

        else:
            out = self.solver(mtx_b,
                              mtx_a,
                              n_eigs=n_eigs,
                              eigenvectors=eigenvectors,
                              status=status)

            if eigenvectors:
                eigs, vecs = out
                out = (1.0 / eigs, vecs[:mtx_m.shape[0], :])

                if conf.debug:
                    res = (1.0 / eigs) * mtx_b.dot(vecs) - mtx_a.dot(vecs)
                    status['lin. error'] = nm.linalg.norm(res, nm.inf)

            else:
                out = 1.0 / out

        if conf.debug and eigenvectors:
            eigs, vecs = out
            res = ((eigs**2 * (mtx_m.dot(vecs))) + (eigs * (mtx_d.dot(vecs))) +
                   (mtx_k.dot(vecs)))
            status['error'] = nm.linalg.norm(res, nm.inf)

        return out
Пример #6
0
Файл: qeigen.py Проект: rc/sfepy
    def __call__(self, mtx_m, mtx_d, mtx_k, n_eigs=None,
                 eigenvectors=None, status=None, conf=None):
        if conf.debug:
            ssym = status['matrix_info'] = {}
            ssym['|M - M^T|'] = max_diff_csr(mtx_m, mtx_m.T)
            ssym['|D - D^T|'] = max_diff_csr(mtx_d, mtx_d.T)
            ssym['|K - K^T|'] = max_diff_csr(mtx_k, mtx_k.T)
            ssym['|M - M^H|'] = max_diff_csr(mtx_m, mtx_m.H)
            ssym['|D - D^H|'] = max_diff_csr(mtx_d, mtx_d.H)
            ssym['|K - K^H|'] = max_diff_csr(mtx_k, mtx_k.H)

        if conf.method == 'companion':
            mtx_eye = -sps.eye(mtx_m.shape[0], dtype=mtx_m.dtype)

            mtx_a = sps.bmat([[mtx_d, mtx_k],
                              [mtx_eye, None]])
            mtx_b = sps.bmat([[-mtx_m, None],
                              [None, mtx_eye]])

        elif conf.method == 'cholesky':
            from sksparse.cholmod import cholesky

            factor = cholesky(mtx_m)
            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()

            if conf.debug:
                ssym['|S - LL^T|'] = max_diff_csr(mtx_m, mtx_l * mtx_l.T)

            mtx_eye = sps.eye(mtx_l.shape[0], dtype=nm.float64)

            mtx_a = sps.bmat([[-mtx_k, None],
                              [None, mtx_eye]])
            mtx_b = sps.bmat([[mtx_d, mtx_l],
                              [mtx_l.T, None]])

        else:
            raise ValueError('unknown method! (%s)' % conf.method)

        if conf.debug:
            ssym['|A - A^T|'] = max_diff_csr(mtx_a, mtx_a.T)
            ssym['|A - A^H|'] = max_diff_csr(mtx_a, mtx_a.H)
            ssym['|B - B^T|'] = max_diff_csr(mtx_b, mtx_b.T)
            ssym['|B - B^H|'] = max_diff_csr(mtx_b, mtx_b.H)

            for key, val in sorted(ssym.items()):
                output('{}: {}'.format(key, val))

        if conf.mode == 'normal':
            out = self.solver(mtx_a, mtx_b, n_eigs=n_eigs,
                              eigenvectors=eigenvectors, status=status)

            if eigenvectors:
                eigs, vecs = out
                out = (eigs, vecs[:mtx_m.shape[0], :])

                if conf.debug:
                    res = mtx_a.dot(vecs) - eigs * mtx_b.dot(vecs)
                    status['lin. error'] = nm.linalg.norm(res, nm.inf)

        else:
            out = self.solver(mtx_b, mtx_a, n_eigs=n_eigs,
                              eigenvectors=eigenvectors, status=status)

            if eigenvectors:
                eigs, vecs = out
                out = (1.0 / eigs, vecs[:mtx_m.shape[0], :])

                if conf.debug:
                    res = (1.0 / eigs) * mtx_b.dot(vecs) -  mtx_a.dot(vecs)
                    status['lin. error'] = nm.linalg.norm(res, nm.inf)

            else:
                out = 1.0 / out

        if conf.debug and eigenvectors:
            eigs, vecs = out
            res = ((eigs**2 * (mtx_m.dot(vecs)))
                   + (eigs * (mtx_d.dot(vecs)))
                   + (mtx_k.dot(vecs)))
            status['error'] = nm.linalg.norm(res, nm.inf)

        return out