예제 #1
0
 def __init__(self, V, fixed_dims=[], direct_solve=False):
     if isinstance(fixed_dims, int):
         fixed_dims = [fixed_dims]
     self.V = V
     self.fixed_dims = fixed_dims
     self.direct_solve = direct_solve
     self.zero = fd.Constant(V.mesh().topological_dimension() * (0, ))
     u = fd.TrialFunction(V)
     v = fd.TestFunction(V)
     self.zero_fun = fd.Function(V)
     self.a = 1e-2 * \
         fd.inner(u, v) * fd.dx + fd.inner(fd.sym(fd.grad(u)),
                                           fd.sym(fd.grad(v))) * fd.dx
     self.bc_fun = fd.Function(V)
     if len(self.fixed_dims) == 0:
         bcs = [fd.DirichletBC(self.V, self.bc_fun, "on_boundary")]
     else:
         bcs = []
         for i in range(self.V.mesh().topological_dimension()):
             if i in self.fixed_dims:
                 bcs.append(fd.DirichletBC(self.V.sub(i), 0, "on_boundary"))
             else:
                 bcs.append(
                     fd.DirichletBC(self.V.sub(i), self.bc_fun.sub(i),
                                    "on_boundary"))
     self.A_ext = fd.assemble(self.a, bcs=bcs, mat_type="aij")
     self.ls_ext = fd.LinearSolver(self.A_ext,
                                   solver_parameters=self.get_params())
     self.A_adj = fd.assemble(self.a,
                              bcs=fd.DirichletBC(self.V, self.zero,
                                                 "on_boundary"),
                              mat_type="aij")
     self.ls_adj = fd.LinearSolver(self.A_adj,
                                   solver_parameters=self.get_params())
예제 #2
0
    def dirichlet_boundary_conditions(sim):

        W = sim.solution_space

        return [
            fe.DirichletBC(W.sub(0), fe.Constant((0., 0.)), (1, 2, 3)),
            fe.DirichletBC(W.sub(0), fe.Constant((1., 0.)), 4)
        ]
예제 #3
0
    def dirichlet_boundary_conditions(self):

        return [
            fe.DirichletBC(self.solution_subspaces["u"], fe.Constant((0., 0.)),
                           (1, 2, 3)),
            fe.DirichletBC(self.solution_subspaces["u"], fe.Constant((1., 0.)),
                           4)
        ]
def dirichlet_boundary_conditions(sim):

    W = sim.function_space

    return [
        fe.DirichletBC(W.sub(1), (0., 0.), "on_boundary"),
        fe.DirichletBC(W.sub(2), sim.hot_wall_temperature, 1),
        fe.DirichletBC(W.sub(2), sim.cold_wall_temperature, 2)
    ]
예제 #5
0
    def dirichlet_boundary_conditions(sim):

        W = sim.solution_space

        return [
            fe.DirichletBC(sim.solution_subspaces["u"], fe.Constant((0, 0)),
                           (1, 2, 3)),
            fe.DirichletBC(sim.solution_subspaces["u"], fe.Constant((1, 0)), 4)
        ]
예제 #6
0
    def dirichlet_boundary_conditions(self):

        W = self.solution_space

        return [
            fe.DirichletBC(W.sub(1), (0., 0.), "on_boundary"),
            fe.DirichletBC(W.sub(2), 0.5, 1),
            fe.DirichletBC(W.sub(2), -0.5, 2)
        ]
예제 #7
0
def temperature_solver(T, t, beta, PeInv, solver_parameters, *, t1, INLET1, t2,
                       INLET2):
    F_T = AdvectionDiffusionGLS(T, beta, t, PeInv=PeInv)

    bc1 = fd.DirichletBC(T, t1, INLET1)
    bc2 = fd.DirichletBC(T, t2, INLET2)
    bcs = [bc1, bc2]
    problem_T = fd.NonlinearVariationalProblem(F_T, t, bcs=bcs)
    return fd.NonlinearVariationalSolver(problem_T,
                                         solver_parameters=solver_parameters)
