Skip to content

Conversation

pbrubeck
Copy link
Contributor

Description

Support assemble(a, mat_type="is")

@pbrubeck pbrubeck force-pushed the pbrubeck/matis branch 2 times, most recently from 27c2f79 to 2c66987 Compare June 25, 2025 15:11
Copy link
Contributor

@wence- wence- left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think a bunch of the indexing is wrong when constructing the masked lgmaps?

continue
off = section.getOffset(p)
# Local indices within W
W_indices = slice(block_size * off, block_size * (off + dof))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If block is True and lgmap has block_size > 1 then this produces out of bounds indices.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or conversely, if this is a mixed space where one component has block size > 1, then this masks out dofs even when running on a single process (which seems wrong).

W_indices = slice(block_size * off, block_size * (off + dof))
own.extend(W_local_ises_indices[W_indices])

mask = numpy.setdiff1d(range(len(lgmap.indices)), own)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you're trying to mask out those entries in lgmap.indices which belong to dofs that are not reachable from owned cells?

I think for a non-mixed space, this is (if block=True):

cmap = V.cell_node_map()
mask = np.setdiff1d(
    cmap.values_with_halo[cmap.iterset.size:], 
    cmap.values[:cmap.iterset.size],
)

For a mixed space, you need to index through to local_ises, I think like this?

mask_pieces = []
for i, W in enumerate(V):
    iset = V.dof_dset.local_ises[i]
    cmap = W.cell_node_map()
    to_mask = np.setdiff1d(cmap.values_with_halo[cmap.iterset.size:], cmap.values[:cmap.iterset.size])
    bs = iset.block_size
    if bs > 1:
        to_mask = np.concatenate([i + bs * to_mask for i in range(bs)])
    mask_pieces.append(iset.indices[to_mask])
mask = np.concatenate(mask_pieces)

Copy link
Contributor Author

@pbrubeck pbrubeck Jun 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cell_node_map is not defined for extruded meshes, but also there is no DM for extruded. The correct thing is to execute a pyop2 kernel that visits only the dofs that are reachable from owned cells.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only VectorElements or TensorElements can have blocksize != 1. Any MixedElement has blocksize = 1

raise ValueError("Monolithic matrix assembly not supported for systems "
"with R-space blocks")

# TODO reconstruct dof_dset with the unghosted lgmap
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ksagiyam is it possible to get a RestrictedFunctionSpace with the unghosted FunctionSpace (the space that corresponds to DistributedMeshOverlapType.None)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alternatively, if I reconstruct the FunctionSpace with the mesh without the overlap, would I get consistent dof orderings? How do I recover the mesh without overlap?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can make a RestrictedFunctionSpace with boundary_set=ghost entities.

DoF ordering on each entity is the same only for CG and DG spaces (assuming that cone orderings are preserved). Otherwise DoFs depend on the global vertex numbers, which are arbitrary.

I think what we want is to be able to pass ignore_halos=True to op2.Sparsity and have op2.DataSet.lgmap (and similar) return the correct lgmap in the first place depending on the value of ignore_halos?

@pbrubeck pbrubeck force-pushed the pbrubeck/matis branch 8 times, most recently from f4a86f7 to c715954 Compare August 1, 2025 16:15
@pbrubeck pbrubeck changed the base branch from release to main September 8, 2025 14:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants