def initialize_data(self):
        """
        Extract required objects for defining error control
        forms. This will be stored and reused.
        """
        # Developer's note: The UFL-FFC-DOLFIN--PyDOLFIN toolchain for
        # error control is quite fine-tuned. In particular, the order
        # of coefficients in forms is (and almost must be) used for
        # their assignment. This means that the order in which these
        # coefficients are defined matters and should be considered
        # fixed.

        # Primal trial element space
        self._V = self.u.function_space()

        # Primal test space == Dual trial space
        Vhat = self.weak_residual.arguments()[0].function_space()

        # Discontinuous version of primal trial element space
        self._dV = tear(self._V)

        # Extract cell and geometric dimension
        mesh = self._V.mesh()
        dim = mesh.topology().dim()

        # Function representing improved dual
        E = increase_order(Vhat)
        self._Ez_h = Function(E)

        # Function representing cell bubble function
        B = FunctionSpace(mesh, "B", dim + 1)
        self._b_T = Function(B)
        self._b_T.vector()[:] = 1.0

        # Function representing strong cell residual
        self._R_T = Function(self._dV)

        # Function representing cell cone function
        C = FunctionSpace(mesh, "DG", dim)
        self._b_e = Function(C)

        # Function representing strong facet residual
        self._R_dT = Function(self._dV)

        # Function for discrete dual on primal test space
        self._z_h = Function(Vhat)

        # Piecewise constants for assembling indicators
        self._DG0 = FunctionSpace(mesh, "DG", 0)
Beispiel #2
0
def test_ref_count(pushpop_parameters):
    "Test petsc4py reference counting"
    parameters["linear_algebra_backend"] = "PETSc"

    mesh = UnitSquareMesh(3, 3)
    V = FunctionSpace(mesh, "P", 1)

    # Check u and x own the vector
    u = Function(V)
    x = as_backend_type(u.vector()).vec()
    assert x.refcount == 2

    # Check decref
    del u
    gc.collect()  # destroy u
    assert x.refcount == 1

    # Check incref
    vec = PETScVector(x)
    assert x.refcount == 2
def deformation_vector():
    n1 = (1 + x1[0] * sin(2 * pi * x1[1])) * VolumeNormal(multimesh.part(1))
    S_sm = VectorFunctionSpace(multimesh.part(1), "CG", 1)
    # Note removing 0 dirichlet at dI introduces problems with the change in
    # the cut cell and overlap cell part. We do not have any way of describing
    # this movement
    bcs = [
        DirichletBC(S_sm, n1, mfs[1], 2),
        DirichletBC(S_sm, Constant((0, 0)), mfs[1], 1)
    ]

    u, v = TrialFunction(S_sm), TestFunction(S_sm)
    a = inner(grad(u), grad(v)) * dx
    l = inner(Constant((0., 0.)), v) * dx
    n = Function(S_sm)
    solve(a == l, n, bcs=bcs)
    S = MultiMeshVectorFunctionSpace(multimesh, "CG", 1)
    s = MultiMeshFunction(S)
    s.assign_part(1, n)
    return s
Beispiel #4
0
def _test_get_set_coordinates(mesh):
    # Get coords
    V = FunctionSpace(mesh, mesh.ufl_coordinate_element())
    c = Function(V)
    get_coordinates(c, mesh.geometry())

    # Check correctness of got coords
    _check_coords(mesh, c)

    # Backup and zero coords
    coords = mesh.coordinates()
    coords_old = coords.copy()
    coords[:] = 0.0
    assert np.all(mesh.coordinates() == 0.0)

    # Set again to old value
    set_coordinates(mesh.geometry(), c)

    # Check
    assert np.all(mesh.coordinates() == coords_old)
