示例#1
0
def vjp_solve_eval_impl(
    g: np.array,
    fenics_solution: fenics.Function,
    fenics_residual: ufl.Form,
    fenics_inputs: List[FenicsVariable],
    bcs: List[fenics.DirichletBC],
) -> Tuple[np.array]:
    """Computes the gradients of the output with respect to the inputs."""
    # Convert tangent covector (adjoint) to a FEniCS variable
    adj_value = numpy_to_fenics(g, fenics_solution)
    adj_value = adj_value.vector()

    F = fenics_residual
    u = fenics_solution
    V = u.function_space()
    dFdu = fenics.derivative(F, u)
    adFdu = ufl.adjoint(
        dFdu, reordered_arguments=ufl.algorithms.extract_arguments(dFdu)
    )

    u_adj = fenics.Function(V)
    adj_F = ufl.action(adFdu, u_adj)
    adj_F = ufl.replace(adj_F, {u_adj: fenics.TrialFunction(V)})
    adj_F_assembled = fenics.assemble(adj_F)

    if len(bcs) != 0:
        for bc in bcs:
            bc.homogenize()
        hbcs = bcs

        for bc in hbcs:
            bc.apply(adj_F_assembled)
            bc.apply(adj_value)

    fenics.solve(adj_F_assembled, u_adj.vector(), adj_value)

    fenics_grads = []
    for fenics_input in fenics_inputs:
        if isinstance(fenics_input, fenics.Function):
            V = fenics_input.function_space()
        dFdm = fenics.derivative(F, fenics_input, fenics.TrialFunction(V))
        adFdm = fenics.adjoint(dFdm)
        result = fenics.assemble(-adFdm * u_adj)
        if isinstance(fenics_input, fenics.Constant):
            fenics_grad = fenics.Constant(result.sum())
        else:  # fenics.Function
            fenics_grad = fenics.Function(V, result)
        fenics_grads.append(fenics_grad)

    # Convert FEniCS gradients to jax array representation
    jax_grads = (
        None if fg is None else np.asarray(fenics_to_numpy(fg)) for fg in fenics_grads
    )

    jax_grad_tuple = tuple(jax_grads)

    return jax_grad_tuple
    def __init__(me, V, max_smooth_vectors=50):
        R = fenics.FunctionSpace(V.mesh(), 'R', 0)

        u_trial = fenics.TrialFunction(V)
        v_test = fenics.TestFunction(V)
        c_trial = fenics.TrialFunction(R)
        d_test = fenics.TestFunction(R)
        a11 = fenics.inner(fenics.grad(u_trial),
                           fenics.grad(v_test)) * fenics.dx
        a12 = c_trial * v_test * fenics.dx
        a21 = u_trial * d_test * fenics.dx
        A11 = convert_fenics_csr_matrix_to_scipy_csr_matrix(
            fenics.assemble(a11))
        A12 = convert_fenics_csr_matrix_to_scipy_csr_matrix(
            fenics.assemble(a12))
        A21 = convert_fenics_csr_matrix_to_scipy_csr_matrix(
            fenics.assemble(a21))
        me.A = sps.bmat([[A11, A12], [A21, None]]).tocsc()
        solve_A = spla.factorized(me.A)

        m = u_trial * v_test * fenics.dx
        me.M = convert_fenics_csr_matrix_to_scipy_csr_matrix(
            fenics.assemble(m)).tocsc()
        solve_M = spla.factorized(me.M)

        def solve_neumann(f_vec):
            fe_vec = np.concatenate([f_vec, np.array([0])])
            ue_vec = solve_A(fe_vec)
            u_vec = ue_vec[:-1]
            return u_vec

        me.solve_neumann_linop = spla.LinearOperator((V.dim(), V.dim()),
                                                     matvec=solve_neumann)
        me.solve_M_linop = spla.LinearOperator((V.dim(), V.dim()),
                                               matvec=solve_M)

        ee, UU = spla.eigsh(me.solve_neumann_linop,
                            k=max_smooth_vectors - 1,
                            M=me.solve_M_linop,
                            which='LM')

        me.U_smooth = np.zeros((V.dim(), max_smooth_vectors))
        const_fct = np.ones(V.dim())
        me.U_smooth[:, 0] = const_fct / np.sqrt(
            np.dot(const_fct, me.M * const_fct))
        me.U_smooth[:, 1:] = solve_M(UU[:, ::-1])

        me.k = 0
