Пример #1
0
def flip_vectors(mesh, eigs, mesh_ref, eigs_ref, test_it=False):
    x_c = 1e-3
    for i in range(len(eigs)):
        s = FESolution(mesh, eigs[i])
        s_ref = FESolution(mesh_ref, eigs_ref[i])
        if s.value(x_c) < 0:
            #print "  Multiplying %d-th coarse eigenvector by (-1)" % i
            eigs[i] = -eigs[i]
        if s_ref.value(x_c) < 0:
            #print "  Multiplying %d-th ref. eigenvector by (-1)" % i
            eigs_ref[i] = -eigs_ref[i]

        if test_it:
            # Test it:
            s = FESolution(mesh, eigs[i]).to_discrete_function()
            s_ref = FESolution(mesh_ref, eigs_ref[i]).to_discrete_function()
            same_norm = (s - s_ref).l2_norm()
            flipped_norm = (s + s_ref).l2_norm()
            print same_norm, flipped_norm
            if same_norm > flipped_norm:
                c = min(same_norm, flipped_norm) / max(same_norm, flipped_norm)
                print "Warning: the flip is wrong, c=", c
                # If "c" is almost one, then the vectors can't really be
                # aligned anyway:
                assert c > 0.9
Пример #2
0
    def project_onto(self, mesh, proj_type="Fekete"):
        """
        Projects 'self' onto the 'mesh' using the 'proj_type' projection.

        proj_type == "Fekete"/"L2"/"H1"
        """
        if mesh == self._mesh:
            return self
        if proj_type == "Fekete":
            return Function(self, mesh)
        elif proj_type in ["L2", "H1"]:
            from hermes1d.h1d_wrapper.h1d_wrapper import \
                    (assemble_projection_matrix_rhs, Mesh, FESolution)
            from hermes1d.hermes_common.matrix import CSCMatrix, AVector
            pts, orders = mesh.get_mesh_data()
            m = Mesh(pts, orders)
            n_dof = m.assign_dofs()
            A = CSCMatrix(n_dof)
            rhs = AVector(n_dof)
            assemble_projection_matrix_rhs(m,
                                           A,
                                           rhs,
                                           self,
                                           projection_type=proj_type)
            coeffs = solve(A.to_scipy_csc().todense(), rhs.to_numpy())
            return FESolution(m, coeffs).to_discrete_function()
        else:
            raise ValueError("Unknown projection type")
Пример #3
0
def test_l2_h1_proj_run():
    """
    Test that the projections run.

    It doesn't test if it's correct.
    """
    pts = arange(0, 2 * pi, 1)
    orders = [3] * (len(pts) - 1)
    m = Mesh(pts, orders)
    n_dof = m.assign_dofs()
    A = CSCMatrix(n_dof)
    rhs = AVector(n_dof)
    assemble_projection_matrix_rhs(m, A, rhs, f_sin, projection_type="L2")
    x = solve(A.to_scipy_csc().todense(), rhs.to_numpy())
    sol_l2 = FESolution(m, x).to_discrete_function()
    A = CSCMatrix(n_dof)
    assemble_projection_matrix_rhs(m, A, rhs, f_sin, projection_type="H1")
    x = solve(A.to_scipy_csc().todense(), rhs.to_numpy())
    sol_h1 = FESolution(m, x).to_discrete_function()
    sol_l2.plot(False)
    sol_h1.plot(False)
Пример #4
0
def test_l2_h1_proj3():
    """
    Tests conversion to FE basis.
    """
    pts = arange(0, 2 * pi, 0.1)
    orders = [2] * (len(pts) - 1)
    m = Mesh(pts, orders)

    f = Function(lambda x: sin(x), Mesh1D(pts, orders))

    n_dof = m.assign_dofs()
    A = CSCMatrix(n_dof)
    rhs = AVector(n_dof)
    assemble_projection_matrix_rhs(m, A, rhs, f, projection_type="L2")
    x = solve(A.to_scipy_csc().todense(), rhs.to_numpy())
    sol_l2 = FESolution(m, x).to_discrete_function()
    A = CSCMatrix(n_dof)
    assemble_projection_matrix_rhs(m, A, rhs, f, projection_type="H1")
    x = solve(A.to_scipy_csc().todense(), rhs.to_numpy())
    sol_h1 = FESolution(m, x).to_discrete_function()
    assert sol_l2 == f
    assert sol_h1 == f
Пример #5
0
 def calculate_FE_coeffs(self):
     if self._fe_sol is None:
         from hermes1d.h1d_wrapper.h1d_wrapper import \
                 (assemble_projection_matrix_rhs, Mesh, FESolution)
         from hermes_common._hermes_common import CooMatrix
         pts, orders = self._mesh.get_mesh_data()
         m = Mesh(pts, orders)
         n_dof = m.assign_dofs()
         A = CooMatrix(n_dof)
         rhs = empty(n_dof)
         assemble_projection_matrix_rhs(m, A, rhs, self,
                 projection_type="L2")
         coeffs = solve(A.to_scipy_coo().todense(), rhs)
         self._fe_sol = FESolution(m, coeffs)
