long resolveFlats_parallel(T& elev, SparsePartition<short>& inc, linearpart<float>& flowDir, std::vector<std::vector<node>>&islands, linearpart<float>& orelevDir) { long nx = flowDir.getnx(); long ny = flowDir.getny(); int rank; MPI_Comm_rank(MCW, &rank); int numFlatsChanged = 0, totalNumFlatsChanged = 0; flowTowardsLower(elev, flowDir, islands, inc); do { inc.share(); numFlatsChanged = propagateBorderIncrements(flowDir, inc); MPI_Allreduce(&numFlatsChanged, &totalNumFlatsChanged, 1, MPI_INT, MPI_SUM, MCW); if (rank == 0) { printf("PRL: Lower gradient processed %d flats this iteration\n", totalNumFlatsChanged); } } while(totalNumFlatsChanged > 0); // Not all grid cells were resolved - pits remain // Remaining grid cells are unresolvable pits markPits(elev, flowDir, islands, inc); // Drain flats away from higher adjacent terrain SparsePartition<short> higherGradient(nx, ny, 0); flowFromHigher(elev, flowDir, islands, higherGradient); do { higherGradient.share(); numFlatsChanged = propagateBorderIncrements(flowDir, higherGradient); MPI_Allreduce(&numFlatsChanged, &totalNumFlatsChanged, 1, MPI_INT, MPI_SUM, MCW); if (rank == 0) { printf("PRL: Higher gradient processed %d flats this iteration\n", totalNumFlatsChanged); } } while(totalNumFlatsChanged > 0); // High flow must be inverted before it is combined // // higherFlowMax has to be greater than all of the increments // higherFlowMax can be maximum value of the data type (e.g. 65535) but it will cause overflow problems if more than one iteration is needed short higherFlowMax = 0; for (auto& island : islands) { for (auto& flat : island) { short val = higherGradient.getData(flat.x, flat.y); if (val > higherFlowMax) higherFlowMax = val; } } // FIXME: Is this needed? would it affect directions at the border? short globalHigherFlowmax = 0; MPI_Allreduce(&higherFlowMax, &globalHigherFlowmax, 1, MPI_SHORT, MPI_MAX, MCW); for (auto& island : islands) { for (auto flat : island) { inc.addToData(flat.x, flat.y, globalHigherFlowmax - higherGradient.getData(flat.x, flat.y)); } } inc.share(); if (rank==0) { fprintf(stderr,"\nPRL: Setting directions\n"); fflush(stderr); } uint64_t localFlatsRemaining = 0, globalFlatsRemaining = 0; double tempdxc, tempdyc; for (auto& island : islands) { for (node flat : island) { //setFlow2(flat.x, flat.y, flowDir, elev, inc); orelevDir.getdxdyc(flat.y, tempdxc, tempdyc); float DXX[3] = {0, tempdxc, tempdyc}; //tardemlib.cpp ln 1291 float DD = sqrt(tempdxc * tempdxc + tempdyc * tempdyc); //tardemlib.cpp ln 1293 SET2(flat.y, flat.x, DXX, DD, elev, inc, flowDir); if (flowDir.getData(flat.x, flat.y) == -1) { localFlatsRemaining++; } } } flowDir.share(); MPI_Allreduce(&localFlatsRemaining, &globalFlatsRemaining, 1, MPI_UINT64_T, MPI_SUM, MCW); auto hasFlowDirection = [&](const node& n) { return flowDir.getData(n.x, n.y) != -1; }; auto isEmpty = [&](const std::vector<node>& i) { return i.empty(); }; // Remove flats which have flow direction set for (auto& island : islands) { island.erase(std::remove_if(island.begin(), island.end(), hasFlowDirection), island.end()); } // Remove empty islands islands.erase(std::remove_if(islands.begin(), islands.end(), isEmpty), islands.end()); return globalFlatsRemaining; }
long resolveFlats(T& elevDEM, SparsePartition<short>& inc, linearpart<float>& flowDir, std::vector<std::vector<node>>&islands, linearpart<float>& orelevDir) { long nx = flowDir.getnx(); long ny = flowDir.getny(); int rank; MPI_Comm_rank(MCW, &rank); if (rank==0) { fprintf(stderr,"Resolving flats\n"); fflush(stderr); } flowTowardsLower(elevDEM, flowDir, islands, inc); // Drain flats away from higher adjacent terrain SparsePartition<short> s(nx, ny, 0); flowFromHigher(elevDEM, flowDir, islands, s); // High flow must be inverted before it is combined // // higherFlowMax has to be greater than all of the increments // higherFlowMax can be maximum value of the data type but it will cause overflow problems if more than one iteration is needed short higherFlowMax = 0; for (auto& island : islands) { for (node flat : island) { short val = s.getData(flat.x, flat.y); if (val > higherFlowMax) higherFlowMax = val; } } for (auto& island : islands) { for (auto flat : island) { inc.addToData(flat.x, flat.y, higherFlowMax - s.getData(flat.x, flat.y)); } } if (rank==0) { fprintf(stderr,"Setting directions\n"); fflush(stderr); } long flatsRemaining = 0; double tempdxc, tempdyc; for (auto& island : islands) { for (node flat : island) { //setFlow2(flat.x, flat.y, flowDir, elevDEM, inc); orelevDir.getdxdyc(flat.y, tempdxc, tempdyc); float DXX[3] = {0, tempdxc, tempdyc}; //tardemlib.cpp ln 1291 float DD = sqrt(tempdxc * tempdxc + tempdyc * tempdyc); //tardemlib.cpp ln 1293 SET2(flat.y, flat.x, DXX, DD, elevDEM, inc, flowDir); if (flowDir.getData(flat.x, flat.y) == -1) { flatsRemaining++; } } } auto hasFlowDirection = [&](const node& n) { return flowDir.getData(n.x, n.y) != -1; }; auto isEmpty = [&](const std::vector<node>& i) { return i.empty(); }; // Remove flats which have flow direction set for (auto& island : islands) { island.erase(std::remove_if(island.begin(), island.end(), hasFlowDirection), island.end()); } // Remove empty islands islands.erase(std::remove_if(islands.begin(), islands.end(), isEmpty), islands.end()); return flatsRemaining; }