示例#1
0
文件: pyfenics.py 项目: xshi/raser
    def boundary_definition_3D(self, my_d, model):
        """
        @description:
            Get boundary definition of 3D detector with Possion and Laplace
        @Modify:
            2021/08/31
        """
        bc_l = []
        p_ele, n_ele = self.model_para(my_d, model)
        x_list = []
        y_list = []
        radius = my_d.e_tr[0][2]
        for i in range(len(my_d.e_tr)):
            e_i = my_d.e_tr[i]
            x_list.append(e_i[0])
            y_list.append(e_i[1])
            str_e = "x[0]>={e_0}-{e_2} && x[0]<={e_0}+"\
                    +"{e_2} && x[1]>={e_1}-{e_2} && "\
                    +"x[1]<={e_1}+{e_2} && x[2]>={e_3} \
                    && x[2]<={e_4} && on_boundary"

            elec_p = str_e.format(e_0=e_i[0],
                                  e_1=e_i[1],
                                  e_2=e_i[2],
                                  e_3=e_i[3],
                                  e_4=e_i[4])
            if e_i[5] == "p":
                bc = fenics.DirichletBC(self.V, p_ele, elec_p)
            else:
                bc = fenics.DirichletBC(self.V, n_ele, elec_p)
            bc_l.append(bc)
        bc = self.out_column(x_list, y_list, radius, model, my_d)
        bc_l.append(bc)
        return bc_l
def main():
    domain = UPDomain(mesh,
                      IsoStVenant({'mu': 1})
                      # 'lambda': 1}),
                      # user_output_fn=output_fn
                      )

    lam = 2

    zero = fe.Constant(0)
    pull = fe.Expression('time*(lam - 1.)', time=0, lam=lam, degree=1)

    step1 = StaticStep(
        domain=domain,
        dbcs=[
            fe.DirichletBC(domain.V.sub(0), zero, 'on_boundary && near(x[0], 0)'),
            fe.DirichletBC(domain.V.sub(1), zero, 'on_boundary && near(x[1], 0)'),
            fe.DirichletBC(domain.V.sub(2), zero, 'on_boundary && near(x[2], 0)'),
            fe.DirichletBC(domain.V.sub(0), pull, 'on_boundary && near(x[0], 1.)'),
        ],
        t_start=0,
        t_end=1.,
        dt0=fe.Expression('dt', dt=0.1, degree=1),
        expressions=[pull])

    solver = SolidMechanicsSolver([step1])
    solver.solve()

    plt.plot(lams, stress)
    plt.show()
示例#3
0
    def boundary_conditions(self):

        return [
            fenics.DirichletBC(self.function_space.sub(1), (1., 0.), self.lid),
            fenics.DirichletBC(self.function_space.sub(1), (0., 0.),
                               self.fixed_walls)
        ]
    def boundary_conditions(self):

        return [
            fenics.DirichletBC(self.function_space.sub(2),
                               self.hot_wall_temperature, self.hot_wall),
            fenics.DirichletBC(self.function_space.sub(2),
                               self.cold_wall_temperature, self.cold_wall)
        ]
示例#5
0
 def set_bcs_staggered(self):
     self.middle.mark(self.boundaries, 1)
     self.presLoad = fe.Expression("t", t=0.0, degree=1)
     BC_u_left = fe.DirichletBC(self.U, fe.Constant((0., 0.)), self.left, method='pointwise')
     BC_u_right = fe.DirichletBC(self.U.sub(1), fe.Constant(0.), self.right, method='pointwise')
     BC_u_middle = fe.DirichletBC(self.U.sub(1), self.presLoad, self.middle, method='pointwise')
     self.BC_u = [BC_u_left, BC_u_right, BC_u_middle]
     self.BC_d = []
示例#6
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
示例#7
0
 def set_bcs_staggered(self):
     self.upper.mark(self.boundaries, 1)
     self.presLoad = fe.Expression(("t", 0), t=0.0, degree=1)
     BC_u_lower = fe.DirichletBC(self.U, fe.Constant((0., 0.)), self.lower)
     BC_u_upper = fe.DirichletBC(self.U, self.presLoad, self.upper)
     BC_u_left = fe.DirichletBC(self.U.sub(1), fe.Constant(0), self.left)
     BC_u_right = fe.DirichletBC(self.U.sub(1), fe.Constant(0), self.right)
     self.BC_u = [BC_u_lower, BC_u_upper, BC_u_left, BC_u_right]
     self.BC_d = []
