Exemple #1
0
    def __init__(self, u_, Space, bcs=[], name="div", method={}):

        solver_type = method.get('solver_type', 'cg')
        preconditioner_type = method.get('preconditioner_type', 'default')
        solver_method = method.get('method', 'default')
        low_memory_version = method.get('low_memory_version', False)

        OasisFunction.__init__(self, div(u_), Space, bcs=bcs, name=name,
                               method=solver_method, solver_type=solver_type,
                               preconditioner_type=preconditioner_type)

        Source = u_[0].function_space()
        if not low_memory_version:
            self.matvec = [[A_cache[(self.test * TrialFunction(Source).dx(i) * dx, ())], u_[i]]
                           for i in range(Space.mesh().geometry().dim())]

        if solver_method.lower() == "gradient_matrix":
            from fenicstools import compiled_gradient_module
            DG = FunctionSpace(Space.mesh(), 'DG', 0)
            G = assemble(TrialFunction(DG) * self.test * dx())
            dg = Function(DG)
            self.WGM = []
            st = TrialFunction(Source)
            for i in range(Space.mesh().geometry().dim()):
                dP = assemble(st.dx(i) * TestFunction(DG) * dx)
                A = Matrix(G)
                self.WGM.append(compiled_gradient_module.compute_weighted_gradient_matrix(A, dP, dg))
Exemple #2
0
    def solve(self, mesh, num=5):
        """ Solve for num eigenvalues based on the mesh. """
        # conforming elements
        V = FunctionSpace(mesh, "CG", self.degree)
        u = TrialFunction(V)
        v = TestFunction(V)

        # weak formulation
        a = inner(grad(u), grad(v)) * dx
        b = u * v * ds
        A = PETScMatrix()
        B = PETScMatrix()
        A = assemble(a, tensor=A)
        B = assemble(b, tensor=B)

        # find eigenvalues
        eigensolver = SLEPcEigenSolver(A, B)
        eigensolver.parameters["spectral_transform"] = "shift-and-invert"
        eigensolver.parameters["problem_type"] = "gen_hermitian"
        eigensolver.parameters["spectrum"] = "smallest real"
        eigensolver.parameters["spectral_shift"] = 1.0E-10
        eigensolver.solve(num + 1)

        # extract solutions
        lst = [
            eigensolver.get_eigenpair(i) for i in range(
                1,
                eigensolver.get_number_converged())]
        for k in range(len(lst)):
            u = Function(V)
            u.vector()[:] = lst[k][2]
            lst[k] = (lst[k][0], u)  # pair (eigenvalue,eigenfunction)
        return np.array(lst)
 def __init__(self, V, Vm, bc, bcadj, \
 RHSinput=[], ObsOp=[], UD=[], Regul=[], Data=[], plot=False, \
 mycomm=None):
     # Define test, trial and all other functions
     self.trial = TrialFunction(V)
     self.test = TestFunction(V)
     self.mtrial = TrialFunction(Vm)
     self.mtest = TestFunction(Vm)
     self.rhs = Function(V)
     self.m = Function(Vm)
     self.mcopy = Function(Vm)
     self.srchdir = Function(Vm)
     self.delta_m = Function(Vm)
     self.MG = Function(Vm)
     self.Grad = Function(Vm)
     self.Gradnorm = 0.0
     self.lenm = len(self.m.vector().array())
     self.u = Function(V)
     self.ud = Function(V)
     self.diff = Function(V)
     self.p = Function(V)
     # Define weak forms to assemble A, C and E
     self._wkforma()
     self._wkformc()
     self._wkforme()
     # Store other info:
     self.ObsOp = ObsOp
     self.UD = UD
     self.reset()    # Initialize U, C and E to []
     self.Data = Data
     self.GN = 1.0   # GN = 0.0 => GN Hessian; = 1.0 => full Hessian
     # Operators and bc
     LinearOperator.__init__(self, self.delta_m.vector(), \
     self.delta_m.vector()) 
     self.bc = bc
     self.bcadj = bcadj
     self._assemble_solverM(Vm)
     self.assemble_A()
     self.assemble_RHS(RHSinput)
     self.Regul = Regul
     # Counters, tolerances and others
     self.nbPDEsolves = 0    # Updated when solve_A called
     self.nbfwdsolves = 0    # Counter for plots
     self.nbadjsolves = 0    # Counter for plots
     self._set_plots(plot)
     # MPI:
     self.mycomm = mycomm
     try:
         self.myrank = MPI.rank(self.mycomm)
     except:
         self.myrank = 0
Exemple #4
0
 def assemble_lui_stiffness(self, g, f, mesh, robin_boundary):
     V = FunctionSpace(mesh, "Lagrange", self.p)
     u = TrialFunction(V)
     v = TestFunction(V)
     n = FacetNormal(mesh)
     robin = MeshFunction('size_t', mesh, mesh.topology().dim() - 1)
     robin_boundary.mark(robin, 1)
     ds = Measure('ds', subdomain_data=robin)
     a = inner(grad(u), grad(v)) * dx
     b = (1 - g) * (inner(grad(u), n)) * v * ds(1)
     c = f * u * v * ds(1)
     k = lhs(a + b - c)
     K = PETScMatrix()
     assemble(k, tensor=K)
     return K, V
Exemple #5
0
def run():
    mesh = UnitSquareMesh(20, 20)
    V = FunctionSpace(mesh, 'Lagrange', 2)
    u = interpolate(Constant(2.0), V)
    sol = []
    for ii in range(10000):
        #sol.append(u.copy(deepcopy=True))
        #sol.append(u.vector().copy())
        sol.append(u.vector().array())
    test, trial = TestFunction(V), TrialFunction(V)
    M = assemble(inner(test, trial) * dx)
    m1 = np.random.randn(1000000).reshape((1000, 1000))
    m2 = []
    for ii in range(1000):
        m2.append(np.random.randn(1000))
Exemple #6
0
 def __init__(self, V, **kwargs):
     # Call parent
     ParametrizedProblem.__init__(self, os.path.join("test_eim_approximation_12_tempdir", expression_type, basis_generation, "mock_problem"))
     # Minimal subset of a ParametrizedDifferentialProblem
     self.V = V
     self._solution = Function(V)
     self.components = ["u"]
     # Parametrized function to be interpolated
     x = SpatialCoordinate(V.mesh())
     mu = SymbolicParameters(self, V, (1., ))
     self.f = (1-x[0])*cos(3*pi*mu[0]*(1+x[0]))*exp(-mu[0]*(1+x[0]))
     # Inner product
     f = TrialFunction(self.V)
     g = TestFunction(self.V)
     self.inner_product = assemble(f*g*dx)
Exemple #7
0
    def __init__(self, p_, Space, i=0, bcs=[], name="grad", method={}):

        assert len(p_.ufl_shape) == 0
        assert i >= 0 and i < Space.mesh().geometry().dim()

        solver_type = method.get('solver_type', 'cg')
        preconditioner_type = method.get('preconditioner_type', 'default')
        solver_method = method.get('method', 'default')
        low_memory_version = method.get('low_memory_version', False)

        OasisFunction.__init__(self,
                               p_.dx(i),
                               Space,
                               bcs=bcs,
                               name=name,
                               method=solver_method,
                               solver_type=solver_type,
                               preconditioner_type=preconditioner_type)

        self.i = i
        Source = p_.function_space()
        if not low_memory_version:
            self.matvec = [
                A_cache[(self.test * TrialFunction(Source).dx(i) * dx, ())], p_
            ]

        if solver_method.lower() == "gradient_matrix":
            from fenicstools import compiled_gradient_module
            DG = FunctionSpace(Space.mesh(), 'DG', 0)
            G = assemble(TrialFunction(DG) * self.test * dx())
            dg = Function(DG)
            dP = assemble(
                TrialFunction(p_.function_space()).dx(i) * TestFunction(DG) *
                dx())
            self.WGM = compiled_gradient_module.compute_weighted_gradient_matrix(
                G, dP, dg)