示例#3
0
    def __init__(self, K):
        # Variables
        x, y = sym.symbols('x[0], x[1]', real=True, positive=True)
        f = sym.Function('f')(x, y)

        grid = np.linspace(0, 1, K + 2)[1:-1]
        x_obs, y_obs = np.meshgrid(grid, grid)
        self.x_obs, self.y_obs = x_obs.reshape(K * K), y_obs.reshape(K * K)

        # --- THIS PART USED TO NOT BE PARALELLIZABLE --- #
        # Create mesh and define function space
        n_mesh = 80
        self.mesh = fen.UnitSquareMesh(n_mesh, n_mesh)
        self.f_space = fen.FunctionSpace(self.mesh, 'P', 2)

        # Define boundary condition
        # u_boundary = fen.Expression('x[0] + x[1]', degree=2)
        u_boundary = fen.Expression('0', degree=2)
        self.bound_cond = fen.DirichletBC(self.f_space, u_boundary,
                                          lambda x, on_boundary: on_boundary)

        # Define variational problem
        self.trial_f = fen.TrialFunction(self.f_space)
        self.test_f = fen.TestFunction(self.f_space)
        rhs = fen.Constant(50)

        self.lin_func = rhs * self.test_f * fen.dx
示例#4
0
    def __setup_decrease_computation(self):
        """Initializes attributes and solver for the frobenius norm check.

		Returns
		-------
		None
		"""

        if not self.angle_change > 0:
            raise ConfigError('MeshQuality', 'angle_change',
                              'This parameter has to be positive.')

        options = [[['ksp_type', 'preonly'], ['pc_type', 'jacobi'],
                    ['pc_jacobi_type', 'diagonal'], ['ksp_rtol', 1e-16],
                    ['ksp_atol', 1e-20], ['ksp_max_it', 1000]]]
        self.ksp_frobenius = PETSc.KSP().create()
        _setup_petsc_options([self.ksp_frobenius], options)

        self.trial_dg0 = fenics.TrialFunction(self.form_handler.DG0)
        self.test_dg0 = fenics.TestFunction(self.form_handler.DG0)

        if not (self.angle_change == float('inf')):
            self.search_direction_container = fenics.Function(
                self.form_handler.deformation_space)

            self.a_frobenius = self.trial_dg0 * self.test_dg0 * self.dx
            self.L_frobenius = fenics.sqrt(
                fenics.inner(fenics.grad(self.search_direction_container),
                             fenics.grad(self.search_direction_container))
            ) * self.test_dg0 * self.dx
示例#5
0
    def run(self):
        domain = self._create_domain()
        mesh = generate_mesh(domain, MESH_PTS)
        
        # fe.plot(mesh)
        # plt.show()

        self._create_boundary_expression()
        
        Omega = fe.FiniteElement("Lagrange", mesh.ufl_cell(), 1)
        R = fe.FiniteElement("Real", mesh.ufl_cell(), 0)
        W = fe.FunctionSpace(mesh, Omega*R)
        Theta, c = fe.TrialFunction(W)
        v, d = fe.TestFunctions(W)
        sigma = self.conductivity
        
        LHS = (sigma * fe.inner(fe.grad(Theta), fe.grad(v)) + c*v + Theta*d) * fe.dx
        RHS = self.boundary_exp * v * fe.ds

        w = fe.Function(W)
        fe.solve(LHS == RHS, w)
        Theta, c = w.split()
        print(c(0, 0))

        # fe.plot(Theta, "solution", mode='color', vmin=-3, vmax=3)
        # plt.show()

        plot(fe.interpolate(Theta, fe.FunctionSpace(mesh, Omega)), mode='color')
        plt.show()