Beispiel #5
0
 def __init__(self, V, **kwargs):
     # Call parent
     ParametrizedProblem.__init__(self, os.path.join("test_eim_approximation_14_tempdir", expression_type, basis_generation, "mock_problem"))
     # Minimal subset of a ParametrizedDifferentialProblem
     self.V = V
     self._solution = Function(V)
     self.components = ["u", "s", "p"]
     # Parametrized function to be interpolated
     x = SpatialCoordinate(V.mesh())
     mu = SymbolicParameters(self, V, (1., ))
     self.f00 = (1-x[0])*cos(3*pi*mu[0]*(1+x[0]))*exp(-mu[0]*(1+x[0]))
     self.f01 = (1-x[0])*sin(3*pi*mu[0]*(1+x[0]))*exp(-mu[0]*(1+x[0]))
     # Inner product
     f = TrialFunction(self.V)
     g = TestFunction(self.V)
     self.inner_product = assemble(inner(f, g)*dx)
     # Collapsed vector and space
     self.V0 = V.sub(0).collapse()
     self.V00 = V.sub(0).sub(0).collapse()
     self.V1 = V.sub(1).collapse()
Beispiel #6
0
    def compute(self, get):
        u = get(self.valuename)

        if u is None:
            return None

        if not isinstance(u, Function):
            cbc_warning("Do not understand how to handle datatype %s" %str(type(u)))
            return None

        #if not hasattr(self, "restriction_map"):
        if not hasattr(self, "keys"):
            V = u.function_space()
            element = V.ufl_element()
            family = element.family()
            degree = element.degree()

            if LooseVersion(dolfin_version()) > LooseVersion("1.6.0"):
                rank = len(u.ufl_shape)
            else:
                rank = u.rank()

            if rank == 0: FS = FunctionSpace(self.submesh, family, degree)
            elif rank == 1: FS = VectorFunctionSpace(self.submesh, family, degree)
            elif rank == 2: FS = TensorFunctionSpace(self.submesh, family, degree, symmetry={})

            self.u = Function(FS)


            #self.restriction_map = restriction_map(V, FS)
            rmap = restriction_map(V, FS)
            self.keys = np.array(rmap.keys(), dtype=np.intc)
            self.values = np.array(rmap.values(), dtype=np.intc)
            self.temp_array = np.zeros(len(self.keys), dtype=np.float_)

        # The simple __getitem__, __setitem__ has been removed in dolfin 1.5.0.
        # The new cbcpost-method get_set_vector should be compatible with 1.4.0 and 1.5.0.
        #self.u.vector()[self.keys] = u.vector()[self.values]

        get_set_vector(self.u.vector(), self.keys, u.vector(), self.values, self.temp_array)
        return self.u
Beispiel #7
0
def load_microstructure(h5file, fgroup, mesh, geo, include_sheets=True):

    if h5file.has_dataset(fgroup):
        # Get fibers
        fiber_attrs = h5file.attributes(fgroup)
        fspace = fiber_attrs["space"]
        if fspace is None:
            # Assume quadrature 4
            family = "Quadrature"
            order = 4
        else:
            family, order = fspace.split("_")

        namesstr = fiber_attrs["names"]
        if namesstr is None:
            names = ["fiber"]
        else:
            names = namesstr.split(":")

        # Check that these fibers exists
        for name in names:
            fsubgroup = fgroup + "/{}".format(name)
            if not h5file.has_dataset(fsubgroup):
                msg = ("H5File does not have dataset {}").format(fsubgroup)
                # FIXME: implement logger
                # logger.warning(msg)

        elm = VectorElement(family=family,
                            cell=mesh.ufl_cell(),
                            degree=int(order),
                            quad_scheme="default")
        V = FunctionSpace(mesh, elm)

        attrs = ["f0", "s0", "n0"]
        for i, name in enumerate(names):
            func = Function(V, name=name)
            fsubgroup = fgroup + "/{}".format(name)

            h5file.read(func, fsubgroup)

            setattr(geo, attrs[i], func)