Exemple #8
0
 def jacobian_solver(self, u, lmbda, rhs):
     t = TrialFunction(self.V)
     v = TestFunction(self.V)
     # from dolfin import Constant
     # a = assemble(
     #     dot(grad(t), grad(v)) * dx - Constant(lmbda) * exp(u) * t * v * dx
     # )
     ufun = Function(self.V)
     ufun.vector()[:] = u
     a = self.a - lmbda * assemble(exp(ufun) * t * v * dx)
     self.bc.apply(a)
     x = Function(self.V)
     # solve(a, x.vector(), rhs, "gmres", "ilu")
     solve(a, x.vector(), rhs)
     return x.vector()
def _new_square_matrix(bc, val):
    from dolfin import TrialFunction, TestFunction
    from dolfin import assemble, Constant, inner, dx
    import numpy
    V = bc.function_space()
    u,v = TrialFunction(V),TestFunction(V)
    Z = assemble(Constant(0)*inner(u,v)*dx)
    if val != 0.0:
        lrange = range(*Z.local_range(0))
        idx = numpy.ndarray(len(lrange), dtype=numpy.intc)
        idx[:] = lrange
        Z.ident(idx)
        if val != 1.0:
            Z *= val
    return Z
def test_is_zero_with_nabla():
    mesh = UnitSquareMesh(4, 4)
    V1 = FunctionSpace(mesh, 'CG', 1)
    V2 = VectorFunctionSpace(mesh, 'CG', 1)
    v1 = TestFunction(V1)
    v2 = TrialFunction(V2)
    n = Constant([1, 1])
    nn = dolfin.outer(n, n)
    vv = dolfin.outer(v2, v2)

    check_is_zero(dot(n, grad(v1)), 1)
    check_is_zero(dolfin.div(v2), 1)
    check_is_zero(dot(dolfin.div(nn), n), 0)
    check_is_zero(dot(dolfin.div(vv), n), 1)
    check_is_zero(dolfin.inner(nn, grad(v2)), 1)
Exemple #11
0
 def setUp(self):
     mesh = UnitSquareMesh(5, 5, 'crossed')
     self.V = FunctionSpace(mesh, 'Lagrange', 5)
     self.u = Function(self.V)
     self.uM = Function(self.V)
     self.uMdiag = Function(self.V)
     test = TestFunction(self.V)
     trial = TrialFunction(self.V)
     m = test * trial * dx
     self.M = assemble(m)
     self.solver = LUSolver()
     self.solver.parameters['reuse_factorization'] = True
     self.solver.parameters['symmetric'] = True
     self.solver.set_operator(self.M)
     self.ones = np.ones(self.V.dim())
Exemple #12
0
    def __init__(self, u_, Space, bcs=[], name="div", method={}):

        solver_type = method.get('solver_type', 'cg')
        preconditioner_type = method.get('preconditioner_type', 'default')
        solver_method = method.get('method', 'default')
        low_memory_version = method.get('low_memory_version', False)

        OasisFunction.__init__(self,
                               div(u_),
                               Space,
                               bcs=bcs,
                               name=name,
                               method=solver_method,
                               solver_type=solver_type,
                               preconditioner_type=preconditioner_type)

        Source = u_[0].function_space()
        if not low_memory_version:
            self.matvec = [[
                A_cache[(self.test * TrialFunction(Source).dx(i) * dx, ())],
                u_[i]
            ] for i in range(Space.mesh().geometry().dim())]

        if solver_method.lower() == "gradient_matrix":
            from fenicstools import compiled_gradient_module
            DG = FunctionSpace(Space.mesh(), 'DG', 0)
            G = assemble(TrialFunction(DG) * self.test * dx())
            dg = Function(DG)
            self.WGM = []
            st = TrialFunction(Source)
            for i in range(Space.mesh().geometry().dim()):
                dP = assemble(st.dx(i) * TestFunction(DG) * dx)
                A = Matrix(G)
                self.WGM.append(
                    compiled_gradient_module.compute_weighted_gradient_matrix(
                        A, dP, dg))
Exemple #13
0
    def compile_constraint_jacobian(self):
        """Compute first variation of constraint form.

        This method only has side effects.
        """
        if self._constraint_form is None:
            raise NotImplementedError("Constraint form not registered.")

        # Fast return if first variation was already compiled.
        if self.__constraint_jacobian is not None:
            return

        du = TrialFunction(self.function_space)
        self.__constraint_jacobian = derivative(self._constraint_form, self.u,
                                                du)
        return
Exemple #14
0
    def field(self, state, x=None, lump=True, rhs_func=None):
        """
    Returns the effective-field contribution for a given state.

    This method uses a projection method to retrieve the field from the
    RHS-form given by the :code:`form_rhs` method. It should be overriden
    for better performance.

    *Arguments*
      state (:class:`State`)
        the simulation state
      x (:class:`dolfin.Vector`)
        the vector to store the result or :code:`None`

    *Returns*
      :class:`dolfin.Function`
        the effective-field contribution
    """

        # TODO set particular solver
        # TODO use caching for mass matrix

        if rhs_func is None:
            w = TestFunction(state.VectorFunctionSpace())
            b = assemble(
                self.form_rhs(state, w) / Constant(Constants.gamma) *
                state.dx('magnetic'))
        else:
            b = rhs_func(state)

        # Optional mass lumping
        if x is None:
            result = Function(state.VectorFunctionSpace())
        else:
            result = Function(state.VectorFunctionSpace(), x)

        if lump:
            A = state.M_inv_diag('magnetic')
            A.mult(b, result.vector())
        else:
            w = TestFunction(state.VectorFunctionSpace())
            h = TrialFunction(state.VectorFunctionSpace())

            A = assemble(inner(w, h) * state.dx('magnetic'))
            solve(A, result.vector(), b)

        return result
Exemple #15
0
def compute_velocity_correction(
    ui, p0, p1, u_bcs, rho, mu, dt, rotational_form, my_dx, tol, verbose
):
    """Compute the velocity correction according to

    .. math::

        U = u_0 - \\frac{dt}{\\rho} \\nabla (p_1-p_0).
    """
    W = ui.function_space()
    P = p1.function_space()

    u = TrialFunction(W)
    v = TestFunction(W)
    a3 = dot(u, v) * my_dx
    phi = Function(P)
    phi.assign(p1)
    if p0:
        phi -= p0
    if rotational_form:
        r = SpatialCoordinate(W.mesh())[0]
        div_ui = 1 / r * (r * ui[0]).dx(0) + ui[1].dx(1)
        phi += mu * div_ui
    L3 = dot(ui, v) * my_dx - dt / rho * (phi.dx(0) * v[0] + phi.dx(1) * v[1]) * my_dx
    u1 = Function(W)
    solve(
        a3 == L3,
        u1,
        bcs=u_bcs,
        solver_parameters={
            "linear_solver": "iterative",
            "symmetric": True,
            "preconditioner": "hypre_amg",
            "krylov_solver": {
                "relative_tolerance": tol,
                "absolute_tolerance": 0.0,
                "maximum_iterations": 100,
                "monitor_convergence": verbose,
            },
        },
    )
    # u = project(ui - k/rho * grad(phi), V)
    # div_u = 1/r * div(r*u)
    r = SpatialCoordinate(W.mesh())[0]
    div_u1 = 1.0 / r * (r * u1[0]).dx(0) + u1[1].dx(1)
    info("||u||_div = {:e}".format(sqrt(assemble(div_u1 * div_u1 * my_dx))))
    return u1