def dirichlet_boundary_conditions(sim, manufactured_solution):
    """Apply velocity and temperature Dirichlet BC's on every boundary.
    
    Do not apply Dirichlet BC's on the pressure.
    """
    _, u, T = manufactured_solution
    
    return [
        fe.DirichletBC(sim.solution_subspaces["u"], u, "on_boundary"),
        fe.DirichletBC(sim.solution_subspaces["T"], T, "on_boundary")]
예제 #9
0
    def dirichlet_boundary_conditions(self):

        W = self.solution_space

        return [
            fe.DirichletBC(W.sub(1), (0., ) * self.mesh.geometric_dimension(),
                           "on_boundary"),
            fe.DirichletBC(W.sub(2), self.hotwall_temperature, 1),
            fe.DirichletBC(W.sub(2), self.initial_temperature, 2)
        ]
예제 #10
0
def dirichlet_boundary_conditions(sim):

    W = sim.function_space

    dim = sim.mesh.geometric_dimension()

    return [
        fe.DirichletBC(W.sub(1), (0., ) * dim, "on_boundary"),
        fe.DirichletBC(W.sub(2), sim.hot_wall_temperature, 1),
        fe.DirichletBC(W.sub(2), sim.cold_wall_temperature, 2)
    ]
예제 #11
0
    def dirichlet_boundary_conditions(self):

        W = self.solution.function_space()

        d = self.solution.function_space().mesh().geometric_dimension()

        return [
            fe.DirichletBC(W.sub(1), (0., ) * d, "on_boundary"),
            fe.DirichletBC(W.sub(2), self.hotwall_temperature,
                           self.hotwall_id),
            fe.DirichletBC(W.sub(2), self.coldwall_temperature,
                           self.coldwall_id)
        ]
        def setup_bcs(self):
            x, y = fd.SpatialCoordinate(self.mesh)

            bcu = [
                fd.DirichletBC(self.V['u'], fd.Constant((0, 0)),
                               (1, 4)),  # top-bottom and cylinder
                fd.DirichletBC(self.V['u'],
                               ((4.0 * 1.5 * y * (0.41 - y) / 0.41**2), 0), 2)
            ]  # inflow
            bcp = [fd.DirichletBC(self.V['p'], fd.Constant(0), 3)]  # outflow

            self.bc['u'][0] = [bcu, None, None, None, 'fixed']
            self.bc['p'] = [[bcp, None, None, None, 'fixed']]
        def setup_bcs(self):
            x, y = fd.SpatialCoordinate(self.mesh)

            bcu = [
                fd.DirichletBC(self.V['u'], fd.Constant((0, 0)),
                               (10, 12)),  # top-bottom
                fd.DirichletBC(self.V['u'],
                               ((1.0 * (y - 1) * (2 - y)) / (0.5**2), 0), 9)
            ]  # inflow
            bcp = [fd.DirichletBC(self.V['p'], fd.Constant(0), 11)]  # outflow

            self.bc['u'][0] = [bcu, None, None, None, 'fixed']
            self.bc['p'] = [[bcp, None, None, None, 'fixed']]
예제 #14
0
    def __init__(self, mesh_m, viscosity):
        super().__init__()
        self.mesh_m = mesh_m
        self.failed_to_solve = False  # when self.solver.solve() fail

        # Setup problem, Taylor-Hood finite elements
        self.V = fd.VectorFunctionSpace(self.mesh_m, "CG", 2) \
            * fd.FunctionSpace(self.mesh_m, "CG", 1)

        # Preallocate solution variables for state equation
        self.solution = fd.Function(self.V, name="State")
        self.testfunction = fd.TestFunction(self.V)

        # Define viscosity parameter
        self.viscosity = viscosity

        # Weak form of incompressible Navier-Stokes equations
        z = self.solution
        u, p = fd.split(z)
        test = self.testfunction
        v, q = fd.split(test)
        nu = self.viscosity  # shorten notation
        self.F = nu*fd.inner(fd.grad(u), fd.grad(v))*fd.dx - p*fd.div(v)*fd.dx\
            + fd.inner(fd.dot(fd.grad(u), u), v)*fd.dx + fd.div(u)*q*fd.dx

        # Dirichlet Boundary conditions
        X = fd.SpatialCoordinate(self.mesh_m)
        dim = self.mesh_m.topological_dimension()
        if dim == 2:
            uin = 4 * fd.as_vector([(1 - X[1]) * X[1], 0])
        elif dim == 3:
            rsq = X[0]**2 + X[1]**2  # squared radius = 0.5**2 = 1/4
            uin = fd.as_vector([0, 0, 1 - 4 * rsq])
        else:
            raise NotImplementedError
        self.bcs = [
            fd.DirichletBC(self.V.sub(0), 0., [12, 13]),
            fd.DirichletBC(self.V.sub(0), uin, [10])
        ]

        # PDE-solver parameters
        self.nsp = None
        self.params = {
            "snes_max_it": 10,
            "mat_type": "aij",
            "pc_type": "lu",
            "pc_factor_mat_solver_type": "superlu_dist",
            # "snes_monitor": None, "ksp_monitor": None,
        }
