message: create loop for offdiag parts of discontinuous case in parallel coarsening matrix assembly
diff: @@ -3116,8 +3116,55 @@ ParFiniteElementSpace::ParallelDerefinementMatrix(int old_ndofs,
  // create the offdiagonal part of the derefinement matrix
  SparseMatrix *offd = new SparseMatrix(ndofs*vdim, 1);
  -
  std::map<HYPRE_BigInt, int> col_map;
  +
  + if (FEColl()->GetContType() == FiniteElementCollection::DISCONTINUOUS)
  + {
  + for (int k = 0; k < dtrans.embeddings.Size(); k++)
  + {
  + const Embedding &emb = dtrans.embeddings[k];
  + if (emb.parent < 0) { continue; }
  +
  + int coarse_rank = old_pncmesh->ElementRank(emb.parent);
  + int fine_rank = old_ranks[k];
  +
  + if (coarse_rank == MyRank && fine_rank != MyRank)
  + {
  + Geometry::Type geom = mesh->GetElementBaseGeometry(emb.parent);
  + DenseMatrix &lR = localR[geom](emb.matrix);
  +
  + elem_dof->GetRow(emb.parent, dofs);
  +
  + DerefDofMessage &msg = messages[k];
  + MFEM_ASSERT(msg.dofs.size(), "");
  +
  + for (int vd = 0; vd < vdim; vd++)
  + {
  + MFEM_ASSERT(ldof[geom], "");
  + HYPRE_BigInt* remote_dofs = &msg.dofs[vd*ldof[geom]];
  +
  + for (int i = 0; i < lR.Height(); i++)
  + {
  + if (!std::isfinite(lR(i, 0))) { continue; }
  +
  + int r = DofToVDof(dofs[i], vd);
  + int m = (r >= 0) ? r : (-1 - r);
  +
  + lR.GetRow(i, row);
  + MFEM_ASSERT(ldof[geom] == row.Size(), "");
  + for (int j = 0; j < ldof[geom]; j++)
  + {
  + if (row[j] == 0.0) { continue; } // NOTE: lR thresholded
  + int &lcol = col_map[remote_dofs[j]];
  + if (!lcol) { lcol = col_map.size(); }
  + offd->_Set_(m, lcol-1, row[j]);
  + }
  + }
  + }
  + }
  + }
  + }
  + else {
  for (int k = 0; k < dtrans.embeddings.Size(); k++)
  {
  const Embedding &emb = dtrans.embeddings[k];
  @@ -3165,6 +3212,9 @@ ParFiniteElementSpace::ParallelDerefinementMatrix(int old_ndofs,
  }
  }
  }
  +
  + }
  +
  messages.clear();
  offd->Finalize(0);
  offd->SetWidth(col_map.size());
  