Beispiel #8
0
def test_scalar_p1_scaled_mesh():
    # Make coarse mesh smaller than fine mesh
    meshc = UnitCubeMesh(MPI.comm_world, 2, 2, 2)
    meshc.geometry.points *= 0.9

    meshf = UnitCubeMesh(MPI.comm_world, 3, 4, 5)

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

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

    u = Expression(expr_eval)
    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

    # Now make coarse mesh larger than fine mesh
    meshc.geometry.points *= 1.5

    uc = interpolate(u, Vc)

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

    diff = Vuc.vector()
    diff.axpy(-1, uf.vector())

    assert diff.norm() < 1.0e-12
Beispiel #9
0
def MeasureFunction(averaged):
    '''Get measure of the averaging shape as a function on the 1d surface'''
    # Get space on 1d mesh for the measure
    V = averaged.function_space()  # 3d one
    # Want the measure in scalar space
    if V.ufl_element().value_shape(): V = V.sub(0).collapse()

    mesh_1d = averaged.average_['mesh']
    # Finally
    TV = average_space(V, mesh_1d)

    TV_coordinates = TV.tabulate_dof_coordinates().reshape((TV.dim(), -1))
    TV_dm = TV.dofmap()

    visited = np.zeros(TV.dim(), dtype=bool)
    mesh_x = mesh_1d.coordinates()
    shape = averaged.average_['shape']

    values = np.empty(TV.dim(), dtype=float)
    for cell in cells(mesh_1d):
        # Get the tangent (normal of the plane which cuts the virtual
        # surface to yield the bdry curve
        v0, v1 = mesh_x[cell.entities(0)]
        n = v0 - v1

        # Where to
        dofs = TV_dm.cell_dofs(cell.index())
        for seen, dof in zip(visited[dofs], dofs):
            if not seen:
                x = TV_coordinates[dof]
                # Values sum up to the measure of the hypersurface
                values[dof] = sum(shape.quadrature(x, n).weights)
                visited[dof] = True

    assert np.all(visited)

    # Wrap as a function
    m = Function(TV)
    m.vector().set_local(values)

    return m
Beispiel #10
0
    def big_error_norms(self, u, overlap_subdomain):
        V = FunctionSpace(self.mesh, "Lagrange", self.p)

        uu = Function(V)
        uu.vector()[:] = u.vector()
        # uu.vector()[:] = u.vector()

        overlap_marker = MeshFunction('size_t', self.mesh,
                                      self.mesh.topology().dim())
        overlap_subdomain.mark(overlap_marker, 1)

        dxo = Measure('dx', subdomain_data=overlap_marker)

        error = (uu**2) * dxo
        semi_error = inner(grad(uu), grad(uu)) * dxo

        L2 = assemble(error)
        H1 = L2 + assemble(semi_error)
        SH = H1 - L2

        return L2, H1, SH
Beispiel #11
0
def read_vtu_function(vtus, V):
    '''Read in functions in V from VTUs files'''
    # NOTE: this would much easier with (py)vtk but that is not part of
    # the FEniCS stack so ...
    gdim = V.mesh().geometry().dim()
    assert gdim > 1

    if isinstance(vtus, str): vtus = [vtus]

    reorder = data_reordering(V)

    npoints, ncells = V.mesh().num_vertices(), V.mesh().num_cells()
    functions = []
    for vtu in vtus:
        f = Function(V)

        data = read_vtu_point_data(vtu, npoints, ncells)
        f.vector().set_local(reorder(data))

        functions.append(f)
    return functions
def basis_functions_matrix_mul_online_matrix(basis_functions_matrix, online_matrix, BasisFunctionsMatrixType):
    space = basis_functions_matrix.space
    assert isinstance(space, FunctionSpace)

    output = BasisFunctionsMatrixType(space)
    assert isinstance(online_matrix.M, dict)
    j = 0
    for col_component_name in basis_functions_matrix._components_name:
        for _ in range(online_matrix.M[col_component_name]):
            assert len(online_matrix[:, j]) == sum(
                len(functions_list) for functions_list in basis_functions_matrix._components)
            output_j = Function(space)
            i = 0
            for row_component_name in basis_functions_matrix._components_name:
                for fun_i in basis_functions_matrix._components[row_component_name]:
                    output_j.vector().add_local(fun_i.vector().get_local() * online_matrix[i, j])
                    i += 1
            output_j.vector().apply("add")
            output.enrich(output_j)
            j += 1
    return output
