Exemplo n.º 1
0
  def __init__(self, coarse_mesh, nref, p_coarse, p_fine):
    super(LaplaceEigenvalueProblem, self).__init__(coarse_mesh, nref, p_coarse, p_fine)

    print0("Assembling fine-mesh problem")

    self.dirichlet_bdry = lambda x,on_boundary: on_boundary

    bc = DirichletBC(self.V_fine, 0.0, self.dirichlet_bdry)
    u = TrialFunction(self.V_fine)
    v = TestFunction(self.V_fine)
    a = inner(grad(u), grad(v))*dx
    m = u*v*dx

    # Assemble the stiffness matrix and the mass matrix.
    b = v*dx # just need this to feed an argument to assemble_system
    assemble_system(a, b, bc, A_tensor=self.A_fine)
    assemble_system(m, b, bc, A_tensor=self.B_fine)
    # set the diagonal elements of M corresponding to boundary nodes to zero to
    # remove spurious eigenvalues.
    bc.zero(self.B_fine)

    print0("Assembling coarse-mesh problem")

    self.bc_coarse = DirichletBC(self.V_coarse, 0.0, self.dirichlet_bdry)
    u = TrialFunction(self.V_coarse)
    v = TestFunction(self.V_coarse)
    a = inner(grad(u), grad(v))*dx
    m = u*v*dx

    # Assemble the stiffness matrix and the mass matrix, without Dirichlet BCs. Dirichlet DOFs will be removed later.
    assemble(a, tensor=self.A_coarse)
    assemble(m, tensor=self.B_coarse)
Exemplo n.º 2
0
 def solveFwd(self, state, x, tol):
     """ Solve the possibly nonlinear forward problem:
     Given :math:`m`, find :math:`u` such that
     
         .. math:: \\delta_p F(u, m, p;\\hat{p}) = 0,\\quad \\forall \\hat{p}."""
     if self.solver is None:
         self.solver = self._createLUSolver()
     if self.is_fwd_linear:
         u = dl.TrialFunction(self.Vh[STATE])
         m = vector2Function(x[PARAMETER], self.Vh[PARAMETER])
         p = dl.TestFunction(self.Vh[ADJOINT])
         res_form = self.varf_handler(u, m, p)
         A_form = dl.lhs(res_form)
         b_form = dl.rhs(res_form)
         A, b = dl.assemble_system(A_form, b_form, bcs=self.bc)
         self.solver.set_operator(A)
         self.solver.solve(state, b)
     else:
         u = vector2Function(x[STATE], self.Vh[STATE])
         m = vector2Function(x[PARAMETER], self.Vh[PARAMETER])
         p = dl.TestFunction(self.Vh[ADJOINT])
         res_form = self.varf_handler(u, m, p)
         dl.solve(res_form == 0, u, self.bc)
         state.zero()
         state.axpy(1., u.vector())
Exemplo n.º 3
0
    def __init__(self, a, L, u, bcs):
        '''
        Solve a problem of this form:
        a u = L

        '''

        if bcs is None:
            bcs = ()
        elif not isinstance(bcs, (list, tuple)):
            bcs = (bcs, )
        if not all(isinstance(bc, DirichletBC) for bc in bcs):
            raise TypeError('Parameter `bcs` must contain '
                            'homogenized `DirichletBC`(\'s)')

        V = u.function_space()
        v0 = dolfin.TestFunction(V)

        L_dummy = dot(v0, Constant((0.0, ) * len(u))) * dx
        K, self._rhs_bcs = assemble_system(a, L_dummy, bcs)
        self._solver = dolfin.LUSolver(K, "mumps")

        dof_bcs = []
        for bc in bcs:
            dof_bcs.extend(bc.get_boundary_values().keys())
        self._dof_bcs = tuple(sorted(dof_bcs))

        self._x = u.vector()
        self._L = L
Exemplo n.º 4
0
    def __init__(self, adjoint_a, L, z, bcs):
        '''
        Solve a problem of this form:
        adjoint_a z = L

        Note, "adjoint" means that the Dirichlet boundary conditions are zero.

        '''

        if bcs is None:
            bcs = ()
        elif not isinstance(bcs, (list, tuple)):
            bcs = (bcs, )
        if not all(isinstance(bc, DirichletBC) for bc in bcs):
            raise TypeError('Parameter `bcs` must contain '
                            'homogenized `DirichletBC`(\'s)')
        if any(any(bc.get_boundary_values().values()) for bc in bcs):
            raise ValueError('Parameter `bcs` must contain '
                             'homogenized `DirichletBC`(\'s)')

        V = z.function_space()
        v0 = dolfin.TestFunction(V)

        if adjoint_a is not None:
            L_dummy = dot(v0, Constant((0.0, ) * len(z))) * dx
            K, _ = assemble_system(adjoint_a, L_dummy, bcs)
            self._solver = dolfin.LUSolver(K, "mumps")

        dof_bcs = []
        for bc in bcs:
            dof_bcs.extend(bc.get_boundary_values().keys())
        self._dof_bcs = tuple(sorted(dof_bcs))

        self._x = z.vector()
        self._L = L
Exemplo n.º 5
0
    def assemble_rhs(self, basis, coeff=None, withDirichletBC=True, withNeumannBC=True, f=None):
        """Assemble the discrete right-hand side."""
        coeff = get_default(coeff, self.coeff)
        f = get_default(f, self.f)
        Dirichlet_boundary = self.dirichlet_boundary
        uD = self.uD

        # get FEniCS function space
        V = basis._fefs
        a = self.weak_form.bilinear_form(V, coeff)
        L = self.weak_form.loading_linear_form(V, f)

        # treat Neumann boundary
        if withNeumannBC and self.neumann_boundary:
            L += self.weak_form.neumann_linear_form(V, self.neumann_boundary, self.g)

        # treat Dirichlet boundary
        bcs = []
        if withDirichletBC:
            bcs = self.create_dirichlet_bcs(V, self.uD, self.dirichlet_boundary)

        # assemble linear form
        if True:    # activate quick hack for system assembler
            facet_function = self.weak_form.neumann_facet_function(self.neumann_boundary, self.g, V.mesh())
            _, F = _assemble_system(a, L, bcs, facet_function)
        else:
            _, F = assemble_system(a, L, bcs)
        return F
Exemplo n.º 6
0
def system0(n):
    import dolfin as df
    mesh = df.UnitIntervalMesh(n)
    V = df.FunctionSpace(mesh, 'CG', 1)
    u = df.TrialFunction(V)
    v = df.TestFunction(V)
    bc = df.DirichletBC(V, df.Constant(0), 'on_boundary')

    a = df.inner(df.grad(u), df.grad(v))*df.dx
    m = df.inner(u, v)*df.dx
    L = df.inner(df.Constant(0), v)*df.dx

    A, _ = df.assemble_system(a, L, bc)
    M, _ = df.assemble_system(m, L, bc)

    return A, M
Exemplo n.º 7
0
    def assign_initial_conditions(self, function):
        function_space = function.function_space()
        markers = self.markers()

        u = TrialFunction(function_space)
        v = TestFunction(function_space)

        dy = Measure("dx", domain=self.mesh(), subdomain_data=markers)

        # Define projection into multiverse
        a = inner(u, v) * dy()

        Ls = list()
        for k, model in enumerate(self.models()):
            ic = model.initial_conditions()  # Extract initial conditions
            n_k = model.num_states()  # Extract number of local states
            i_k = self.keys()[k]  # Extract domain index of cell model k
            L_k = sum(ic[j] * v[j] * dy(i_k)
                      for j in range(n_k + 1))  # include v and s
            Ls.append(L_k)
        L = sum(Ls)
        # solve(a == L, function)       # really inaccurate

        params = df.KrylovSolver.default_parameters()
        params["absolute_tolerance"] = 1e-14
        params["relative_tolerance"] = 1e-14
        params["nonzero_initial_guess"] = True
        solver = df.KrylovSolver()
        solver.update_parameters(params)
        A, b = df.assemble_system(a, L)
        solver.set_operator(A)
        solver.solve(function.vector(), b)
Exemplo n.º 8
0
    def setLinearizationPoint(self, x, gauss_newton_approx):
        """ Set the values of the state and parameter
            for the incremental forward and adjoint solvers. """

        x_fun = [vector2Function(x[i], self.Vh[i]) for i in range(3)]

        f_form = self.varf_handler(*x_fun)

        g_form = [None, None, None]
        for i in range(3):
            g_form[i] = dl.derivative(f_form, x_fun[i])

        self.A, dummy = dl.assemble_system(
            dl.derivative(g_form[ADJOINT], x_fun[STATE]), g_form[ADJOINT],
            self.bc0)
        self.At, dummy = dl.assemble_system(
            dl.derivative(g_form[STATE], x_fun[ADJOINT]), g_form[STATE],
            self.bc0)
        self.C = dl.assemble(dl.derivative(g_form[ADJOINT], x_fun[PARAMETER]))
        [bc.zero(self.C) for bc in self.bc0]

        if self.solver_fwd_inc is None:
            self.solver_fwd_inc = self._createLUSolver()
            self.solver_adj_inc = self._createLUSolver()

        self.solver_fwd_inc.set_operator(self.A)
        self.solver_adj_inc.set_operator(self.At)

        if gauss_newton_approx:
            self.Wuu = None
            self.Wmu = None
            self.Wmm = None
        else:
            self.Wuu = dl.assemble(dl.derivative(g_form[STATE], x_fun[STATE]))
            [bc.zero(self.Wuu) for bc in self.bc0]
            Wuu_t = Transpose(self.Wuu)
            [bc.zero(Wuu_t) for bc in self.bc0]
            self.Wuu = Transpose(Wuu_t)
            self.Wmu = dl.assemble(
                dl.derivative(g_form[PARAMETER], x_fun[STATE]))
            Wmu_t = Transpose(self.Wmu)
            [bc.zero(Wmu_t) for bc in self.bc0]
            self.Wmu = Transpose(Wmu_t)
            self.Wmm = dl.assemble(
                dl.derivative(g_form[PARAMETER], x_fun[PARAMETER]))
Exemplo n.º 9
0
def run_steady_state_model(function_space,
                           kappa,
                           forcing,
                           boundary_conditions=None,
                           velocity=None):
    """
    Solve steady-state diffusion equation

    -grad (k* grad u) = f
    """
    mesh = function_space.mesh()

    if boundary_conditions == None:
        bndry_obj = dl.CompiledSubDomain("on_boundary")
        boundary_conditions = [['dirichlet', bndry_obj, dl.Constant(0)]]

    num_bndrys = len(boundary_conditions)
    boundaries = mark_boundaries(mesh, boundary_conditions)
    dirichlet_bcs = collect_dirichlet_boundaries(function_space,
                                                 boundary_conditions,
                                                 boundaries)

    # To express integrals over the boundary parts using ds(i), we must first
    # redefine the measure ds in terms of our boundary markers:
    ds = dl.Measure('ds', domain=mesh, subdomain_data=boundaries)
    dx = dl.Measure('dx', domain=mesh)

    # Variational problem at each time
    u = dl.TrialFunction(function_space)
    v = dl.TestFunction(function_space)

    a = kappa * dl.inner(dl.grad(u), dl.grad(v)) * dx
    L = forcing * v * dx

    if velocity is not None:
        a += v * dl.dot(velocity, dl.grad(u)) * dx

    beta_1_list = []
    alpha_1_list = []
    for ii in range(num_bndrys):
        if (boundary_conditions[ii][0] == 'robin'):
            alpha = boundary_conditions[ii][3]
            a += alpha * u * v * ds(ii)

        if ((boundary_conditions[ii][0] == 'robin')
                or (boundary_conditions[ii][0] == 'neumann')):
            beta = boundary_conditions[ii][2]
            L -= beta * v * ds(ii)

    u = dl.Function(function_space)
    A, b = dl.assemble_system(a, L, dirichlet_bcs)
    # apply boundary conditions
    for bc in dirichlet_bcs:
        bc.apply(A, b)
    dl.solve(A, u.vector(), b)

    return u
