gridap / GridapDistributed.jl

Parallel distributed-memory version of Gridap
MIT License
104 stars 15 forks source link

New tag for interface faces #108

Open JordiManyer opened 1 year ago

JordiManyer commented 1 year ago

Hello all,

Currently, the face labeling for a DistributedDiscreteModel contains a "boundary" tag which contains the entities that belong to the physical boundary (i.e the boundary of the global model). The faces belonging to the interface between processors (i.e belonging to local boundary but not to the global boundary) currently belong to the "interior" entity.

It would probably be beneficial to be able to distinguish these faces by creating a new entity/tag ("ghost_boundary", "interface", ..?). For instance, when implementing DD methods, patch-based smoothers, etc...

The question would then be how to select the "interface" faces in general for any distributed model (dimensions, conformal/non-conformal,etc...). Ideas are most welcome!

JordiManyer commented 1 year ago

This is what I've implemented for patch-based smoothers in PR 7. It's probably not general enough, and only works for facets (Df = Dc-1). Quite inspired by what was done here.

function mark_interface_facets!(model::GridapDistributed.DistributedDiscreteModel{Dc,Dp}) where {Dc,Dp}
  face_labeling = get_face_labeling(model)
  topo = get_grid_topology(model)

  map_parts(local_views(face_labeling),local_views(topo)) do face_labeling, topo
    tag_to_name = face_labeling.tag_to_name
    tag_to_entities = face_labeling.tag_to_entities
    d_to_dface_to_entity = face_labeling.d_to_dface_to_entity

    # Create new tag & entity 
    interface_entity = maximum(map(maximum,tag_to_entities)) + 1
    push!(tag_to_entities,[interface_entity])
    push!(tag_to_name,"interface")

    # Interface faces should also be interior
    interior_tag = findfirst(x->(x=="interior"),tag_to_name)
    push!(tag_to_entities[interior_tag],interface_entity)

    # Select interface entities
    boundary_tag = findfirst(x->(x=="boundary"),tag_to_name)
    boundary_entities = tag_to_entities[boundary_tag]

    f2c_map = Geometry.get_faces(topo,Dc-1,Dc)
    num_cells_around_facet = map(length,f2c_map)
    mx = maximum(num_cells_around_facet)
    for (f,nf) in enumerate(num_cells_around_facet)
      is_boundary = (d_to_dface_to_entity[Dc][f] ∈ boundary_entities)
      if !is_boundary && (nf != mx)
        d_to_dface_to_entity[Dc][f] = interface_entity
      end
    end
  end
end