コード例 #1
0
ファイル: hat_function.py プロジェクト: blechta/dolfin-tape
def hat_function_collection(vertex_colors, color, element=None):
    """Return Expression on given element which takes values:
      1 ... if vertex_colors[node] == color
      0 ... at other nodes
    This is well defined just on Lagrange 1 element (default) and Dicontinuous
    Lagrange 1 element.

    NOTE: This expression provides a little hack as it lacks continuity across
    MPI partitions boundaries unless vertex_colors is compatible there. In fact,
    this behaviour is needed in FluxReconstructor."""
    assert isinstance(vertex_colors, cpp.VertexFunctionSizet)
    mesh = vertex_colors.mesh()
    if not element:
        element = FiniteElement('Lagrange', mesh.ufl_cell(), 1)
    assert element.family() in ['Lagrange', 'Discontinuous Lagrange']
    assert element.degree() == 1
    ufc_element, ufc_dofmap = jit(element, mpi_comm=mesh.mpi_comm())
    dolfin_element = cpp.FiniteElement(ufc_element)

    e = Expression(hats_cpp_code, element=element, domain=mesh)
    e.vertex_colors = vertex_colors
    e.color = color
    e.dolfin_element = dolfin_element

    return e
コード例 #2
0
ファイル: metric_matrix.py プロジェクト: getzze/magnum.fe
  def create_for_cube(size, coord, order=1):
    """
    Creates an expression for the metric matrix used for the cuboid
    transformation method for the stray-field calculation.

    *Arguments*
        size
            The size of the inner cuboid. This is used for the correct
            scaling of the tensor.
        coord
            The principal direction of transformation. For each shell
            patch this has to be chosen accordingly.
        order
            Order of transformation. Use 1 for P1 finite elements and
            2 for P>1 elements.
    """

    # Read cpp implementation from file
    filename = "%s/metric_matrix_cube_%d.cpp" % (os.path.dirname(__file__), order)
    code = open(filename, 'r').read()

    # Create Quadrature Element
    element = TensorElement("Quadrature", "tetrahedron", 2)

    # Initialize expression and set size and coord
    g = Expression(code, element=element)
    g.size_x = size[0]
    g.size_y = size[1]
    g.size_z = size[2]
    g.coord  = coord

    return g
コード例 #3
0
def _check_space_order(problem, method):
    mesh_generator, solution, weak_F = problem()

    # Translate data into FEniCS expressions.
    fenics_sol = Expression(smp.prining.ccode(solution['value']),
                            degree=solution['degree'],
                            t=0.0
                            )

    # Create initial solution.
    theta0 = Expression(fenics_sol.cppcode,
                        degree=solution['degree'],
                        t=0.0,
                        cell=triangle
                        )

    # Estimate the error component in space.
    # Leave out too rough discretizations to avoid showing spurious errors.
    N = [2 ** k for k in range(2, 8)]
    dt = 1.0e-8
    Err = []
    H = []
    for n in N:
        mesh = mesh_generator(n)
        H.append(MPI.max(mesh.hmax()))
        V = FunctionSpace(mesh, 'CG', 3)
        # Create boundary conditions.
        fenics_sol.t = dt
        #bcs = DirichletBC(V, fenics_sol, 'on_boundary')
        # Create initial state.
        theta_approx = method(V,
                              weak_F,
                              theta0,
                              0.0, dt,
                              bcs=[solution],
                              tol=1.0e-12,
                              verbose=True
                              )
        # Compute the error.
        fenics_sol.t = dt
        Err.append(errornorm(fenics_sol, theta_approx)
                   / norm(fenics_sol, mesh=mesh)
                   )
        print('n: %d    error: %e' % (n, Err[-1]))

    from matplotlib import pyplot as pp
    # Compare with order 1, 2, 3 curves.
    for o in [2, 3, 4]:
        pp.loglog([H[0], H[-1]],
                  [Err[0], Err[0] * (H[-1] / H[0]) ** o],
                  color='0.5'
                  )
    # Finally, the actual data.
    pp.loglog(H, Err, '-o')
    pp.xlabel('h_max')
    pp.ylabel('||u-u_h|| / ||u||')
    pp.show()
    return
コード例 #4
0
ファイル: problems.py プロジェクト: BijanZarif/ns-fenics
 def __init__(self, U_max, t, unit, s, K, compute_width):
     '''Unit and s characterize domain, t, K - time parameters,
     U_max is the maximal magnitude of inflow velocity.'''
     Expression.__init__(self)
     self.U_max, self.t, self.K = U_max, t, K
     # Channel width
     self.w = compute_width(unit)
     # Midpoint on the inflow
     M = [4*unit*cos(5*pi/4) + s*sin(5*pi/4) - 0.5*self.w*cos(5*pi/4),
          4*unit*sin(5*pi/4) - s*cos(5*pi/4) - 0.5*self.w*sin(5*pi/4)]
     self.M = M
コード例 #5
0
def initialise_multivector(mv, M):
    # initial multiindices
    mis = [Multiindex(mis) for mis in MultiindexSet.createCompleteOrderSet(M, 1)]
    # intialise fem vectors
    N = 15
    mesh = UnitSquareMesh(N, N)
    V = FunctionSpace(mesh, 'CG', 1)
    ex = Expression('sin(2*pi*A*x[0])', A=0)
    for i, mi in enumerate(mis):
        ex.A = i+1
        f = interpolate(ex, V)
        mv[mi] = FEniCSVector(f)
コード例 #6
0
def _compute_time_errors(problem, method, mesh_sizes, Dt, plot_error=False):
    mesh_generator, solution, ProblemClass, cell_type = problem()
    # Translate data into FEniCS expressions.
    fenics_sol = Expression(smp.printing.ccode(solution['value']),
                            degree=solution['degree'],
                            t=0.0,
                            cell=cell_type
                            )
    # Compute the problem
    errors = {'theta': numpy.empty((len(mesh_sizes), len(Dt)))}
    # Create initial state.
    # Deepcopy the expression into theta0. Specify the cell to allow for
    # more involved operations with it (e.g., grad()).
    theta0 = Expression(fenics_sol.cppcode,
                        degree=solution['degree'],
                        t=0.0,
                        cell=cell_type
                        )
    for k, mesh_size in enumerate(mesh_sizes):
        mesh = mesh_generator(mesh_size)
        V = FunctionSpace(mesh, 'CG', 1)
        theta_approx = Function(V)
        theta0p = project(theta0, V)
        stepper = method(ProblemClass(V))
        if plot_error:
            error = Function(V)
        for j, dt in enumerate(Dt):
            # TODO We are facing a little bit of a problem here, being the
            # fact that the time stepper only accept elements from V as u0.
            # In principle, though, this isn't necessary or required. We
            # could allow for arbitrary expressions here, but then the API
            # would need changing for problem.lhs(t, u).
            # Think about this.
            stepper.step(theta_approx, theta0p,
                         0.0, dt,
                         tol=1.0e-12,
                         verbose=False
                         )
            fenics_sol.t = dt
            #
            # NOTE
            # When using errornorm(), it is quite likely to see a good part
            # of the error being due to the spatial discretization.  Some
            # analyses "get rid" of this effect by (sometimes implicitly)
            # projecting the exact solution onto the discrete function
            # space.
            errors['theta'][k][j] = errornorm(fenics_sol, theta_approx)
            if plot_error:
                error.assign(project(fenics_sol - theta_approx, V))
                plot(error, title='error (dt=%e)' % dt)
                interactive()
    return errors, stepper.name, stepper.order
コード例 #7
0
    def EoM_term(self, term, output_label=True):

        # cast params as constant functions so that, if they are set to 0, FEniCS still understand
        # what is being integrated
        mu, M = Constant(self.physics.mu), Constant(self.physics.M)
        lam = Constant(self.physics.lam)
        mn = Constant(self.mn)

        D = self.physics.D

        Phi = self.Phi
        varPhi = self.varPhi

        # define r for use in the computation of the Laplacian
        r = Expression('x[0]', degree=self.fem.func_degree)

        if term == 1:
            Term = (Constant(D - 1.) / r * Phi.dx(0) + Phi.dx(0).dx(0)) * mn**2
            label = r"$\nabla^2\phi$"
        elif term == 2:
            Term = mu**2 * varPhi
            label = r"$m^2\phi$"
        elif term == 3:
            Term = -lam * varPhi**3
            label = r"$-\lambda \phi^3$"
        elif term == 4:
            Term = mn**D / M**2 * self.source.rho * varPhi
            label = r"$\frac{\rho}{M^2}\phi$"

        Term = project(Term, self.fem.dS, self.physics.D, self.fem.func_degree)

        if output_label:
            return Term, label
        else:
            return Term