Beispiel #13
0
def eikonal_1d(mb, p0=0, function=None):
    "Compute distance from p0 on set of edges"

    # edge-to-vertex connectivity
    EE = np.zeros((mb.num_cells(), mb.num_vertices()), dtype=bool)
    for e in edges(mb):
        EE[e.index(), e.entities(0)] = True

    # vertex-to-vertex connectivity (via edges)
    PP = EE.T @ EE
    np.fill_diagonal(PP, False)

    # initial solution is inf everywhere
    sol = np.empty(PP.shape[0])
    sol.fill(np.inf)

    # initial conditions
    active = deque([p0])
    sol[p0] = 0.0

    # fast marching on edges
    x = mb.coordinates()
    while active:
        curr = active.pop()
        neig = np.where(PP[curr, :])[0]
        ll = sol[curr] + np.linalg.norm(x[neig, :] - x[curr, :], axis=1)
        up = neig[ll < sol[neig]]
        active.extend(up)
        sol[neig] = np.minimum(sol[neig], ll)

    # return solution
    if function is None:
        P1e = FiniteElement("CG", mb.ufl_cell(), 1)
        Ve = FunctionSpace(mb, P1e)
        function = Function(Ve)
        function.vector()[vertex_to_dof_map(Ve)] = sol
        return function
    else:
        Ve = function.function_space()
        function.vector()[vertex_to_dof_map(Ve)] = sol
Beispiel #14
0
def STD(series):
    """std of a series. NOTE: this is a sort of copy-paste coding of RMS; maybe rather
    put in RMS with a STD flag?"""

    # first, compute the mean
    mean = Mean(series)

    # get the square of the field of the mean
    mean_vector = mean.vector()
    mvs = as_backend_type(mean_vector).vec()
    # the mean squared, to be used for computing the RMS
    mvs.pointwiseMult(mvs, mvs)

    # now, compute the STD
    # for this, follow the example of RMS
    std = Function(series.V)
    # NOTE: for efficiency we stay away from Interpreter and all is in PETSc layer
    x = as_backend_type(
        std.vector()).vec()  # PETSc.Vec, stores the final output
    y = x.copy()  # Stores the current working field
    # Integrate
    dts = np.diff(series.times)
    f_vectors = [as_backend_type(f.vector()).vec() for f in series.functions]
    for dt, (f0, f1) in zip(dts, zip(f_vectors[:-1], f_vectors[1:])):
        y.pointwiseMult(f0, f0)  # y = f0**2
        x.axpy(dt / 2., y)  # x += dt / 2 * y

        y.pointwiseMult(f1, f1)  # y = f1**2
        x.axpy(dt / 2., y)  # x += dt / 2 * y

        x.axpy(
            -dt, mvs
        )  # x += -dt * mvs  NOTE: no factor 2, as adding 2 dt / 2 to compensate

    # Time interval scaling
    x /= dts.sum()
    # sqrt
    x.sqrtabs()

    return std