Exemplo n.º 10
0
    def _get_constant_pressure(self, W):
        w = TrialFunction(W)
        w_ = TestFunction(W)
        p_ = self.test_functions()["p"]
        A, b = assemble_system(inner(w, w_) * dx, p_ * dx)
        null_fcn = Function(W)
        solver = LUSolver("mumps")
        solver.solve(A, null_fcn.vector(), b)

        return null_fcn
Exemplo n.º 11
0
    def setLinearizationPoint(self,x):
        return
        assert False
        assert self.extra_args[-1] == True
        """ Set the values of the state and parameter
            for the incremental Fwd and Adj solvers """
        state_fun = vector2Function(x[STATE], self.Vh[STATE])
        param_fun = vector2Function(x[PARAMETER], self.Vh[PARAMETER])
        adjoint_fun = vector2Function(x[ADJOINT], self.Vh[ADJOINT])
        
        x_fun = [state_fun,param_fun, adjoint_fun]
        x_test = [dl.TestFunction(self.Vh[STATE]),
                  dl.TestFunction(self.Vh[PARAMETER]),
                  dl.TestFunction(self.Vh[ADJOINT])]
        x_trial = [dl.TrialFunction(self.Vh[STATE]),
                  dl.TrialFunction(self.Vh[PARAMETER]),
                  dl.TrialFunction(self.Vh[ADJOINT])]
        
        self.extra_args[self.parameter_location] = param_fun
        f_form = self.model.residual(state_fun, adjoint_fun, *self.extra_args )
        
        g_form = [None,None,None]
        g_form[STATE] = dl.derivative(f_form, x_fun[STATE], x_test[STATE])
        g_form[PARAMETER] = dl.derivative(f_form, x_fun[PARAMETER], x_test[PARAMETER])
        g_form[ADJOINT] = dl.derivative(f_form, x_fun[ADJOINT], x_test[ADJOINT])

        
        Aform = dl.derivative(g_form[ADJOINT],state_fun, x_trial[STATE])
        self.A, dummy = dl.assemble_system(Aform, g_form[ADJOINT], self.bcs0, form_compiler_parameters = self.fcp)
        self.C = dl.assemble(dl.derivative(g_form[ADJOINT],param_fun, x_trial[PARAMETER]),form_compiler_parameters = self.fcp )
        [bc.zero(self.C) for bc in self.bcs0]
        self.Wum = dl.assemble(dl.derivative(g_form[STATE],param_fun, x_trial[PARAMETER]), form_compiler_parameters = self.fcp)
        [bc.zero(self.Wum) for bc in self.bcs0]
        
        Wuuform = dl.derivative(g_form[STATE],state_fun, x_trial[STATE])
        self.Wuu, dummy = dl.assemble_system(Wuuform, g_form[STATE], self.bcs0, form_compiler_parameters = self.fcp)
        [bc.zero(self.Wuu) for bc in self.bcs0]

        self.Wmm = dl.assemble(dl.derivative(g_form[PARAMETER],param_fun, x_trial[PARAMETER]), form_compiler_parameters = self.fcp)
        
        self.Asolver.set_operator(self.A)
        self.extra_args[self.parameter_location] = None
Exemplo n.º 12
0
    def setLinearizationPoint(self,x, gauss_newton_approx):
        """ Set the values of the state and parameter
            for the incremental Fwd and Adj solvers """
        u = vector2Function(x[STATE], self.Vh[STATE])
        a = vector2Function(x[PARAMETER], self.Vh[PARAMETER])
        p = vector2Function(x[ADJOINT], self.Vh[ADJOINT])
        x_fun = [u,a,p]
        
        f_form = self.varf_handler(u,a,p)
        
        g_form = [None,None,None]
        for i in range(3):
            g_form[i] = dl.derivative(f_form, x_fun[i])
            
        self.A, dummy = dl.assemble_system(dl.derivative(g_form[ADJOINT],u), g_form[ADJOINT], self.bc0)
        self.At, dummy = dl.assemble_system(dl.derivative(g_form[STATE],p),  g_form[STATE], self.bc0)
        self.C = dl.assemble(dl.derivative(g_form[ADJOINT],a))
        [bc.zero(self.C) for bc in self.bc0]
                
        if self.solver_fwd_inc is None:
            self.solver_fwd_inc = self._createLUSolver()
            self.solver_adj_inc = self._createLUSolver()
        
        self.solver_fwd_inc.set_operator(self.A)
        self.solver_adj_inc.set_operator(self.At)

        if gauss_newton_approx:
            self.Wuu = None
            self.Wau = None
            self.Waa = None
        else:
            self.Wuu = dl.assemble(dl.derivative(g_form[STATE],u))
            [bc.zero(self.Wuu) for bc in self.bc0]
            Wuu_t = Transpose(self.Wuu)
            [bc.zero(Wuu_t) for bc in self.bc0]
            self.Wuu = Transpose(Wuu_t)
            self.Wau = dl.assemble(dl.derivative(g_form[PARAMETER],u))
            Wau_t = Transpose(self.Wau)
            [bc.zero(Wau_t) for bc in self.bc0]
            self.Wau = Transpose(Wau_t)
            self.Waa = dl.assemble(dl.derivative(g_form[PARAMETER],a))
    def Jacobian(self, x, extra_args=()):
        """
        Assemble the Jacobian operator at point x.
        extra_args is a tuple of additional arguments necessary to assemble the Jacobian
        """
        xfun = vector2Function(x, self.Vh)

        Jform = self.model.Jacobian(xfun, self.x_test, self.x_trial, *extra_args)
                                    
        J, dummy = dl.assemble_system(Jform, self.dummyform, self.bcs0, form_compiler_parameters=self.fcp)
        
        return J
Exemplo n.º 14
0
 def assembleA(self,x, assemble_adjoint = False, assemble_rhs = False):
     """
     Assemble the matrices and rhs for the forward/adjoint problems
     """
     trial = dl.TrialFunction(self.Vh[STATE])
     test = dl.TestFunction(self.Vh[STATE])
     m = vector2Function(x[PARAMETER], self.Vh[PARAMETER])
     Avarf = ufl.inner(ufl.exp(m)*sigma(trial), strain(test))*ufl.dx
     if not assemble_adjoint:
         bform = ufl.inner(self.f, test)*ufl.dx
         Matrix, rhs = dl.assemble_system(Avarf, bform, self.bc)
     else:
         # Assemble the adjoint of A (i.e. the transpose of A)
         u = vector2Function(x[STATE], self.Vh[STATE])
         obs = vector2Function(self.u_o, self.Vh[STATE])
         bform = ufl.inner(obs - u, test)*ufl.dx
         Matrix, rhs = dl.assemble_system(dl.adjoint(Avarf), bform, self.bc0)
         
     if assemble_rhs:
         return Matrix, rhs
     else:
         return Matrix
Exemplo n.º 15
0
    def assemble_lhs(self, basis, coeff=None, withDirichletBC=True):
        """Assemble the discrete problem (i.e. the stiffness matrix)."""
        # get FEniCS function space
        V = basis._fefs
        coeff = get_default(coeff, self.coeff)

        a = self.weak_form.bilinear_form(V, coeff)
        L = self.weak_form.loading_linear_form(V, self.f)
        bcs = []
        if withDirichletBC:
            bcs = self.create_dirichlet_bcs(V, self.uD, self.dirichlet_boundary)
        A, _ = assemble_system(a, L, bcs)
        return A
Exemplo n.º 16
0
 def assembleA(self,x, assemble_adjoint = False, assemble_rhs = False):
     """
     Assemble the matrices and rhs for the forward/adjoint problems
     """
     trial = dl.TrialFunction(self.Vh[STATE])
     test = dl.TestFunction(self.Vh[STATE])
     m = vector2Function(x[PARAMETER], self.Vh[PARAMETER])
     Avarf = dl.inner(dl.exp(m)*dl.grad(trial), dl.grad(test))*dl.dx
     if not assemble_adjoint:
         bform = dl.inner(self.f, test)*dl.dx
         Matrix, rhs = dl.assemble_system(Avarf, bform, self.bc)
     else:
         # Assemble the adjoint of A (i.e. the transpose of A)
         u = vector2Function(x[STATE], self.Vh[STATE])
         obs = vector2Function(self.u_o, self.Vh[STATE])
         bform = dl.inner(obs - u, test)*dl.dx
         Matrix, rhs = dl.assemble_system(dl.adjoint(Avarf), bform, self.bc0)
         
     if assemble_rhs:
         return Matrix, rhs
     else:
         return Matrix
Exemplo n.º 17
0
    def assemble(self):

        ## Time function execution ##
        timer = df.Timer("pFibs: Assemble")
        timer.start()

        if self.log_level >= 1:
            ## Time system assembly ##
            timer1 = df.Timer("pFibs: Assemble - System")

        ## Assembly system of equations ##
        df.assemble_system(self.a,
                           self.L,
                           self.bcs,
                           A_tensor=self.A,
                           b_tensor=self.b)
        if self.log_level >= 1:
            timer1.stop()

        if self.log_level >= 1:
            ## Time preconditioner assembly ##
            timer2 = df.Timer("pFibs: Assemble - Preconditioner")

        ## Assemble preconditioner if provided ##
        if self.aP is not None:
            df.assemble(self.aP, tensor=self.P)
            if isinstance(self.bcs, list):
                for bc in self.bcs:
                    bc.apply(self.P)
            else:
                self.bcs.apply(self.P)
        if self.log_level >= 1:
            timer2.stop()

        # self.A.mat().zeroEntries()
        # self.A.mat().shift(1.0)

        timer.stop()
Exemplo n.º 18
0
    def assemble_system_fenics(self, x, bc, *, only_free_dofs=True):

        self.set_x(x)
        L = bc.neumann_boundary_condition.compile_form()

        K, f = df.assemble_system(self.a,
                                  L,
                                  bcs=bc.dirichlet_boundary_condition.transfer(
                                      self.V))

        if not only_free_dofs:
            return ConvertFenicsBackendToScipyCSRSparse(K), f
        else:
            raise NotImplementedError