コード例 #8
0
def test_taylor_hood_cube():
    pytest.xfail("Problem with Mixed Function Spaces")
    meshc = UnitCubeMesh(MPI.comm_world, 2, 2, 2)
    meshf = UnitCubeMesh(MPI.comm_world, 3, 4, 5)

    Ve = VectorElement("CG", meshc.ufl_cell(), 2)
    Qe = FiniteElement("CG", meshc.ufl_cell(), 1)
    Ze = MixedElement([Ve, Qe])

    Zc = FunctionSpace(meshc, Ze)
    Zf = FunctionSpace(meshf, Ze)

    @function.expression.numba_eval
    def expr_eval(values, x, cell_idx):
        values[:, 0] = x[:, 0] * x[:, 1]
        values[:, 1] = x[:, 1] * x[:, 2]
        values[:, 2] = x[:, 2] * x[:, 0]
        values[:, 3] = x[:, 0] + 3.0 * x[:, 1] + x[:, 2]

    z = Expression(expr_eval, shape=(4,))
    zc = interpolate(z, Zc)
    zf = interpolate(z, Zf)

    mat = PETScDMCollection.create_transfer_matrix(Zc, Zf)
    Zuc = Function(Zf)
    mat.mult(zc.vector(), Zuc.vector())
    Zuc.vector().update_ghost_values()

    diff = Function(Zf)
    diff.assign(Zuc - zf)
    assert diff.vector().norm("l2") < 1.0e-12
コード例 #9
0
def test_vector_p1_3d():
    meshc = UnitCubeMesh(MPI.comm_world, 2, 3, 4)
    meshf = UnitCubeMesh(MPI.comm_world, 3, 4, 5)

    Vc = VectorFunctionSpace(meshc, ("CG", 1))
    Vf = VectorFunctionSpace(meshf, ("CG", 1))

    @function.expression.numba_eval
    def expr_eval(values, x, cell_idx):
        values[:, 0] = x[:, 0] + 2.0 * x[:, 1]
        values[:, 1] = 4.0 * x[:, 0]
        values[:, 2] = 3.0 * x[:, 2] + x[:, 0]

    u = Expression(expr_eval, shape=(3,))
    uc = interpolate(u, Vc)
    uf = interpolate(u, Vf)

    mat = PETScDMCollection.create_transfer_matrix(Vc._cpp_object,
                                                   Vf._cpp_object)
    Vuc = Function(Vf)
    mat.mult(uc.vector(), Vuc.vector())

    diff = Vuc.vector()
    diff.axpy(-1, uf.vector())
    assert diff.norm() < 1.0e-12
コード例 #10
0
ファイル: test_Probes.py プロジェクト: sweeneyd/fenicstools
def test_Probes_vectorfunctionspace_2D(VF2, dirpath):
    u0 = interpolate(Expression(('x[0]', 'x[1]'), degree=1), VF2)
    x = array([[0.5, 0.5], [0.4, 0.4], [0.3, 0.3]])

    p = Probes(x.flatten(), VF2)

    # Probe twice
    p(u0)
    p(u0)

    # Check both snapshots
    p0 = p.array(N=0)
    if MPI.rank(mpi_comm_world()) == 0:
        assert round(p0[0, 0] - 0.5, 7) == 0
        assert round(p0[1, 1] - 0.4, 7) == 0
        assert round(p0[2, 1] - 0.3, 7) == 0
    p0 = p.array(N=1)
    if MPI.rank(mpi_comm_world()) == 0:
        assert round(p0[0, 0] - 0.5, 7) == 0
        assert round(p0[1, 0] - 0.4, 7) == 0
        assert round(p0[2, 1] - 0.3, 7) == 0

    p0 = p.array(filename=dirpath + 'dumpvector2D')
    if MPI.rank(mpi_comm_world()) == 0:
        assert round(p0[0, 0, 0] - 0.5, 7) == 0
        assert round(p0[1, 1, 1] - 0.4, 7) == 0
        assert round(p0[2, 0, 1] - 0.3, 7) == 0

        p1 = load(dirpath + 'dumpvector2D_all.npy')
        assert round(p1[0, 0, 0] - 0.5, 7) == 0
        assert round(p1[1, 1, 0] - 0.4, 7) == 0
        assert round(p1[2, 1, 1] - 0.3, 7) == 0
コード例 #11
0
ファイル: test_XDMF.py プロジェクト: tianyikillua/dolfinx
def test_save_and_checkpoint_timeseries(tempdir, encoding):
    if invalid_config(encoding):
        pytest.skip("XDMF unsupported in current configuration")

    mesh = UnitSquareMesh(MPI.comm_world, 16, 16)
    filename = os.path.join(tempdir, "u2_checkpoint.xdmf")
    FE = FiniteElement("CG", mesh.ufl_cell(), 2)
    V = FunctionSpace(mesh, FE)

    times = [0.5, 0.2, 0.1]
    u_out = [None] * len(times)
    u_in = [None] * len(times)

    with XDMFFile(mesh.mpi_comm(), filename, encoding=encoding) as file:
        for i, p in enumerate(times):
            u_out[i] = interpolate(Expression("x[0]*p", p=p, degree=1), V)
            file.write_checkpoint(u_out[i], "u_out", p)

    with XDMFFile(mesh.mpi_comm(), filename) as file:
        for i, p in enumerate(times):
            u_in[i] = file.read_checkpoint(V, "u_out", i)

    for i, p in enumerate(times):
        u_in[i].vector().axpy(-1.0, u_out[i].vector())
        assert u_in[i].vector().norm(cpp.la.Norm.l2) < 1.0e-12

    # test reading last
    with XDMFFile(mesh.mpi_comm(), filename) as file:
        u_in_last = file.read_checkpoint(V, "u_out", -1)

    u_out[-1].vector().axpy(-1.0, u_in_last.vector())
    assert u_out[-1].vector().norm(cpp.la.Norm.l2) < 1.0e-12
コード例 #12
0
def test_HarmonicSmoothing():

    # Create some mesh and its boundary
    mesh = UnitSquareMesh(10, 10)
    boundary = BoundaryMesh(mesh, 'exterior')

    # Move boundary
    disp = Expression(("0.3*x[0]*x[1]", "0.5*(1.0-x[1])"), degree=2)
    ALE.move(boundary, disp)

    # Move mesh according to given boundary
    ALE.move(mesh, boundary)

    # Check that new boundary topology corresponds to given one
    boundary_new = BoundaryMesh(mesh, 'exterior')
    assert boundary.topology().hash() == boundary_new.topology().hash()

    # Check that coordinates are almost equal
    err = sum(sum(abs(boundary.coordinates() \
                    - boundary_new.coordinates()))) / mesh.num_vertices()
    print("Current CG solver produced error in boundary coordinates", err)
    assert round(err - 0.0, 5) == 0

    # Check mesh quality
    magic_number = 0.35
    rmin = MeshQuality.radius_ratio_min_max(mesh)[0]
    assert rmin > magic_number
コード例 #13
0
def get_list_of_functions_1(block_V):
    shape_1 = block_V[0].ufl_element().value_shape()
    if len(shape_1) == 0:
        f = Expression("2*x[0] + 4*x[1]*x[1]", degree=2)
    elif len(shape_1) == 1 and shape_1[0] == 2:
        f = Expression(("2*x[0] + 4*x[1]*x[1]", "3*x[0] + 5*x[1]*x[1]"),
                       degree=2)
    elif len(shape_1) == 1 and shape_1[0] == 3:
        f = Expression(("2*x[0] + 4*x[1]*x[1]", "3*x[0] + 5*x[1]*x[1]",
                        "7*x[0] + 11*x[1]*x[1]"),
                       degree=2)
    elif len(shape_1) == 2:
        f = Expression((("2*x[0] + 4*x[1]*x[1]", "3*x[0] + 5*x[1]*x[1]"),
                        ("7*x[0] + 11*x[1]*x[1]", "13*x[0] + 17*x[1]*x[1]")),
                       degree=2)
    return [project(f, block_V[0])]
コード例 #14
0
    def strong_residual_form(self, sol, units):

        if units == 'rescaled':
            resc = 1.
        elif units == 'physical':
            resc = self.mn**2 * self.mf
        else:
            message = "Invalid choice of units: valid choices are 'physical' or 'rescaled'."
            raise ValueError, message

        # cast params as constant functions so that, if they are set to 0, FEniCS still understand
        # what is being integrated
        mu, M = Constant(self.physics.mu), Constant(self.physics.M)
        lam = Constant(self.physics.lam)
        mn, mf = Constant(self.mn), Constant(self.mf)

        D = self.physics.D

        # define r for use in the computation of the Laplacian
        r = Expression('x[0]', degree=self.fem.func_degree)

        # I expand manually the Laplacian into (D-1)/r df/dr + d2f/dr2
        f = sol.dx(0).dx(0) + Constant(D-1.)/r * sol.dx(0) - lam*(mf/mn)**2*sol**3 \
            - 3.*d.sqrt(lam)*(mu*mf/mn**2)*sol**2 - 2.*(mu/mn)**2*sol - (mn**(D-2.)/(mf*M))*self.source.rho
        f *= resc
        F = project(f, self.fem.dS, self.physics.D, self.fem.func_degree)

        return F
