Esempio n. 1
0
def set_poisson_eq_2d(n=8):
    '''
    Basic example where only the mesh refinement is controlled.
    '''

    # mesh
    mesh = UnitSquareMesh(n, n)

    # function space
    V = FunctionSpace(mesh, 'P', 1)

    # bcs
    u_D = Expression('1 + x[0]*x[0] + 2*x[1]*x[1]', degree=2)

    def boundary(x, on_boundary):
        return on_boundary

    bc = DirichletBC(V, u_D, boundary)

    # variational problem
    u = TrialFunction(V)
    v = TestFunction(V)
    f = Constant(-6.0)
    a = dot(grad(u), grad(v)) * dx
    L = f * v * dx

    # define unknown
    u = Function(V)

    return a, L, u, bc
Esempio n. 2
0
def test_linear_pde():
    """Test Newton solver for a linear PDE"""
    # Create mesh and function space
    mesh = dolfin.generation.UnitSquareMesh(dolfin.MPI.comm_world, 12, 12)
    V = dolfin.function.FunctionSpace(mesh, ("Lagrange", 1))
    u = dolfin.function.Function(V)
    v = function.TestFunction(V)
    F = inner(10.0, v) * dx - inner(grad(u), grad(v)) * dx

    def boundary(x):
        """Define Dirichlet boundary (x = 0 or x = 1)."""
        return np.logical_or(x[:, 0] < 1.0e-8, x[:, 0] > 1.0 - 1.0e-8)

    u_bc = function.Function(V)
    u_bc.vector().set(1.0)
    u_bc.vector().update_ghosts()
    bc = fem.DirichletBC(V, u_bc, boundary)

    # Create nonlinear problem
    problem = NonlinearPDEProblem(F, u, bc)

    # Create Newton solver and solve
    solver = dolfin.cpp.nls.NewtonSolver(dolfin.MPI.comm_world)
    n, converged = solver.solve(problem, u.vector())
    assert converged
    assert n == 1
Esempio n. 3
0
    def update_time(self, actual_time, step_number):
        super(Problem, self).update_time(actual_time, step_number)
        if self.actual_time > 0.5 and int(round(self.actual_time * 1000)) % 1000 == 0:
            self.isWholeSecond = True
            seconds = int(round(self.actual_time))
            self.second_list.append(seconds)
            self.N1 = seconds*self.stepsInSecond
            self.N0 = (seconds-1)*self.stepsInSecond
        else:
            self.isWholeSecond = False

        # Update boundary condition
        self.tc.start('updateBC')
        if not self.ic == 'correct':
            self.v_in.t = self.actual_time
        self.tc.end('updateBC')

        self.tc.start('analyticVnorms')
        self.analytic_v_norm_L2 = norm(self.solution, norm_type='L2')
        self.analytic_v_norm_H1 = norm(self.solution, norm_type='H1')
        self.analytic_v_norm_H1w = sqrt(assemble((inner(grad(self.solution), grad(self.solution)) +
                                                  inner(self.solution, self.solution)) * self.dsWall))
        self.listDict['av_norm_L2']['list'].append(self.analytic_v_norm_L2)
        self.listDict['av_norm_H1']['list'].append(self.analytic_v_norm_H1)
        self.listDict['av_norm_H1w']['list'].append(self.analytic_v_norm_H1w)
        self.tc.end('analyticVnorms')
    def update_time(self, actual_time, step_number):
        super(Problem, self).update_time(actual_time, step_number)
        if self.actual_time > 0.5 and int(round(self.actual_time * 1000)) % 1000 == 0:
            self.isWholeSecond = True
            seconds = int(round(self.actual_time))
            self.second_list.append(seconds)
            self.N1 = seconds*self.stepsInSecond
            self.N0 = (seconds-1)*self.stepsInSecond
        else:
            self.isWholeSecond = False

        self.solution = self.assemble_solution(self.actual_time)

        # Update boundary condition
        self.tc.start('updateBC')
        self.v_in.assign(self.solution)
        self.tc.end('updateBC')

        # construct analytic pressure (used for computing pressure and force errors)
        self.tc.start('analyticP')
        analytic_pressure = womersleyBC.analytic_pressure(self.factor, self.actual_time)
        self.sol_p = interpolate(analytic_pressure, self.pSpace)
        self.tc.end('analyticP')

        self.tc.start('analyticVnorms')
        self.analytic_v_norm_L2 = norm(self.solution, norm_type='L2')
        self.analytic_v_norm_H1 = norm(self.solution, norm_type='H1')
        self.analytic_v_norm_H1w = sqrt(assemble((inner(grad(self.solution), grad(self.solution)) +
                                                  inner(self.solution, self.solution)) * self.dsWall))
        self.listDict['av_norm_L2']['list'].append(self.analytic_v_norm_L2)
        self.listDict['av_norm_H1']['list'].append(self.analytic_v_norm_H1)
        self.listDict['av_norm_H1w']['list'].append(self.analytic_v_norm_H1w)
        self.tc.end('analyticVnorms')
Esempio n. 5
0
def get_inner_products(W, for_):
    # Test and trial functions
    block_v = BlockTestFunction(W)
    v, q = block_split(block_v)
    block_u = BlockTrialFunction(W)
    u, p = block_split(block_u)

    # Inner products
    assert for_ in ("POD", "L2 projection")
    if for_ == "POD":
        # x = {
        #     "u": [[inner(grad(u), grad(v)) * dx]]
        # }
        x = {
            "u": [[inner(grad(u), grad(v)) * dx, 0], [0, 0]],
            "p": [[0, 0], [0, inner(p, q) * dx]]
        }
    elif for_ == "L2 projection":
        # x = {
        #     "u": [[inner(u, v) * dx]]
        # }
        x = {
            "u": [[inner(u, v) * dx, 0], [0, 0]],
            "p": [[0, 0], [0, inner(p, q) * dx]]
        }
    return {c: block_assemble(x[c]) for c in components}
Esempio n. 6
0
 def nonlinearity(function):
     if self.use_ema:
        return 2*inner(dot(sym(grad(function)), u_ext), v1) * dx + inner(div(function)*u_ext, v1) * dx
         # return 2*inner(dot(sym(grad(function)), u_ext), v) * dx + inner(div(u_ext)*function, v) * dx
         # QQ implement this way?
     else:
         return inner(dot(grad(function), u_ext), v1) * dx
Esempio n. 7
0
def test_physically_mapped_facet():
    mesh = Mesh(VectorElement("P", triangle, 1))

    # set up variational problem
    U = FiniteElement("Morley", mesh.ufl_cell(), 2)
    V = FiniteElement("P", mesh.ufl_cell(), 1)
    R = FiniteElement("P", mesh.ufl_cell(), 1)
    Vv = VectorElement(BrokenElement(V))
    Qhat = VectorElement(BrokenElement(V[facet]))
    Vhat = VectorElement(V[facet])
    Z = FunctionSpace(mesh, MixedElement(U, Vv, Qhat, Vhat, R))

    z = Coefficient(Z)
    u, d, qhat, dhat, lam = split(z)

    s = FacetNormal(mesh)
    trans = as_matrix([[1, 0], [0, 1]])
    mat = trans*grad(grad(u))*trans + outer(d, d) * u
    J = (u**2*dx +
         u**3*dx +
         u**4*dx +
         inner(mat, mat)*dx +
         inner(grad(d), grad(d))*dx +
         dot(s, d)**2*ds)
    L_match = inner(qhat, dhat - d)
    L = J + inner(lam, inner(d, d)-1)*dx + (L_match('+') + L_match('-'))*dS + L_match*ds
    compile_form(L)
Esempio n. 8
0
def test_assemble_manifold():
    """Test assembly of poisson problem on a mesh with topological dimension 1
    but embedded in 2D (gdim=2).
    """
    points = numpy.array([[0.0, 0.0], [0.2, 0.0], [0.4, 0.0], [0.6, 0.0],
                          [0.8, 0.0], [1.0, 0.0]],
                         dtype=numpy.float64)
    cells = numpy.array([[0, 1], [1, 2], [2, 3], [3, 4], [4, 5]],
                        dtype=numpy.int32)
    cell = ufl.Cell("interval", geometric_dimension=points.shape[1])
    domain = ufl.Mesh(ufl.VectorElement("Lagrange", cell, 1))
    mesh = create_mesh(MPI.COMM_WORLD, cells, points, domain)
    assert mesh.geometry.dim == 2
    assert mesh.topology.dim == 1

    U = dolfinx.FunctionSpace(mesh, ("P", 1))

    u, v = ufl.TrialFunction(U), ufl.TestFunction(U)
    w = dolfinx.Function(U)

    a = ufl.inner(ufl.grad(u), ufl.grad(v)) * ufl.dx(mesh)
    L = ufl.inner(1.0, v) * ufl.dx(mesh)

    bcdofs = dolfinx.fem.locate_dofs_geometrical(
        U, lambda x: numpy.isclose(x[0], 0.0))
    bcs = [dolfinx.DirichletBC(w, bcdofs)]
    A = dolfinx.fem.assemble_matrix(a, bcs)
    A.assemble()

    b = dolfinx.fem.assemble_vector(L)
    dolfinx.fem.apply_lifting(b, [a], [bcs])
    dolfinx.fem.set_bc(b, bcs)

    assert numpy.isclose(b.norm(), 0.41231)
    assert numpy.isclose(A.norm(), 25.0199)
Esempio n. 9
0
 def compute_err(self, is_tent, velocity, t):
     super(Problem, self).compute_err(is_tent, velocity, t)
     er_list_H1w = self.listDict['u2H1w' if is_tent else 'u_H1w']['list']
     errorH1wall = sqrt(assemble((inner(grad(velocity - self.solution), grad(velocity - self.solution)) +
                                  inner(velocity - self.solution, velocity - self.solution)) * self.dsWall))
     er_list_H1w.append(errorH1wall)
     print('  Relative H1wall error:', errorH1wall / self.analytic_v_norm_H1w)
Esempio n. 10
0
File: run.py Progetto: miklos1/urumi
def hyperelasticity(domain, q, p, nf=0):
    # Based on https://github.com/firedrakeproject/firedrake-bench/blob/experiments/forms/firedrake_forms.py
    V = ufl.FunctionSpace(domain, ufl.VectorElement('P', domain.ufl_cell(), q))
    P = ufl.FunctionSpace(domain, ufl.VectorElement('P', domain.ufl_cell(), p))
    v = ufl.TestFunction(V)
    du = ufl.TrialFunction(V)  # Incremental displacement
    u = ufl.Coefficient(V)     # Displacement from previous iteration
    B = ufl.Coefficient(V)     # Body force per unit mass
    # Kinematics
    I = ufl.Identity(domain.ufl_cell().topological_dimension())
    F = I + ufl.grad(u)        # Deformation gradient
    C = F.T*F                  # Right Cauchy-Green tensor
    E = (C - I)/2              # Euler-Lagrange strain tensor
    E = ufl.variable(E)
    # Material constants
    mu = ufl.Constant(domain)  # Lame's constants
    lmbda = ufl.Constant(domain)
    # Strain energy function (material model)
    psi = lmbda/2*(ufl.tr(E)**2) + mu*ufl.tr(E*E)
    S = ufl.diff(psi, E)       # Second Piola-Kirchhoff stress tensor
    PK = F*S                   # First Piola-Kirchoff stress tensor
    # Variational problem
    it = ufl.inner(PK, ufl.grad(v)) - ufl.inner(B, v)
    f = [ufl.Coefficient(P) for _ in range(nf)]
    return ufl.derivative(reduce(ufl.inner,
                                 list(map(ufl.div, f)) + [it])*ufl.dx, u, du)