Exemple #16
0
    def generate_mesh_deformation(self):
        """
        Generates an linear elastic mesh deformation using the steepest
        gradient as stress on the boundary.
        """
        u, v = TrialFunction(self.S), TestFunction(self.S)

        def compute_mu(constant=True):
            """
            Compute mu as according to arxiv paper
            https://arxiv.org/pdf/1509.08601.pdf
            """
            mu_min=Constant(1)
            mu_max=Constant(500)
            if constant:
                return mu_max
            else:
                V = FunctionSpace(self.mesh, "CG",1)
                u, v = TrialFunction(V), TestFunction(V)
                a = inner(grad(u),grad(v))*dx
                l = Constant(0)*v*dx
                bcs = []
                for marker in self.move_dict["Fixed"]:
                    bcs.append(DirichletBC(V, mu_min, self.mf, marker))
                for marker in self.move_dict["Deform"]:
                    bcs.append(DirichletBC(V, mu_max, self.mf, marker))
                mu = Function(V)
                solve(a==l, mu, bcs=bcs)
                return mu
        mu = compute_mu(False)
        
        def epsilon(u):
            return sym(grad(u))
        def sigma(u,mu=500, lmb=0):
            return 2*mu*epsilon(u) + lmb*tr(epsilon(u))*Identity(2)
        a = inner(sigma(u,mu=mu), grad(v))*dx
        L = inner(Constant((0,0)), v)*dx
        L -= self.dJ_form
        
        bcs = []
        for marker in self.move_dict["Fixed"]:
            bcs.append(DirichletBC(self.S,
                                   Constant([0]*mesh.geometric_dimension()),
                                   self.mf, marker))
        s = Function(self.S)
        solve(a==L, s, bcs=bcs)
        self.perturbation = s
Exemple #17
0
    def compile_objective_hessian(self):
        """Compute second variation of objective functional.

        This method only has side effects.
        """
        # Fast return if second variation was already compiled.
        if self.__objective_hessian is not None:
            return

        # Make sure first variation was compiled.
        if self.__objective_gradient is None:
            self.compile_objective_gradient()

        du = TrialFunction(self.function_space)
        self.__objective_hessian = derivative(self.__objective_gradient,
                                              self.u, du)
        return
 def __init__(self, VV):
     """ Input argument:
     VV = MixedFunctionSpace for both inversion parameters """
     self.ab = Function(VV)
     self.abv = self.ab.vector()
     self.MG = Function(VV)
     # cost
     self.a, self.b = self.ab.split(deepcopy=True)
     self.cost = 0.5*( inner(nabla_grad(self.a), nabla_grad(self.a))*\
     inner(nabla_grad(self.b), nabla_grad(self.b))*dx - \
     inner(nabla_grad(self.a), nabla_grad(self.b))*\
     inner(nabla_grad(self.a), nabla_grad(self.b))*dx )
     # gradient
     testa, testb = TestFunction(VV)
     grada = inner( nabla_grad(testa), \
     inner(nabla_grad(self.b), nabla_grad(self.b))*nabla_grad(self.a) - \
     inner(nabla_grad(self.a), nabla_grad(self.b))*nabla_grad(self.b) )*dx
     gradb = inner( nabla_grad(testb), \
     inner(nabla_grad(self.a), nabla_grad(self.a))*nabla_grad(self.b) - \
     inner(nabla_grad(self.a), nabla_grad(self.b))*nabla_grad(self.a) )*dx
     self.grad = grada + gradb
     # Hessian
     self.ahat, self.bhat = self.ab.split(deepcopy=True)
     self.abhat = Function(VV)
     at, bt = TestFunction(VV)
     ah, bh = TrialFunction(VV)
     wkform11 = inner( nabla_grad(at), \
     inner(nabla_grad(self.b), nabla_grad(self.b))*nabla_grad(ah) - \
     inner(nabla_grad(ah), nabla_grad(self.b))*nabla_grad(self.b) )*dx
     #
     wkform21 = inner( nabla_grad(bt), \
     2*inner(nabla_grad(self.a), nabla_grad(ah))*nabla_grad(self.b) - \
     inner(nabla_grad(self.a), nabla_grad(self.b))*nabla_grad(ah) - \
     inner(nabla_grad(ah), nabla_grad(self.b))*nabla_grad(self.a) )*dx
     #
     wkform12 = inner( nabla_grad(at), \
     2*inner(nabla_grad(self.b), nabla_grad(bh))*nabla_grad(self.a) - \
     inner(nabla_grad(self.a), nabla_grad(self.b))*nabla_grad(bh) - \
     inner(nabla_grad(self.a), nabla_grad(bh))*nabla_grad(self.b) )*dx
     #
     wkform22 = inner( nabla_grad(bt), \
     inner(nabla_grad(self.a), nabla_grad(self.a))*nabla_grad(bh) - \
     inner(nabla_grad(self.a), nabla_grad(bh))*nabla_grad(self.a) )*dx
     #
     self.hessian = wkform11 + wkform21 + wkform12 + wkform22
     self.precond = wkform11 + wkform22
Exemple #19
0
def solve_elasticity(mesh: Mesh) -> Function:
    V = VectorFunctionSpace(mesh, 'P', 1)
    bc = DirichletBC(V, Constant((0, 0, 0)), lambda x, on_boundary: on_boundary and near(x[2], 0))

    u = TrialFunction(V)
    v = TestFunction(V)

    f = Expression(('0', '0', '-rho*g'), rho=_c.rho, g=_c.g, degree=3)
    T = Constant((0, 0, 0))

    a = inner(sigma(u), sym(nabla_grad(v))) * dx
    L = dot(f, v) * dx + dot(T, v) * ds

    u = Function(V)
    solve(a == L, u, bc)

    return u
Exemple #20
0
def deformation_vector():
    # n1 = VolumeNormal(multimesh.part(1))
    x1 = SpatialCoordinate(multimesh.part(1))
    n1 = as_vector((x1[1], x1[0]))
    S_sm = VectorFunctionSpace(multimesh.part(1), "CG", 1)
    #bcs = [DirichletBC(S_sm, Constant((0,0)), mfs[1],2),
    bcs = [DirichletBC(S_sm, n1, mfs[1], 1)]

    u, v = TrialFunction(S_sm), TestFunction(S_sm)
    a = inner(grad(u), grad(v)) * dx
    l = inner(Constant((0., 0.)), v) * dx
    n = Function(S_sm)
    solve(a == l, n, bcs=bcs)
    S = MultiMeshVectorFunctionSpace(multimesh, "CG", 1)
    s = MultiMeshFunction(S)
    s.assign_part(1, n)
    return s