예제 #15
0
    def setup(self, **kwargs):
        for name, field in kwargs.items():
            if name in self._fields.keys():
                self._fields[name].assign(field)
            else:
                self._fields[name] = utilities.copy(field)

        # Create homogeneous BCs for the Dirichlet part of the boundary
        u = self._fields.get('velocity', self._fields.get('u'))
        V = u.function_space()
        bcs = firedrake.DirichletBC(V, u, self._dirichlet_ids)
        if not self._dirichlet_ids:
            bcs = None

        # Find the numeric IDs for the ice front
        boundary_ids = u.ufl_domain().exterior_facets.unique_markers
        ice_front_ids_comp = set(self._dirichlet_ids + self._side_wall_ids)
        ice_front_ids = list(set(boundary_ids) - ice_front_ids_comp)

        # Create the action and scale functionals
        _kwargs = {
            'side_wall_ids': self._side_wall_ids,
            'ice_front_ids': ice_front_ids
        }
        action = self._model.action(**self._fields, **_kwargs)
        F = firedrake.derivative(action, u)

        degree = self._model.quadrature_degree(**self._fields)
        params = {'form_compiler_parameters': {'quadrature_degree': degree}}
        problem = firedrake.NonlinearVariationalProblem(F, u, bcs, **params)
        self._solver = firedrake.NonlinearVariationalSolver(
            problem, solver_parameters=self._solver_parameters)
예제 #16
0
    def __init__(self, mesh_m):
        super().__init__()
        self.mesh_m = mesh_m

        # Setup problem
        self.V = fd.FunctionSpace(self.mesh_m, "CG", 1)

        # Preallocate solution variables for state and adjoint equations
        self.solution = fd.Function(self.V, name="State")

        # Weak form of Poisson problem
        u = self.solution
        v = fd.TestFunction(self.V)
        self.f = fd.Constant(4.)
        self.F = (fd.inner(fd.grad(u), fd.grad(v)) - self.f * v) * fd.dx
        self.bcs = fd.DirichletBC(self.V, 0., "on_boundary")

        # PDE-solver parameters
        self.params = {
            "ksp_type": "cg",
            "mat_type": "aij",
            "pc_type": "hypre",
            "pc_factor_mat_solver_package": "boomerang",
            "ksp_rtol": 1e-11,
            "ksp_atol": 1e-11,
            "ksp_stol": 1e-15,
        }

        stateproblem = fd.NonlinearVariationalProblem(self.F,
                                                      self.solution,
                                                      bcs=self.bcs)
        self.solver = fd.NonlinearVariationalSolver(
            stateproblem, solver_parameters=self.params)
예제 #17
0
 def get_mu(self, V):
     W = fd.FunctionSpace(V.mesh(), "CG", 1)
     bcs = []
     if len(self.fixed_bids):
         bcs.append(fd.DirichletBC(W, 1, self.fixed_bids))
     if len(self.free_bids):
         bcs.append(fd.DirichletBC(W, 10, self.free_bids))
     if len(bcs) == 0:
         bcs = None
     u = fd.TrialFunction(W)
     v = fd.TestFunction(W)
     a = fd.inner(fd.grad(u), fd.grad(v)) * fd.dx
     b = fd.inner(fd.Constant(0.), v) * fd.dx
     mu = fd.Function(W)
     fd.solve(a == b, mu, bcs=bcs)
     return mu