示例#8
0
 def set_bcs_staggered(self):
     self.lower.mark(self.boundaries, 1)
     self.presLoad = fe.Expression("t", t=0.0, degree=1)
     BC_u_lower = fe.DirichletBC(self.U, fe.Constant((0., 0.)), self.lower)
     BC_u_segment = fe.DirichletBC(self.U.sub(1),
                                   self.presLoad,
                                   self.segment,
                                   method="pointwise")
     self.BC_u = [BC_u_lower, BC_u_segment]
     self.BC_d = []
示例#9
0
 def set_bcs_staggered(self):
     self.upper.mark(self.boundaries, 1)
     self.presLoad = fe.Expression("t", t=0.0, degree=1)
     BC_u_lower = fe.DirichletBC(self.U.sub(1), fe.Constant(0), self.lower)
     BC_u_upper = fe.DirichletBC(self.U.sub(1), self.presLoad, self.upper)
     BC_u_corner = fe.DirichletBC(self.U.sub(0),
                                  fe.Constant(0.0),
                                  self.corner,
                                  method='pointwise')
     self.BC_u = [BC_u_lower, BC_u_upper, BC_u_corner]
     self.BC_d = []
    def boundary_conditions(self):

        return [
            fenics.DirichletBC(self.function_space.sub(1), (0., 0.),
                               self.walls),
            fenics.DirichletBC(self.function_space.sub(2),
                               self.T(self.hot_wall_temperature_degC),
                               self.hot_wall),
            fenics.DirichletBC(self.function_space.sub(2),
                               self.T(self.cold_wall_temperature_degC),
                               self.cold_wall)
        ]
示例#11
0
def create_bcs_list(function_space, value, boundaries, idcs, **kwargs):
    """Create several Dirichlet boundary conditions at once.

	Wraps multiple Dirichlet boundary conditions into a list, in case
	they have the same value but are to be defined for multiple boundaries
	with different markers. Particularly useful for defining homogeneous
	boundary conditions.

	Parameters
	----------
	function_space : dolfin.function.functionspace.FunctionSpace
		The function space onto which the BCs should be imposed on.
	value : dolfin.function.constant.Constant or dolfin.function.expression.Expression or dolfin.function.function.Function or float or tuple(float)
		The value of the boundary condition. Has to be compatible with the function_space,
		so that it could also be used as ``fenics.DirichletBC(function_space, value, ...)``.
	boundaries : dolfin.cpp.mesh.MeshFunctionSizet
		The :py:class:`fenics.MeshFunction` object representing the boundaries.
	idcs : list[int] or int
		A list of indices / boundary markers that determine the boundaries
		onto which the Dirichlet boundary conditions should be applied to.
		Can also be a single integer for a single boundary.

	Returns
	-------
	list[dolfin.fem.dirichletbc.DirichletBC]
		A list of DirichletBC objects that represent the boundary conditions.

	Examples
	--------
	Generate homogeneous Dirichlet boundary conditions for all 4 sides of the unit square ::

	    from fenics import *
	    import cashocs

	    mesh, _, _, _, _, _ = cashocs.regular_mesh(25)
	    V = FunctionSpace(mesh, 'CG', 1)
	    bcs = cashocs.create_bcs_list(V, Constant(0), boundaries, [1,2,3,4])
	"""

    bcs_list = []
    if type(idcs) == list:
        for i in idcs:
            bcs_list.append(
                fenics.DirichletBC(function_space, value, boundaries, i,
                                   **kwargs))

    elif type(idcs) == int:
        bcs_list.append(
            fenics.DirichletBC(function_space, value, boundaries, idcs,
                               **kwargs))

    return bcs_list