Exemple #21
0
    def __init__(self, N, dt):
        """Set up PDE problem for NxN mesh and time step dt."""
        from dolfin import UnitSquareMesh, FunctionSpace, TrialFunction, \
             TestFunction, Function, dx, dot, grad

        mesh = UnitSquareMesh(N, N)
        self.V = V = FunctionSpace(mesh, "Lagrange", 1)

        u = TrialFunction(V)
        v = TestFunction(V)

        a = u * v * dx + dt * dot(grad(u), grad(v)) * dx

        self.a = a
        self.dt = dt
        self.mesh = mesh
        self.U = Function(V)
    def __init__(self, energy, alpha, bcs, lb=None, ub=None):

        OptimisationProblem.__init__(self)
        self.energy = energy
        self.alpha = alpha
        self.V = self.alpha.function_space()
        self.denergy = derivative(self.energy, self.alpha,
                                  TestFunction(self.V))
        self.ddenergy = derivative(self.denergy, self.alpha,
                                   TrialFunction(self.V))
        if lb == None:
            lb = interpolate(Constant("0."), self.V)
        if ub == None:
            ub = interpolate(Constant("2."), self.V)
        self.lb = lb
        self.ub = ub
        self.bcs = bcs
        self.update_lb()
Exemple #23
0
        def __init__(self, V):
            self.sol = Expression(sympy.printing.ccode(solution),
                                  degree=MAX_DEGREE,
                                  t=0.0,
                                  cell=triangle)

            self.V = V
            u = TrialFunction(V)
            v = TestFunction(V)
            self.M = assemble(u * v * dx)

            n = FacetNormal(self.V.mesh())
            self.A = assemble(-inner(kappa * grad(u), grad(v /
                                                           (rho * cp))) * dx +
                              inner(kappa * grad(u), n) * v / (rho * cp) * ds)

            self.bcs = DirichletBC(self.V, self.sol, 'on_boundary')
            return
Exemple #24
0
    def before_first_compute(self, get):
        u = get("Velocity")
        assert len(u) == 2, "Can only compute stream function for 2D problems"
        V = u.function_space()
        spaces = SpacePool(V.mesh())
        degree = V.ufl_element().degree()
        V = spaces.get_space(degree, 0)

        psi = TrialFunction(V)
        self.q = TestFunction(V)
        a = dot(grad(psi), grad(self.q)) * dx()

        self.bc = DirichletBC(V, Constant(0), DomainBoundary())
        self.A = assemble(a)
        self.L = Vector()
        self.bc.apply(self.A)
        self.solver = KrylovSolver(self.A, "cg")
        self.psi = Function(V)