Beispiel #15
0
def run_test():
    q = 3
    Nxy = 100
    tf = 0.1
    h = 1. / Nxy
    mesh = UnitSquareMesh(Nxy, Nxy, "crossed")
    V = FunctionSpace(mesh, 'Lagrange', q)
    Vl = FunctionSpace(mesh, 'Lagrange', 1)
    Dt = h / (q * 10.)
    u0_expr = Expression(\
    '100*pow(x[i]-.25,2)*pow(x[i]-0.75,2)*(x[i]<=0.75)*(x[i]>=0.25)', i=0)

    Wave = AcousticWave({'V': V, 'Vl': Vl, 'Vr': Vl})
    Wave.lump = True
    Wave.timestepper = 'backward'
    Wave.update({'lambda':1.0, 'rho':1.0, 't0':0.0, 'tf':tf, 'Dt':Dt,\
    'u0init':interpolate(u0_expr, V), 'utinit':Function(V)})
    K = Wave.K
    u = Wave.u0
    u.vector()[:] = 1.0
    b = Wave.u1
    for ii in range(100):
        K * u.vector()
        (K * u.vector()).array()

        b.vector()[:] = (K * u.vector()).array()
        b.vector()[:] = 0.0
        b.vector().axpy(1.0, K * u.vector())

        b.vector()[:] = (K * u.vector()).array() + (K * u.vector()).array()
        b.vector()[:] = (K * u.vector() + K * u.vector()).array()

        b.vector()[:] = 2.*u.vector().array() + u.vector().array() + \
        Dt*u.vector().array()
        b.vector()[:] = 0.0
        b.vector().axpy(2.0, u.vector())
        b.vector().axpy(1.0, u.vector())
        b.vector().axpy(Dt, u.vector())
        b.assign(u)
        b.vector().zero()
Beispiel #16
0
def les_setup(u_, mesh, Smagorinsky, CG1Function, nut_krylov_solver, bcs, **NS_namespace):
    """
    Set up for solving Smagorinsky-Lilly LES model.
    """
    DG = FunctionSpace(mesh, "DG", 0)
    CG1 = FunctionSpace(mesh, "CG", 1)

    # Compute cell size and put in delta
    dim = mesh.geometry().dim()
    delta = Function(DG)
    delta.vector().zero()
    delta.vector().set_local(assemble(TestFunction(DG) * dx).array()**(1. / dim))
    delta.vector().apply('insert')

    # Set up Smagorinsky form
    Sij = sym(grad(u_))
    magS = sqrt(2 * inner(Sij, Sij))
    nut_form = Smagorinsky['Cs']**2 * delta**2 * magS
    bcs_nut = derived_bcs(CG1, bcs['u0'], u_)
    nut_ = CG1Function(nut_form, mesh, method=nut_krylov_solver,
                       bcs=bcs_nut, bounded=True, name="nut")
    return dict(Sij=Sij, nut_=nut_, delta=delta, bcs_nut=bcs_nut)
Beispiel #17
0
def les_setup(u_, mesh, Wale, bcs, CG1Function, nut_krylov_solver, **NS_namespace):
    """Set up for solving Wale LES model
    """
    DG = FunctionSpace(mesh, "DG", 0)
    CG1 = FunctionSpace(mesh, "CG", 1)
    
    # Compute cell size and put in delta
    delta = Function(DG)
    delta.vector().zero()
    delta.vector().axpy(1.0, assemble(TestFunction(DG)*dx))
    
    # Set up Wale form
    Gij = grad(u_)
    Sij = sym(Gij)
    Skk = tr(Sij)
    dim = mesh.geometry().dim()
    Sd = sym(Gij*Gij) - 1./3.*Identity(mesh.geometry().dim())*Skk*Skk 
    nut_form = Wale['Cw']**2 * pow(delta, 2./dim) * pow(inner(Sd, Sd), 1.5) / (Max(pow(inner(Sij, Sij), 2.5) + pow(inner(Sd, Sd), 1.25), 1e-6))
    ff = FacetFunction("size_t", mesh, 0)
    bcs_nut = derived_bcs(CG1, bcs['u0'], u_)
    nut_ = CG1Function(nut_form, mesh, method=nut_krylov_solver, bcs=bcs_nut, name='nut', bounded=True)
    return dict(Sij=Sij, Sd=Sd, Skk=Skk, nut_=nut_, delta=delta, bcs_nut=bcs_nut)
Beispiel #18
0
def test_vector_p2_2d():
    meshc = UnitSquareMesh(MPI.comm_world, 5, 4)
    meshf = UnitSquareMesh(MPI.comm_world, 5, 8)

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

    def u(values, x):
        values[:, 0] = x[:, 0] + 2.0 * x[:, 1]
        values[:, 1] = 4.0 * x[:, 0] * x[:, 1]

    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
