Test that elasticity nullspace is actually a nullspace.
(gdim, degree, dtype)
| 84 | @pytest.mark.parametrize("gdim", [2, 3]) |
| 85 | @pytest.mark.parametrize("degree", [1, 2]) |
| 86 | def test_nullspace_check(gdim, degree, dtype): |
| 87 | """Test that elasticity nullspace is actually a nullspace.""" |
| 88 | # TODO: Once we support SpMV, run on MPI.COMM_WORLD |
| 89 | comm = MPI.COMM_SELF |
| 90 | xtype = dtype(0).real.dtype |
| 91 | if gdim == 2: |
| 92 | mesh = create_unit_square(comm, 12, 13, dtype=xtype) |
| 93 | elif gdim == 3: |
| 94 | mesh = create_box( |
| 95 | comm, |
| 96 | [np.array([0.8, -0.2, -5.0]), np.array([3.0, 11.0, 1.2])], |
| 97 | [12, 18, 25], |
| 98 | cell_type=CellType.tetrahedron, |
| 99 | ghost_mode=GhostMode.none, |
| 100 | dtype=xtype, |
| 101 | ) |
| 102 | |
| 103 | gdim = mesh.geometry.dim |
| 104 | V = functionspace(mesh, ("Lagrange", degree, (gdim,))) |
| 105 | u, v = TrialFunction(V), TestFunction(V) |
| 106 | |
| 107 | E, nu = 2.0e2, 0.3 |
| 108 | mu = E / (2.0 * (1.0 + nu)) |
| 109 | lmbda = E * nu / ((1.0 + nu) * (1.0 - 2.0 * nu)) |
| 110 | |
| 111 | def sigma(w, gdim): |
| 112 | return 2.0 * mu * ufl.sym(grad(w)) + lmbda * ufl.tr(grad(w)) * ufl.Identity(gdim) |
| 113 | |
| 114 | a = form(inner(sigma(u, mesh.geometry.dim), grad(v)) * dx, dtype=dtype) |
| 115 | |
| 116 | # Assemble matrix and create compatible vector |
| 117 | A = assemble_matrix(a) |
| 118 | A.scatter_reverse() |
| 119 | |
| 120 | # Create null space basis and test |
| 121 | nullspace = build_elastic_nullspace(V, dtype) |
| 122 | la.orthonormalize(nullspace) |
| 123 | As = A.to_scipy() |
| 124 | |
| 125 | eps = np.sqrt(np.finfo(dtype).eps) |
| 126 | for x in nullspace: |
| 127 | assert np.isclose(np.linalg.norm(As * nullspace[0].array), 0, atol=eps) |
nothing calls this directly
no test coverage detected