Esempio n. 11
0
def tn_reg(lmda, mu, dx, R_lmda=1, R_mu=1):
    grad_lamda = grad(lmda)
    grad_mu = grad(mu)
    reg = 0.5 * R_lmda * inner(grad_lamda, grad_lamda) * dx + \
        0.5 * R_mu * inner(grad_mu, grad_mu) * dx
    Reg = assemble(reg)
    return Reg
Esempio n. 12
0
def test_linear_pde():
    """Test Newton solver for a linear PDE"""
    # Create mesh and function space
    mesh = dolfin.generation.UnitSquareMesh(dolfin.MPI.comm_world, 12, 12)
    V = functionspace.FunctionSpace(mesh, ("Lagrange", 1))
    u = function.Function(V)
    v = function.TestFunction(V)
    F = inner(10.0, v) * dx - inner(grad(u), grad(v)) * dx

    def boundary(x):
        """Define Dirichlet boundary (x = 0 or x = 1)."""
        return np.logical_or(x[:, 0] < 1.0e-8, x[:, 0] > 1.0 - 1.0e-8)

    u_bc = function.Function(V)
    u_bc.vector.set(1.0)
    u_bc.vector.ghostUpdate(addv=PETSc.InsertMode.INSERT, mode=PETSc.ScatterMode.FORWARD)
    bc = fem.DirichletBC(V, u_bc, boundary)

    # Create nonlinear problem
    problem = NonlinearPDEProblem(F, u, bc)

    # Create Newton solver and solve
    solver = dolfin.cpp.nls.NewtonSolver(dolfin.MPI.comm_world)
    n, converged = solver.solve(problem, u.vector)
    assert converged
    assert n == 1

    # Increment boundary condition and solve again
    u_bc.vector.set(2.0)
    u_bc.vector.ghostUpdate(addv=PETSc.InsertMode.INSERT, mode=PETSc.ScatterMode.FORWARD)
    n, converged = solver.solve(problem, u.vector)
    assert converged
    assert n == 1
Esempio n. 13
0
 def compute_err(self, is_tent, velocity, t):
     if self.doErrControl:
         er_list_L2 = self.listDict['u2L2' if is_tent else 'u_L2']['list']
         er_list_H1 = self.listDict['u2H1' if is_tent else 'u_H1']['list']
         self.tc.start('errorV')
         # assemble is faster than errornorm
         errorL2_sq = assemble(inner(velocity - self.solution, velocity - self.solution) * dx)
         errorH1seminorm_sq = assemble(inner(grad(velocity - self.solution), grad(velocity - self.solution)) * dx)
         info('  H1 seminorm error: %f' % sqrt(errorH1seminorm_sq))
         errorL2 = sqrt(errorL2_sq)
         errorH1 = sqrt(errorL2_sq + errorH1seminorm_sq)
         info("  Relative L2 error in velocity = %f" % (errorL2 / self.analytic_v_norm_L2))
         self.last_error = errorH1 / self.analytic_v_norm_H1
         self.last_status_functional = self.last_error
         info("  Relative H1 error in velocity = %f" % self.last_error)
         er_list_L2.append(errorL2)
         er_list_H1.append(errorH1)
         self.tc.end('errorV')
         if self.testErrControl:
             er_list_test_H1 = self.listDict['u2H1test' if is_tent else 'u_H1test']['list']
             er_list_test_L2 = self.listDict['u2L2test' if is_tent else 'u_L2test']['list']
             self.tc.start('errorVtest')
             er_list_test_L2.append(errornorm(velocity, self.solution, norm_type='L2', degree_rise=0))
             er_list_test_H1.append(errornorm(velocity, self.solution, norm_type='H1', degree_rise=0))
             self.tc.end('errorVtest')
         # stopping criteria for detecting diverging solution
         if self.last_error > self.divergence_treshold:
             raise RuntimeError('STOPPED: Failed divergence test!')
Esempio n. 14
0
def test_expression_assemble(V1, vV1, squaremesh_5):

    u1, u2 = dolfinx.fem.Function(V1), dolfinx.fem.Function(vV1)

    dx = ufl.dx(squaremesh_5)

    u1.vector.set(3.0)
    u2.vector.set(2.0)
    u1.vector.ghostUpdate()
    u2.vector.ghostUpdate()

    # check assembled shapes

    assert numpy.shape(dolfiny.expression.assemble(1.0, dx)) == ()
    assert numpy.shape(dolfiny.expression.assemble(ufl.grad(u1), dx)) == (2, )
    assert numpy.shape(dolfiny.expression.assemble(ufl.grad(u2), dx)) == (2, 2)

    # check assembled values

    assert numpy.isclose(dolfiny.expression.assemble(1.0, dx), 1.0)
    assert numpy.isclose(dolfiny.expression.assemble(u1, dx), 3.0)
    assert numpy.isclose(dolfiny.expression.assemble(u2, dx), 2.0).all()
    assert numpy.isclose(dolfiny.expression.assemble(u1 * u2, dx), 6.0).all()

    assert numpy.isclose(dolfiny.expression.assemble(ufl.grad(u1), dx),
                         0.0).all()
    assert numpy.isclose(dolfiny.expression.assemble(ufl.grad(u2), dx),
                         0.0).all()
Esempio n. 15
0
def test_helmholtz_form_2d(mode, expected_result, compile_args):
    cell = ufl.triangle
    element = ufl.FiniteElement("Lagrange", cell, 1)
    u, v = ufl.TrialFunction(element), ufl.TestFunction(element)
    if mode == "double":
        k = 1.0
    elif mode == "double complex":
        k = ufl.constantvalue.ComplexValue(1j)
    else:
        raise RuntimeError("Unknown mode type")

    a = (ufl.inner(ufl.grad(u), ufl.grad(v)) - ufl.inner(k * u, v)) * ufl.dx
    forms = [a]
    compiled_forms, module = ffcx.codegeneration.jit.compile_forms(
        forms, parameters={'scalar_type': mode}, cffi_extra_compile_args=compile_args)

    for f, compiled_f in zip(forms, compiled_forms):
        assert compiled_f.rank == len(f.arguments())

    form0 = compiled_forms[0][0].create_cell_integral(-1)

    c_type, np_type = float_to_type(mode)
    A = np.zeros((3, 3), dtype=np_type)
    w = np.array([], dtype=np_type)
    c = np.array([], dtype=np_type)

    ffi = cffi.FFI()
    coords = np.array([0.0, 0.0, 1.0, 0.0, 0.0, 1.0], dtype=np.float64)
    form0.tabulate_tensor(
        ffi.cast('{type} *'.format(type=c_type), A.ctypes.data),
        ffi.cast('{type} *'.format(type=c_type), w.ctypes.data),
        ffi.cast('{type} *'.format(type=c_type), c.ctypes.data),
        ffi.cast('double *', coords.ctypes.data), ffi.NULL, ffi.NULL, 0)

    assert np.allclose(A, expected_result)
Esempio n. 16
0
def test_laplace_bilinear_form_3d(mode, expected_result, compile_args):
    cell = ufl.tetrahedron
    element = ufl.FiniteElement("Lagrange", cell, 1)
    u, v = ufl.TrialFunction(element), ufl.TestFunction(element)
    a = ufl.inner(ufl.grad(u), ufl.grad(v)) * ufl.dx
    forms = [a]
    compiled_forms, module = ffcx.codegeneration.jit.compile_forms(
        forms, parameters={'scalar_type': mode}, cffi_extra_compile_args=compile_args)

    for f, compiled_f in zip(forms, compiled_forms):
        assert compiled_f.rank == len(f.arguments())

    form0 = compiled_forms[0][0].create_cell_integral(-1)

    c_type, np_type = float_to_type(mode)
    A = np.zeros((4, 4), dtype=np_type)
    w = np.array([], dtype=np_type)
    c = np.array([], dtype=np_type)

    ffi = cffi.FFI()
    coords = np.array([0.0, 0.0, 0.0,
                       1.0, 0.0, 0.0,
                       0.0, 1.0, 0.0,
                       0.0, 0.0, 1.0], dtype=np.float64)
    form0.tabulate_tensor(
        ffi.cast('{type} *'.format(type=c_type), A.ctypes.data),
        ffi.cast('{type} *'.format(type=c_type), w.ctypes.data),
        ffi.cast('{type} *'.format(type=c_type), c.ctypes.data),
        ffi.cast('double *', coords.ctypes.data), ffi.NULL, ffi.NULL, 0)

    assert np.allclose(A, expected_result)
Esempio n. 17
0
def test_cache_modes(compile_args):
    cell = ufl.triangle
    element = ufl.FiniteElement("Lagrange", cell, 1)
    u, v = ufl.TrialFunction(element), ufl.TestFunction(element)
    a = ufl.inner(ufl.grad(u), ufl.grad(v)) * ufl.dx
    forms = [a]

    # Load form from /tmp
    compiled_forms, module = ffcx.codegeneration.jit.compile_forms(
        forms, cffi_extra_compile_args=compile_args)
    tmpname = module.__name__
    tmpfile = module.__file__
    print(tmpname, tmpfile)
    del sys.modules[tmpname]

    # Load form from cache
    compiled_forms, module = ffcx.codegeneration.jit.compile_forms(
        forms,
        cache_dir="./compile-cache",
        cffi_extra_compile_args=compile_args)
    newname = module.__name__
    newfile = module.__file__
    print(newname, newfile)

    assert (newname == tmpname)
    assert (newfile != tmpfile)
Esempio n. 18
0
def laplace_coeff_action_forms(mesh, el, coeff_el):
    Q = dolfin.function.functionspace.FunctionSpace(mesh, el)

    u = dolfin.function.argument.TrialFunction(Q)
    v = dolfin.function.argument.TestFunction(Q)

    """
    def boundary(x):
        return np.sum(np.logical_or(x < DOLFIN_EPS, x > 1.0 - DOLFIN_EPS), axis=1) > 0
    """

    # u_bc = dolfin.function.constant.Constant(50.0)
    # bc = dolfin.fem.dirichletbc.DirichletBC(Q, u_bc, boundary)

    c = dolfin.function.expression.Expression("3.14*x[0]", element=coeff_el)
    f = dolfin.function.expression.Expression("0.4*x[1]*x[2]", element=el)

    a = inner(c * grad(u), grad(v)) * dx
    L = f * v * dx

    w = dolfin.Function(Q)
    w.vector().set(1.2)

    L = ufl.action(a, w)

    return None, L, None
Esempio n. 19
0
    def update_time(self, actual_time, step_number):
        super(Problem, self).update_time(actual_time, step_number)
        if self.actual_time > 0.5 and abs(math.modf(actual_time)[0]) < 0.5*self.metadata['dt']:
            self.second_list.append(int(round(self.actual_time)))

        self.solution = self.assemble_solution(self.actual_time)

        # Update boundary condition
        self.tc.start('updateBC')
        self.v_in.assign(self.onset_factor * self.solution)
        self.tc.end('updateBC')

        # construct analytic pressure (used for computing pressure and force errors)
        self.tc.start('analyticP')
        analytic_pressure = womersleyBC.analytic_pressure(self.factor, self.actual_time)
        self.sol_p = interpolate(analytic_pressure, self.pSpace)
        self.tc.end('analyticP')

        self.tc.start('analyticVnorms')
        self.analytic_v_norm_L2 = norm(self.solution, norm_type='L2')
        self.analytic_v_norm_H1 = norm(self.solution, norm_type='H1')
        self.analytic_v_norm_H1w = sqrt(assemble((inner(grad(self.solution), grad(self.solution)) +
                                                  inner(self.solution, self.solution)) * self.dsWall))
        self.listDict['av_norm_L2']['list'].append(self.analytic_v_norm_L2)
        self.listDict['av_norm_H1']['list'].append(self.analytic_v_norm_H1)
        self.listDict['av_norm_H1w']['list'].append(self.analytic_v_norm_H1w)
        self.tc.end('analyticVnorms')