Exemplo n.º 19
0
def harmonic_interpolation(setup,
                           points=(),
                           values=(),
                           subdomains=dict(),
                           boundaries=None):
    if isinstance(setup, Geometry):
        geo = setup
        phys = Physics(geo=geo)
        phys.update(cyl=phys.dim == 2)
    else:
        geo = setup.geo
        phys = setup.phys
    mesh = geo.mesh

    # Laplace equation
    V = dolfin.FunctionSpace(mesh, "CG", 1)
    u = dolfin.TrialFunction(V)
    v = dolfin.TestFunction(V)
    a = dolfin.inner(dolfin.grad(u), dolfin.grad(v)) * phys.r2pi * geo.dx()
    L = dolfin.Constant(0.) * v * phys.r2pi * geo.dx()

    # Point-wise boundary condition
    bc = PointBC(V, points, values)
    bcs = [bc]

    # Volume boundary conditions
    for sub, f in subdomains.items():
        bc = geo.VolumeBC(V, sub, f)
        bcs.append(bc)

    # Normal boundary conditions
    if boundaries is not None:
        bc = geo.pwBC(V, "", value=boundaries)
        bcs.extend(bc)

    # Assemble, apply bc and solve
    A, b = dolfin.assemble_system(a, L)
    for bc in bcs:
        bc.apply(A)
        bc.apply(b)

    u = dolfin.Function(V)
    dolfin.solve(A, u.vector(), b, "bicgstab", "hypre_euclid")
    #    if phys.cyl:
    #        dolfin.solve(A, u.vector(), b, "bicgstab", "hypre_euclid")
    #    else:
    #        dolfin.solve(A, u.vector(), b, "cg", "hypre_amg")
    return u
Exemplo n.º 20
0
 def solveAdj(self, adj, x, adj_rhs, tol):
     """ Solve the linear Adj Problem: 
         Given a, u; find p such that
         \delta_u F(u,a,p;\hat_u) = 0 \for all \hat_u
     """
     u = vector2Function(x[STATE], self.Vh[STATE])
     a = vector2Function(x[PARAMETER], self.Vh[PARAMETER])
     p = dl.Function(self.Vh[ADJOINT])
     du = dl.TestFunction(self.Vh[STATE])
     dp = dl.TrialFunction(self.Vh[ADJOINT])
     varf = self.varf_handler(u,a,p)
     adj_form = dl.derivative( dl.derivative(varf, u, du), p, dp )
     Aadj, dummy = dl.assemble_system(adj_form, dl.Constant(0.)*dl.inner(u,du)*dl.dx, self.bc0)
     solver = dl.PETScLUSolver()
     solver.set_operator(Aadj)
     solver.solve(adj, adj_rhs)
 def Norm(self, coeffsL2=None, coeffsH1=None, apply_bc=False):
     """
     Returns a finite element matrix for a (weighted) H^1 norm.
     INPUTS:
     - coeffsL2: weights for the L2 norm (DEFAULT: 1)
     - coeffsH1: weights for the H1 norm (DEFAULT: 1)
     - apply_bc: if True apply essential b.c. (DEFAULT: False) 
     """
     Wform = self.model.mass(self.x_trial, self.x_test, coeffsL2) \
             +self.model.stiffness(self.x_trial, self.x_test, coeffsH1)
     
     if apply_bc:
         W, dummy = dl.assemble_system(Wform, self.dummyform, self.bcs0, form_compiler_parameters=self.fcp)
     else:
         W =  dl.assemble(Wform, form_compiler_parameters=self.fcp)
         
     return W
Exemplo n.º 22
0
 def forward_sensitivities(self, sm, dm):
     
     assert self.extra_args[self.parameter_location] == None
     assert self.extra_args[self.field_location] == None
     assert self.extra_args[-1] == True
     
     d_state = dl.Function( self.Vh[STATE] ).vector()
     dd_state = dl.Function( self.Vh[STATE] ).vector()
     
     [state_fun, m_fun] = [vector2Function(sm[ii], self.Vh[ii]) for ii in range(2)]
     dm_fun = vector2Function(dm, self.Vh[PARAMETER])
     e_mean_fun =vector2Function(self.field.e_mean, self.Vh[FIELD])
     
     test = dl.TestFunction(self.Vh[STATE])
     trial = dl.TrialFunction(self.Vh[STATE])
     
     self.extra_args[self.parameter_location] = m_fun
     self.extra_args[self.field_location] = e_mean_fun
     
     res_form = self.model.residual(state_fun, test, *self.extra_args)
     
     J_form = dl.derivative(res_form, state_fun, trial)
     b1_form = dl.derivative(res_form, m_fun, dm_fun)
     
     J, b1 = dl.assemble_system(J_form, b1_form, bcs = self.bcs0, form_compiler_parameters = self.fcp)
     Jsolver = dl.PETScLUSolver()
     Jsolver.set_operator(J)
     Jsolver.solve(d_state, -b1)
     
     d_state_fun = vector2Function(d_state, self.Vh[STATE])
     
     b2_form = dl.derivative( dl.derivative(res_form, state_fun, d_state_fun), state_fun, d_state_fun ) \
              + dl.Constant(2.)*dl.derivative( dl.derivative(res_form, state_fun, d_state_fun), m_fun, dm_fun ) \
              + dl.derivative( dl.derivative(res_form, m_fun, dm_fun), m_fun, dm_fun )
              
     b2 = dl.assemble(b2_form, form_compiler_parameters=self.fcp)
     [bc.apply(b2) for bc in self.bcs0]
     
     Jsolver.solve(dd_state, -b2)
     
     self.extra_args[self.parameter_location] = None
     self.extra_args[self.field_location] = None
     
     return d_state, dd_state        
Exemplo n.º 23
0
def harmonic_interpolation_simple(mesh, points, values):
    # Laplace equation
    V = dolfin.FunctionSpace(mesh, "CG", 1)
    u = dolfin.TrialFunction(V)
    v = dolfin.TestFunction(V)
    a = dolfin.inner(dolfin.grad(u), dolfin.grad(v)) * dolfin.dx
    L = dolfin.Constant(0.) * v * dolfin.dx(domain=mesh)

    # Point-wise boundary condition
    bc = PointBC(V, points, values)

    # Assemble, apply bc and solve
    A, b = dolfin.assemble_system(a, L)
    bc.apply(A)
    bc.apply(b)

    u = dolfin.Function(V)
    dolfin.solve(A, u.vector(), b, "cg", "hypre_amg")
    return u
Exemplo n.º 24
0
def solve_krylov(
    a,
    L,
    bcs,
    u: df.Function,
    verbose: bool = False,
    ksp_type="cg",
    ksp_norm_type="unpreconditioned",
    ksp_atol=1e-15,
    ksp_rtol=1e-10,
    ksp_max_it=10000,
    ksp_error_if_not_converged=False,
    pc_type="hypre",
) -> df.PETScKrylovSolver:

    pc_hypre_type = "boomeramg"
    ksp_monitor = verbose
    ksp_view = verbose

    pc_view = verbose
    solver = df.PETScKrylovSolver()
    df.PETScOptions.set("ksp_type", ksp_type)
    df.PETScOptions.set("ksp_norm_type", ksp_norm_type)
    df.PETScOptions.set("ksp_atol", ksp_atol)
    df.PETScOptions.set("ksp_rtol", ksp_rtol)
    df.PETScOptions.set("ksp_max_it", ksp_max_it)
    df.PETScOptions.set("ksp_error_if_not_converged",
                        ksp_error_if_not_converged)
    if ksp_monitor:
        df.PETScOptions.set("ksp_monitor")
    if ksp_view:
        df.PETScOptions.set("ksp_view")
    df.PETScOptions.set("pc_type", pc_type)
    df.PETScOptions.set("pc_hypre_type", pc_hypre_type)
    if pc_view:
        df.PETScOptions.set("pc_view")
    solver.set_from_options()

    A, b = df.assemble_system(a, L, bcs)
    solver.set_operator(A)
    solver.solve(u.vector(), b)
    df.info("Sucessfully solved using Krylov solver")
    return solver
Exemplo n.º 25
0
	def assemble(self, ff, gs = [], hs = [], *, mesh = None, facets = None):
		if mesh is None:
			mesh = self.mesh
		space = self.getSpace(mesh)
		if facets is None:
			facets = self.facets
		dx = dolfin.Measure('dx', domain = mesh)
		ds = dolfin.ds if facets is None else dolfin.Measure('ds', domain = mesh, subdomain_data = facets)
		test = dolfin.TestFunction(space)
		trial = dolfin.TrialFunction(space)
		kk = dolfin.inner(self.sigma(trial), self.epsilon(test))*dx
		ll = dolfin.inner(ff, test)*dx
		for hh, domain in hs:
			ll += dolfin.inner(hh, test)*ds(domain)
		bcs = []
		for gg, domain in gs:
			bcs.append(dolfin.DirichletBC(space, gg, facets, domain))
		AA, bb = dolfin.assemble_system(kk, ll, bcs)
		return AA, bb
Exemplo n.º 26
0
 def solveAdj(self, adj, x, adj_rhs, tol):
     """ Solve the linear adjoint problem: 
         Given :math:`m, u`; find :math:`p` such that
         
             .. math:: \\delta_u F(u, m, p;\\hat{u}) = 0, \\quad \\forall \\hat{u}.
     """
     if self.solver is None:
         self.solver = self._createLUSolver()
         
     u = vector2Function(x[STATE], self.Vh[STATE])
     m = vector2Function(x[PARAMETER], self.Vh[PARAMETER])
     p = dl.Function(self.Vh[ADJOINT])
     du = dl.TestFunction(self.Vh[STATE])
     dp = dl.TrialFunction(self.Vh[ADJOINT])
     varf = self.varf_handler(u, m, p)
     adj_form = dl.derivative( dl.derivative(varf, u, du), p, dp )
     Aadj, dummy = dl.assemble_system(adj_form, dl.inner(u,du)*dl.dx, self.bc0)
     self.solver.set_operator(Aadj)
     self.solver.solve(adj, adj_rhs)
Exemplo n.º 27
0
    def linearize(self, inputs, outputs, partials):
        # print('linearize')
        residual_form = self.options['residual'](self.unfiltered_density, 
                                                    self.filtered_density,
                                                    C=self.filter_strength)
        J = df.derivative(residual_form, self.filtered_density)

        self.A, b = df.assemble_system(J, - residual_form)

        self.unfiltered_density.vector().set_local(inputs['density_unfiltered'])
        self.filtered_density.vector().set_local(outputs['density'])
        
        dR_dstate = self.compute_derivative('dR_dstate', self.filtered_density)
        dR_dinput = self.compute_derivative('dR_dinput', self.unfiltered_density)

        self.dR_du_sparse = df.as_backend_type(self.A).mat()
        
        partials['density','density'] = dR_dstate.data
        partials['density','density_unfiltered'] = dR_dinput.data