コード例 #15
0
    def linear_solver(self, phi_k):

        # cast params as constant functions so that, if they are set to 0, FEniCS still understand
        # what is being integrated
        mu, M = Constant(self.physics.mu), Constant(self.physics.M)
        lam = Constant(self.physics.lam)
        mn, mf = Constant(self.mn), Constant(self.mf)

        D = self.physics.D

        # boundary condition
        Dirichlet_bc = self.get_Dirichlet_bc()

        # trial and test function
        phi = d.TrialFunction(self.fem.S)
        v = d.TestFunction(self.fem.S)

        # r^(D-1)
        rD = Expression('pow(x[0],D-1)', D=D, degree=self.fem.func_degree)

        # bilinear form a and linear form L
        a = - inner( grad(phi), grad(v) ) * rD * dx + ( - 3.*lam*(mf/mn)**2*phi_k**2 \
            - 6.*d.sqrt(lam)*(mu*mf/mn**2)*phi_k - 2.*(mu/mn)**2 ) * phi * v * rD * dx
        L = ( (mn**(D-2.)/(mf*M))*self.source.rho - 2.*lam*(mf/mn)**2*phi_k**3 \
            - 3.*d.sqrt(lam)*(mu*mf/mn**2)*phi_k**2 ) * v * rD * dx

        # define a vector with the solution
        sol = d.Function(self.fem.S)

        # solve linearised system
        pde = d.LinearVariationalProblem(a, L, sol, Dirichlet_bc)
        solver = d.LinearVariationalSolver(pde)
        solver.solve()

        return sol
コード例 #16
0
def test_mixed_parallel():
    mesh = UnitSquareMesh(MPI.comm_world, 5, 8)
    V = VectorElement("Lagrange", triangle, 4)
    Q = FiniteElement("Lagrange", triangle, 5)
    W = FunctionSpace(mesh, Q * V)
    F = Function(W)

    tree = cpp.geometry.BoundingBoxTree(mesh, mesh.geometry.dim)

    @function.expression.numba_eval
    def expr_eval(values, x, cell_idx):
        values[:, 0] = x[:, 0]
        values[:, 1] = x[:, 1]
        values[:, 2] = numpy.sin(x[:, 0] + x[:, 1])

    F.interpolate(Expression(expr_eval, shape=(3,)))

    # Generate random points in this mesh partition (one per cell)
    x = numpy.zeros(3)
    for c in Cells(mesh):
        x[0] = random()
        x[1] = random() * (1 - x[0])
        x[2] = (1 - x[0] - x[1])
        p = Point(0.0, 0.0)
        for i, v in enumerate(VertexRange(c)):
            p += v.point() * x[i]
        p = p.array()[:2]

        val = F(p, tree)
        assert numpy.allclose(val[0], p[0])
        assert numpy.isclose(val[1], p[1])
        assert numpy.isclose(val[2], numpy.sin(p[0] + p[1]))
コード例 #17
0
def test_l2projection(polynomial_order, in_expression):
    # Test l2 projection for scalar and vector valued expression
    interpolate_expression = Expression(in_expression, degree=3)

    xmin, xmax = 0.0, 1.0
    ymin, ymax = 0.0, 1.0

    property_idx = 5

    mesh = RectangleMesh(Point(xmin, ymin), Point(xmax, ymax), 40, 40)

    if len(interpolate_expression.ufl_shape) == 0:
        V = FunctionSpace(mesh, "DG", polynomial_order)
    elif len(interpolate_expression.ufl_shape) == 1:
        V = VectorFunctionSpace(mesh, "DG", polynomial_order)

    v_exact = Function(V)
    v_exact.interpolate(interpolate_expression)

    x = RandomRectangle(Point(xmin, ymin), Point(xmax, ymax)).generate([500, 500])
    s = assign_particle_values(x, interpolate_expression)

    # Just make a complicated particle, possibly with scalars and vectors mixed
    p = particles(x, [x, s, x, x, s], mesh)

    vh = Function(V)
    lstsq_rho = l2projection(p, V, property_idx)
    lstsq_rho.project(vh)

    error_sq = abs(assemble(dot(v_exact - vh, v_exact - vh) * dx))
    assert error_sq < 1e-15
コード例 #18
0
def test_p4_parallel_3d():
    mesh = UnitCubeMesh(MPI.comm_world, 3, 5, 8)
    Q = FunctionSpace(mesh, ("CG", 5))
    F = Function(Q)

    @function.expression.numba_eval
    def x0(values, x, cell_idx):
        values[:, 0] = x[:, 0]

    F.interpolate(Expression(x0))

    # Generate random points in this mesh partition (one per cell)
    x = numpy.zeros(4)
    tree = cpp.geometry.BoundingBoxTree(mesh, mesh.geometry.dim)
    for c in Cells(mesh):
        x[0] = random()
        x[1] = random() * (1 - x[0])
        x[2] = random() * (1 - x[0] - x[1])
        x[3] = 1 - x[0] - x[1] - x[2]
        p = Point(0.0, 0.0, 0.0)
        for i, v in enumerate(VertexRange(c)):
            p += v.point() * x[i]
        p = p.array()

        assert numpy.isclose(F(p, tree)[0], p[0])
コード例 #19
0
    def initial_guess(self):
        r"""
        Obtains an initial guess for the Newton solver.

        This is done by solving the equation of motion for :math:`\lambda=0`, which form a linear system.
        All other parameters are unchanged.

        """

        # cast params as constant functions so that, if they are set to 0,
        # fenics still understand what it is integrating
        m, M, Mp = Constant(self.fields.m), Constant(self.fields.M), Constant(
            self.fields.Mp)
        alpha = Constant(self.fields.alpha)
        Mn, Mf1, Mf2 = Constant(self.Mn), Constant(self.Mf1), Constant(
            self.Mf2)

        # get the boundary conditions
        Dirichlet_bc = self.get_Dirichlet_bc()

        # create a vector (phi,h) with the two trial functions for the fields
        u = d.TrialFunction(self.V)
        # ... and split it into phi and h
        phi, h, y, z = d.split(u)

        # define test functions over the function space
        v1, v2, v3, v4 = d.TestFunctions(self.V)

        # r^2
        r2 = Expression('pow(x[0],2)', degree=self.fem.func_degree)

        # define bilinear form
        # Eq.1
        a1 = y * v1 * r2 * dx - ( m / Mn )**2 * phi * v1 * r2 * dx \
             - alpha * ( Mf2/Mf1 ) * z * v1 * r2 * dx

        # Eq.2
        a2 = z * v2 * r2 * dx - ( M / Mn )**2 * h * v2 * r2 * dx \
             - alpha * ( Mf1/Mf2 ) * y * v2 * r2 * dx

        a3 = -inner(grad(phi), grad(v3)) * r2 * dx - y * v3 * r2 * dx

        a4 = -inner(grad(h), grad(v4)) * r2 * dx - z * v4 * r2 * dx

        # both equations
        a = a1 + a2 + a3 + a4

        # define linear form
        L = self.source.rho / Mp * Mn / Mf1 * v1 * r2 * dx

        # define a vector with the solution
        sol = d.Function(self.V)

        # solve linearised system
        pde = d.LinearVariationalProblem(a, L, sol, Dirichlet_bc)
        solver = d.LinearVariationalSolver(pde)
        solver.solve()

        return sol
コード例 #20
0
ファイル: test_function.py プロジェクト: minrk/dolfinx
def test_cffi_expression(V):

    code_h = """
    void eval(double* values, const double* x, const int64_t* cell_idx,
            int num_points, int value_size, int gdim, int num_cells);
    """

    code_c = """
    void eval(double* values, const double* x, const int64_t* cell_idx,
            int num_points, int value_size, int gdim, int num_cells)
    {
        for (int i = 0; i < num_points; ++i)
        {
            values[i*value_size + 0] = x[i*gdim + 0] + x[i*gdim + 1];
        }
    }
    """
    module = "_expr_eval" + str(MPI.comm_world.rank)

    # Build the kernel
    ffi = cffi.FFI()
    ffi.set_source(module, code_c)
    ffi.cdef(code_h)
    ffi.compile()

    # Import the compiled kernel
    kernel_mod = importlib.import_module(module)
    ffi, lib = kernel_mod.ffi, kernel_mod.lib

    # Get pointer to the compiled function
    eval_ptr = ffi.cast("uintptr_t", ffi.addressof(lib, "eval"))

    # Handle C func address by hand
    ex1 = Expression(int(eval_ptr))
    f1 = Function(V)
    f1.interpolate(ex1)

    @function.expression.numba_eval
    def expr_eval2(values, x, cell_idx):
        values[:, 0] = x[:, 0] + x[:, 1]

    ex2 = Expression(expr_eval2)
    f2 = Function(V)
    f2.interpolate(ex2)

    assert (f1.vector().get_local() == f2.vector().get_local()).all()