예제 #18
0
    def __init__(self, mesh_m):
        super().__init__()

        # Setup problem
        V = fd.FunctionSpace(mesh_m, "CG", 1)

        # Weak form of Poisson problem
        u = fd.Function(V, name="State")
        v = fd.TestFunction(V)
        f = fd.Constant(4.)
        self.F = (fd.inner(fd.grad(u), fd.grad(v)) - f * v) * fd.dx
        self.bcs = fd.DirichletBC(V, 0., "on_boundary")

        # PDE-solver parameters
        self.params = {
            "ksp_type": "cg",
            "mat_type": "aij",
            "pc_type": "hypre",
            "pc_factor_mat_solver_package": "boomerang",
            "ksp_rtol": 1e-11,
            "ksp_atol": 1e-11,
            "ksp_stol": 1e-15,
        }

        self.solution = u
        def setup_bcs(self):
            x, y = fd.SpatialCoordinate(self.mesh)
            c0 = fd.exp(x * y * self.t)

            bcu = [
                fd.DirichletBC(self.V['u'], fd.Constant((0, 0)),
                               (10, 12)),  # top-bottom and cylinder
                fd.DirichletBC(self.V['u'],
                               ((1.0 * (y - 1) * (2 - y)) / (0.5**2), 0), 9)
            ]  # inflow
            bcp = [fd.DirichletBC(self.V['p'], fd.Constant(0), 11)]  # outflow
            bcc1 = [fd.DirichletBC(self.V['c'].sub(0), c0, 'on_boundary')]

            self.bc['u'][0] = [bcu, None, None, None, 'fixed']
            self.bc['p'] = [[bcp, None, None, None, 'fixed']]
            self.bc['c'][0] = [bcc1, c0, 'on_boundary', 0, 'update']
예제 #20
0
def _newton_solve(z, E, scale, tolerance=1e-6, armijo=1e-4, max_iterations=50):
    F = derivative(E, z)
    H = derivative(F, z)

    Q = z.function_space()
    bc = firedrake.DirichletBC(Q, 0, 'on_boundary')
    p = firedrake.Function(Q)
    for iteration in range(max_iterations):
        firedrake.solve(H == -F, p, bc,
            solver_parameters={'ksp_type': 'preonly', 'pc_type': 'lu'})

        dE_dp = assemble(action(F, p))
        α = 1.0
        E0 = assemble(E)
        Ez = assemble(replace(E, {z: z + firedrake.Constant(α) * p}))
        while (Ez > E0 + armijo * α * dE_dp) or np.isnan(Ez):
            α /= 2
            Ez = assemble(replace(E, {z: z + firedrake.Constant(α) * p}))

        z.assign(z + firedrake.Constant(α) * p)
        if abs(dE_dp) < tolerance * assemble(scale):
            return z

    raise ValueError("Newton solver failed to converge after {0} iterations"
                     .format(max_iterations))
예제 #21
0
    def get_boundary_conditions(self):
        """Impose Dirichlet boundary conditions."""
        dim = self.mesh_m.cell_dimension()
        if dim == 2:
            zerovector = fd.Constant((0.0, 0.0))
        elif dim == 3:
            zerovector = fd.Constant((0.0, 0.0, 0.0))

        bcs = []
        if len(self.inflow_bids) is not None:
            bcs.append(
                fd.DirichletBC(self.V.sub(0), self.inflow_expr,
                               self.inflow_bids))
        if len(self.noslip_bids) > 0:
            bcs.append(
                fd.DirichletBC(self.V.sub(0), zerovector, self.noslip_bids))
        return bcs