Exemplo n.º 28
0
    def solve(self, results_file=None):
        if self.solver is None:
            logger.warning("The solver has to be set.")
        if self.load_integrals is not None:
            L_terms = []
            for contrib_list in self.load_integrals.values():
                L_terms += contrib_list
            L = sum(L_terms)
        else:
            zero = fe.Constant(np.zeros(shape=self.v.ufl_shape))
            L = fe.dot(zero, self.v) * self.measures[self.part.dim]

        logger.info("Assembling system...")
        K, res = fe.assemble_system(self.a, L, self.Dirichlet_bc)
        logger.info("Assembling system : done")
        self.u_sol = fe.Function(self.displ_fspace)
        logger.info("Solving system...")
        self.solver.solve(K, self.u_sol.vector(), res)
        logger.info("Solving system : done")
        logger.info("Computing strain solution...")
        eps = mat.epsilon(self.u_sol)
        self.eps_sol = local_project(eps,
                                     self.strain_fspace,
                                     solver_method="LU")
        logger.info("Saving results...")
        if results_file is not None:
            try:
                if results_file.suffix != ".xdmf":
                    results_file = results_file.with_suffix(".xdmf")
            except AttributeError:
                results_file = Path(results_file).with_suffix(".xdmf")
            with fe.XDMFFile(results_file.as_posix()) as ofile:
                ofile.parameters["flush_output"] = False
                ofile.parameters["functions_share_mesh"] = True
                self.u_sol.rename("displacement",
                                  "displacement solution, full scale problem")
                self.eps_sol.rename("strain",
                                    "strain solution, full scale problem")
                ofile.write(self.u_sol, 0.0)
                ofile.write(self.eps_sol, 0.0)
        return self.u_sol
Exemplo n.º 29
0
    def _assemble_and_solve_adj_eq(self, dFdu_form, dJdu):
        dJdu_copy = dJdu.copy()
        bcs = self._homogenize_bcs()

        solver = self.block_helper.adjoint_solver
        if solver is None:

            adj_sol = df.Function(self.function_space)

            adjoint_problem = pf.BlockProblem(dFdu_form,
                                              dJdu,
                                              adj_sol,
                                              bcs=bcs)
            for key, value in self.block_field.items():
                adjoint_problem.field(key, value[1], solver=value[2])
            for key, value in self.block_split.items():
                adjoint_problem.split(key, value[0], solver=value[1])
            solver = pf.LinearBlockSolver(adjoint_problem)
            self.block_helper.adjoint_solver = solver

            ############
            ## Assemble ##
            rhs_bcs_form = df.inner(df.Function(self.function_space),
                                    dFdu_form.arguments()[0]) * df.dx
            A_, _ = df.assemble_system(dFdu_form, rhs_bcs_form, bcs)
            A = df.as_backend_type(A_)

            solver.linear_solver.set_operators(A, A)
            solver.linear_solver.init_solver_options()

        [bc.apply(dJdu) for bc in bcs]
        b = df.as_backend_type(dJdu)
        ## Actual solve ##
        its = solver.linear_solver.solve(adj_sol.vector(), b)
        ###########

        adj_sol_bdy = dfa.compat.function_from_vector(
            self.function_space, dJdu_copy -
            dfa.compat.assemble_adjoint_value(df.action(dFdu_form, adj_sol)))
        return adj_sol, adj_sol_bdy
Exemplo n.º 30
0
 def solveFwd(self, state, x, tol):
     """ Solve the possibly nonlinear Fwd Problem:
     Given a, find u such that
     \delta_p F(u,a,p;\hat_p) = 0 \for all \hat_p"""
     if self.is_fwd_linear:
         u = dl.TrialFunction(self.Vh[STATE])
         a = vector2Function(x[PARAMETER], self.Vh[PARAMETER])
         p = dl.TestFunction(self.Vh[ADJOINT])
         res_form = self.varf_handler(u, a, p)
         A_form = dl.lhs(res_form)
         b_form = dl.rhs(res_form)
         A, b = dl.assemble_system(A_form, b_form, bcs=self.bc)
         solver = dl.PETScLUSolver()
         solver.set_operator(A)
         solver.solve(state, b)
     else:
         u = vector2Function(x[STATE], self.Vh[STATE])
         a = vector2Function(x[PARAMETER], self.Vh[PARAMETER])
         p = dl.TestFunction(self.Vh[ADJOINT])
         res_form = self.varf_handler(u, a, p)
         dl.solve(res_form == 0, u, self.bc)
         state.zero()
         state.axpy(1., u.vector())
                def solve(selfmat, var, b):
                    if selfmat.adjoint:
                        operators = transpose_operators(selfmat.operators)
                    else:
                        operators = selfmat.operators

                    # Fetch/construct the solver
                    if var.type in ['ADJ_FORWARD', 'ADJ_TLM']:
                        solver = petsc_krylov_solvers[idx]
                        need_to_set_operator = self._need_to_reset_operator
                    else:
                        if adj_petsc_krylov_solvers[idx] is None:
                            need_to_set_operator = True
                            adj_petsc_krylov_solvers[idx] = PETScKrylovSolver(*solver_parameters)
                            adj_ksp = adj_petsc_krylov_solvers[idx].ksp()
                            fwd_ksp = petsc_krylov_solvers[idx].ksp()
                            adj_ksp.setOptionsPrefix(fwd_ksp.getOptionsPrefix())
                            adj_ksp.setType(fwd_ksp.getType())
                            adj_ksp.pc.setType(fwd_ksp.pc.getType())
                            adj_ksp.setFromOptions()
                        else:
                            need_to_set_operator = self._need_to_reset_operator
                        solver = adj_petsc_krylov_solvers[idx]
                        # FIXME: work around DOLFIN bug #583
                        try:
                            solver.parameters.convergence_norm_type
                        except:
                            solver.parameters.convergence_norm_type = "preconditioned"
                        # end FIXME
                    solver.parameters.update(parameters)
                    self._need_to_reset_operator = False

                    if selfmat.adjoint:
                        (nsp_, tnsp_) = (tnsp, nsp)
                    else:
                        (nsp_, tnsp_) = (nsp, tnsp)

                    x = dolfin.Function(fn_space)
                    if selfmat.initial_guess is not None and var.type == 'ADJ_FORWARD':
                        x.vector()[:] = selfmat.initial_guess.vector()

                    if b.data is None:
                        dolfin.info_red("Warning: got zero RHS for the solve associated with variable %s" % var)
                        return adjlinalg.Vector(x)

                    if var.type in ['ADJ_TLM', 'ADJ_ADJOINT']:
                        selfmat.bcs = [utils.homogenize(bc) for bc in selfmat.bcs if isinstance(bc, dolfin.cpp.DirichletBC)] + [bc for bc in selfmat.bcs if not isinstance(bc, dolfin.cpp.DirichletBC)]

                    # This is really hideous. Sorry.
                    if isinstance(b.data, dolfin.Function):
                        rhs = b.data.vector().copy()
                        [bc.apply(rhs) for bc in selfmat.bcs]

                        if need_to_set_operator:
                            if assemble_system: # if we called assemble_system, rather than assemble
                                v = dolfin.TestFunction(fn_space)
                                (A, rhstmp) = dolfin.assemble_system(operators[0], dolfin.inner(b.data, v)*dolfin.dx, selfmat.bcs)
                                if has_preconditioner:
                                    (P, rhstmp) = dolfin.assemble_system(operators[1], dolfin.inner(b.data, v)*dolfin.dx, selfmat.bcs)
                                    solver.set_operators(A, P)
                                else:
                                    solver.set_operator(A)
                            else: # we called assemble
                                A = dolfin.assemble(operators[0])
                                [bc.apply(A) for bc in selfmat.bcs]
                                if has_preconditioner:
                                    P = dolfin.assemble(operators[1])
                                    [bc.apply(P) for bc in selfmat.bcs]
                                    solver.set_operators(A, P)
                                else:
                                    solver.set_operator(A)
                    else:

                        if assemble_system: # if we called assemble_system, rather than assemble
                            (A, rhs) = dolfin.assemble_system(operators[0], b.data, selfmat.bcs)
                            if need_to_set_operator:
                                if has_preconditioner:
                                    (P, rhstmp) = dolfin.assemble_system(operators[1], b.data, selfmat.bcs)
                                    solver.set_operators(A, P)
                                else:
                                    solver.set_operator(A)
                        else: # we called assemble
                            A = dolfin.assemble(operators[0])
                            rhs = dolfin.assemble(b.data)
                            [bc.apply(A) for bc in selfmat.bcs]
                            [bc.apply(rhs) for bc in selfmat.bcs]
                            if need_to_set_operator:
                                if has_preconditioner:
                                    P = dolfin.assemble(operators[1])
                                    [bc.apply(P) for bc in selfmat.bcs]
                                    solver.set_operators(A, P)
                                else:
                                    solver.set_operator(A)

                    if need_to_set_operator:
                        print "|A|: %.6e" % A.norm("frobenius")

                    # Set the nullspace for the linear operator
                    if nsp_ is not None and need_to_set_operator:
                        dolfin.as_backend_type(A).set_nullspace(nsp_)

                    # (Possibly override the user in) orthogonalize
                    # the right-hand-side
                    if tnsp_ is not None:
                        tnsp_.orthogonalize(rhs)

                    print "%s: |b|: %.6e" % (var, rhs.norm("l2"))
                    solver.solve(x.vector(), rhs)
                    return adjlinalg.Vector(x)
Exemplo n.º 32
0
                def solve(self, var, b):
                    if self.adjoint:
                        operators = transpose_operators(self.operators)
                    else:
                        operators = self.operators

                    # Fetch/construct the solver
                    if var.type in ['ADJ_FORWARD', 'ADJ_TLM']:
                        solver = krylov_solvers[idx]
                        need_to_set_operator = False
                    else:
                        if adj_krylov_solvers[idx] is None:
                            need_to_set_operator = True
                            adj_krylov_solvers[idx] = KrylovSolver(*solver_parameters)
                        else:
                            need_to_set_operator = False
                        solver = adj_krylov_solvers[idx]
                    solver.parameters.update(parameters)

                    if self.adjoint:
                        (nsp_, tnsp_) = (tnsp, nsp)
                    else:
                        (nsp_, tnsp_) = (nsp, tnsp)

                    x = dolfin.Function(fn_space)
                    if self.initial_guess is not None and var.type == 'ADJ_FORWARD':
                        x.vector()[:] = self.initial_guess.vector()

                    if b.data is None:
                        dolfin.info_red("Warning: got zero RHS for the solve associated with variable %s" % var)
                        return adjlinalg.Vector(x)

                    if var.type in ['ADJ_TLM', 'ADJ_ADJOINT']:
                        self.bcs = [utils.homogenize(bc) for bc in self.bcs if isinstance(bc, dolfin.cpp.DirichletBC)] + [bc for bc in self.bcs if not isinstance(bc, dolfin.cpp.DirichletBC)]

                    # This is really hideous. Sorry.
                    if isinstance(b.data, dolfin.Function):
                        rhs = b.data.vector().copy()
                        [bc.apply(rhs) for bc in self.bcs]

                        if need_to_set_operator:
                            if assemble_system: # if we called assemble_system, rather than assemble
                                v = dolfin.TestFunction(fn_space)
                                (A, rhstmp) = dolfin.assemble_system(operators[0], dolfin.inner(b.data, v)*dolfin.dx, self.bcs)
                                if has_preconditioner:
                                    (P, rhstmp) = dolfin.assemble_system(operators[1], dolfin.inner(b.data, v)*dolfin.dx, self.bcs)
                                    solver.set_operators(A, P)
                                else:
                                    solver.set_operator(A)
                            else: # we called assemble
                                A = dolfin.assemble(operators[0])
                                [bc.apply(A) for bc in self.bcs]
                                if has_preconditioner:
                                    P = dolfin.assemble(operators[1])
                                    [bc.apply(P) for bc in self.bcs]
                                    solver.set_operators(A, P)
                                else:
                                    solver.set_operator(A)
                    else:

                        if assemble_system: # if we called assemble_system, rather than assemble
                            (A, rhs) = dolfin.assemble_system(operators[0], b.data, self.bcs)
                            if need_to_set_operator:
                                if has_preconditioner:
                                    (P, rhstmp) = dolfin.assemble_system(operators[1], b.data, self.bcs)
                                    solver.set_operators(A, P)
                                else:
                                    solver.set_operator(A)
                        else: # we called assemble
                            A = dolfin.assemble(operators[0])
                            rhs = dolfin.assemble(b.data)
                            [bc.apply(A) for bc in self.bcs]
                            [bc.apply(rhs) for bc in self.bcs]
                            if need_to_set_operator:
                                if has_preconditioner:
                                    P = dolfin.assemble(operators[1])
                                    [bc.apply(P) for bc in self.bcs]
                                    solver.set_operators(A, P)
                                else:
                                    solver.set_operator(A)

                    # Set the nullspace for the linear operator
                    if nsp_ is not None and need_to_set_operator:
                        dolfin.as_backend_type(A).set_nullspace(nsp_)

                    # (Possibly override the user in) orthogonalize
                    # the right-hand-side
                    if tnsp_ is not None:
                        tnsp_.orthogonalize(rhs)

                    solver.solve(x.vector(), rhs)
                    return adjlinalg.Vector(x)