コード例 #21
0
def main(N: int, dt: float, T: float,
         theta: float) -> Tuple[float, float, float, float, float]:
    """Run bidomain MMA."""
    # Create data
    mesh = UnitSquareMesh(N, N)
    time = Constant(0.0)
    ac_str = "cos(t)*cos(2*pi*x[0])*cos(2*pi*x[1]) + 4*pi*pi*cos(2*pi*x[0])*cos(2*pi*x[1])*sin(t)"
    stimulus = Expression(ac_str, t=time, degree=5)
    M_i = 1.
    M_e = 1.0

    # Set-up solver
    parameters = BidomainSolver.default_parameters()
    parameters["theta"] = theta
    parameters["linear_solver_type"] = "direct"
    parameters["use_avg_u_constraint"] = True
    parameters["Chi"] = 1.0
    parameters["Cm"] = 1.0
    solver = BidomainSolver(mesh,
                            time,
                            M_i,
                            M_e,
                            I_s=stimulus,
                            parameters=parameters)

    # Define exact solution (Note: v is returned at end of time
    # interval(s), u is computed at somewhere in the time interval
    # depending on theta)
    v_exact = Expression("cos(2*pi*x[0])*cos(2*pi*x[1])*sin(t)", t=T, degree=3)
    u_exact = Expression("-cos(2*pi*x[0])*cos(2*pi*x[1])*sin(t)/2.0",
                         t=T - (1. - theta) * dt,
                         degree=3)

    # Define initial condition(s)
    v_, vu = solver.solution_fields()

    # Solve
    solutions = solver.solve(0, T, dt)
    for interval, fields in solutions:
        continue

    # Compute errors
    v, u = vu.split(deepcopy=True)[:2]
    v_error = errornorm(v_exact, v, "L2", degree_rise=2)
    u_error = errornorm(u_exact, u, "L2", degree_rise=2)
    return v_error, u_error, mesh.hmin(), dt, T
コード例 #22
0
def test_mpi_dependent_jiting():
    # FIXME: Not a proper unit test...
    from dolfin import (Expression, UnitSquareMesh, Function, TestFunction,
                        Form, FunctionSpace, dx, CompiledSubDomain,
                        SubSystemsManager)

    # Init petsc (needed to initalize petsc collectively on
    # all processes)
    SubSystemsManager.init_petsc()

    import mpi4py.MPI as mpi
    import petsc4py.PETSc as petsc

    # Set communicator and get process information
    comm = mpi.COMM_WORLD
    group = comm.Get_group()
    size = comm.Get_size()

    # Only consider parallel runs
    if size == 1:
        return

    rank = comm.Get_rank()
    group_comm_0 = petsc.Comm(comm.Create(group.Incl(range(1))))
    group_comm_1 = petsc.Comm(comm.Create(group.Incl(range(1, 2))))

    if size > 2:
        group_comm_2 = petsc.Comm(comm.Create(group.Incl(range(2, size))))

    if rank == 0:
        e = Expression("4", mpi_comm=group_comm_0, degree=0)

    elif rank == 1:
        e = Expression("5", mpi_comm=group_comm_1, degree=0)
        assert (e)
        domain = CompiledSubDomain("on_boundary",
                                   mpi_comm=group_comm_1,
                                   degree=0)
        assert (domain)

    else:
        mesh = UnitSquareMesh(group_comm_2, 2, 2)
        V = FunctionSpace(mesh, "P", 1)
        u = Function(V)
        v = TestFunction(V)
        Form(u * v * dx)
コード例 #23
0
def test_WeightedGradient(V2):
    expr = "+".join(["%d*x[%d]" % (i+1,i) for i in range(2)])
    u = interpolate(Expression(expr, degree=3), V2)
    du = Function(V2)
    wx = weighted_gradient_matrix(V2.mesh(), tuple(range(2)))
    for i in range(2):
        du.vector()[:] = wx[i] * u.vector()
        assert round(du.vector().min() - (i+1), 7) == 0
コード例 #24
0
    def build_source(self):

        self.rho = Expression(
            'Ms / pow( sqrt(2*pi) * sigma, D ) * exp( -0.5 * pow(x[0]/sigma,2) )',
            Ms=self.Ms,
            D=self.physics.D,
            sigma=self.sigma,
            degree=self.fem.func_degree)
コード例 #25
0
ファイル: test_function.py プロジェクト: knut0815/dolfinx
def test_interpolation_mismatch_rank0(W):
    @function.expression.numba_eval
    def expr_eval(values, x, t):
        values[:, 0] = 1.0

    f = Expression(expr_eval, shape=())
    with pytest.raises(RuntimeError):
        interpolate(f, W)
コード例 #26
0
 def generate_shape_expression(self):
     return Expression(
         ParabolicInflow._shape_expression_schema,
         degree=2,
         A=self.left,
         B=self.right,
         amplitude=1.0,
     )
コード例 #27
0
ファイル: hat_function.py プロジェクト: blechta/dolfin-tape
def hat_function(vertex):
    """Return Expression on Lagrange degree 1 element which is
      1 ... at given 'vertex'
      0 ... at other vertices
    """
    assert isinstance(vertex, Vertex)
    mesh = vertex.mesh()
    element = FiniteElement('Lagrange', mesh.ufl_cell(), 1)
    ufc_element, ufc_dofmap = jit(element, mpi_comm=mesh.mpi_comm())
    ufc_element = make_ufc_finite_element(ufc_element)
    dolfin_element = cpp.FiniteElement(ufc_element)

    e = Expression(hat_cpp_code, element=element, domain=mesh)
    e.vertex = vertex
    e.dolfin_element = dolfin_element

    return e
コード例 #28
0
def _compute_time_errors(problem, method, mesh_sizes, Dt, plot_error=False):
    mesh_generator, solution, ProblemClass, _ = problem()
    # Translate data into FEniCS expressions.
    fenics_sol = Expression(sympy.printing.ccode(solution),
                            degree=MAX_DEGREE,
                            t=0.0)
    # Compute the problem
    errors = numpy.empty((len(mesh_sizes), len(Dt)))
    # Create initial state.
    # Deepcopy the expression into theta0. Specify the cell to allow for
    # more involved operations with it (e.g., grad()).
    theta0 = Expression(fenics_sol.cppcode, degree=MAX_DEGREE, t=0.0)
    for k, mesh_size in enumerate(mesh_sizes):
        mesh = mesh_generator(mesh_size)

        # Choose the function space such that the exact solution can be
        # represented as well as possible.
        V = FunctionSpace(mesh, 'CG', 4)

        theta_approx = Function(V)
        theta0p = project(theta0, V)

        stepper = method(ProblemClass(V))
        if plot_error:
            error = Function(V)
        for j, dt in enumerate(Dt):
            # TODO We are facing a little bit of a problem here, being the fact
            # that the time stepper only accept elements from V as u0.  In
            # principle, though, this isn't necessary or required. We could
            # allow for arbitrary expressions here, but then the API would need
            # changing for problem.lhs(t, u).  Think about this.
            theta_approx.assign(stepper.step(theta0p, 0.0, dt))
            fenics_sol.t = dt

            # NOTE
            # When using errornorm(), it is quite likely to see a good part of
            # the error being due to the spatial discretization.  Some analyses
            # "get rid" of this effect by (sometimes implicitly) projecting the
            # exact solution onto the discrete function space.

            errors[k][j] = errornorm(fenics_sol, theta_approx)
            if plot_error:
                error.assign(project(fenics_sol - theta_approx, V))
                plot(error, title='error (dt={:e})'.format(dt))
                plt.show()
    return errors
