Ejemplo n.º 1
0
def make_from_data(data, assembly_type):
    """
    Creating a finite element operator from internal data and an assembly type.
    :param: data: data defining the operator.
    :param: assembly_type: type of assembling procedure.
    """
    operator = FiniteElementOperator(fe_space=fe_sp.FiniteElementSpace(),
                                     assembly_type=assembly_type)
    operator.assembly_type = assembly_type

    if assembly_type is AssemblyType.ASSEMBLED:
        if len(data.shape) is 2:
            operator.data = scipy.sparse.csc_matrix(data)
        else:
            raise ValueError(
                "Expecting two dimensional array when creating ASSEMBLED operator from data."
            )
    elif assembly_type is AssemblyType.LOCALLY_ASSEMBLED:
        if len(data.shape) is 1:
            operator.data = data
        else:
            raise ValueError(
                "Expecting one dimensional array when creating LOCALLY_ASSEMBLED operator from data."
            )
    elif assembly_type is AssemblyType.LUMPED:
        if len(data.shape) is 1:
            operator.data = data
        else:
            raise ValueError(
                "Expecting one dimensional array when creating LUMPED operator from data."
            )

    return operator
Ejemplo n.º 2
0
def test_locals_to_globals():
    """
    Testing extracting of global indexes from an element index.
    """
    fe_space = fe_sp.FiniteElementSpace(mesh.Mesh([0.0, -1.0, -4.0]),
                                        fe_order=3)
    np_test.assert_array_equal(fe_space.locals_to_globals(1), [3, 4, 5, 6])
Ejemplo n.º 3
0
def test_get_coord():
    """
    Testing coordinate computation from parametric coordinate of an element.
    """
    random.seed()

    # Mesh with positive coordinates.
    fe_space = fe_sp.FiniteElementSpace(mesh.Mesh([0.0, 1.0, 4.0]), fe_order=3)
    for _ in range(50):
        v = random.random()
        np_test.assert_almost_equal(fe_space.get_coord(1, v), 1.0 + 3.0 * v)

    # Mesh with negative coordinates.
    fe_space = fe_sp.FiniteElementSpace(mesh.Mesh([0.0, -1.0, -4.0]),
                                        fe_order=3)
    for _ in range(50):
        v = random.random()
        np_test.assert_almost_equal(fe_space.get_coord(0, v), -4.0 + 3.0 * v)
Ejemplo n.º 4
0
def test_locals_to_globals_discontinuous():
    """
    Testing extracting of global indexes in discontinuous numbering from an element index.
    """
    fe_space = fe_sp.FiniteElementSpace(mesh.Mesh([0.0, -1.0, -4.0]),
                                        fe_order=3)
    np_test.assert_array_equal(fe_space.locals_to_globals_discontinuous(0),
                               [0, 1, 2, 3])
    np_test.assert_array_equal(fe_space.locals_to_globals_discontinuous(1),
                               [4, 5, 6, 7])
Ejemplo n.º 5
0
def test_assembled_stiffness_p2():
    """
    Testing assembling routine in the case of p2 finite element space on one element.
    """
    p = 2.3
    fe_space = fe_sp.FiniteElementSpace(mesh.Mesh([0.0, 1.0]), fe_order=2, quad_order=2)
    stiffness = stiffness_assembler.assemble_stiffness(fe_space, lambda s: p)
    np_test.assert_array_almost_equal(stiffness.data.data, [7.0 * p / 3.0, -8.0 * p / 3.0, p / 3.0, -8.0 * p / 3.0,
                                                            16.0 * p / 3.0, -8.0 * p / 3.0, p / 3.0, -8.0 * p / 3.0,
                                                            7.0 * p / 3.0])
Ejemplo n.º 6
0
def test_get_quadrature_weight():
    """
    Testing extractin of quadrature weights.
    """
    fe_space = fe_sp.FiniteElementSpace(mesh.Mesh([0.0, 1.0]),
                                        fe_order=3,
                                        quad_order=4)
    _, w = lag_poly.make_quadrature_formula(
        4, lag_poly.PointDistributionType.GAUSS_LOBATTO)
    for iq in range(len(w)):
        np_test.assert_almost_equal(fe_space.get_quadrature_weight(iq), w[iq])
Ejemplo n.º 7
0
def test_assembled_mass_p1():
    """
    Testing assembling routine in the case of p1 finite element space on one element.
    """
    cte_density = 2.3
    fe_space = fe_sp.FiniteElementSpace(mesh.Mesh([0.0, 1.0]),
                                        fe_order=1,
                                        quad_order=2)
    mass = mass_assembler.assemble_mass(fe_space, lambda s: cte_density)
    np_test.assert_array_almost_equal(mass.data.data, [
        cte_density / 3.0, cte_density / 6.0, cte_density / 6.0,
        cte_density / 3.0
    ])
Ejemplo n.º 8
0
def test_apply_basis_diag_basis():
    """
    Testing basisx * diag * basis^T operation.
    """
    distrib_type = lag_poly.PointDistributionType.EQUALLY_DISTRIBUTED
    fe_space = fe_sp.FiniteElementSpace(mesh.Mesh([0.0, 1.0]),
                                        fe_order=2,
                                        basis_type=distrib_type,
                                        quad_order=2,
                                        quad_type=distrib_type)

    test_diag = [666.0, 666.0, 666.0]
    np_test.assert_array_almost_equal(
        fe_space.apply_basis_diag_basis(test_diag), np.diag(test_diag))
