Hello dealii community,

I am working on a problem with several subdomains. At the interface between 
them a boundary integral is to be evaluated. I am identifying the interface 
by comparing the material_id of neighboring cells (or their active_fe_index 
as I am using a different FESystem per subdomain). In order to speed up the 
search during assembly, a Vector<float> is previously filled with 1.0 at 
the cells where the material_id/active_fe_index differ. This approach works 
in serial but in parallel the material_id() call of a neighbor cell outside 
the locally owned subdomain always returns 0 (An assertion is missing 
here). As such, not only the interface between subdomains is marked but 
also the interface between locally owned subdomains, as shown in the 
attached picture

My question is, if there is an equivalent to locally owned and relevant 
dofs for the case of cells, i.e., locally owned and relevant cells such 
that the material_id/active_fe_index of the neighboring cell outside the 
locally owned subdomain can be read? Alternatively, is there a built-in 
method/member which can be used for my purpose or someone has already done 
it through another approach?

Attached is also the MWE used to obtain the attached screenshot.

Cheers,
Jose

-- 
The deal.II project is located at http://www.dealii.org/
For mailing list/forum options, see 
https://groups.google.com/d/forum/dealii?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"deal.II User Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/dealii/2fed0564-bd7c-451e-af9f-f9e0d16bacc0n%40googlegroups.com.
#include <deal.II/base/conditional_ostream.h>

#include <deal.II/distributed/tria.h>

#include <deal.II/dofs/dof_handler.h>

#include <deal.II/grid/tria.h>
#include <deal.II/grid/grid_generator.h>
#include <deal.II/grid/grid_out.h>

#include <deal.II/numerics/data_out.h>



namespace Tests
{



template<int dim>
class MarkInterface
{
public:

  MarkInterface();

  void run();

private:

  dealii::ConditionalOStream                    pcout;

  dealii::parallel::distributed::Triangulation<dim>
                                                triangulation;

  dealii::DoFHandler<dim>                       dof_handler;

  dealii::Vector<float>                         locally_owned_subdomain;

  dealii::Vector<float>                         material_id;

  dealii::Vector<float>                         active_fe_index;

  dealii::Vector<float>                         cell_is_at_interface;

  const double                                  edge_length;

  void make_grid();

  void mark_grid();

  void output();
};



template<int dim>
MarkInterface<dim>::MarkInterface()
:
pcout(
  std::cout,
  dealii::Utilities::MPI::this_mpi_process(MPI_COMM_WORLD) == 0),
triangulation(MPI_COMM_WORLD),
dof_handler(triangulation),
edge_length(1.0)
{}



template<int dim>
void MarkInterface<dim>::run()
{
  make_grid();

  mark_grid();

  output();
}



template<int dim>
void MarkInterface<dim>::make_grid()
{
  // Grid
  dealii::GridGenerator::hyper_cube(
    triangulation,
    0,
    edge_length,
    false);

  triangulation.refine_global(5);

  // Subdomains
  for (const auto &active_cell : triangulation.active_cell_iterators())
    if (active_cell->is_locally_owned())
    {
      if (std::fabs(active_cell->center()[0]) < edge_length/2.0)
        active_cell->set_material_id(1);
      else
        active_cell->set_material_id(2);
    }

  // Match active FE index to material index
  for (const auto &active_cell : dof_handler.active_cell_iterators())
    if (active_cell->is_locally_owned())
      active_cell->set_active_fe_index(active_cell->material_id());
}



template <int dim>
void MarkInterface<dim>::mark_grid()
{
  cell_is_at_interface.reinit(triangulation.n_active_cells());
  locally_owned_subdomain.reinit(triangulation.n_active_cells());
  material_id.reinit(triangulation.n_active_cells());
  active_fe_index.reinit(triangulation.n_active_cells());

  cell_is_at_interface    = -1.0;
  locally_owned_subdomain = -1.0;
  material_id             = -1.0;
  active_fe_index         = -1.0;

  for (const auto &active_cell :
       dof_handler.active_cell_iterators())
  {
    if (active_cell->is_locally_owned())
    {
      locally_owned_subdomain(active_cell->active_cell_index()) =
        triangulation.locally_owned_subdomain();
      material_id(active_cell->active_cell_index()) =
        active_cell->material_id();
      active_fe_index(active_cell->active_cell_index()) =
        active_cell->active_fe_index();

      for (const auto &face_index : active_cell->face_indices())
      {
        if (!active_cell->face(face_index)->at_boundary() &&
            active_cell->active_fe_index() !=
              active_cell->neighbor(face_index)->active_fe_index())
        {
          cell_is_at_interface(active_cell->active_cell_index()) = 1.0;
          break;
        }
      }
    }
  }
}



template<int dim>
void MarkInterface<dim>::output()
{
  dealii::DataOut<dim> data_out;

  data_out.attach_dof_handler(dof_handler);

  data_out.add_data_vector(locally_owned_subdomain,
                           "locally_owned_subdomain");

  data_out.add_data_vector(material_id,
                           "material_id");

  data_out.add_data_vector(active_fe_index,
                           "active_fe_index");

  data_out.add_data_vector(cell_is_at_interface,
                           "cell_is_at_interface");

  data_out.build_patches();

  data_out.write_vtu_in_parallel(
    "triangulation_" + std::to_string(dim) + ".vtu",
    MPI_COMM_WORLD);
}



} // namespace Test



int main(int argc, char *argv[])
{
  try
  {
    dealii::Utilities::MPI::MPI_InitFinalize mpi_initialization(
      argc, argv, dealii::numbers::invalid_unsigned_int);

    {
      Tests::MarkInterface<2> test;
      test.run();
    }

    {
      Tests::MarkInterface<3> test;
      test.run();
    }

  }
  catch (std::exception &exc)
  {
    std::cerr << std::endl
              << std::endl
              << "----------------------------------------------------"
              << std::endl;
    std::cerr << "Exception on processing: " << std::endl
              << exc.what() << std::endl
              << "Aborting!" << std::endl
              << "----------------------------------------------------"
              << std::endl;
    return 1;
  }
  catch (...)
  {
    std::cerr << std::endl
              << std::endl
              << "----------------------------------------------------"
              << std::endl;
    std::cerr << "Unknown exception!" << std::endl
              << "Aborting!" << std::endl
              << "----------------------------------------------------"
              << std::endl;
    return 1;
  }
  return 0;
}

Reply via email to