コード例 #29
0
ファイル: IR.py プロジェクト: scaramouche-00/phienics
    def weak_residual_form(self, sol):
        r"""
        Computes the residual with respect to the weak form of the equations:

        .. math:: F = F_1 + F_2 + F_3
        
        with
        
        .. math:: F_1(\hat{\pi},\hat{W},\hat{Y}) & = - \int\hat{\nabla}\hat{\pi}\hat{\nabla}v_1 \hat{r}^2 d\hat{r}
                  - \int \hat{Y} v_1 \hat{r}^2 d\hat{r} \\

                  F_2(\hat{\pi},\hat{W},\hat{Y}) & = \int \hat{W} v_2 \hat{r}^2 d\hat{r} 
                  - \int \hat{Y}^n v_2 \hat{r}^2 d\hat{r} \\

                  F_3(\hat{\pi},\hat{W},\hat{Y}) & = \int \hat{Y} v_3 \hat{r}^2 d\hat{r} 
                  - \int \left( \frac{m}{M_n} \right)^2 \hat{\pi} v_3 \hat{r}^2 d\hat{r} + 

                  & + \epsilon \left( \frac{M_n}{\Lambda} \right)^{3n-1}
                  \left(\frac{M_{f1}}{M_n}\right)^{n-1} \int\hat{\nabla} \hat{W} \hat{\nabla} v_3 \hat{r}^2 d\hat{r} 
                  - \int \frac{\hat{\rho}}{M_p}\frac{M_n}{M_{f1}} v_3 \hat{r}^2 d\hat{r}

        The weak residual is employed within :func:`solver.Solver.solve` to check convergence -
        also see :func:`solver.Solver.compute_errors`.

        *Parameters*
            sol
                the solution with respect to which the weak residual is computed.


        """

        # cast params as constant functions so that, if they are set to 0, FEniCS still understand
        # what is being integrated
        m, Lambda, Mp = Constant(self.fields.m), Constant(
            self.fields.Lambda), Constant(self.fields.Mp)
        n = self.fields.n
        epsilon = Constant(self.fields.epsilon)
        Mn, Mf1 = Constant(self.Mn), Constant(self.Mf1)

        # test functions
        v1, v2, v3 = d.TestFunctions(self.V)

        # split solution into pi, w, y
        pi, w, y = d.split(sol)

        # r^2
        r2 = Expression('pow(x[0],2)', degree=self.fem.func_degree)

        # define the weak residual form
        F1 = -inner(grad(pi), grad(v1)) * r2 * dx - y * v1 * r2 * dx
        F2 = w * v2 * r2 * dx - y**n * v2 * r2 * dx
        F3 = y * v3 * r2 * dx - (m/Mn)**2 * pi * v3 * r2 * dx + \
             epsilon * ( Mn / Lambda )**(3*n-1) * ( Mf1 / Mn )**(n-1) * inner( grad(w), grad(v3) ) * r2 * dx \
             - self.source.rho / Mp * Mn / Mf1 * v3 * r2 * dx

        F = F1 + F2 + F3

        return F
コード例 #30
0
ファイル: test_utils.py プロジェクト: MiroK/multiphenics
def get_rhs_block_form_1(block_V):
    block_v = BlockTestFunction(block_V)
    (v, ) = block_split(block_v)
    shape_1 = block_V[0].ufl_element().value_shape()
    if len(shape_1) is 0:
        f = Expression("2*x[0] + 4*x[1]*x[1]", degree=2)
        block_form = [f*v*dx]
    elif len(shape_1) is 1 and shape_1[0] is 2:
        f = Expression(("2*x[0] + 4*x[1]*x[1]", "3*x[0] + 5*x[1]*x[1]"), degree=2)
        block_form = [inner(f, v)*dx]
    elif len(shape_1) is 1 and shape_1[0] is 3:
        f = Expression(("2*x[0] + 4*x[1]*x[1]", "3*x[0] + 5*x[1]*x[1]", "7*x[0] + 11*x[1]*x[1]"), degree=2)
        block_form = [inner(f, v)*dx]
    elif len(shape_1) is 2:
        f = Expression((("2*x[0] + 4*x[1]*x[1]", "3*x[0] + 5*x[1]*x[1]"),
                        ("7*x[0] + 11*x[1]*x[1]", "13*x[0] + 17*x[1]*x[1]")), degree=2)
        block_form = [inner(f, v)*dx]
    return block_form
コード例 #31
0
def test_Probe_vectorfunctionspace_2D(VF2_self):
    u0 = interpolate(Expression(('x[0]', 'x[1]'), degree=1), VF2_self)
    x = array([0.5, 0.75])

    p = Probe(x, VF2_self)
    p(u0)
    p(u0)
    assert round(p[0][0] - 0.5, 7) == 0
    assert round(p[1][1] - 0.75, 7) == 0
コード例 #32
0
        def _potential_gradient_normal(self, conductivity=0.0):
            # (1 / r)' = -1 / dst^2
            # -1 * dz / dst
            # dz / dst^3 = dz * (dst^2)^-1.5
            # drx / r * dx / dst = (drx * dx) / (r * dst)
            # = (x * src_x - x * x) / (r * dst)

            # dx = '(x[0] - src_x)'
            # dy = '(x[1] - src_y)'
            # dz = '(x[2] - src_z)'
            # drx = 'x[0]'
            # dry = 'x[1]'
            # drz = 'x[2]'
            # dot = f'({dx} * {drx} + {dy} * {dry} + {dz} * {drz})'
            # r2 = f'({drx} * {drx} + {dry} * {dry} + {drz} * {drz})'
            # dst2 = f'({dx} * {dx} + {dy} * {dy} + {dz} * {dz})'
            # return Expression(f'''
            #                   {0.25 / np.pi} / conductivity
            #                   * ({dot} / sqrt({dst2} * {r2}) - 1.0)
            #                   / {dst2}
            #                   ''',
            #                   degree=self.degree,
            #                   domain=self._fm.mesh,
            #                   src_x=0.0,
            #                   src_y=0.0,
            #                   src_z=0.0,
            #                   conductivity=conductivity)

            dx_src = f'(x[0] - src_x)'
            dy_src = f'(x[1] - src_y)'
            dz_src = f'(x[2] - src_z)'

            dx_snk = f'(x[0] - snk_x)'
            dy_snk = f'(x[1] - snk_y)'
            dz_snk = f'(x[2] - snk_z)'

            r_src2 = f'({dx_src} * {dx_src} + {dy_src} * {dy_src} + {dz_src} * {dz_src})'
            r_src = f'sqrt({r_src2})'
            r_snk2 = f'({dx_snk} * {dx_snk} + {dy_snk} * {dy_snk} + {dz_snk} * {dz_snk})'
            r_snk = f'sqrt({r_snk2})'
            r_sphere2 = '(x[0] * x[0] + x[1] * x[1] + x[2] * x[2])'
            r_sphere = f'sqrt({r_sphere2})'
            dot_src = f'({dx_src} * x[0] + {dy_src} * x[1] + {dz_src} * x[2]) / ({r_src} * {r_sphere})'
            dot_snk = f'({dx_snk} * x[0] + {dy_snk} * x[1] + {dz_snk} * x[2]) / ({r_snk} * {r_sphere})'
            return Expression(f'''
                              {-0.25 / np.pi} / conductivity
                              * ({dot_src} / {r_src2} - {dot_snk} / {r_snk2})
                              ''',
                              degree=self.degree,
                              domain=self._fm.mesh,
                              conductivity=conductivity,
                              src_x=0.0,
                              src_y=0.0,
                              src_z=0.0,
                              snk_x=0.0,
                              snk_y=0.0,
                              snk_z=0.0)
コード例 #33
0
def test_Probe_functionspace_3D(V3_self):
    u0 = interpolate(Expression('x[0]', degree=1), V3_self)
    x = array([0.25, 0.5, 0.5])

    p = Probe(x, V3_self)
    p(u0)
    p(u0)
    assert round(p[0][0] - 0.25, 7) == 0
    assert round(p[1][0] - 0.25, 7) == 0
コード例 #34
0
def MHD2D(NScase,Mcase,Show="no"):

    PrintFuncs.PrintStr("MHD 2D Exact Solution:",5,">","\n","\n")

    x = symbols('x[0]')
    y = symbols('x[1]')
    u, v, p, u0, p0, Laplacian, Advection, gradPres = Fluid2D(NScase,Show,"MHD")
    b,d,r,b0, r0, CurlCurl, gradR = Mag2D(Mcase,Show,"MHD")

    NS1 = -d*(diff(d,x)-diff(b,y))
    NS2 = b*(diff(d,x)-diff(b,y))

    M1 = diff(u*d-v*b,y)
    M2 = -diff(u*d-v*b,x)
    NS_Couple = Expression((ccode(NS1),ccode(NS2)))
    M_Couple = Expression((ccode(M1),ccode(M2)))

    return u0, p0,b0, r0, Laplacian, Advection, gradPres,CurlCurl, gradR, NS_Couple, M_Couple
コード例 #35
0
def test_GaussDivergence(mesh):
    dim = mesh.topology().dim()
    expr = ["%s*x[%s]" % (dim, i) for i in range(dim)]
    V = VectorFunctionSpace(mesh, 'CG', 1)
    u = interpolate(Expression(tuple(expr)), V)
    divu = gauss_divergence(u)
    DIVU = divu.vector().array()
    point_0 = all(abs(DIVU - dim * dim) < 1E-13)
    if MPI.rank(mpi_comm_world()) == 0:
        assert point_0