示例#6
0
    def eva(self, num):
        # construct basis functions, Set num points corresponding to num basis functions
        basPoints = np.linspace(0, 1, num)
        dx = basPoints[1] - basPoints[0]
        aa, bb, cc = -dx, 0.0, dx
        for x_p in basPoints:
            self.theta.append(
                fe.interpolate(
                    fe.Expression(
                        'x[0] < a || x[0] > c ? 0 : (x[0] >=a && x[0] <= b ? (x[0]-a)/(b-a) : 1-(x[0]-b)/(c-b))',
                        degree=2,
                        a=aa,
                        b=bb,
                        c=cc), self.Vc))
            aa, bb, cc = aa + dx, bb + dx, cc + dx

        u_trial, u_test = fe.TrialFunction(self.Vu), fe.TestFunction(self.Vu)
        left = fe.inner(self.al * fe.nabla_grad(u_trial),
                        fe.nabla_grad(u_test)) * fe.dx
        right = self.f * u_test * fe.dx

        def boundaryD(x, on_boundary):
            return on_boundary and fe.near(x[1], 1.0)

        for i in range(num):
            uH = fe.Function(self.Vu)
            bcD = fe.DirichletBC(self.Vu, self.theta[i], boundaryD)
            left_m, right_m = fe.assemble_system(left, right, bcD)
            fe.solve(left_m, uH.vector(), right_m)
            self.sol.append(uH)
    def _assemble(self) -> Tuple[fenics.PETScMatrix, fenics.PETScMatrix]:
        """Construct matrices for generalized eigenvalue problem.

        Assemble the left and the right hand side of the eigenfunction
        equation into the corresponding matrices.

        Returns
        -------
        A : fenics.PETScMatrix
            Matrix corresponding to the form $a(u, v)$.
        B : fenics.PETScMatrix
            Matrix corresponding to the form $b(u, v)$.

        """
        V = self.vector_space

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

        a, b = self._construct_eigenproblem(u, v)

        A = fenics.PETScMatrix()
        B = fenics.PETScMatrix()

        fenics.assemble(a * fenics.dx, tensor=A)
        fenics.assemble(b * fenics.dx, tensor=B)

        return A, B
示例#8
0
def solver(f, u_D, bc_funs, ndim, length, nx, ny, nz=None, degree=1):
    """Fenics 求解器

    Args:
        f (Expression): [description]
        u_D (Expression): [description]
        bc_funs (List[Callable]): [description]
        ndim (int): [description]
        length (float): [description]
        nx (int): [description]
        ny (int): [description]
        nz (int, optional): [description]. Defaults to None.
        degree (int, optional): [description]. Defaults to 1.

    Returns:
        Function: 解 u
    """

    mesh = get_mesh(length, nx, ny, nz)
    V = fs.FunctionSpace(mesh, "P", degree)
    bcs = [fs.DirichletBC(V, u_D, bc) for bc in bc_funs]
    u = fs.TrialFunction(V)
    v = fs.TestFunction(V)
    FF = fs.dot(fs.grad(u), fs.grad(v)) * fs.dx - f * v * fs.dx
    a = fs.lhs(FF)
    L = fs.rhs(FF)
    u = fs.Function(V)
    fs.solve(a == L, u, bcs)
    return u
示例#9
0
 def generate_mesh(self, typ, order, resolution):
     self._mesh = mshr.generate_mesh(self._domain, resolution)
     self.input['mesh'] = self._mesh
     self._V = FEN.FunctionSpace(self._mesh, typ, order)
     self.input['V'] = self._V
     self._u = FEN.TrialFunction(self._V)
     self._v = FEN.TestFunction(self._V)
    def _make_variational_problem(V):
        """
        Formulate the variational problem a(u, v) = L(v).

        Parameters
        ----------
        V: FEniCS.FunctionSpace

        Returns
        -------
        a, L: FEniCS.Expression
            Variational forms.
        """
        # Define trial and test functions
        u = F.TrialFunction(V)
        v = F.TestFunction(V)

        # Collect Neumann conditions
        ds = F.Measure("ds", domain=mesh, subdomain_data=boundary_markers)
        integrals_N = []
        for i in boundary_conditions:
            if isinstance(boundary_conditions[i], dict):
                if "Neumann" in boundary_conditions[i]:
                    if boundary_conditions[i]["Neumann"] != 0:
                        g = boundary_conditions[i]["Neumann"]
                        integrals_N.append(g[0] * v * ds(i))

        # Define variational problem
        a = F.inner(u, v) * F.dx + (DT**2) * (C**2) * F.inner(
            F.grad(u), F.grad(v)) * F.dx
        L = ((DT**2) * f[0] + 2 * u_nm1 -
             u_nm2) * v * F.dx + (DT**2) * (C**2) * sum(integrals_N)
        return a, L
示例#11
0
    def __call__(self, mesh, V=None, Vc=None):

        boundaries, boundarymarkers, domainmarkers, dx, ds, V, Vc = SetupUnitMeshHelper(
            mesh, V, Vc)

        self._ds_markers = boundarymarkers
        self._dx_markers = domainmarkers

        self._dx = dx
        self._ds = ds
        self._boundaries = boundaries
        self._subdomains = self._boundaries

        u = df.TrialFunction(V)
        v = df.TestFunction(V)
        alpha = df.Function(Vc, name='conductivity')
        alpha.vector()[:] = 1

        def set_alpha(x):
            alpha.vector()[:] = x

        self._set_alpha = set_alpha
        a = alpha * df.inner(df.grad(u), df.grad(v)) * dx

        return a, set_alpha, alpha, V, Vc
