Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

More work towards supporting mixed-topology meshes #3590

Merged
merged 112 commits into from
Jan 16, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
112 commits
Select commit Hold shift + click to select a range
939ffd2
Add very low level example code
chrisrichardson Apr 17, 2024
5d7f356
Merge branch 'main' into chris/add-basic-mixed-mesh-demo
chrisrichardson May 8, 2024
348535b
Update to latest dolfinx
chrisrichardson May 8, 2024
9ff5bd2
Add comments
chrisrichardson May 8, 2024
2d8a574
Use vtk permutation
chrisrichardson May 8, 2024
83fd7d7
Merge branch 'main' into chris/add-basic-mixed-mesh-demo
chrisrichardson May 23, 2024
5aaa7bd
Merge branch 'main' into chris/add-basic-mixed-mesh-demo
chrisrichardson May 24, 2024
3ce8772
Call ffcx once
chrisrichardson May 24, 2024
5a2ac74
Remove unused
chrisrichardson May 24, 2024
3028fcb
Merge branch 'main' into chris/add-basic-mixed-mesh-demo
chrisrichardson May 28, 2024
789ec07
Fix some mypy moaning
chrisrichardson May 28, 2024
041958d
Exit in parallel
chrisrichardson May 28, 2024
8f354f9
Work on create_mesh [skip ci]
chrisrichardson Jun 3, 2024
4024520
push back spans [skip ci]
chrisrichardson Jun 3, 2024
a480bb9
add test
chrisrichardson Jun 3, 2024
d16c01a
Adjust docstring
chrisrichardson Jun 3, 2024
13aa54e
Enable no-partitioning mode
chrisrichardson Jun 3, 2024
f366554
Merge branch 'chris/create-mixed-mesh' into chris/add-basic-mixed-mes…
chrisrichardson Jun 4, 2024
cf5e9c2
Use create_mesh
chrisrichardson Jun 4, 2024
257347c
merge
chrisrichardson Aug 9, 2024
c7cb1c3
Merge branch 'main' into chris/add-basic-mixed-mesh-demo
chrisrichardson Sep 26, 2024
809c940
Merge branch 'chris/dofmapbuilder-update' into chris/geometry-mix-more
chrisrichardson Dec 2, 2024
be14655
Update to API
chrisrichardson Dec 2, 2024
2f50810
Slight tidy up
chrisrichardson Dec 2, 2024
51448fc
More dolfinx integration
chrisrichardson Dec 17, 2024
ff4dd0f
Simplify and add more docs
chrisrichardson Dec 17, 2024
75d4c92
Fix for MPI
chrisrichardson Dec 17, 2024
008ab7a
Merge branch 'main' into chris/add-basic-mixed-mesh-demo
jpdean Dec 18, 2024
75b2b95
Start on generalising assembler
jpdean Dec 18, 2024
550d217
Used custom SP for now
jpdean Dec 18, 2024
3fe59d8
Ranges
jpdean Dec 18, 2024
7b41aeb
Check only one type of imap when Topology::index_map called
jpdean Dec 18, 2024
11810ef
Fix default integration entities
jpdean Dec 18, 2024
7e4fcf8
Combine
jpdean Dec 18, 2024
774712a
Add sparsity build function
jpdean Dec 19, 2024
b5e374d
Simplify
jpdean Dec 19, 2024
22a8351
Tidy
jpdean Dec 19, 2024
25a5ddf
Format
jpdean Dec 19, 2024
0c3d74e
Fix docs
jpdean Dec 19, 2024
3aa6a86
Docs
jpdean Dec 19, 2024
866b952
Add FIXMEs
jpdean Dec 19, 2024
9f79409
Add list of eles
jpdean Dec 23, 2024
e15d8c1
Multiple dofmaps
jpdean Dec 23, 2024
c23b185
Add new FS contructor
jpdean Dec 23, 2024
1eea4d3
Add getters
jpdean Dec 23, 2024
3e27ecd
Bind new constructor
jpdean Dec 23, 2024
88ae9a6
Start on form
jpdean Dec 23, 2024
9cca7c2
Add func to get cell types
jpdean Dec 23, 2024
130c064
Pass multiple ufcx_forms
jpdean Dec 23, 2024
3011afc
Merge branch 'main' into jpdean/mixed_mesh_hackathon_2
jpdean Jan 6, 2025
7b45bba
Work on demo
jpdean Jan 6, 2025
0f707e7
Remove commented line
jpdean Jan 6, 2025
fad7acc
Start on adding cell_type to integral data
jpdean Jan 6, 2025
2d6d581
More work
jpdean Jan 6, 2025
02dfcf2
More work
jpdean Jan 6, 2025
c567e52
More hacking
jpdean Jan 6, 2025
9551741
More work
jpdean Jan 7, 2025
61abc40
More work
jpdean Jan 7, 2025
b37454d
Multiple kernels
jpdean Jan 7, 2025
91807cf
Fix sparsity pattern creation
jpdean Jan 7, 2025
5eca1ef
Add back rest of demo
jpdean Jan 7, 2025
019d557
Tidy
jpdean Jan 7, 2025
0fd7f33
Tidy
jpdean Jan 7, 2025
24cd618
Tidy
jpdean Jan 7, 2025
d51cb62
Tidy
jpdean Jan 7, 2025
9287ff4
Uncomment code
jpdean Jan 7, 2025
067ae90
Tidy
jpdean Jan 7, 2025
b5d170f
Tidy
jpdean Jan 7, 2025
a271625
Add FIXME
jpdean Jan 7, 2025
1161c52
Tidy
jpdean Jan 7, 2025
f6ab437
Tidy
jpdean Jan 7, 2025
9e215de
Uncomment code
jpdean Jan 7, 2025
7d19df3
Simplify
jpdean Jan 7, 2025
007dbb6
Uncomment more code
jpdean Jan 7, 2025
a58354f
Rename
jpdean Jan 7, 2025
e85dc8f
Simplify
jpdean Jan 7, 2025
b274e4e
Tidy
jpdean Jan 7, 2025
7db4562
Add comment
jpdean Jan 7, 2025
b138bef
Get kernel properly
jpdean Jan 8, 2025
33f29bc
Comments
jpdean Jan 8, 2025
f2433ec
More work
jpdean Jan 8, 2025
5467685
Check number of elements/dofmaps
jpdean Jan 8, 2025
df2b2d6
Add note
jpdean Jan 8, 2025
5ddbac9
Tidy
jpdean Jan 8, 2025
cab867c
Tidy
jpdean Jan 8, 2025
3dd3959
Tidy
jpdean Jan 8, 2025
ca7e12d
Ruff fix
chrisrichardson Jan 8, 2025
6652f1c
Merge branch 'main' into jpdean/mixed_mesh_hackathon_2
chrisrichardson Jan 8, 2025
b6cfb8e
Add []
chrisrichardson Jan 9, 2025
d0ee5d8
Fix vector vs span
chrisrichardson Jan 9, 2025
eef9ff6
Ruff formatting
chrisrichardson Jan 9, 2025
bb9f12b
Ruff formatting
chrisrichardson Jan 9, 2025
e217faf
Doc fix
chrisrichardson Jan 9, 2025
6798def
Add separate function
jpdean Jan 9, 2025
c6f85e4
Add FIXME
jpdean Jan 9, 2025
a6f3480
mypy
jpdean Jan 10, 2025
5599f5e
Use std::size_t
jpdean Jan 10, 2025
08f1b1d
Docs
jpdean Jan 10, 2025
66f32a3
Fix float type
jpdean Jan 10, 2025
945d940
Fix type
jpdean Jan 10, 2025
68eb4f3
Fix test
jpdean Jan 10, 2025
98996d3
Merge branch 'main' into jpdean/mixed_mesh_hackathon_2
garth-wells Jan 11, 2025
2355c6b
Merge branch 'main' into jpdean/mixed_mesh_hackathon_2
garth-wells Jan 11, 2025
d7296e9
Updates
garth-wells Jan 11, 2025
3a3c0a8
Merge branch 'main' into jpdean/mixed_mesh_hackathon_2
garth-wells Jan 12, 2025
5ad4369
Add check
jpdean Jan 13, 2025
955f85a
Merge branch 'jpdean/mixed_mesh_hackathon_2' of github.com:FEniCS/dol…
jpdean Jan 13, 2025
85a2eda
Merge branch 'main' into jpdean/mixed_mesh_hackathon_2
jpdean Jan 13, 2025
52521ac
Update cpp/dolfinx/fem/FunctionSpace.h
garth-wells Jan 13, 2025
00f0672
Style updates
garth-wells Jan 13, 2025
19ebda5
Docs
jpdean Jan 13, 2025
6172b0d
Merge branch 'main' into jpdean/mixed_mesh_hackathon_2
chrisrichardson Jan 14, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
112 changes: 93 additions & 19 deletions cpp/dolfinx/fem/Form.h
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,35 @@ class Form
return _function_spaces;
}