Esempio n. 20
0
def tv_reg(lmda, mu, dx, R_lmda=1, R_mu=1, eps=1e-10):

    grad_lamda = grad(lmda)
    grad_mu = grad(mu)
    integrand_lmda = R_lmda * sqrt(inner(grad_lamda, grad_lamda) + eps) * dx
    integrand_mu = R_mu * sqrt(inner(grad_mu, grad_mu) + eps) * dx
    return assemble(integrand_lmda + integrand_mu)
Esempio n. 21
0
def fenics_solve(f):
    u = fa.Function(V, name="State")
    v = fn.TestFunction(V)
    F = (ufl.inner(ufl.grad(u), ufl.grad(v)) - f * v) * ufl.dx
    bcs = [fa.DirichletBC(V, 0.0, "on_boundary")]
    fa.solve(F == 0, u, bcs)
    return u
Esempio n. 22
0
  def __init__(self, coarse_mesh, nref, p_coarse, p_fine):
    super(LaplaceEigenvalueProblem, self).__init__(coarse_mesh, nref, p_coarse, p_fine)

    print0("Assembling fine-mesh problem")

    self.dirichlet_bdry = lambda x,on_boundary: on_boundary

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

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

    print0("Assembling coarse-mesh problem")

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

    # Assemble the stiffness matrix and the mass matrix, without Dirichlet BCs. Dirichlet DOFs will be removed later.
    assemble(a, tensor=self.A_coarse)
    assemble(m, tensor=self.B_coarse)
def solve_equation():
    mesh = UnitSquareMesh(32, 32)
    V = FunctionSpace(mesh, "Lagrange", 1)

    def boundary(x, on_boundary):
        return on_boundary

    u0 = Expression("cos(10 * x[0])", degree=2)
    bc = DirichletBC(V, u0, boundary)

    u = TrialFunction(V)
    v = TestFunction(V)
    f = Expression("(x[0] - 0.5)*(x[0] - 0.5)", degree=2)

    a = inner(grad(u), grad(v)) * dx
    L = f * v * dx

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

    # Plot solution at current time step
    fig = plt.figure()
    plot(u, fig=fig)
    plt.show()

    print("The norm of u is {}".format(u.vector().norm("l2")))
Esempio n. 24
0
    def initialize(self, V, Q, PS, D):
        super(Problem, self).initialize(V, Q, PS, D)

        print("IC type: " + self.ic)
        print("Velocity scale factor = %4.2f" % self.factor)
        reynolds = 728.761 * self.factor
        print("Computing with Re = %f" % reynolds)

        # set constants for
        self.area = assemble(interpolate(Expression("1.0"), Q) * self.dsIn)  # inflow area

        self.solution = interpolate(Expression(("0.0", "0.0", "factor*(1081.48-43.2592*(x[0]*x[0]+x[1]*x[1]))"),
                                               factor=self.factor), self.vSpace)
        analytic_pressure = womersleyBC.average_analytic_pressure_expr(self.factor)
        self.sol_p = interpolate(analytic_pressure, self.pSpace)
        self.analytic_gradient = womersleyBC.average_analytic_pressure_grad(self.factor)
        self.analytic_pressure_norm = norm(self.sol_p, norm_type='L2')
        self.analytic_v_norm_L2 = norm(self.solution, norm_type='L2')
        self.analytic_v_norm_H1 = norm(self.solution, norm_type='H1')
        self.analytic_v_norm_H1w = sqrt(assemble((inner(grad(self.solution), grad(self.solution)) +
                                                  inner(self.solution, self.solution)) * self.dsWall))
        print("Prepared analytic solution.")

        self.pg_normalization_factor.append(womersleyBC.average_analytic_pressure_grad(self.factor))
        self.p_normalization_factor.append(self.analytic_pressure_norm)
        self.vel_normalization_factor.append(norm(self.solution, norm_type='L2'))

        print('Normalisation factors (vel, p, pg):', self.vel_normalization_factor[0], self.p_normalization_factor[0],
              self.pg_normalization_factor[0])

        one = (interpolate(Expression('1.0'), Q))
        self.outflow_area = assemble(one*self.dsOut)
        print('Outflow area:', self.outflow_area)
Esempio n. 25
0
def run_scalar_test(mesh, V, degree):
    """ Manufactured Poisson problem, solving u = x[1]**p, where p is the
    degree of the Lagrange function space.

    """
    u, v = TrialFunction(V), TestFunction(V)
    a = inner(grad(u), grad(v)) * dx

    # Get quadrature degree for bilinear form integrand (ignores effect of non-affine map)
    a = inner(grad(u), grad(v)) * dx(metadata={"quadrature_degree": -1})
    a.integrals()[0].metadata(
    )["quadrature_degree"] = ufl.algorithms.estimate_total_polynomial_degree(a)
    a = form(a)

    # Source term
    x = SpatialCoordinate(mesh)
    u_exact = x[1]**degree
    f = -div(grad(u_exact))

    # Set quadrature degree for linear form integrand (ignores effect of non-affine map)
    L = inner(f, v) * dx(metadata={"quadrature_degree": -1})
    L.integrals()[0].metadata(
    )["quadrature_degree"] = ufl.algorithms.estimate_total_polynomial_degree(L)
    L = form(L)

    u_bc = Function(V)
    u_bc.interpolate(lambda x: x[1]**degree)

    # Create Dirichlet boundary condition
    facetdim = mesh.topology.dim - 1
    mesh.topology.create_connectivity(facetdim, mesh.topology.dim)
    bndry_facets = np.where(
        np.array(compute_boundary_facets(mesh.topology)) == 1)[0]
    bdofs = locate_dofs_topological(V, facetdim, bndry_facets)
    bc = dirichletbc(u_bc, bdofs)

    b = assemble_vector(L)
    apply_lifting(b, [a], bcs=[[bc]])
    b.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE)
    set_bc(b, [bc])

    a = form(a)
    A = assemble_matrix(a, bcs=[bc])
    A.assemble()

    # Create LU linear solver
    solver = PETSc.KSP().create(MPI.COMM_WORLD)
    solver.setType(PETSc.KSP.Type.PREONLY)
    solver.getPC().setType(PETSc.PC.Type.LU)
    solver.setOperators(A)

    uh = Function(V)
    solver.solve(b, uh.vector)
    uh.x.scatter_forward()

    M = (u_exact - uh)**2 * dx
    M = form(M)
    error = mesh.comm.allreduce(assemble_scalar(M), op=MPI.SUM)
    assert np.absolute(error) < 1.0e-14
Esempio n. 26
0
    def monolithic_solve():
        """Monolithic (interleaved) solver"""
        P2_el = ufl.VectorElement("Lagrange", mesh.ufl_cell(), 2)
        P1_el = ufl.FiniteElement("Lagrange", mesh.ufl_cell(), 1)
        TH = P2_el * P1_el
        W = FunctionSpace(mesh, TH)
        (u, p) = ufl.TrialFunctions(W)
        (v, q) = ufl.TestFunctions(W)
        a00 = ufl.inner(ufl.grad(u), ufl.grad(v)) * dx
        a01 = ufl.inner(p, ufl.div(v)) * dx
        a10 = ufl.inner(ufl.div(u), q) * dx
        a = a00 + a01 + a10

        p00 = ufl.inner(ufl.grad(u), ufl.grad(v)) * dx
        p11 = ufl.inner(p, q) * dx
        p_form = p00 + p11

        f = Function(W.sub(0).collapse()[0])
        p_zero = Function(W.sub(1).collapse()[0])
        L0 = inner(f, v) * dx
        L1 = inner(p_zero, q) * dx
        L = L0 + L1

        a, p_form, L = form(a), form(p_form), form(L)

        bdofsW0_P2_0 = locate_dofs_topological(W.sub(0), facetdim, bndry_facets0)
        bdofsW0_P2_1 = locate_dofs_topological(W.sub(0), facetdim, bndry_facets1)

        bc0 = dirichletbc(bc_value, bdofsW0_P2_0, W.sub(0))
        bc1 = dirichletbc(bc_value, bdofsW0_P2_1, W.sub(0))

        A = assemble_matrix(a, bcs=[bc0, bc1])
        A.assemble()
        P = assemble_matrix(p_form, bcs=[bc0, bc1])
        P.assemble()

        b = assemble_vector(L)
        apply_lifting(b, [a], bcs=[[bc0, bc1]])
        b.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE)
        set_bc(b, [bc0, bc1])

        ksp = PETSc.KSP()
        ksp.create(mesh.comm)
        ksp.setOperators(A, P)
        ksp.setType("minres")
        pc = ksp.getPC()
        pc.setType('lu')

        def monitor(ksp, its, rnorm):
            # print("Num it, rnorm:", its, rnorm)
            pass

        ksp.setTolerances(rtol=1.0e-8, max_it=50)
        ksp.setMonitor(monitor)
        ksp.setFromOptions()
        x = A.createVecRight()
        ksp.solve(b, x)
        assert ksp.getConvergedReason() > 0
        return b.norm(), x.norm(), A.norm(), P.norm()
def eval_cost_fem(w, rho):
    u, _ = fenics.split(w)
    J_form = (
        0.5 * ufl.inner(alpha(rho) * u, u) * ufl.dx
        + mu * ufl.inner(ufl.grad(u), ufl.grad(u)) * ufl.dx
    )
    J = fenics_adjoint.assemble(J_form)
    return J
 def rP(self, u, alpha, v, beta):
     w_1 = self.w(1)
     a = self.a
     sigma = self.sigma
     eps = self.eps
     return inner(sqrt(a(alpha))*sigma(v) + diff(a(alpha), alpha)/sqrt(a(alpha))*sigma(u)*beta,
                 sqrt(a(alpha))*eps(v) + diff(a(alpha), alpha)/sqrt(a(alpha))*eps(u)*beta) + \
                 2*w_1*self.ell ** 2 * dot(grad(beta), grad(beta))
Esempio n. 29
0
File: run.py Progetto: miklos1/urumi
def helmholtz(domain, q, p, nf=0):
    # Based on https://github.com/firedrakeproject/firedrake-bench/blob/experiments/forms/firedrake_forms.py
    V = ufl.FunctionSpace(domain, ufl.FiniteElement('P', domain.ufl_cell(), q))
    P = ufl.FunctionSpace(domain, ufl.FiniteElement('P', domain.ufl_cell(), p))
    u = ufl.TrialFunction(V)
    v = ufl.TestFunction(V)
    f = [ufl.Coefficient(P) for _ in range(nf)]
    it = ufl.dot(ufl.grad(v), ufl.grad(u)) + 1.0*v*u
    return reduce(ufl.inner, f + [it])*ufl.dx
