1dfc14de9SMatthew G. Knepley #include <petscsf.h> 208056efcSDave May #include <petscdmswarm.h> 35917a6f0SStefano Zampini #include <petscdmda.h> 4df21e3a8SDave May #include <petsc/private/dmswarmimpl.h> /*I "petscdmswarm.h" I*/ 5279f676cSBarry Smith #include "../src/dm/impls/swarm/data_bucket.h" 6279f676cSBarry Smith #include "../src/dm/impls/swarm/data_ex.h" 7df21e3a8SDave May 8480eef7bSDave May /* 9480eef7bSDave May User loads desired location (MPI rank) into field DMSwarm_rank 106497c311SBarry Smith 116497c311SBarry Smith It should be storing the rank information as MPIInt not Int 12480eef7bSDave May */ 13d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSwarmMigrate_Push_Basic(DM dm, PetscBool remove_sent_points) 14d71ae5a4SJacob Faibussowitsch { 15df21e3a8SDave May DM_Swarm *swarm = (DM_Swarm *)dm->data; 1677048351SPatrick Sanan DMSwarmDataEx de; 17df21e3a8SDave May PetscInt p, npoints, *rankval, n_points_recv; 18df21e3a8SDave May PetscMPIInt rank, nrank; 19df21e3a8SDave May void *point_buffer, *recv_points; 20df21e3a8SDave May size_t sizeof_dmswarm_point; 21356ed814SMatthew G. Knepley PetscBool debug = PETSC_FALSE; 22df21e3a8SDave May 23521f74f9SMatthew G. Knepley PetscFunctionBegin; 249566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)dm), &rank)); 25df21e3a8SDave May 269566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketGetSizes(swarm->db, &npoints, NULL, NULL)); 279566063dSJacob Faibussowitsch PetscCall(DMSwarmGetField(dm, DMSwarmField_rank, NULL, NULL, (void **)&rankval)); 289566063dSJacob Faibussowitsch PetscCall(DMSwarmDataExCreate(PetscObjectComm((PetscObject)dm), 0, &de)); 299566063dSJacob Faibussowitsch PetscCall(DMSwarmDataExTopologyInitialize(de)); 30521f74f9SMatthew G. Knepley for (p = 0; p < npoints; ++p) { 31835f2295SStefano Zampini PetscCall(PetscMPIIntCast(rankval[p], &nrank)); 3248a46eb9SPierre Jolivet if (nrank != rank) PetscCall(DMSwarmDataExTopologyAddNeighbour(de, nrank)); 33df21e3a8SDave May } 349566063dSJacob Faibussowitsch PetscCall(DMSwarmDataExTopologyFinalize(de)); 359566063dSJacob Faibussowitsch PetscCall(DMSwarmDataExInitializeSendCount(de)); 36df21e3a8SDave May for (p = 0; p < npoints; p++) { 37835f2295SStefano Zampini PetscCall(PetscMPIIntCast(rankval[p], &nrank)); 3848a46eb9SPierre Jolivet if (nrank != rank) PetscCall(DMSwarmDataExAddToSendCount(de, nrank, 1)); 39df21e3a8SDave May } 409566063dSJacob Faibussowitsch PetscCall(DMSwarmDataExFinalizeSendCount(de)); 419566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketCreatePackedArray(swarm->db, &sizeof_dmswarm_point, &point_buffer)); 429566063dSJacob Faibussowitsch PetscCall(DMSwarmDataExPackInitialize(de, sizeof_dmswarm_point)); 43df21e3a8SDave May for (p = 0; p < npoints; p++) { 44835f2295SStefano Zampini PetscCall(PetscMPIIntCast(rankval[p], &nrank)); 45df21e3a8SDave May if (nrank != rank) { 46df21e3a8SDave May /* copy point into buffer */ 479566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketFillPackedArray(swarm->db, p, point_buffer)); 4877048351SPatrick Sanan /* insert point buffer into DMSwarmDataExchanger */ 499566063dSJacob Faibussowitsch PetscCall(DMSwarmDataExPackData(de, nrank, 1, point_buffer)); 50df21e3a8SDave May } 51df21e3a8SDave May } 529566063dSJacob Faibussowitsch PetscCall(DMSwarmDataExPackFinalize(de)); 539566063dSJacob Faibussowitsch PetscCall(DMSwarmRestoreField(dm, DMSwarmField_rank, NULL, NULL, (void **)&rankval)); 54df21e3a8SDave May 55df21e3a8SDave May if (remove_sent_points) { 5677048351SPatrick Sanan DMSwarmDataField gfield; 5722a417f9SDave May 589566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketGetDMSwarmDataFieldByName(swarm->db, DMSwarmField_rank, &gfield)); 599566063dSJacob Faibussowitsch PetscCall(DMSwarmDataFieldGetAccess(gfield)); 609566063dSJacob Faibussowitsch PetscCall(DMSwarmDataFieldGetEntries(gfield, (void **)&rankval)); 6122a417f9SDave May 62df21e3a8SDave May /* remove points which left processor */ 639566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketGetSizes(swarm->db, &npoints, NULL, NULL)); 64df21e3a8SDave May for (p = 0; p < npoints; p++) { 65835f2295SStefano Zampini PetscCall(PetscMPIIntCast(rankval[p], &nrank)); 66df21e3a8SDave May if (nrank != rank) { 67df21e3a8SDave May /* kill point */ 689566063dSJacob Faibussowitsch PetscCall(DMSwarmDataFieldRestoreAccess(gfield)); 6922a417f9SDave May 709566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketRemovePointAtIndex(swarm->db, p)); 7122a417f9SDave May 729566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketGetSizes(swarm->db, &npoints, NULL, NULL)); /* you need to update npoints as the list size decreases! */ 739566063dSJacob Faibussowitsch PetscCall(DMSwarmDataFieldGetAccess(gfield)); 749566063dSJacob Faibussowitsch PetscCall(DMSwarmDataFieldGetEntries(gfield, (void **)&rankval)); 75df21e3a8SDave May p--; /* check replacement point */ 76df21e3a8SDave May } 77df21e3a8SDave May } 789566063dSJacob Faibussowitsch PetscCall(DMSwarmDataFieldRestoreEntries(gfield, (void **)&rankval)); 799566063dSJacob Faibussowitsch PetscCall(DMSwarmDataFieldRestoreAccess(gfield)); 80df21e3a8SDave May } 819566063dSJacob Faibussowitsch PetscCall(DMSwarmDataExBegin(de)); 829566063dSJacob Faibussowitsch PetscCall(DMSwarmDataExEnd(de)); 83835f2295SStefano Zampini PetscCall(DMSwarmDataExGetRecvData(de, &n_points_recv, &recv_points)); 849566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketGetSizes(swarm->db, &npoints, NULL, NULL)); 859566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketSetSizes(swarm->db, npoints + n_points_recv, DMSWARM_DATA_BUCKET_BUFFER_DEFAULT)); 86df21e3a8SDave May for (p = 0; p < n_points_recv; p++) { 87df21e3a8SDave May void *data_p = (void *)((char *)recv_points + p * sizeof_dmswarm_point); 88df21e3a8SDave May 899566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketInsertPackedArray(swarm->db, npoints + p, data_p)); 90df21e3a8SDave May } 91356ed814SMatthew G. Knepley if (debug) PetscCall(DMSwarmDataExView(de)); 929566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketDestroyPackedArray(swarm->db, &point_buffer)); 939566063dSJacob Faibussowitsch PetscCall(DMSwarmDataExDestroy(de)); 943ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 95df21e3a8SDave May } 962712d1f2SDave May 9766976f2fSJacob Faibussowitsch static PetscErrorCode DMSwarmMigrate_DMNeighborScatter(DM dm, DM dmcell, PetscBool remove_sent_points, PetscInt *npoints_prior_migration) 98d71ae5a4SJacob Faibussowitsch { 9940c453e9SDave May DM_Swarm *swarm = (DM_Swarm *)dm->data; 100*19307e5cSMatthew G. Knepley DMSwarmCellDM celldm; 10177048351SPatrick Sanan DMSwarmDataEx de; 1021f70fafbSZach Atkins PetscInt r, p, npoints, *p_cellid, n_points_recv; 10340c453e9SDave May PetscMPIInt rank, _rank; 10440c453e9SDave May const PetscMPIInt *neighbourranks; 10540c453e9SDave May void *point_buffer, *recv_points; 10640c453e9SDave May size_t sizeof_dmswarm_point; 10740c453e9SDave May PetscInt nneighbors; 1087c6d1d28SDave May PetscMPIInt mynneigh, *myneigh; 109*19307e5cSMatthew G. Knepley const char *cellid; 11040c453e9SDave May 111521f74f9SMatthew G. Knepley PetscFunctionBegin; 1129566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)dm), &rank)); 1139566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketGetSizes(swarm->db, &npoints, NULL, NULL)); 114*19307e5cSMatthew G. Knepley PetscCall(DMSwarmGetCellDMActive(dm, &celldm)); 115*19307e5cSMatthew G. Knepley PetscCall(DMSwarmCellDMGetCellID(celldm, &cellid)); 116*19307e5cSMatthew G. Knepley PetscCall(DMSwarmGetField(dm, cellid, NULL, NULL, (void **)&p_cellid)); 1179566063dSJacob Faibussowitsch PetscCall(DMSwarmDataExCreate(PetscObjectComm((PetscObject)dm), 0, &de)); 1189566063dSJacob Faibussowitsch PetscCall(DMGetNeighbors(dmcell, &nneighbors, &neighbourranks)); 1199566063dSJacob Faibussowitsch PetscCall(DMSwarmDataExTopologyInitialize(de)); 12040c453e9SDave May for (r = 0; r < nneighbors; r++) { 12140c453e9SDave May _rank = neighbourranks[r]; 12248a46eb9SPierre Jolivet if ((_rank != rank) && (_rank > 0)) PetscCall(DMSwarmDataExTopologyAddNeighbour(de, _rank)); 12340c453e9SDave May } 1249566063dSJacob Faibussowitsch PetscCall(DMSwarmDataExTopologyFinalize(de)); 1259566063dSJacob Faibussowitsch PetscCall(DMSwarmDataExTopologyGetNeighbours(de, &mynneigh, &myneigh)); 1269566063dSJacob Faibussowitsch PetscCall(DMSwarmDataExInitializeSendCount(de)); 12740c453e9SDave May for (p = 0; p < npoints; p++) { 1281f70fafbSZach Atkins if (p_cellid[p] == DMLOCATEPOINT_POINT_NOT_FOUND) { 1297c6d1d28SDave May for (r = 0; r < mynneigh; r++) { 1307c6d1d28SDave May _rank = myneigh[r]; 1319566063dSJacob Faibussowitsch PetscCall(DMSwarmDataExAddToSendCount(de, _rank, 1)); 13240c453e9SDave May } 13340c453e9SDave May } 13440c453e9SDave May } 1359566063dSJacob Faibussowitsch PetscCall(DMSwarmDataExFinalizeSendCount(de)); 1369566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketCreatePackedArray(swarm->db, &sizeof_dmswarm_point, &point_buffer)); 1379566063dSJacob Faibussowitsch PetscCall(DMSwarmDataExPackInitialize(de, sizeof_dmswarm_point)); 13840c453e9SDave May for (p = 0; p < npoints; p++) { 1391f70fafbSZach Atkins if (p_cellid[p] == DMLOCATEPOINT_POINT_NOT_FOUND) { 1407c6d1d28SDave May for (r = 0; r < mynneigh; r++) { 1417c6d1d28SDave May _rank = myneigh[r]; 14240c453e9SDave May /* copy point into buffer */ 1439566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketFillPackedArray(swarm->db, p, point_buffer)); 14477048351SPatrick Sanan /* insert point buffer into DMSwarmDataExchanger */ 1459566063dSJacob Faibussowitsch PetscCall(DMSwarmDataExPackData(de, _rank, 1, point_buffer)); 14640c453e9SDave May } 14740c453e9SDave May } 14840c453e9SDave May } 1499566063dSJacob Faibussowitsch PetscCall(DMSwarmDataExPackFinalize(de)); 150*19307e5cSMatthew G. Knepley PetscCall(DMSwarmRestoreField(dm, cellid, NULL, NULL, (void **)&p_cellid)); 15140c453e9SDave May if (remove_sent_points) { 15277048351SPatrick Sanan DMSwarmDataField PField; 1537c6d1d28SDave May 154*19307e5cSMatthew G. Knepley PetscCall(DMSwarmDataBucketGetDMSwarmDataFieldByName(swarm->db, cellid, &PField)); 1551f70fafbSZach Atkins PetscCall(DMSwarmDataFieldGetEntries(PField, (void **)&p_cellid)); 15640c453e9SDave May /* remove points which left processor */ 1579566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketGetSizes(swarm->db, &npoints, NULL, NULL)); 15840c453e9SDave May for (p = 0; p < npoints; p++) { 1591f70fafbSZach Atkins if (p_cellid[p] == DMLOCATEPOINT_POINT_NOT_FOUND) { 16040c453e9SDave May /* kill point */ 1619566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketRemovePointAtIndex(swarm->db, p)); 1629566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketGetSizes(swarm->db, &npoints, NULL, NULL)); /* you need to update npoints as the list size decreases! */ 1631f70fafbSZach Atkins PetscCall(DMSwarmDataFieldGetEntries(PField, (void **)&p_cellid)); /* update date point increase realloc performed */ 16440c453e9SDave May p--; /* check replacement point */ 16540c453e9SDave May } 16640c453e9SDave May } 16740c453e9SDave May } 1689566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketGetSizes(swarm->db, npoints_prior_migration, NULL, NULL)); 1699566063dSJacob Faibussowitsch PetscCall(DMSwarmDataExBegin(de)); 1709566063dSJacob Faibussowitsch PetscCall(DMSwarmDataExEnd(de)); 171835f2295SStefano Zampini PetscCall(DMSwarmDataExGetRecvData(de, &n_points_recv, &recv_points)); 1729566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketGetSizes(swarm->db, &npoints, NULL, NULL)); 1739566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketSetSizes(swarm->db, npoints + n_points_recv, DMSWARM_DATA_BUCKET_BUFFER_DEFAULT)); 17440c453e9SDave May for (p = 0; p < n_points_recv; p++) { 17540c453e9SDave May void *data_p = (void *)((char *)recv_points + p * sizeof_dmswarm_point); 17640c453e9SDave May 1779566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketInsertPackedArray(swarm->db, npoints + p, data_p)); 17840c453e9SDave May } 1799566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketDestroyPackedArray(swarm->db, &point_buffer)); 1809566063dSJacob Faibussowitsch PetscCall(DMSwarmDataExDestroy(de)); 1813ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 18240c453e9SDave May } 183480eef7bSDave May 184d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSwarmMigrate_CellDMScatter(DM dm, PetscBool remove_sent_points) 185d71ae5a4SJacob Faibussowitsch { 186480eef7bSDave May DM_Swarm *swarm = (DM_Swarm *)dm->data; 187*19307e5cSMatthew G. Knepley DMSwarmCellDM celldm; 188*19307e5cSMatthew G. Knepley PetscInt p, npoints, npointsg = 0, npoints2, npoints2g, *rankval, *p_cellid, npoints_prior_migration, Nfc; 189bbe8250bSMatthew G. Knepley PetscSF sfcell = NULL; 190dfc14de9SMatthew G. Knepley const PetscSFNode *LA_sfcell; 191480eef7bSDave May DM dmcell; 192480eef7bSDave May Vec pos; 19340c453e9SDave May PetscBool error_check = swarm->migrate_error_on_missing_point; 194*19307e5cSMatthew G. Knepley const char **coordFields; 195e4fbd051SBarry Smith PetscMPIInt size, rank; 196*19307e5cSMatthew G. Knepley const char *cellid; 197480eef7bSDave May 198521f74f9SMatthew G. Knepley PetscFunctionBegin; 1999566063dSJacob Faibussowitsch PetscCall(DMSwarmGetCellDM(dm, &dmcell)); 20028b400f6SJacob Faibussowitsch PetscCheck(dmcell, PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Only valid if cell DM provided"); 201*19307e5cSMatthew G. Knepley PetscCall(DMSwarmGetCellDMActive(dm, &celldm)); 202*19307e5cSMatthew G. Knepley PetscCall(DMSwarmCellDMGetCellID(celldm, &cellid)); 203480eef7bSDave May 2049566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)dm), &size)); 2059566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)dm), &rank)); 2067c6d1d28SDave May 20743a82f2bSDave May #if 1 20843a82f2bSDave May { 20943a82f2bSDave May PetscInt npoints_curr, range = 0; 21043a82f2bSDave May PetscSFNode *sf_cells; 21143a82f2bSDave May 2129566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketGetSizes(swarm->db, &npoints_curr, NULL, NULL)); 2139566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(npoints_curr, &sf_cells)); 21443a82f2bSDave May 215*19307e5cSMatthew G. Knepley PetscCall(DMSwarmGetField(dm, cellid, NULL, NULL, (void **)&p_cellid)); 21643a82f2bSDave May for (p = 0; p < npoints_curr; p++) { 21743a82f2bSDave May sf_cells[p].rank = 0; 21843a82f2bSDave May sf_cells[p].index = p_cellid[p]; 219ad540459SPierre Jolivet if (p_cellid[p] > range) range = p_cellid[p]; 22043a82f2bSDave May } 221*19307e5cSMatthew G. Knepley PetscCall(DMSwarmRestoreField(dm, cellid, NULL, NULL, (void **)&p_cellid)); 22243a82f2bSDave May 2239566063dSJacob Faibussowitsch /* PetscCall(PetscSFCreate(PetscObjectComm((PetscObject)dm),&sfcell)); */ 2249566063dSJacob Faibussowitsch PetscCall(PetscSFCreate(PETSC_COMM_SELF, &sfcell)); 2259566063dSJacob Faibussowitsch PetscCall(PetscSFSetGraph(sfcell, range, npoints_curr, NULL, PETSC_OWN_POINTER, sf_cells, PETSC_OWN_POINTER)); 22643a82f2bSDave May } 22743a82f2bSDave May #endif 22843a82f2bSDave May 229*19307e5cSMatthew G. Knepley PetscCall(DMSwarmCellDMGetCoordinateFields(celldm, &Nfc, &coordFields)); 230*19307e5cSMatthew G. Knepley PetscCall(DMSwarmCreateLocalVectorFromFields(dm, Nfc, coordFields, &pos)); 2319566063dSJacob Faibussowitsch PetscCall(DMLocatePoints(dmcell, pos, DM_POINTLOCATION_NONE, &sfcell)); 232*19307e5cSMatthew G. Knepley PetscCall(DMSwarmDestroyLocalVectorFromFields(dm, Nfc, coordFields, &pos)); 233480eef7bSDave May 23448a46eb9SPierre Jolivet if (error_check) PetscCall(DMSwarmGetSize(dm, &npointsg)); 2359566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketGetSizes(swarm->db, &npoints, NULL, NULL)); 236*19307e5cSMatthew G. Knepley PetscCall(DMSwarmGetField(dm, cellid, NULL, NULL, (void **)&p_cellid)); 2379566063dSJacob Faibussowitsch PetscCall(DMSwarmGetField(dm, DMSwarmField_rank, NULL, NULL, (void **)&rankval)); 2389566063dSJacob Faibussowitsch PetscCall(PetscSFGetGraph(sfcell, NULL, NULL, NULL, &LA_sfcell)); 2391f70fafbSZach Atkins 2401f70fafbSZach Atkins for (p = 0; p < npoints; p++) { 2411f70fafbSZach Atkins p_cellid[p] = LA_sfcell[p].index; 2421f70fafbSZach Atkins rankval[p] = rank; 2431f70fafbSZach Atkins } 2449566063dSJacob Faibussowitsch PetscCall(DMSwarmRestoreField(dm, DMSwarmField_rank, NULL, NULL, (void **)&rankval)); 245*19307e5cSMatthew G. Knepley PetscCall(DMSwarmRestoreField(dm, cellid, NULL, NULL, (void **)&p_cellid)); 2469566063dSJacob Faibussowitsch PetscCall(PetscSFDestroy(&sfcell)); 247480eef7bSDave May 248e4fbd051SBarry Smith if (size > 1) { 2499566063dSJacob Faibussowitsch PetscCall(DMSwarmMigrate_DMNeighborScatter(dm, dmcell, remove_sent_points, &npoints_prior_migration)); 2506fbf25f8SDave May } else { 25177048351SPatrick Sanan DMSwarmDataField PField; 2520ed23c7fSDave May PetscInt npoints_curr; 2530ed23c7fSDave May 2540ed23c7fSDave May /* remove points which the domain */ 255*19307e5cSMatthew G. Knepley PetscCall(DMSwarmDataBucketGetDMSwarmDataFieldByName(swarm->db, cellid, &PField)); 2561f70fafbSZach Atkins PetscCall(DMSwarmDataFieldGetEntries(PField, (void **)&p_cellid)); 2570ed23c7fSDave May 2589566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketGetSizes(swarm->db, &npoints_curr, NULL, NULL)); 2590ed23c7fSDave May for (p = 0; p < npoints_curr; p++) { 2601f70fafbSZach Atkins if (p_cellid[p] == DMLOCATEPOINT_POINT_NOT_FOUND) { 2610ed23c7fSDave May /* kill point */ 2629566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketRemovePointAtIndex(swarm->db, p)); 2639566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketGetSizes(swarm->db, &npoints_curr, NULL, NULL)); /* you need to update npoints as the list size decreases! */ 2641f70fafbSZach Atkins PetscCall(DMSwarmDataFieldGetEntries(PField, (void **)&p_cellid)); /* update date point in case realloc performed */ 2650ed23c7fSDave May p--; /* check replacement point */ 2660ed23c7fSDave May } 2670ed23c7fSDave May } 2681f70fafbSZach Atkins PetscCall(DMSwarmGetLocalSize(dm, &npoints_prior_migration)); 2696fbf25f8SDave May } 270480eef7bSDave May 2712d4ee042Sprj- /* locate points newly received */ 2729566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketGetSizes(swarm->db, &npoints2, NULL, NULL)); 273009b43efSDave May 2747c6d1d28SDave May #if 0 2752d4ee042Sprj- { /* safe alternative - however this performs two point locations on: (i) the initial points set and; (ii) the (initial + received) point set */ 2767c6d1d28SDave May PetscScalar *LA_coor; 2777c6d1d28SDave May PetscInt bs; 27877048351SPatrick Sanan DMSwarmDataField PField; 2797c6d1d28SDave May 280d52c2f21SMatthew G. Knepley PetscCall(DMSwarmGetField(dm,coordname,&bs,NULL,(void**)&LA_coor)); 2819566063dSJacob Faibussowitsch PetscCall(VecCreateSeqWithArray(PETSC_COMM_SELF,bs,bs*npoints2,(const PetscScalar*)LA_coor,&pos)); 2829566063dSJacob Faibussowitsch PetscCall(DMLocatePoints(dmcell,pos,DM_POINTLOCATION_NONE,&sfcell)); 2837c6d1d28SDave May 2849566063dSJacob Faibussowitsch PetscCall(VecDestroy(&pos)); 285d52c2f21SMatthew G. Knepley PetscCall(DMSwarmRestoreField(dm,coordname,&bs,NULL,(void**)&LA_coor)); 2867c6d1d28SDave May 2879566063dSJacob Faibussowitsch PetscCall(PetscSFGetGraph(sfcell, NULL, NULL, NULL, &LA_sfcell)); 2889566063dSJacob Faibussowitsch PetscCall(DMSwarmGetField(dm,DMSwarmField_rank,NULL,NULL,(void**)&rankval)); 2897c6d1d28SDave May for (p=0; p<npoints2; p++) { 290dfc14de9SMatthew G. Knepley rankval[p] = LA_sfcell[p].index; 2917c6d1d28SDave May } 2929566063dSJacob Faibussowitsch PetscCall(PetscSFDestroy(&sfcell)); 2939566063dSJacob Faibussowitsch PetscCall(DMSwarmRestoreField(dm,DMSwarmField_rank,NULL,NULL,(void**)&rankval)); 29440c453e9SDave May 2957c6d1d28SDave May /* remove points which left processor */ 2969566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketGetDMSwarmDataFieldByName(swarm->db,DMSwarmField_rank,&PField)); 2979566063dSJacob Faibussowitsch PetscCall(DMSwarmDataFieldGetEntries(PField,(void**)&rankval)); 2987c6d1d28SDave May 2999566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketGetSizes(swarm->db,&npoints2,NULL,NULL)); 3007c6d1d28SDave May for (p=0; p<npoints2; p++) { 301f954cb40SDave May if (rankval[p] == DMLOCATEPOINT_POINT_NOT_FOUND) { 3027c6d1d28SDave May /* kill point */ 3039566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketRemovePointAtIndex(swarm->db,p)); 3049566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketGetSizes(swarm->db,&npoints2,NULL,NULL)); /* you need to update npoints as the list size decreases! */ 3059566063dSJacob Faibussowitsch PetscCall(DMSwarmDataFieldGetEntries(PField,(void**)&rankval)); /* update date point increase realloc performed */ 3067c6d1d28SDave May p--; /* check replacement point */ 3077c6d1d28SDave May } 3087c6d1d28SDave May } 30940c453e9SDave May } 310009b43efSDave May #endif 311009b43efSDave May 3125627991aSBarry Smith { /* perform two point locations: (i) on the initial points set prior to communication; and (ii) on the new (received) points */ 313*19307e5cSMatthew G. Knepley Vec npos; 314*19307e5cSMatthew G. Knepley IS nis; 315009b43efSDave May PetscInt npoints_from_neighbours, bs; 31677048351SPatrick Sanan DMSwarmDataField PField; 317009b43efSDave May 318009b43efSDave May npoints_from_neighbours = npoints2 - npoints_prior_migration; 319009b43efSDave May 320*19307e5cSMatthew G. Knepley PetscCall(DMSwarmCreateLocalVectorFromFields(dm, Nfc, coordFields, &pos)); 321*19307e5cSMatthew G. Knepley PetscCall(VecGetBlockSize(pos, &bs)); 322*19307e5cSMatthew G. Knepley PetscCall(ISCreateStride(PETSC_COMM_SELF, npoints_from_neighbours * bs, npoints_prior_migration * bs, 1, &nis)); 323*19307e5cSMatthew G. Knepley PetscCall(VecGetSubVector(pos, nis, &npos)); 324*19307e5cSMatthew G. Knepley PetscCall(DMLocatePoints(dmcell, npos, DM_POINTLOCATION_NONE, &sfcell)); 325*19307e5cSMatthew G. Knepley PetscCall(VecRestoreSubVector(pos, nis, &npos)); 326*19307e5cSMatthew G. Knepley PetscCall(ISDestroy(&nis)); 327*19307e5cSMatthew G. Knepley PetscCall(DMSwarmDestroyLocalVectorFromFields(dm, Nfc, coordFields, &pos)); 328009b43efSDave May 3299566063dSJacob Faibussowitsch PetscCall(PetscSFGetGraph(sfcell, NULL, NULL, NULL, &LA_sfcell)); 3309566063dSJacob Faibussowitsch PetscCall(DMSwarmGetField(dm, DMSwarmField_rank, NULL, NULL, (void **)&rankval)); 331*19307e5cSMatthew G. Knepley PetscCall(DMSwarmGetField(dm, cellid, NULL, NULL, (void **)&p_cellid)); 3321f70fafbSZach Atkins for (p = 0; p < npoints_from_neighbours; p++) { 3331f70fafbSZach Atkins rankval[npoints_prior_migration + p] = rank; 3341f70fafbSZach Atkins p_cellid[npoints_prior_migration + p] = LA_sfcell[p].index; 3351f70fafbSZach Atkins } 3361f70fafbSZach Atkins 337*19307e5cSMatthew G. Knepley PetscCall(DMSwarmRestoreField(dm, cellid, NULL, NULL, (void **)&p_cellid)); 3389566063dSJacob Faibussowitsch PetscCall(DMSwarmRestoreField(dm, DMSwarmField_rank, NULL, NULL, (void **)&rankval)); 3399566063dSJacob Faibussowitsch PetscCall(PetscSFDestroy(&sfcell)); 340009b43efSDave May 341009b43efSDave May /* remove points which left processor */ 342*19307e5cSMatthew G. Knepley PetscCall(DMSwarmDataBucketGetDMSwarmDataFieldByName(swarm->db, cellid, &PField)); 3431f70fafbSZach Atkins PetscCall(DMSwarmDataFieldGetEntries(PField, (void **)&p_cellid)); 344009b43efSDave May 3459566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketGetSizes(swarm->db, &npoints2, NULL, NULL)); 346009b43efSDave May for (p = npoints_prior_migration; p < npoints2; p++) { 3471f70fafbSZach Atkins if (p_cellid[p] == DMLOCATEPOINT_POINT_NOT_FOUND) { 348009b43efSDave May /* kill point */ 3499566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketRemovePointAtIndex(swarm->db, p)); 3509566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketGetSizes(swarm->db, &npoints2, NULL, NULL)); /* you need to update npoints as the list size decreases! */ 3511f70fafbSZach Atkins PetscCall(DMSwarmDataFieldGetEntries(PField, (void **)&p_cellid)); /* update date point in case realloc performed */ 352009b43efSDave May p--; /* check replacement point */ 353009b43efSDave May } 354009b43efSDave May } 355009b43efSDave May } 356009b43efSDave May 35740c453e9SDave May /* check for error on removed points */ 35840c453e9SDave May if (error_check) { 3599566063dSJacob Faibussowitsch PetscCall(DMSwarmGetSize(dm, &npoints2g)); 36063a3b9bcSJacob Faibussowitsch PetscCheck(npointsg == npoints2g, PetscObjectComm((PetscObject)dm), PETSC_ERR_USER, "Points from the DMSwarm must remain constant during migration (initial %" PetscInt_FMT " - final %" PetscInt_FMT ")", npointsg, npoints2g); 36140c453e9SDave May } 3623ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 363480eef7bSDave May } 364480eef7bSDave May 365d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSwarmMigrate_CellDMExact(DM dm, PetscBool remove_sent_points) 366d71ae5a4SJacob Faibussowitsch { 367521f74f9SMatthew G. Knepley PetscFunctionBegin; 3683ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 36908056efcSDave May } 37008056efcSDave May 371480eef7bSDave May /* 372480eef7bSDave May Redundant as this assumes points can only be sent to a single rank 373480eef7bSDave May */ 374d71ae5a4SJacob Faibussowitsch PetscErrorCode DMSwarmMigrate_GlobalToLocal_Basic(DM dm, PetscInt *globalsize) 375d71ae5a4SJacob Faibussowitsch { 3762712d1f2SDave May DM_Swarm *swarm = (DM_Swarm *)dm->data; 37777048351SPatrick Sanan DMSwarmDataEx de; 3782712d1f2SDave May PetscInt p, npoints, *rankval, n_points_recv; 3792712d1f2SDave May PetscMPIInt rank, nrank, negrank; 3802712d1f2SDave May void *point_buffer, *recv_points; 3812712d1f2SDave May size_t sizeof_dmswarm_point; 3822712d1f2SDave May 383521f74f9SMatthew G. Knepley PetscFunctionBegin; 3849566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)dm), &rank)); 3859566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketGetSizes(swarm->db, &npoints, NULL, NULL)); 3862712d1f2SDave May *globalsize = npoints; 3879566063dSJacob Faibussowitsch PetscCall(DMSwarmGetField(dm, DMSwarmField_rank, NULL, NULL, (void **)&rankval)); 3889566063dSJacob Faibussowitsch PetscCall(DMSwarmDataExCreate(PetscObjectComm((PetscObject)dm), 0, &de)); 3899566063dSJacob Faibussowitsch PetscCall(DMSwarmDataExTopologyInitialize(de)); 3902712d1f2SDave May for (p = 0; p < npoints; p++) { 391835f2295SStefano Zampini PetscCall(PetscMPIIntCast(rankval[p], &negrank)); 3922712d1f2SDave May if (negrank < 0) { 3932712d1f2SDave May nrank = -negrank - 1; 3949566063dSJacob Faibussowitsch PetscCall(DMSwarmDataExTopologyAddNeighbour(de, nrank)); 3952712d1f2SDave May } 3962712d1f2SDave May } 3979566063dSJacob Faibussowitsch PetscCall(DMSwarmDataExTopologyFinalize(de)); 3989566063dSJacob Faibussowitsch PetscCall(DMSwarmDataExInitializeSendCount(de)); 3992712d1f2SDave May for (p = 0; p < npoints; p++) { 400835f2295SStefano Zampini PetscCall(PetscMPIIntCast(rankval[p], &negrank)); 4012712d1f2SDave May if (negrank < 0) { 4022712d1f2SDave May nrank = -negrank - 1; 4039566063dSJacob Faibussowitsch PetscCall(DMSwarmDataExAddToSendCount(de, nrank, 1)); 4042712d1f2SDave May } 4052712d1f2SDave May } 4069566063dSJacob Faibussowitsch PetscCall(DMSwarmDataExFinalizeSendCount(de)); 4079566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketCreatePackedArray(swarm->db, &sizeof_dmswarm_point, &point_buffer)); 4089566063dSJacob Faibussowitsch PetscCall(DMSwarmDataExPackInitialize(de, sizeof_dmswarm_point)); 4092712d1f2SDave May for (p = 0; p < npoints; p++) { 410835f2295SStefano Zampini PetscCall(PetscMPIIntCast(rankval[p], &negrank)); 4112712d1f2SDave May if (negrank < 0) { 4122712d1f2SDave May nrank = -negrank - 1; 4132712d1f2SDave May rankval[p] = nrank; 4142712d1f2SDave May /* copy point into buffer */ 4159566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketFillPackedArray(swarm->db, p, point_buffer)); 41677048351SPatrick Sanan /* insert point buffer into DMSwarmDataExchanger */ 4179566063dSJacob Faibussowitsch PetscCall(DMSwarmDataExPackData(de, nrank, 1, point_buffer)); 4182712d1f2SDave May rankval[p] = negrank; 4192712d1f2SDave May } 4202712d1f2SDave May } 4219566063dSJacob Faibussowitsch PetscCall(DMSwarmDataExPackFinalize(de)); 4229566063dSJacob Faibussowitsch PetscCall(DMSwarmRestoreField(dm, DMSwarmField_rank, NULL, NULL, (void **)&rankval)); 4239566063dSJacob Faibussowitsch PetscCall(DMSwarmDataExBegin(de)); 4249566063dSJacob Faibussowitsch PetscCall(DMSwarmDataExEnd(de)); 425835f2295SStefano Zampini PetscCall(DMSwarmDataExGetRecvData(de, &n_points_recv, &recv_points)); 4269566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketGetSizes(swarm->db, &npoints, NULL, NULL)); 4279566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketSetSizes(swarm->db, npoints + n_points_recv, DMSWARM_DATA_BUCKET_BUFFER_DEFAULT)); 4282712d1f2SDave May for (p = 0; p < n_points_recv; p++) { 4292712d1f2SDave May void *data_p = (void *)((char *)recv_points + p * sizeof_dmswarm_point); 4302712d1f2SDave May 4319566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketInsertPackedArray(swarm->db, npoints + p, data_p)); 4322712d1f2SDave May } 4339566063dSJacob Faibussowitsch PetscCall(DMSwarmDataExView(de)); 4349566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketDestroyPackedArray(swarm->db, &point_buffer)); 4359566063dSJacob Faibussowitsch PetscCall(DMSwarmDataExDestroy(de)); 4363ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4372712d1f2SDave May } 438b16650c8SDave May 439b16650c8SDave May typedef struct { 440b16650c8SDave May PetscMPIInt owner_rank; 441b16650c8SDave May PetscReal min[3], max[3]; 442b16650c8SDave May } CollectBBox; 443b16650c8SDave May 444d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode DMSwarmCollect_DMDABoundingBox(DM dm, PetscInt *globalsize) 445d71ae5a4SJacob Faibussowitsch { 446b16650c8SDave May DM_Swarm *swarm = (DM_Swarm *)dm->data; 44777048351SPatrick Sanan DMSwarmDataEx de; 448b16650c8SDave May PetscInt p, pk, npoints, *rankval, n_points_recv, n_bbox_recv, dim, neighbour_cells; 449b16650c8SDave May PetscMPIInt rank, nrank; 450b16650c8SDave May void *point_buffer, *recv_points; 451b16650c8SDave May size_t sizeof_dmswarm_point, sizeof_bbox_ctx; 452b16650c8SDave May PetscBool isdmda; 453b16650c8SDave May CollectBBox *bbox, *recv_bbox; 454b16650c8SDave May const PetscMPIInt *dmneighborranks; 455b16650c8SDave May DM dmcell; 456b16650c8SDave May 457521f74f9SMatthew G. Knepley PetscFunctionBegin; 4589566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)dm), &rank)); 459b16650c8SDave May 4609566063dSJacob Faibussowitsch PetscCall(DMSwarmGetCellDM(dm, &dmcell)); 46128b400f6SJacob Faibussowitsch PetscCheck(dmcell, PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Only valid if cell DM provided"); 462b16650c8SDave May isdmda = PETSC_FALSE; 4633ba16761SJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)dmcell, DMDA, &isdmda)); 46428b400f6SJacob Faibussowitsch PetscCheck(isdmda, PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Only DMDA support for CollectBoundingBox"); 465b16650c8SDave May 4669566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dm, &dim)); 467b16650c8SDave May sizeof_bbox_ctx = sizeof(CollectBBox); 4683ba16761SJacob Faibussowitsch PetscCall(PetscMalloc1(1, &bbox)); 469b16650c8SDave May bbox->owner_rank = rank; 470b16650c8SDave May 471b16650c8SDave May /* compute the bounding box based on the overlapping / stenctil size */ 472b16650c8SDave May { 473b16650c8SDave May Vec lcoor; 474b16650c8SDave May 4759566063dSJacob Faibussowitsch PetscCall(DMGetCoordinatesLocal(dmcell, &lcoor)); 476fe39f135SDave May if (dim >= 1) { 4779566063dSJacob Faibussowitsch PetscCall(VecStrideMin(lcoor, 0, NULL, &bbox->min[0])); 4789566063dSJacob Faibussowitsch PetscCall(VecStrideMax(lcoor, 0, NULL, &bbox->max[0])); 479fe39f135SDave May } 480fe39f135SDave May if (dim >= 2) { 4819566063dSJacob Faibussowitsch PetscCall(VecStrideMin(lcoor, 1, NULL, &bbox->min[1])); 4829566063dSJacob Faibussowitsch PetscCall(VecStrideMax(lcoor, 1, NULL, &bbox->max[1])); 483b16650c8SDave May } 484fe39f135SDave May if (dim == 3) { 4859566063dSJacob Faibussowitsch PetscCall(VecStrideMin(lcoor, 2, NULL, &bbox->min[2])); 4869566063dSJacob Faibussowitsch PetscCall(VecStrideMax(lcoor, 2, NULL, &bbox->max[2])); 487fe39f135SDave May } 488fe39f135SDave May } 4899566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketGetSizes(swarm->db, &npoints, NULL, NULL)); 490b16650c8SDave May *globalsize = npoints; 4919566063dSJacob Faibussowitsch PetscCall(DMSwarmGetField(dm, DMSwarmField_rank, NULL, NULL, (void **)&rankval)); 4929566063dSJacob Faibussowitsch PetscCall(DMSwarmDataExCreate(PetscObjectComm((PetscObject)dm), 0, &de)); 493b16650c8SDave May /* use DMDA neighbours */ 4949566063dSJacob Faibussowitsch PetscCall(DMDAGetNeighbors(dmcell, &dmneighborranks)); 4958dbd68bcSDave May if (dim == 1) { 4968dbd68bcSDave May neighbour_cells = 3; 4978dbd68bcSDave May } else if (dim == 2) { 4988dbd68bcSDave May neighbour_cells = 9; 4998dbd68bcSDave May } else { 5008dbd68bcSDave May neighbour_cells = 27; 5018dbd68bcSDave May } 5029566063dSJacob Faibussowitsch PetscCall(DMSwarmDataExTopologyInitialize(de)); 503b16650c8SDave May for (p = 0; p < neighbour_cells; p++) { 50448a46eb9SPierre Jolivet if ((dmneighborranks[p] >= 0) && (dmneighborranks[p] != rank)) PetscCall(DMSwarmDataExTopologyAddNeighbour(de, dmneighborranks[p])); 505b16650c8SDave May } 5069566063dSJacob Faibussowitsch PetscCall(DMSwarmDataExTopologyFinalize(de)); 5079566063dSJacob Faibussowitsch PetscCall(DMSwarmDataExInitializeSendCount(de)); 508b16650c8SDave May for (p = 0; p < neighbour_cells; p++) { 50948a46eb9SPierre Jolivet if ((dmneighborranks[p] >= 0) && (dmneighborranks[p] != rank)) PetscCall(DMSwarmDataExAddToSendCount(de, dmneighborranks[p], 1)); 510b16650c8SDave May } 5119566063dSJacob Faibussowitsch PetscCall(DMSwarmDataExFinalizeSendCount(de)); 512b16650c8SDave May /* send bounding boxes */ 5139566063dSJacob Faibussowitsch PetscCall(DMSwarmDataExPackInitialize(de, sizeof_bbox_ctx)); 514b16650c8SDave May for (p = 0; p < neighbour_cells; p++) { 515b16650c8SDave May nrank = dmneighborranks[p]; 516b16650c8SDave May if ((nrank >= 0) && (nrank != rank)) { 51777048351SPatrick Sanan /* insert bbox buffer into DMSwarmDataExchanger */ 5189566063dSJacob Faibussowitsch PetscCall(DMSwarmDataExPackData(de, nrank, 1, bbox)); 519b16650c8SDave May } 520b16650c8SDave May } 5219566063dSJacob Faibussowitsch PetscCall(DMSwarmDataExPackFinalize(de)); 522b16650c8SDave May /* recv bounding boxes */ 5239566063dSJacob Faibussowitsch PetscCall(DMSwarmDataExBegin(de)); 5249566063dSJacob Faibussowitsch PetscCall(DMSwarmDataExEnd(de)); 5259566063dSJacob Faibussowitsch PetscCall(DMSwarmDataExGetRecvData(de, &n_bbox_recv, (void **)&recv_bbox)); 526298827fbSBarry Smith /* Wrong, should not be using PETSC_COMM_WORLD */ 527b16650c8SDave May for (p = 0; p < n_bbox_recv; p++) { 5289371c9d4SSatish Balay PetscCall(PetscSynchronizedPrintf(PETSC_COMM_WORLD, "[rank %d]: box from %d : range[%+1.4e,%+1.4e]x[%+1.4e,%+1.4e]\n", rank, recv_bbox[p].owner_rank, (double)recv_bbox[p].min[0], (double)recv_bbox[p].max[0], (double)recv_bbox[p].min[1], 5299371c9d4SSatish Balay (double)recv_bbox[p].max[1])); 530b16650c8SDave May } 5319566063dSJacob Faibussowitsch PetscCall(PetscSynchronizedFlush(PETSC_COMM_WORLD, stdout)); 532b16650c8SDave May /* of course this is stupid as this "generic" function should have a better way to know what the coordinates are called */ 5339566063dSJacob Faibussowitsch PetscCall(DMSwarmDataExInitializeSendCount(de)); 534b16650c8SDave May for (pk = 0; pk < n_bbox_recv; pk++) { 535b16650c8SDave May PetscReal *array_x, *array_y; 536b16650c8SDave May 5379566063dSJacob Faibussowitsch PetscCall(DMSwarmGetField(dm, "coorx", NULL, NULL, (void **)&array_x)); 5389566063dSJacob Faibussowitsch PetscCall(DMSwarmGetField(dm, "coory", NULL, NULL, (void **)&array_y)); 539b16650c8SDave May for (p = 0; p < npoints; p++) { 540b16650c8SDave May if ((array_x[p] >= recv_bbox[pk].min[0]) && (array_x[p] <= recv_bbox[pk].max[0])) { 54148a46eb9SPierre Jolivet if ((array_y[p] >= recv_bbox[pk].min[1]) && (array_y[p] <= recv_bbox[pk].max[1])) PetscCall(DMSwarmDataExAddToSendCount(de, recv_bbox[pk].owner_rank, 1)); 542b16650c8SDave May } 543b16650c8SDave May } 5449566063dSJacob Faibussowitsch PetscCall(DMSwarmRestoreField(dm, "coory", NULL, NULL, (void **)&array_y)); 5459566063dSJacob Faibussowitsch PetscCall(DMSwarmRestoreField(dm, "coorx", NULL, NULL, (void **)&array_x)); 546b16650c8SDave May } 5479566063dSJacob Faibussowitsch PetscCall(DMSwarmDataExFinalizeSendCount(de)); 5489566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketCreatePackedArray(swarm->db, &sizeof_dmswarm_point, &point_buffer)); 5499566063dSJacob Faibussowitsch PetscCall(DMSwarmDataExPackInitialize(de, sizeof_dmswarm_point)); 550b16650c8SDave May for (pk = 0; pk < n_bbox_recv; pk++) { 551b16650c8SDave May PetscReal *array_x, *array_y; 552b16650c8SDave May 5539566063dSJacob Faibussowitsch PetscCall(DMSwarmGetField(dm, "coorx", NULL, NULL, (void **)&array_x)); 5549566063dSJacob Faibussowitsch PetscCall(DMSwarmGetField(dm, "coory", NULL, NULL, (void **)&array_y)); 555b16650c8SDave May for (p = 0; p < npoints; p++) { 556b16650c8SDave May if ((array_x[p] >= recv_bbox[pk].min[0]) && (array_x[p] <= recv_bbox[pk].max[0])) { 557b16650c8SDave May if ((array_y[p] >= recv_bbox[pk].min[1]) && (array_y[p] <= recv_bbox[pk].max[1])) { 558521f74f9SMatthew G. Knepley /* copy point into buffer */ 5599566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketFillPackedArray(swarm->db, p, point_buffer)); 56077048351SPatrick Sanan /* insert point buffer into DMSwarmDataExchanger */ 5619566063dSJacob Faibussowitsch PetscCall(DMSwarmDataExPackData(de, recv_bbox[pk].owner_rank, 1, point_buffer)); 562b16650c8SDave May } 563b16650c8SDave May } 564b16650c8SDave May } 5659566063dSJacob Faibussowitsch PetscCall(DMSwarmRestoreField(dm, "coory", NULL, NULL, (void **)&array_y)); 5669566063dSJacob Faibussowitsch PetscCall(DMSwarmRestoreField(dm, "coorx", NULL, NULL, (void **)&array_x)); 567b16650c8SDave May } 5689566063dSJacob Faibussowitsch PetscCall(DMSwarmDataExPackFinalize(de)); 5699566063dSJacob Faibussowitsch PetscCall(DMSwarmRestoreField(dm, DMSwarmField_rank, NULL, NULL, (void **)&rankval)); 5709566063dSJacob Faibussowitsch PetscCall(DMSwarmDataExBegin(de)); 5719566063dSJacob Faibussowitsch PetscCall(DMSwarmDataExEnd(de)); 572835f2295SStefano Zampini PetscCall(DMSwarmDataExGetRecvData(de, &n_points_recv, &recv_points)); 5739566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketGetSizes(swarm->db, &npoints, NULL, NULL)); 5749566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketSetSizes(swarm->db, npoints + n_points_recv, DMSWARM_DATA_BUCKET_BUFFER_DEFAULT)); 575b16650c8SDave May for (p = 0; p < n_points_recv; p++) { 576b16650c8SDave May void *data_p = (void *)((char *)recv_points + p * sizeof_dmswarm_point); 577b16650c8SDave May 5789566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketInsertPackedArray(swarm->db, npoints + p, data_p)); 579b16650c8SDave May } 5809566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketDestroyPackedArray(swarm->db, &point_buffer)); 581e57ab8abSSatish Balay PetscCall(PetscFree(bbox)); 5829566063dSJacob Faibussowitsch PetscCall(DMSwarmDataExView(de)); 5839566063dSJacob Faibussowitsch PetscCall(DMSwarmDataExDestroy(de)); 5843ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 585b16650c8SDave May } 586a9fd7477SDave May 587a9fd7477SDave May /* General collection when no order, or neighbour information is provided */ 588a9fd7477SDave May /* 589a9fd7477SDave May User provides context and collect() method 590a9fd7477SDave May Broadcast user context 591a9fd7477SDave May 592a9fd7477SDave May for each context / rank { 593a9fd7477SDave May collect(swarm,context,n,list) 594a9fd7477SDave May } 595a9fd7477SDave May */ 596d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode DMSwarmCollect_General(DM dm, PetscErrorCode (*collect)(DM, void *, PetscInt *, PetscInt **), size_t ctx_size, void *ctx, PetscInt *globalsize) 597d71ae5a4SJacob Faibussowitsch { 598a9fd7477SDave May DM_Swarm *swarm = (DM_Swarm *)dm->data; 59977048351SPatrick Sanan DMSwarmDataEx de; 6006497c311SBarry Smith PetscInt p, npoints, n_points_recv; 6016497c311SBarry Smith PetscMPIInt size, rank, len; 602a9fd7477SDave May void *point_buffer, *recv_points; 603a9fd7477SDave May void *ctxlist; 604a9fd7477SDave May PetscInt *n2collect, **collectlist; 605a9fd7477SDave May size_t sizeof_dmswarm_point; 606a9fd7477SDave May 607521f74f9SMatthew G. Knepley PetscFunctionBegin; 6089566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)dm), &size)); 6099566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)dm), &rank)); 6109566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketGetSizes(swarm->db, &npoints, NULL, NULL)); 611a9fd7477SDave May *globalsize = npoints; 612a9fd7477SDave May /* Broadcast user context */ 6136497c311SBarry Smith PetscCall(PetscMPIIntCast(ctx_size, &len)); 6143ba16761SJacob Faibussowitsch PetscCall(PetscMalloc(ctx_size * size, &ctxlist)); 6156497c311SBarry Smith PetscCallMPI(MPI_Allgather(ctx, len, MPI_CHAR, ctxlist, len, MPI_CHAR, PetscObjectComm((PetscObject)dm))); 6169566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(size, &n2collect)); 6179566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(size, &collectlist)); 6186497c311SBarry Smith for (PetscMPIInt r = 0; r < size; r++) { 619a9fd7477SDave May PetscInt _n2collect; 620a9fd7477SDave May PetscInt *_collectlist; 621a9fd7477SDave May void *_ctx_r; 622a9fd7477SDave May 623a9fd7477SDave May _n2collect = 0; 624a9fd7477SDave May _collectlist = NULL; 625a9fd7477SDave May if (r != rank) { /* don't collect data from yourself */ 626a9fd7477SDave May _ctx_r = (void *)((char *)ctxlist + r * ctx_size); 6279566063dSJacob Faibussowitsch PetscCall(collect(dm, _ctx_r, &_n2collect, &_collectlist)); 628a9fd7477SDave May } 629a9fd7477SDave May n2collect[r] = _n2collect; 630a9fd7477SDave May collectlist[r] = _collectlist; 631a9fd7477SDave May } 6329566063dSJacob Faibussowitsch PetscCall(DMSwarmDataExCreate(PetscObjectComm((PetscObject)dm), 0, &de)); 633a9fd7477SDave May /* Define topology */ 6349566063dSJacob Faibussowitsch PetscCall(DMSwarmDataExTopologyInitialize(de)); 6356497c311SBarry Smith for (PetscMPIInt r = 0; r < size; r++) { 636835f2295SStefano Zampini if (n2collect[r] > 0) PetscCall(DMSwarmDataExTopologyAddNeighbour(de, r)); 637a9fd7477SDave May } 6389566063dSJacob Faibussowitsch PetscCall(DMSwarmDataExTopologyFinalize(de)); 639a9fd7477SDave May /* Define send counts */ 6409566063dSJacob Faibussowitsch PetscCall(DMSwarmDataExInitializeSendCount(de)); 6416497c311SBarry Smith for (PetscMPIInt r = 0; r < size; r++) { 64248a46eb9SPierre Jolivet if (n2collect[r] > 0) PetscCall(DMSwarmDataExAddToSendCount(de, r, n2collect[r])); 643a9fd7477SDave May } 6449566063dSJacob Faibussowitsch PetscCall(DMSwarmDataExFinalizeSendCount(de)); 645a9fd7477SDave May /* Pack data */ 6469566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketCreatePackedArray(swarm->db, &sizeof_dmswarm_point, &point_buffer)); 6479566063dSJacob Faibussowitsch PetscCall(DMSwarmDataExPackInitialize(de, sizeof_dmswarm_point)); 6486497c311SBarry Smith for (PetscMPIInt r = 0; r < size; r++) { 649a9fd7477SDave May for (p = 0; p < n2collect[r]; p++) { 6509566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketFillPackedArray(swarm->db, collectlist[r][p], point_buffer)); 651a9fd7477SDave May /* insert point buffer into the data exchanger */ 6529566063dSJacob Faibussowitsch PetscCall(DMSwarmDataExPackData(de, r, 1, point_buffer)); 653a9fd7477SDave May } 654a9fd7477SDave May } 6559566063dSJacob Faibussowitsch PetscCall(DMSwarmDataExPackFinalize(de)); 656a9fd7477SDave May /* Scatter */ 6579566063dSJacob Faibussowitsch PetscCall(DMSwarmDataExBegin(de)); 6589566063dSJacob Faibussowitsch PetscCall(DMSwarmDataExEnd(de)); 659a9fd7477SDave May /* Collect data in DMSwarm container */ 660835f2295SStefano Zampini PetscCall(DMSwarmDataExGetRecvData(de, &n_points_recv, &recv_points)); 6619566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketGetSizes(swarm->db, &npoints, NULL, NULL)); 6629566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketSetSizes(swarm->db, npoints + n_points_recv, DMSWARM_DATA_BUCKET_BUFFER_DEFAULT)); 663a9fd7477SDave May for (p = 0; p < n_points_recv; p++) { 664a9fd7477SDave May void *data_p = (void *)((char *)recv_points + p * sizeof_dmswarm_point); 665a9fd7477SDave May 6669566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketInsertPackedArray(swarm->db, npoints + p, data_p)); 667a9fd7477SDave May } 668a9fd7477SDave May /* Release memory */ 6696497c311SBarry Smith for (PetscMPIInt r = 0; r < size; r++) { 670e57ab8abSSatish Balay if (collectlist[r]) PetscCall(PetscFree(collectlist[r])); 671a9fd7477SDave May } 6729566063dSJacob Faibussowitsch PetscCall(PetscFree(collectlist)); 6739566063dSJacob Faibussowitsch PetscCall(PetscFree(n2collect)); 6749566063dSJacob Faibussowitsch PetscCall(PetscFree(ctxlist)); 6759566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketDestroyPackedArray(swarm->db, &point_buffer)); 6769566063dSJacob Faibussowitsch PetscCall(DMSwarmDataExView(de)); 6779566063dSJacob Faibussowitsch PetscCall(DMSwarmDataExDestroy(de)); 6783ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 679a9fd7477SDave May } 68047ce4f4bSMatthew G. Knepley 68147ce4f4bSMatthew G. Knepley /*@ 68247ce4f4bSMatthew G. Knepley DMSwarmGetMigrateType - Get the style of point migration 68347ce4f4bSMatthew G. Knepley 68420f4b53cSBarry Smith Logically Collective 68547ce4f4bSMatthew G. Knepley 68660225df5SJacob Faibussowitsch Input Parameter: 68720f4b53cSBarry Smith . dm - the `DMSWARM` 68847ce4f4bSMatthew G. Knepley 68960225df5SJacob Faibussowitsch Output Parameter: 69020f4b53cSBarry Smith . mtype - The migration type, see `DMSwarmMigrateType` 69147ce4f4bSMatthew G. Knepley 69247ce4f4bSMatthew G. Knepley Level: intermediate 69347ce4f4bSMatthew G. Knepley 69442747ad1SJacob Faibussowitsch .seealso: `DM`, `DMSWARM`, `DMSwarmMigrateType`, `DMSwarmMigrate()` 69547ce4f4bSMatthew G. Knepley @*/ 69647ce4f4bSMatthew G. Knepley PetscErrorCode DMSwarmGetMigrateType(DM dm, DMSwarmMigrateType *mtype) 69747ce4f4bSMatthew G. Knepley { 69847ce4f4bSMatthew G. Knepley PetscFunctionBegin; 69947ce4f4bSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 7004f572ea9SToby Isaac PetscAssertPointer(mtype, 2); 70147ce4f4bSMatthew G. Knepley *mtype = ((DM_Swarm *)dm->data)->migrate_type; 7023ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 70347ce4f4bSMatthew G. Knepley } 70447ce4f4bSMatthew G. Knepley 70547ce4f4bSMatthew G. Knepley /*@ 70647ce4f4bSMatthew G. Knepley DMSwarmSetMigrateType - Set the style of point migration 70747ce4f4bSMatthew G. Knepley 70820f4b53cSBarry Smith Logically Collective 70947ce4f4bSMatthew G. Knepley 71060225df5SJacob Faibussowitsch Input Parameters: 71120f4b53cSBarry Smith + dm - the `DMSWARM` 71220f4b53cSBarry Smith - mtype - The migration type, see `DMSwarmMigrateType` 71347ce4f4bSMatthew G. Knepley 71447ce4f4bSMatthew G. Knepley Level: intermediate 71547ce4f4bSMatthew G. Knepley 71660225df5SJacob Faibussowitsch .seealso: `DM`, `DMSWARM`, `DMSwarmMigrateType`, `DMSwarmGetMigrateType()`, `DMSwarmMigrate()` 71747ce4f4bSMatthew G. Knepley @*/ 71847ce4f4bSMatthew G. Knepley PetscErrorCode DMSwarmSetMigrateType(DM dm, DMSwarmMigrateType mtype) 71947ce4f4bSMatthew G. Knepley { 72047ce4f4bSMatthew G. Knepley PetscFunctionBegin; 72147ce4f4bSMatthew G. Knepley PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 72247ce4f4bSMatthew G. Knepley PetscValidLogicalCollectiveInt(dm, mtype, 2); 72347ce4f4bSMatthew G. Knepley ((DM_Swarm *)dm->data)->migrate_type = mtype; 7243ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 72547ce4f4bSMatthew G. Knepley } 726