2727#include " GraphOfGridWrappers.hpp"
2828#include < opm/grid/common/CommunicationUtils.hpp>
2929#include < opm/grid/common/ZoltanPartition.hpp> // function scatterExportInformation
30+ #include < opm/grid/common/ZoltanGraphFunctions.hpp> // makeImportAndExportLists when allowDistributedWells==true
3031
3132namespace Opm {
3233
@@ -524,6 +525,7 @@ zoltanPartitioningWithGraphOfGrid(const Dune::CpGrid& grid,
524525 Dune::EdgeWeightMethod edgeWeightMethod,
525526 int root,
526527 const double zoltanImbalanceTol,
528+ bool allowDistributedWells,
527529 const std::map<std::string, std::string>& params,
528530 int level)
529531{
@@ -562,8 +564,11 @@ zoltanPartitioningWithGraphOfGrid(const Dune::CpGrid& grid,
562564 assert (gog.size ()==0 || !partitionIsEmpty);
563565 auto wellConnections = partitionIsEmpty || !wells ? Dune::cpgrid::WellConnections ()
564566 : Dune::cpgrid::WellConnections (*wells, possibleFutureConnections, grid);
565- addWellConnections (gog, wellConnections);
566- gog.addNeighboringCellsToWells (layers);
567+ if (!allowDistributedWells){
568+ // skip cell contraction if wells can be distributed over multiple processes
569+ addWellConnections (gog, wellConnections);
570+ gog.addNeighboringCellsToWells (layers);
571+ }
567572
568573 // call partitioner
569574 setGraphOfGridZoltanGraphFunctions (zz, gog, partitionIsEmpty);
@@ -590,30 +595,63 @@ zoltanPartitioningWithGraphOfGrid(const Dune::CpGrid& grid,
590595 }
591596
592597 // arrange output into tuples and add well cells
593- auto importExportLists = makeImportAndExportLists (gog,
594- cc,
595- wells,
596- wellConnections,
597- root,
598- numExport,
599- numImport,
600- exportLocalGids,
601- exportGlobalGids,
602- exportProcs,
603- importGlobalGids,
604- level);
598+ auto prepareIELists = [&]() {
599+ if (allowDistributedWells) {
600+ // wells can be split among several processes
601+ using CombinedGridWellGraph = Dune::cpgrid::CombinedGridWellGraph;
602+ std::shared_ptr<CombinedGridWellGraph> gridAndWells;
603+ if (wells) {
604+ gridAndWells.reset (new CombinedGridWellGraph (grid,
605+ wells,
606+ possibleFutureConnections,
607+ transmissibilities,
608+ partitionIsEmpty,
609+ edgeWeightMethod));
610+ }
611+ auto result = makeImportAndExportLists (grid,
612+ cc,
613+ wells,
614+ possibleFutureConnections,
615+ gridAndWells.get (),
616+ root,
617+ numExport,
618+ numImport,
619+ exportGlobalGids, // function uses Local GIDs that are identical to global GIDs
620+ exportGlobalGids,
621+ exportProcs,
622+ importGlobalGids,
623+ allowDistributedWells);
624+ std::sort (std::get<2 >(result).begin (), std::get<2 >(result).end ());
625+ std::sort (std::get<3 >(result).begin (), std::get<3 >(result).end ());
626+ return result;
627+ } else {
628+ // each well is guaranteed to be on a single process
629+ auto partResult = makeImportAndExportLists (gog,
630+ cc,
631+ wells,
632+ wellConnections,
633+ root,
634+ numExport,
635+ numImport,
636+ exportLocalGids,
637+ exportGlobalGids,
638+ exportProcs,
639+ importGlobalGids,
640+ level);
641+ return std::tuple (std::move (std::get<0 >(partResult)),
642+ std::move (std::get<1 >(partResult)),
643+ std::move (std::get<2 >(partResult)),
644+ std::move (std::get<3 >(partResult)),
645+ std::move (wellConnections));
646+ }
647+ };
648+ auto importExportLists = prepareIELists ();
605649
606650 Zoltan_LB_Free_Part (&exportGlobalGids, &exportLocalGids, &exportProcs, &exportToPart);
607651 Zoltan_LB_Free_Part (&importGlobalGids, &importLocalGids, &importProcs, &importToPart);
608652 Zoltan_Destroy (&zz);
609653
610- // add wellConnections to the importExportLists and return it
611- auto result = std::tuple (std::move (std::get<0 >(importExportLists)),
612- std::move (std::get<1 >(importExportLists)),
613- std::move (std::get<2 >(importExportLists)),
614- std::move (std::get<3 >(importExportLists)),
615- std::move (wellConnections));
616- return result;
654+ return importExportLists;
617655}
618656
619657std::vector<std::vector<int > >
@@ -640,6 +678,7 @@ applySerialZoltan (const Dune::CpGrid& grid,
640678 Dune::EdgeWeightMethod edgeWeightMethod,
641679 int root,
642680 const double zoltanImbalanceTol,
681+ bool allowDistributedWells,
643682 const std::map<std::string, std::string>& params)
644683{
645684 int rc = ZOLTAN_OK;
@@ -673,8 +712,11 @@ applySerialZoltan (const Dune::CpGrid& grid,
673712
674713 // prepare graph and contract well cells
675714 GraphOfGrid gog (grid, transmissibilities, edgeWeightMethod);
676- addWellConnections (gog, wellConnections);
677- gog.addNeighboringCellsToWells (layers);
715+ if (!allowDistributedWells){
716+ // skip cell contraction if wells can be distributed over multiple processes
717+ addWellConnections (gog, wellConnections);
718+ gog.addNeighboringCellsToWells (layers);
719+ }
678720
679721 // call partitioner
680722 setGraphOfGridZoltanGraphFunctions (zz, gog, false );
@@ -723,6 +765,7 @@ zoltanSerialPartitioningWithGraphOfGrid(const Dune::CpGrid& grid,
723765 Dune::EdgeWeightMethod edgeWeightMethod,
724766 int root,
725767 const double zoltanImbalanceTol,
768+ bool allowDistributedWells,
726769 const std::map<std::string, std::string>& params)
727770{
728771 // root process has the whole grid, other ranks nothing
@@ -744,6 +787,7 @@ zoltanSerialPartitioningWithGraphOfGrid(const Dune::CpGrid& grid,
744787 edgeWeightMethod,
745788 root,
746789 zoltanImbalanceTol,
790+ allowDistributedWells,
747791 params);
748792 }
749793
@@ -788,8 +832,15 @@ zoltanSerialPartitioningWithGraphOfGrid(const Dune::CpGrid& grid,
788832 // get the distribution of wells
789833 std::vector<std::pair<std::string, bool >> parallel_wells;
790834 if (wells) {
791- auto wellRanks = getWellRanks (gIDtoRank , wellConnections);
792- parallel_wells = wellsOnThisRank (*wells, wellRanks, cc, root);
835+ if (allowDistributedWells) {
836+ // wells can be split among several processes
837+ auto wellsOnProc = Dune::cpgrid::perforatingWellIndicesOnProc (gIDtoRank , *wells, possibleFutureConnections, grid);
838+ parallel_wells = Dune::cpgrid::computeParallelWells (wellsOnProc, *wells, cc, root);
839+ } else {
840+ // each well is guaranteed to be on a single process
841+ auto wellRanks = getWellRanks (gIDtoRank , wellConnections);
842+ parallel_wells = wellsOnThisRank (*wells, wellRanks, cc, root);
843+ }
793844 }
794845
795846 return std::make_tuple (std::move (gIDtoRank ),
0 commit comments