示例#12
0
def setup_vectorspace(mesh):
    """setup"""
    V = fe.VectorFunctionSpace(mesh, "CG", 1, dim=3)
    v = fe.TestFunction(V)
    u = fe.TrialFunction(V)
    m = fe.Function(V)
    Heff = fe.Function(V)
    return m, Heff, u, v, V
示例#13
0
 def geneForwardMatrix(self, q_fun=fe.Constant(0.0), fR=fe.Constant(0.0), \
                       fI=fe.Constant(0.0)):
     if self.haveFunctionSpace == False:
         self.geneFunctionSpace()
         
     xx, yy, dPML, sig0_, p_ = self.domain.xx, self.domain.yy, self.domain.dPML,\
                               self.domain.sig0, self.domain.p
     # define the coefficents induced by PML
     sig1 = fe.Expression('x[0] > x1 && x[0] < x1 + dd ? sig0*pow((x[0]-x1)/dd, p) : (x[0] < 0 && x[0] > -dd ? sig0*pow((-x[0])/dd, p) : 0)', 
                  degree=3, x1=xx, dd=dPML, sig0=sig0_, p=p_)
     sig2 = fe.Expression('x[1] > x2 && x[1] < x2 + dd ? sig0*pow((x[1]-x2)/dd, p) : (x[1] < 0 && x[1] > -dd ? sig0*pow((-x[1])/dd, p) : 0)', 
                  degree=3, x2=yy, dd=dPML, sig0=sig0_, p=p_)
     
     sR = fe.as_matrix([[(1+sig1*sig2)/(1+sig1*sig1), 0.0], [0.0, (1+sig1*sig2)/(1+sig2*sig2)]])
     sI = fe.as_matrix([[(sig2-sig1)/(1+sig1*sig1), 0.0], [0.0, (sig1-sig2)/(1+sig2*sig2)]])
     cR = 1 - sig1*sig2
     cI = sig1 + sig2
     
     # define the coefficients with physical meaning
     angl_fre = self.kappa*np.pi
     angl_fre2 = fe.Constant(angl_fre*angl_fre)
     
     # define equations
     u_ = fe.TestFunction(self.V)
     du = fe.TrialFunction(self.V)
     
     u_R, u_I = fe.split(u_)
     duR, duI = fe.split(du)
     
     def sigR(v):
         return fe.dot(sR, fe.nabla_grad(v))
     def sigI(v):
         return fe.dot(sI, fe.nabla_grad(v))
     
     F1 = - fe.inner(sigR(duR)-sigI(duI), fe.nabla_grad(u_R))*(fe.dx) \
         - fe.inner(sigR(duI)+sigI(duR), fe.nabla_grad(u_I))*(fe.dx) \
         - fR*u_R*(fe.dx) - fI*u_I*(fe.dx)
     
     a2 = fe.inner(angl_fre2*q_fun*(cR*duR-cI*duI), u_R)*(fe.dx) \
          + fe.inner(angl_fre2*q_fun*(cR*duI+cI*duR), u_I)*(fe.dx) \
     
     # define boundary conditions
     def boundary(x, on_boundary):
         return on_boundary
     
     bc = [fe.DirichletBC(self.V.sub(0), fe.Constant(0.0), boundary), \
           fe.DirichletBC(self.V.sub(1), fe.Constant(0.0), boundary)]
     
     a1, L1 = fe.lhs(F1), fe.rhs(F1)
     self.u = fe.Function(self.V)
     self.A1 = fe.assemble(a1)
     self.b1 = fe.assemble(L1)
     self.A2 = fe.assemble(a2)
     bc[0].apply(self.A1, self.b1)
     bc[1].apply(self.A1, self.b1)
     bc[0].apply(self.A2)
     bc[1].apply(self.A2)
     self.A = self.A1 + self.A2
示例#14
0
 def _solve_pde(self, diff_coef):
     # Actual PDE solver for any coefficient diff_coef
     u = fe.TrialFunction(self.function_space)
     v = fe.TestFunction(self.function_space)
     a = fe.dot(diff_coef * fe.grad(u), fe.grad(v)) * fe.dx
     L = self.f * v * fe.dx
     bc = fe.DirichletBC(self.function_space, self.bc_function,
                         PoissonSolver.boundary)
     fe.solve(a == L, self.solution, bc)