Beispiel #19
0
def test_scalar_p2():
    meshc = UnitCubeMesh(MPI.comm_world, 2, 2, 2)
    meshf = UnitCubeMesh(MPI.comm_world, 3, 4, 5)

    Vc = FunctionSpace(meshc, ("CG", 2))
    Vf = FunctionSpace(meshf, ("CG", 2))

    def u(values, x):
        values[:, 0] = x[:, 0] + 2.0 * x[:, 1] + 3.0 * x[:, 2]

    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
    def solve(self, opt):
        """ This procedure implements a first-order
        semi-Lagrangian time-stepping scheme to solve a parabolic
        second-order PDE in non-variational form
                - du/dt - (a : D^2 u + b * D u + c * u )  =  - f
        <==>    - du/dt - (a : D^2 u + b * D u + c * u - f ) = 0
        """

        if hasattr(self, 'dt'):
            opt["timeSteps"] *= opt["timeStepFactor"]
        nt = opt["timeSteps"]

        Tspace = np.linspace(self.T[1], self.T[0], nt + 1)
        self.dt = (self.T[1] - self.T[0]) / nt
        self.u_np1 = Function(self.V)

        if opt["saveSolution"]:
            file_u = File('./pvd/u.pvd')

        print('Setting final time conditions')
        assign(self.u, project(self.u_T, self.V))
        if opt["saveSolution"]:
            file_u << self.u

        for i, s in enumerate(Tspace[1:]):

            print('Iteration {}/{}:\t t = {}'.format(i + 1, nt, s))
            self.iter = i

            # Update time in coefficient functions
            self.updateTime(s)

            assign(self.u_np1, self.u)

            # Solve problem for current time step
            super().solve(opt)

            if opt["saveSolution"]:
                file_u << self.u
 def __init__(self, Th, callback_type):
     # Create mesh and define function space
     mesh = UnitSquareMesh(Th, Th)
     self.V = FunctionSpace(mesh, "Lagrange", 1)
     # Define variational problem
     du = TrialFunction(self.V)
     v = TestFunction(self.V)
     self.u = Function(self.V)
     self.r = lambda u, g: inner(grad(u), grad(v))*dx + inner(u + u**3, v)*dx - g*v*dx
     self.j = lambda u, r: derivative(r, u, du)
     # Define initial guess
     self.initial_guess_expression = Expression("0.1 + 0.9*x[0]*x[1]", element=self.V.ufl_element())
     # Define callback function depending on callback type
     assert callback_type in ("form callbacks", "tensor callbacks")
     if callback_type == "form callbacks":
         def callback(arg):
             return arg
     elif callback_type == "tensor callbacks":
         def callback(arg):
             return assemble(arg)
     self.callback_type = callback_type
     self.callback = callback
Beispiel #22
0
 def compute_mu(constant=True):
     """
     Compute mu as according to arxiv paper
     https://arxiv.org/pdf/1509.08601.pdf
     """
     mu_min=Constant(1)
     mu_max=Constant(500)
     if constant:
         return mu_max
     else:
         V = FunctionSpace(self.mesh, "CG",1)
         u, v = TrialFunction(V), TestFunction(V)
         a = inner(grad(u),grad(v))*dx
         l = Constant(0)*v*dx
         bcs = []
         for marker in self.move_dict["Fixed"]:
             bcs.append(DirichletBC(V, mu_min, self.mf, marker))
         for marker in self.move_dict["Deform"]:
             bcs.append(DirichletBC(V, mu_max, self.mf, marker))
         mu = Function(V)
         solve(a==l, mu, bcs=bcs)
         return mu