Exemplo n.º 33
0
f = dfn.Expression(
    '500.0 * exp(-(pow(x[0] - 0.5, 2) + pow(x[1] - 0.5, 2)) / 0.02)', degree=1)
L = v * f * dfn.dx

# Define Dirichlet boundary (x = 0 or x = 1)


class DirichletBoundary(dfn.SubDomain):
    def inside(self, x, on_boundary):
        return x[0] < dfn.DOLFIN_EPS or x[0] > 1.0 - dfn.DOLFIN_EPS


u0 = dfn.Constant(0.0)
bc = dfn.DirichletBC(V, u0, DirichletBoundary())

A, rhs = dfn.assemble_system(a, L, bcs=bc)
############################################################

############################################################
# Part II: Solve with PyAMG
Asp = dfn.as_backend_type(A).sparray()
b = dfn.as_backend_type(rhs).array_view()

ml = pyamg.smoothed_aggregation_solver(Asp, max_coarse=10)
residuals = []
x = ml.solve(b, tol=1e-10, accel='cg', residuals=residuals)

residuals = residuals / residuals[0]
print(ml)
############################################################
Exemplo n.º 34
0
                def solve(self, var, b):
                    if self.adjoint:
                        operators = transpose_operators(self.operators)
                    else:
                        operators = self.operators

                    solver = dolfin.LinearSolver(*solver_parameters)
                    solver.parameters.update(parameters)

                    x = dolfin.Function(fn_space)
                    if self.initial_guess is not None and var.type == 'ADJ_FORWARD':
                        x.vector()[:] = self.initial_guess.vector()

                    if b.data is None:
                        dolfin.info_red("Warning: got zero RHS for the solve associated with variable %s" % var)
                        return adjlinalg.Vector(x)

                    if var.type in ['ADJ_TLM', 'ADJ_ADJOINT']:
                        self.bcs = [utils.homogenize(bc) for bc in self.bcs if isinstance(bc, dolfin.cpp.DirichletBC)] + [bc for bc in self.bcs if not isinstance(bc, dolfin.cpp.DirichletBC)]

                    # This is really hideous. Sorry.
                    if isinstance(b.data, dolfin.Function):
                        rhs = b.data.vector().copy()
                        [bc.apply(rhs) for bc in self.bcs]

                        if assemble_system: # if we called assemble_system, rather than assemble
                            v = dolfin.TestFunction(fn_space)
                            (A, rhstmp) = dolfin.assemble_system(operators[0], dolfin.inner(b.data, v)*dolfin.dx, self.bcs)
                            if has_preconditioner:
                                (P, rhstmp) = dolfin.assemble_system(operators[1], dolfin.inner(b.data, v)*dolfin.dx, self.bcs)
                                solver.set_operators(A, P)
                            else:
                                solver.set_operator(A)
                        else: # we called assemble
                            A = dolfin.assemble(operators[0])
                            [bc.apply(A) for bc in self.bcs]

                            # Set nullspace
                            if nsp:
                                dolfin.as_backend_type(A).set_nullspace(nsp)
                                nsp.orthogonalize(b);

                            if has_preconditioner:
                                P = dolfin.assemble(operators[1])
                                [bc.apply(P) for bc in self.bcs]
                                solver.set_operators(A, P)
                            else:
                                solver.set_operator(A)
                    else:

                        if assemble_system: # if we called assemble_system, rather than assemble
                            (A, rhs) = dolfin.assemble_system(operators[0], b.data, self.bcs)
                            if has_preconditioner:
                                (P, rhstmp) = dolfin.assemble_system(operators[1], b.data, self.bcs)
                                solver.set_operators(A, P)
                            else:
                                solver.set_operator(A)
                        else: # we called assemble
                            A = dolfin.assemble(operators[0])
                            rhs = dolfin.assemble(b.data)
                            [bc.apply(A) for bc in self.bcs]
                            [bc.apply(rhs) for bc in self.bcs]

                            # Set nullspace
                            if nsp:
                                dolfin.as_backend_type(A).set_nullspace(nsp)
                                nsp.orthogonalize(rhs);

                            if has_preconditioner:
                                P = dolfin.assemble(operators[1])
                                [bc.apply(P) for bc in self.bcs]
                                solver.set_operators(A, P)
                            else:
                                solver.set_operator(A)

                    solver.solve(x.vector(), rhs)
                    return adjlinalg.Vector(x)
Exemplo n.º 35
0
np.set_printoptions(formatter={'all': lambda x: '%.5E' % x})

def copy_to_vector(U, U_array):
    assert U.size() == len(U_array)
    U.set_local(U_array)
    U.apply('')

# Get the forms
# a, L, V, bc, Z = neumann_poisson_data()

a, L, V, bc, Z = neumann_elasticity_data()

# Turn to dolfin.la objects
parameters.linear_algebra_backend = 'uBLAS'  # this one provides Matrix.data
A, b = Matrix(), Vector()
assemble_system(a, L, A_tensor=A, b_tensor=b)

# Turn to scipy objects
rows, cols, values = A.data()
AA = csr_matrix((values, cols, rows))

bb = np.array(b.array())

# Okay, first claim is that CG solver can't solve the problem Ax=b if the
# rhs is not perpendicular to the nullspace
ZZ = [np.array(Zi.array()) for Zi in Z]

for ZZi in ZZ:
    print '<b, Zi> =', ZZi.dot(bb)
x, info = la.cg(AA, bb)
Exemplo n.º 36
0
def solve(W, P,
          mu,
          u_bcs, p_bcs,
          f,
          verbose=True,
          tol=1.0e-10
          ):
    # Some initial sanity checks.
    assert mu > 0.0

    WP = MixedFunctionSpace([W, P])

    # Translate the boundary conditions into the product space.
    # This conditional loop is able to deal with conditions of the kind
    #
    #     DirichletBC(W.sub(1), 0.0, right_boundary)
    #
    new_bcs = []
    for k, bcs in enumerate([u_bcs, p_bcs]):
        for bc in bcs:
            space = bc.function_space()
            C = space.component()
            if len(C) == 0:
                new_bcs.append(DirichletBC(WP.sub(k),
                                           bc.value(),
                                           bc.domain_args[0]))
            elif len(C) == 1:
                new_bcs.append(DirichletBC(WP.sub(k).sub(int(C[0])),
                                           bc.value(),
                                           bc.domain_args[0]))
            else:
                raise RuntimeError('Illegal number of subspace components.')

    # Define variational problem
    (u, p) = TrialFunctions(WP)
    (v, q) = TestFunctions(WP)

    # Build system.
    # The sign of the div(u)-term is somewhat arbitrary since the right-hand
    # side is 0 here. We can either make the system symmetric or positive-
    # definite.
    # On a second note, we have
    #
    #    \int grad(p).v = - \int p * div(v) + \int_\Gamma p n.v.
    #
    # Since, we have either p=0 or n.v=0 on the boundary, we could as well
    # replace the term dot(grad(p), v) by -p*div(v).
    #
    a = mu * inner(grad(u), grad(v))*dx \
      - p * div(v) * dx \
      - q * div(u) * dx
    #a = mu * inner(grad(u), grad(v))*dx + dot(grad(p), v) * dx \
    #  - div(u) * q * dx
    L = dot(f, v)*dx
    A, b = assemble_system(a, L, new_bcs)

    if has_petsc():
        # For an assortment of preconditioners, see
        #
        #     Performance and analysis of saddle point preconditioners
        #     for the discrete steady-state Navier-Stokes equations;
        #     H.C. Elman, D.J. Silvester, A.J. Wathen;
        #     Numer. Math. (2002) 90: 665-688;
        #     <http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.145.3554>.
        #
        # Set up field split.
        W = SubSpace(WP, 0)
        P = SubSpace(WP, 1)
        u_dofs = W.dofmap().dofs()
        p_dofs = P.dofmap().dofs()
        prec = PETScPreconditioner()
        prec.set_fieldsplit([u_dofs, p_dofs], ['u', 'p'])

        PETScOptions.set('pc_type', 'fieldsplit')
        PETScOptions.set('pc_fieldsplit_type', 'additive')
        PETScOptions.set('fieldsplit_u_pc_type', 'lu')
        PETScOptions.set('fieldsplit_p_pc_type', 'jacobi')

        ## <http://scicomp.stackexchange.com/questions/7288/which-preconditioners-and-solver-in-petsc-for-indefinite-symmetric-systems-sho>
        #PETScOptions.set('pc_type', 'fieldsplit')
        ##PETScOptions.set('pc_fieldsplit_type', 'schur')
        ##PETScOptions.set('pc_fieldsplit_schur_fact_type', 'upper')
        #PETScOptions.set('pc_fieldsplit_detect_saddle_point')
        ##PETScOptions.set('fieldsplit_u_pc_type', 'lsc')
        ##PETScOptions.set('fieldsplit_u_ksp_type', 'preonly')

        #PETScOptions.set('pc_type', 'fieldsplit')
        #PETScOptions.set('fieldsplit_u_pc_type', 'hypre')
        #PETScOptions.set('fieldsplit_u_ksp_type', 'preonly')
        #PETScOptions.set('fieldsplit_p_pc_type', 'jacobi')
        #PETScOptions.set('fieldsplit_p_ksp_type', 'preonly')

        ## From PETSc/src/ksp/ksp/examples/tutorials/ex42-fsschur.opts:
        #PETScOptions.set('pc_type', 'fieldsplit')
        #PETScOptions.set('pc_fieldsplit_type', 'SCHUR')
        #PETScOptions.set('pc_fieldsplit_schur_fact_type', 'UPPER')
        #PETScOptions.set('fieldsplit_p_ksp_type', 'preonly')
        #PETScOptions.set('fieldsplit_u_pc_type', 'bjacobi')

        ## From
        ##
        ##     Composable Linear Solvers for Multiphysics;
        ##     J. Brown, M. Knepley, D.A. May, L.C. McInnes, B. Smith;
        ##     <http://www.computer.org/csdl/proceedings/ispdc/2012/4805/00/4805a055-abs.html>;
        ##     <http://www.mcs.anl.gov/uploads/cels/papers/P2017-0112.pdf>.
        ##
        #PETScOptions.set('pc_type', 'fieldsplit')
        #PETScOptions.set('pc_fieldsplit_type', 'schur')
        #PETScOptions.set('pc_fieldsplit_schur_factorization_type', 'upper')
        ##
        #PETScOptions.set('fieldsplit_u_ksp_type', 'cg')
        #PETScOptions.set('fieldsplit_u_ksp_rtol', 1.0e-6)
        #PETScOptions.set('fieldsplit_u_pc_type', 'bjacobi')
        #PETScOptions.set('fieldsplit_u_sub_pc_type', 'cholesky')
        ##
        #PETScOptions.set('fieldsplit_p_ksp_type', 'fgmres')
        #PETScOptions.set('fieldsplit_p_ksp_constant_null_space')
        #PETScOptions.set('fieldsplit_p_pc_type', 'lsc')
        ##
        #PETScOptions.set('fieldsplit_p_lsc_ksp_type', 'cg')
        #PETScOptions.set('fieldsplit_p_lsc_ksp_rtol', 1.0e-2)
        #PETScOptions.set('fieldsplit_p_lsc_ksp_constant_null_space')
        ##PETScOptions.set('fieldsplit_p_lsc_ksp_converged_reason')
        #PETScOptions.set('fieldsplit_p_lsc_pc_type', 'bjacobi')
        #PETScOptions.set('fieldsplit_p_lsc_sub_pc_type', 'icc')

        # Create Krylov solver with custom preconditioner.
        solver = PETScKrylovSolver('gmres', prec)
        solver.set_operator(A)
    else:
        # Use the preconditioner as recommended in
        # <http://fenicsproject.org/documentation/dolfin/dev/python/demo/pde/stokes-iterative/python/documentation.html>,
        #
        #     prec = inner(grad(u), grad(v))*dx - p*q*dx
        #
        # although it doesn't seem to be too efficient.
        # The sign on the last term doesn't matter.
        prec = mu * inner(grad(u), grad(v))*dx \
             - p*q*dx
        M, _ = assemble_system(prec, L, new_bcs)
        #solver = KrylovSolver('tfqmr', 'amg')
        solver = KrylovSolver('gmres', 'amg')
        solver.set_operators(A, M)

    solver.parameters['monitor_convergence'] = verbose
    solver.parameters['report'] = verbose
    solver.parameters['absolute_tolerance'] = 0.0
    solver.parameters['relative_tolerance'] = tol
    solver.parameters['maximum_iterations'] = 500

    # Solve
    up = Function(WP)
    solver.solve(up.vector(), b)

    # Get sub-functions
    u, p = up.split()

    return u, p