コード例 #36
0
ファイル: Geometries.py プロジェクト: afqueiruga/WovenYarns
def apply_helix(fib, restX, setX, NTURN, A1, A2, phase):
    fib.problem.fields['wx'].interpolate(
        Expression((
            "x[0]*sq", "A1*sin(x[0]*p + w)-x[1]", "A2*cos(x[0]*p + w)-x[2]",
            "-((A1*A2*pow(p,3))/sqrt(pow(p,4)*(pow(A1,2)*pow(A2,2)*pow(p,2) + pow(A2,2)*pow(1 + sq,2)*pow(cos(x[0]*p + w),2) + pow(A1,2)*pow(1 + sq,2)*pow(sin(x[0]*p + w),2))))",
            "-1 + (A2*pow(p,2)*(1 + sq)*cos(x[0]*p + w))/sqrt(pow(p,4)*(pow(A1,2)*pow(A2,2)*pow(p,2) + pow(A2,2)*pow(1 + sq,2)*pow(cos(x[0]*p + w),2) + pow(A1,2)*pow(1 + sq,2)*pow(sin(x[0]*p + w),2)))",
            "-((A1*pow(p,2)*(1 + sq)*sin(x[0]*p + w))/sqrt(pow(p,4)*(pow(A1,2)*pow(A2,2)*pow(p,2) + pow(A2,2)*pow(1 + sq,2)*pow(cos(x[0]*p + w),2) + pow(A1,2)*pow(1 + sq,2)*pow(sin(x[0]*p + w),2))))",
            "-((pow(A1,2) - pow(A2,2))*pow(p,3)*(1 + sq)*sin(2*(x[0]*p + w)))/(2.*sqrt(pow(1 + sq,2) + pow(A1,2)*pow(p,2)*pow(cos(x[0]*p + w),2) + pow(A2,2)*pow(p,2)*pow(sin(x[0]*p + w),2))*sqrt(pow(p,4)*(pow(A1,2)*pow(A2,2)*pow(p,2) + pow(A2,2)*pow(1 + sq,2)*pow(cos(x[0]*p + w),2) + pow(A1,2)*pow(1 + sq,2)*pow(sin(x[0]*p + w),2))))",
            "(A1*pow(p,2)*(pow(A2,2)*pow(p,2) + pow(1 + sq,2))*sin(x[0]*p + w))/(sqrt(pow(1 + sq,2) + pow(A1,2)*pow(p,2)*pow(cos(x[0]*p + w),2) + pow(A2,2)*pow(p,2)*pow(sin(x[0]*p + w),2))*sqrt(pow(p,4)*(pow(A1,2)*pow(A2,2)*pow(p,2) + pow(A2,2)*pow(1 + sq,2)*pow(cos(x[0]*p + w),2) + pow(A1,2)*pow(1 + sq,2)*pow(sin(x[0]*p + w),2))))",
            "(A2*pow(p,2)*(pow(A1,2)*pow(p,2) + pow(1 + sq,2))*cos(x[0]*p + w) - sqrt(pow(1 + sq,2) + pow(A1,2)*pow(p,2)*pow(cos(x[0]*p + w),2) + pow(A2,2)*pow(p,2)*pow(sin(x[0]*p + w),2))*sqrt(pow(p,4)*(pow(A2,2)*pow(1 + sq,2)*pow(cos(x[0]*p + w),2) + pow(A1,2)*(pow(A2,2)*pow(p,2) + pow(1 + sq,2)*pow(sin(x[0]*p + w),2)))))/(sqrt(pow(1 + sq,2) + pow(A1,2)*pow(p,2)*pow(cos(x[0]*p + w),2) + pow(A2,2)*pow(p,2)*pow(sin(x[0]*p + w),2))*sqrt(pow(p,4)*(pow(A2,2)*pow(1 + sq,2)*pow(cos(x[0]*p + w),2) + pow(A1,2)*(pow(A2,2)*pow(p,2) + pow(1 + sq,2)*pow(sin(x[0]*p + w),2)))))"
        ),
                   sq=-(restX - setX) / restX,
                   p=np.pi / restX * (NTURN) / 2.0,
                   A1=A1,
                   A2=A2,
                   w=phase * np.pi * 2.0))
    fib.problem.fields['wv'].interpolate(
        Expression(
            ("0.0", "0.0", "0.0", "0.0", " 0.0", "0.0", "0.0", "0.0", "0.0")))
コード例 #37
0
    def profile(mesh, degree):
        bot = mesh.coordinates().min(axis=0)[1]
        top = mesh.coordinates().max(axis=0)[1]
        print bot, top
        H = top - bot

        Um = 1.5

        return Expression(('-4*Um*(x[1]-bot)*(x[1]-top)/H/H',
                        '0'), bot=bot, top=top, H=H, Um=Um, degree=degree)
コード例 #38
0
ファイル: sample_problems2.py プロジェクト: SpuqTeam/spuq
 def generate_expression(func, freq, A, B, m, n, degree, element):
     func, min_val, max_val, max_grad = func
     if n is None:
         ex = Expression(func, freq=freq, A=A, B=B,
                             m=m, degree=degree, element=element)
     else:
         ex = Expression(func, freq=freqscale, A=A, B=B,
                             m=m, n=n, degree=degree, element=element)
     try:            
         for k, v in {"freq":freq, "A":A, "B":B, "m":m, "n":n, "pi":"np.pi"}.iteritems():
             v = str(v)
             min_val = min_val.replace(k, v)
             max_val = max_val.replace(k, v)
             max_grad = max_grad.replace(k, v)
         ex.min_val = eval(min_val)
         ex.max_val = eval(max_val)
         ex.max_grad = eval(max_grad)
     except:
         logger.info("no min/max info available for coefficients")
     return ex
コード例 #39
0
def CompositeExpression(domains, expressions):
  e = Expression('''
    class CompositeExpression : public Expression
    {
      public:
        std::shared_ptr<MeshFunction<std::size_t> > cell_data;
        std::map<std::size_t, std::shared_ptr<Expression> > expressions;

        CompositeExpression() : Expression(3) {}

        void add_expression(std::size_t domain, std::shared_ptr<Expression> expression) {
          expressions[domain] = expression;
        }

        void eval(Array<double>& values, const Array<double>& x, const ufc::cell& c) const {
          assert(cell_data);
          const Cell cell(*cell_data->mesh(), c.index);
          std::size_t domain = (*cell_data)[cell.index()];

          if (expressions.find(domain) == expressions.end()) {
            for (std::size_t i=0; i<values.size(); ++i) values[i] = 0.0;
          } 
          else {
            expressions.at(domain)->eval(values, x, c);
          }
        }
    };''')
  if isinstance(domains, Mesh):
    e.cell_data = MeshFunction('size_t', domains, 3, domains.domains())
  else:
    e.cell_data = domains

  for domain in expressions:
    e.add_expression(domain, expressions[domain])

  return e