Ejemplo n.º 9
0
def test_make_finite_element_space():
    """
    Simple construction of a finite element space.
    """
    fe_space = fe_sp.FiniteElementSpace(mesh.Mesh([0.0, 1.0, 4.0]),
                                        fe_order=3,
                                        quad_order=4)
    np_test.assert_equal(fe_space.get_ndof(), 7)
    np_test.assert_equal(fe_space.get_nelem(), 2)
    np_test.assert_almost_equal(fe_space.get_elem_length(0), 1.0)
    np_test.assert_almost_equal(fe_space.get_elem_length(1), 3)
    np_test.assert_equal(fe_space.get_nlocaldof(), 4)
    np_test.assert_equal(fe_space.get_left_idx(), 0)
    np_test.assert_equal(fe_space.get_right_idx(), 6)
Ejemplo n.º 10
0
def test_lumped_mass_p2():
    """
    Testing mass lumping routine in the case of p2 finite element spaces.
    """
    def density(x):
        return 2.3 * x + 1.3

    fe_space = fe_sp.FiniteElementSpace(mesh.Mesh([0.0, 1.0, 4.0]),
                                        fe_order=2,
                                        quad_order=2)
    assemb_mass = mass_assembler.assemble_mass(
        fe_space, density, fe_op.AssemblyType.ASSEMBLED).data.todense()
    lumped_mass = np.diag(
        mass_assembler.assemble_mass(fe_space, density,
                                     fe_op.AssemblyType.LUMPED).data)
    np_test.assert_array_almost_equal(assemb_mass, lumped_mass)
Ejemplo n.º 11
0
def test_eval_at_quadrature_pnts():
    """
    Testing evaluation of callable at quadrature points.
    """
    fe_space = fe_sp.FiniteElementSpace(
        mesh.Mesh([0.0, -1.0, -4.0]),
        quad_order=3,
        quad_type=lag_poly.PointDistributionType.EQUALLY_DISTRIBUTED)

    # Testing quadrature point indexes.
    np_test.assert_array_equal(
        fe_space.eval_at_quadrature_pnts(lambda k, s: k), [0, 1, 2, 3])

    # Testing quadrature points coordinates.
    p, _ = lag_poly.make_quadrature_formula(
        3, lag_poly.PointDistributionType.EQUALLY_DISTRIBUTED)
    np_test.assert_array_equal(
        fe_space.eval_at_quadrature_pnts(lambda k, s: s), p)
Ejemplo n.º 12
0
def assemble_discontinuous_mass(fe_space,
                                density=lambda x: 1.0,
                                assembly_type=fe_op.AssemblyType.ASSEMBLED):
    """
    Assembling discontinuous mass matrix.
    :param fe_space: input finite element space.
    :param density: function of space variable.
    :param assembly_type: type of assembling procedure.
    :return: instance of FiniteElementOperator class representing the discontinuous mass operator.
    """
    if assembly_type is fe_op.AssemblyType.LUMPED:
        discontinuous_mass = fe_op.FiniteElementOperator(
            fe_space=fe_sp.FiniteElementSpace(), assembly_type=assembly_type)
        discontinuous_mass.data = np.zeros(fe_space.get_nelem() *
                                           fe_space.get_nlocaldof())
        apply_discontinuous_mass_lumping(fe_space, density,
                                         discontinuous_mass.data)
        return discontinuous_mass
    else:
        raise NotImplementedError()
Ejemplo n.º 13
0
def assemble_gradient(fe_space, param=lambda x: 1.0, assembly_type=fe_op.AssemblyType.ASSEMBLED):
    """
    Assembling gradient operator applied on a unknown in H^1-conform discrete space and return a result in a L^2-conform
    discrete space.
    :param fe_space: input finite element space.
    :param param: function of space variable.
    :param assembly_type: type of assembling procedure.
    :return: instance of FiniteElementOperator class representing the gradient operator.
    """
    if assembly_type is fe_op.AssemblyType.ASSEMBLED:

        # Computing operator data.
        lil_gradient = scipy.sparse.lil_matrix((fe_space.get_nelem() * fe_space.get_nlocaldof(), fe_space.get_ndof()))
        apply_gradient_assembling(fe_space, param, lil_gradient)

        # Setting operator data.
        gradient = fe_op.FiniteElementOperator(fe_space=fe_sp.FiniteElementSpace(), assembly_type=assembly_type)
        gradient.data = lil_gradient.tocsc()

        return gradient
    else:
        raise NotImplementedError()

# Creating left dirichlet boundary condition.
left_bc = configuration.BoundaryCondition(boundary_condition_type=configuration.BoundaryConditionType.DIRICHLET,
                                          value=lambda t: functional.ricker(t - src_offset, central_frequency))

absorbing_param = np.sqrt(rho(0.) * modulus(0.))
right_bc = configuration.BoundaryCondition(boundary_condition_type=configuration.BoundaryConditionType.ABSORBING,
                                           value=lambda t: 0, param=absorbing_param)

# Creating configuration.
config = configuration.ViscoElasticKelvinVoigt(density=rho, modulus=modulus, eta=eta, left_bc=left_bc,
                                               right_bc=right_bc)

# Creating finite element space.
fe_space = fe_sp.FiniteElementSpace(mesh=mesh.make_mesh_from_npt(0.0, 10.0, 300), fe_order=5, quad_order=5)

# Creating propagator.
propag = visco_elastic_kelvin_voigt_propagator.ViscoElasticKelvinVoigt(config=config, fe_space=fe_space)

# Initializing.
propag.initialize()

# Runing.
if show_snapshot:

    fig, ax = plt.subplots()
    lines = ax.plot(propag.u0)
    ax.set_ylim((-1, 1))
    plt.ylabel("u (mm)")
    plt.xlabel("x (mm)")