Exemplo n.º 37
0
    plt.show()

    # Final test with some real example from fenics
    import dolfin as df
    mesh = df.UnitSquareMesh(20, 20)
    V = df.FunctionSpace(mesh, 'CG', 1)
    u = df.TrialFunction(V)
    v = df.TestFunction(V)

    f = df.Expression('sin(pi*x[0])*sin(2*pi*x[1])')
    a = df.inner(df.grad(u), df.grad(v))*df.dx
    L = df.inner(f, v)*df.dx

    bc = df.DirichletBC(V, df.Constant(0), 'on_boundary')
    A, b = df.assemble_system(a, L, bc)

    uh = df.Function(V)
    iters = df.solve(A, uh.vector(), b, 'cg')

    A_, b_ = A.array(), b.array()
    x0 = np.zeros(b.size())
    x0, my_iters = solve(A_, b_, x0)

    print 'DOLFIN, Conjugate grad finished in', iters
    print 'My Conjugate grad finished in', my_iters

    # Compare error
    e = uh.vector()[:] - x0[:]
    print 'Error betwween DOLFIN and CG', la.norm(e)
    def ab2tr_step0(u0,
                    P,
                    f,  # right-hand side
                    rho,
                    mu,
                    dudt_bcs=[],
                    p_bcs=[],
                    eps=1.0e-4,  # relative error tolerance
                    verbose=True
                    ):
        # Make sure that the initial velocity is divergence-free.
        alpha = norm(u0, 'Hdiv0')
        if abs(alpha) > DOLFIN_EPS:
            warn('Initial velocity not divergence-free (||u||_div = %e).'
                 % alpha
                 )
        # Get the initial u0' and p0 by solving the linear equation system
        #
        #     [M   C] [u0']   [f0 - (K+N(u0)u0)]
        #     [C^T 0] [p0 ] = [ g0'            ],
        #
        # i.e.,
        #
        #     rho u0' + nabla(p0) = f0 + mu\Delta(u0) - rho u0.nabla(u0),
        #     div(u0')            = 0.
        #
        W = u0.function_space()
        WP = W*P

        # Translate the boundary conditions into product space. See
        # <http://fenicsproject.org/qa/703/boundary-conditions-in-product-space>.
        dudt_bcs_new = []
        for dudt_bc in dudt_bcs:
            dudt_bcs_new.append(DirichletBC(WP.sub(0),
                                            dudt_bc.value(),
                                            dudt_bc.user_sub_domain()))
        p_bcs_new = []
        for p_bc in p_bcs:
            p_bcs_new.append(DirichletBC(WP.sub(1),
                                         p_bc.value(),
                                         p_bc.user_sub_domain()))

        new_bcs = dudt_bcs_new + p_bcs_new

        (u, p) = TrialFunctions(WP)
        (v, q) = TestFunctions(WP)

        #a = rho * dot(u, v) * dx + dot(grad(p), v) * dx \
        a = rho * inner(u, v) * dx - p * div(v) * dx \
            - div(u) * q * dx
        L = _rhs_weak(u0, v, f, rho, mu)

        A, b = assemble_system(a, L, new_bcs)

        # Similar preconditioner as for the Stokes problem.
        # TODO implement something better!
        prec = rho * inner(u, v) * dx \
            - p*q*dx
        M, _ = assemble_system(prec, L, new_bcs)

        solver = KrylovSolver('gmres', 'amg')

        solver.parameters['monitor_convergence'] = verbose
        solver.parameters['report'] = verbose
        solver.parameters['absolute_tolerance'] = 0.0
        solver.parameters['relative_tolerance'] = 1.0e-6
        solver.parameters['maximum_iterations'] = 10000

        # Associate operator (A) and preconditioner matrix (M)
        solver.set_operators(A, M)
        #solver.set_operator(A)

        # Solve
        up = Function(WP)
        solver.solve(up.vector(), b)

        # Get sub-functions
        dudt0, p0 = up.split()

        # Choosing the first step size for the trapezoidal rule can be tricky.
        # Chapters 2.7.4a, 2.7.4e of the book
        #
        #     Incompressible flow and the finite element method,
        #     volume 1: advection-diffusion;
        #     P.M. Gresho, R.L. Sani,
        #
        # give some hints.
        #
        #     eps ... relative error tolerance
        #     tau ... estimate of the initial 'time constant'
        tau = None
        if tau:
            dt0 = tau * eps**(1.0/3.0)
        else:
            # Choose something 'reasonably small'.
            dt0 = 1.0e-3
        # Alternative:
        # Use a dissipative scheme like backward Euler or BDF2 for the first
        # couple of steps. This makes sure that noisy initial data is damped
        # out.
        return dudt0, p0, dt0
Exemplo n.º 39
0
    # Nonlinear coefficient 2
    q2 = ufl.operators.exp(a * u2)

    for k in range(10):

        # Two parts of the weak form
        F1 = (u1.dx(0) * v1.dx(0) + a * u1.dx(0) * q2 * v1) * df.dx
        F2 = (u2.dx(0) * v2.dx(0) - a * q1 * u2.dx(0) * v2) * df.dx

        F = F1 + F2

        # Compute Jacobian
        dF = df.derivative(F, u, du)

        # Assemble matrix and load vector
        A, b = df.assemble_system(dF, -F, bch)

        # Compute Newton update
        df.solve(A, u_inc.vector(), b)

        # Update solution
        u.vector()[:] += u_inc.vector()

    # Evaluate solution
    ug = u.compute_vertex_values()

    # partition into u1 and u2
    U = np.reshape(ug, (2, nel + 1))

    plt.plot(xg, U[0, :])
    plt.plot(xg, U[1, :])
Exemplo n.º 40
0
def test_stokes_noflow(gamma, Re, nu_interp, postprocessor):
    #set_log_level(WARNING)

    basename = postprocessor.basename
    label = "{}_{}_gamma_{}_Re_{:.0e}".format(basename, nu_interp, gamma, Re)

    c = postprocessor.get_coefficients()
    c[r"\nu_1"] = c[r"\rho_1"] / Re
    c[r"\nu_2"] = c[r"r_visc"] * c[r"\nu_1"]
    c[r"\nu_1"] /= c[r"\rho_0"] * c[r"V_0"] * c[r"L_0"]
    c[r"\nu_2"] /= c[r"\rho_0"] * c[r"V_0"] * c[r"L_0"]

    cc = wrap_coeffs_as_constants(c)
    nu = eval("nu_" + nu_interp)  # choose viscosity interpolation

    for level in range(1, 4):
        mesh, boundary_markers, pinpoint, periodic_bnd = create_domain(level)
        periodic_bnd = None
        W = create_mixed_space(mesh, periodic_boundary=periodic_bnd)
        bcs = create_bcs(W,
                         boundary_markers,
                         periodic_boundary=periodic_bnd,
                         pinpoint=pinpoint)

        phi = create_fixed_vfract(mesh, c)

        # Create forms
        a, L = create_forms(W, rho(phi, cc), nu(phi, cc), c[r"g_a"],
                            boundary_markers, gamma)

        # Solve problem
        w = df.Function(W)
        A, b = df.assemble_system(a, L, bcs)
        solver = df.LUSolver("mumps")
        df.PETScOptions.set("fieldsplit_u_mat_mumps_icntl_14", 500)
        solver.set_operator(A)
        try:
            solver.solve(w.vector(), b)
        except:
            df.warning("Ooops! Something went wrong: {}".format(
                sys.exc_info()[0]))
            continue

        # Pre-process results
        v, p = w.split(True)
        v.rename("v", "velocity")
        p.rename("p", "pressure")

        V_dv = df.FunctionSpace(mesh, "DG",
                                W.sub(0).ufl_element().degree() - 1)
        div_v = df.project(df.div(v), V_dv)
        div_v.rename("div_v", "velocity-divergence")
        D_22 = df.project(v.sub(1).dx(1), V_dv)

        p_h = create_hydrostatic_pressure(mesh, cc)
        #p_ref = df.project(p_h, W.sub(1).ufl_element())
        p_ref = df.project(
            p_h,
            df.FunctionSpace(mesh, df.FiniteElement("CG", mesh.ufl_cell(), 4)))
        v_errL2, v_errH10, div_errL2, p_errL2 = compute_errornorms(
            v, div_v, p, p_ref)

        if nu_interp[:2] == "PW":
            V_nu = df.FunctionSpace(mesh, "DG", phi.ufl_element().degree())
        else:
            V_nu = phi.function_space()
        nu_0 = df.project(nu(phi, cc), V_nu)
        T_22 = df.project(2.0 * nu(phi, cc) * v.sub(1).dx(1), V_nu)

        # Save results
        make_cut = postprocessor._make_cut
        rs = dict(ndofs=W.dim(),
                  level=level,
                  h=mesh.hmin(),
                  r_dens=c[r"r_dens"],
                  r_visc=c[r"r_visc"],
                  gamma=gamma,
                  Re=Re,
                  nu_interp=nu_interp)
        rs[r"$v_2$"] = make_cut(v.sub(1))
        rs[r"$p$"] = make_cut(p)
        rs[r"$\phi$"] = make_cut(phi)
        rs[r"$D_{22}$"] = make_cut(D_22)
        rs[r"$T_{22}$"] = make_cut(T_22)
        rs[r"$\nu$"] = make_cut(nu_0)
        rs[r"$||\mathbf{v} - \mathbf{v}_h||_{L^2}$"] = v_errL2
        rs[r"$||\nabla (\mathbf{v} - \mathbf{v}_h)||_{L^2}$"] = v_errH10
        rs[r"$||\mathrm{div} \mathbf{v}_h||_{L^2}$"] = div_errL2
        rs[r"$||\mathbf{p} - \mathbf{p}_h||_{L^2}$"] = p_errL2
        print(label, level)

        # Send to posprocessor
        comm = mesh.mpi_comm()
        rank = df.MPI.rank(comm)
        postprocessor.add_result(rank, rs)

    # Plot results obtained in the last round
    outdir = os.path.join(postprocessor.outdir, "XDMFoutput")
    with df.XDMFFile(os.path.join(outdir, "v.xdmf")) as file:
        file.write(v, 0.0)
    with df.XDMFFile(os.path.join(outdir, "p.xdmf")) as file:
        file.write(p, 0.0)
    with df.XDMFFile(os.path.join(outdir, "phi.xdmf")) as file:
        file.write(phi, 0.0)
    with df.XDMFFile(os.path.join(outdir, "div_v.xdmf")) as file:
        file.write(div_v, 0.0)

    # Save results into a binary file
    filename = "results_{}.pickle".format(label)
    postprocessor.save_results(filename)

    # Flush plots as we now have data for all level values
    postprocessor.pop_items(["level", "h"])
    postprocessor.flush_plots()

    # Cleanup
    df.set_log_level(df.INFO)
    gc.collect()