예제 #22
0
    def setup(self, **kwargs):
        for name, field in kwargs.items():
            if name in self._fields.keys():
                self._fields[name].assign(field)
            else:
                if isinstance(field, firedrake.Constant):
                    self._fields[name] = firedrake.Constant(field)
                elif isinstance(field, firedrake.Function):
                    self._fields[name] = field.copy(deepcopy=True)
                else:
                    raise TypeError(
                        "Input %s field has type %s, must be Constant or Function!"
                        % (name, type(field))
                    )

        # Create homogeneous BCs for the Dirichlet part of the boundary
        u = self._fields["velocity"]
        V = u.function_space()
        # NOTE: This will have to change when we do Stokes!
        if hasattr(V._ufl_element, "_sub_element"):
            bcs = firedrake.DirichletBC(V, Constant((0, 0)), self._dirichlet_ids)
        else:
            bcs = firedrake.DirichletBC(V, Constant(0), self._dirichlet_ids)
        if not self._dirichlet_ids:
            bcs = None

        # Find the numeric IDs for the ice front
        boundary_ids = u.ufl_domain().exterior_facets.unique_markers
        ice_front_ids_comp = set(self._dirichlet_ids + self._side_wall_ids)
        ice_front_ids = list(set(boundary_ids) - ice_front_ids_comp)

        # Create the action and scale functionals
        _kwargs = {"side_wall_ids": self._side_wall_ids, "ice_front_ids": ice_front_ids}
        action = self._model.action(**self._fields, **_kwargs)
        scale = self._model.scale(**self._fields, **_kwargs)

        # Set up a minimization problem and solver
        quadrature_degree = self._model.quadrature_degree(**self._fields)
        params = {"quadrature_degree": quadrature_degree}
        problem = MinimizationProblem(action, scale, u, bcs, params)
        self._solver = NewtonSolver(
            problem,
            self._tolerance,
            solver_parameters=self._solver_parameters,
            max_iterations=self._max_iterations,
        )
예제 #23
0
 def __init__(self, function_space, state, boundary):
     self.state = state.clone()
     self.values = fire.Function(function_space)
     self.dofs = function_space.boundary_nodes(boundary, "topological")
     self.dirichlet = fire.DirichletBC(function_space,
                                       self.values,
                                       boundary,
                                       method="topological")
예제 #24
0
def dirichlet_boundary_conditions(sim, manufactured_solution):
    """Apply velocity Dirichlet BC's on every boundary."""
    
    p, u = manufactured_solution
    
    return [fe.DirichletBC(
        sim.solution_subspaces["u"],
        u,
        "on_boundary"),]
예제 #25
0
def dirichlet_boundary_conditions(sim, manufactured_solution):
    """Apply velocity Dirichlet BC's on every boundary."""
    W = sim.solution_space

    u, p = manufactured_solution

    return [
        fe.DirichletBC(W.sub(0), u, "on_boundary"),
    ]
예제 #26
0
def test_solver_no_flow_region():
    mesh = fd.Mesh("./2D_mesh.msh")
    no_flow = [2]
    no_flow_markers = [1]
    mesh = mark_no_flow_regions(mesh, no_flow, no_flow_markers)
    P2 = fd.VectorElement("CG", mesh.ufl_cell(), 1)
    P1 = fd.FiniteElement("CG", mesh.ufl_cell(), 1)
    TH = P2 * P1
    W = fd.FunctionSpace(mesh, TH)
    (v, q) = fd.TestFunctions(W)

    # Stokes 1
    w_sol1 = fd.Function(W)
    nu = fd.Constant(0.05)
    F = NavierStokesBrinkmannForm(W, w_sol1, nu, beta_gls=2.0)

    x, y = fd.SpatialCoordinate(mesh)
    u_mms = fd.as_vector(
        [sin(2.0 * pi * x) * sin(pi * y),
         sin(pi * x) * sin(2.0 * pi * y)])
    p_mms = -0.5 * (u_mms[0]**2 + u_mms[1]**2)
    f_mms_u = (grad(u_mms) * u_mms + grad(p_mms) -
               2.0 * nu * div(sym(grad(u_mms))))
    f_mms_p = div(u_mms)
    F += -inner(f_mms_u, v) * dx - f_mms_p * q * dx
    bc1 = fd.DirichletBC(W.sub(0), u_mms, "on_boundary")
    bc2 = fd.DirichletBC(W.sub(1), p_mms, "on_boundary")
    bc_no_flow = InteriorBC(W.sub(0), fd.Constant((0.0, 0.0)), no_flow_markers)

    solver_parameters = {"ksp_max_it": 500, "ksp_monitor": None}

    problem1 = fd.NonlinearVariationalProblem(F,
                                              w_sol1,
                                              bcs=[bc1, bc2, bc_no_flow])
    solver1 = NavierStokesBrinkmannSolver(
        problem1,
        options_prefix="navier_stokes",
        solver_parameters=solver_parameters,
    )
    solver1.solve()
    u_sol, _ = w_sol1.split()
    u_mms_func = fd.interpolate(u_mms, W.sub(0))
    error = fd.errornorm(u_sol, u_mms_func)
    assert error < 0.07