Beispiel #23
0
def exact_eigensolve(A, B, V, params):
    '''A direct solver intended to run in serial'''
    assert A.comm.size == 1

    A = csr_matrix(A.getValuesCSR()[::-1], shape=A.size)
    B = csr_matrix(B.getValuesCSR()[::-1], shape=B.size)
    
    eigw, eigv = eigh(A.todense(), B.todense())
    sort_idx = np.argsort(eigw)

    # Fall back to 10 eigenpair
    nev = params.get('-eps_type', 10)
    eigw = eigw[sort_idx[:nev]]
    eigv = (eigv.T)[sort_idx[:nev]]

    eigenpairs = []
    for w, v in zip(eigw, eigv):
        f = Function(V)
        f.vector().set_local(v)

        eigenpairs.append((w, f))
    return eigenpairs
Beispiel #24
0
    def __init__(self, W, components=None):
        if components is None:
            self.functions = list(map(Function, W))
        else:
            assert len(components) == len(W)
            # Functions them selves
            if hasattr(first(components), 'function_space'):
                assert [
                    c.function_space() == Wi for c, Wi in zip(components, W)
                ]
                self.functions = components
            # The components can be vectors in that case
            else:
                # Dim check
                assert all(c.size() == Wi.dim()
                           for c, Wi in zip(components, W))
                # Create
                self.functions = [
                    Function(Wi, c) for c, Wi in zip(components, W)
                ]

        self._W = W
Beispiel #25
0
def RMS(series):
    '''sqrt(1/(T - t0)\int_{t0}^{t1}f^2(t)dt'''
    # Again by applying simpson
    rms = Function(series.V)
    # NOTE: for efficiency we stay away from Interpreter and all is in PETSc layer
    x = as_backend_type(rms.vector()).vec()  # PETSc.Vec
    y = x.copy()  # Stores fi**2
    # Integrate
    dts = np.diff(series.times)
    f_vectors = [as_backend_type(f.vector()).vec() for f in series.functions]
    for dt, (f0, f1) in zip(dts, zip(f_vectors[:-1], f_vectors[1:])):
        y.pointwiseMult(f0, f0)  # y = f0**2
        x.axpy(dt / 2., y)  # (f0**2+f1**2)*dt/2

        y.pointwiseMult(f1, f1)  # y = f1**2
        x.axpy(dt / 2., y)
    # Time interval scaling
    x /= dts.sum()
    # sqrt
    x.sqrtabs()

    return rms
Beispiel #26
0
def subdomain_interpolate(pairs, V, reduce='last'):
    '''(f, chi), V -> Function fh in V such that fh|chi is f'''
    array = lambda f: f.vector().get_local()
    fs, chis = zip(*pairs)

    fs = np.column_stack([array(interpolate(f, V)) for f in fs])
    x = np.column_stack([
        array(interpolate(Expression('x[%d]' % i, degree=1), V))
        for i in range(V.mesh().geometry().dim())
    ])

    chis = [CompiledSubDomain(chi, tol=1E-10) for chi in chis]
    is_masked = np.column_stack([
        map(lambda xi, chi=chi: not chi.inside(xi, False), x) for chi in chis
    ])

    fs = mask.masked_array(fs, is_masked)

    if reduce == 'avg':
        values = np.mean(fs, axis=1)
    elif reduce == 'max':
        values = np.choose(np.argmax(fs, axis=1), fs.T)
    elif reduce == 'min':
        values = np.choose(np.argmin(fs, axis=1), fs.T)
    elif reduce == 'first':
        choice = [row.tolist().index(False) for row in is_masked]
        values = np.choose(choice, fs.T)
    elif reduce == 'last':
        choice = np.array(
            [row[::-1].tolist().index(False) for row in is_masked], dtype=int)
        nsubs = len(chis)
        values = np.choose(nsubs - 1 - choice, fs.T)
    else:
        raise ValueError

    fh = Function(V)
    fh.vector().set_local(values)

    return fh