/// @brief Get the kernel function for integral `i` on given domain
/// type.
/// @param[in] type Integral type.
/// @param[in] i The subdomain ID.
/// @param[in] kernel_idx Index of the kernel (we may have multiple kernels
/// for a given ID in mixed-topology meshes).
/// @return Function to call for `tabulate_tensor`.
std::function<void(scalar_type*, const scalar_type*, const scalar_type*,
const geometry_type*, const int*, const uint8_t*)>
kernel(IntegralType type, int i, int kernel_idx) const
{
const std::vector<integral_data<scalar_type, geometry_type>>& integrals
= _integrals[static_cast<std::size_t>(type)];

// Get the range of integrals with a given ID
auto get_id = [](const auto& a) { return a.id; };
auto start = std::ranges::lower_bound(integrals, i, std::less<>{}, get_id);
auto end = std::ranges::upper_bound(integrals, i, std::less<>{}, get_id);

// Check that the kernel is valid and return it if so
if (start == integrals.end() or start->id != i
or std::distance(start, end) <= kernel_idx)
{
throw std::runtime_error("No kernel for requested domain index.");
}

return std::next(start, kernel_idx)->kernel;
}

/// @brief Get the kernel function for integral `i` on given domain
/// type.
/// @param[in] type Integral type.
Expand All @@ -267,13 +296,7 @@ class Form
const geometry_type*, const int*, const uint8_t*)>
kernel(IntegralType type, int i) const
{
const auto& integrals = _integrals[static_cast<std::size_t>(type)];
auto it = std::ranges::lower_bound(integrals, i, std::less<>{},
[](const auto& a) { return a.id; });
if (it != integrals.end() and it->id == i)
return it->kernel;
else
throw std::runtime_error("No kernel for requested domain index.");
return kernel(type, i, 0);
}