Esempio n. 30
0
def solve_system(N):
    fenics_mesh = dolfinx.UnitCubeMesh(fenicsx_comm, N, N, N)
    fenics_space = dolfinx.FunctionSpace(fenics_mesh, ("CG", 1))
    u = ufl.TrialFunction(fenics_space)
    v = ufl.TestFunction(fenics_space)
    k = 2
    # print(u*v*ufl.ds)
    form = (ufl.inner(ufl.grad(u), ufl.grad(v)) -
            k**2 * ufl.inner(u, v)) * ufl.dx

    # locate facets on the cube boundary
    facets = locate_entities_boundary(
        fenics_mesh, 2, lambda x: np.logical_or(
            np.logical_or(
                np.logical_or(np.isclose(x[2], 0.0), np.isclose(x[2], 1.0)),
                np.logical_or(np.isclose(x[1], 0.0), np.isclose(x[1], 1.0))),
            np.logical_or(np.isclose(x[0], 0.0), np.isclose(x[0], 1.0))))

    facets.sort()

    # alternative - more general approach
    boundary = entities_to_geometry(
        fenics_mesh,
        fenics_mesh.topology.dim - 1,
        exterior_facet_indices(fenics_mesh),
        True,
    )
    # print(len(facets)
    assert len(facets) == len(exterior_facet_indices(fenics_mesh))

    u0 = fem.Function(fenics_space)

    with u0.vector.localForm() as u0_loc:
        u0_loc.set(0)
    # solution vector
    bc = DirichletBC(u0, locate_dofs_topological(fenics_space, 2, facets))

    A = 1 + 1j
    f = Function(fenics_space)
    f.interpolate(lambda x: A * k**2 * np.cos(k * x[0]) * np.cos(k * x[1]))

    L = ufl.inner(f, v) * ufl.dx
    u0.name = "u"
    problem = fem.LinearProblem(form,
                                L,
                                u=u0,
                                petsc_options={
                                    "ksp_type": "preonly",
                                    "pc_type": "lu"
                                })
    # problem = fem.LinearProblem(form, L, bcs=[bc], u=u0, petsc_options={"ksp_type": "preonly", "pc_type": "lu"})

    start_time = time.time()
    soln = problem.solve()
    if world_rank == 0:
        print("--- fenics solve done in %s seconds ---" %
              (time.time() - start_time))
Esempio n. 31
0
def velocity_expression(theta_k, theta_kp1, dt):
    theta_avg = avg(theta_k, theta_kp1, implicitness=.5)

    velocity_form_ = (
            (theta_kp1 - theta_k) / dt
            / ufl.sqrt(inner(grad(theta_avg), grad(theta_avg)) + DOLFIN_EPS)
        )

    return velocity_form_
Esempio n. 32
0
def test_mini():
    m = Mesh(VectorElement('CG', triangle, 1))
    P1 = FiniteElement('Lagrange', triangle, 1)
    B = FiniteElement("Bubble", triangle, 3)
    V = FunctionSpace(m, VectorElement(P1 + B))
    u = TrialFunction(V)
    v = TestFunction(V)
    a = inner(grad(u), grad(v)) * dx
    count_flops(a)
Esempio n. 33
0
def forms(arguments, coefficients):
    v, u = arguments
    c, f = coefficients
    n = FacetNormal(triangle)
    a = u * v * dx
    L = f * v * dx
    b = u * v * dx(0) + inner(c * grad(u), grad(v)) * \
        dx(1) + dot(n, grad(u)) * v * ds + f * v * dx
    return (a, L, b)
Esempio n. 34
0
 def sqrt_precision_varf_handler(trial, test):
     if Theta == None:
         varfL = ufl.inner(ufl.grad(trial), ufl.grad(test)) * ufl.dx
     else:
         varfL = ufl.inner(Theta * ufl.grad(trial), ufl.grad(test)) * ufl.dx
     varfM = ufl.inner(trial, test) * ufl.dx
     varfmo = mfun * ufl.inner(trial, test) * ufl.dx
     return dl.Constant(gamma) * varfL + dl.Constant(
         delta) * varfM + dl.Constant(pen) * varfmo
Esempio n. 35
0
def forms(arguments, coefficients):
    v, u = arguments
    c, f = coefficients
    n = FacetNormal(triangle)
    a = u * v * dx
    L = f * v * dx
    b = u * v * dx(0) + inner(c * grad(u), grad(v)) * \
        dx(1) + dot(n, grad(u)) * v * ds + f * v * dx
    return (a, L, b)
Esempio n. 36
0
def test_compute_form_adjoint(self):
    cell = triangle
    element = FiniteElement('Lagrange', cell, 1)

    u = TrialFunction(element)
    v = TestFunction(element)

    a = inner(grad(u), grad(v)) * dx

    assert compute_form_adjoint(a) == conj(inner(grad(v), grad(u))) * dx
 def compute_err(self, is_tent, velocity, t):
     super(Problem, self).compute_err(is_tent, velocity, t)
     er_list_H1w = self.listDict['u2H1w' if is_tent else 'u_H1w']['list']
     errorH1wall = sqrt(assemble((inner(grad(velocity - self.solution), grad(velocity - self.solution)) +
                                  inner(velocity - self.solution, velocity - self.solution)) * self.dsWall))
     er_list_H1w.append(errorH1wall)
     print('  Relative H1wall error:', errorH1wall / self.analytic_v_norm_H1w)
     if self.isWholeSecond:
         self.listDict['u2H1w' if is_tent else 'u_H1w']['slist'].append(
             sqrt(sum([i*i for i in er_list_H1w[self.N0:self.N1]])/self.stepsInSecond))
Esempio n. 38
0
def HodgeLaplaceGradCurl(element, felement):
    tau, v = TestFunctions(element)
    sigma, u = TrialFunctions(element)
    f = Coefficient(felement)

    a = (inner(tau, sigma) - inner(grad(tau), u) + inner(v, grad(sigma)) +
         inner(curl(v), curl(u))) * dx
    L = inner(v, f) * dx

    return a, L
Esempio n. 39
0
def a(u_k, u_kp1, v, control_k,
      vhc, kappa, cooling_bc, laser_bc, dt, implicitness, x, ds):
    u_avg = avg(u_k, u_kp1, implicitness)

    a_ = vhc(u_k) * (u_kp1 - u_k) * v * x[0] * dx\
       + dt * inner(kappa(u_k) * grad(u_avg), grad(v)) * x[0] * dx\
       - dt * laser_bc(control_k) * v * x[0] * ds(1)\
       - dt * cooling_bc(u_avg) * v * x[0] * (ds(1) + ds(2) + ds(4))

    return a_
Esempio n. 40
0
def test_conditional(mode, compile_args):
    cell = ufl.triangle
    element = ufl.FiniteElement("Lagrange", cell, 1)
    u, v = ufl.TrialFunction(element), ufl.TestFunction(element)
    x = ufl.SpatialCoordinate(cell)
    condition = ufl.Or(ufl.ge(ufl.real(x[0] + x[1]), 0.1),
                       ufl.ge(ufl.real(x[1] + x[1]**2), 0.1))
    c1 = ufl.conditional(condition, 2.0, 1.0)
    a = c1 * ufl.inner(ufl.grad(u), ufl.grad(v)) * ufl.dx

    x1x2 = ufl.real(x[0] + ufl.as_ufl(2) * x[1])
    c2 = ufl.conditional(ufl.ge(x1x2, 0), 6.0, 0.0)
    b = c2 * ufl.conj(v) * ufl.dx

    forms = [a, b]

    compiled_forms, module = ffcx.codegeneration.jit.compile_forms(
        forms,
        parameters={'scalar_type': mode},
        cffi_extra_compile_args=compile_args)

    form0 = compiled_forms[0][0].create_cell_integral(-1)
    form1 = compiled_forms[1][0].create_cell_integral(-1)

    ffi = cffi.FFI()
    c_type, np_type = float_to_type(mode)

    A1 = np.zeros((3, 3), dtype=np_type)
    w1 = np.array([1.0, 1.0, 1.0], dtype=np_type)
    c = np.array([], dtype=np.float64)

    coords = np.array([0.0, 0.0, 1.0, 0.0, 0.0, 1.0], dtype=np.float64)

    form0.tabulate_tensor(
        ffi.cast('{type} *'.format(type=c_type), A1.ctypes.data),
        ffi.cast('{type} *'.format(type=c_type), w1.ctypes.data),
        ffi.cast('{type} *'.format(type=c_type), c.ctypes.data),
        ffi.cast('double *', coords.ctypes.data), ffi.NULL, ffi.NULL, 0)

    expected_result = np.array([[2, -1, -1], [-1, 1, 0], [-1, 0, 1]],
                               dtype=np_type)
    assert np.allclose(A1, expected_result)

    A2 = np.zeros(3, dtype=np_type)
    w2 = np.array([1.0, 1.0, 1.0], dtype=np_type)
    coords = np.array([0.0, 0.0, 1.0, 0.0, 0.0, 1.0], dtype=np.float64)

    form1.tabulate_tensor(
        ffi.cast('{type} *'.format(type=c_type), A2.ctypes.data),
        ffi.cast('{type} *'.format(type=c_type), w2.ctypes.data),
        ffi.cast('{type} *'.format(type=c_type), c.ctypes.data),
        ffi.cast('double *', coords.ctypes.data), ffi.NULL, ffi.NULL, 0)

    expected_result = np.ones(3, dtype=np_type)
    assert np.allclose(A2, expected_result)
Esempio n. 41
0
 def save_vel(self, is_tent, field, t):
     self.vFunction.assign(field)
     self.fileDict['u2' if is_tent else 'u']['file'] << self.vFunction
     if self.doSaveDiff:
         self.vFunction.assign((1.0 / self.vel_normalization_factor[0]) * (field - self.solution))
         self.fileDict['u2D' if is_tent else 'uD']['file'] << self.vFunction
     if self.args.ldsg:
         # info(div(2.*sym(grad(field))-grad(field)).ufl_shape)
         form = div(2.*sym(grad(field))-grad(field))
         self.pFunction.assign(project(sqrt_ufl(inner(form, form)), self.pSpace))
         self.fileDict['ldsg2' if is_tent else 'ldsg']['file'] << self.pFunction
Esempio n. 42
0
 def diffusion(fce):
     if self.useLaplace:
         return nu * inner(grad(fce), grad(v1)) * dx
     else:
         form = inner(nu * 2 * sym(grad(fce)), sym(grad(v1))) * dx
         if self.bcv == 'CDN':
             return form
         if self.bcv == 'LAP':
             return form - inner(nu * dot(grad(fce).T, n), v1) * problem.get_outflow_measure_form()
         if self.bcv == 'DDN':
             return form  # additional term must be added to non-constant part
Esempio n. 43
0
def test_gradient_error(cell, degree):
    """Test that tabulating gradient evaluations of the trace
    element triggers `gem.Failure` to raise the TraceError
    exception.
    """
    trace_element = FiniteElement("HDiv Trace", cell, degree)
    lambdar = TrialFunction(trace_element)
    gammar = TestFunction(trace_element)

    with pytest.raises(TraceError):
        compile_form(inner(grad(lambdar('+')), grad(gammar('+'))) * dS)