Beispiel #27
0
def NLtol(x, u, FS, Type=None):
    IS = common.IndexSet(FS)

    if Type == 'Update':
        v = x.getSubVector(IS['Velocity']).array
        p = x.getSubVector(IS['Pressure']).array

        pa = Function(FS['Pressure'])
        pa.vector()[:] = p

        ones = Function(FS['Pressure'])
        ones.vector()[:] = (0 * p + 1)
        pp = Function(FS['Pressure'])
        pp.vector(
        )[:] = pa.vector().array() - assemble(pa * dx) / assemble(ones * dx)

        vnorm = norm(v)
        pnorm = norm(pp.vector().array())

        V = [vnorm, pnorm]
        eps = PrintFuncs.NormPrint(V, Type)

        x.axpy(1.0, u)
        return x, eps
    else:
        vcurrent = x.getSubVector(IS['Velocity']).array
        pcurrent = x.getSubVector(IS['Pressure']).array
        vprev = u.getSubVector(IS['Velocity']).array
        pprev = u.getSubVector(IS['Pressure']).array

        pa = Function(FS['Pressure'])
        pa.vector()[:] = pcurrent

        ones = Function(FS['Pressure'])
        ones.vector()[:] = (0 * pcurrent + 1)
        pp = Function(FS['Pressure'])
        pp.vector(
        )[:] = pa.vector().array() - assemble(pa * dx) / assemble(ones * dx)

        vnorm = norm(vcurrent - vprev)
        pnorm = norm(pp.vector().array() - pprev)

        V = [vnorm, pnorm]
        eps = PrintFuncs.NormPrint(V, Type)

        return x, eps
Beispiel #28
0
def main(solver, N: int, dt: float, T: float,
         theta: float) -> Tuple[float, float, float, float, float]:
    # Create cardiac model
    mesh = UnitSquareMesh(N, N)
    time = Constant(0.0)
    cell_model = NoCellModel()

    ac_str = "cos(t)*cos(2*pi*x[0])*cos(2*pi*x[1]) + 4*pow(pi, 2)*cos(2*pi*x[0])*cos(2*pi*x[1])*sin(t)"
    stimulus = Expression(ac_str, t=time, degree=5)

    ps = solver.default_parameters()
    ps["Chi"] = 1.0
    ps["Cm"] = 1.0
    _solver = solver(mesh, time, 1.0, 1.0, stimulus, parameters=ps)

    # 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=5)
    u_exact = Expression("-cos(2*pi*x[0])*cos(2*pi*x[1])*sin(t)/2.0",
                         t=T - (1 - theta) * dt,
                         degree=5)

    # Define initial condition(s)
    vs0 = Function(_solver.V)
    vs_, *_ = _solver.solution_fields()
    vs_.assign(vs0)

    # Solve
    for _, (vs_, vur) in _solver.solve(0, T, dt):
        continue

    # Compute errors
    v, u, *_ = vur.split(deepcopy=True)
    v_error = errornorm(v_exact, v, "L2", degree_rise=5)
    u_error = errornorm(u_exact, u, "L2", degree_rise=5)
    return v_error, u_error, mesh.hmin(), dt, T
Beispiel #29
0
def test_scalar_conditions(R):
    c = Function(R)
    c.vector().set(1.5)

    # Float conversion does not interfere with boolean ufl expressions
    assert isinstance(ufl.lt(c, 3), ufl.classes.LT)
    assert not isinstance(ufl.lt(c, 3), bool)

    # Float conversion is not implicit in boolean Python expressions
    assert isinstance(c < 3, ufl.classes.LT)
    assert not isinstance(c < 3, bool)

    # == is used in ufl to compare equivalent representations,
    # <,> result in LT/GT expressions, bool conversion is illegal

    # Note that 1.5 < 0 == False == 1.5 < 1, but that is not what we
    # compare here:
    assert not (c < 0) == (c < 1)
    # This protects from "if c < 0: ..." misuse:
    with pytest.raises(ufl.UFLException):
        bool(c < 0)
    with pytest.raises(ufl.UFLException):
        not c < 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))

    def u(values, x):
        values[:, 0] = x[:, 0] + 2.0 * x[:, 1]
        values[:, 1] = 4.0 * x[:, 0]
        values[:, 2] = 3.0 * x[:, 2] + x[:, 0]

    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