-
-
Notifications
You must be signed in to change notification settings - Fork 189
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add multiple dofmaps and elements to Geometry (#3071)
* Add b ack some mixed topology * Start working on mixed topology again * Create _entity_types instead of _cell_type * Fixes in Python for testing * A bit of debug and a test * Add access to IndexMaps * Add more accessors and tests * Use general version of create_topology * Clarify for mypy * Add more accessors and test * Use nb::overload_cast * Remove commented code * Add test file * more tests * Improve docs * Const fix * const fix * Doc fix * Rewrite topology computation slightly * Use int8_t * more int8 * Adjustments to compute_entities * Something not working * Fix up * Pass more back up * Make all entities of dim * flake8 * More suggestions * Fixes for suggestions * flake8 * Update test * update test * Apply suggestions from code review Co-authored-by: Jørgen Schartum Dokken <[email protected]> * Add a few suggestions * Update cpp/dolfinx/mesh/Topology.cpp Co-authored-by: Jørgen Schartum Dokken <[email protected]> * Fixes for multiple cell types * Compute connectivity (edges) * Fix create_connectivity and test * Print some topology * Fix typo * Make interprocess_facets available * Clean up test a bit * Start work on Geometry * work in progress * More work to do... * doc fix * Python fixes * Add python wrapper * Pass IndexMaps, not topology * More work in progress [skip ci] * Fix [skip ci] * Add a (failing) test * Debug and test * isort * int type * Get a parallel test working * isort * Create an actual mesh * Create a dofmap * docs * More changes * More work on build_basic_dofmap * More tidying up * Fix global offset loop level * Remove a few unneeded checks * Compute global start correctly * clean up * Remove unused * format * doc * Fix typo * Update ufl syntax * Some tidy up * Update test * Update test * Revert Geometry.h to main * Improvements to utils.cpp * Adjust python interface * Fix for name resolution in pybind * Clean up debug * More test updates * Specify dtype more precisely * More dtype * Update to types in utils.cpp * Update to python interface * test names * Apply suggestions from code review Co-authored-by: Garth N. Wells <[email protected]> * Changes from review so far * Fix memory allocation * Suggested changes --------- Co-authored-by: Jørgen Schartum Dokken <[email protected]> Co-authored-by: Garth N. Wells <[email protected]>
- Loading branch information
1 parent
7a22dbc
commit 0f85bab
Showing
8 changed files
with
546 additions
and
170 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
from mpi4py import MPI | ||
|
||
import numpy as np | ||
|
||
import basix | ||
import dolfinx.cpp as _cpp | ||
from dolfinx import jit | ||
from dolfinx.cpp.mesh import Mesh_float64, create_geometry, create_topology | ||
from dolfinx.fem import coordinate_element | ||
from dolfinx.fem.dofmap import DofMap | ||
from dolfinx.log import LogLevel, set_log_level | ||
from dolfinx.mesh import CellType | ||
|
||
|
||
def create_element_dofmap(mesh, cell_types, degree): | ||
cpp_elements = [] | ||
dofmaps = [] | ||
for cell_type in cell_types: | ||
ufl_e = basix.ufl.element("P", cell_type, degree) | ||
form_compiler_options = {"scalar_type": np.float64} | ||
(ufcx_element, ufcx_dofmap), module, code = jit.ffcx_jit( | ||
mesh.comm, ufl_e, form_compiler_options=form_compiler_options | ||
) | ||
ffi = module.ffi | ||
cpp_elements += [ | ||
_cpp.fem.FiniteElement_float64(ffi.cast("uintptr_t", ffi.addressof(ufcx_element))) | ||
] | ||
dofmaps += [ufcx_dofmap] | ||
|
||
cpp_dofmaps = _cpp.fem.create_dofmaps( | ||
mesh.comm, [ffi.cast("uintptr_t", ffi.addressof(dm)) for dm in dofmaps], mesh.topology | ||
) | ||
|
||
return (cpp_elements, cpp_dofmaps) | ||
|
||
|
||
def test_dofmap_mixed_topology(): | ||
rank = MPI.COMM_WORLD.Get_rank() | ||
|
||
# Two triangles and one quadrilateral | ||
tri = [0, 1, 4, 0, 3, 4] | ||
quad = [1, 4, 2, 5] | ||
# cells with global indexing | ||
cells = [[t + 3 * rank for t in tri], [q + 3 * rank for q in quad]] | ||
orig_index = [[3 * rank, 1 + 3 * rank], [2 + 3 * rank]] | ||
# No ghosting | ||
ghost_owners = [[], []] | ||
# All vertices are on boundary | ||
boundary_vertices = [3 * rank + i for i in range(6)] | ||
|
||
topology = create_topology( | ||
MPI.COMM_WORLD, | ||
[CellType.triangle, CellType.quadrilateral], | ||
cells, | ||
orig_index, | ||
ghost_owners, | ||
boundary_vertices, | ||
) | ||
# Create dofmaps for Geometry | ||
tri = coordinate_element(CellType.triangle, 1) | ||
quad = coordinate_element(CellType.quadrilateral, 1) | ||
nodes = np.arange(6, dtype=np.int64) + 3 * rank | ||
xdofs = np.array([0, 1, 4, 0, 3, 4, 1, 4, 2, 5], dtype=np.int64) + 3 * rank | ||
x = np.array( | ||
[[0.0, 0.0], [1.0, 0.0], [2.0, 0.0], [0.0, 1.0], [1.0, 1.0], [2.0, 1.0]], dtype=np.float64 | ||
) | ||
x[:, 1] += 1.0 * rank | ||
|
||
set_log_level(LogLevel.INFO) | ||
geom = create_geometry( | ||
topology, [tri._cpp_object, quad._cpp_object], nodes, xdofs, x.flatten(), 2 | ||
) | ||
mesh = Mesh_float64(MPI.COMM_WORLD, topology, geom) | ||
|
||
assert mesh.geometry.x.shape == (6, 3) | ||
|
||
# Second order dofmap on mixed mesh | ||
elements, dofmaps = create_element_dofmap( | ||
mesh, [basix.CellType.triangle, basix.CellType.quadrilateral], 2 | ||
) | ||
|
||
assert len(elements) == 2 | ||
assert elements[0].basix_element.cell_type.name == "triangle" | ||
assert elements[1].basix_element.cell_type.name == "quadrilateral" | ||
|
||
assert len(dofmaps) == 2 | ||
q0 = DofMap(dofmaps[0]) | ||
q1 = DofMap(dofmaps[1]) | ||
assert q0.index_map.size_local == q1.index_map.size_local | ||
# Triangles | ||
print(q0.list) | ||
assert q0.list.shape == (2, 6) | ||
assert len(q0.dof_layout.entity_dofs(2, 0)) == 0 | ||
# Quadrilaterals | ||
print(q1.list) | ||
assert q1.list.shape == (1, 9) | ||
assert len(q1.dof_layout.entity_dofs(2, 0)) == 1 | ||
|
||
|
||
def test_dofmap_prism_mesh(): | ||
# Prism mesh | ||
cells = [[0, 1, 2, 3, 4, 5]] | ||
# cells with global indexing | ||
orig_index = [[0, 1, 2, 3, 4, 5]] | ||
# No ghosting | ||
ghost_owners = [[]] | ||
# All vertices are on boundary | ||
boundary_vertices = [0, 1, 2, 3, 4, 5] | ||
|
||
topology = create_topology( | ||
MPI.COMM_SELF, [CellType.prism], cells, orig_index, ghost_owners, boundary_vertices | ||
) | ||
topology.create_entities(2) | ||
|
||
# Create dofmaps for Geometry | ||
prism = coordinate_element(CellType.prism, 1) | ||
nodes = np.array([0, 1, 2, 3, 4, 5], dtype=np.int64) | ||
xdofs = np.array([0, 1, 2, 3, 4, 5], dtype=np.int64) | ||
x = 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], | ||
[1.0, 0.0, 1.0], | ||
[0.0, 1.0, 1.0], | ||
], | ||
dtype=np.float64, | ||
) | ||
|
||
set_log_level(LogLevel.INFO) | ||
geom = create_geometry(topology, [prism._cpp_object], nodes, xdofs, x.flatten(), 3) | ||
mesh = Mesh_float64(MPI.COMM_WORLD, topology, geom) | ||
|
||
elements, dofmaps = create_element_dofmap(mesh, [basix.CellType.prism], 2) | ||
print() | ||
assert len(elements) == 1 | ||
assert len(dofmaps) == 1 | ||
q = DofMap(dofmaps[0]) | ||
assert q.index_map.size_local == 18 | ||
print(q.list) | ||
facet_dofs = [] | ||
for j in range(5): | ||
facet_dofs += q.dof_layout.entity_dofs(2, j) | ||
assert len(facet_dofs) == 3 |
Oops, something went wrong.