示例#15
0
 def solve_problem_variational_form(self):
     u = fa.Function(self.V)
     du = fa.TrialFunction(self.V)
     v = fa.TestFunction(self.V)
     E = self._energy_density(u) * fa.dx
     dE = fa.derivative(E, u, v)
     jacE = fa.derivative(dE, u, du)
     fa.solve(dE == 0, u, self.bcs, J=jacE)
     return u
示例#16
0
文件: pyfenics.py 项目: xshi/raser
    def fenics_p_electric(self, my_d):
        """
        @description:
            Solve poisson equation to get potential and electric field
        @Modify:
            2021/08/31
        """
        if "plugin3D" in self.det_model:
            bc_l = []
            bc_l = self.boundary_definition_3D(my_d, "Possion")
        elif "planar3D" in self.det_model:
            bc_l = self.boundary_definition_2D(my_d, "Possion")

        u = fenics.TrialFunction(self.V)
        v = fenics.TestFunction(self.V)
        if self.det_dic['name'] == "lgad3D":
            if self.det_dic['part'] == 2:
                bond = self.det_dic['bond1']
                doping_avalanche = self.f_value(my_d, self.det_dic['doping1'])
                doping = self.f_value(my_d, self.det_dic['doping2'])
                f = fenics.Expression('x[2] < width ? doping1 : doping2',
                                      degree=1,
                                      width=bond,
                                      doping1=doping_avalanche,
                                      doping2=doping)
            elif self.det_dic['part'] == 3:
                bond1 = self.det_dic['bond1']
                bond2 = self.det_dic['bond2']
                doping1 = self.f_value(my_d, self.det_dic['doping1'])
                doping2 = self.f_value(my_d, self.det_dic['doping2'])
                doping3 = self.f_value(my_d, self.det_dic['doping3'])
                f = fenics.Expression(
                    'x[2] < bonda ? dopinga : x[2] > bondb ? dopingc : dopingb',
                    degree=1,
                    bonda=bond1,
                    bondb=bond2,
                    dopinga=doping1,
                    dopingb=doping2,
                    dopingc=doping3)
            else:
                print("The structure of lgad is wrong.")
        else:
            f = fenics.Constant(self.f_value(my_d))
        a = fenics.dot(fenics.grad(u), fenics.grad(v)) * fenics.dx
        L = f * v * fenics.dx
        # Compute solution
        self.u = fenics.Function(self.V)
        fenics.solve(a == L,
                     self.u,
                     bc_l,
                     solver_parameters=dict(linear_solver='gmres',
                                            preconditioner='ilu'))
        #calculate electric field
        W = fenics.VectorFunctionSpace(self.mesh3D, 'P', 1)
        self.E_field = fenics.project(
            fenics.as_vector((self.u.dx(0), self.u.dx(1), self.u.dx(2))), W)
示例#17
0
def forward(x):
    u = fn.TrialFunction(V)
    w = fn.TestFunction(V)
    sigma = lmbda * tr(sym(grad(u))) * Identity(2) + 2 * G * sym(
        grad(u))  # Stress
    R = simp(x) * inner(sigma, grad(w)) * dx - dot(b, w) * dx
    a, L = ufl.lhs(R), ufl.rhs(R)
    u = fa.Function(V)
    fa.solve(a == L, u, bcs)
    return u
示例#18
0
 def compute_operators(self):
     u = fa.TrialFunction(self.V)
     v = fa.TestFunction(self.V)
     form_a = fa.inner(fa.grad(u), fa.grad(v)) * fa.dx
     form_b = u * v * fa.dx
     A = da.assemble(form_a)
     B = da.assemble(form_b)
     A_np = np.array(A.array())
     B_np = np.array(B.array())
     return A_np, B_np