示例#12
0
def dynamic_solver_func(ncells=10,  # количество узлов на заданном итервале
                        init_time=0,  # начальный момент времени
                        end_time=10,  # конечный момент времени
                        dxdphi=1,  # производная от потенциала по х
                        dydphi=1,  # производня от потенциала по у
                        x0=0,  # начальное положение по оси х
                        vx0=1,  # проекция начальной скорости на ось х
                        y0=0,  # начальное положение по оси у
                        vy0=1):  # проекция начальной скорости на ось у
    """ Функция на вход которой подается производная от потенциала
        гравитационного поля, возвращающая координаты смещенных
        материальных точек (частиц).
    """
    # генерация сетки на заданном интервале времени
    mesh = fen.IntervalMesh(ncells, 0, end_time-init_time)

    welm = fen.MixedElement([fen.FiniteElement('Lagrange', fen.interval, 2),
                             fen.FiniteElement('Lagrange', fen.interval, 2),
                             fen.FiniteElement('Lagrange', fen.interval, 2),
                             fen.FiniteElement('Lagrange', fen.interval, 2)])

    # генерация функционального рростаанства
    W = fen.FunctionSpace(mesh, welm)

    # постановка начальных условий задачи
    bcsys = [fen.DirichletBC(W.sub(0), fen.Constant(x0), 'near(x[0], 0)'),
             fen.DirichletBC(W.sub(1), fen.Constant(vx0), 'near(x[0], 0)'),
             fen.DirichletBC(W.sub(2), fen.Constant(y0), 'near(x[0], 0)'),
             fen.DirichletBC(W.sub(3), fen.Constant(vy0), 'near(x[0], 0)')]

    # опееделение тестовых функций для решения задачи
    up = fen.Function(W)
    x_cor, v_x, y_cor, v_y = fen.split(up)
    v1, v2, v3, v4 = fen.split(fen.TestFunction(W))

    # постановка задачи drdt = v; dvdt = - grad(phi) в проекциях на оси системы координат
    weak_form = (x_cor.dx(0) - v_x) * v1 * fen.dx + (v_x.dx(0) + dxdphi) * v2 * fen.dx \
                + (y_cor.dx(0) - v_y) * v3 * fen.dx + (v_y.dx(0) + dydphi) * v4 * fen.dx

    # решние поставленной задачи
    fen.solve(weak_form == 0, up, bcs=bcsys)

    # определение момента времени
    time = fen.Point(end_time - init_time)

    # расчет координат и скоростей
    x_end_time = up(time.x())[0]
    vx_end_time = up(time.x())[1]
    y_end_time = up(time.x())[2]
    vy_end_time = up(time.x())[3]

    return x_end_time, y_end_time, vx_end_time, vy_end_time
示例#13
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')
示例#14
0
文件: pyfenics.py 项目: xshi/raser
    def out_column(self, x_list, y_list, radius, model, my_d):
        x_min = min(x_list) - radius
        x_max = max(x_list) + radius
        y_min = min(y_list) - radius
        y_max = max(y_list) + radius

        x_center = my_d.e_tr[0][0]
        y_center = my_d.e_tr[0][1]
        str_e = "(x[0]-{e_0})*(x[0]-{e_0}) +(x[1]-{e_1})*(x[1]-{e_1}) >= {e_2}*{e_2}"
        elec_p = str_e.format(e_0=x_center, e_1=y_center, e_2=my_d.e_gap)
        if model == "Possion":
            bc = fenics.DirichletBC(self.V, 0.0, elec_p)
        elif model == "Laplace":
            bc = fenics.DirichletBC(self.V, 1.0, elec_p)
        return bc
示例#15
0
 def applyRightPotentialDirichletBC(self, u0):
     """FEniCS Dirichlet BC u0 for potential at right boundary."""
     self.boundary_conditions.extend([
         fn.DirichletBC(
             self.W.sub(0), u0,
             lambda x, on_boundary: self.boundary_R(x, on_boundary))
     ])
示例#16
0
 def applyLeftConcentrationDirichletBC(self, k, c0):
     """FEniCS Dirichlet BC c0 for k'th ion species at left boundary."""
     self.boundary_conditions.extend([
         fn.DirichletBC(
             self.W.sub(k + 1), c0,
             lambda x, on_boundary: self.boundary_L(x, on_boundary))
     ])
示例#17
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
示例#18
0
 def applyCentralReferenceConcentrationConstraint(self, k, c0):
     """FEniCS Dirichlet BC c0 for k'th ion species at right boundary."""
     self.boundary_conditions.extend([
         fn.DirichletBC(
             self.W.sub(k + 1), c0,
             lambda x, on_boundary: self.boundary_C(x, on_boundary))
     ])
示例#19
0
 def getDirichletBCs(self, vectorspace, *args, **kwargs):
     dbcs = []
     for (dict_key, dict_value) in self.bcs.iteritems():
         if dict_value["type"] == 'Dirichlet':
             bc = fenics.DirichletBC(vectorspace, dict_value["value"], self.markers[dict_key], dict_value.get("marked", 1), *args, **kwargs)
             dbcs.append(bc)
     return dbcs
    def get_nodepoints_from_boundary(mesh, boundaries, boundary_id):

        # Define an auxiliary Function Space.
        V = fn.FunctionSpace(mesh, 'Lagrange', 1)

        # Get the dimension of the auxiliary Function Space.
        F = V.dim()

        # Generate a map of the degrees of freedom (=nodes for this case).
        dofmap = V.dofmap()
        dofs = dofmap.dofs()

        # Apply a Dirichlet BC to a function to get nodes where the bc is applied.
        u = fn.Function(V)
        bc = fn.DirichletBC(V, fn.Constant(1.0), boundaries, 8)
        bc.apply(u.vector())
        dofs_bc = list(np.where(u.vector()[:] == 1.0))

        dofs_x = V.tabulate_dof_coordinates().reshape(F, mesh.topology().dim())

        coords_r = []
        coords_z = []

        # Get the coordinates of the nodes on the meniscus.
        for dof, coord in zip(dofs, dofs_x):
            if dof in dofs_bc[0]:
                coords_r.append(coord[0])
                coords_z.append(coord[1])
        coords_r = np.sort(coords_r)
        coords_z = np.sort(coords_z)[::-1]

        return coords_r, coords_z