예제 #27
0
def run_solver(r):
    mesh = fd.UnitSquareMesh(2**r, 2**r)
    P2 = fd.VectorElement("CG", mesh.ufl_cell(), 1)
    P1 = fd.FiniteElement("CG", mesh.ufl_cell(), 1)
    TH = P2 * P1
    W = fd.FunctionSpace(mesh, TH)
    (v, q) = fd.TestFunctions(W)

    # Stokes 1
    w_sol1 = fd.Function(W)
    nu = fd.Constant(0.05)
    F = NavierStokesBrinkmannForm(W, w_sol1, nu, beta_gls=2.0)

    from firedrake import sin, grad, pi, sym, div, inner

    x, y = fd.SpatialCoordinate(mesh)
    u_mms = fd.as_vector(
        [sin(2.0 * pi * x) * sin(pi * y),
         sin(pi * x) * sin(2.0 * pi * y)])
    p_mms = -0.5 * (u_mms[0]**2 + u_mms[1]**2)
    f_mms_u = (grad(u_mms) * u_mms + grad(p_mms) -
               2.0 * nu * div(sym(grad(u_mms))))
    f_mms_p = div(u_mms)
    F += -inner(f_mms_u, v) * dx - f_mms_p * q * dx
    bc1 = fd.DirichletBC(W.sub(0), u_mms, "on_boundary")
    bc2 = fd.DirichletBC(W.sub(1), p_mms, "on_boundary")

    solver_parameters = {"ksp_max_it": 200}

    problem1 = fd.NonlinearVariationalProblem(F, w_sol1, bcs=[bc1, bc2])
    solver1 = NavierStokesBrinkmannSolver(
        problem1,
        options_prefix="navier_stokes",
        solver_parameters=solver_parameters,
    )
    solver1.solve()
    u_sol, _ = w_sol1.split()
    fd.File("test_u_sol.pvd").write(u_sol)
    u_mms_func = fd.interpolate(u_mms, W.sub(0))
    error = fd.errornorm(u_sol, u_mms_func)
    print(f"Error: {error}")
    return error
예제 #28
0
def mms_dirichlet_boundary_conditions(sim, manufactured_solution):

    W = sim.function_space

    if type(sim.element) is fe.FiniteElement:

        w = (manufactured_solution, )

    else:

        w = manufactured_solution

    return [fe.DirichletBC(V, g, "on_boundary") for V, g in zip(W, w)]
예제 #29
0
파일: pmg.py 프로젝트: dacreman/firedrake
 def coarsen_bcs(fbcs):
     cbcs = []
     for bc in fbcs:
         cV_ = cV
         for index in bc._indices:
             cV_ = cV_.sub(index)
         cbc_value = self.coarsen_bc_value(bc, cV_)
         if type(bc) == firedrake.DirichletBC:
             cbcs.append(firedrake.DirichletBC(cV_, cbc_value,
                                               bc.sub_domain))
         else:
             raise NotImplementedError("Unsupported BC type, please get in touch if you need this")
     return cbcs
예제 #30
0
파일: mms.py 프로젝트: mfkiwl/sapphire
def default_mms_dirichlet_boundary_conditions(sim, manufactured_solution):
    """Apply Dirichlet BC's to every component on every boundary."""
    W = sim.solution_space

    if type(W.ufl_element()) is fe.FiniteElement:

        w = (manufactured_solution, )

    else:

        w = manufactured_solution

    return [fe.DirichletBC(V, g, "on_boundary") for V, g in zip(W, w)]