def test_empty_measure():
    mesh, _, _, dx, ds, dS = cashocs.regular_mesh(5)
    V = fenics.FunctionSpace(mesh, 'CG', 1)
    dm = cashocs.utils.EmptyMeasure(dx)

    trial = fenics.TrialFunction(V)
    test = fenics.TestFunction(V)

    assert fenics.assemble(1 * dm) == 0.0
    assert (fenics.assemble(test * dm).norm('linf')) == 0.0
    assert (fenics.assemble(trial * test * dm).norm('linf')) == 0.0
    def refine_mesh(self, tolerance: float) -> Optional[bool]:
        """Generate refined mesh.

        This method locates cells of the mesh where the error of the
        eigenfunction is above a certain threshold and generates a new mesh
        with finer resolution on the problematic regions.

        For a given eigenfunction $u$ with corresponding eigenvalue
        $\lambda$, it must be true that $a(u, v) = \lambda b(u, v)$ for all
        functions $v$. We make $v$ go through all the basis functions on the
        mesh and locate the cells where the previous identity fails to hold.

        Parameters
        ----------
        tolerance : float
            Criterion to determine whether a cell needs to be refined or not.

        Returns
        -------
        refined_mesh : Optional[fenics.Mesh]
            A new mesh derived from `mesh` with higher level of granularity
            on certain regions. If no refinements are needed, None is
            returned.

        """
        ew, ev = self.eigenvalues[1:], self.eigenfunctions[1:]
        dofs_needing_refinement = set()

        # Find all the degrees of freedom needing refinement.
        for k, (l, u) in enumerate(zip(ew, ev)):
            v = fenics.TrialFunction(self.vector_space)
            a, b = self._construct_eigenproblem(u, v)
            A = fenics.assemble(a * fenics.dx)
            B = fenics.assemble(b * fenics.dx)

            error = np.abs((A - l * B).sum())
            indices = np.flatnonzero(error > tolerance)
            dofs_needing_refinement.update(indices)

        if not dofs_needing_refinement:
            return

        # Refine the cells corresponding to the degrees of freedom needing
        # refinement.
        dofmap = self.vector_space.dofmap()
        cell_markers = fenics.MeshFunction('bool', self.mesh,
                                           self.mesh.topology().dim())
        cell_markers.set_all(False)
        for cell in fenics.cells(self.mesh):
            cell_dofs = set(dofmap.cell_dofs(cell.index()))
            if cell_dofs.intersection(dofs_needing_refinement):
                cell_markers[cell] = True

        return fenics.refine(self.mesh, cell_markers)
示例#21
0
    def create_bilinear_form_and_rhs(self):

        # Define variational problem
        u = fe.TrialFunction(self.function_space)
        v = fe.TestFunction(self.function_space)

        self.bilinear_form = (1 + self.lam * self.dt) *\
                (u * v * fe.dx) + self.dt * self.diffusion_coefficient *\
                (fe.dot(fe.grad(u), fe.grad(v)) * fe.dx)

        self.rhs = (self.u_n + self.dt * self.rhs_fun * self.u_n) * v * fe.dx
示例#22
0
 def _solve_cell_problems(self):
     # Solves the cell problems (one for each space dimension)
     w = fe.TrialFunction(self.function_space)
     v = fe.TestFunction(self.function_space)
     a = self.a_y * fe.dot(fe.grad(w), fe.grad(v)) * fe.dx
     for i in range(self.dim):
         L = fe.div(self.a_y * self.e_is[i]) * v * fe.dx
         bc = fe.DirichletBC(self.function_space, self.bc_function,
                             PoissonSolver.boundary)
         fe.solve(a == L, self.cell_solutions[i], bc)
         fe.plot(self.cell_solutions[i])
示例#23
0
 def mesh_gen_default(self, intervals, typ='P', order=1):
     """
     creates a square with sides of 1, divided by intervals
     by default the type of the volume associated with the mesh
     is considered to be Lagrangian, with order 1.
     """
     self._mesh = FEN.UnitSquareMesh(intervals, intervals)
     self.input['mesh'] = self._mesh
     self._V = FEN.FunctionSpace(self._mesh, typ, order)
     self.input['V'] = self._V
     self._u = FEN.TrialFunction(self._V)
     self._v = FEN.TestFunction(self._V)
