Beispiel #1
0
class Space:
    def __init__(self, mesh, N=0):

        # Define mesh parameters
        self.mesh = mesh
        self.cell_size = CellDiameter(mesh)
        self.normal_vector = FacetNormal(mesh)

        # Define measures
        inner_boundary = Inner_boundary()
        sub_domains = MeshFunction("size_t", mesh, mesh.topology().dim() - 1)
        sub_domains.set_all(0)
        inner_boundary.mark(sub_domains, 1)
        self.dx = Measure("dx", domain=mesh)
        self.ds = Measure("ds", domain=mesh, subdomain_data=sub_domains)

        # Define function spaces
        finite_element = FiniteElement("Lagrange", mesh.ufl_cell(), 1)
        self.function_space = FunctionSpace(mesh,
                                            finite_element * finite_element)
        self.function_space_split = [
            self.function_space.sub(0).collapse(),
            self.function_space.sub(1).collapse(),
        ]
Beispiel #2
0
def project_gradient(
        f0,
        mesh=None,
        degree=None,
        debug=False,
        solver_type='gmres',
        preconditioner_type='default'
    ):
    """Find an approximation to f0 that has the same gradient

    Parameters:    
    f0: the function to approximate
    mesh=None: the mesh on which to approximate it. If not provided, the
        mesh is extracted from f0.
    degree=None: degree of the polynomial approximation. extracted
        from f0 if not provided. 
    solver_type='gmres': The linear solver type to use.
    preconditioner_type='default': Preconditioner type to use
    """
    if not mesh: mesh = f0.function_space().mesh()
    element = f0.ufl_element()
    if not degree:
        degree = element.degree()
    CE = FiniteElement('CG', mesh.ufl_cell(), degree)
    CS = FunctionSpace(mesh, CE)
    DE = FiniteElement('DG', mesh.ufl_cell(), degree)
    DS = FunctionSpace(mesh, DE)
    CVE = VectorElement('CG', mesh.ufl_cell(), degree - 1)
    CV = FunctionSpace(mesh, CVE)
    RE = FiniteElement('R', mesh.ufl_cell(), 0)
    R = FunctionSpace(mesh, RE)
    CRE = MixedElement([CE, RE])
    CR = FunctionSpace(mesh, CRE)
    f = fe.project(f0, CS,
                   solver_type=solver_type,
                   preconditioner_type= preconditioner_type)
    g = fe.project(fe.grad(f), CV,
                   solver_type=solver_type,
                   preconditioner_type= preconditioner_type)
    tf, tc = TrialFunction(CR)
    wf, wc = TestFunctions(CR)
    dx = Measure('dx', domain=mesh,
                 metadata={'quadrature_degree': min(degree, 10)})
    a = (fe.dot(fe.grad(tf), fe.grad(wf)) + tc * wf + tf * wc) * fe.dx
    L = (f * wc + fe.dot(g, fe.grad(wf))) * fe.dx
    igc = Function(CR)
    fe.solve(a == L, igc,
             solver_parameters={'linear_solver': solver_type,
                                 'preconditioner': preconditioner_type}
    )
    if debug:
        print('igc', igc.vector()[:])
    assigner = FunctionAssigner(CS, CR.sub(0))
#    ig = Function(CS)
#    assigner.assign(ig, igc.sub(0))
#    fe.assign(ig, igc.sub(0))
#    if debug:
#        print('ig', igc.sub(0).vector()[:])
    igd = fe.project(igc.sub(0), DS,
                     solver_type=solver_type,
                     preconditioner_type=preconditioner_type)
    if debug:
        print('igd', igd.vector()[:])
    return igd