Exemplo n.º 41
0
    # Nonlinear coefficient 2
    q2 = ufl.operators.exp(a * u2)

    for k in range(10):

        # Two parts of the weak form
        F1 = (u1.dx(0) * v1.dx(0) + a * u1.dx(0) * q2 * v1) * df.dx
        F2 = (u2.dx(0) * v2.dx(0) - a * q1 * u2.dx(0) * v2) * df.dx

        F = F1 + F2

        # Compute Jacobian
        dF = df.derivative(F, u, du)

        # Assemble matrix and load vector
        A, b = df.assemble_system(dF, -F, bch)

        # Compute Newton update
        df.solve(A, u_inc.vector(), b)

        # Update solution
        u.vector()[:] += u_inc.vector()

    # Evaluate solution
    ug = u.compute_vertex_values()

    # partition into u1 and u2
    U = np.reshape(ug, (2, nel + 1))

    plt.plot(xg, U[0, :])
    plt.plot(xg, U[1, :])
Exemplo n.º 42
0
def get_1d_matrices(mesh_, N, root=''):
    '''Given mesh construct 1d matrices for GEVP.'''
    if not isinstance(N, (int, float)):
        assert root
        return all([get_1d_matrices(mesh_, n, root) == 0 for n in N])
    
    mesh_dir = '../plate-beam/py/fem_new/meshes'

    # Zig zag mesh
    if mesh_ == 'nonuniform':
        mesh = 'Pb_zig_zag_bif'
        mesh2d = '%s/%s_%d.xml.gz' % (mesh_dir, mesh, N)
        # mesh1d = '%s/%s_%d_facet_region.xml.gz' % (mesh_dir, mesh, N)
        mesh2d = Mesh(mesh2d)
        # Constructing facet function can be too expensive so here's and
        # alternative
        # mesh1d = get_marked_facets(mesh1d)
    # Structured meshes
    elif mesh_ == 'uniform':
        mesh = mesh_
        N = int(N)
        mesh2d = UnitSquareMesh(N, N)
        # mesh1d = EdgeFunction('size_t', mesh2d, 0)
        # Beam at y = 0.5
        # CompiledSubDomain('near(x[1], 0.5, 1E-10)').mark(mesh1d, 1)

        # Use the above here as well
        # from dolfin import SubsetIterator
        # mesh1d = [e.index() for e in SubsetIterator(mesh1d, 1)]
    mesh1d = '%s/%s_%d_edgelist' % (mesh_dir, mesh, N)
    mesh1d = map(int, np.loadtxt(mesh1d))

    print FunctionSpace(mesh2d, 'CG', 1).dim()

    # Extract 1d
    import sys; sys.setrecursionlimit(20000);
    mesh = interval_mesh_from_edge_f(mesh2d, mesh1d, 1)[0].pop()

    # Assemble
    V = FunctionSpace(mesh, 'CG', 1)
    u = TrialFunction(V)
    v = TestFunction(V)
    bc = DirichletBC(V, Constant(0), 'on_boundary')

    a = inner(grad(u), grad(v))*dx
    m = inner(u, v)*dx
    L = inner(Constant(0), v)*dx

    A, _ = assemble_system(a, L, bc)
    M, _ = assemble_system(m, L, bc)

    A, M = A.array(), M.array()

    if root:
        dA = np.diagonal(A, 0)
        uA = np.r_[np.diagonal(A, 1), 0]
        A = np.c_[dA, uA]

        dM = np.diagonal(M, 0)
        uM = np.r_[np.diagonal(M, 1), 0]
        M = np.c_[dM, uM]

        header = 'main and upper diagonals of A, M'
        f = '_'.join([mesh_, str(N)])
        import os
        f = os.path.join(root, f)
        np.savetxt(f, np.c_[A, M], header=header)
        return 0
    else:
        return A, M
Exemplo n.º 43
0
 def _assemble_system(a, L, bcs, facet_function):
     return assemble_system(a, L, bcs, exterior_facet_domains=facet_function)
Exemplo n.º 44
0
def boundary_D(x, on_boundary):

    return on_boundary and (near(x[0], 0, tol) or near(x[0], 1.0, tol))


bc = DirichletBC(V, u_D, boundary_D)
u = TrialFunction(V)
v = TestFunction(V)
f = Expression("10*exp(-(pow(x[0] - 0.5, 2) + pow(x[1] - 0.5, 2) \
                 + pow(x[2] - 0.5, 2)) / 0.02)", degree=6)
g = Expression("sin(5.0*x[0])*sin(5.0*x[1])", degree=6)
a = dot(grad(u), grad(v)) * dx
L = f * v * dx + g * v * ds
A = PETScMatrix()
b = PETScVector()
assemble_system(a, L, bc, A_tensor=A, b_tensor=b)

A = A.mat()
b = b.vec()

# =========================================================================

# Construct the alist for systems on levels from fine to coarse
# construct the transfer operators first
ruse = [None] * (nl - 1)
Alist = [None] * (nl)

ruse[0] = Mat()
puse[0].transpose(ruse[0])
Alist[0] = A
Exemplo n.º 45
0
    '500.0 * exp(-(pow(x[0] - 0.5, 2) + pow(x[1] - 0.5, 2)) / 0.02)',
    degree=1)
L = v * f * dfn.dx

# Define Dirichlet boundary (x = 0 or x = 1)


class DirichletBoundary(dfn.SubDomain):
    def inside(self, x, on_boundary):
        return x[0] < dfn.DOLFIN_EPS or x[0] > 1.0 - dfn.DOLFIN_EPS


u0 = dfn.Constant(0.0)
bc = dfn.DirichletBC(V, u0, DirichletBoundary())

A, rhs = dfn.assemble_system(a, L, bcs=bc)
############################################################


############################################################
# Part II: Solve with PyAMG
Asp = dfn.as_backend_type(A).sparray()
b = dfn.as_backend_type(rhs).array_view()

ml = pyamg.smoothed_aggregation_solver(Asp, max_coarse=10)
residuals = []
x = ml.solve(b, tol=1e-10, accel='cg', residuals=residuals)

residuals = residuals / residuals[0]
print(ml)
############################################################
Exemplo n.º 46
0
    def solve_linear(self, d_outputs, d_residuals, mode):
        linear_solver_ = self.options['linear_solver_']
        pde_problem = self.options['pde_problem']
        state_name = self.options['state_name']

        state_function = pde_problem.states_dict[state_name]['function']

        residual_form = pde_problem.states_dict[state_name]['residual_form']
        if state_name == 'density':
            print('this is a variational density filter')
            A, _ = df.assemble_system(self.derivative_form, -residual_form)
        else:
            A, _ = df.assemble_system(self.derivative_form, -residual_form,
                                      pde_problem.bcs_list)

        def report(xk):
            frame = inspect.currentframe().f_back

        if linear_solver_ == 'fenics_direct':

            rhs_ = df.Function(state_function.function_space())
            dR = df.Function(state_function.function_space())

            rhs_.vector().set_local(d_outputs[state_name])
            if state_name != 'density':
                for bc in pde_problem.bcs_list:
                    bc.apply(A)
            Am = df.as_backend_type(A).mat()
            ATm = Am.transpose()
            AT = df.PETScMatrix(ATm)

            df.solve(AT, dR.vector(), rhs_.vector())
            d_residuals[state_name] = dR.vector().get_local()

        elif linear_solver_ == 'scipy_splu':
            if state_name != 'density':
                for bc in pde_problem.bcs_list:
                    bc.apply(A)
            Am = df.as_backend_type(A).mat()
            ATm = Am.transpose()
            ATm_csr = csr_matrix(ATm.getValuesCSR()[::-1], shape=Am.size)
            lu = splu(ATm_csr.tocsc())
            d_residuals[state_name] = lu.solve(d_outputs[state_name],
                                               trans='T')

        elif linear_solver_ == 'scipy_cg':
            if state_name != 'density':
                for bc in pde_problem.bcs_list:
                    bc.apply(A)
            Am = df.as_backend_type(A).mat()
            ATm = Am.transpose()
            ATm_csr = csr_matrix(ATm.getValuesCSR()[::-1], shape=Am.size)
            # lu = splu(ATm_csr.tocsc())
            b = d_outputs[state_name]
            x, info = splinalg.cg(ATm_csr, b, tol=1e-8, callback=report)
            print('the residual is:')
            print(info)

            d_residuals[state_name] = x

        elif linear_solver_ == 'fenics_krylov':

            rhs_ = df.Function(state_function.function_space())
            dR = df.Function(state_function.function_space())

            rhs_.vector().set_local(d_outputs[state_name])
            if state_name != 'density':
                for bc in pde_problem.bcs_list:
                    bc.apply(A)

            Am = df.as_backend_type(A).mat()
            ATm = Am.transpose()
            AT = df.PETScMatrix(ATm)

            solver = df.KrylovSolver('gmres', 'ilu')
            prm = solver.parameters
            prm["maximum_iterations"] = 1000000
            prm["divergence_limit"] = 1e2
            solver.solve(AT, dR.vector(), rhs_.vector())
            # print('solve'+iter)

            d_residuals[state_name] = dR.vector().get_local()

        elif linear_solver_ == 'petsc_gmres_ilu':
            ksp = PETSc.KSP().create()
            ksp.setType(PETSc.KSP.Type.GMRES)
            ksp.setTolerances(rtol=5e-17)

            if state_name != 'density':
                for bc in pde_problem.bcs_list:
                    bc.apply(A)
            Am = df.as_backend_type(A).mat()

            ksp.setOperators(Am)

            ksp.setFromOptions()
            pc = ksp.getPC()
            pc.setType("lu")

            size = state_function.function_space().dim()

            dR = PETSc.Vec().create()
            dR.setSizes(size)
            dR.setType('seq')
            dR.setValues(range(size), d_residuals[state_name])
            dR.setUp()

            du = PETSc.Vec().create()
            du.setSizes(size)
            du.setType('seq')
            du.setValues(range(size), d_outputs[state_name])
            du.setUp()

            if mode == 'fwd':
                ksp.solve(dR, du)
                d_outputs[state_name] = du.getValues(range(size))
            else:
                ksp.solveTranspose(du, dR)
                d_residuals[state_name] = dR.getValues(range(size))

        elif linear_solver_ == 'petsc_cg_ilu':
            ksp = PETSc.KSP().create()
            ksp.setType(PETSc.KSP.Type.CG)
            ksp.setTolerances(rtol=5e-15)

            if state_name != 'density':
                for bc in pde_problem.bcs_list:
                    bc.apply(A)
            Am = df.as_backend_type(A).mat()

            ksp.setOperators(Am)

            ksp.setFromOptions()
            pc = ksp.getPC()
            pc.setType("lu")

            size = state_function.function_space().dim()

            dR = PETSc.Vec().create()
            dR.setSizes(size)
            dR.setType('seq')
            dR.setValues(range(size), d_residuals[state_name])
            dR.setUp()

            du = PETSc.Vec().create()
            du.setSizes(size)
            du.setType('seq')
            du.setValues(range(size), d_outputs[state_name])
            du.setUp()

            if mode == 'fwd':
                ksp.solve(dR, du)
                d_outputs[state_name] = du.getValues(range(size))
            else:
                ksp.solveTranspose(du, dR)
                d_residuals[state_name] = dR.getValues(range(size))