示例#24
0
def calTrueSol(para):
    nx, ny = para['mesh_N'][0], para['mesh_N'][1]
    mesh = fe.UnitSquareMesh(nx, ny)
    Vu = fe.FunctionSpace(mesh, 'P', para['P'])
    Vc = fe.FunctionSpace(mesh, 'P', para['P'])
    al = fe.Constant(para['alpha'])
    f = fe.Expression(para['f'], degree=5)
    q1 = fe.interpolate(fe.Expression(para['q1'], degree=5), Vc)
    q2 = fe.interpolate(fe.Expression(para['q2'], degree=5), Vc)
    q3 = fe.interpolate(fe.Expression(para['q3'], degree=5), Vc)
    theta = fe.interpolate(fe.Expression(para['q4'], degree=5), Vc)

    class BoundaryX0(fe.SubDomain):
        def inside(self, x, on_boundary):
            return on_boundary and fe.near(x[0], 0.0)

    class BoundaryX1(fe.SubDomain):
        def inside(self, x, on_boundary):
            return on_boundary and fe.near(x[0], 1.0)

    class BoundaryY0(fe.SubDomain):
        def inside(self, x, on_boundary):
            return on_boundary and fe.near(x[1], 0.0)

    class BoundaryY1(fe.SubDomain):
        def inside(self, x, on_boundary):
            return on_boundary and fe.near(x[1], 1.0)

    boundaries = fe.MeshFunction('size_t', mesh, mesh.topology().dim() - 1)
    boundaries.set_all(0)
    bc0, bc1, bc2, bc3 = BoundaryX0(), BoundaryX1(), BoundaryY0(), BoundaryY1()
    bc0.mark(boundaries, 1)
    bc1.mark(boundaries, 2)
    bc2.mark(boundaries, 3)
    bc3.mark(boundaries, 4)

    domains = fe.MeshFunction("size_t", mesh, mesh.topology().dim())
    domains.set_all(0)

    bcD = fe.DirichletBC(Vu, theta, boundaries, 4)
    dx = fe.Measure('dx', domain=mesh, subdomain_data=domains)
    ds = fe.Measure('ds', domain=mesh, subdomain_data=boundaries)

    u_trial, u_test = fe.TrialFunction(Vu), fe.TestFunction(Vu)
    u = fe.Function(Vu)
    left = fe.inner(al * fe.nabla_grad(u_trial), fe.nabla_grad(u_test)) * dx
    right = f * u_test * dx + (q1 * u_test * ds(1) + q2 * u_test * ds(2) +
                               q3 * u_test * ds(3))

    left_m, right_m = fe.assemble_system(left, right, bcD)
    fe.solve(left_m, u.vector(), right_m)

    return u
示例#25
0
    def solve_problem_weak_form(self):
        u = fa.Function(self.V)
        du = fa.TrialFunction(self.V)
        v = fa.TestFunction(self.V)
        F = fa.inner(fa.grad(u), fa.grad(v)) * fa.dx - self.source * v * fa.dx
        J = fa.derivative(F, u, du)

        # The problem in this case is indeed linear, but using a nonlinear
        # solver doesn't hurt
        problem = fa.NonlinearVariationalProblem(F, u, self.bcs, J)
        solver = fa.NonlinearVariationalSolver(problem)
        solver.solve()
        return u
示例#26
0
def solve_poisson_problem(mesh, boundary_values_expression, forcing_function):
    """ Solve the Poisson problem with P2 elements. """
    V = fenics.FunctionSpace(mesh, "P", 2)

    u, v = fenics.TrialFunction(V), fenics.TestFunction(V)

    solution = fenics.Function(V)

    fenics.solve(
        fenics.dot(fenics.grad(v), fenics.grad(u)) * fenics.dx == v *
        forcing_function * fenics.dx, solution,
        fenics.DirichletBC(V, boundary_values_expression, boundary))

    return solution
示例#27
0
    def solve_problem_matrix_approach(self):
        u = fa.TrialFunction(self.V)
        v = fa.TestFunction(self.V)
        a = fa.inner(fa.grad(u), fa.grad(v)) * fa.dx
        L = self.source * v * fa.dx

        # equivalent to solve(a == L, U, b)
        A = fa.assemble(a)
        b = fa.assemble(L)
        [bc.apply(A, b) for bc in self.bcs]
        u = fa.Function(self.V)
        U = u.vector()
        fa.solve(A, U, b)
        return u
示例#28
0
    def __init__(self, N, K):
        # Variables
        x, y = sym.symbols('x[0], x[1]', real=True, positive=True)
        f = sym.Function('f')(x, y)

        # Precision (inverse covariance) operator, when α = 1
        tau, alpha = 3, 2
        precision = (-sym.diff(f, x, x) - sym.diff(f, y, y) + tau**2 * f)

        indices = [(m, n) for m in range(0, N) for n in range(0, N)]
        # indices = indices[:-1]
        self.indices = sorted(indices, key=max)
        eig_f = [
            sym.cos(i[0] * sym.pi * x) * sym.cos(i[1] * sym.pi * y)
            for i in self.indices
        ]

        # Eigenvalues of the covariance operator
        self.eig_v = [
            1 / (precision.subs(f, e).doit() / e).simplify()**alpha
            for e in eig_f
        ]

        grid = np.linspace(0, 1, K + 2)[1:-1]
        x_obs, y_obs = np.meshgrid(grid, grid)
        self.x_obs, self.y_obs = x_obs.reshape(K * K), y_obs.reshape(K * K)

        # Basis_functions
        self.functions = [
            f * np.sqrt(float(v)) for f, v in zip(eig_f, self.eig_v)
        ]

        # --- THIS PART USED TO NOT BE PARALELLIZABLE --- #
        # Create mesh and define function space
        n_mesh = 80
        mesh = fen.UnitSquareMesh(n_mesh, n_mesh)
        self.f_space = fen.FunctionSpace(mesh, 'P', 2)

        # Define boundary condition
        # u_boundary = fen.Expression('x[0] + x[1]', degree=2)
        u_boundary = fen.Expression('0', degree=2)
        self.bound_cond = fen.DirichletBC(self.f_space, u_boundary,
                                          lambda x, on_boundary: on_boundary)

        # Define variational problem
        self.trial_f = fen.TrialFunction(self.f_space)
        self.test_f = fen.TestFunction(self.f_space)
        rhs = fen.Constant(50)
        # rhs = fen.Expression('sin(x[0])*sin(x[1])', degree=2)
        self.lin_func = rhs * self.test_f * fen.dx