Esempio n. 44
0
def norm(v, norm_type="L2", mesh=None):
    """Compute the norm of ``v``.

    :arg v: a :class:`.Function` to compute the norm of
    :arg norm_type: the type of norm to compute, see below for
         options.
    :arg mesh: an optional mesh on which to compute the norm
         (currently ignored).

    Available norm types are:

    * L2

       .. math::

          ||v||_{L^2}^2 = \int (v, v) \mathrm{d}x

    * H1

       .. math::

          ||v||_{H^1}^2 = \int (v, v) + (\\nabla v, \\nabla v) \mathrm{d}x

    * Hdiv

       .. math::

          ||v||_{H_\mathrm{div}}^2 = \int (v, v) + (\\nabla\cdot v, \\nabla \cdot v) \mathrm{d}x

    * Hcurl

       .. math::

          ||v||_{H_\mathrm{curl}}^2 = \int (v, v) + (\\nabla \wedge v, \\nabla \wedge v) \mathrm{d}x
    """
    assert isinstance(v, function.Function)

    typ = norm_type.lower()
    mesh = v.function_space().mesh()
    dx = mesh._dx
    if typ == 'l2':
        form = inner(v, v)*dx
    elif typ == 'h1':
        form = inner(v, v)*dx + inner(grad(v), grad(v))*dx
    elif typ == "hdiv":
        form = inner(v, v)*dx + div(v)*div(v)*dx
    elif typ == "hcurl":
        form = inner(v, v)*dx + inner(curl(v), curl(v))*dx
    else:
        raise RuntimeError("Unknown norm type '%s'" % norm_type)

    return sqrt(solving.assemble(form))
Esempio n. 45
0
 def diffusion(fce):
     if self.useLaplace:
         return nu*inner(grad(fce), grad(v1)) * dx
     else:
         form = inner(nu * 2 * sym(grad(fce)), sym(grad(v1))) * dx
         if self.bcv == 'CDN':
             # IMP will work only if p=0 on output, or we must add term
             # inner(p0*n, v)*problem.get_outflow_measure_form() to avoid boundary layer
             return form
         if self.bcv == 'LAP':
             return form - inner(nu*dot(grad(fce).T, n), v1)  * problem.get_outflow_measure_form()
         if self.bcv == 'DDN':
             # IMP will work only if p=0 on output, or we must add term
             # inner(p0*n, v)*problem.get_outflow_measure_form() to avoid boundary layer
             return form  # additional term must be added to non-constant part
Esempio n. 46
0
def norm(v, norm_type="L2", mesh=None):
    """Compute the norm of ``v``.

    :arg v: a ufl expression (:class:`~.ufl.classes.Expr`) to compute the norm of
    :arg norm_type: the type of norm to compute, see below for
         options.
    :arg mesh: an optional mesh on which to compute the norm
         (currently ignored).

    Available norm types are:

    * L2

       .. math::

          ||v||_{L^2}^2 = \int (v, v) \mathrm{d}x

    * H1

       .. math::

          ||v||_{H^1}^2 = \int (v, v) + (\\nabla v, \\nabla v) \mathrm{d}x

    * Hdiv

       .. math::

          ||v||_{H_\mathrm{div}}^2 = \int (v, v) + (\\nabla\cdot v, \\nabla \cdot v) \mathrm{d}x

    * Hcurl

       .. math::

          ||v||_{H_\mathrm{curl}}^2 = \int (v, v) + (\\nabla \wedge v, \\nabla \wedge v) \mathrm{d}x
    """
    typ = norm_type.lower()
    if typ == 'l2':
        form = inner(v, v)*dx
    elif typ == 'h1':
        form = inner(v, v)*dx + inner(grad(v), grad(v))*dx
    elif typ == "hdiv":
        form = inner(v, v)*dx + div(v)*div(v)*dx
    elif typ == "hcurl":
        form = inner(v, v)*dx + inner(curl(v), curl(v))*dx
    else:
        raise RuntimeError("Unknown norm type '%s'" % norm_type)

    return sqrt(assemble(form))
Esempio n. 47
0
    def compute_functionals(self, velocity, pressure, t):
        if self.args.wss:
            info('Computing stress tensor')
            I = Identity(velocity.geometric_dimension())
            T = TensorFunctionSpace(self.mesh, 'Lagrange', 1)
            stress = project(-pressure*I + 2*sym(grad(velocity)), T)
            info('Generating boundary mesh')
            wall_mesh = BoundaryMesh(self.mesh, 'exterior')
            # wall_mesh = SubMesh(self.mesh, self.facet_function, 1)   # QQ why does not work?
            # plot(wall_mesh, interactive=True)
            info('  Boundary mesh geometric dim: %d' % wall_mesh.geometry().dim())
            info('  Boundary mesh topologic dim: %d' % wall_mesh.topology().dim())
            info('Projecting stress to boundary mesh')
            Tb = TensorFunctionSpace(wall_mesh, 'Lagrange', 1)
            stress_b = interpolate(stress, Tb)
            self.fileDict['wss']['file'] << stress_b


            if False:  # does not work
                info('Computing WSS')
                n = FacetNormal(wall_mesh)
                info(stress_b, True)
                # wss = stress_b*n - inner(stress_b*n, n)*n
                wss = dot(stress_b, n) - inner(dot(stress_b, n), n)*n   # equivalent
                Vb = VectorFunctionSpace(wall_mesh, 'Lagrange', 1)
                Sb = FunctionSpace(wall_mesh, 'Lagrange', 1)
                # wss_func = project(wss, Vb)
                wss_norm = project(sqrt(inner(wss, wss)), Sb)
                plot(wss_norm, interactive=True)
Esempio n. 48
0
def test_latex_formatting_of_derivatives():
    xx = ufl.SpatialCoordinate(ufl.triangle)
    x = xx[0]
    # Test derivatives of basic operators
    assert expr2latex(x.dx(0)) == "1"
    assert expr2latex(x.dx(1)) == "0"
    assert expr2latex(ufl.grad(xx)[0, 0]) == "1"
    assert expr2latex(ufl.grad(xx)[0, 1]) == "0"
    assert expr2latex(ufl.sin(x).dx(0)) == r"\cos(x_0)"

    # Test derivatives of form arguments
    V = ufl.FiniteElement("CG", ufl.triangle, 1)
    f = ufl.Coefficient(V, count=0)
    assert expr2latex(f.dx(0)) == r"\overset{0}{w}_{, 0}"
    v = ufl.Argument(V, number=3)
    assert expr2latex(v.dx(1)) == r"\overset{3}{v}_{, 1}"
Esempio n. 49
0
def test_cpp_formatting_of_derivatives():
    xx = ufl.SpatialCoordinate(ufl.triangle)
    x, y = xx
    # Test derivatives of basic operators
    assert expr2cpp(x.dx(0)) == "1"
    assert expr2cpp(x.dx(1)) == "0"
    assert expr2cpp(ufl.grad(xx)[0, 0]) == "1"
    assert expr2cpp(ufl.grad(xx)[0, 1]) == "0"
    assert expr2cpp(ufl.sin(x).dx(0)) == "cos(x[0])"

    # Test derivatives of target specific test fakes
    V = ufl.FiniteElement("CG", ufl.triangle, 1)
    f = ufl.Coefficient(V, count=0)
    assert expr2cpp(f.dx(0)) == "d1_w0[0]"
    v = ufl.Argument(V, number=3)
    assert expr2cpp(v.dx(1)) == "d1_v3[1]"  # NOT renumbered to 0...
Esempio n. 50
0
    def compute_functionals(self, velocity, pressure, t, step):
        if self.args.wss == 'all' or \
                (step >= self.stepsInCycle and self.args.wss == 'peak' and
                 (self.distance_from_chosen_steps < 0.5 * self.metadata['dt'])):
            # TODO check if choosing time steps works properly
            # QQ might skip step? change 0.5 to 0.51?
            self.tc.start('WSS')
            begin('WSS (%dth step)' % step)
            if self.args.wss_method == 'expression':
                stress = project(self.nu*2*sym(grad(velocity)), self.T)
                # pressure is not used as it contributes only to the normal component
                stress.set_allow_extrapolation(True)   # need because of some inaccuracies in BoundaryMesh coordinates
                stress_b = interpolate(stress, self.Tb)    # restrict stress to boundary mesh
                # self.fileDict['stress']['file'].write(stress_b, self.actual_time)
                # info('Saved stress tensor')
                info('Computing WSS')
                wss = dot(stress_b, self.nb) - inner(dot(stress_b, self.nb), self.nb)*self.nb
                wss_func = project(wss, self.Vb)
                wss_norm = project(sqrt_ufl(inner(wss, wss)), self.Sb)
                info('Saving WSS')
                self.fileDict['wss']['file'].write(wss_func, self.actual_time)
                self.fileDict['wss_norm']['file'].write(wss_norm, self.actual_time)
            if self.args.wss_method == 'integral':
                wss_norm = Function(self.SDG)
                mS = TestFunction(self.SDG)
                scaling = 1/FacetArea(self.mesh)
                stress = self.nu*2*sym(grad(velocity))
                wss = dot(stress, self.normal) - inner(dot(stress, self.normal), self.normal)*self.normal
                wss_norm_form = scaling*mS*sqrt_ufl(inner(wss, wss))*ds   # ds is integral over exterior facets only
                assemble(wss_norm_form, tensor=wss_norm.vector())
                self.fileDict['wss_norm']['file'].write(wss_norm, self.actual_time)

                # to get vector WSS values:
                # NT this works, but in ParaView for (DG,1)-vector space glyphs are displayed in cell centers
                # wss_vector = []
                # for i in range(3):
                #     wss_component = Function(self.SDG)
                #     wss_vector_form = scaling*wss[i]*mS*ds
                #     assemble(wss_vector_form, tensor=wss_component.vector())
                #     wss_vector.append(wss_component)
                # wss_func = project(as_vector(wss_vector), self.VDG)
                # self.fileDict['wss']['file'].write(wss_func, self.actual_time)
            self.tc.end('WSS')
            end()
Esempio n. 51
0
def test_latex_formatting_of_variables():
    x, y = ufl.SpatialCoordinate(ufl.triangle)
    # Test user-provided C variables for subexpressions
    # we can use variables for x[0], and sum, and power
    assert expr2latex(x**2 + y**2, variables={x**2: 'x2', y**2: 'y2'}) == "x2 + y2"
    assert expr2latex(x**2 + y**2, variables={x: 'z', y**2: 'y2'}) == r"{z}^{2} + y2"
    assert expr2latex(x**2 + y**2, variables={x**2 + y**2: 'q'}) == "q"
    # we can use variables in conditionals
    if 0:
        assert expr2latex(ufl.conditional(ufl.Or(ufl.eq(x, 2), ufl.ne(y, 4)), 7, 8), variables={ufl.eq(x, 2): 'c1', ufl.ne(y, 4): 'c2'}) == "c1 || c2 ? 7: 8"
    # we can replace coefficients (formatted by user provided code)
    V = ufl.FiniteElement("CG", ufl.triangle, 1)
    f = ufl.Coefficient(V, count=0)
    assert expr2latex(f, variables={f: 'f'}) == "f"
    assert expr2latex(f**3, variables={f: 'f'}) == r"{f}^{3}"
    # variables do not replace derivatives of variable expressions
    assert expr2latex(f.dx(0), variables={f: 'f'}) == r"\overset{0}{w}_{, 0}"
    # variables do replace variable expressions that are themselves derivatives
    assert expr2latex(f.dx(0), variables={f.dx(0): 'df', ufl.grad(f)[0]: 'df'}) == "df"
    assert expr2latex(ufl.grad(f)[0], variables={f.dx(0): 'df', ufl.grad(f)[0]: 'df'}) == "df"
