Exemplo n.º 1
0
    def get_projection_error_function(self, mu_src, mu_dest, reference_degree, refine_mesh=0):
        """Construct projection error function by projecting mu_src vector to mu_dest space of dest_degree.
        From this, the projection of mu_src onto the mu_dest space, then to the mu_dest space of dest_degree is subtracted.
        If refine_mesh > 0, the destination mesh is refined uniformly n times."""
        from spuq.fem.fenics.fenics_utils import create_joint_mesh
        from dolfin import FunctionSpace, VectorFunctionSpace
        from spuq.fem.fenics.fenics_basis import FEniCSBasis
        
        # get joint mesh based on destination space
        basis_src = self[mu_src].basis 
        basis_dest = self[mu_dest].basis
        mesh_reference, parents = create_joint_mesh([basis_src.mesh], basis_dest.mesh)

        # create function space on destination mesh        
        if basis_dest._fefs.num_sub_spaces() > 0:
            fs_reference = VectorFunctionSpace(mesh_reference, basis_dest._fefs.ufl_element().family(), reference_degree)
        else:
            fs_reference = FunctionSpace(mesh_reference, basis_dest._fefs.ufl_element().family(), reference_degree)
        basis_reference = FEniCSBasis(fs_reference, basis_dest._ptype)
        
        # project both vectors to reference space
        w_reference = basis_reference.project_onto(self[mu_src])
        w_dest = self.get_projection(mu_src, mu_dest)
        w_dest = basis_reference.project_onto(w_dest)
        
        # define summation function to get values on original destination mesh from function space on joint mesh
        def sum_up(vals):
            sum_vals = [sum(vals[v]) for _, v in parents.iteritems()]
            return np.array(sum_vals)
        return w_dest - w_reference, sum_up
Exemplo n.º 2
0
    def get_projection_error_function_old(self, mu_src, mu_dest, reference_degree, refine_mesh=0):
        """Construct projection error function by projecting mu_src vector to mu_dest space of dest_degree.
        From this, the projection of mu_src onto the mu_dest space, then to the mu_dest space of dest_degree is subtracted.
        If refine_mesh > 0, the destination mesh is refined uniformly n times."""
        # TODO: If refine_mesh is True, the destination space of mu_dest is ensured to include the space of mu_src by mesh refinement
        # TODO: proper description
        # TODO: separation of fenics specific code
        from dolfin import refine, FunctionSpace, VectorFunctionSpace
        from spuq.fem.fenics.fenics_basis import FEniCSBasis
        if not refine_mesh:
            w_reference = self.get_projection(mu_src, mu_dest, reference_degree)
            w_dest = self.get_projection(mu_src, mu_dest)
            w_dest = w_reference.basis.project_onto(w_dest)
            sum_up = lambda vals: vals
        else:
            # uniformly refine destination mesh
            # NOTE: the cell_marker based refinement used in FEniCSBasis is a bisection of elements
            # while refine(mesh) carries out a red-refinement of all cells (split into 4)
#            basis_src = self[mu_src].basis
            basis_dest = self[mu_dest].basis
            mesh_reference = basis_dest.mesh
            for _ in range(refine_mesh):
                mesh_reference = refine(mesh_reference)
#            print "multi_vector::get_projection_error_function"
#            print type(basis_src._fefs), type(basis_dest._fefs)
#            print basis_src._fefs.num_sub_spaces(), basis_dest._fefs.num_sub_spaces()
#            if isinstance(basis_dest, VectorFunctionSpace):
            if basis_dest._fefs.num_sub_spaces() > 0:
                fs_reference = VectorFunctionSpace(mesh_reference, basis_dest._fefs.ufl_element().family(), reference_degree)
            else:
                fs_reference = FunctionSpace(mesh_reference, basis_dest._fefs.ufl_element().family(), reference_degree)
            basis_reference = FEniCSBasis(fs_reference, basis_dest._ptype)
            # project both vectors to reference space
            w_reference = basis_reference.project_onto(self[mu_src])
            w_dest = self.get_projection(mu_src, mu_dest)
            w_dest = basis_reference.project_onto(w_dest)
            sum_up = lambda vals: np.array([sum(vals[i * 4:(i + 1) * 4]) for i in range(len(vals) / 4 ** refine_mesh)])
        return w_dest - w_reference, sum_up