Пример #6
0
def test_l2_h1_proj2():
    """
    Tests the correctness of the projections.
    """
    pts = arange(0, 2 * pi, 3)
    orders = [4] * (len(pts) - 1)
    m = Mesh(pts, orders)

    pts = array(list(arange(0, pts[-1], 0.1)) + [pts[-1]])
    orders = [6] * (len(pts) - 1)
    f_exact = Function(lambda x: sin(x), Mesh1D(pts, orders))

    n_dof = m.assign_dofs()
    A = CSCMatrix(n_dof)
    rhs = AVector(n_dof)
    assemble_projection_matrix_rhs(m, A, rhs, f_sin, projection_type="L2")
    x = solve(A.to_scipy_csc().todense(), rhs.to_numpy())
    sol_l2 = FESolution(m, x).to_discrete_function()
    A = CSCMatrix(n_dof)
    assemble_projection_matrix_rhs(m, A, rhs, f_sin, projection_type="H1")
    x = solve(A.to_scipy_csc().todense(), rhs.to_numpy())
    sol_h1 = FESolution(m, x).to_discrete_function()
    assert (sol_l2 - f_exact).l2_norm() < 0.002
    assert (sol_h1 - f_exact).l2_norm() < 0.002
Пример #7
0
def refine_mesh_romanowski(mesh, solutions):
    """
    Uses Romanowski refinement for all solutions in 'solutions'.

    Solutions are given as vectors coming from the matrix solver.
    """
    els2refine = []
    errors = []
    for sol in solutions:
        s = FESolution(mesh, sol)
        id, error = find_element_romanowski(s.get_element_coeffs())
        els2refine.append(id)
        errors.append(error)
    els2refine = list(set(els2refine))
    print "Will refine the elements:", els2refine
    mesh = refine_mesh(mesh, els2refine)
    return mesh
Пример #8
0
def adapt_mesh(mesh, eigs, l=0, Z=1, adapt_type="hp", eqn_type="R"):
    """
    Adapts the mesh using the adaptivity type 'adapt_type'.

    Returns a new instance of the H1D mesh.

    adapt_type .... one of: h, hp, p, uniform-p, romanowski
    """
    if adapt_type == "romanowski":
        m = refine_mesh_romanowski(mesh, eigs)
        pts, orders = m.get_mesh_data()
        return Mesh(pts, orders)
    elif adapt_type == "uniform-p":
        pts, orders = mesh.get_mesh_data()
        orders = array(orders) + 1
        return Mesh(pts, orders)
    elif adapt_type in ["h", "p", "hp"]:
        NORM = 1  # 1 ... H1; 0 ... L2;
        THRESHOLD = 0.7
        mesh_ref = mesh.reference_refinement()
        print "Fine mesh created (%d DOF)." % mesh_ref.get_n_dof()
        N_dof, energies, eigs_ref = solve_schroedinger(mesh_ref,
                                                       l=l,
                                                       Z=Z,
                                                       eqn_type=eqn_type,
                                                       eig_num=len(eigs))
        flip_vectors(mesh, eigs, mesh_ref, eigs_ref)
        print "    Done."
        sols = []
        sols_ref = []
        print "Normalizing solutions..."
        for i in range(len(eigs)):
            e = (eigs[i]).copy()
            coarse_h1_norm = FESolution(mesh, e).h1_norm()
            e /= coarse_h1_norm
            sols.append(e)
            e = (eigs_ref[i]).copy()
            reference_h1_norm = FESolution(mesh_ref, e).h1_norm()
            e /= reference_h1_norm
            sols_ref.append(e)
            #print "H1 norms:"
            #print "coarse    (%d):" % i, coarse_h1_norm
            #print "reference (%d):" % i, reference_h1_norm
        print "    Done."
        meshes = []
        mesh_orig = mesh.copy()
        mesh_orig.assign_dofs()
        errors = []
        for sol, sol_ref in zip(sols, sols_ref):
            mesh = mesh_orig.copy()
            mesh.assign_dofs()
            mesh_ref = mesh.reference_refinement()
            mesh_ref.assign_dofs()
            mesh.copy_vector_to_mesh(sol, 0)
            mesh_ref.copy_vector_to_mesh(sol_ref, 0)
            err_est_total, err_est_array = calc_error_estimate(
                NORM, mesh, mesh_ref)
            ref_sol_norm = calc_solution_norm(NORM, mesh_ref)
            err_est_rel = err_est_total / ref_sol_norm
            print "Relative error (est) = %g %%\n" % (100. * err_est_rel)
            errors.append(err_est_rel)
            # TODO: adapt using all the vectors:
            # 0 ... hp, 1 ... h, 2 ... p
            if adapt_type == "hp":
                ADAPT_TYPE = 0
            elif adapt_type == "h":
                ADAPT_TYPE = 1
            elif adapt_type == "p":
                ADAPT_TYPE = 2
            else:
                raise ValueError("Unkown adapt_type")
            adapt(NORM, ADAPT_TYPE, THRESHOLD, err_est_array, mesh, mesh_ref)
            meshes.append(mesh)
        pts, orders = mesh_orig.get_mesh_data()
        mesh = Mesh1D(pts, orders)
        for m in meshes:
            pts, orders = m.get_mesh_data()
            m = Mesh1D(pts, orders)
            mesh = mesh.union(m)
        pts, orders = mesh.get_mesh_data()
        mesh = Mesh(pts, orders)
        return mesh
    else:
        raise ValueError("Unknown adapt_type")