コード例 #40
0
ファイル: helpers.py プロジェクト: garethcmurphy/maelstrom
def compute_time_errors(problem, MethodClass, mesh_sizes, Dt):

    mesh_generator, solution, f, mu, rho, cell_type = problem()
    # Translate data into FEniCS expressions.
    sol_u = Expression((smp.printing.ccode(solution['u']['value'][0]),
                        smp.printing.ccode(solution['u']['value'][1])
                        ),
                       degree=_truncate_degree(solution['u']['degree']),
                       t=0.0,
                       cell=cell_type
                       )
    sol_p = Expression(smp.printing.ccode(solution['p']['value']),
                       degree=_truncate_degree(solution['p']['degree']),
                       t=0.0,
                       cell=cell_type
                       )

    fenics_rhs0 = Expression((smp.printing.ccode(f['value'][0]),
                              smp.printing.ccode(f['value'][1])
                              ),
                             degree=_truncate_degree(f['degree']),
                             t=0.0,
                             mu=mu, rho=rho,
                             cell=cell_type
                             )
    # Deep-copy expression to be able to provide f0, f1 for the Dirichlet-
    # boundary conditions later on.
    fenics_rhs1 = Expression(fenics_rhs0.cppcode,
                             degree=_truncate_degree(f['degree']),
                             t=0.0,
                             mu=mu, rho=rho,
                             cell=cell_type
                             )
    # Create initial states.
    p0 = Expression(
        sol_p.cppcode,
        degree=_truncate_degree(solution['p']['degree']),
        t=0.0,
        cell=cell_type
        )

    # Compute the problem
    errors = {'u': numpy.empty((len(mesh_sizes), len(Dt))),
              'p': numpy.empty((len(mesh_sizes), len(Dt)))
              }
    for k, mesh_size in enumerate(mesh_sizes):
        info('')
        info('')
        with Message('Computing for mesh size %r...' % mesh_size):
            mesh = mesh_generator(mesh_size)
            mesh_area = assemble(1.0 * dx(mesh))
            W = VectorFunctionSpace(mesh, 'CG', 2)
            P = FunctionSpace(mesh, 'CG', 1)
            method = MethodClass(W, P,
                                 rho, mu,
                                 theta=1.0,
                                 #theta=0.5,
                                 stabilization=None
                                 #stabilization='SUPG'
                                 )
            u1 = Function(W)
            p1 = Function(P)
            err_p = Function(P)
            divu1 = Function(P)
            for j, dt in enumerate(Dt):
                # Prepare previous states for multistepping.
                u = [Expression(
                    sol_u.cppcode,
                    degree=_truncate_degree(solution['u']['degree']),
                    t=0.0,
                    cell=cell_type
                    ),
                    # Expression(
                    #sol_u.cppcode,
                    #degree=_truncate_degree(solution['u']['degree']),
                    #t=0.5*dt,
                    #cell=cell_type
                    #)
                    ]
                sol_u.t = dt
                u_bcs = [DirichletBC(W, sol_u, 'on_boundary')]
                sol_p.t = dt
                #p_bcs = [DirichletBC(P, sol_p, 'on_boundary')]
                p_bcs = []
                fenics_rhs0.t = 0.0
                fenics_rhs1.t = dt
                method.step(dt,
                            u1, p1,
                            u, p0,
                            u_bcs=u_bcs, p_bcs=p_bcs,
                            f0=fenics_rhs0, f1=fenics_rhs1,
                            verbose=False,
                            tol=1.0e-10
                            )
                sol_u.t = dt
                sol_p.t = dt
                errors['u'][k][j] = errornorm(sol_u, u1)
                # The pressure is only determined up to a constant which makes
                # it a bit harder to define what the error is. For our
                # purposes, choose an alpha_0\in\R such that
                #
                #    alpha0 = argmin ||e - alpha||^2
                #
                # with  e := sol_p - p.
                # This alpha0 is unique and explicitly given by
                #
                #     alpha0 = 1/(2|Omega|) \int (e + e*)
                #            = 1/|Omega| \int Re(e),
                #
                # i.e., the mean error in \Omega.
                alpha = assemble(sol_p * dx(mesh)) \
                    - assemble(p1 * dx(mesh))
                alpha /= mesh_area
                # We would like to perform
                #     p1 += alpha.
                # To avoid creating a temporary function every time, assume
                # that p1 lives in a function space where the coefficients
                # represent actual function values. This is true for CG
                # elements, for example. In that case, we can just add any
                # number to the vector of p1.
                p1.vector()[:] += alpha
                errors['p'][k][j] = errornorm(sol_p, p1)

                show_plots = False
                if show_plots:
                    plot(p1, title='p1', mesh=mesh)
                    plot(sol_p, title='sol_p', mesh=mesh)
                    err_p.vector()[:] = p1.vector()
                    sol_interp = interpolate(sol_p, P)
                    err_p.vector()[:] -= sol_interp.vector()
                    #plot(sol_p - p1, title='p1 - sol_p', mesh=mesh)
                    plot(err_p, title='p1 - sol_p', mesh=mesh)
                    #r = Expression('x[0]', degree=1, cell=triangle)
                    #divu1 = 1 / r * (r * u1[0]).dx(0) + u1[1].dx(1)
                    divu1.assign(project(u1[0].dx(0) + u1[1].dx(1), P))
                    plot(divu1, title='div(u1)')
                    interactive()
    return errors
コード例 #41
0
ファイル: stabilization.py プロジェクト: nschloe/maelstrom
def supg(mesh, convection, diffusion, element_degree):
    """For each cell, this function return the expression

    ..math::

        \\begin{align*}
        \\tau &= \\frac{h}{2\\|b\\|}
        \\left(\\frac{1}{\\tanh Pe} - \\frac{1}{Pe}\\right)\\\\
        & = \\frac{h^2}{4\\varepsilon} \\frac{1}{Pe}
        \\left(\\frac{1}{\\tanh Pe} - \\frac{1}{Pe}\\right)
        \\end{align*}

    with the element diameter in the direction of the convection vector
    :math:`b` and the Péclet number :math:`Pe = \\frac{\\|b\\|
    h}{2\\varepsilon}`; see (3) in :cite:`sold2`.
    Note that :math:`\\tau` does not have a singularity for :math:`\\|b\\|=0`
    since

    ..math::

        \\frac{1}{\\tanh Pe} - \\frac{1}{Pe} = \\frac{1}{3}Pe + O(Pe^3)

    for :math:`Pe\\approx 0`. This Taylor expansion (with a few more terms) is
    made use of in the code.
    """
    cppcode = """#include <dolfin/mesh/Vertex.h>

class SupgStab : public Expression {
public:
double epsilon;
int p;
std::shared_ptr<GenericFunction> convection;
std::shared_ptr<Mesh> mesh;

SupgStab(): Expression()
{}

void eval(
  Array<double>& tau,
  const Array<double>& x,
  const ufc::cell& c
  ) const
{
  Array<double> v(x.size());
  convection->eval(v, x, c);
  double conv_norm = 0.0;
  for (uint i = 0; i < v.size(); ++i)
    conv_norm += v[i]*v[i];
  conv_norm = sqrt(conv_norm);

  Cell cell(*mesh, c.index);

  //// The alternative for the lazy:
  //const double h = cell.diameter();

  // Compute the directed diameter of the cell, cf. :cite:`sold2`.
  //
  //    diam(cell, s) = 2*||s|| / sum_{nodes n_i} |s.\\grad\\psi|
  //
  // where \\psi is the P_1 basis function of n_i.
  //
  const double area = cell.volume();
  const unsigned int* vertices = cell.entities(0);
  assert(vertices);
  double sum = 0.0;
  for (int i=0; i<3; i++) {
    for (int j=i+1; j<3; j++) {
      // Get edge coords.
      const dolfin::Vertex v0(*mesh, vertices[i]);
      const dolfin::Vertex v1(*mesh, vertices[j]);
      const Point p0 = v0.point();
      const Point p1 = v1.point();
      const double e0 = p0[0] - p1[0];
      const double e1 = p0[1] - p1[1];

      // Note that
      //
      //     \\grad\\psi = ortho_edge / edgelength / height
      //               = ortho_edge / (2*area)
      //
      // so
      //
      //   (v.\\grad\\psi) = (v.ortho_edge) / (2*area).
      //
      // Move the constant factors out of the summation.
      //
      // It would be really nice if we could just do
      //    edge.dot((-v[1], v[0]))
      // but unfortunately, edges just dot with other edges.
      sum += fabs(e1*v[0] - e0*v[1]);
    }
  }
  const double h = 4 * conv_norm * area / sum;

  // Just a little sanity check here.
  assert(h <= cell.diameter());

  const double Pe = 0.5*conv_norm * h/(p*epsilon);
  assert(Pe > 0.0);

  // We'd like to compute `xi = (1.0/tanh(Pe) - 1.0/Pe) / Pe`. This expression
  // can hardly be evaluated for small Pe, see
  // <https://stackoverflow.com/a/43279491/353337>. Hence, use its Taylor
  // expansion around 0.
  const double xi = Pe > 1.0e-5 ?
      (1.0/tanh(Pe) - 1.0/Pe) / Pe :
      1.0/3.0 - Pe*Pe / 45.0 + 2.0/945.0 * Pe*Pe*Pe*Pe;
  // const double xi =  (Pe > 1.0 ? 1.0 - 1.0/Pe : 0.0) / Pe;

  tau[0] = h*h / 4 / epsilon / p * xi;

  if (tau[0] > 1.0e3)
  {
    std::cout << "tau   = " << tau[0] << std::endl;
    std::cout << "||b|| = " << conv_norm << std::endl;
    std::cout << "Pe    = " << Pe << std::endl;
    std::cout << "h     = " << h << std::endl;
    std::cout << "xi    = " << xi << std::endl;
    throw 1;
  }

  return;
}
};
"""
    # TODO set degree
    tau = Expression(cppcode, degree=5)
    tau.convection = convection
    tau.mesh = mesh
    tau.epsilon = diffusion
    tau.p = element_degree
    return tau
コード例 #42
0
ファイル: test_pickling.py プロジェクト: SpuqTeam/spuq
from spuq.fem.fenics.fenics_vector import FEniCSVector
from spuq.application.egsz.multi_vector import MultiVector, MultiVectorWithProjection
from spuq.math_utils.multiindex import Multiindex
from spuq.math_utils.multiindex_set import MultiindexSet

from dolfin import UnitSquare, FunctionSpace, Function, refine, Expression, plot, interactive
from math import pi
import pickle

mis = [Multiindex(mis) for mis in MultiindexSet.createCompleteOrderSet(3, 1)]
N = len(mis)
meshes = [UnitSquare(10 + 2 * i, 10 + 2 * i) for i in range(N)]
functions = [Function(FunctionSpace(m, "CG", d + 1)) for d, m in enumerate(meshes)]
ex = Expression('sin(A*x[0])*sin(A*x[1])', A=1)
for i, f in enumerate(functions):
    ex.A = 2 * pi * (i + 1)
    f.interpolate(ex)

# test FEniCSVector
# =================
vectors = [FEniCSVector(f) for f in functions]
with open('test-vector.pkl', 'wb') as f:
    pickle.dump(vectors[1], f)

with open('test-vector.pkl', "rb") as f:
    v1 = pickle.load(f)