/// @brief Get types of integrals in the form.
Expand Down Expand Up @@ -310,8 +333,7 @@ class Form
/// @param[in] i Index of the integral.
std::vector<int> active_coeffs(IntegralType type, std::size_t i) const
{
assert(i < _integrals[static_cast<std::size_t>(type)].size());
return _integrals[static_cast<std::size_t>(type)][i].coeffs;
return _integrals[static_cast<std::size_t>(type)].at(i).coeffs;
}

/// @brief Get the IDs for integrals (kernels) for given integral type.
Expand All @@ -324,9 +346,15 @@ class Form
std::vector<int> integral_ids(IntegralType type) const
{
std::vector<int> ids;
const auto& integrals = _integrals[static_cast<std::size_t>(type)];
const std::vector<integral_data<scalar_type, geometry_type>>& integrals
= _integrals[static_cast<std::size_t>(type)];
std::ranges::transform(integrals, std::back_inserter(ids),
[](auto& integral) { return integral.id; });

// IDs may be repeated in mixed-topology meshes, so remove duplicates
std::sort(ids.begin(), ids.end());
auto it = std::unique(ids.begin(), ids.end());
ids.erase(it, ids.end());
return ids;
}

Expand All @@ -344,12 +372,14 @@ class Form
/// local_facet_index_1)`. Data is flattened with row-major layout,
/// `shape=(num_facets, 4)`.
///
/// @param[in] type Integral domain type.
/// @param[in] type Integral type.
/// @param[in] i Integral ID, i.e. (sub)domain index.
/// @return List of active entities for the given integral (kernel).
std::span<const std::int32_t> domain(IntegralType type, int i) const
{
const auto& integrals = _integrals[static_cast<std::size_t>(type)];
// FIXME This should call domain with kernel_idx=0
const std::vector<integral_data<scalar_type, geometry_type>>& integrals
= _integrals[static_cast<std::size_t>(type)];
auto it = std::ranges::lower_bound(integrals, i, std::less<>{},
[](const auto& a) { return a.id; });
if (it != integrals.end() and it->id == i)
Expand All @@ -358,24 +388,52 @@ class Form
throw std::runtime_error("No mesh entities for requested domain index.");
}

