Exemplo n.º 1
0
    def __init__(self, *args, bcs=None, J=None, Jp=None, method="topological", V=None, is_linear=False, Jp_eq_J=False):
        from firedrake.variational_solver import check_pde_args, is_form_consistent
        if isinstance(args[0], ufl.classes.Equation):
            # initial construction from equation
            eq = args[0]
            u = args[1]
            sub_domain = args[2]
            if V is None:
                V = eq.lhs.arguments()[0].function_space()
            bcs = solving._extract_bcs(bcs)
            # Jp_eq_J is progressively evaluated as the tree is constructed
            self.Jp_eq_J = Jp is None and all([bc.Jp_eq_J for bc in bcs])

            # linear
            if isinstance(eq.lhs, ufl.Form) and isinstance(eq.rhs, ufl.Form):
                J = eq.lhs
                Jp = Jp or J
                if eq.rhs == 0:
                    F = ufl_expr.action(J, u)
                else:
                    if not isinstance(eq.rhs, (ufl.Form, slate.slate.TensorBase)):
                        raise TypeError("Provided BC RHS is a '%s', not a Form or Slate Tensor" % type(eq.rhs).__name__)
                    if len(eq.rhs.arguments()) != 1:
                        raise ValueError("Provided BC RHS is not a linear form")
                    F = ufl_expr.action(J, u) - eq.rhs
                self.is_linear = True
            # nonlinear
            else:
                if eq.rhs != 0:
                    raise TypeError("RHS of a nonlinear form equation has to be 0")
                F = eq.lhs
                J = J or ufl_expr.derivative(F, u)
                Jp = Jp or J
                self.is_linear = False
            # Check form style consistency
            is_form_consistent(self.is_linear, bcs)
            # Argument checking
            check_pde_args(F, J, Jp)
            # EquationBCSplit objects for `F`, `J`, and `Jp`
            self._F = EquationBCSplit(F, u, sub_domain, bcs=[bc if isinstance(bc, DirichletBC) else bc._F for bc in bcs], method=method, V=V)
            self._J = EquationBCSplit(J, u, sub_domain, bcs=[bc if isinstance(bc, DirichletBC) else bc._J for bc in bcs], method=method, V=V)
            self._Jp = EquationBCSplit(Jp, u, sub_domain, bcs=[bc if isinstance(bc, DirichletBC) else bc._Jp for bc in bcs], method=method, V=V)
        elif all(isinstance(args[i], EquationBCSplit) for i in range(3)):
            # reconstruction for splitting `solving_utils.split`
            self.Jp_eq_J = Jp_eq_J
            self.is_linear = is_linear
            self._F = args[0]
            self._J = args[1]
            self._Jp = args[2]
        else:
            raise TypeError("Wrong EquationBC arguments")
Exemplo n.º 2
0
    def __init__(self, *args, bcs=None, J=None, Jp=None, method="topological", V=None, is_linear=False, Jp_eq_J=False):
        from firedrake.variational_solver import check_pde_args, is_form_consistent
        if isinstance(args[0], ufl.classes.Equation):
            # initial construction from equation
            eq = args[0]
            u = args[1]
            sub_domain = args[2]
            if V is None:
                V = eq.lhs.arguments()[0].function_space()
            bcs = solving._extract_bcs(bcs)
            # Jp_eq_J is progressively evaluated as the tree is constructed
            self.Jp_eq_J = Jp is None and all([bc.Jp_eq_J for bc in bcs])

            # linear
            if isinstance(eq.lhs, ufl.Form) and isinstance(eq.rhs, ufl.Form):
                J = eq.lhs
                Jp = Jp or J
                if eq.rhs == 0:
                    F = ufl_expr.action(J, u)
                else:
                    if not isinstance(eq.rhs, (ufl.Form, slate.slate.TensorBase)):
                        raise TypeError("Provided BC RHS is a '%s', not a Form or Slate Tensor" % type(eq.rhs).__name__)
                    if len(eq.rhs.arguments()) != 1:
                        raise ValueError("Provided BC RHS is not a linear form")
                    F = ufl_expr.action(J, u) - eq.rhs
                self.is_linear = True
            # nonlinear
            else:
                if eq.rhs != 0:
                    raise TypeError("RHS of a nonlinear form equation has to be 0")
                F = eq.lhs
                J = J or ufl_expr.derivative(F, u)
                Jp = Jp or J
                self.is_linear = False
            # Check form style consistency
            is_form_consistent(self.is_linear, bcs)
            # Argument checking
            check_pde_args(F, J, Jp)
            # EquationBCSplit objects for `F`, `J`, and `Jp`
            self._F = EquationBCSplit(F, u, sub_domain, bcs=[bc if isinstance(bc, DirichletBC) else bc._F for bc in bcs], method=method, V=V)
            self._J = EquationBCSplit(J, u, sub_domain, bcs=[bc if isinstance(bc, DirichletBC) else bc._J for bc in bcs], method=method, V=V)
            self._Jp = EquationBCSplit(Jp, u, sub_domain, bcs=[bc if isinstance(bc, DirichletBC) else bc._Jp for bc in bcs], method=method, V=V)
        elif all(isinstance(args[i], EquationBCSplit) for i in range(3)):
            # reconstruction for splitting `solving_utils.split`
            self.Jp_eq_J = Jp_eq_J
            self.is_linear = is_linear
            self._F = args[0]
            self._J = args[1]
            self._Jp = args[2]
        else:
            raise TypeError("Wrong EquationBC arguments")