示例#29
0
    def xest_second_tutorial(self):
        T = 2.0  # final time
        num_steps = 50  # number of time steps
        dt = T / num_steps  # time step size
        # Create mesh and define function space
        nx = ny = 30
        mesh = fenics.RectangleMesh(fenics.Point(-2, -2), fenics.Point(2, 2),
                                    nx, ny)
        V = fenics.FunctionSpace(mesh, 'P', 1)

        # Define boundary condition
        def boundary(x, on_boundary):
            return on_boundary

        bc = fenics.DirichletBC(V, fenics.Constant(0), boundary)
        # Define initial value
        u_0 = fenics.Expression('exp(-a*pow(x[0], 2) - a*pow(x[1], 2))',
                                degree=2,
                                a=5)
        u_n = fenics.interpolate(u_0, V)
        # Define variational problem
        u = fenics.TrialFunction(V)
        v = fenics.TestFunction(V)
        f = fenics.Constant(0)
        F = u * v * fenics.dx + dt * fenics.dot(fenics.grad(u), fenics.grad(
            v)) * fenics.dx - (u_n + dt * f) * v * fenics.dx
        a, L = fenics.lhs(F), fenics.rhs(F)
        # Create VTK file for saving solution
        vtkfile = fenics.File(
            os.path.join(os.path.dirname(__file__), 'output', 'heat_gaussian',
                         'solution.pvd'))
        # Time-stepping
        u = fenics.Function(V)
        t = 0
        not_initialised = True
        for n in range(num_steps):
            # Update current time
            t += dt
            # Compute solution
            fenics.solve(a == L, u, bc)
            # Save to file and plot solution
            vtkfile << (u, t)
            # Here we'll need to call tripcolor ourselves to get access to the color range
            fenics.plot(u)
            animation_camera.snap()
            u_n.assign(u)
        animation = animation_camera.animate()
        animation.save(
            os.path.join(os.path.dirname(__file__), 'output',
                         'heat_gaussian.mp4'))
示例#30
0
    def solve_initial_problem_v2(self):
        V = fn.FunctionSpace(self.mesh, 'Lagrange', 2)

        # Define test and trial functions.
        v = fn.TestFunction(V)
        u = fn.TrialFunction(V)

        # Define radial coordinates.
        r = fn.SpatialCoordinate(self.mesh)[0]

        # Define the relative permittivity.

        class relative_perm(fn.UserExpression):
            def __init__(self, markers, subdomain_ids, **kwargs):
                super().__init__(**kwargs)
                self.markers = markers
                self.subdomain_ids = subdomain_ids

            def eval_cell(self, values, x, cell):
                if self.markers[cell.index] == self.subdomain_ids['Vacuum']:
                    values[0] = 1.
                else:
                    values[0] = 10.

        rel_perm = relative_perm(self.subdomains,
                                 self.subdomains_ids,
                                 degree=0)

        # Define the variational form.
        a = r * rel_perm * fn.inner(fn.grad(u), fn.grad(v)) * self.dx
        L = fn.Constant(0.) * v * self.dx

        # Define the boundary conditions.
        bc1 = fn.DirichletBC(V, fn.Constant(0.), self.boundaries,
                             self.boundaries_ids['Bottom_Wall'])
        bc4 = fn.DirichletBC(V, fn.Constant(-10.), self.boundaries,
                             self.boundaries_ids['Top_Wall'])
        bcs = [bc1, bc4]

        # Solve the problem.
        init_phi = fn.Function(V)
        fn.solve(a == L, init_phi, bcs)

        return Poisson.block_project(init_phi,
                                     self.mesh,
                                     self.restrictions_dict['vacuum_rtc'],
                                     self.subdomains,
                                     self.subdomains_ids['Vacuum'],
                                     space_type='scalar')