/// @brief Get the list of mesh entity indices for the ith integral
/// (kernel) of a given type.
/// @param[in] type Integral type.
/// @param[in] i Integral ID, i.e. (sub)domain index.
/// @param[in] kernel_idx Index of the kernel (we may have multiple kernels
/// for a given ID in mixed-topology meshes).
/// @return List of active entities for the given integral (kernel).
std::vector<std::int32_t> domain(IntegralType type, int i,
int kernel_idx) const
{
const std::vector<integral_data<scalar_type, geometry_type>>& integrals
= _integrals[static_cast<std::size_t>(type)];
auto get_id = [](const auto& a) { return a.id; };
auto start = std::ranges::lower_bound(integrals, i, std::less<>{}, get_id);
auto end = std::ranges::upper_bound(integrals, i, std::less<>{}, get_id);

// Check that the kernel is valid and return it if so
if (start == integrals.end() or start->id != i
or std::distance(start, end) <= kernel_idx)
{
throw std::runtime_error("No kernel for requested domain index.");
}

return std::next(start, kernel_idx)->entities;
}

/// @brief Compute the list of entity indices in `mesh` for the ith
/// integral (kernel) of a given type (i.e. cell, exterior facet, or
/// interior facet).
///
/// @param type Integral type.
/// @param i Integral ID, i.e. the (sub)domain index.
/// @param kernel_idx Index of the kernel (we may have multiple
/// kernels for a given ID in mixed-topology meshes).
/// @param mesh The mesh the entities are numbered with respect to.
/// @return List of active entities in `mesh` for the given integral.
std::vector<std::int32_t> domain(IntegralType type, int i,
std::vector<std::int32_t> domain(IntegralType type, int i, int kernel_idx,
const mesh::Mesh<geometry_type>& mesh) const
{
// Hack to avoid passing shared pointer to this function
std::shared_ptr<const mesh::Mesh<geometry_type>> msh_ptr(
&mesh, [](const mesh::Mesh<geometry_type>*) {});

std::span<const std::int32_t> entities = domain(type, i);
std::vector<std::int32_t> entities = domain(type, i, kernel_idx);
if (msh_ptr == _mesh)
return std::vector(entities.begin(), entities.end());
return entities;
else
{
std::span<const std::int32_t> entity_map = _entity_maps.at(msh_ptr);
Expand Down Expand Up @@ -416,6 +474,7 @@ class Form
// Get the facet index
const std::int32_t facet
= c_to_f->links(entities[i])[entities[i + 1]];

// Add cell and the local facet index
mapped_entities.insert(mapped_entities.end(),
{entity_map[facet], entities[i + 1]});
Expand Down Expand Up @@ -443,16 +502,17 @@ class Form
}
else if (codim == 1)
{
// In this case, the entity maps take facets in (`_mesh`) to cells in
// `mesh`, so we need to get the facet number from the (cell,
// local_facet pair) first.
// In this case, the entity maps take facets in (`_mesh`) to
// cells in `mesh`, so we need to get the facet number from
// the (cell, local_facet pair) first.
auto c_to_f = _mesh->topology()->connectivity(tdim, tdim - 1);
assert(c_to_f);
for (std::size_t i = 0; i < entities.size(); i += 2)
{
// Get the facet index
const std::int32_t facet
= c_to_f->links(entities[i])[entities[i + 1]];

// Add cell and the local facet index
mapped_entities.insert(mapped_entities.end(),
{entity_map[facet], entities[i + 1]});
Expand All @@ -468,6 +528,20 @@ class Form
}
}

/// @brief Compute the list of entity indices in `mesh` for the ith
/// integral (kernel) of a given type (i.e. cell, exterior facet, or
/// interior facet).
///
/// @param type Integral type.
/// @param i Integral ID, i.e. the (sub)domain index.
/// @param mesh The mesh the entities are numbered with respect to.
/// @return List of active entities in `mesh` for the given integral.
std::vector<std::int32_t> domain(IntegralType type, int i,
const mesh::Mesh<geometry_type>& mesh) const
{
return domain(type, i, 0, mesh);
}

/// @brief Access coefficients.
const std::vector<
std::shared_ptr<const Function<scalar_type, geometry_type>>>&
Expand Down Expand Up @@ -531,5 +605,5 @@ class Form
std::map<std::shared_ptr<const mesh::Mesh<geometry_type>>,
std::vector<std::int32_t>>
_entity_maps;
}; // namespace dolfinx::fem
};
} // namespace dolfinx::fem
Loading
Loading