Exemple #25
0
def test_multi_ps_matrix_node_vector_fs(mesh):
    """Tests point source applied to a matrix with given constructor
    PointSource(V, source) and a vector function space when points
    placed at 3 vertices for 1D, 2D and 3D. Global points given to
    constructor from rank 0 processor.

    """

    point = [0.0, 0.5, 1.0]
    rank = MPI.rank(mesh.mpi_comm())
    V = VectorFunctionSpace(mesh, "CG", 1, dim=2)
    u, v = TrialFunction(V), TestFunction(V)
    w = Function(V)
    A = assemble(Constant(0.0) * dot(u, v) * dx)
    dim = mesh.geometry().dim()

    source = []
    point_coords = np.zeros(dim)
    for p in point:
        for i in range(dim):
            point_coords[i - 1] = p
        if rank == 0:
            source.append((Point(point_coords), 10.0))
    ps = PointSource(V, source)
    ps.apply(A)

    # Checks array sums to correct value
    A.get_diagonal(w.vector())
    a_sum = MPI.sum(mesh.mpi_comm(), np.sum(A.array()))
    assert round(a_sum - 2 * len(point) * 10) == 0

    # Check if coordinates are in portion of mesh and if so check that
    # diagonal components sum to the correct value.
    mesh_coords = V.tabulate_dof_coordinates()
    for p in point:
        for i in range(dim):
            point_coords[i] = p

        j = 0
        for i in range(len(mesh_coords) // (dim)):
            mesh_coords_check = mesh_coords[j:j + dim - 1]
            if np.array_equal(point_coords, mesh_coords_check) is True:
                assert np.round(w.vector()[j // (dim)] - 10.0) == 0.0
            j += dim
Exemple #26
0
    def assemble_matrices(self):
        V = VectorElement("Lagrange", self.mesh.ufl_cell(),
                          self.lagrange_order, dim = 3)
        self._VComplex = FunctionSpace(self.mesh, V*V)
        u = TrialFunction(self._VComplex)
        (ur, ui) = split(u)
        v = TestFunction(self._VComplex)
        (vr, vi) = split(v)

        A_ij = None
        B_ij = None

        # construct matrices for each domain
        if not isinstance(self.materials, collections.Iterable):
            material = self.materials
            C = as_matrix(material.el.C)
            rho = material.el.rho
            DX  = material.domain
            A_ij = LHS(self.q_b, C, ur, ui, vr, vi, DX)
            B_ij = RHS(rho, ur, ui, vr, vi, DX)


        else:
            counter = 0 # a work around for summing forms
            for material in self.materials:
                C = as_matrix(material.el.C)
                rho = material.el.rho
                DX  = material.domain
                
                if counter == 0:
                    A_ij = LHS(self.q_b, C, ur, ui, vr, vi, DX)
                    B_ij = RHS(rho, ur, ui, vr, vi, DX)
                    counter += 1
                else:
                    a_ij = LHS(self.q_b, C, ur, ui, vr, vi, DX)
                    b_ij = RHS(rho, ur, ui, vr, vi, DX)

                    A_ij += a_ij
                    B_ij += b_ij


        # assemble the matrices
        assemble(A_ij, tensor=self._A)
        assemble(B_ij, tensor=self._B)
def test_krylov_reuse_pc_lu():
    """Test that LU re-factorisation is only performed after
    set_operator(A) is called"""

    # Test requires PETSc version 3.5 or later. Use petsc4py to check
    # version number.
    try:
        from petsc4py import PETSc
    except ImportError:
        pytest.skip("petsc4py required to check PETSc version")
    else:
        if not PETSc.Sys.getVersion() >= (3, 5, 0):
            pytest.skip("PETSc version must be 3.5  of higher")

    mesh = UnitSquareMesh(MPI.comm_world, 12, 12)
    V = FunctionSpace(mesh, ("Lagrange", 1))
    u, v = TrialFunction(V), TestFunction(V)

    a = Constant(1.0) * u * v * dx
    L = Constant(1.0) * v * dx
    assembler = fem.Assembler(a, L)
    A = assembler.assemble_matrix()
    b = assembler.assemble_vector()
    norm = 13.0

    solver = PETScKrylovSolver(mesh.mpi_comm())
    solver.set_options_prefix("test_lu_")
    PETScOptions.set("test_lu_ksp_type", "preonly")
    PETScOptions.set("test_lu_pc_type", "lu")
    solver.set_from_options()
    solver.set_operator(A)
    x = PETScVector(mesh.mpi_comm())
    solver.solve(x, b)
    assert round(x.norm(cpp.la.Norm.l2) - norm, 10) == 0

    assembler = fem.assemble.Assembler(Constant(0.5) * u * v * dx, L)
    assembler.assemble(A)
    x = PETScVector(mesh.mpi_comm())
    solver.solve(x, b)
    assert round(x.norm(cpp.la.Norm.l2) - 2.0 * norm, 10) == 0

    solver.set_operator(A)
    solver.solve(x, b)
    assert round(x.norm(cpp.la.Norm.l2) - 2.0 * norm, 10) == 0
 def __init__(self, V, expression_type, basis_generation):
     self.V = V
     # Parametrized function to be interpolated
     mock_problem = MockProblem(V)
     f1 = ParametrizedExpression(
         mock_problem,
         "1/sqrt(pow(x[0]-mu[0], 2) + pow(x[1]-mu[1], 2) + 0.01)",
         mu=(-1., -1.),
         element=V.sub(1).ufl_element())
     f2 = ParametrizedExpression(
         mock_problem,
         "exp( - 2*pow(x[0]-mu[0], 2) - 2*pow(x[1]-mu[1], 2) )",
         mu=(-1., -1.),
         element=V.sub(1).ufl_element())
     f3 = ParametrizedExpression(
         mock_problem,
         "(1-x[0])*cos(3*pi*(pi+mu[1])*(1+x[1]))*exp(-(pi+mu[0])*(1+x[0]))",
         mu=(-1., -1.),
         element=V.sub(1).ufl_element())
     #
     folder_prefix = os.path.join("test_eim_approximation_05_tempdir",
                                  expression_type, basis_generation)
     assert expression_type in ("Vector", "Matrix")
     if expression_type == "Vector":
         vq = TestFunction(V)
         (v, q) = split(vq)
         form = f1 * v[0] * dx + f2 * v[1] * dx + f3 * q * dx
         # Call Parent constructor
         EIMApproximation.__init__(self, mock_problem,
                                   ParametrizedTensorFactory(form),
                                   folder_prefix, basis_generation)
     elif expression_type == "Matrix":
         up = TrialFunction(V)
         vq = TestFunction(V)
         (u, p) = split(up)
         (v, q) = split(vq)
         form = f1 * inner(grad(u), grad(v)) * dx + f2 * p * div(
             v) * dx + f3 * q * div(u) * dx
         # Call Parent constructor
         EIMApproximation.__init__(self, mock_problem,
                                   ParametrizedTensorFactory(form),
                                   folder_prefix, basis_generation)
     else:  # impossible to arrive here anyway thanks to the assert
         raise AssertionError("Invalid expression_type")
Exemple #29
0
 def __init__(self, truth_problem, expression_type, basis_generation):
     self.V = truth_problem.V1
     (f0, _) = split(truth_problem._solution)
     #
     folder_prefix = os.path.join("test_eim_approximation_15_tempdir", expression_type, basis_generation)
     assert expression_type in ("Vector", "Matrix")
     if expression_type == "Vector":
         v = TestFunction(self.V)
         form = inner(f0, grad(v))*dx
         # Call Parent constructor
         EIMApproximation.__init__(self, truth_problem, ParametrizedTensorFactory(form), folder_prefix, basis_generation)
     elif expression_type == "Matrix":
         u = TrialFunction(self.V)
         v = TestFunction(self.V)
         form = inner(f0, grad(u))*v*dx
         # Call Parent constructor
         EIMApproximation.__init__(self, truth_problem, ParametrizedTensorFactory(form), folder_prefix, basis_generation)
     else: # impossible to arrive here anyway thanks to the assert
         raise AssertionError("Invalid expression_type")
    def __init__(self, energy, alpha, bcs, lb=None, ub=None):

        NonlinearProblem.__init__(self)
        self.energy = energy
        self.alpha = alpha
        self.V = self.alpha.function_space()
        self.denergy = derivative(self.energy, self.alpha,
                                  TestFunction(self.V))
        self.ddenergy = derivative(self.denergy, self.alpha,
                                   TrialFunction(self.V))
        if lb == None:
            lb = interpolate(Constant("0."), self.V)
        if ub == None:
            ub = interpolate(Constant("1."), self.V)
        self.lb = lb
        self.ub = ub
        self.bcs = bcs
        self.b = PETScVector()
        self.A = PETScMatrix()
def test_numba_assembly():
    mesh = UnitSquareMesh(MPI.comm_world, 13, 13)
    Q = FunctionSpace(mesh, "Lagrange", 1)

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

    a = cpp.fem.Form([Q._cpp_object, Q._cpp_object])
    L = cpp.fem.Form([Q._cpp_object])

    sig = types.void(types.CPointer(typeof(ScalarType())),
                     types.CPointer(types.CPointer(typeof(ScalarType()))),
                     types.CPointer(types.double), types.intc)

    fnA = cfunc(sig, cache=True)(tabulate_tensor_A)
    a.set_cell_tabulate(0, fnA.address)

    fnb = cfunc(sig, cache=True)(tabulate_tensor_b)
    L.set_cell_tabulate(0, fnb.address)

    if (False):
        ufc_form = ffc_jit(dot(grad(u), grad(v)) * dx)
        ufc_form = cpp.fem.make_ufc_form(ufc_form[0])
        a = cpp.fem.Form(ufc_form, [Q._cpp_object, Q._cpp_object])
        ufc_form = ffc_jit(v * dx)
        ufc_form = cpp.fem.make_ufc_form(ufc_form[0])
        L = cpp.fem.Form(ufc_form, [Q._cpp_object])

    assembler = cpp.fem.Assembler([[a]], [L], [])
    A = PETScMatrix()
    b = PETScVector()
    assembler.assemble(A, cpp.fem.Assembler.BlockType.monolithic)
    assembler.assemble(b, cpp.fem.Assembler.BlockType.monolithic)

    Anorm = A.norm(cpp.la.Norm.frobenius)
    bnorm = b.norm(cpp.la.Norm.l2)

    print(Anorm, bnorm)

    assert (np.isclose(Anorm, 56.124860801609124))
    assert (np.isclose(bnorm, 0.0739710713711999))

    list_timings([TimingType.wall])
def main_slice_fem(mesh, subdomains, boundaries, src_pos, snk_pos):
    sigma_ROI = Constant(params.sigma_roi)
    sigma_SLICE = Constant(params.sigma_slice)
    sigma_SALINE = Constant(params.sigma_saline)
    sigma_AIR = Constant(0.)

    V = FunctionSpace(mesh, "CG", 2)
    v = TestFunction(V)
    u = TrialFunction(V)

    phi = Function(V)
    dx = Measure("dx")(subdomain_data=subdomains)
    ds = Measure("ds")(subdomain_data=boundaries)
    a = inner(sigma_ROI * grad(u), grad(v))*dx(params.roivol) + \
        inner(sigma_SLICE * grad(u), grad(v))*dx(params.slicevol) + \
        inner(sigma_SALINE * grad(u), grad(v))*dx(params.salinevol)
    L = Constant(0) * v * dx
    A = assemble(a)
    b = assemble(L)

    x_pos, y_pos, z_pos = src_pos
    point = Point(x_pos, y_pos, z_pos)
    delta = PointSource(V, point, 1.)
    delta.apply(b)

    x_pos, y_pos, z_pos = snk_pos
    point1 = Point(x_pos, y_pos, z_pos)
    delta1 = PointSource(V, point1, -1.)
    delta1.apply(b)

    solver = KrylovSolver("cg", "ilu")
    solver.parameters["maximum_iterations"] = 1000
    solver.parameters["absolute_tolerance"] = 1E-8
    solver.parameters["monitor_convergence"] = True

    info(solver.parameters, True)
    #    set_log_level(PROGRESS) does not work in fenics 2018.1.0
    solver.solve(A, phi.vector(), b)

    ele_pos_list = params.ele_coords
    vals = extract_pots(phi, ele_pos_list)
    # np.save(os.path.join('results', save_as), vals)
    return vals
Exemple #33
0
 def __init__(self, V, **kwargs):
     # Call parent
     ParametrizedProblem.__init__(self, os.path.join("test_eim_approximation_15_tempdir", expression_type, basis_generation, "mock_problem"))
     # Minimal subset of a ParametrizedDifferentialProblem
     self.V = V
     self._solution = Function(V)
     self.components = ["u", "s", "p"]
     # Parametrized function to be interpolated
     x = SpatialCoordinate(V.mesh())
     mu = SymbolicParameters(self, V, (-1., -1.))
     self.f00 = 1./sqrt(pow(x[0]-mu[0], 2) + pow(x[1]-mu[1], 2) + 0.01)
     self.f01 = 1./sqrt(pow(x[0]-mu[0], 4) + pow(x[1]-mu[1], 4) + 0.01)
     # Inner product
     f = TrialFunction(self.V)
     g = TestFunction(self.V)
     self.inner_product = assemble(inner(f, g)*dx)
     # Collapsed vector and space
     self.V0 = V.sub(0).collapse()
     self.V00 = V.sub(0).sub(0).collapse()
     self.V1 = V.sub(1).collapse()
Exemple #34
0
def les_setup(u_, mesh, assemble_matrix, CG1Function, nut_krylov_solver, bcs, **NS_namespace):
    """
    Set up for solving the Germano Dynamic LES model applying
    Lagrangian Averaging.
    """

    # Create function spaces
    CG1 = FunctionSpace(mesh, "CG", 1)
    p, q = TrialFunction(CG1), TestFunction(CG1)
    dim = mesh.geometry().dim()

    # Define delta and project delta**2 to CG1
    delta = pow(CellVolume(mesh), 1. / dim)
    delta_CG1_sq = project(delta, CG1)
    delta_CG1_sq.vector().set_local(delta_CG1_sq.vector().array()**2)
    delta_CG1_sq.vector().apply("insert")

    # Define nut_
    Sij = sym(grad(u_))
    magS = sqrt(2 * inner(Sij, Sij))
    Cs = Function(CG1)
    nut_form = Cs**2 * delta**2 * magS
    # Create nut_ BCs
    ff = MeshFunction("size_t", mesh, mesh.topology().dim() - 1, 0)
    bcs_nut = []
    for i, bc in enumerate(bcs['u0']):
        bc.apply(u_[0].vector())  # Need to initialize bc
        m = bc.markers()  # Get facet indices of boundary
        ff.array()[m] = i + 1
        bcs_nut.append(DirichletBC(CG1, Constant(0), ff, i + 1))
    nut_ = CG1Function(nut_form, mesh, method=nut_krylov_solver,
                       bcs=bcs_nut, bounded=True, name="nut")

    # Create functions for holding the different velocities
    u_CG1 = as_vector([Function(CG1) for i in range(dim)])
    u_filtered = as_vector([Function(CG1) for i in range(dim)])
    dummy = Function(CG1)
    ll = LagrangeInterpolator()

    # Assemble required filter matrices and functions
    G_under = Function(CG1, assemble(TestFunction(CG1) * dx))
    G_under.vector().set_local(1. / G_under.vector().array())
    G_under.vector().apply("insert")
    G_matr = assemble(inner(p, q) * dx)

    # Set up functions for Lij and Mij
    Lij = [Function(CG1) for i in range(dim * dim)]
    Mij = [Function(CG1) for i in range(dim * dim)]
    # Check if case is 2D or 3D and set up uiuj product pairs and
    # Sij forms, assemble required matrices
    Sijcomps = [Function(CG1) for i in range(dim * dim)]
    Sijfcomps = [Function(CG1) for i in range(dim * dim)]
    # Assemble some required matrices for solving for rate of strain terms
    Sijmats = [assemble_matrix(p.dx(i) * q * dx) for i in range(dim)]
    if dim == 3:
        tensdim = 6
        uiuj_pairs = ((0, 0), (0, 1), (0, 2), (1, 1), (1, 2), (2, 2))
    else:
        tensdim = 3
        uiuj_pairs = ((0, 0), (0, 1), (1, 1))

    # Set up Lagrange functions
    JLM = Function(CG1)
    JLM.vector()[:] += 1E-32
    JMM = Function(CG1)
    JMM.vector()[:] += 1

    return dict(Sij=Sij, nut_form=nut_form, nut_=nut_, delta=delta, bcs_nut=bcs_nut,
                delta_CG1_sq=delta_CG1_sq, CG1=CG1, Cs=Cs, u_CG1=u_CG1,
                u_filtered=u_filtered, ll=ll, Lij=Lij, Mij=Mij, Sijcomps=Sijcomps,
                Sijfcomps=Sijfcomps, Sijmats=Sijmats, JLM=JLM, JMM=JMM, dim=dim,
                tensdim=tensdim, G_matr=G_matr, G_under=G_under, dummy=dummy,
                uiuj_pairs=uiuj_pairs)
Exemple #35
0
    def solve(self):
        """ Find eigenvalues for transformed mesh. """
        self.progress("Building mesh.")
        # build transformed mesh
        mesh = self.refineMesh()
        # dim = mesh.topology().dim()
        if self.bcLast:
            mesh = transform_mesh(mesh, self.transformList)
            Robin, Steklov, shift, bcs = get_bc_parts(mesh, self.bcList)
        else:
            Robin, Steklov, shift, bcs = get_bc_parts(mesh, self.bcList)
            mesh = transform_mesh(mesh, self.transformList)
            # boundary conditions computed on non-transformed mesh
            # copy the values to transformed mesh
            fun = FacetFunction("size_t", mesh, shift)
            fun.array()[:] = bcs.array()[:]
            bcs = fun
        ds = Measure('ds', domain=mesh, subdomain_data=bcs)
        V = FunctionSpace(mesh, self.method, self.deg)
        u = TrialFunction(V)
        v = TestFunction(V)
        self.progress("Assembling matrices.")
        wTop = Expression(self.wTop, degree=self.deg)
        wBottom = Expression(self.wBottom, degree=self.deg)

        #
        # build stiffness matrix form
        #
        s = dot(grad(u), grad(v))*wTop*dx
        # add Robin parts
        for bc in Robin:
            s += Constant(bc.parValue)*u*v*wTop*ds(bc.value+shift)

        #
        # build mass matrix form
        #
        if len(Steklov) > 0:
            m = 0
            for bc in Steklov:
                m += Constant(bc.parValue)*u*v*wBottom*ds(bc.value+shift)
        else:
            m = u*v*wBottom*dx

        # assemble
        # if USE_EIGEN:
        #     S, M = EigenMatrix(), EigenMatrix()
            # tempv = EigenVector()
        # else:
        S, M = PETScMatrix(), PETScMatrix()
        # tempv = PETScVector()

        if not np.any(bcs.array() == shift+1):
            # no Dirichlet parts
            assemble(s, tensor=S)
            assemble(m, tensor=M)
        else:
            #
            # with EIGEN we could
            #   apply Dirichlet condition symmetrically
            #   completely remove rows and columns
            #
            # Dirichlet parts are marked with shift+1
            #
            # temp = Constant(0)*v*dx
            bc = DirichletBC(V, Constant(0.0), bcs, shift+1)
            # assemble_system(s, temp, bc, A_tensor=S, b_tensor=tempv)
            # assemble_system(m, temp, bc, A_tensor=M, b_tensor=tempv)
            assemble(s, tensor=S)
            bc.apply(S)
            assemble(m, tensor=M)
            # bc.zero(M)

        # if USE_EIGEN:
        #    M = M.sparray()
        #    M.eliminate_zeros()
        #    print M.shape
        #    indices = M.indptr[:-1] - M.indptr[1:] < 0
        #    M = M[indices, :].tocsc()[:, indices]
        #    S = S.sparray()[indices, :].tocsc()[:, indices]
        #    print M.shape
        #
        # solve the eigenvalue problem
        #
        self.progress("Solving eigenvalue problem.")
        eigensolver = SLEPcEigenSolver(S, M)
        eigensolver.parameters["problem_type"] = "gen_hermitian"
        eigensolver.parameters["solver"] = "krylov-schur"
        if self.target is not None:
            eigensolver.parameters["spectrum"] = "target real"
            eigensolver.parameters["spectral_shift"] = self.target
        else:
            eigensolver.parameters["spectrum"] = "smallest magnitude"
            eigensolver.parameters["spectral_shift"] = -0.01
        eigensolver.parameters["spectral_transform"] = "shift-and-invert"
        eigensolver.solve(self.number)
        self.progress("Generating eigenfunctions.")
        if eigensolver.get_number_converged() == 0:
            return None
        eigf = []
        eigv = []
        if self.deg > 1:
            mesh = refine(mesh)
        W = FunctionSpace(mesh, 'CG', 1)
        for i in range(eigensolver.get_number_converged()):
            pair = eigensolver.get_eigenpair(i)[::2]
            eigv.append(pair[0])
            u = Function(V)
            u.vector()[:] = pair[1]
            eigf.append(interpolate(u, W))
        return eigv, eigf
class ObjectiveFunctional(LinearOperator):
    """
    Provides data misfit, gradient and Hessian information for the data misfit
    part of a time-independent symmetric inverse problem.
    """
    __metaclass__ = abc.ABCMeta

    # Instantiation
    def __init__(self, V, Vm, bc, bcadj, \
    RHSinput=[], ObsOp=[], UD=[], Regul=[], Data=[], plot=False, \
    mycomm=None):
        # Define test, trial and all other functions
        self.trial = TrialFunction(V)
        self.test = TestFunction(V)
        self.mtrial = TrialFunction(Vm)
        self.mtest = TestFunction(Vm)
        self.rhs = Function(V)
        self.m = Function(Vm)
        self.mcopy = Function(Vm)
        self.srchdir = Function(Vm)
        self.delta_m = Function(Vm)
        self.MG = Function(Vm)
        self.Grad = Function(Vm)
        self.Gradnorm = 0.0
        self.lenm = len(self.m.vector().array())
        self.u = Function(V)
        self.ud = Function(V)
        self.diff = Function(V)
        self.p = Function(V)
        # Define weak forms to assemble A, C and E
        self._wkforma()
        self._wkformc()
        self._wkforme()
        # Store other info:
        self.ObsOp = ObsOp
        self.UD = UD
        self.reset()    # Initialize U, C and E to []
        self.Data = Data
        self.GN = 1.0   # GN = 0.0 => GN Hessian; = 1.0 => full Hessian
        # Operators and bc
        LinearOperator.__init__(self, self.delta_m.vector(), \
        self.delta_m.vector()) 
        self.bc = bc
        self.bcadj = bcadj
        self._assemble_solverM(Vm)
        self.assemble_A()
        self.assemble_RHS(RHSinput)
        self.Regul = Regul
        # Counters, tolerances and others
        self.nbPDEsolves = 0    # Updated when solve_A called
        self.nbfwdsolves = 0    # Counter for plots
        self.nbadjsolves = 0    # Counter for plots
        self._set_plots(plot)
        # MPI:
        self.mycomm = mycomm
        try:
            self.myrank = MPI.rank(self.mycomm)
        except:
            self.myrank = 0

    def copy(self):
        """Define a copy method"""
        V = self.trial.function_space()
        Vm = self.mtrial.function_space()
        newobj = self.__class__(V, Vm, self.bc, self.bcadj, [], self.ObsOp, \
        self.UD, self.Regul, self.Data, False)
        newobj.RHS = self.RHS
        newobj.update_m(self.m)
        return newobj

    def mult(self, mhat, y):
        """mult(self, mhat, y): do y = Hessian * mhat
        member self.GN sets full Hessian (=1.0) or GN Hessian (=0.0)"""
        N = self.Nbsrc # Number of sources
        y[:] = np.zeros(self.lenm)
        for C, E in zip(self.C, self.E):
            # Solve for uhat
            C.transpmult(mhat, self.rhs.vector())
            self.bcadj.apply(self.rhs.vector())
            self.solve_A(self.u.vector(), -self.rhs.vector())
            # Solve for phat
            E.transpmult(mhat, self.rhs.vector())
            Etmhat = self.rhs.vector().array()
            self.rhs.vector().axpy(1.0, self.ObsOp.incradj(self.u))
            self.bcadj.apply(self.rhs.vector())
            self.solve_A(self.p.vector(), -self.rhs.vector())
            # Compute Hessian*x:
            y.axpy(1.0/N, C * self.p.vector())
            y.axpy(self.GN/N, E * self.u.vector())
        y.axpy(1.0, self.Regul.hessian(mhat))

    # Getters
    def getm(self): return self.m
    def getmarray(self):    return self.m.vector().array()
    def getmcopyarray(self):    return self.mcopy.vector().array()
    def getVm(self):    return self.mtrial.function_space()
    def getMGarray(self):   return self.MG.vector().array()
    def getMGvec(self):   return self.MG.vector()
    def getGradarray(self):   return self.Grad.vector().array()
    def getGradnorm(self):  return self.Gradnorm
    def getsrchdirarray(self):    return self.srchdir.vector().array()
    def getsrchdirvec(self):    return self.srchdir.vector()
    def getsrchdirnorm(self):
        return np.sqrt((self.MM*self.getsrchdirvec()).inner(self.getsrchdirvec()))
    def getgradxdir(self): return self.gradxdir
    def getcost(self):  return self.cost, self.misfit, self.regul
    def getprecond(self):
        Prec = PETScKrylovSolver("richardson", "amg")
        Prec.parameters["maximum_iterations"] = 1
        Prec.parameters["error_on_nonconvergence"] = False
        Prec.parameters["nonzero_initial_guess"] = False
        Prec.set_operator(self.Regul.get_precond())
        return Prec
    def getMass(self):    return self.MM

    # Setters
    def setsrchdir(self, arr):  self.srchdir.vector()[:] = arr
    def setgradxdir(self, valueloc):   
        """Sum all local results for Grad . Srch_dir"""
        try:
            valueglob = MPI.sum(self.mycomm, valueloc)
        except:
            valueglob = valueloc
        self.gradxdir = valueglob

    # Solve
    def solvefwd(self, cost=False):
        """Solve fwd operators for given RHS"""
        self.nbfwdsolves += 1
        if self.ObsOp.noise:    self.noise = 0.0
        if self.plot:
            self.plotu = PlotFenics(self.plotoutdir)
            self.plotu.set_varname('u{0}'.format(self.nbfwdsolves))
        if cost:    self.misfit = 0.0
        for ii, rhs in enumerate(self.RHS):
            self.solve_A(self.u.vector(), rhs)
            if self.plot:   self.plotu.plot_vtk(self.u, ii)
            u_obs, noiselevel = self.ObsOp.obs(self.u)
            self.U.append(u_obs)
            if self.ObsOp.noise:    self.noise += noiselevel
            if cost:
                self.misfit += self.ObsOp.costfct(u_obs, self.UD[ii])
            self.C.append(assemble(self.c))
        if cost:
            self.misfit /= len(self.U)
            self.regul = self.Regul.cost(self.m)
            self.cost = self.misfit + self.regul
        if self.ObsOp.noise and self.myrank == 0:
            print 'Total noise in data misfit={:.5e}\n'.\
            format(self.noise*.5/len(self.U))
            self.ObsOp.noise = False    # Safety
        if self.plot:   self.plotu.gather_vtkplots()

    def solvefwd_cost(self):
        """Solve fwd operators for given RHS and compute cost fct"""
        self.solvefwd(True)

    def solveadj(self, grad=False):
        """Solve adj operators"""
        self.nbadjsolves += 1
        if self.plot:
            self.plotp = PlotFenics(self.plotoutdir)
            self.plotp.set_varname('p{0}'.format(self.nbadjsolves))
        self.Nbsrc = len(self.UD)
        if grad:    self.MG.vector()[:] = np.zeros(self.lenm)
        for ii, C in enumerate(self.C):
            self.ObsOp.assemble_rhsadj(self.U[ii], self.UD[ii], \
            self.rhs, self.bcadj)
            self.solve_A(self.p.vector(), self.rhs.vector())
            if self.plot:   self.plotp.plot_vtk(self.p, ii)
            self.E.append(assemble(self.e))
            if grad:    self.MG.vector().axpy(1.0/self.Nbsrc, \
                        C * self.p.vector())
        if grad:
            self.MG.vector().axpy(1.0, self.Regul.grad(self.m))
            self.solverM.solve(self.Grad.vector(), self.MG.vector())
            self.Gradnorm = np.sqrt(self.Grad.vector().inner(self.MG.vector()))
        if self.plot:   self.plotp.gather_vtkplots()

    def solveadj_constructgrad(self):
        """Solve adj operators and assemble gradient"""
        self.solveadj(True)

    # Assembler
    def assemble_A(self):
        """Assemble operator A(m)"""
        self.A = assemble(self.a)
        self.bc.apply(self.A)
        self.set_solver()

    def solve_A(self, b, f):
        """Solve system of the form A.b = f, 
        with b and f in form to be used in solver."""
        self.solver.solve(b, f)
        self.nbPDEsolves += 1

    def assemble_RHS(self, RHSin):
        """Assemble RHS for fwd solve"""
        if RHSin == []: self.RHS = None
        else:
            self.RHS = []
            for rhs in RHSin:
                if isinstance(rhs, Expression):
                    L = rhs*self.test*dx
                    b = assemble(L)
                    self.bc.apply(b)
                    self.RHS.append(b)
                else:   raise WrongInstanceError("rhs should be Expression")

    def _assemble_solverM(self, Vm):
        self.MM = assemble(inner(self.mtrial, self.mtest)*dx)
        self.solverM = LUSolver()
        self.solverM.parameters['reuse_factorization'] = True
        self.solverM.parameters['symmetric'] = True
        self.solverM.set_operator(self.MM)

    def _set_plots(self, plot):
        self.plot = plot
        if self.plot:
            filename, ext = splitext(sys.argv[0])
            self.plotoutdir = filename + '/Plots/'
            self.plotvarm = PlotFenics(self.plotoutdir)
            self.plotvarm.set_varname('m')

    def plotm(self, index):
        if self.plot:   self.plotvarm.plot_vtk(self.m, index)

    def gatherm(self):
        if self.plot:   self.plotvarm.gather_vtkplots()

    # Update param
    def update_Data(self, Data):
        """Update Data member"""
        self.Data = Data
        self.assemble_A()
        self.reset()

    def update_m(self, m):
        """Update values of parameter m"""
        if isinstance(m, np.ndarray):
            self.m.vector()[:] = m
        elif isinstance(m, Function):
            self.m.assign(m)
        elif isinstance(m, float):
            self.m.vector()[:] = m
        elif isinstance(m, int):
            self.m.vector()[:] = float(m)
        else:   raise WrongInstanceError('Format for m not accepted')
        self.assemble_A()
        self.reset()

    def backup_m(self):
        self.mcopy.assign(self.m)

    def restore_m(self):
        self.update_m(self.mcopy)

    def reset(self):
        """Reset U, C and E"""
        self.U = []
        self.C = []
        self.E = []

    def set_solver(self):
        """Reset solver for fwd operator"""
        self.solver = LUSolver()
        self.solver.parameters['reuse_factorization'] = True
        self.solver.set_operator(self.A)

    def addPDEcount(self, increment=1):
        """Increase 'nbPDEsolves' by 'increment'"""
        self.nbPDEsolves += increment

    def resetPDEsolves(self):
        self.nbPDEsolves = 0

    # Additional methods for compatibility with CG solver:
    def init_vector(self, x, dim):
        """Initialize vector x to be compatible with parameter
         Does not work in dolfin 1.3.0"""
        self.MM.init_vector(x, 0)

    def init_vector130(self):
        """Initialize vector x to be compatible with parameter"""
        return Vector(Function(self.mcopy.function_space()).vector())

    # Abstract methods
    @abc.abstractmethod
    def _wkforma(self): self.a = []

    @abc.abstractmethod
    def _wkformc(self): self.c = []

    @abc.abstractmethod
    def _wkforme(self): self.e = []
Exemple #37
0
def femsolve():
    
    ''' Bilineaarinen muoto:

        a(u,v) = L(v)
        a(u,v) = (inner(grad(u), grad(v)) + u*v)*dx
        L(v) = f*v*dx - g*v*ds
        g(x) = -du/dx = -u1, x = x1
        u(x0) = u0
        Omega = {xeR|x0<=x<=x1}

    '''

    from dolfin import UnitInterval, FunctionSpace, DirichletBC, TrialFunction
    from dolfin import TestFunction, grad, Constant, Function, solve, inner, dx, ds
    from dolfin import MeshFunction, assemble
    import dolfin
#    from dolfin import set_log_level, PROCESS

    # Create mesh and define function space
    mesh = UnitInterval(30)
    V = FunctionSpace(mesh, 'Lagrange', 2)

    boundaries  = MeshFunction('uint', mesh, mesh.topology().dim()-1)

    boundaries.set_all(0)

    class Left(dolfin.SubDomain):
        def inside(self, x, on_boundary):
            tol = 1E-14   # tolerance for coordinate comparisons
            return on_boundary and abs(x[0]) < tol

    class Right(dolfin.SubDomain):
        def inside(self, x, on_boundary):
            return dolfin.near(x[0], 1.0)
    
    left = Left()
    right = Right()
    
    left.mark(boundaries, 1)
    right.mark(boundaries, 2)

#    def u0_boundary(x):
#        return abs(x[0]) < tol
#    
#    bc = DirichletBC(V, Constant(u0), lambda x: abs(x[0]) < tol)
    
    bcs = [DirichletBC(V, Constant(u0), boundaries, 1)]
    
    # Define variational problem
    u = TrialFunction(V)
    v = TestFunction(V)
    a = (inner(grad(u), grad(v)) + u*v)*dx
    g = Constant(-u1)
    L = Constant(f)*v*dx - g*v*ds(2)
    
 #   set_log_level(PROCESS)
    # Compute solution
    
    A = assemble(a, exterior_facet_domains=boundaries)
    b = assemble(L, exterior_facet_domains=boundaries)
    for bc in bcs: 
        bc.apply(A, b)
    
    u = Function(V)
    solve(A, u.vector(), b, 'lu')
    
    coor = mesh.coordinates()
    u_array = u.vector().array()
    a = []
    b = []
    for i in range(mesh.num_vertices()):
        a.append(coor[i])
        b.append(u_array[i])
        print('u(%3.2f) = %0.14E'%(coor[i],u_array[i]))
    
    import numpy as np
    np.savez('fem',a,b)