Esempio n. 52
0
def split_vector_laplace(cell, degree):
    m = Mesh(VectorElement('CG', cell, 1))
    if cell.cellname() in ['interval * interval', 'quadrilateral']:
        hcurl_element = FiniteElement('RTCE', cell, degree)
    elif cell.cellname() == 'triangle * interval':
        U0 = FiniteElement('RT', triangle, degree)
        U1 = FiniteElement('CG', triangle, degree)
        V0 = FiniteElement('CG', interval, degree)
        V1 = FiniteElement('DG', interval, degree - 1)
        Wa = HCurlElement(TensorProductElement(U0, V0))
        Wb = HCurlElement(TensorProductElement(U1, V1))
        hcurl_element = EnrichedElement(Wa, Wb)
    elif cell.cellname() == 'quadrilateral * interval':
        hcurl_element = FiniteElement('NCE', cell, degree)
    RT = FunctionSpace(m, hcurl_element)
    CG = FunctionSpace(m, FiniteElement('Q', cell, degree))
    sigma = TrialFunction(CG)
    u = TrialFunction(RT)
    tau = TestFunction(CG)
    v = TestFunction(RT)
    return [dot(u, grad(tau))*dx, dot(grad(sigma), v)*dx, dot(curl(u), curl(v))*dx]
Esempio n. 53
0
def test_expand_indices():
    element = FiniteElement("Lagrange", triangle, 2)
    v = TestFunction(element)
    u = TrialFunction(element)

    def evaluate(form):
        return form.cell_integral()[0].integrand()((), {v: 3, u: 5})  # TODO: How to define values of derivatives?

    a = div(grad(v)) * u * dx
    # a1 = evaluate(a)
    a = expand_derivatives(a)
    # a2 = evaluate(a)
    a = expand_indices(a)
Esempio n. 54
0
def norm(v, norm_type="L2", mesh=None):
    r"""Compute the norm of ``v``.

    :arg v: a ufl expression (:class:`~.ufl.classes.Expr`) to compute the norm of
    :arg norm_type: the type of norm to compute, see below for
         options.
    :arg mesh: an optional mesh on which to compute the norm
         (currently ignored).

    Available norm types are:

    - Lp :math:`||v||_{L^p} = (\int |v|^p)^{\frac{1}{p}} \mathrm{d}x`
    - H1 :math:`||v||_{H^1}^2 = \int (v, v) + (\nabla v, \nabla v) \mathrm{d}x`
    - Hdiv :math:`||v||_{H_\mathrm{div}}^2 = \int (v, v) + (\nabla\cdot v, \nabla \cdot v) \mathrm{d}x`
    - Hcurl :math:`||v||_{H_\mathrm{curl}}^2 = \int (v, v) + (\nabla \wedge v, \nabla \wedge v) \mathrm{d}x`

    """
    typ = norm_type.lower()
    p = 2
    if typ == 'l2':
        expr = inner(v, v)
    elif typ.startswith('l'):
        try:
            p = int(typ[1:])
            if p < 1:
                raise ValueError
        except ValueError:
            raise ValueError("Don't know how to interpret %s-norm" % norm_type)
        expr = inner(v, v)
    elif typ == 'h1':
        expr = inner(v, v) + inner(grad(v), grad(v))
    elif typ == "hdiv":
        expr = inner(v, v) + div(v)*div(v)
    elif typ == "hcurl":
        expr = inner(v, v) + inner(curl(v), curl(v))
    else:
        raise RuntimeError("Unknown norm type '%s'" % norm_type)

    return assemble((expr**(p/2))*dx)**(1/p)
Esempio n. 55
0
def test_cpp_formatting_with_variables():
    x, y = ufl.SpatialCoordinate(ufl.triangle)
    # Test user-provided C variables for subexpressions
    # we can use variables for x[0], and sum, and power
    assert expr2cpp(x**2 + y**2, variables={x**2: 'x2', y**2: 'y2'}) == "x2 + y2"
    assert expr2cpp(x**2 + y**2, variables={x: 'z', y**2: 'y2'}) == "pow(z, 2) + y2"
    assert expr2cpp(x**2 + y**2, variables={x**2 + y**2: 'q'}) == "q"
    # we can use variables in conditionals
    assert expr2cpp(ufl.conditional(ufl.Or(ufl.eq(x, 2), ufl.ne(y, 4)), 7, 8),
                    variables={ufl.eq(x, 2): 'c1', ufl.ne(y, 4): 'c2'}) == "c1 || c2 ? 7: 8"
    # we can replace coefficients (formatted by user provided code)
    V = ufl.FiniteElement("CG", ufl.triangle, 1)
    f = ufl.Coefficient(V, count=0)
    assert expr2cpp(f, variables={f: 'f'}) == "f"
    assert expr2cpp(f**3, variables={f: 'f'}) == "pow(f, 3)"
    # variables do not replace derivatives of variable expressions
    assert expr2cpp(f.dx(0), variables={f: 'f'}) == "d1_w0[0]"

    # This test depends on which differentiation algorithm is in use
    # in UFL, representing derivatives as SpatialDerivative or Grad:
    # variables do replace variable expressions that are themselves derivatives
    assert expr2cpp(f.dx(0), variables={f.dx(0): 'df', ufl.grad(f)[0]: 'df'}) == "df"
    assert expr2cpp(ufl.grad(f)[0], variables={f.dx(0): 'df', ufl.grad(f)[0]: 'df'}) == "df"