Exemplo n.º 47
0
def stokes_solve(
    up_out,
    mu,
    u_bcs, p_bcs,
    f,
    dx=dx,
    verbose=True,
    tol=1.0e-10,
    maxiter=1000
    ):
    # Some initial sanity checks.
    assert mu > 0.0

    WP = up_out.function_space()

    # Translate the boundary conditions into the product space.
    new_bcs = []
    for k, bcs in enumerate([u_bcs, p_bcs]):
        for bc in bcs:
            space = bc.function_space()
            C = space.component()
            if len(C) == 0:
                new_bcs.append(DirichletBC(WP.sub(k),
                                           bc.value(),
                                           bc.domain_args[0]))
            elif len(C) == 1:
                new_bcs.append(DirichletBC(WP.sub(k).sub(int(C[0])),
                                           bc.value(),
                                           bc.domain_args[0]))
            else:
                raise RuntimeError('Illegal number of subspace components.')

    # TODO define p*=-1 and reverse sign in the end to get symmetric system?

    # Define variational problem
    (u, p) = TrialFunctions(WP)
    (v, q) = TestFunctions(WP)

    r = Expression('x[0]', degree=1, domain=WP.mesh())

    print("mu = %e" % mu)

    # build system
    a = mu * inner(r * grad(u), grad(v)) * 2 * pi * dx \
        - ((r * v[0]).dx(0) + (r * v[1]).dx(1)) * p * 2 * pi * dx \
        + ((r * u[0]).dx(0) + (r * u[1]).dx(1)) * q * 2 * pi * dx
      #- div(r*v)*p* 2*pi*dx \
      #+ q*div(r*u)* 2*pi*dx
    L = inner(f, v) * 2 * pi * r * dx

    A, b = assemble_system(a, L, new_bcs)

    mode = 'lu'

    if mode == 'lu':
        solve(A, up_out.vector(), b, 'lu')

    elif mode == 'gmres':
        # For preconditioners for the Stokes system, see
        #
        #     Fast iterative solvers for discrete Stokes equations;
        #     J. Peters, V. Reichelt, A. Reusken.
        #
        prec = mu * inner(r * grad(u), grad(v)) * 2 * pi * dx \
            - p * q * 2 * pi * r * dx
        P, btmp = assemble_system(prec, L, new_bcs)
        solver = KrylovSolver('tfqmr', 'amg')
        #solver = KrylovSolver('gmres', 'amg')
        solver.set_operators(A, P)

        solver.parameters['monitor_convergence'] = verbose
        solver.parameters['report'] = verbose
        solver.parameters['absolute_tolerance'] = 0.0
        solver.parameters['relative_tolerance'] = tol
        solver.parameters['maximum_iterations'] = maxiter

        # Solve
        solver.solve(up_out.vector(), b)
    elif mode == 'fieldsplit':
        raise NotImplementedError('Fieldsplit solver not yet implemented.')
        # For an assortment of preconditioners, see
        #
        #     Performance and analysis of saddle point preconditioners
        #     for the discrete steady-state Navier-Stokes equations;
        #     H.C. Elman, D.J. Silvester, A.J. Wathen;
        #     Numer. Math. (2002) 90: 665-688;
        #     <http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.145.3554>.
        #
        # Set up field split.
        W = SubSpace(WP, 0)
        P = SubSpace(WP, 1)
        u_dofs = W.dofmap().dofs()
        p_dofs = P.dofmap().dofs()
        prec = PETScPreconditioner()
        prec.set_fieldsplit([u_dofs, p_dofs], ['u', 'p'])

        PETScOptions.set('pc_type', 'fieldsplit')
        PETScOptions.set('pc_fieldsplit_type', 'additive')
        PETScOptions.set('fieldsplit_u_pc_type', 'lu')
        PETScOptions.set('fieldsplit_p_pc_type', 'jacobi')

        # Create Krylov solver with custom preconditioner.
        solver = PETScKrylovSolver('gmres', prec)
        solver.set_operator(A)

    return
Exemplo n.º 48
0
    def __init__(
        self,
        Q,
        kappa,
        rho,
        cp,
        convection,
        source,
        dirichlet_bcs=None,
        neumann_bcs=None,
        robin_bcs=None,
        my_dx=dx,
        my_ds=ds,
        stabilization=None,
    ):
        super(Heat, self).__init__()
        self.Q = Q

        dirichlet_bcs = dirichlet_bcs or []
        neumann_bcs = neumann_bcs or {}
        robin_bcs = robin_bcs or {}

        self.convection = convection

        u = TrialFunction(Q)
        v = TestFunction(Q)

        # If there are sharp temperature gradients, numerical oscillations may
        # occur. This happens because the resulting matrix is not an M-matrix,
        # caused by the fact that A1 puts positive elements in places other
        # than the main diagonal. To prevent that, it is suggested by
        # Großmann/Roos to use a vertex-centered discretization for the mass
        # matrix part.
        # Check
        # https://bitbucket.org/fenics-project/ffc/issues/145/uflacs-error-for-vertex-quadrature-scheme
        #
        self.M = assemble(
            u * v * dx,
            form_compiler_parameters={
                "representation": "quadrature",
                "quadrature_rule": "vertex",
            },
        )

        mesh = Q.mesh()
        r = SpatialCoordinate(mesh)[0]
        self.F0 = F(
            u,
            v,
            kappa,
            rho,
            cp,
            convection,
            source,
            r,
            neumann_bcs,
            robin_bcs,
            my_dx,
            my_ds,
            stabilization,
        )

        self.dirichlet_bcs = dirichlet_bcs

        self.A, self.b = assemble_system(-lhs(self.F0), rhs(self.F0))
        return
Exemplo n.º 49
0
def stokes_solve(up_out, mu, u_bcs, p_bcs, f, my_dx=dx):
    # Some initial sanity checks.
    assert mu > 0.0

    WP = up_out.function_space()

    # Translate the boundary conditions into the product space.
    new_bcs = helpers.dbcs_to_productspace(WP, [u_bcs, p_bcs])

    # TODO define p*=-1 and reverse sign in the end to get symmetric system?

    # Define variational problem
    (u, p) = TrialFunctions(WP)
    (v, q) = TestFunctions(WP)

    mesh = WP.mesh()
    r = SpatialCoordinate(mesh)[0]

    # build system
    f = F(u, p, v, q, f, r, mu, my_dx)
    a = lhs(f)
    L = rhs(f)
    A, b = assemble_system(a, L, new_bcs)

    mode = "lu"

    assert mode == "lu"
    solve(A, up_out.vector(), b, "lu")

    # TODO Krylov solver for Stokes
    # assert mode == 'gmres'
    # # For preconditioners for the Stokes system, see
    # #
    # #     Fast iterative solvers for discrete Stokes equations;
    # #     J. Peters, V. Reichelt, A. Reusken.
    # #
    # prec = mu * inner(r * grad(u), grad(v)) * 2 * pi * my_dx \
    #     - p * q * 2 * pi * r * my_dx
    # P, _ = assemble_system(prec, L, new_bcs)
    # solver = KrylovSolver('tfqmr', 'hypre_amg')
    # # solver = KrylovSolver('gmres', 'hypre_amg')
    # solver.set_operators(A, P)

    # solver.parameters['monitor_convergence'] = verbose
    # solver.parameters['report'] = verbose
    # solver.parameters['absolute_tolerance'] = 0.0
    # solver.parameters['relative_tolerance'] = tol
    # solver.parameters['maximum_iterations'] = maxiter

    # # Solve
    # solver.solve(up_out.vector(), b)
    # elif mode == 'fieldsplit':
    #     # For an assortment of preconditioners, see
    #     #
    #     # Performance and analysis of saddle point preconditioners
    #     # for the discrete steady-state Navier-Stokes equations;
    #     # H.C. Elman, D.J. Silvester, A.J. Wathen;
    #     # Numer. Math. (2002) 90: 665-688;
    #     # <http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.145.3554>.
    #     #
    #     # Set up field split.
    #     W = SubSpace(WP, 0)
    #     P = SubSpace(WP, 1)
    #     u_dofs = W.dofmap().dofs()
    #     p_dofs = P.dofmap().dofs()
    #     prec = PETScPreconditioner()
    #     prec.set_fieldsplit([u_dofs, p_dofs], ['u', 'p'])

    #     PETScOptions.set('pc_type', 'fieldsplit')
    #     PETScOptions.set('pc_fieldsplit_type', 'additive')
    #     PETScOptions.set('fieldsplit_u_pc_type', 'lu')
    #     PETScOptions.set('fieldsplit_p_pc_type', 'jacobi')

    #     # Create Krylov solver with custom preconditioner.
    #     solver = PETScKrylovSolver('gmres', prec)
    #     solver.set_operator(A)

    return