示例#21
0
def fenics_solve(f):
    u = fn.Function(V, name="State")
    v = fn.TestFunction(V)
    F = (ufl.inner(ufl.grad(u), ufl.grad(v)) - f * v) * ufl.dx
    bcs = [fn.DirichletBC(V, 0.0, "on_boundary")]
    fn.solve(F == 0, u, bcs)
    return u, F, bcs
示例#22
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
示例#23
0
 def solve_pde(self):
     u = fe.Function(self.function_space)
     v = fe.TestFunction(self.function_space)
     u_old = fe.project(self.u_0, self.function_space)
     # Todo: Average right hand side if we choose it non-constant
     flux = self.dt * fe.dot(
         self.composed_diff_coef *
         (fe.grad(u) + self.drift_function(u)), fe.grad(v)) * fe.dx
     bilin_part = u * v * fe.dx + flux
     funtional_part = self.rhs * v * self.dt * fe.dx + u_old * v * fe.dx
     full_form = bilin_part - funtional_part
     num_steps = int(self.T / self.dt) + 1
     bc = fe.DirichletBC(self.function_space, self.u_boundary,
                         MembraneSimulator.full_boundary)
     for n in range(num_steps):
         print("Step %d" % n)
         self.time += self.dt
         fe.solve(full_form == 0, u, bc)
         # fe.plot(u)
         # plt.show()
         # print(fe.errornorm(u_old, u))
         u_old.assign(u)
         self.file << (u, self.time)
     f = fe.plot(u)
     plt.rc('text', usetex=True)
     plt.colorbar(f, format='%.0e')
     plt.title(r'Macroscopic density profile of $u(x,t)$ at $t=1$')
     plt.xlabel(r'$x_1$')
     plt.ylabel(r'$x_2$')
     plt.show()
    def set_constant_concentration(self, value):

        function_space_copy = fenics.FunctionSpace(self.mesh, self.element())

        new_solution = fenics.Function(function_space_copy)

        new_solution.vector()[:] = self.solution.vector()

        class WholeDomain(fenics.SubDomain):
            def inside(self, x, on_boundary):

                return True

        hack = fenics.DirichletBC(function_space_copy.sub(3), value,
                                  WholeDomain())

        hack.apply(new_solution.vector())

        for solution in self._solutions:

            solution.vector()[:] = new_solution.vector()

        for i in range(len(self._times)):

            self._times[i] = 0.
示例#25
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)
示例#26
0
    def set_solution_on_subdomain(self, subdomain, values):
        """ Abuse `fenics.DirichletBC` to set values of a function on a subdomain. 
        
        Parameters
        ----------
        subdomain
        
            `fenics.SubDomain`
            
        values
        
            container of objects that would typically be passed to 
            `fenics.DirichletBC` as the values of the boundary condition,
            one for each subspace of the mixed finite element solution space
        """
        function_space = fenics.FunctionSpace(self.mesh.leaf_node(),
                                              self.element())

        new_solution = fenics.Function(function_space)

        new_solution.vector()[:] = self.solution.vector()

        for function_subspace_index in range(len(fenics.split(self.solution))):

            hack = fenics.DirichletBC(
                function_space.sub(function_subspace_index),
                values[function_subspace_index], subdomain)

            hack.apply(new_solution.vector())

        self.solution.vector()[:] = new_solution.vector()
示例#27
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)
示例#28
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])
示例#29
0
def test_1d_velocity_unit__ci__():

    mesh = fenics.UnitIntervalMesh(5)

    V = fenics.VectorFunctionSpace(mesh, "P", 1)

    u = fenics.Function(V)

    bc = fenics.DirichletBC(V, [10.0], "x[0] < 0.5")

    print(bc.get_boundary_values())
示例#30
0
    def dirichlet(self, expression, bc_fnc=None):
        """
        This function defines Dirichlet boundary condition based on the given expression on the boundary.

        Args:
            expression (string): The expression used to evaluate the value of the unknown on the boundary.
            bc_fnc (fnc): The function which evaluates which nodes belong to the boundary to which the provided
                expression is applied as displacement.
        """
        bc_fnc = bc_fnc or self._default_bc_fnc
        return FEN.DirichletBC(self._job.V, expression, bc_fnc)