Esempio n. 56
0
    def solve(self, problem):
        self.problem = problem
        doSave = problem.doSave
        save_this_step = False
        onlyVel = problem.saveOnlyVel
        dt = self.metadata['dt']

        nu = Constant(self.problem.nu)
        # TODO check proper use of watches
        self.tc.init_watch('init', 'Initialization', True, count_to_percent=False)
        self.tc.init_watch('rhs', 'Assembled right hand side', True, count_to_percent=True)
        self.tc.init_watch('updateBC', 'Updated velocity BC', True, count_to_percent=True)
        self.tc.init_watch('applybc1', 'Applied velocity BC 1st step', True, count_to_percent=True)
        self.tc.init_watch('applybc3', 'Applied velocity BC 3rd step', True, count_to_percent=True)
        self.tc.init_watch('applybcP', 'Applied pressure BC or othogonalized rhs', True, count_to_percent=True)
        self.tc.init_watch('assembleMatrices', 'Initial matrix assembly', False, count_to_percent=True)
        self.tc.init_watch('solve 1', 'Running solver on 1st step', True, count_to_percent=True)
        self.tc.init_watch('solve 2', 'Running solver on 2nd step', True, count_to_percent=True)
        self.tc.init_watch('solve 3', 'Running solver on 3rd step', True, count_to_percent=True)
        self.tc.init_watch('solve 4', 'Running solver on 4th step', True, count_to_percent=True)
        self.tc.init_watch('assembleA1', 'Assembled A1 matrix (without stabiliz.)', True, count_to_percent=True)
        self.tc.init_watch('assembleA1stab', 'Assembled A1 stabilization', True, count_to_percent=True)
        self.tc.init_watch('next', 'Next step assignments', True, count_to_percent=True)
        self.tc.init_watch('saveVel', 'Saved velocity', True)

        self.tc.start('init')

        # Define function spaces (P2-P1)
        mesh = self.problem.mesh
        self.V = VectorFunctionSpace(mesh, "Lagrange", 2)  # velocity
        self.Q = FunctionSpace(mesh, "Lagrange", 1)  # pressure
        self.PS = FunctionSpace(mesh, "Lagrange", 2)  # partial solution (must be same order as V)
        self.D = FunctionSpace(mesh, "Lagrange", 1)   # velocity divergence space
        if self.bc == 'lagrange':
            L = FunctionSpace(mesh, "R", 0)
            QL = self.Q*L

        problem.initialize(self.V, self.Q, self.PS, self.D)

        # Define trial and test functions
        u = TrialFunction(self.V)
        v = TestFunction(self.V)
        if self.bc == 'lagrange':
            (pQL, rQL) = TrialFunction(QL)
            (qQL, lQL) = TestFunction(QL)
        else:
            p = TrialFunction(self.Q)
            q = TestFunction(self.Q)

        n = FacetNormal(mesh)
        I = Identity(u.geometric_dimension())

        # Initial conditions: u0 velocity at previous time step u1 velocity two time steps back p0 previous pressure
        [u1, u0, p0] = self.problem.get_initial_conditions([{'type': 'v', 'time': -dt},
                                                          {'type': 'v', 'time': 0.0},
                                                          {'type': 'p', 'time': 0.0}])

        if doSave:
            problem.save_vel(False, u0, 0.0)
            problem.save_vel(True, u0, 0.0)

        u_ = Function(self.V)         # current tentative velocity
        u_cor = Function(self.V)         # current corrected velocity
        if self.bc == 'lagrange':
            p_QL = Function(QL)    # current pressure or pressure help function from rotation scheme
            pQ = Function(self.Q)     # auxiliary function for conversion between QL.sub(0) and Q
        else:
            p_ = Function(self.Q)         # current pressure or pressure help function from rotation scheme
        p_mod = Function(self.Q)      # current modified pressure from rotation scheme

        # Define coefficients
        k = Constant(self.metadata['dt'])
        f = Constant((0, 0, 0))

        # Define forms
        # step 1: Tentative velocity, solve to u_
        u_ext = 1.5*u0 - 0.5*u1  # extrapolation for convection term

        # Stabilisation
        h = CellSize(mesh)
        # CBC delta:
        if self.cbcDelta:
            delta = Constant(self.stabCoef)*h/(sqrt(inner(u_ext, u_ext))+h)
        else:
            delta = Constant(self.stabCoef)*h**2/(2*nu*k + k*h*inner(u_ext, u_ext)+h**2)

        if self.use_full_SUPG:
            v1 = v + delta*0.5*k*dot(grad(v), u_ext)
            parameters['form_compiler']['quadrature_degree'] = 6
        else:
            v1 = v

        def nonlinearity(function):
            if self.use_ema:
               return 2*inner(dot(sym(grad(function)), u_ext), v1) * dx + inner(div(function)*u_ext, v1) * dx
                # return 2*inner(dot(sym(grad(function)), u_ext), v) * dx + inner(div(u_ext)*function, v) * dx
                # QQ implement this way?
            else:
                return inner(dot(grad(function), u_ext), v1) * dx

        def diffusion(fce):
            if self.useLaplace:
                return nu*inner(grad(fce), grad(v1)) * dx
            else:
                form = inner(nu * 2 * sym(grad(fce)), sym(grad(v1))) * dx
                if self.bcv == 'CDN':
                    # IMP will work only if p=0 on output, or we must add term
                    # inner(p0*n, v)*problem.get_outflow_measure_form() to avoid boundary layer
                    return form
                if self.bcv == 'LAP':
                    return form - inner(nu*dot(grad(fce).T, n), v1)  * problem.get_outflow_measure_form()
                if self.bcv == 'DDN':
                    # IMP will work only if p=0 on output, or we must add term
                    # inner(p0*n, v)*problem.get_outflow_measure_form() to avoid boundary layer
                    return form  # additional term must be added to non-constant part

        def pressure_rhs():
            if self.useLaplace or self.bcv == 'LAP':
                return inner(p0, div(v1)) * dx - inner(p0*n, v1) * problem.get_outflow_measure_form()
                # NT term inner(inner(p, n), v) is 0 when p=0 on outflow
            else:
                return inner(p0, div(v1)) * dx

        a1_const = (1./k)*inner(u, v1)*dx + diffusion(0.5*u)
        a1_change = nonlinearity(0.5*u)
        if self.bcv == 'DDN':
            # IMP Problem: Does not penalize influx for current step, only for the next one
            # IMP this can lead to oscilation: DDN correct next step, but then u_ext is OK so in next step DDN is not used, leading to new influx...
            # u and u_ext cannot be switched, min_value is nonlinear function
            a1_change += -0.5*min_value(Constant(0.), inner(u_ext, n))*inner(u, v1)*problem.get_outflow_measure_form()
            # IMP works only with uflacs compiler

        L1 = (1./k)*inner(u0, v1)*dx - nonlinearity(0.5*u0) - diffusion(0.5*u0) + pressure_rhs()
        if self.bcv == 'DDN':
            L1 += 0.5*min_value(0., inner(u_ext, n))*inner(u0, v1)*problem.get_outflow_measure_form()

        # Non-consistent SUPG stabilisation
        if self.stabilize and not self.use_full_SUPG:
            # a1_stab = delta*inner(dot(grad(u), u_ext), dot(grad(v), u_ext))*dx
            a1_stab = 0.5*delta*inner(dot(grad(u), u_ext), dot(grad(v), u_ext))*dx(None, {'quadrature_degree': 6})
            # NT optional: use Crank Nicolson in stabilisation term: change RHS
            # L1 += -0.5*delta*inner(dot(grad(u0), u_ext), dot(grad(v), u_ext))*dx(None, {'quadrature_degree': 6})

        outflow_area = Constant(problem.outflow_area)
        need_outflow = Constant(0.0)
        if self.useRotationScheme:
            # Rotation scheme
            if self.bc == 'lagrange':
                F2 = inner(grad(pQL), grad(qQL))*dx + (1./k)*qQL*div(u_)*dx + pQL*lQL*dx + qQL*rQL*dx
            else:
                F2 = inner(grad(p), grad(q))*dx + (1./k)*q*div(u_)*dx
        else:
            # Projection, solve to p_
            if self.bc == 'lagrange':
                F2 = inner(grad(pQL - p0), grad(qQL))*dx + (1./k)*qQL*div(u_)*dx + pQL*lQL*dx + qQL*rQL*dx
            else:
                if self.forceOutflow and problem.can_force_outflow:
                    info('Forcing outflow.')
                    F2 = inner(grad(p - p0), grad(q))*dx + (1./k)*q*div(u_)*dx
                    for m in problem.get_outflow_measures():
                        F2 += (1./k)*(1./outflow_area)*need_outflow*q*m
                else:
                    F2 = inner(grad(p - p0), grad(q))*dx + (1./k)*q*div(u_)*dx
        a2, L2 = system(F2)

        # step 3: Finalize, solve to u_
        if self.useRotationScheme:
            # Rotation scheme
            if self.bc == 'lagrange':
                F3 = (1./k)*inner(u - u_, v)*dx + inner(grad(p_QL.sub(0)), v)*dx
            else:
                F3 = (1./k)*inner(u - u_, v)*dx + inner(grad(p_), v)*dx
        else:
            if self.bc == 'lagrange':
                F3 = (1./k)*inner(u - u_, v)*dx + inner(grad(p_QL.sub(0) - p0), v)*dx
            else:
                F3 = (1./k)*inner(u - u_, v)*dx + inner(grad(p_ - p0), v)*dx
        a3, L3 = system(F3)

        if self.useRotationScheme:
            # Rotation scheme: modify pressure
            if self.bc == 'lagrange':
                pr = TrialFunction(self.Q)
                qr = TestFunction(self.Q)
                F4 = (pr - p0 - p_QL.sub(0) + nu*div(u_))*qr*dx
            else:
                F4 = (p - p0 - p_ + nu*div(u_))*q*dx
            # TODO zkusit, jestli to nebude rychlejsi? nepocitat soustavu, ale p.assign(...), nutno project(div(u),Q) coz je pocitani podobne soustavy
            # TODO zkusit v project zadat solver_type='lu' >> primy resic by mel byt efektivnejsi
            a4, L4 = system(F4)

        # Assemble matrices
        self.tc.start('assembleMatrices')
        A1_const = assemble(a1_const)  # need to be here, so A1 stays one Python object during repeated assembly
        A1_change = A1_const.copy()  # copy to get matrix with same sparse structure (data will be overwriten)
        if self.stabilize and not self.use_full_SUPG:
            A1_stab = A1_const.copy()  # copy to get matrix with same sparse structure (data will be overwriten)
        A2 = assemble(a2)
        A3 = assemble(a3)
        if self.useRotationScheme:
            A4 = assemble(a4)
        self.tc.end('assembleMatrices')

        if self.solvers == 'direct':
            self.solver_vel_tent = LUSolver('mumps')
            self.solver_vel_cor = LUSolver('mumps')
            self.solver_p = LUSolver('umfpack')
            if self.useRotationScheme:
                self.solver_rot = LUSolver('umfpack')
        else:
            # NT not needed, chosen not to use hypre_parasails
            # if self.prec_v == 'hypre_parasails':  # in FEniCS 1.6.0 inaccessible using KrylovSolver class
            #     self.solver_vel_tent = PETScKrylovSolver('gmres')   # PETSc4py object
            #     self.solver_vel_tent.ksp().getPC().setType('hypre')
            #     PETScOptions.set('pc_hypre_type', 'parasails')
            #     # this is global setting, but preconditioners for pressure solvers are set by their constructors
            # else:
            self.solver_vel_tent = KrylovSolver('gmres', self.prec_v)   # nonsymetric > gmres
            # IMP cannot use 'ilu' in parallel (choose different default option)
            self.solver_vel_cor = KrylovSolver('cg', 'hypre_amg')   # nonsymetric > gmres
            self.solver_p = KrylovSolver('cg', self.prec_p)          # symmetric > CG
            if self.useRotationScheme:
                self.solver_rot = KrylovSolver('cg', self.prec_p)

        solver_options = {'monitor_convergence': True, 'maximum_iterations': 1000, 'nonzero_initial_guess': True}
        # 'nonzero_initial_guess': True   with  solver.solbe(A, u, b) means that
        # Solver will use anything stored in u as an initial guess

        # Get the nullspace if there are no pressure boundary conditions
        foo = Function(self.Q)     # auxiliary vector for setting pressure nullspace
        if self.bc in ['nullspace', 'nullspace_s']:
            null_vec = Vector(foo.vector())
            self.Q.dofmap().set(null_vec, 1.0)
            null_vec *= 1.0/null_vec.norm('l2')
            self.null_space = VectorSpaceBasis([null_vec])
            if self.bc == 'nullspace':
                as_backend_type(A2).set_nullspace(self.null_space)

        # apply global options for Krylov solvers
        self.solver_vel_tent.parameters['relative_tolerance'] = 10 ** (-self.precision_rel_v_tent)
        self.solver_vel_tent.parameters['absolute_tolerance'] = 10 ** (-self.precision_abs_v_tent)
        self.solver_vel_cor.parameters['relative_tolerance'] = 10E-12
        self.solver_vel_cor.parameters['absolute_tolerance'] = 10E-4
        self.solver_p.parameters['relative_tolerance'] = 10**(-self.precision_p)
        self.solver_p.parameters['absolute_tolerance'] = 10E-10
        if self.useRotationScheme:
            self.solver_rot.parameters['relative_tolerance'] = 10**(-self.precision_p)
            self.solver_rot.parameters['absolute_tolerance'] = 10E-10

        if self.solvers == 'krylov':
            for solver in [self.solver_vel_tent, self.solver_vel_cor, self.solver_p, self.solver_rot] if \
                    self.useRotationScheme else [self.solver_vel_tent, self.solver_vel_cor, self.solver_p]:
                for key, value in solver_options.items():
                    try:
                        solver.parameters[key] = value
                    except KeyError:
                        info('Invalid option %s for KrylovSolver' % key)
                        return 1
                solver.parameters['preconditioner']['structure'] = 'same'
                # matrices A2-A4 do not change, so we can reuse preconditioners

        self.solver_vel_tent.parameters['preconditioner']['structure'] = 'same_nonzero_pattern'
        # matrix A1 changes every time step, so change of preconditioner must be allowed

        if self.bc == 'lagrange':
            fa = FunctionAssigner(self.Q, QL.sub(0))

        # boundary conditions
        bcu, bcp = problem.get_boundary_conditions(self.bc == 'outflow', self.V, self.Q)
        self.tc.end('init')
        # Time-stepping
        info("Running of Incremental pressure correction scheme n. 1")
        ttime = self.metadata['time']
        t = dt
        step = 1
        while t < (ttime + dt/2.0):
            info("t = %f" % t)
            self.problem.update_time(t, step)
            if self.MPI_rank == 0:
                problem.write_status_file(t)

            if doSave:
                save_this_step = problem.save_this_step

            # DDN debug
            # u_ext_in = assemble(inner(u_ext, n)*problem.get_outflow_measure_form())
            # DDN_triggered = assemble(min_value(Constant(0.), inner(u_ext, n))*problem.get_outflow_measure_form())
            # print('DDN: u_ext*n dSout = ', u_ext_in)
            # print('DDN: negative part of u_ext*n dSout = ', DDN_triggered)

            # assemble matrix (it depends on solution)
            self.tc.start('assembleA1')
            assemble(a1_change, tensor=A1_change)  # assembling into existing matrix is faster than assembling new one
            A1 = A1_const.copy()  # we dont want to change A1_const
            A1.axpy(1, A1_change, True)
            self.tc.end('assembleA1')
            self.tc.start('assembleA1stab')
            if self.stabilize and not self.use_full_SUPG:
                assemble(a1_stab, tensor=A1_stab)  # assembling into existing matrix is faster than assembling new one
                A1.axpy(1, A1_stab, True)
            self.tc.end('assembleA1stab')

            # Compute tentative velocity step
            begin("Computing tentative velocity")
            self.tc.start('rhs')
            b = assemble(L1)
            self.tc.end('rhs')
            self.tc.start('applybc1')
            [bc.apply(A1, b) for bc in bcu]
            self.tc.end('applybc1')
            try:
                self.tc.start('solve 1')
                self.solver_vel_tent.solve(A1, u_.vector(), b)
                self.tc.end('solve 1')
                if save_this_step:
                    self.tc.start('saveVel')
                    problem.save_vel(True, u_, t)
                    self.tc.end('saveVel')
                if save_this_step and not onlyVel:
                    problem.save_div(True, u_)
                problem.compute_err(True, u_, t)
                problem.compute_div(True, u_)
            except RuntimeError as inst:
                problem.report_fail(t)
                return 1
            end()

            # DDN debug
            # u_ext_in = assemble(inner(u_, n)*problem.get_outflow_measure_form())
            # DDN_triggered = assemble(min_value(Constant(0.), inner(u_, n))*problem.get_outflow_measure_form())
            # print('DDN: u_tent*n dSout = ', u_ext_in)
            # print('DDN: negative part of u_tent*n dSout = ', DDN_triggered)

            if self.useRotationScheme:
                begin("Computing tentative pressure")
            else:
                begin("Computing pressure")
            if self.forceOutflow and problem.can_force_outflow:
                out = problem.compute_outflow(u_)
                info('Tentative outflow: %f' % out)
                n_o = -problem.last_inflow-out
                info('Needed outflow: %f' % n_o)
                need_outflow.assign(n_o)
            self.tc.start('rhs')
            b = assemble(L2)
            self.tc.end('rhs')
            self.tc.start('applybcP')
            [bc.apply(A2, b) for bc in bcp]
            if self.bc in ['nullspace', 'nullspace_s']:
                self.null_space.orthogonalize(b)
            self.tc.end('applybcP')
            try:
                self.tc.start('solve 2')
                if self.bc == 'lagrange':
                    self.solver_p.solve(A2, p_QL.vector(), b)
                else:
                    self.solver_p.solve(A2, p_.vector(), b)
                self.tc.end('solve 2')
            except RuntimeError as inst:
                problem.report_fail(t)
                return 1
            if self.useRotationScheme:
                foo = Function(self.Q)
                if self.bc == 'lagrange':
                    fa.assign(pQ, p_QL.sub(0))
                    foo.assign(pQ + p0)
                else:
                    foo.assign(p_+p0)
                problem.averaging_pressure(foo)
                if save_this_step and not onlyVel:
                    problem.save_pressure(True, foo)
            else:
                if self.bc == 'lagrange':
                    fa.assign(pQ, p_QL.sub(0))
                    problem.averaging_pressure(pQ)
                    if save_this_step and not onlyVel:
                        problem.save_pressure(False, pQ)
                else:
                    # we do not want to change p=0 on outflow, it conflicts with do-nothing conditions
                    foo = Function(self.Q)
                    foo.assign(p_)
                    problem.averaging_pressure(foo)
                    if save_this_step and not onlyVel:
                        problem.save_pressure(False, foo)
            end()

            begin("Computing corrected velocity")
            self.tc.start('rhs')
            b = assemble(L3)
            self.tc.end('rhs')
            if not self.B:
                self.tc.start('applybc3')
                [bc.apply(A3, b) for bc in bcu]
                self.tc.end('applybc3')
            try:
                self.tc.start('solve 3')
                self.solver_vel_cor.solve(A3, u_cor.vector(), b)
                self.tc.end('solve 3')
                problem.compute_err(False, u_cor, t)
                problem.compute_div(False, u_cor)
            except RuntimeError as inst:
                problem.report_fail(t)
                return 1
            if save_this_step:
                self.tc.start('saveVel')
                problem.save_vel(False, u_cor, t)
                self.tc.end('saveVel')
            if save_this_step and not onlyVel:
                problem.save_div(False, u_cor)
            end()

            # DDN debug
            # u_ext_in = assemble(inner(u_cor, n)*problem.get_outflow_measure_form())
            # DDN_triggered = assemble(min_value(Constant(0.), inner(u_cor, n))*problem.get_outflow_measure_form())
            # print('DDN: u_cor*n dSout = ', u_ext_in)
            # print('DDN: negative part of u_cor*n dSout = ', DDN_triggered)

            if self.useRotationScheme:
                begin("Rotation scheme pressure correction")
                self.tc.start('rhs')
                b = assemble(L4)
                self.tc.end('rhs')
                try:
                    self.tc.start('solve 4')
                    self.solver_rot.solve(A4, p_mod.vector(), b)
                    self.tc.end('solve 4')
                except RuntimeError as inst:
                    problem.report_fail(t)
                    return 1
                problem.averaging_pressure(p_mod)
                if save_this_step and not onlyVel:
                    problem.save_pressure(False, p_mod)
                end()

            # compute functionals (e. g. forces)
            problem.compute_functionals(u_cor,
                                        p_mod if self.useRotationScheme else (pQ if self.bc == 'lagrange' else p_), t)

            # Move to next time step
            self.tc.start('next')
            u1.assign(u0)
            u0.assign(u_cor)
            u_.assign(u_cor)  # use corretced velocity as initial guess in first step

            if self.useRotationScheme:
                p0.assign(p_mod)
            else:
                if self.bc == 'lagrange':
                    p0.assign(pQ)
                else:
                    p0.assign(p_)

            t = round(t + dt, 6)  # round time step to 0.000001
            step += 1
            self.tc.end('next')

        info("Finished: Incremental pressure correction scheme n. 1")
        problem.report()
        return 0