# test MultiVector
# ================
#mv1 = MultiVector()
コード例 #43
0
ファイル: helpers.py プロジェクト: nschloe/maelstrom
def compute_time_errors(problem, MethodClass, mesh_sizes, Dt):

    mesh_generator, solution, f, mu, rho, cell_type = problem()

    # Compute the problem
    errors = {
        "u": numpy.empty((len(mesh_sizes), len(Dt))),
        "p": numpy.empty((len(mesh_sizes), len(Dt))),
    }
    for k, mesh_size in enumerate(mesh_sizes):
        info("")
        info("")
        with Message("Computing for mesh size {}...".format(mesh_size)):
            mesh = mesh_generator(mesh_size)

            # Define all expression with `domain`, see
            # <https://bitbucket.org/fenics-project/ufl/issues/96>.
            #
            # Translate data into FEniCS expressions.
            sol_u = Expression(
                (ccode(solution["u"]["value"][0]), ccode(solution["u"]["value"][1])),
                degree=_truncate_degree(solution["u"]["degree"]),
                t=0.0,
                domain=mesh,
            )
            sol_p = Expression(
                ccode(solution["p"]["value"]),
                degree=_truncate_degree(solution["p"]["degree"]),
                t=0.0,
                domain=mesh,
            )

            fenics_rhs0 = Expression(
                (ccode(f["value"][0]), ccode(f["value"][1])),
                degree=_truncate_degree(f["degree"]),
                t=0.0,
                mu=mu,
                rho=rho,
                domain=mesh,
            )
            # Deep-copy expression to be able to provide f0, f1 for the
            # Dirichlet boundary conditions later on.
            fenics_rhs1 = Expression(
                fenics_rhs0.cppcode,
                degree=_truncate_degree(f["degree"]),
                t=0.0,
                mu=mu,
                rho=rho,
                domain=mesh,
            )
            # Create initial states.
            W = VectorFunctionSpace(mesh, "CG", 2)
            P = FunctionSpace(mesh, "CG", 1)
            p0 = Expression(
                sol_p.cppcode,
                degree=_truncate_degree(solution["p"]["degree"]),
                t=0.0,
                domain=mesh,
            )

            mesh_area = assemble(1.0 * dx(mesh))
            method = MethodClass(
                time_step_method="backward euler",
                # time_step_method='crank-nicolson',
                # stabilization=None
                # stabilization='SUPG'
            )
            u1 = Function(W)
            p1 = Function(P)
            err_p = Function(P)
            divu1 = Function(P)
            for j, dt in enumerate(Dt):
                # Prepare previous states for multistepping.
                u = {
                    0: Expression(
                        sol_u.cppcode,
                        degree=_truncate_degree(solution["u"]["degree"]),
                        t=0.0,
                        cell=cell_type,
                    )
                }
                sol_u.t = dt
                u_bcs = [DirichletBC(W, sol_u, "on_boundary")]
                sol_p.t = dt
                # p_bcs = [DirichletBC(P, sol_p, 'on_boundary')]
                p_bcs = []
                fenics_rhs0.t = 0.0
                fenics_rhs1.t = dt
                u1, p1 = method.step(
                    Constant(dt),
                    u,
                    p0,
                    W,
                    P,
                    u_bcs,
                    p_bcs,
                    Constant(rho),
                    Constant(mu),
                    f={0: fenics_rhs0, 1: fenics_rhs1},
                    verbose=False,
                    tol=1.0e-10,
                )

                sol_u.t = dt
                sol_p.t = dt
                errors["u"][k][j] = errornorm(sol_u, u1)
                # The pressure is only determined up to a constant which makes
                # it a bit harder to define what the error is. For our
                # purposes, choose an alpha_0\in\R such that
                #
                #    alpha0 = argmin ||e - alpha||^2
                #
                # with  e := sol_p - p.
                # This alpha0 is unique and explicitly given by
                #
                #     alpha0 = 1/(2|Omega|) \int (e + e*)
                #            = 1/|Omega| \int Re(e),
                #
                # i.e., the mean error in \Omega.
                alpha = +assemble(sol_p * dx(mesh)) - assemble(p1 * dx(mesh))
                alpha /= mesh_area
                # We would like to perform
                #     p1 += alpha.
                # To avoid creating a temporary function every time, assume
                # that p1 lives in a function space where the coefficients
                # represent actual function values. This is true for CG
                # elements, for example. In that case, we can just add any
                # number to the vector of p1.
                p1.vector()[:] += alpha
                errors["p"][k][j] = errornorm(sol_p, p1)

                show_plots = False
                if show_plots:
                    plot(p1, title="p1", mesh=mesh)
                    plot(sol_p, title="sol_p", mesh=mesh)
                    err_p.vector()[:] = p1.vector()
                    sol_interp = interpolate(sol_p, P)
                    err_p.vector()[:] -= sol_interp.vector()
                    # plot(sol_p - p1, title='p1 - sol_p', mesh=mesh)
                    plot(err_p, title="p1 - sol_p", mesh=mesh)
                    # r = SpatialCoordinate(mesh)[0]
                    # divu1 = 1 / r * (r * u1[0]).dx(0) + u1[1].dx(1)
                    divu1.assign(project(u1[0].dx(0) + u1[1].dx(1), P))
                    plot(divu1, title="div(u1)")
    return errors
コード例 #44
0
ファイル: test_fenics_operator.py プロジェクト: SpuqTeam/spuq
def teXXXst_fenics_vector():
#    quad_degree = 13
#    dolfin.parameters["form_compiler"]["quadrature_degree"] = quad_degree
    pi = 3.14159265358979323
    k1, k2 = 2, 3
    EV = pi * pi * (k1 * k1 + k2 * k2)
    N = 11
    degree = 1
    mesh = UnitSquare(N, N)
    fs = FunctionSpace(mesh, "CG", degree)
    ex = Expression("A*sin(k1*pi*x[0])*sin(k2*pi*x[1])", k1=k1, k2=k2, A=1.0)

    x = FEniCSVector(interpolate(ex, fs))
#    print "x.coeff", x.coeffs.array()

    ex.A = EV
    b_ex = assemble_rhs(ex, fs)
    bexg = interpolate(ex, fs)

#    print b_ex.array()
#    print b_ex.array() / (2 * pi * pi * x.coeffs.array())

    Afe = assemble_lhs(Expression('1'), fs)

    # apply discrete operator on (interpolated) x
    A = FEniCSOperator(Afe, x.basis)
    b = A * x

    # evaluate solution for eigenfunction rhs
    if False:
        b_num = Function(fs)
        solve(A, b_num.vector(), b_ex)
        bnv = A * b_num.vector()
        b3 = Function(fs, bnv / EV)

    np.set_printoptions(threshold='nan', suppress=True)
    print b.coeffs.array()
    print np.abs((b_ex.array() - b.coeffs.array()) / np.max(b_ex.array()))
    print np.max(np.abs((b_ex.array() - b.coeffs.array()) / np.max(b_ex.array())))
    #print b_ex.array() / (M * interpolate(ex1, fs).vector()).array()

#    #assert_array_almost_equal(b.coeffs, b_ex.coeffs)


    b2 = Function(fs, b_ex.copy())
    bg = Function(fs, b_ex.copy())
    b2g = Function(fs, b_ex.copy())
    G = assemble_gramian(x.basis)
    dolfin.solve(G, bg.vector(), b.coeffs)
    dolfin.solve(G, b2g.vector(), b2.vector())


#    # compute eigenpairs numerically
#    eigensolver = evaluate_evp(FEniCSBasis(fs))
#    # Extract largest (first) eigenpair
#    r, c, rx, cx = eigensolver.get_eigenpair(0)    
#    print "Largest eigenvalue: ", r    
#    # Initialize function and assign eigenvector
#    ef0 = Function(fs)
#    ef0.vector()[:] = rx

    if False:
        # export
        out_b = dolfin.File(__name__ + "_b.pvd", "compressed")
        out_b << b._fefunc
        out_b_ex = dolfin.File(__name__ + "_b_ex.pvd", "compressed")
        out_b_ex << b2
        out_b_num = dolfin.File(__name__ + "_b_num.pvd", "compressed")
        out_b_num << b_num


    #dolfin.plot(x._fefunc, title="interpolant x", rescale=False, axes=True, legend=True)
    dolfin.plot(bg, title="b", rescale=False, axes=True, legend=True)
    dolfin.plot(b2g, title="b_ex (ass/G)", rescale=False, axes=True, legend=True)
    dolfin.plot(bexg, title="b_ex (dir)", rescale=False, axes=True, legend=True)
    #dolfin.plot(b_num, title="b_num", rescale=False, axes=True, legend=True)
#    dolfin.plot(b3, title="M*b_num", rescale=False, axes=True, legend=True)
    #dolfin.plot(ef0, title="ef0", rescale=False, axes=True, legend=True)
    print dolfin.errornorm(u=b._fefunc, uh=b2) #, norm_type, degree, mesh)
    dolfin.interactive()