Esempio n. 57
0
u_tent = TrialFunction(V)
v = TestFunction(V)
# U_ = 1.5*u0 - 0.5*u1
# nonlinearity = inner(dot(0.5 * (u_tent.dx(0) + u0.dx(0)), U_), v) * dx
# F_tent = (1./dt)*inner(u_tent - u0, v) * dx + nonlinearity\
#     + nu*inner(0.5 * (u_tent.dx(0) + u0.dx(0)), v.dx(0)) * dx + inner(p0.dx(0), v) * dx\
#     - inner(f, v)*dx     # solve to u_
# using explicite scheme: so LHS has interpretation as heat equation, RHS are sources
F_tent = (1./dt)*inner(u_tent - u0, v)*dx + inner(dot(u0.dx(0), u0), v)*dx + nu*inner((u_tent.dx(0) + u0.dx(0)), v.dx(0)) * dx + inner(p0.dx(0), v) * dx\
    - inner(f, v)*dx     # solve to u_
a_tent, L_tent = system(F_tent)
# step 2
u_tent_computed = Function(V)
p = TrialFunction(Q)
q = TestFunction(Q)
F_p = inner(grad(p-p0), grad(q))*dx + (1./dt)*u_tent_computed.dx(0)*q*dx # + 2*p.dx(0)*q*ds(1) # tried to force dp/dn=0 on inflow
# TEST: prescribe Neumann outflow BC
# F_p = inner(grad(p-p0), grad(q))*dx + (1./dt)*u_tent_computed.dx(0)*q*dx + (1./dt)*(v_in_expr-u_tent_computed)*q*ds(2)
a_p, L_p = system(F_p)
A_p = assemble(a_p)
as_backend_type(A_p).set_nullspace(null_space)
print(A_p.array())
# step 2 rotation
# F_p_rot = inner(grad(p), grad(q))*dx + (1./dt)*u_tent_computed.dx(0)*q*dx + (1./dt)*(v_in_expr-u_tent_computed)*q*ds(2)
F_p_rot = inner(grad(p), grad(q))*dx + (1./dt)*u_tent_computed.dx(0)*q*dx
a_p_rot, L_p_rot = system(F_p_rot)
A_p_rot = assemble(a_p_rot)
as_backend_type(A_p_rot).set_nullspace(null_space)
# step 3
p_computed = Function(Q)
u_cor = TrialFunction(V)
# plot_matrix(A_diffusion_1D)
# plot_matrix(A_diffusion_1D)

a_convection_1D = inner(dot(u.dx(0), u_ext), v)*dx
A_convection_1D = assemble(a_convection_1D)
# plot_matrix(A_convection_1D)

u_exts = [interpolate(Expression(('1.', '1.')), V2D), interpolate(Expression(('1.', '1.', '1.')), V3D)]
Qspaces = [Q2D, Q3D]
Vspaces = [V2D, V3D]
names = ['2D', '3D']

for i in [0, 1]:
    Qspace = Qspaces[i]
    Vspace = Vspaces[i]
    u = TrialFunction(Vspace)
    v = TestFunction(Vspace)
    a_mass = inner(u, v)*dx
    A_mass = assemble(a_mass)
    a_diffusion = inner(grad(u), grad(v))*dx
    A_diffusion = assemble(a_diffusion)
    a_convection = inner(dot(grad(u), u_exts[i]), v)*dx
    A_convection = assemble(a_convection)
    plot_matrix(A_mass, 'mass' + names[i])
    plot_matrix(A_diffusion, 'diff' + names[i])
    plot_matrix(A_convection, 'conv' + names[i])

show()


Esempio n. 59
0
def norm(v, norm_type="L2", mesh=None):
    """
    Return the norm of a given vector or function.

    *Arguments*
        v
            a :py:class:`Vector <dolfin.cpp.Vector>` or
            a :py:class:`Function <dolfin.functions.function.Function>`.
        norm_type
            see below for alternatives.
        mesh
            optional :py:class:`Mesh <dolfin.cpp.Mesh>` on
            which to compute the norm.

    If the norm type is not specified, the standard :math:`L^2` -norm
    is computed. Possible norm types include:

    *Vectors*

    ================   =================  ================
    Norm               Usage
    ================   =================  ================
    :math:`l^2`        norm(x, 'l2')      Default
    :math:`l^1`        norm(x, 'l1')
    :math:`l^\infty`   norm(x, 'linf')
    ================   =================  ================

    *Functions*

    ================  =================  =================================
    Norm              Usage              Includes the :math:`L^2` -term
    ================  =================  =================================
    :math:`L^2`       norm(v, 'L2')      Yes
    :math:`H^1`       norm(v, 'H1')      Yes
    :math:`H^1_0`     norm(v, 'H10')     No
    :math:`H` (div)   norm(v, 'Hdiv')    Yes
    :math:`H` (div)   norm(v, 'Hdiv0')   No
    :math:`H` (curl)  norm(v, 'Hcurl')   Yes
    :math:`H` (curl)  norm(v, 'Hcurl0')  No
    ================  =================  =================================

    *Examples of usage*

    .. code-block:: python

        v = Function(V)
        x = v.vector()

        print norm(x, 'linf')   # print the infinity norm of vector x

        n = norm(v)             # compute L^2 norm of v
        print norm(v, 'Hdiv')   # print H(div) norm of v
        n = norm(v, 'H1', mesh) # compute H^1 norm of v on given mesh

    """

    if not isinstance(v, (GenericVector, GenericFunction)):
        raise TypeError, "expected a GenericVector or GenericFunction"

    # Check arguments
    if not isinstance(norm_type, str):
        cpp.dolfin_error("norms.py",
                         "compute norm",
                         "Norm type must be a string, not " + str(type(norm_type)))
    if mesh is not None and not isinstance(mesh, Mesh):
        cpp.dolfin_error("norms.py",
                         "compute norm",
                         "Expecting a Mesh, not " + str(type(mesh)))

    # Select norm type
    if isinstance(v, GenericVector):
        return v.norm(norm_type.lower())

    elif (isinstance(v, Coefficient) and isinstance(v, GenericFunction)):
        if norm_type.lower() == "l2":
            M = inner(v, v)*dx()
        elif norm_type.lower() == "h1":
            M = inner(v, v)*dx() + inner(grad(v), grad(v))*dx()
        elif norm_type.lower() == "h10":
            M = inner(grad(v), grad(v))*dx()
        elif norm_type.lower() == "hdiv":
            M = inner(v, v)*dx() + div(v)*div(v)*dx()
        elif norm_type.lower() == "hdiv0":
            M = div(v)*div(v)*dx()
        elif norm_type.lower() == "hcurl":
            M = inner(v, v)*dx() + inner(curl(v), curl(v))*dx()
        elif norm_type.lower() == "hcurl0":
            M = inner(curl(v), curl(v))*dx()
        else:
            cpp.dolfin_error("norms.py",
                             "compute norm",
                             "Unknown norm type (\"%s\") for functions" % str(norm_type))
    else:
        cpp.dolfin_error("norms.py",
                         "compute norm",
                         "Unknown object type. Must be a vector or a function")

    # Get mesh
    if isinstance(v, Function) and mesh is None:
        mesh = v.function_space().mesh()

    # Assemble value
    r = assemble(M, mesh=mesh, form_compiler_parameters={"representation": "quadrature"})

    # Check value
    if r < 0.0:
        cpp.dolfin_error("norms.py",
                         "compute norm",
                         "Square of norm is negative, might be a round-off error")
    elif r == 0.0:
        return 0.0
    else:
        return sqrt(r)
 def T(p, v):
     return -p * I + 2.0 * self.nu * sym(grad(v))