157795646SDave May #define PETSCDM_DLL 257795646SDave May #include <petsc/private/dmswarmimpl.h> /*I "petscdmswarm.h" I*/ 3e8f14785SLisandro Dalcin #include <petsc/private/hashsetij.h> 40643ed39SMatthew G. Knepley #include <petsc/private/petscfeimpl.h> 55917a6f0SStefano Zampini #include <petscviewer.h> 65917a6f0SStefano Zampini #include <petscdraw.h> 783c47955SMatthew G. Knepley #include <petscdmplex.h> 84cc7f7b2SMatthew G. Knepley #include <petscblaslapack.h> 9279f676cSBarry Smith #include "../src/dm/impls/swarm/data_bucket.h" 10d0c080abSJoseph Pusztay #include <petscdmlabel.h> 11d0c080abSJoseph Pusztay #include <petscsection.h> 1257795646SDave May 13f2b2bee7SDave May PetscLogEvent DMSWARM_Migrate, DMSWARM_SetSizes, DMSWARM_AddPoints, DMSWARM_RemovePoints, DMSWARM_Sort; 14ed923d71SDave May PetscLogEvent DMSWARM_DataExchangerTopologySetup, DMSWARM_DataExchangerBegin, DMSWARM_DataExchangerEnd; 15ed923d71SDave May PetscLogEvent DMSWARM_DataExchangerSendCount, DMSWARM_DataExchangerPack; 16ed923d71SDave May 17ea78f98cSLisandro Dalcin const char *DMSwarmTypeNames[] = {"basic", "pic", NULL}; 18ea78f98cSLisandro Dalcin const char *DMSwarmMigrateTypeNames[] = {"basic", "dmcellnscatter", "dmcellexact", "user", NULL}; 19ea78f98cSLisandro Dalcin const char *DMSwarmCollectTypeNames[] = {"basic", "boundingbox", "general", "user", NULL}; 20ea78f98cSLisandro Dalcin const char *DMSwarmPICLayoutTypeNames[] = {"regular", "gauss", "subdivision", NULL}; 21f0cdbbbaSDave May 22f0cdbbbaSDave May const char DMSwarmField_pid[] = "DMSwarm_pid"; 23f0cdbbbaSDave May const char DMSwarmField_rank[] = "DMSwarm_rank"; 24f0cdbbbaSDave May const char DMSwarmPICField_coor[] = "DMSwarmPIC_coor"; 25e2d107dbSDave May const char DMSwarmPICField_cellid[] = "DMSwarm_cellid"; 26f0cdbbbaSDave May 272e956fe4SStefano Zampini PetscInt SwarmDataFieldId = -1; 282e956fe4SStefano Zampini 2974d0cae8SMatthew G. Knepley #if defined(PETSC_HAVE_HDF5) 3074d0cae8SMatthew G. Knepley #include <petscviewerhdf5.h> 3174d0cae8SMatthew G. Knepley 329371c9d4SSatish Balay PetscErrorCode VecView_Swarm_HDF5_Internal(Vec v, PetscViewer viewer) { 3374d0cae8SMatthew G. Knepley DM dm; 3474d0cae8SMatthew G. Knepley PetscReal seqval; 3574d0cae8SMatthew G. Knepley PetscInt seqnum, bs; 3674d0cae8SMatthew G. Knepley PetscBool isseq; 3774d0cae8SMatthew G. Knepley 3874d0cae8SMatthew G. Knepley PetscFunctionBegin; 399566063dSJacob Faibussowitsch PetscCall(VecGetDM(v, &dm)); 409566063dSJacob Faibussowitsch PetscCall(VecGetBlockSize(v, &bs)); 419566063dSJacob Faibussowitsch PetscCall(PetscViewerHDF5PushGroup(viewer, "/particle_fields")); 429566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)v, VECSEQ, &isseq)); 439566063dSJacob Faibussowitsch PetscCall(DMGetOutputSequenceNumber(dm, &seqnum, &seqval)); 449566063dSJacob Faibussowitsch PetscCall(PetscViewerHDF5SetTimestep(viewer, seqnum)); 459566063dSJacob Faibussowitsch /* PetscCall(DMSequenceView_HDF5(dm, "time", seqnum, (PetscScalar) seqval, viewer)); */ 469566063dSJacob Faibussowitsch PetscCall(VecViewNative(v, viewer)); 479566063dSJacob Faibussowitsch PetscCall(PetscViewerHDF5WriteObjectAttribute(viewer, (PetscObject)v, "Nc", PETSC_INT, (void *)&bs)); 489566063dSJacob Faibussowitsch PetscCall(PetscViewerHDF5PopGroup(viewer)); 4974d0cae8SMatthew G. Knepley PetscFunctionReturn(0); 5074d0cae8SMatthew G. Knepley } 5174d0cae8SMatthew G. Knepley 529371c9d4SSatish Balay PetscErrorCode DMSwarmView_HDF5(DM dm, PetscViewer viewer) { 5374d0cae8SMatthew G. Knepley Vec coordinates; 5474d0cae8SMatthew G. Knepley PetscInt Np; 5574d0cae8SMatthew G. Knepley PetscBool isseq; 5674d0cae8SMatthew G. Knepley 5774d0cae8SMatthew G. Knepley PetscFunctionBegin; 589566063dSJacob Faibussowitsch PetscCall(DMSwarmGetSize(dm, &Np)); 599566063dSJacob Faibussowitsch PetscCall(DMSwarmCreateGlobalVectorFromField(dm, DMSwarmPICField_coor, &coordinates)); 609566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)coordinates, "coordinates")); 619566063dSJacob Faibussowitsch PetscCall(PetscViewerHDF5PushGroup(viewer, "/particles")); 629566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)coordinates, VECSEQ, &isseq)); 639566063dSJacob Faibussowitsch PetscCall(VecViewNative(coordinates, viewer)); 649566063dSJacob Faibussowitsch PetscCall(PetscViewerHDF5WriteObjectAttribute(viewer, (PetscObject)coordinates, "Np", PETSC_INT, (void *)&Np)); 659566063dSJacob Faibussowitsch PetscCall(PetscViewerHDF5PopGroup(viewer)); 669566063dSJacob Faibussowitsch PetscCall(DMSwarmDestroyGlobalVectorFromField(dm, DMSwarmPICField_coor, &coordinates)); 6774d0cae8SMatthew G. Knepley PetscFunctionReturn(0); 6874d0cae8SMatthew G. Knepley } 6974d0cae8SMatthew G. Knepley #endif 7074d0cae8SMatthew G. Knepley 719371c9d4SSatish Balay PetscErrorCode VecView_Swarm(Vec v, PetscViewer viewer) { 7274d0cae8SMatthew G. Knepley DM dm; 73f9558f5cSBarry Smith #if defined(PETSC_HAVE_HDF5) 7474d0cae8SMatthew G. Knepley PetscBool ishdf5; 75f9558f5cSBarry Smith #endif 7674d0cae8SMatthew G. Knepley 7774d0cae8SMatthew G. Knepley PetscFunctionBegin; 789566063dSJacob Faibussowitsch PetscCall(VecGetDM(v, &dm)); 7928b400f6SJacob Faibussowitsch PetscCheck(dm, PetscObjectComm((PetscObject)v), PETSC_ERR_ARG_WRONG, "Vector not generated from a DM"); 80f9558f5cSBarry Smith #if defined(PETSC_HAVE_HDF5) 819566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5, &ishdf5)); 8274d0cae8SMatthew G. Knepley if (ishdf5) { 839566063dSJacob Faibussowitsch PetscCall(VecView_Swarm_HDF5_Internal(v, viewer)); 84f9558f5cSBarry Smith PetscFunctionReturn(0); 8574d0cae8SMatthew G. Knepley } 86f9558f5cSBarry Smith #endif 879566063dSJacob Faibussowitsch PetscCall(VecViewNative(v, viewer)); 8874d0cae8SMatthew G. Knepley PetscFunctionReturn(0); 8974d0cae8SMatthew G. Knepley } 9074d0cae8SMatthew G. Knepley 91d3a51819SDave May /*@C 9262741f57SDave May DMSwarmVectorDefineField - Sets the field from which to define a Vec object 9362741f57SDave May when DMCreateLocalVector(), or DMCreateGlobalVector() is called 9457795646SDave May 95d083f849SBarry Smith Collective on dm 9657795646SDave May 97d3a51819SDave May Input parameters: 9862741f57SDave May + dm - a DMSwarm 9962741f57SDave May - fieldname - the textual name given to a registered field 10057795646SDave May 101d3a51819SDave May Level: beginner 10257795646SDave May 103d3a51819SDave May Notes: 104e7af74c8SDave May 10562741f57SDave May The field with name fieldname must be defined as having a data type of PetscScalar. 106e7af74c8SDave May 107d3a51819SDave May This function must be called prior to calling DMCreateLocalVector(), DMCreateGlobalVector(). 108d3a51819SDave May Mutiple calls to DMSwarmVectorDefineField() are permitted. 10957795646SDave May 110db781477SPatrick Sanan .seealso: `DMSwarmRegisterPetscDatatypeField()`, `DMCreateGlobalVector()`, `DMCreateLocalVector()` 111d3a51819SDave May @*/ 1129371c9d4SSatish Balay PetscErrorCode DMSwarmVectorDefineField(DM dm, const char fieldname[]) { 113b5bcf523SDave May DM_Swarm *swarm = (DM_Swarm *)dm->data; 114b5bcf523SDave May PetscInt bs, n; 115b5bcf523SDave May PetscScalar *array; 116b5bcf523SDave May PetscDataType type; 117b5bcf523SDave May 118a9cbaee5SMatthew G. Knepley PetscFunctionBegin; 1199566063dSJacob Faibussowitsch if (!swarm->issetup) PetscCall(DMSetUp(dm)); 1209566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketGetSizes(swarm->db, &n, NULL, NULL)); 1219566063dSJacob Faibussowitsch PetscCall(DMSwarmGetField(dm, fieldname, &bs, &type, (void **)&array)); 122b5bcf523SDave May 123b5bcf523SDave May /* Check all fields are of type PETSC_REAL or PETSC_SCALAR */ 12408401ef6SPierre Jolivet PetscCheck(type == PETSC_REAL, PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Only valid for PETSC_REAL"); 1259566063dSJacob Faibussowitsch PetscCall(PetscSNPrintf(swarm->vec_field_name, PETSC_MAX_PATH_LEN - 1, "%s", fieldname)); 126b5bcf523SDave May swarm->vec_field_set = PETSC_TRUE; 1271b1ea282SDave May swarm->vec_field_bs = bs; 128b5bcf523SDave May swarm->vec_field_nlocal = n; 1299566063dSJacob Faibussowitsch PetscCall(DMSwarmRestoreField(dm, fieldname, &bs, &type, (void **)&array)); 130b5bcf523SDave May PetscFunctionReturn(0); 131b5bcf523SDave May } 132b5bcf523SDave May 133cc651181SDave May /* requires DMSwarmDefineFieldVector has been called */ 1349371c9d4SSatish Balay PetscErrorCode DMCreateGlobalVector_Swarm(DM dm, Vec *vec) { 135b5bcf523SDave May DM_Swarm *swarm = (DM_Swarm *)dm->data; 136b5bcf523SDave May Vec x; 137b5bcf523SDave May char name[PETSC_MAX_PATH_LEN]; 138b5bcf523SDave May 139a9cbaee5SMatthew G. Knepley PetscFunctionBegin; 1409566063dSJacob Faibussowitsch if (!swarm->issetup) PetscCall(DMSetUp(dm)); 14128b400f6SJacob Faibussowitsch PetscCheck(swarm->vec_field_set, PetscObjectComm((PetscObject)dm), PETSC_ERR_USER, "Must call DMSwarmVectorDefineField first"); 14208401ef6SPierre Jolivet PetscCheck(swarm->vec_field_nlocal == swarm->db->L, PetscObjectComm((PetscObject)dm), PETSC_ERR_USER, "DMSwarm sizes have changed since last call to VectorDefineField first"); /* Stale data */ 143cc651181SDave May 1449566063dSJacob Faibussowitsch PetscCall(PetscSNPrintf(name, PETSC_MAX_PATH_LEN - 1, "DMSwarmField_%s", swarm->vec_field_name)); 1459566063dSJacob Faibussowitsch PetscCall(VecCreate(PetscObjectComm((PetscObject)dm), &x)); 1469566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)x, name)); 1479566063dSJacob Faibussowitsch PetscCall(VecSetSizes(x, swarm->db->L * swarm->vec_field_bs, PETSC_DETERMINE)); 1489566063dSJacob Faibussowitsch PetscCall(VecSetBlockSize(x, swarm->vec_field_bs)); 1499566063dSJacob Faibussowitsch PetscCall(VecSetDM(x, dm)); 1509566063dSJacob Faibussowitsch PetscCall(VecSetFromOptions(x)); 1519566063dSJacob Faibussowitsch PetscCall(VecSetDM(x, dm)); 1529566063dSJacob Faibussowitsch PetscCall(VecSetOperation(x, VECOP_VIEW, (void (*)(void))VecView_Swarm)); 153b5bcf523SDave May *vec = x; 154b5bcf523SDave May PetscFunctionReturn(0); 155b5bcf523SDave May } 156b5bcf523SDave May 157b5bcf523SDave May /* requires DMSwarmDefineFieldVector has been called */ 1589371c9d4SSatish Balay PetscErrorCode DMCreateLocalVector_Swarm(DM dm, Vec *vec) { 159b5bcf523SDave May DM_Swarm *swarm = (DM_Swarm *)dm->data; 160b5bcf523SDave May Vec x; 161b5bcf523SDave May char name[PETSC_MAX_PATH_LEN]; 162b5bcf523SDave May 163a9cbaee5SMatthew G. Knepley PetscFunctionBegin; 1649566063dSJacob Faibussowitsch if (!swarm->issetup) PetscCall(DMSetUp(dm)); 16528b400f6SJacob Faibussowitsch PetscCheck(swarm->vec_field_set, PetscObjectComm((PetscObject)dm), PETSC_ERR_USER, "Must call DMSwarmVectorDefineField first"); 16608401ef6SPierre Jolivet PetscCheck(swarm->vec_field_nlocal == swarm->db->L, PetscObjectComm((PetscObject)dm), PETSC_ERR_USER, "DMSwarm sizes have changed since last call to VectorDefineField first"); 167cc651181SDave May 1689566063dSJacob Faibussowitsch PetscCall(PetscSNPrintf(name, PETSC_MAX_PATH_LEN - 1, "DMSwarmField_%s", swarm->vec_field_name)); 1699566063dSJacob Faibussowitsch PetscCall(VecCreate(PETSC_COMM_SELF, &x)); 1709566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)x, name)); 1719566063dSJacob Faibussowitsch PetscCall(VecSetSizes(x, swarm->db->L * swarm->vec_field_bs, PETSC_DETERMINE)); 1729566063dSJacob Faibussowitsch PetscCall(VecSetBlockSize(x, swarm->vec_field_bs)); 1739566063dSJacob Faibussowitsch PetscCall(VecSetDM(x, dm)); 1749566063dSJacob Faibussowitsch PetscCall(VecSetFromOptions(x)); 175b5bcf523SDave May *vec = x; 176b5bcf523SDave May PetscFunctionReturn(0); 177b5bcf523SDave May } 178b5bcf523SDave May 1799371c9d4SSatish Balay static PetscErrorCode DMSwarmDestroyVectorFromField_Private(DM dm, const char fieldname[], Vec *vec) { 180fb1bcc12SMatthew G. Knepley DM_Swarm *swarm = (DM_Swarm *)dm->data; 18177048351SPatrick Sanan DMSwarmDataField gfield; 1822e956fe4SStefano Zampini PetscInt bs, nlocal, fid = -1, cfid = -2; 1832e956fe4SStefano Zampini PetscBool flg; 184d3a51819SDave May 185fb1bcc12SMatthew G. Knepley PetscFunctionBegin; 1862e956fe4SStefano Zampini /* check vector is an inplace array */ 1872e956fe4SStefano Zampini PetscCall(DMSwarmDataBucketGetDMSwarmDataFieldIdByName(swarm->db, fieldname, &fid)); 1882e956fe4SStefano Zampini PetscCall(PetscObjectComposedDataGetInt((PetscObject)*vec, SwarmDataFieldId, cfid, flg)); 1892e956fe4SStefano Zampini PetscCheck(cfid == fid, PetscObjectComm((PetscObject)dm), PETSC_ERR_USER, "Vector being destroyed was not created from DMSwarm field(%s)! %" PetscInt_FMT " != %" PetscInt_FMT "", fieldname, cfid, fid); 1909566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(*vec, &nlocal)); 1919566063dSJacob Faibussowitsch PetscCall(VecGetBlockSize(*vec, &bs)); 19208401ef6SPierre Jolivet PetscCheck(nlocal / bs == swarm->db->L, PetscObjectComm((PetscObject)dm), PETSC_ERR_USER, "DMSwarm sizes have changed since vector was created - cannot ensure pointers are valid"); 1939566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketGetDMSwarmDataFieldByName(swarm->db, fieldname, &gfield)); 1949566063dSJacob Faibussowitsch PetscCall(DMSwarmDataFieldRestoreAccess(gfield)); 1958df78e51SMark Adams PetscCall(VecResetArray(*vec)); 1969566063dSJacob Faibussowitsch PetscCall(VecDestroy(vec)); 197fb1bcc12SMatthew G. Knepley PetscFunctionReturn(0); 198fb1bcc12SMatthew G. Knepley } 199fb1bcc12SMatthew G. Knepley 2009371c9d4SSatish Balay static PetscErrorCode DMSwarmCreateVectorFromField_Private(DM dm, const char fieldname[], MPI_Comm comm, Vec *vec) { 201fb1bcc12SMatthew G. Knepley DM_Swarm *swarm = (DM_Swarm *)dm->data; 202fb1bcc12SMatthew G. Knepley PetscDataType type; 203fb1bcc12SMatthew G. Knepley PetscScalar *array; 2042e956fe4SStefano Zampini PetscInt bs, n, fid; 205fb1bcc12SMatthew G. Knepley char name[PETSC_MAX_PATH_LEN]; 206e4fbd051SBarry Smith PetscMPIInt size; 2078df78e51SMark Adams PetscBool iscuda, iskokkos; 208fb1bcc12SMatthew G. Knepley 209fb1bcc12SMatthew G. Knepley PetscFunctionBegin; 2109566063dSJacob Faibussowitsch if (!swarm->issetup) PetscCall(DMSetUp(dm)); 2119566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketGetSizes(swarm->db, &n, NULL, NULL)); 2129566063dSJacob Faibussowitsch PetscCall(DMSwarmGetField(dm, fieldname, &bs, &type, (void **)&array)); 21308401ef6SPierre Jolivet PetscCheck(type == PETSC_REAL, PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Only valid for PETSC_REAL"); 214fb1bcc12SMatthew G. Knepley 2159566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(comm, &size)); 2168df78e51SMark Adams PetscCall(PetscStrcmp(dm->vectype, VECKOKKOS, &iskokkos)); 2178df78e51SMark Adams PetscCall(PetscStrcmp(dm->vectype, VECCUDA, &iscuda)); 2188df78e51SMark Adams PetscCall(VecCreate(comm, vec)); 2198df78e51SMark Adams PetscCall(VecSetSizes(*vec, n * bs, PETSC_DETERMINE)); 2208df78e51SMark Adams PetscCall(VecSetBlockSize(*vec, bs)); 2218df78e51SMark Adams if (iskokkos) PetscCall(VecSetType(*vec, VECKOKKOS)); 2228df78e51SMark Adams else if (iscuda) PetscCall(VecSetType(*vec, VECCUDA)); 2238df78e51SMark Adams else PetscCall(VecSetType(*vec, VECSTANDARD)); 2248df78e51SMark Adams PetscCall(VecPlaceArray(*vec, array)); 2258df78e51SMark Adams 2269566063dSJacob Faibussowitsch PetscCall(PetscSNPrintf(name, PETSC_MAX_PATH_LEN - 1, "DMSwarmSharedField_%s", fieldname)); 2279566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)*vec, name)); 228fb1bcc12SMatthew G. Knepley 229fb1bcc12SMatthew G. Knepley /* Set guard */ 2302e956fe4SStefano Zampini PetscCall(DMSwarmDataBucketGetDMSwarmDataFieldIdByName(swarm->db, fieldname, &fid)); 2312e956fe4SStefano Zampini PetscCall(PetscObjectComposedDataSetInt((PetscObject)*vec, SwarmDataFieldId, fid)); 23274d0cae8SMatthew G. Knepley 2339566063dSJacob Faibussowitsch PetscCall(VecSetDM(*vec, dm)); 2349566063dSJacob Faibussowitsch PetscCall(VecSetOperation(*vec, VECOP_VIEW, (void (*)(void))VecView_Swarm)); 235fb1bcc12SMatthew G. Knepley PetscFunctionReturn(0); 236fb1bcc12SMatthew G. Knepley } 237fb1bcc12SMatthew G. Knepley 2380643ed39SMatthew G. Knepley /* This creates a "mass matrix" between a finite element and particle space. If a finite element interpolant is given by 2390643ed39SMatthew G. Knepley 2400643ed39SMatthew G. Knepley \hat f = \sum_i f_i \phi_i 2410643ed39SMatthew G. Knepley 2420643ed39SMatthew G. Knepley and a particle function is given by 2430643ed39SMatthew G. Knepley 2440643ed39SMatthew G. Knepley f = \sum_i w_i \delta(x - x_i) 2450643ed39SMatthew G. Knepley 2460643ed39SMatthew G. Knepley then we want to require that 2470643ed39SMatthew G. Knepley 2480643ed39SMatthew G. Knepley M \hat f = M_p f 2490643ed39SMatthew G. Knepley 2500643ed39SMatthew G. Knepley where the particle mass matrix is given by 2510643ed39SMatthew G. Knepley 2520643ed39SMatthew G. Knepley (M_p)_{ij} = \int \phi_i \delta(x - x_j) 2530643ed39SMatthew G. Knepley 2540643ed39SMatthew G. Knepley The way Dave May does particles, they amount to quadratue weights rather than delta functions, so he has |J| is in 2550643ed39SMatthew G. Knepley his integral. We allow this with the boolean flag. 2560643ed39SMatthew G. Knepley */ 2579371c9d4SSatish Balay static PetscErrorCode DMSwarmComputeMassMatrix_Private(DM dmc, DM dmf, Mat mass, PetscBool useDeltaFunction, void *ctx) { 25883c47955SMatthew G. Knepley const char *name = "Mass Matrix"; 2590643ed39SMatthew G. Knepley MPI_Comm comm; 26083c47955SMatthew G. Knepley PetscDS prob; 26183c47955SMatthew G. Knepley PetscSection fsection, globalFSection; 262e8f14785SLisandro Dalcin PetscHSetIJ ht; 2630643ed39SMatthew G. Knepley PetscLayout rLayout, colLayout; 26483c47955SMatthew G. Knepley PetscInt *dnz, *onz; 265adb2528bSMark Adams PetscInt locRows, locCols, rStart, colStart, colEnd, *rowIDXs; 2660643ed39SMatthew G. Knepley PetscReal *xi, *v0, *J, *invJ, detJ = 1.0, v0ref[3] = {-1.0, -1.0, -1.0}; 26783c47955SMatthew G. Knepley PetscScalar *elemMat; 2680643ed39SMatthew G. Knepley PetscInt dim, Nf, field, cStart, cEnd, cell, totDim, maxC = 0; 26983c47955SMatthew G. Knepley 27083c47955SMatthew G. Knepley PetscFunctionBegin; 2719566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)mass, &comm)); 2729566063dSJacob Faibussowitsch PetscCall(DMGetCoordinateDim(dmf, &dim)); 2739566063dSJacob Faibussowitsch PetscCall(DMGetDS(dmf, &prob)); 2749566063dSJacob Faibussowitsch PetscCall(PetscDSGetNumFields(prob, &Nf)); 2759566063dSJacob Faibussowitsch PetscCall(PetscDSGetTotalDimension(prob, &totDim)); 2769566063dSJacob Faibussowitsch PetscCall(PetscMalloc3(dim, &v0, dim * dim, &J, dim * dim, &invJ)); 2779566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dmf, &fsection)); 2789566063dSJacob Faibussowitsch PetscCall(DMGetGlobalSection(dmf, &globalFSection)); 2799566063dSJacob Faibussowitsch PetscCall(DMPlexGetHeightStratum(dmf, 0, &cStart, &cEnd)); 2809566063dSJacob Faibussowitsch PetscCall(MatGetLocalSize(mass, &locRows, &locCols)); 28183c47955SMatthew G. Knepley 2829566063dSJacob Faibussowitsch PetscCall(PetscLayoutCreate(comm, &colLayout)); 2839566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetLocalSize(colLayout, locCols)); 2849566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetBlockSize(colLayout, 1)); 2859566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(colLayout)); 2869566063dSJacob Faibussowitsch PetscCall(PetscLayoutGetRange(colLayout, &colStart, &colEnd)); 2879566063dSJacob Faibussowitsch PetscCall(PetscLayoutDestroy(&colLayout)); 2880643ed39SMatthew G. Knepley 2899566063dSJacob Faibussowitsch PetscCall(PetscLayoutCreate(comm, &rLayout)); 2909566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetLocalSize(rLayout, locRows)); 2919566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetBlockSize(rLayout, 1)); 2929566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(rLayout)); 2939566063dSJacob Faibussowitsch PetscCall(PetscLayoutGetRange(rLayout, &rStart, NULL)); 2949566063dSJacob Faibussowitsch PetscCall(PetscLayoutDestroy(&rLayout)); 2950643ed39SMatthew G. Knepley 2969566063dSJacob Faibussowitsch PetscCall(PetscCalloc2(locRows, &dnz, locRows, &onz)); 2979566063dSJacob Faibussowitsch PetscCall(PetscHSetIJCreate(&ht)); 29853e60ab4SJoseph Pusztay 2999566063dSJacob Faibussowitsch PetscCall(PetscSynchronizedFlush(comm, NULL)); 3000643ed39SMatthew G. Knepley /* count non-zeros */ 3019566063dSJacob Faibussowitsch PetscCall(DMSwarmSortGetAccess(dmc)); 30283c47955SMatthew G. Knepley for (field = 0; field < Nf; ++field) { 30383c47955SMatthew G. Knepley for (cell = cStart; cell < cEnd; ++cell) { 3040643ed39SMatthew G. Knepley PetscInt c, i; 3050643ed39SMatthew G. Knepley PetscInt *findices, *cindices; /* fine is vertices, coarse is particles */ 30683c47955SMatthew G. Knepley PetscInt numFIndices, numCIndices; 30783c47955SMatthew G. Knepley 3089566063dSJacob Faibussowitsch PetscCall(DMPlexGetClosureIndices(dmf, fsection, globalFSection, cell, PETSC_FALSE, &numFIndices, &findices, NULL, NULL)); 3099566063dSJacob Faibussowitsch PetscCall(DMSwarmSortGetPointsPerCell(dmc, cell, &numCIndices, &cindices)); 310fc7c92abSMatthew G. Knepley maxC = PetscMax(maxC, numCIndices); 31183c47955SMatthew G. Knepley { 312e8f14785SLisandro Dalcin PetscHashIJKey key; 313e8f14785SLisandro Dalcin PetscBool missing; 31483c47955SMatthew G. Knepley for (i = 0; i < numFIndices; ++i) { 315adb2528bSMark Adams key.j = findices[i]; /* global column (from Plex) */ 316adb2528bSMark Adams if (key.j >= 0) { 31783c47955SMatthew G. Knepley /* Get indices for coarse elements */ 31883c47955SMatthew G. Knepley for (c = 0; c < numCIndices; ++c) { 319adb2528bSMark Adams key.i = cindices[c] + rStart; /* global cols (from Swarm) */ 320adb2528bSMark Adams if (key.i < 0) continue; 3219566063dSJacob Faibussowitsch PetscCall(PetscHSetIJQueryAdd(ht, key, &missing)); 32283c47955SMatthew G. Knepley if (missing) { 3230643ed39SMatthew G. Knepley if ((key.j >= colStart) && (key.j < colEnd)) ++dnz[key.i - rStart]; 324e8f14785SLisandro Dalcin else ++onz[key.i - rStart]; 32563a3b9bcSJacob Faibussowitsch } else SETERRQ(PetscObjectComm((PetscObject)dmf), PETSC_ERR_SUP, "Set new value at %" PetscInt_FMT ",%" PetscInt_FMT, key.i, key.j); 32683c47955SMatthew G. Knepley } 327fc7c92abSMatthew G. Knepley } 328fc7c92abSMatthew G. Knepley } 3299566063dSJacob Faibussowitsch PetscCall(PetscFree(cindices)); 33083c47955SMatthew G. Knepley } 3319566063dSJacob Faibussowitsch PetscCall(DMPlexRestoreClosureIndices(dmf, fsection, globalFSection, cell, PETSC_FALSE, &numFIndices, &findices, NULL, NULL)); 33283c47955SMatthew G. Knepley } 33383c47955SMatthew G. Knepley } 3349566063dSJacob Faibussowitsch PetscCall(PetscHSetIJDestroy(&ht)); 3359566063dSJacob Faibussowitsch PetscCall(MatXAIJSetPreallocation(mass, 1, dnz, onz, NULL, NULL)); 3369566063dSJacob Faibussowitsch PetscCall(MatSetOption(mass, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_TRUE)); 3379566063dSJacob Faibussowitsch PetscCall(PetscFree2(dnz, onz)); 3389566063dSJacob Faibussowitsch PetscCall(PetscMalloc3(maxC * totDim, &elemMat, maxC, &rowIDXs, maxC * dim, &xi)); 33983c47955SMatthew G. Knepley for (field = 0; field < Nf; ++field) { 340ef0bb6c7SMatthew G. Knepley PetscTabulation Tcoarse; 34183c47955SMatthew G. Knepley PetscObject obj; 342ef0bb6c7SMatthew G. Knepley PetscReal *coords; 3430643ed39SMatthew G. Knepley PetscInt Nc, i; 34483c47955SMatthew G. Knepley 3459566063dSJacob Faibussowitsch PetscCall(PetscDSGetDiscretization(prob, field, &obj)); 3469566063dSJacob Faibussowitsch PetscCall(PetscFEGetNumComponents((PetscFE)obj, &Nc)); 34763a3b9bcSJacob Faibussowitsch PetscCheck(Nc == 1, PetscObjectComm((PetscObject)dmf), PETSC_ERR_SUP, "Can only interpolate a scalar field from particles, Nc = %" PetscInt_FMT, Nc); 3489566063dSJacob Faibussowitsch PetscCall(DMSwarmGetField(dmc, DMSwarmPICField_coor, NULL, NULL, (void **)&coords)); 34983c47955SMatthew G. Knepley for (cell = cStart; cell < cEnd; ++cell) { 35083c47955SMatthew G. Knepley PetscInt *findices, *cindices; 35183c47955SMatthew G. Knepley PetscInt numFIndices, numCIndices; 3520643ed39SMatthew G. Knepley PetscInt p, c; 35383c47955SMatthew G. Knepley 3540643ed39SMatthew G. Knepley /* TODO: Use DMField instead of assuming affine */ 3559566063dSJacob Faibussowitsch PetscCall(DMPlexComputeCellGeometryFEM(dmf, cell, NULL, v0, J, invJ, &detJ)); 3569566063dSJacob Faibussowitsch PetscCall(DMPlexGetClosureIndices(dmf, fsection, globalFSection, cell, PETSC_FALSE, &numFIndices, &findices, NULL, NULL)); 3579566063dSJacob Faibussowitsch PetscCall(DMSwarmSortGetPointsPerCell(dmc, cell, &numCIndices, &cindices)); 358ad540459SPierre Jolivet for (p = 0; p < numCIndices; ++p) CoordinatesRealToRef(dim, dim, v0ref, v0, invJ, &coords[cindices[p] * dim], &xi[p * dim]); 3599566063dSJacob Faibussowitsch PetscCall(PetscFECreateTabulation((PetscFE)obj, 1, numCIndices, xi, 0, &Tcoarse)); 36083c47955SMatthew G. Knepley /* Get elemMat entries by multiplying by weight */ 3619566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(elemMat, numCIndices * totDim)); 36283c47955SMatthew G. Knepley for (i = 0; i < numFIndices; ++i) { 3630643ed39SMatthew G. Knepley for (p = 0; p < numCIndices; ++p) { 3640643ed39SMatthew G. Knepley for (c = 0; c < Nc; ++c) { 3650643ed39SMatthew G. Knepley /* B[(p*pdim + i)*Nc + c] is the value at point p for basis function i and component c */ 366ef0bb6c7SMatthew G. Knepley elemMat[p * numFIndices + i] += Tcoarse->T[0][(p * numFIndices + i) * Nc + c] * (useDeltaFunction ? 1.0 : detJ); 36783c47955SMatthew G. Knepley } 3680643ed39SMatthew G. Knepley } 3690643ed39SMatthew G. Knepley } 370adb2528bSMark Adams for (p = 0; p < numCIndices; ++p) rowIDXs[p] = cindices[p] + rStart; 3719566063dSJacob Faibussowitsch if (0) PetscCall(DMPrintCellMatrix(cell, name, 1, numCIndices, elemMat)); 3729566063dSJacob Faibussowitsch PetscCall(MatSetValues(mass, numCIndices, rowIDXs, numFIndices, findices, elemMat, ADD_VALUES)); 3739566063dSJacob Faibussowitsch PetscCall(PetscFree(cindices)); 3749566063dSJacob Faibussowitsch PetscCall(DMPlexRestoreClosureIndices(dmf, fsection, globalFSection, cell, PETSC_FALSE, &numFIndices, &findices, NULL, NULL)); 3759566063dSJacob Faibussowitsch PetscCall(PetscTabulationDestroy(&Tcoarse)); 37683c47955SMatthew G. Knepley } 3779566063dSJacob Faibussowitsch PetscCall(DMSwarmRestoreField(dmc, DMSwarmPICField_coor, NULL, NULL, (void **)&coords)); 37883c47955SMatthew G. Knepley } 3799566063dSJacob Faibussowitsch PetscCall(PetscFree3(elemMat, rowIDXs, xi)); 3809566063dSJacob Faibussowitsch PetscCall(DMSwarmSortRestoreAccess(dmc)); 3819566063dSJacob Faibussowitsch PetscCall(PetscFree3(v0, J, invJ)); 3829566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(mass, MAT_FINAL_ASSEMBLY)); 3839566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(mass, MAT_FINAL_ASSEMBLY)); 38483c47955SMatthew G. Knepley PetscFunctionReturn(0); 38583c47955SMatthew G. Knepley } 38683c47955SMatthew G. Knepley 387d0c080abSJoseph Pusztay /* Returns empty matrix for use with SNES FD */ 3889371c9d4SSatish Balay static PetscErrorCode DMCreateMatrix_Swarm(DM sw, Mat *m) { 389d0c080abSJoseph Pusztay Vec field; 390d0c080abSJoseph Pusztay PetscInt size; 391d0c080abSJoseph Pusztay 392d0c080abSJoseph Pusztay PetscFunctionBegin; 3939566063dSJacob Faibussowitsch PetscCall(DMGetGlobalVector(sw, &field)); 3949566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(field, &size)); 3959566063dSJacob Faibussowitsch PetscCall(DMRestoreGlobalVector(sw, &field)); 3969566063dSJacob Faibussowitsch PetscCall(MatCreate(PETSC_COMM_WORLD, m)); 3979566063dSJacob Faibussowitsch PetscCall(MatSetFromOptions(*m)); 3989566063dSJacob Faibussowitsch PetscCall(MatSetSizes(*m, PETSC_DECIDE, PETSC_DECIDE, size, size)); 3999566063dSJacob Faibussowitsch PetscCall(MatSeqAIJSetPreallocation(*m, 1, NULL)); 4009566063dSJacob Faibussowitsch PetscCall(MatZeroEntries(*m)); 4019566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(*m, MAT_FINAL_ASSEMBLY)); 4029566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(*m, MAT_FINAL_ASSEMBLY)); 4039566063dSJacob Faibussowitsch PetscCall(MatShift(*m, 1.0)); 4049566063dSJacob Faibussowitsch PetscCall(MatSetDM(*m, sw)); 405d0c080abSJoseph Pusztay PetscFunctionReturn(0); 406d0c080abSJoseph Pusztay } 407d0c080abSJoseph Pusztay 408adb2528bSMark Adams /* FEM cols, Particle rows */ 4099371c9d4SSatish Balay static PetscErrorCode DMCreateMassMatrix_Swarm(DM dmCoarse, DM dmFine, Mat *mass) { 410895a1698SMatthew G. Knepley PetscSection gsf; 41183c47955SMatthew G. Knepley PetscInt m, n; 41283c47955SMatthew G. Knepley void *ctx; 41383c47955SMatthew G. Knepley 41483c47955SMatthew G. Knepley PetscFunctionBegin; 4159566063dSJacob Faibussowitsch PetscCall(DMGetGlobalSection(dmFine, &gsf)); 4169566063dSJacob Faibussowitsch PetscCall(PetscSectionGetConstrainedStorageSize(gsf, &m)); 4179566063dSJacob Faibussowitsch PetscCall(DMSwarmGetLocalSize(dmCoarse, &n)); 4189566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)dmCoarse), mass)); 4199566063dSJacob Faibussowitsch PetscCall(MatSetSizes(*mass, n, m, PETSC_DETERMINE, PETSC_DETERMINE)); 4209566063dSJacob Faibussowitsch PetscCall(MatSetType(*mass, dmCoarse->mattype)); 4219566063dSJacob Faibussowitsch PetscCall(DMGetApplicationContext(dmFine, &ctx)); 42283c47955SMatthew G. Knepley 4239566063dSJacob Faibussowitsch PetscCall(DMSwarmComputeMassMatrix_Private(dmCoarse, dmFine, *mass, PETSC_TRUE, ctx)); 4249566063dSJacob Faibussowitsch PetscCall(MatViewFromOptions(*mass, NULL, "-mass_mat_view")); 42583c47955SMatthew G. Knepley PetscFunctionReturn(0); 42683c47955SMatthew G. Knepley } 42783c47955SMatthew G. Knepley 4289371c9d4SSatish Balay static PetscErrorCode DMSwarmComputeMassMatrixSquare_Private(DM dmc, DM dmf, Mat mass, PetscBool useDeltaFunction, void *ctx) { 4294cc7f7b2SMatthew G. Knepley const char *name = "Mass Matrix Square"; 4304cc7f7b2SMatthew G. Knepley MPI_Comm comm; 4314cc7f7b2SMatthew G. Knepley PetscDS prob; 4324cc7f7b2SMatthew G. Knepley PetscSection fsection, globalFSection; 4334cc7f7b2SMatthew G. Knepley PetscHSetIJ ht; 4344cc7f7b2SMatthew G. Knepley PetscLayout rLayout, colLayout; 4354cc7f7b2SMatthew G. Knepley PetscInt *dnz, *onz, *adj, depth, maxConeSize, maxSupportSize, maxAdjSize; 4364cc7f7b2SMatthew G. Knepley PetscInt locRows, locCols, rStart, colStart, colEnd, *rowIDXs; 4374cc7f7b2SMatthew G. Knepley PetscReal *xi, *v0, *J, *invJ, detJ = 1.0, v0ref[3] = {-1.0, -1.0, -1.0}; 4384cc7f7b2SMatthew G. Knepley PetscScalar *elemMat, *elemMatSq; 4394cc7f7b2SMatthew G. Knepley PetscInt cdim, Nf, field, cStart, cEnd, cell, totDim, maxC = 0; 4404cc7f7b2SMatthew G. Knepley 4414cc7f7b2SMatthew G. Knepley PetscFunctionBegin; 4429566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)mass, &comm)); 4439566063dSJacob Faibussowitsch PetscCall(DMGetCoordinateDim(dmf, &cdim)); 4449566063dSJacob Faibussowitsch PetscCall(DMGetDS(dmf, &prob)); 4459566063dSJacob Faibussowitsch PetscCall(PetscDSGetNumFields(prob, &Nf)); 4469566063dSJacob Faibussowitsch PetscCall(PetscDSGetTotalDimension(prob, &totDim)); 4479566063dSJacob Faibussowitsch PetscCall(PetscMalloc3(cdim, &v0, cdim * cdim, &J, cdim * cdim, &invJ)); 4489566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dmf, &fsection)); 4499566063dSJacob Faibussowitsch PetscCall(DMGetGlobalSection(dmf, &globalFSection)); 4509566063dSJacob Faibussowitsch PetscCall(DMPlexGetHeightStratum(dmf, 0, &cStart, &cEnd)); 4519566063dSJacob Faibussowitsch PetscCall(MatGetLocalSize(mass, &locRows, &locCols)); 4524cc7f7b2SMatthew G. Knepley 4539566063dSJacob Faibussowitsch PetscCall(PetscLayoutCreate(comm, &colLayout)); 4549566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetLocalSize(colLayout, locCols)); 4559566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetBlockSize(colLayout, 1)); 4569566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(colLayout)); 4579566063dSJacob Faibussowitsch PetscCall(PetscLayoutGetRange(colLayout, &colStart, &colEnd)); 4589566063dSJacob Faibussowitsch PetscCall(PetscLayoutDestroy(&colLayout)); 4594cc7f7b2SMatthew G. Knepley 4609566063dSJacob Faibussowitsch PetscCall(PetscLayoutCreate(comm, &rLayout)); 4619566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetLocalSize(rLayout, locRows)); 4629566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetBlockSize(rLayout, 1)); 4639566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(rLayout)); 4649566063dSJacob Faibussowitsch PetscCall(PetscLayoutGetRange(rLayout, &rStart, NULL)); 4659566063dSJacob Faibussowitsch PetscCall(PetscLayoutDestroy(&rLayout)); 4664cc7f7b2SMatthew G. Knepley 4679566063dSJacob Faibussowitsch PetscCall(DMPlexGetDepth(dmf, &depth)); 4689566063dSJacob Faibussowitsch PetscCall(DMPlexGetMaxSizes(dmf, &maxConeSize, &maxSupportSize)); 4694cc7f7b2SMatthew G. Knepley maxAdjSize = PetscPowInt(maxConeSize * maxSupportSize, depth); 4709566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(maxAdjSize, &adj)); 4714cc7f7b2SMatthew G. Knepley 4729566063dSJacob Faibussowitsch PetscCall(PetscCalloc2(locRows, &dnz, locRows, &onz)); 4739566063dSJacob Faibussowitsch PetscCall(PetscHSetIJCreate(&ht)); 4744cc7f7b2SMatthew G. Knepley /* Count nonzeros 4754cc7f7b2SMatthew G. Knepley This is just FVM++, but we cannot use the Plex P0 allocation since unknowns in a cell will not be contiguous 4764cc7f7b2SMatthew G. Knepley */ 4779566063dSJacob Faibussowitsch PetscCall(DMSwarmSortGetAccess(dmc)); 4784cc7f7b2SMatthew G. Knepley for (cell = cStart; cell < cEnd; ++cell) { 4794cc7f7b2SMatthew G. Knepley PetscInt i; 4804cc7f7b2SMatthew G. Knepley PetscInt *cindices; 4814cc7f7b2SMatthew G. Knepley PetscInt numCIndices; 4824cc7f7b2SMatthew G. Knepley #if 0 4834cc7f7b2SMatthew G. Knepley PetscInt adjSize = maxAdjSize, a, j; 4844cc7f7b2SMatthew G. Knepley #endif 4854cc7f7b2SMatthew G. Knepley 4869566063dSJacob Faibussowitsch PetscCall(DMSwarmSortGetPointsPerCell(dmc, cell, &numCIndices, &cindices)); 4874cc7f7b2SMatthew G. Knepley maxC = PetscMax(maxC, numCIndices); 4884cc7f7b2SMatthew G. Knepley /* Diagonal block */ 489ad540459SPierre Jolivet for (i = 0; i < numCIndices; ++i) dnz[cindices[i]] += numCIndices; 4904cc7f7b2SMatthew G. Knepley #if 0 4914cc7f7b2SMatthew G. Knepley /* Off-diagonal blocks */ 4929566063dSJacob Faibussowitsch PetscCall(DMPlexGetAdjacency(dmf, cell, &adjSize, &adj)); 4934cc7f7b2SMatthew G. Knepley for (a = 0; a < adjSize; ++a) { 4944cc7f7b2SMatthew G. Knepley if (adj[a] >= cStart && adj[a] < cEnd && adj[a] != cell) { 4954cc7f7b2SMatthew G. Knepley const PetscInt ncell = adj[a]; 4964cc7f7b2SMatthew G. Knepley PetscInt *ncindices; 4974cc7f7b2SMatthew G. Knepley PetscInt numNCIndices; 4984cc7f7b2SMatthew G. Knepley 4999566063dSJacob Faibussowitsch PetscCall(DMSwarmSortGetPointsPerCell(dmc, ncell, &numNCIndices, &ncindices)); 5004cc7f7b2SMatthew G. Knepley { 5014cc7f7b2SMatthew G. Knepley PetscHashIJKey key; 5024cc7f7b2SMatthew G. Knepley PetscBool missing; 5034cc7f7b2SMatthew G. Knepley 5044cc7f7b2SMatthew G. Knepley for (i = 0; i < numCIndices; ++i) { 5054cc7f7b2SMatthew G. Knepley key.i = cindices[i] + rStart; /* global rows (from Swarm) */ 5064cc7f7b2SMatthew G. Knepley if (key.i < 0) continue; 5074cc7f7b2SMatthew G. Knepley for (j = 0; j < numNCIndices; ++j) { 5084cc7f7b2SMatthew G. Knepley key.j = ncindices[j] + rStart; /* global column (from Swarm) */ 5094cc7f7b2SMatthew G. Knepley if (key.j < 0) continue; 5109566063dSJacob Faibussowitsch PetscCall(PetscHSetIJQueryAdd(ht, key, &missing)); 5114cc7f7b2SMatthew G. Knepley if (missing) { 5124cc7f7b2SMatthew G. Knepley if ((key.j >= colStart) && (key.j < colEnd)) ++dnz[key.i - rStart]; 5134cc7f7b2SMatthew G. Knepley else ++onz[key.i - rStart]; 5144cc7f7b2SMatthew G. Knepley } 5154cc7f7b2SMatthew G. Knepley } 5164cc7f7b2SMatthew G. Knepley } 5174cc7f7b2SMatthew G. Knepley } 5189566063dSJacob Faibussowitsch PetscCall(PetscFree(ncindices)); 5194cc7f7b2SMatthew G. Knepley } 5204cc7f7b2SMatthew G. Knepley } 5214cc7f7b2SMatthew G. Knepley #endif 5229566063dSJacob Faibussowitsch PetscCall(PetscFree(cindices)); 5234cc7f7b2SMatthew G. Knepley } 5249566063dSJacob Faibussowitsch PetscCall(PetscHSetIJDestroy(&ht)); 5259566063dSJacob Faibussowitsch PetscCall(MatXAIJSetPreallocation(mass, 1, dnz, onz, NULL, NULL)); 5269566063dSJacob Faibussowitsch PetscCall(MatSetOption(mass, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_TRUE)); 5279566063dSJacob Faibussowitsch PetscCall(PetscFree2(dnz, onz)); 5289566063dSJacob Faibussowitsch PetscCall(PetscMalloc4(maxC * totDim, &elemMat, maxC * maxC, &elemMatSq, maxC, &rowIDXs, maxC * cdim, &xi)); 5294cc7f7b2SMatthew G. Knepley /* Fill in values 5304cc7f7b2SMatthew G. Knepley Each entry is a sum of terms \phi_i(x_p) \phi_i(x_q) 5314cc7f7b2SMatthew G. Knepley Start just by producing block diagonal 5324cc7f7b2SMatthew G. Knepley Could loop over adjacent cells 5334cc7f7b2SMatthew G. Knepley Produce neighboring element matrix 5344cc7f7b2SMatthew G. Knepley TODO Determine which columns and rows correspond to shared dual vector 5354cc7f7b2SMatthew G. Knepley Do MatMatMult with rectangular matrices 5364cc7f7b2SMatthew G. Knepley Insert block 5374cc7f7b2SMatthew G. Knepley */ 5384cc7f7b2SMatthew G. Knepley for (field = 0; field < Nf; ++field) { 5394cc7f7b2SMatthew G. Knepley PetscTabulation Tcoarse; 5404cc7f7b2SMatthew G. Knepley PetscObject obj; 5414cc7f7b2SMatthew G. Knepley PetscReal *coords; 5424cc7f7b2SMatthew G. Knepley PetscInt Nc, i; 5434cc7f7b2SMatthew G. Knepley 5449566063dSJacob Faibussowitsch PetscCall(PetscDSGetDiscretization(prob, field, &obj)); 5459566063dSJacob Faibussowitsch PetscCall(PetscFEGetNumComponents((PetscFE)obj, &Nc)); 54663a3b9bcSJacob Faibussowitsch PetscCheck(Nc == 1, PetscObjectComm((PetscObject)dmf), PETSC_ERR_SUP, "Can only interpolate a scalar field from particles, Nc = %" PetscInt_FMT, Nc); 5479566063dSJacob Faibussowitsch PetscCall(DMSwarmGetField(dmc, DMSwarmPICField_coor, NULL, NULL, (void **)&coords)); 5484cc7f7b2SMatthew G. Knepley for (cell = cStart; cell < cEnd; ++cell) { 5494cc7f7b2SMatthew G. Knepley PetscInt *findices, *cindices; 5504cc7f7b2SMatthew G. Knepley PetscInt numFIndices, numCIndices; 5514cc7f7b2SMatthew G. Knepley PetscInt p, c; 5524cc7f7b2SMatthew G. Knepley 5534cc7f7b2SMatthew G. Knepley /* TODO: Use DMField instead of assuming affine */ 5549566063dSJacob Faibussowitsch PetscCall(DMPlexComputeCellGeometryFEM(dmf, cell, NULL, v0, J, invJ, &detJ)); 5559566063dSJacob Faibussowitsch PetscCall(DMPlexGetClosureIndices(dmf, fsection, globalFSection, cell, PETSC_FALSE, &numFIndices, &findices, NULL, NULL)); 5569566063dSJacob Faibussowitsch PetscCall(DMSwarmSortGetPointsPerCell(dmc, cell, &numCIndices, &cindices)); 557ad540459SPierre Jolivet for (p = 0; p < numCIndices; ++p) CoordinatesRealToRef(cdim, cdim, v0ref, v0, invJ, &coords[cindices[p] * cdim], &xi[p * cdim]); 5589566063dSJacob Faibussowitsch PetscCall(PetscFECreateTabulation((PetscFE)obj, 1, numCIndices, xi, 0, &Tcoarse)); 5594cc7f7b2SMatthew G. Knepley /* Get elemMat entries by multiplying by weight */ 5609566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(elemMat, numCIndices * totDim)); 5614cc7f7b2SMatthew G. Knepley for (i = 0; i < numFIndices; ++i) { 5624cc7f7b2SMatthew G. Knepley for (p = 0; p < numCIndices; ++p) { 5634cc7f7b2SMatthew G. Knepley for (c = 0; c < Nc; ++c) { 5644cc7f7b2SMatthew G. Knepley /* B[(p*pdim + i)*Nc + c] is the value at point p for basis function i and component c */ 5654cc7f7b2SMatthew G. Knepley elemMat[p * numFIndices + i] += Tcoarse->T[0][(p * numFIndices + i) * Nc + c] * (useDeltaFunction ? 1.0 : detJ); 5664cc7f7b2SMatthew G. Knepley } 5674cc7f7b2SMatthew G. Knepley } 5684cc7f7b2SMatthew G. Knepley } 5699566063dSJacob Faibussowitsch PetscCall(PetscTabulationDestroy(&Tcoarse)); 5704cc7f7b2SMatthew G. Knepley for (p = 0; p < numCIndices; ++p) rowIDXs[p] = cindices[p] + rStart; 5719566063dSJacob Faibussowitsch if (0) PetscCall(DMPrintCellMatrix(cell, name, 1, numCIndices, elemMat)); 5724cc7f7b2SMatthew G. Knepley /* Block diagonal */ 57378884ca7SMatthew G. Knepley if (numCIndices) { 5744cc7f7b2SMatthew G. Knepley PetscBLASInt blasn, blask; 5754cc7f7b2SMatthew G. Knepley PetscScalar one = 1.0, zero = 0.0; 5764cc7f7b2SMatthew G. Knepley 5779566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(numCIndices, &blasn)); 5789566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(numFIndices, &blask)); 579792fecdfSBarry Smith PetscCallBLAS("BLASgemm", BLASgemm_("T", "N", &blasn, &blasn, &blask, &one, elemMat, &blask, elemMat, &blask, &zero, elemMatSq, &blasn)); 5804cc7f7b2SMatthew G. Knepley } 5819566063dSJacob Faibussowitsch PetscCall(MatSetValues(mass, numCIndices, rowIDXs, numCIndices, rowIDXs, elemMatSq, ADD_VALUES)); 5824cc7f7b2SMatthew G. Knepley /* TODO Off-diagonal */ 5839566063dSJacob Faibussowitsch PetscCall(PetscFree(cindices)); 5849566063dSJacob Faibussowitsch PetscCall(DMPlexRestoreClosureIndices(dmf, fsection, globalFSection, cell, PETSC_FALSE, &numFIndices, &findices, NULL, NULL)); 5854cc7f7b2SMatthew G. Knepley } 5869566063dSJacob Faibussowitsch PetscCall(DMSwarmRestoreField(dmc, DMSwarmPICField_coor, NULL, NULL, (void **)&coords)); 5874cc7f7b2SMatthew G. Knepley } 5889566063dSJacob Faibussowitsch PetscCall(PetscFree4(elemMat, elemMatSq, rowIDXs, xi)); 5899566063dSJacob Faibussowitsch PetscCall(PetscFree(adj)); 5909566063dSJacob Faibussowitsch PetscCall(DMSwarmSortRestoreAccess(dmc)); 5919566063dSJacob Faibussowitsch PetscCall(PetscFree3(v0, J, invJ)); 5929566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(mass, MAT_FINAL_ASSEMBLY)); 5939566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(mass, MAT_FINAL_ASSEMBLY)); 5944cc7f7b2SMatthew G. Knepley PetscFunctionReturn(0); 5954cc7f7b2SMatthew G. Knepley } 5964cc7f7b2SMatthew G. Knepley 5974cc7f7b2SMatthew G. Knepley /*@C 5984cc7f7b2SMatthew G. Knepley DMSwarmCreateMassMatrixSquare - Creates the block-diagonal of the square, M^T_p M_p, of the particle mass matrix M_p 5994cc7f7b2SMatthew G. Knepley 6004cc7f7b2SMatthew G. Knepley Collective on dmCoarse 6014cc7f7b2SMatthew G. Knepley 6024cc7f7b2SMatthew G. Knepley Input parameters: 6034cc7f7b2SMatthew G. Knepley + dmCoarse - a DMSwarm 6044cc7f7b2SMatthew G. Knepley - dmFine - a DMPlex 6054cc7f7b2SMatthew G. Knepley 6064cc7f7b2SMatthew G. Knepley Output parameter: 6074cc7f7b2SMatthew G. Knepley . mass - the square of the particle mass matrix 6084cc7f7b2SMatthew G. Knepley 6094cc7f7b2SMatthew G. Knepley Level: advanced 6104cc7f7b2SMatthew G. Knepley 6114cc7f7b2SMatthew G. Knepley Notes: 6124cc7f7b2SMatthew G. Knepley We only compute the block diagonal since this provides a good preconditioner and is completely local. It would be possible in the 6134cc7f7b2SMatthew G. Knepley future to compute the full normal equations. 6144cc7f7b2SMatthew G. Knepley 615db781477SPatrick Sanan .seealso: `DMCreateMassMatrix()` 6164cc7f7b2SMatthew G. Knepley @*/ 6179371c9d4SSatish Balay PetscErrorCode DMSwarmCreateMassMatrixSquare(DM dmCoarse, DM dmFine, Mat *mass) { 6184cc7f7b2SMatthew G. Knepley PetscInt n; 6194cc7f7b2SMatthew G. Knepley void *ctx; 6204cc7f7b2SMatthew G. Knepley 6214cc7f7b2SMatthew G. Knepley PetscFunctionBegin; 6229566063dSJacob Faibussowitsch PetscCall(DMSwarmGetLocalSize(dmCoarse, &n)); 6239566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)dmCoarse), mass)); 6249566063dSJacob Faibussowitsch PetscCall(MatSetSizes(*mass, n, n, PETSC_DETERMINE, PETSC_DETERMINE)); 6259566063dSJacob Faibussowitsch PetscCall(MatSetType(*mass, dmCoarse->mattype)); 6269566063dSJacob Faibussowitsch PetscCall(DMGetApplicationContext(dmFine, &ctx)); 6274cc7f7b2SMatthew G. Knepley 6289566063dSJacob Faibussowitsch PetscCall(DMSwarmComputeMassMatrixSquare_Private(dmCoarse, dmFine, *mass, PETSC_TRUE, ctx)); 6299566063dSJacob Faibussowitsch PetscCall(MatViewFromOptions(*mass, NULL, "-mass_sq_mat_view")); 6304cc7f7b2SMatthew G. Knepley PetscFunctionReturn(0); 6314cc7f7b2SMatthew G. Knepley } 6324cc7f7b2SMatthew G. Knepley 633fb1bcc12SMatthew G. Knepley /*@C 634d3a51819SDave May DMSwarmCreateGlobalVectorFromField - Creates a Vec object sharing the array associated with a given field 635d3a51819SDave May 636d083f849SBarry Smith Collective on dm 637d3a51819SDave May 638d3a51819SDave May Input parameters: 63962741f57SDave May + dm - a DMSwarm 64062741f57SDave May - fieldname - the textual name given to a registered field 641d3a51819SDave May 6428b8a3813SDave May Output parameter: 643d3a51819SDave May . vec - the vector 644d3a51819SDave May 645d3a51819SDave May Level: beginner 646d3a51819SDave May 6478b8a3813SDave May Notes: 6488b8a3813SDave May The vector must be returned using a matching call to DMSwarmDestroyGlobalVectorFromField(). 6498b8a3813SDave May 650db781477SPatrick Sanan .seealso: `DMSwarmRegisterPetscDatatypeField()`, `DMSwarmDestroyGlobalVectorFromField()` 651d3a51819SDave May @*/ 6529371c9d4SSatish Balay PetscErrorCode DMSwarmCreateGlobalVectorFromField(DM dm, const char fieldname[], Vec *vec) { 653fb1bcc12SMatthew G. Knepley MPI_Comm comm = PetscObjectComm((PetscObject)dm); 654b5bcf523SDave May 655fb1bcc12SMatthew G. Knepley PetscFunctionBegin; 6569566063dSJacob Faibussowitsch PetscCall(DMSwarmCreateVectorFromField_Private(dm, fieldname, comm, vec)); 657b5bcf523SDave May PetscFunctionReturn(0); 658b5bcf523SDave May } 659b5bcf523SDave May 660d3a51819SDave May /*@C 661d3a51819SDave May DMSwarmDestroyGlobalVectorFromField - Destroys the Vec object which share the array associated with a given field 662d3a51819SDave May 663d083f849SBarry Smith Collective on dm 664d3a51819SDave May 665d3a51819SDave May Input parameters: 66662741f57SDave May + dm - a DMSwarm 66762741f57SDave May - fieldname - the textual name given to a registered field 668d3a51819SDave May 6698b8a3813SDave May Output parameter: 670d3a51819SDave May . vec - the vector 671d3a51819SDave May 672d3a51819SDave May Level: beginner 673d3a51819SDave May 674db781477SPatrick Sanan .seealso: `DMSwarmRegisterPetscDatatypeField()`, `DMSwarmCreateGlobalVectorFromField()` 675d3a51819SDave May @*/ 6769371c9d4SSatish Balay PetscErrorCode DMSwarmDestroyGlobalVectorFromField(DM dm, const char fieldname[], Vec *vec) { 677fb1bcc12SMatthew G. Knepley PetscFunctionBegin; 6789566063dSJacob Faibussowitsch PetscCall(DMSwarmDestroyVectorFromField_Private(dm, fieldname, vec)); 679b5bcf523SDave May PetscFunctionReturn(0); 680b5bcf523SDave May } 681b5bcf523SDave May 682fb1bcc12SMatthew G. Knepley /*@C 683fb1bcc12SMatthew G. Knepley DMSwarmCreateLocalVectorFromField - Creates a Vec object sharing the array associated with a given field 684fb1bcc12SMatthew G. Knepley 685d083f849SBarry Smith Collective on dm 686fb1bcc12SMatthew G. Knepley 687fb1bcc12SMatthew G. Knepley Input parameters: 68862741f57SDave May + dm - a DMSwarm 68962741f57SDave May - fieldname - the textual name given to a registered field 690fb1bcc12SMatthew G. Knepley 6918b8a3813SDave May Output parameter: 692fb1bcc12SMatthew G. Knepley . vec - the vector 693fb1bcc12SMatthew G. Knepley 694fb1bcc12SMatthew G. Knepley Level: beginner 695fb1bcc12SMatthew G. Knepley 6968b8a3813SDave May Notes: 6978b8a3813SDave May The vector must be returned using a matching call to DMSwarmDestroyLocalVectorFromField(). 6988b8a3813SDave May 699db781477SPatrick Sanan .seealso: `DMSwarmRegisterPetscDatatypeField()`, `DMSwarmDestroyLocalVectorFromField()` 700fb1bcc12SMatthew G. Knepley @*/ 7019371c9d4SSatish Balay PetscErrorCode DMSwarmCreateLocalVectorFromField(DM dm, const char fieldname[], Vec *vec) { 702fb1bcc12SMatthew G. Knepley MPI_Comm comm = PETSC_COMM_SELF; 703bbe8250bSMatthew G. Knepley 704fb1bcc12SMatthew G. Knepley PetscFunctionBegin; 7059566063dSJacob Faibussowitsch PetscCall(DMSwarmCreateVectorFromField_Private(dm, fieldname, comm, vec)); 706fb1bcc12SMatthew G. Knepley PetscFunctionReturn(0); 707bbe8250bSMatthew G. Knepley } 708fb1bcc12SMatthew G. Knepley 709fb1bcc12SMatthew G. Knepley /*@C 710fb1bcc12SMatthew G. Knepley DMSwarmDestroyLocalVectorFromField - Destroys the Vec object which share the array associated with a given field 711fb1bcc12SMatthew G. Knepley 712d083f849SBarry Smith Collective on dm 713fb1bcc12SMatthew G. Knepley 714fb1bcc12SMatthew G. Knepley Input parameters: 71562741f57SDave May + dm - a DMSwarm 71662741f57SDave May - fieldname - the textual name given to a registered field 717fb1bcc12SMatthew G. Knepley 7188b8a3813SDave May Output parameter: 719fb1bcc12SMatthew G. Knepley . vec - the vector 720fb1bcc12SMatthew G. Knepley 721fb1bcc12SMatthew G. Knepley Level: beginner 722fb1bcc12SMatthew G. Knepley 723db781477SPatrick Sanan .seealso: `DMSwarmRegisterPetscDatatypeField()`, `DMSwarmCreateLocalVectorFromField()` 724fb1bcc12SMatthew G. Knepley @*/ 7259371c9d4SSatish Balay PetscErrorCode DMSwarmDestroyLocalVectorFromField(DM dm, const char fieldname[], Vec *vec) { 726fb1bcc12SMatthew G. Knepley PetscFunctionBegin; 7279566063dSJacob Faibussowitsch PetscCall(DMSwarmDestroyVectorFromField_Private(dm, fieldname, vec)); 728bbe8250bSMatthew G. Knepley PetscFunctionReturn(0); 729bbe8250bSMatthew G. Knepley } 730bbe8250bSMatthew G. Knepley 731d3a51819SDave May /*@C 732d3a51819SDave May DMSwarmInitializeFieldRegister - Initiates the registration of fields to a DMSwarm 733d3a51819SDave May 734d083f849SBarry Smith Collective on dm 735d3a51819SDave May 736d3a51819SDave May Input parameter: 737d3a51819SDave May . dm - a DMSwarm 738d3a51819SDave May 739d3a51819SDave May Level: beginner 740d3a51819SDave May 741d3a51819SDave May Notes: 7428b8a3813SDave May After all fields have been registered, you must call DMSwarmFinalizeFieldRegister(). 743d3a51819SDave May 744db781477SPatrick Sanan .seealso: `DMSwarmFinalizeFieldRegister()`, `DMSwarmRegisterPetscDatatypeField()`, 745db781477SPatrick Sanan `DMSwarmRegisterUserStructField()`, `DMSwarmRegisterUserDatatypeField()` 746d3a51819SDave May @*/ 7479371c9d4SSatish Balay PetscErrorCode DMSwarmInitializeFieldRegister(DM dm) { 7485f50eb2eSDave May DM_Swarm *swarm = (DM_Swarm *)dm->data; 7493454631fSDave May 750521f74f9SMatthew G. Knepley PetscFunctionBegin; 751cc651181SDave May if (!swarm->field_registration_initialized) { 7525f50eb2eSDave May swarm->field_registration_initialized = PETSC_TRUE; 7539566063dSJacob Faibussowitsch PetscCall(DMSwarmRegisterPetscDatatypeField(dm, DMSwarmField_pid, 1, PETSC_INT64)); /* unique identifer */ 7549566063dSJacob Faibussowitsch PetscCall(DMSwarmRegisterPetscDatatypeField(dm, DMSwarmField_rank, 1, PETSC_INT)); /* used for communication */ 755cc651181SDave May } 7565f50eb2eSDave May PetscFunctionReturn(0); 7575f50eb2eSDave May } 7585f50eb2eSDave May 75974d0cae8SMatthew G. Knepley /*@ 760d3a51819SDave May DMSwarmFinalizeFieldRegister - Finalizes the registration of fields to a DMSwarm 761d3a51819SDave May 762d083f849SBarry Smith Collective on dm 763d3a51819SDave May 764d3a51819SDave May Input parameter: 765d3a51819SDave May . dm - a DMSwarm 766d3a51819SDave May 767d3a51819SDave May Level: beginner 768d3a51819SDave May 769d3a51819SDave May Notes: 77062741f57SDave May After DMSwarmFinalizeFieldRegister() has been called, no new fields can be defined on the DMSwarm. 771d3a51819SDave May 772db781477SPatrick Sanan .seealso: `DMSwarmInitializeFieldRegister()`, `DMSwarmRegisterPetscDatatypeField()`, 773db781477SPatrick Sanan `DMSwarmRegisterUserStructField()`, `DMSwarmRegisterUserDatatypeField()` 774d3a51819SDave May @*/ 7759371c9d4SSatish Balay PetscErrorCode DMSwarmFinalizeFieldRegister(DM dm) { 7765f50eb2eSDave May DM_Swarm *swarm = (DM_Swarm *)dm->data; 7776845f8f5SDave May 778521f74f9SMatthew G. Knepley PetscFunctionBegin; 77948a46eb9SPierre Jolivet if (!swarm->field_registration_finalized) PetscCall(DMSwarmDataBucketFinalize(swarm->db)); 780f0cdbbbaSDave May swarm->field_registration_finalized = PETSC_TRUE; 7815f50eb2eSDave May PetscFunctionReturn(0); 7825f50eb2eSDave May } 7835f50eb2eSDave May 78474d0cae8SMatthew G. Knepley /*@ 785d3a51819SDave May DMSwarmSetLocalSizes - Sets the length of all registered fields on the DMSwarm 786d3a51819SDave May 787d3a51819SDave May Not collective 788d3a51819SDave May 789d3a51819SDave May Input parameters: 79062741f57SDave May + dm - a DMSwarm 791d3a51819SDave May . nlocal - the length of each registered field 79262741f57SDave May - buffer - the length of the buffer used to efficient dynamic re-sizing 793d3a51819SDave May 794d3a51819SDave May Level: beginner 795d3a51819SDave May 796db781477SPatrick Sanan .seealso: `DMSwarmGetLocalSize()` 797d3a51819SDave May @*/ 7989371c9d4SSatish Balay PetscErrorCode DMSwarmSetLocalSizes(DM dm, PetscInt nlocal, PetscInt buffer) { 7995f50eb2eSDave May DM_Swarm *swarm = (DM_Swarm *)dm->data; 8005f50eb2eSDave May 801521f74f9SMatthew G. Knepley PetscFunctionBegin; 8029566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(DMSWARM_SetSizes, 0, 0, 0, 0)); 8039566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketSetSizes(swarm->db, nlocal, buffer)); 8049566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(DMSWARM_SetSizes, 0, 0, 0, 0)); 8055f50eb2eSDave May PetscFunctionReturn(0); 8065f50eb2eSDave May } 8075f50eb2eSDave May 80874d0cae8SMatthew G. Knepley /*@ 809d3a51819SDave May DMSwarmSetCellDM - Attachs a DM to a DMSwarm 810d3a51819SDave May 811d083f849SBarry Smith Collective on dm 812d3a51819SDave May 813d3a51819SDave May Input parameters: 81462741f57SDave May + dm - a DMSwarm 81562741f57SDave May - dmcell - the DM to attach to the DMSwarm 816d3a51819SDave May 817d3a51819SDave May Level: beginner 818d3a51819SDave May 819d3a51819SDave May Notes: 820d3a51819SDave May The attached DM (dmcell) will be queried for point location and 8218b8a3813SDave May neighbor MPI-rank information if DMSwarmMigrate() is called. 822d3a51819SDave May 823db781477SPatrick Sanan .seealso: `DMSwarmSetType()`, `DMSwarmGetCellDM()`, `DMSwarmMigrate()` 824d3a51819SDave May @*/ 8259371c9d4SSatish Balay PetscErrorCode DMSwarmSetCellDM(DM dm, DM dmcell) { 826b16650c8SDave May DM_Swarm *swarm = (DM_Swarm *)dm->data; 827521f74f9SMatthew G. Knepley 828521f74f9SMatthew G. Knepley PetscFunctionBegin; 829b16650c8SDave May swarm->dmcell = dmcell; 830b16650c8SDave May PetscFunctionReturn(0); 831b16650c8SDave May } 832b16650c8SDave May 83374d0cae8SMatthew G. Knepley /*@ 834d3a51819SDave May DMSwarmGetCellDM - Fetches the attached cell DM 835d3a51819SDave May 836d083f849SBarry Smith Collective on dm 837d3a51819SDave May 838d3a51819SDave May Input parameter: 839d3a51819SDave May . dm - a DMSwarm 840d3a51819SDave May 841d3a51819SDave May Output parameter: 842d3a51819SDave May . dmcell - the DM which was attached to the DMSwarm 843d3a51819SDave May 844d3a51819SDave May Level: beginner 845d3a51819SDave May 846db781477SPatrick Sanan .seealso: `DMSwarmSetCellDM()` 847d3a51819SDave May @*/ 8489371c9d4SSatish Balay PetscErrorCode DMSwarmGetCellDM(DM dm, DM *dmcell) { 849fe39f135SDave May DM_Swarm *swarm = (DM_Swarm *)dm->data; 850521f74f9SMatthew G. Knepley 851521f74f9SMatthew G. Knepley PetscFunctionBegin; 852fe39f135SDave May *dmcell = swarm->dmcell; 853fe39f135SDave May PetscFunctionReturn(0); 854fe39f135SDave May } 855fe39f135SDave May 85674d0cae8SMatthew G. Knepley /*@ 857d3a51819SDave May DMSwarmGetLocalSize - Retrives the local length of fields registered 858d3a51819SDave May 859d3a51819SDave May Not collective 860d3a51819SDave May 861d3a51819SDave May Input parameter: 862d3a51819SDave May . dm - a DMSwarm 863d3a51819SDave May 864d3a51819SDave May Output parameter: 865d3a51819SDave May . nlocal - the length of each registered field 866d3a51819SDave May 867d3a51819SDave May Level: beginner 868d3a51819SDave May 869db781477SPatrick Sanan .seealso: `DMSwarmGetSize()`, `DMSwarmSetLocalSizes()` 870d3a51819SDave May @*/ 8719371c9d4SSatish Balay PetscErrorCode DMSwarmGetLocalSize(DM dm, PetscInt *nlocal) { 872dcf43ee8SDave May DM_Swarm *swarm = (DM_Swarm *)dm->data; 873dcf43ee8SDave May 874521f74f9SMatthew G. Knepley PetscFunctionBegin; 8759566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketGetSizes(swarm->db, nlocal, NULL, NULL)); 876dcf43ee8SDave May PetscFunctionReturn(0); 877dcf43ee8SDave May } 878dcf43ee8SDave May 87974d0cae8SMatthew G. Knepley /*@ 880d3a51819SDave May DMSwarmGetSize - Retrives the total length of fields registered 881d3a51819SDave May 882d083f849SBarry Smith Collective on dm 883d3a51819SDave May 884d3a51819SDave May Input parameter: 885d3a51819SDave May . dm - a DMSwarm 886d3a51819SDave May 887d3a51819SDave May Output parameter: 888d3a51819SDave May . n - the total length of each registered field 889d3a51819SDave May 890d3a51819SDave May Level: beginner 891d3a51819SDave May 892d3a51819SDave May Note: 893d3a51819SDave May This calls MPI_Allreduce upon each call (inefficient but safe) 894d3a51819SDave May 895db781477SPatrick Sanan .seealso: `DMSwarmGetLocalSize()`, `DMSwarmSetLocalSizes()` 896d3a51819SDave May @*/ 8979371c9d4SSatish Balay PetscErrorCode DMSwarmGetSize(DM dm, PetscInt *n) { 898dcf43ee8SDave May DM_Swarm *swarm = (DM_Swarm *)dm->data; 8995627991aSBarry Smith PetscInt nlocal; 900dcf43ee8SDave May 901521f74f9SMatthew G. Knepley PetscFunctionBegin; 9029566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketGetSizes(swarm->db, &nlocal, NULL, NULL)); 9039566063dSJacob Faibussowitsch PetscCallMPI(MPI_Allreduce(&nlocal, n, 1, MPIU_INT, MPI_SUM, PetscObjectComm((PetscObject)dm))); 904dcf43ee8SDave May PetscFunctionReturn(0); 905dcf43ee8SDave May } 906dcf43ee8SDave May 907d3a51819SDave May /*@C 9088b8a3813SDave May DMSwarmRegisterPetscDatatypeField - Register a field to a DMSwarm with a native PETSc data type 909d3a51819SDave May 910d083f849SBarry Smith Collective on dm 911d3a51819SDave May 912d3a51819SDave May Input parameters: 91362741f57SDave May + dm - a DMSwarm 914d3a51819SDave May . fieldname - the textual name to identify this field 915d3a51819SDave May . blocksize - the number of each data type 91662741f57SDave May - type - a valid PETSc data type (PETSC_CHAR, PETSC_SHORT, PETSC_INT, PETSC_FLOAT, PETSC_REAL, PETSC_LONG) 917d3a51819SDave May 918d3a51819SDave May Level: beginner 919d3a51819SDave May 920d3a51819SDave May Notes: 9218b8a3813SDave May The textual name for each registered field must be unique. 922d3a51819SDave May 923db781477SPatrick Sanan .seealso: `DMSwarmRegisterUserStructField()`, `DMSwarmRegisterUserDatatypeField()` 924d3a51819SDave May @*/ 9259371c9d4SSatish Balay PetscErrorCode DMSwarmRegisterPetscDatatypeField(DM dm, const char fieldname[], PetscInt blocksize, PetscDataType type) { 926b62e03f8SDave May DM_Swarm *swarm = (DM_Swarm *)dm->data; 927b62e03f8SDave May size_t size; 928b62e03f8SDave May 929521f74f9SMatthew G. Knepley PetscFunctionBegin; 93028b400f6SJacob Faibussowitsch PetscCheck(swarm->field_registration_initialized, PetscObjectComm((PetscObject)dm), PETSC_ERR_USER, "Must call DMSwarmInitializeFieldRegister() first"); 93128b400f6SJacob Faibussowitsch PetscCheck(!swarm->field_registration_finalized, PetscObjectComm((PetscObject)dm), PETSC_ERR_USER, "Cannot register additional fields after calling DMSwarmFinalizeFieldRegister() first"); 9325f50eb2eSDave May 93308401ef6SPierre Jolivet PetscCheck(type != PETSC_OBJECT, PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Valid for {char,short,int,long,float,double}"); 93408401ef6SPierre Jolivet PetscCheck(type != PETSC_FUNCTION, PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Valid for {char,short,int,long,float,double}"); 93508401ef6SPierre Jolivet PetscCheck(type != PETSC_STRING, PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Valid for {char,short,int,long,float,double}"); 93608401ef6SPierre Jolivet PetscCheck(type != PETSC_STRUCT, PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Valid for {char,short,int,long,float,double}"); 93708401ef6SPierre Jolivet PetscCheck(type != PETSC_DATATYPE_UNKNOWN, PetscObjectComm((PetscObject)dm), PETSC_ERR_SUP, "Valid for {char,short,int,long,float,double}"); 938b62e03f8SDave May 9399566063dSJacob Faibussowitsch PetscCall(PetscDataTypeGetSize(type, &size)); 940b62e03f8SDave May /* Load a specific data type into data bucket, specifying textual name and its size in bytes */ 9419566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketRegisterField(swarm->db, "DMSwarmRegisterPetscDatatypeField", fieldname, blocksize * size, NULL)); 94252c3ed93SDave May { 94377048351SPatrick Sanan DMSwarmDataField gfield; 94452c3ed93SDave May 9459566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketGetDMSwarmDataFieldByName(swarm->db, fieldname, &gfield)); 9469566063dSJacob Faibussowitsch PetscCall(DMSwarmDataFieldSetBlockSize(gfield, blocksize)); 94752c3ed93SDave May } 948b62e03f8SDave May swarm->db->field[swarm->db->nfields - 1]->petsc_type = type; 949b62e03f8SDave May PetscFunctionReturn(0); 950b62e03f8SDave May } 951b62e03f8SDave May 952d3a51819SDave May /*@C 953d3a51819SDave May DMSwarmRegisterUserStructField - Register a user defined struct to a DMSwarm 954d3a51819SDave May 955d083f849SBarry Smith Collective on dm 956d3a51819SDave May 957d3a51819SDave May Input parameters: 95862741f57SDave May + dm - a DMSwarm 959d3a51819SDave May . fieldname - the textual name to identify this field 96062741f57SDave May - size - the size in bytes of the user struct of each data type 961d3a51819SDave May 962d3a51819SDave May Level: beginner 963d3a51819SDave May 964d3a51819SDave May Notes: 9658b8a3813SDave May The textual name for each registered field must be unique. 966d3a51819SDave May 967db781477SPatrick Sanan .seealso: `DMSwarmRegisterPetscDatatypeField()`, `DMSwarmRegisterUserDatatypeField()` 968d3a51819SDave May @*/ 9699371c9d4SSatish Balay PetscErrorCode DMSwarmRegisterUserStructField(DM dm, const char fieldname[], size_t size) { 970b62e03f8SDave May DM_Swarm *swarm = (DM_Swarm *)dm->data; 971b62e03f8SDave May 972521f74f9SMatthew G. Knepley PetscFunctionBegin; 9739566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketRegisterField(swarm->db, "DMSwarmRegisterUserStructField", fieldname, size, NULL)); 974b62e03f8SDave May swarm->db->field[swarm->db->nfields - 1]->petsc_type = PETSC_STRUCT; 975b62e03f8SDave May PetscFunctionReturn(0); 976b62e03f8SDave May } 977b62e03f8SDave May 978d3a51819SDave May /*@C 979d3a51819SDave May DMSwarmRegisterUserDatatypeField - Register a user defined data type to a DMSwarm 980d3a51819SDave May 981d083f849SBarry Smith Collective on dm 982d3a51819SDave May 983d3a51819SDave May Input parameters: 98462741f57SDave May + dm - a DMSwarm 985d3a51819SDave May . fieldname - the textual name to identify this field 986d3a51819SDave May . size - the size in bytes of the user data type 98762741f57SDave May - blocksize - the number of each data type 988d3a51819SDave May 989d3a51819SDave May Level: beginner 990d3a51819SDave May 991d3a51819SDave May Notes: 9928b8a3813SDave May The textual name for each registered field must be unique. 993d3a51819SDave May 994db781477SPatrick Sanan .seealso: `DMSwarmRegisterPetscDatatypeField()`, `DMSwarmRegisterUserStructField()`, `DMSwarmRegisterUserDatatypeField()` 995d3a51819SDave May @*/ 9969371c9d4SSatish Balay PetscErrorCode DMSwarmRegisterUserDatatypeField(DM dm, const char fieldname[], size_t size, PetscInt blocksize) { 997b62e03f8SDave May DM_Swarm *swarm = (DM_Swarm *)dm->data; 998b62e03f8SDave May 999521f74f9SMatthew G. Knepley PetscFunctionBegin; 10009566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketRegisterField(swarm->db, "DMSwarmRegisterUserDatatypeField", fieldname, blocksize * size, NULL)); 1001320740a0SDave May { 100277048351SPatrick Sanan DMSwarmDataField gfield; 1003320740a0SDave May 10049566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketGetDMSwarmDataFieldByName(swarm->db, fieldname, &gfield)); 10059566063dSJacob Faibussowitsch PetscCall(DMSwarmDataFieldSetBlockSize(gfield, blocksize)); 1006320740a0SDave May } 1007b62e03f8SDave May swarm->db->field[swarm->db->nfields - 1]->petsc_type = PETSC_DATATYPE_UNKNOWN; 1008b62e03f8SDave May PetscFunctionReturn(0); 1009b62e03f8SDave May } 1010b62e03f8SDave May 1011d3a51819SDave May /*@C 1012d3a51819SDave May DMSwarmGetField - Get access to the underlying array storing all entries associated with a registered field 1013d3a51819SDave May 1014d3a51819SDave May Not collective 1015d3a51819SDave May 1016d3a51819SDave May Input parameters: 101762741f57SDave May + dm - a DMSwarm 101862741f57SDave May - fieldname - the textual name to identify this field 1019d3a51819SDave May 1020d3a51819SDave May Output parameters: 102162741f57SDave May + blocksize - the number of each data type 1022d3a51819SDave May . type - the data type 102362741f57SDave May - data - pointer to raw array 1024d3a51819SDave May 1025d3a51819SDave May Level: beginner 1026d3a51819SDave May 1027d3a51819SDave May Notes: 10288b8a3813SDave May The array must be returned using a matching call to DMSwarmRestoreField(). 1029d3a51819SDave May 1030db781477SPatrick Sanan .seealso: `DMSwarmRestoreField()` 1031d3a51819SDave May @*/ 10329371c9d4SSatish Balay PetscErrorCode DMSwarmGetField(DM dm, const char fieldname[], PetscInt *blocksize, PetscDataType *type, void **data) { 1033b62e03f8SDave May DM_Swarm *swarm = (DM_Swarm *)dm->data; 103477048351SPatrick Sanan DMSwarmDataField gfield; 1035b62e03f8SDave May 1036521f74f9SMatthew G. Knepley PetscFunctionBegin; 10379566063dSJacob Faibussowitsch if (!swarm->issetup) PetscCall(DMSetUp(dm)); 10389566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketGetDMSwarmDataFieldByName(swarm->db, fieldname, &gfield)); 10399566063dSJacob Faibussowitsch PetscCall(DMSwarmDataFieldGetAccess(gfield)); 10409566063dSJacob Faibussowitsch PetscCall(DMSwarmDataFieldGetEntries(gfield, data)); 1041ad540459SPierre Jolivet if (blocksize) *blocksize = gfield->bs; 1042ad540459SPierre Jolivet if (type) *type = gfield->petsc_type; 1043b62e03f8SDave May PetscFunctionReturn(0); 1044b62e03f8SDave May } 1045b62e03f8SDave May 1046d3a51819SDave May /*@C 1047d3a51819SDave May DMSwarmRestoreField - Restore access to the underlying array storing all entries associated with a registered field 1048d3a51819SDave May 1049d3a51819SDave May Not collective 1050d3a51819SDave May 1051d3a51819SDave May Input parameters: 105262741f57SDave May + dm - a DMSwarm 105362741f57SDave May - fieldname - the textual name to identify this field 1054d3a51819SDave May 1055d3a51819SDave May Output parameters: 105662741f57SDave May + blocksize - the number of each data type 1057d3a51819SDave May . type - the data type 105862741f57SDave May - data - pointer to raw array 1059d3a51819SDave May 1060d3a51819SDave May Level: beginner 1061d3a51819SDave May 1062d3a51819SDave May Notes: 10638b8a3813SDave May The user must call DMSwarmGetField() prior to calling DMSwarmRestoreField(). 1064d3a51819SDave May 1065db781477SPatrick Sanan .seealso: `DMSwarmGetField()` 1066d3a51819SDave May @*/ 10679371c9d4SSatish Balay PetscErrorCode DMSwarmRestoreField(DM dm, const char fieldname[], PetscInt *blocksize, PetscDataType *type, void **data) { 1068b62e03f8SDave May DM_Swarm *swarm = (DM_Swarm *)dm->data; 106977048351SPatrick Sanan DMSwarmDataField gfield; 1070b62e03f8SDave May 1071521f74f9SMatthew G. Knepley PetscFunctionBegin; 10729566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketGetDMSwarmDataFieldByName(swarm->db, fieldname, &gfield)); 10739566063dSJacob Faibussowitsch PetscCall(DMSwarmDataFieldRestoreAccess(gfield)); 1074b62e03f8SDave May if (data) *data = NULL; 1075b62e03f8SDave May PetscFunctionReturn(0); 1076b62e03f8SDave May } 1077b62e03f8SDave May 107874d0cae8SMatthew G. Knepley /*@ 1079d3a51819SDave May DMSwarmAddPoint - Add space for one new point in the DMSwarm 1080d3a51819SDave May 1081d3a51819SDave May Not collective 1082d3a51819SDave May 1083d3a51819SDave May Input parameter: 1084d3a51819SDave May . dm - a DMSwarm 1085d3a51819SDave May 1086d3a51819SDave May Level: beginner 1087d3a51819SDave May 1088d3a51819SDave May Notes: 10898b8a3813SDave May The new point will have all fields initialized to zero. 1090d3a51819SDave May 1091db781477SPatrick Sanan .seealso: `DMSwarmAddNPoints()` 1092d3a51819SDave May @*/ 10939371c9d4SSatish Balay PetscErrorCode DMSwarmAddPoint(DM dm) { 1094cb1d1399SDave May DM_Swarm *swarm = (DM_Swarm *)dm->data; 1095cb1d1399SDave May 1096521f74f9SMatthew G. Knepley PetscFunctionBegin; 10979566063dSJacob Faibussowitsch if (!swarm->issetup) PetscCall(DMSetUp(dm)); 10989566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(DMSWARM_AddPoints, 0, 0, 0, 0)); 10999566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketAddPoint(swarm->db)); 11009566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(DMSWARM_AddPoints, 0, 0, 0, 0)); 1101cb1d1399SDave May PetscFunctionReturn(0); 1102cb1d1399SDave May } 1103cb1d1399SDave May 110474d0cae8SMatthew G. Knepley /*@ 1105d3a51819SDave May DMSwarmAddNPoints - Add space for a number of new points in the DMSwarm 1106d3a51819SDave May 1107d3a51819SDave May Not collective 1108d3a51819SDave May 1109d3a51819SDave May Input parameters: 111062741f57SDave May + dm - a DMSwarm 111162741f57SDave May - npoints - the number of new points to add 1112d3a51819SDave May 1113d3a51819SDave May Level: beginner 1114d3a51819SDave May 1115d3a51819SDave May Notes: 11168b8a3813SDave May The new point will have all fields initialized to zero. 1117d3a51819SDave May 1118db781477SPatrick Sanan .seealso: `DMSwarmAddPoint()` 1119d3a51819SDave May @*/ 11209371c9d4SSatish Balay PetscErrorCode DMSwarmAddNPoints(DM dm, PetscInt npoints) { 1121cb1d1399SDave May DM_Swarm *swarm = (DM_Swarm *)dm->data; 1122cb1d1399SDave May PetscInt nlocal; 1123cb1d1399SDave May 1124521f74f9SMatthew G. Knepley PetscFunctionBegin; 11259566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(DMSWARM_AddPoints, 0, 0, 0, 0)); 11269566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketGetSizes(swarm->db, &nlocal, NULL, NULL)); 1127cb1d1399SDave May nlocal = nlocal + npoints; 11289566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketSetSizes(swarm->db, nlocal, DMSWARM_DATA_BUCKET_BUFFER_DEFAULT)); 11299566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(DMSWARM_AddPoints, 0, 0, 0, 0)); 1130cb1d1399SDave May PetscFunctionReturn(0); 1131cb1d1399SDave May } 1132cb1d1399SDave May 113374d0cae8SMatthew G. Knepley /*@ 1134d3a51819SDave May DMSwarmRemovePoint - Remove the last point from the DMSwarm 1135d3a51819SDave May 1136d3a51819SDave May Not collective 1137d3a51819SDave May 1138d3a51819SDave May Input parameter: 1139d3a51819SDave May . dm - a DMSwarm 1140d3a51819SDave May 1141d3a51819SDave May Level: beginner 1142d3a51819SDave May 1143db781477SPatrick Sanan .seealso: `DMSwarmRemovePointAtIndex()` 1144d3a51819SDave May @*/ 11459371c9d4SSatish Balay PetscErrorCode DMSwarmRemovePoint(DM dm) { 1146cb1d1399SDave May DM_Swarm *swarm = (DM_Swarm *)dm->data; 1147cb1d1399SDave May 1148521f74f9SMatthew G. Knepley PetscFunctionBegin; 11499566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(DMSWARM_RemovePoints, 0, 0, 0, 0)); 11509566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketRemovePoint(swarm->db)); 11519566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(DMSWARM_RemovePoints, 0, 0, 0, 0)); 1152cb1d1399SDave May PetscFunctionReturn(0); 1153cb1d1399SDave May } 1154cb1d1399SDave May 115574d0cae8SMatthew G. Knepley /*@ 1156d3a51819SDave May DMSwarmRemovePointAtIndex - Removes a specific point from the DMSwarm 1157d3a51819SDave May 1158d3a51819SDave May Not collective 1159d3a51819SDave May 1160d3a51819SDave May Input parameters: 116162741f57SDave May + dm - a DMSwarm 116262741f57SDave May - idx - index of point to remove 1163d3a51819SDave May 1164d3a51819SDave May Level: beginner 1165d3a51819SDave May 1166db781477SPatrick Sanan .seealso: `DMSwarmRemovePoint()` 1167d3a51819SDave May @*/ 11689371c9d4SSatish Balay PetscErrorCode DMSwarmRemovePointAtIndex(DM dm, PetscInt idx) { 1169cb1d1399SDave May DM_Swarm *swarm = (DM_Swarm *)dm->data; 1170cb1d1399SDave May 1171521f74f9SMatthew G. Knepley PetscFunctionBegin; 11729566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(DMSWARM_RemovePoints, 0, 0, 0, 0)); 11739566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketRemovePointAtIndex(swarm->db, idx)); 11749566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(DMSWARM_RemovePoints, 0, 0, 0, 0)); 1175cb1d1399SDave May PetscFunctionReturn(0); 1176cb1d1399SDave May } 1177b62e03f8SDave May 117874d0cae8SMatthew G. Knepley /*@ 1179ba4fc9c6SDave May DMSwarmCopyPoint - Copy point pj to point pi in the DMSwarm 1180ba4fc9c6SDave May 1181ba4fc9c6SDave May Not collective 1182ba4fc9c6SDave May 1183ba4fc9c6SDave May Input parameters: 1184ba4fc9c6SDave May + dm - a DMSwarm 1185ba4fc9c6SDave May . pi - the index of the point to copy 1186ba4fc9c6SDave May - pj - the point index where the copy should be located 1187ba4fc9c6SDave May 1188ba4fc9c6SDave May Level: beginner 1189ba4fc9c6SDave May 1190db781477SPatrick Sanan .seealso: `DMSwarmRemovePoint()` 1191ba4fc9c6SDave May @*/ 11929371c9d4SSatish Balay PetscErrorCode DMSwarmCopyPoint(DM dm, PetscInt pi, PetscInt pj) { 1193ba4fc9c6SDave May DM_Swarm *swarm = (DM_Swarm *)dm->data; 1194ba4fc9c6SDave May 1195ba4fc9c6SDave May PetscFunctionBegin; 11969566063dSJacob Faibussowitsch if (!swarm->issetup) PetscCall(DMSetUp(dm)); 11979566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketCopyPoint(swarm->db, pi, swarm->db, pj)); 1198ba4fc9c6SDave May PetscFunctionReturn(0); 1199ba4fc9c6SDave May } 1200ba4fc9c6SDave May 12019371c9d4SSatish Balay PetscErrorCode DMSwarmMigrate_Basic(DM dm, PetscBool remove_sent_points) { 1202521f74f9SMatthew G. Knepley PetscFunctionBegin; 12039566063dSJacob Faibussowitsch PetscCall(DMSwarmMigrate_Push_Basic(dm, remove_sent_points)); 12043454631fSDave May PetscFunctionReturn(0); 12053454631fSDave May } 12063454631fSDave May 120774d0cae8SMatthew G. Knepley /*@ 1208d3a51819SDave May DMSwarmMigrate - Relocates points defined in the DMSwarm to other MPI-ranks 1209d3a51819SDave May 1210d083f849SBarry Smith Collective on dm 1211d3a51819SDave May 1212d3a51819SDave May Input parameters: 121362741f57SDave May + dm - the DMSwarm 121462741f57SDave May - remove_sent_points - flag indicating if sent points should be removed from the current MPI-rank 1215d3a51819SDave May 1216d3a51819SDave May Notes: 1217a5b23f4aSJose E. Roman The DM will be modified to accommodate received points. 12188b8a3813SDave May If remove_sent_points = PETSC_TRUE, any points that were sent will be removed from the DM. 12198b8a3813SDave May Different styles of migration are supported. See DMSwarmSetMigrateType(). 1220d3a51819SDave May 1221d3a51819SDave May Level: advanced 1222d3a51819SDave May 1223db781477SPatrick Sanan .seealso: `DMSwarmSetMigrateType()` 1224d3a51819SDave May @*/ 12259371c9d4SSatish Balay PetscErrorCode DMSwarmMigrate(DM dm, PetscBool remove_sent_points) { 1226f0cdbbbaSDave May DM_Swarm *swarm = (DM_Swarm *)dm->data; 1227f0cdbbbaSDave May 1228521f74f9SMatthew G. Knepley PetscFunctionBegin; 12299566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(DMSWARM_Migrate, 0, 0, 0, 0)); 1230f0cdbbbaSDave May switch (swarm->migrate_type) { 12319371c9d4SSatish Balay case DMSWARM_MIGRATE_BASIC: PetscCall(DMSwarmMigrate_Basic(dm, remove_sent_points)); break; 12329371c9d4SSatish Balay case DMSWARM_MIGRATE_DMCELLNSCATTER: PetscCall(DMSwarmMigrate_CellDMScatter(dm, remove_sent_points)); break; 12339371c9d4SSatish Balay case DMSWARM_MIGRATE_DMCELLEXACT: SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_SUP, "DMSWARM_MIGRATE_DMCELLEXACT not implemented"); 12349371c9d4SSatish Balay case DMSWARM_MIGRATE_USER: SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_SUP, "DMSWARM_MIGRATE_USER not implemented"); 12359371c9d4SSatish Balay default: SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_SUP, "DMSWARM_MIGRATE type unknown"); 1236f0cdbbbaSDave May } 12379566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(DMSWARM_Migrate, 0, 0, 0, 0)); 12389566063dSJacob Faibussowitsch PetscCall(DMClearGlobalVectors(dm)); 12393454631fSDave May PetscFunctionReturn(0); 12403454631fSDave May } 12413454631fSDave May 1242f0cdbbbaSDave May PetscErrorCode DMSwarmMigrate_GlobalToLocal_Basic(DM dm, PetscInt *globalsize); 1243f0cdbbbaSDave May 1244d3a51819SDave May /* 1245d3a51819SDave May DMSwarmCollectViewCreate 1246d3a51819SDave May 1247d3a51819SDave May * Applies a collection method and gathers point neighbour points into dm 1248d3a51819SDave May 1249d3a51819SDave May Notes: 12508b8a3813SDave May Users should call DMSwarmCollectViewDestroy() after 1251d3a51819SDave May they have finished computations associated with the collected points 1252d3a51819SDave May */ 1253d3a51819SDave May 125474d0cae8SMatthew G. Knepley /*@ 1255d3a51819SDave May DMSwarmCollectViewCreate - Applies a collection method and gathers points 12565627991aSBarry Smith in neighbour ranks into the DMSwarm 1257d3a51819SDave May 1258d083f849SBarry Smith Collective on dm 1259d3a51819SDave May 1260d3a51819SDave May Input parameter: 1261d3a51819SDave May . dm - the DMSwarm 1262d3a51819SDave May 1263d3a51819SDave May Notes: 1264d3a51819SDave May Users should call DMSwarmCollectViewDestroy() after 1265d3a51819SDave May they have finished computations associated with the collected points 12668b8a3813SDave May Different collect methods are supported. See DMSwarmSetCollectType(). 1267d3a51819SDave May 1268d3a51819SDave May Level: advanced 1269d3a51819SDave May 1270db781477SPatrick Sanan .seealso: `DMSwarmCollectViewDestroy()`, `DMSwarmSetCollectType()` 1271d3a51819SDave May @*/ 12729371c9d4SSatish Balay PetscErrorCode DMSwarmCollectViewCreate(DM dm) { 12732712d1f2SDave May DM_Swarm *swarm = (DM_Swarm *)dm->data; 12742712d1f2SDave May PetscInt ng; 12752712d1f2SDave May 1276521f74f9SMatthew G. Knepley PetscFunctionBegin; 127728b400f6SJacob Faibussowitsch PetscCheck(!swarm->collect_view_active, PetscObjectComm((PetscObject)dm), PETSC_ERR_USER, "CollectView currently active"); 12789566063dSJacob Faibussowitsch PetscCall(DMSwarmGetLocalSize(dm, &ng)); 1279480eef7bSDave May switch (swarm->collect_type) { 12809371c9d4SSatish Balay case DMSWARM_COLLECT_BASIC: PetscCall(DMSwarmMigrate_GlobalToLocal_Basic(dm, &ng)); break; 12819371c9d4SSatish Balay case DMSWARM_COLLECT_DMDABOUNDINGBOX: SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_SUP, "DMSWARM_COLLECT_DMDABOUNDINGBOX not implemented"); 12829371c9d4SSatish Balay case DMSWARM_COLLECT_GENERAL: SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_SUP, "DMSWARM_COLLECT_GENERAL not implemented"); 12839371c9d4SSatish Balay default: SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_SUP, "DMSWARM_COLLECT type unknown"); 1284480eef7bSDave May } 1285480eef7bSDave May swarm->collect_view_active = PETSC_TRUE; 1286480eef7bSDave May swarm->collect_view_reset_nlocal = ng; 12872712d1f2SDave May PetscFunctionReturn(0); 12882712d1f2SDave May } 12892712d1f2SDave May 129074d0cae8SMatthew G. Knepley /*@ 1291d3a51819SDave May DMSwarmCollectViewDestroy - Resets the DMSwarm to the size prior to calling DMSwarmCollectViewCreate() 1292d3a51819SDave May 1293d083f849SBarry Smith Collective on dm 1294d3a51819SDave May 1295d3a51819SDave May Input parameters: 1296d3a51819SDave May . dm - the DMSwarm 1297d3a51819SDave May 1298d3a51819SDave May Notes: 1299d3a51819SDave May Users should call DMSwarmCollectViewCreate() before this function is called. 1300d3a51819SDave May 1301d3a51819SDave May Level: advanced 1302d3a51819SDave May 1303db781477SPatrick Sanan .seealso: `DMSwarmCollectViewCreate()`, `DMSwarmSetCollectType()` 1304d3a51819SDave May @*/ 13059371c9d4SSatish Balay PetscErrorCode DMSwarmCollectViewDestroy(DM dm) { 13062712d1f2SDave May DM_Swarm *swarm = (DM_Swarm *)dm->data; 13072712d1f2SDave May 1308521f74f9SMatthew G. Knepley PetscFunctionBegin; 130928b400f6SJacob Faibussowitsch PetscCheck(swarm->collect_view_active, PetscObjectComm((PetscObject)dm), PETSC_ERR_USER, "CollectView is currently not active"); 13109566063dSJacob Faibussowitsch PetscCall(DMSwarmSetLocalSizes(dm, swarm->collect_view_reset_nlocal, -1)); 1311480eef7bSDave May swarm->collect_view_active = PETSC_FALSE; 13122712d1f2SDave May PetscFunctionReturn(0); 13132712d1f2SDave May } 13143454631fSDave May 13159371c9d4SSatish Balay PetscErrorCode DMSwarmSetUpPIC(DM dm) { 1316f0cdbbbaSDave May PetscInt dim; 1317f0cdbbbaSDave May 1318521f74f9SMatthew G. Knepley PetscFunctionBegin; 13199566063dSJacob Faibussowitsch PetscCall(DMSwarmSetNumSpecies(dm, 1)); 13209566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dm, &dim)); 132163a3b9bcSJacob Faibussowitsch PetscCheck(dim >= 1, PetscObjectComm((PetscObject)dm), PETSC_ERR_USER, "Dimension must be 1,2,3 - found %" PetscInt_FMT, dim); 132263a3b9bcSJacob Faibussowitsch PetscCheck(dim <= 3, PetscObjectComm((PetscObject)dm), PETSC_ERR_USER, "Dimension must be 1,2,3 - found %" PetscInt_FMT, dim); 13239566063dSJacob Faibussowitsch PetscCall(DMSwarmRegisterPetscDatatypeField(dm, DMSwarmPICField_coor, dim, PETSC_DOUBLE)); 13249566063dSJacob Faibussowitsch PetscCall(DMSwarmRegisterPetscDatatypeField(dm, DMSwarmPICField_cellid, 1, PETSC_INT)); 1325f0cdbbbaSDave May PetscFunctionReturn(0); 1326f0cdbbbaSDave May } 1327f0cdbbbaSDave May 132874d0cae8SMatthew G. Knepley /*@ 132931403186SMatthew G. Knepley DMSwarmSetPointCoordinatesRandom - Sets initial coordinates for particles in each cell 133031403186SMatthew G. Knepley 133131403186SMatthew G. Knepley Collective on dm 133231403186SMatthew G. Knepley 133331403186SMatthew G. Knepley Input parameters: 133431403186SMatthew G. Knepley + dm - the DMSwarm 133531403186SMatthew G. Knepley - Npc - The number of particles per cell in the cell DM 133631403186SMatthew G. Knepley 133731403186SMatthew G. Knepley Notes: 133831403186SMatthew G. Knepley The user must use DMSwarmSetCellDM() to set the cell DM first. The particles are placed randomly inside each cell. If only 133931403186SMatthew G. Knepley one particle is in each cell, it is placed at the centroid. 134031403186SMatthew G. Knepley 134131403186SMatthew G. Knepley Level: intermediate 134231403186SMatthew G. Knepley 1343db781477SPatrick Sanan .seealso: `DMSwarmSetCellDM()` 134431403186SMatthew G. Knepley @*/ 13459371c9d4SSatish Balay PetscErrorCode DMSwarmSetPointCoordinatesRandom(DM dm, PetscInt Npc) { 134631403186SMatthew G. Knepley DM cdm; 134731403186SMatthew G. Knepley PetscRandom rnd; 134831403186SMatthew G. Knepley DMPolytopeType ct; 134931403186SMatthew G. Knepley PetscBool simplex; 135031403186SMatthew G. Knepley PetscReal *centroid, *coords, *xi0, *v0, *J, *invJ, detJ; 135131403186SMatthew G. Knepley PetscInt dim, d, cStart, cEnd, c, p; 135231403186SMatthew G. Knepley 135331403186SMatthew G. Knepley PetscFunctionBeginUser; 13549566063dSJacob Faibussowitsch PetscCall(PetscRandomCreate(PetscObjectComm((PetscObject)dm), &rnd)); 13559566063dSJacob Faibussowitsch PetscCall(PetscRandomSetInterval(rnd, -1.0, 1.0)); 13569566063dSJacob Faibussowitsch PetscCall(PetscRandomSetType(rnd, PETSCRAND48)); 135731403186SMatthew G. Knepley 13589566063dSJacob Faibussowitsch PetscCall(DMSwarmGetCellDM(dm, &cdm)); 13599566063dSJacob Faibussowitsch PetscCall(DMGetDimension(cdm, &dim)); 13609566063dSJacob Faibussowitsch PetscCall(DMPlexGetHeightStratum(cdm, 0, &cStart, &cEnd)); 13619566063dSJacob Faibussowitsch PetscCall(DMPlexGetCellType(cdm, cStart, &ct)); 136231403186SMatthew G. Knepley simplex = DMPolytopeTypeGetNumVertices(ct) == DMPolytopeTypeGetDim(ct) + 1 ? PETSC_TRUE : PETSC_FALSE; 136331403186SMatthew G. Knepley 13649566063dSJacob Faibussowitsch PetscCall(PetscMalloc5(dim, ¢roid, dim, &xi0, dim, &v0, dim * dim, &J, dim * dim, &invJ)); 136531403186SMatthew G. Knepley for (d = 0; d < dim; ++d) xi0[d] = -1.0; 13669566063dSJacob Faibussowitsch PetscCall(DMSwarmGetField(dm, DMSwarmPICField_coor, NULL, NULL, (void **)&coords)); 136731403186SMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 136831403186SMatthew G. Knepley if (Npc == 1) { 13699566063dSJacob Faibussowitsch PetscCall(DMPlexComputeCellGeometryFVM(cdm, c, NULL, centroid, NULL)); 137031403186SMatthew G. Knepley for (d = 0; d < dim; ++d) coords[c * dim + d] = centroid[d]; 137131403186SMatthew G. Knepley } else { 13729566063dSJacob Faibussowitsch PetscCall(DMPlexComputeCellGeometryFEM(cdm, c, NULL, v0, J, invJ, &detJ)); /* affine */ 137331403186SMatthew G. Knepley for (p = 0; p < Npc; ++p) { 137431403186SMatthew G. Knepley const PetscInt n = c * Npc + p; 137531403186SMatthew G. Knepley PetscReal sum = 0.0, refcoords[3]; 137631403186SMatthew G. Knepley 137731403186SMatthew G. Knepley for (d = 0; d < dim; ++d) { 13789566063dSJacob Faibussowitsch PetscCall(PetscRandomGetValueReal(rnd, &refcoords[d])); 137931403186SMatthew G. Knepley sum += refcoords[d]; 138031403186SMatthew G. Knepley } 13819371c9d4SSatish Balay if (simplex && sum > 0.0) 13829371c9d4SSatish Balay for (d = 0; d < dim; ++d) refcoords[d] -= PetscSqrtReal(dim) * sum; 138331403186SMatthew G. Knepley CoordinatesRefToReal(dim, dim, xi0, v0, J, refcoords, &coords[n * dim]); 138431403186SMatthew G. Knepley } 138531403186SMatthew G. Knepley } 138631403186SMatthew G. Knepley } 13879566063dSJacob Faibussowitsch PetscCall(DMSwarmRestoreField(dm, DMSwarmPICField_coor, NULL, NULL, (void **)&coords)); 13889566063dSJacob Faibussowitsch PetscCall(PetscFree5(centroid, xi0, v0, J, invJ)); 13899566063dSJacob Faibussowitsch PetscCall(PetscRandomDestroy(&rnd)); 139031403186SMatthew G. Knepley PetscFunctionReturn(0); 139131403186SMatthew G. Knepley } 139231403186SMatthew G. Knepley 139331403186SMatthew G. Knepley /*@ 1394d3a51819SDave May DMSwarmSetType - Set particular flavor of DMSwarm 1395d3a51819SDave May 1396d083f849SBarry Smith Collective on dm 1397d3a51819SDave May 1398d3a51819SDave May Input parameters: 139962741f57SDave May + dm - the DMSwarm 140062741f57SDave May - stype - the DMSwarm type (e.g. DMSWARM_PIC) 1401d3a51819SDave May 1402d3a51819SDave May Level: advanced 1403d3a51819SDave May 1404db781477SPatrick Sanan .seealso: `DMSwarmSetMigrateType()`, `DMSwarmSetCollectType()`, `DMSwarmType`, `DMSWARM_PIC`, `DMSWARM_BASIC` 1405d3a51819SDave May @*/ 14069371c9d4SSatish Balay PetscErrorCode DMSwarmSetType(DM dm, DMSwarmType stype) { 1407f0cdbbbaSDave May DM_Swarm *swarm = (DM_Swarm *)dm->data; 1408f0cdbbbaSDave May 1409521f74f9SMatthew G. Knepley PetscFunctionBegin; 1410f0cdbbbaSDave May swarm->swarm_type = stype; 141148a46eb9SPierre Jolivet if (swarm->swarm_type == DMSWARM_PIC) PetscCall(DMSwarmSetUpPIC(dm)); 1412f0cdbbbaSDave May PetscFunctionReturn(0); 1413f0cdbbbaSDave May } 1414f0cdbbbaSDave May 14159371c9d4SSatish Balay PetscErrorCode DMSetup_Swarm(DM dm) { 14163454631fSDave May DM_Swarm *swarm = (DM_Swarm *)dm->data; 14173454631fSDave May PetscMPIInt rank; 14183454631fSDave May PetscInt p, npoints, *rankval; 14193454631fSDave May 1420521f74f9SMatthew G. Knepley PetscFunctionBegin; 14213454631fSDave May if (swarm->issetup) PetscFunctionReturn(0); 14223454631fSDave May swarm->issetup = PETSC_TRUE; 14233454631fSDave May 1424f0cdbbbaSDave May if (swarm->swarm_type == DMSWARM_PIC) { 1425f0cdbbbaSDave May /* check dmcell exists */ 142628b400f6SJacob Faibussowitsch PetscCheck(swarm->dmcell, PetscObjectComm((PetscObject)dm), PETSC_ERR_USER, "DMSWARM_PIC requires you call DMSwarmSetCellDM"); 1427f0cdbbbaSDave May 1428f0cdbbbaSDave May if (swarm->dmcell->ops->locatepointssubdomain) { 1429f0cdbbbaSDave May /* check methods exists for exact ownership identificiation */ 14309566063dSJacob Faibussowitsch PetscCall(PetscInfo(dm, "DMSWARM_PIC: Using method CellDM->ops->LocatePointsSubdomain\n")); 1431f0cdbbbaSDave May swarm->migrate_type = DMSWARM_MIGRATE_DMCELLEXACT; 1432f0cdbbbaSDave May } else { 1433f0cdbbbaSDave May /* check methods exist for point location AND rank neighbor identification */ 1434f0cdbbbaSDave May if (swarm->dmcell->ops->locatepoints) { 14359566063dSJacob Faibussowitsch PetscCall(PetscInfo(dm, "DMSWARM_PIC: Using method CellDM->LocatePoints\n")); 1436f0cdbbbaSDave May } else SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_USER, "DMSWARM_PIC requires the method CellDM->ops->locatepoints be defined"); 1437f0cdbbbaSDave May 1438f0cdbbbaSDave May if (swarm->dmcell->ops->getneighbors) { 14399566063dSJacob Faibussowitsch PetscCall(PetscInfo(dm, "DMSWARM_PIC: Using method CellDM->GetNeigbors\n")); 1440f0cdbbbaSDave May } else SETERRQ(PetscObjectComm((PetscObject)dm), PETSC_ERR_USER, "DMSWARM_PIC requires the method CellDM->ops->getneighbors be defined"); 1441f0cdbbbaSDave May 1442f0cdbbbaSDave May swarm->migrate_type = DMSWARM_MIGRATE_DMCELLNSCATTER; 1443f0cdbbbaSDave May } 1444f0cdbbbaSDave May } 1445f0cdbbbaSDave May 14469566063dSJacob Faibussowitsch PetscCall(DMSwarmFinalizeFieldRegister(dm)); 1447f0cdbbbaSDave May 14483454631fSDave May /* check some fields were registered */ 144908401ef6SPierre Jolivet PetscCheck(swarm->db->nfields > 2, PetscObjectComm((PetscObject)dm), PETSC_ERR_USER, "At least one field user must be registered via DMSwarmRegisterXXX()"); 14503454631fSDave May 14513454631fSDave May /* check local sizes were set */ 145208401ef6SPierre Jolivet PetscCheck(swarm->db->L != -1, PetscObjectComm((PetscObject)dm), PETSC_ERR_USER, "Local sizes must be set via DMSwarmSetLocalSizes()"); 14533454631fSDave May 14543454631fSDave May /* initialize values in pid and rank placeholders */ 14553454631fSDave May /* TODO: [pid - use MPI_Scan] */ 14569566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)dm), &rank)); 14579566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketGetSizes(swarm->db, &npoints, NULL, NULL)); 14589566063dSJacob Faibussowitsch PetscCall(DMSwarmGetField(dm, DMSwarmField_rank, NULL, NULL, (void **)&rankval)); 1459ad540459SPierre Jolivet for (p = 0; p < npoints; p++) rankval[p] = (PetscInt)rank; 14609566063dSJacob Faibussowitsch PetscCall(DMSwarmRestoreField(dm, DMSwarmField_rank, NULL, NULL, (void **)&rankval)); 14613454631fSDave May PetscFunctionReturn(0); 14623454631fSDave May } 14633454631fSDave May 1464dc5f5ce9SDave May extern PetscErrorCode DMSwarmSortDestroy(DMSwarmSort *_ctx); 1465dc5f5ce9SDave May 14669371c9d4SSatish Balay PetscErrorCode DMDestroy_Swarm(DM dm) { 146757795646SDave May DM_Swarm *swarm = (DM_Swarm *)dm->data; 146857795646SDave May 146957795646SDave May PetscFunctionBegin; 1470d0c080abSJoseph Pusztay if (--swarm->refct > 0) PetscFunctionReturn(0); 14719566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketDestroy(&swarm->db)); 147248a46eb9SPierre Jolivet if (swarm->sort_context) PetscCall(DMSwarmSortDestroy(&swarm->sort_context)); 14739566063dSJacob Faibussowitsch PetscCall(PetscFree(swarm)); 147457795646SDave May PetscFunctionReturn(0); 147557795646SDave May } 147657795646SDave May 14779371c9d4SSatish Balay PetscErrorCode DMSwarmView_Draw(DM dm, PetscViewer viewer) { 1478a9ee3421SMatthew G. Knepley DM cdm; 1479a9ee3421SMatthew G. Knepley PetscDraw draw; 148031403186SMatthew G. Knepley PetscReal *coords, oldPause, radius = 0.01; 1481a9ee3421SMatthew G. Knepley PetscInt Np, p, bs; 1482a9ee3421SMatthew G. Knepley 1483a9ee3421SMatthew G. Knepley PetscFunctionBegin; 14849566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetReal(NULL, ((PetscObject)dm)->prefix, "-dm_view_swarm_radius", &radius, NULL)); 14859566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw)); 14869566063dSJacob Faibussowitsch PetscCall(DMSwarmGetCellDM(dm, &cdm)); 14879566063dSJacob Faibussowitsch PetscCall(PetscDrawGetPause(draw, &oldPause)); 14889566063dSJacob Faibussowitsch PetscCall(PetscDrawSetPause(draw, 0.0)); 14899566063dSJacob Faibussowitsch PetscCall(DMView(cdm, viewer)); 14909566063dSJacob Faibussowitsch PetscCall(PetscDrawSetPause(draw, oldPause)); 1491a9ee3421SMatthew G. Knepley 14929566063dSJacob Faibussowitsch PetscCall(DMSwarmGetLocalSize(dm, &Np)); 14939566063dSJacob Faibussowitsch PetscCall(DMSwarmGetField(dm, DMSwarmPICField_coor, &bs, NULL, (void **)&coords)); 1494a9ee3421SMatthew G. Knepley for (p = 0; p < Np; ++p) { 1495a9ee3421SMatthew G. Knepley const PetscInt i = p * bs; 1496a9ee3421SMatthew G. Knepley 14979566063dSJacob Faibussowitsch PetscCall(PetscDrawEllipse(draw, coords[i], coords[i + 1], radius, radius, PETSC_DRAW_BLUE)); 1498a9ee3421SMatthew G. Knepley } 14999566063dSJacob Faibussowitsch PetscCall(DMSwarmRestoreField(dm, DMSwarmPICField_coor, &bs, NULL, (void **)&coords)); 15009566063dSJacob Faibussowitsch PetscCall(PetscDrawFlush(draw)); 15019566063dSJacob Faibussowitsch PetscCall(PetscDrawPause(draw)); 15029566063dSJacob Faibussowitsch PetscCall(PetscDrawSave(draw)); 1503a9ee3421SMatthew G. Knepley PetscFunctionReturn(0); 1504a9ee3421SMatthew G. Knepley } 1505a9ee3421SMatthew G. Knepley 15069371c9d4SSatish Balay static PetscErrorCode DMView_Swarm_Ascii(DM dm, PetscViewer viewer) { 15076a5217c0SMatthew G. Knepley PetscViewerFormat format; 15086a5217c0SMatthew G. Knepley PetscInt *sizes; 15096a5217c0SMatthew G. Knepley PetscInt dim, Np, maxSize = 17; 15106a5217c0SMatthew G. Knepley MPI_Comm comm; 15116a5217c0SMatthew G. Knepley PetscMPIInt rank, size, p; 15126a5217c0SMatthew G. Knepley const char *name; 15136a5217c0SMatthew G. Knepley 15146a5217c0SMatthew G. Knepley PetscFunctionBegin; 15156a5217c0SMatthew G. Knepley PetscCall(PetscViewerGetFormat(viewer, &format)); 15166a5217c0SMatthew G. Knepley PetscCall(DMGetDimension(dm, &dim)); 15176a5217c0SMatthew G. Knepley PetscCall(DMSwarmGetLocalSize(dm, &Np)); 15186a5217c0SMatthew G. Knepley PetscCall(PetscObjectGetComm((PetscObject)dm, &comm)); 15196a5217c0SMatthew G. Knepley PetscCallMPI(MPI_Comm_rank(comm, &rank)); 15206a5217c0SMatthew G. Knepley PetscCallMPI(MPI_Comm_size(comm, &size)); 15216a5217c0SMatthew G. Knepley PetscCall(PetscObjectGetName((PetscObject)dm, &name)); 152263a3b9bcSJacob Faibussowitsch if (name) PetscCall(PetscViewerASCIIPrintf(viewer, "%s in %" PetscInt_FMT " dimension%s:\n", name, dim, dim == 1 ? "" : "s")); 152363a3b9bcSJacob Faibussowitsch else PetscCall(PetscViewerASCIIPrintf(viewer, "Swarm in %" PetscInt_FMT " dimension%s:\n", dim, dim == 1 ? "" : "s")); 15246a5217c0SMatthew G. Knepley if (size < maxSize) PetscCall(PetscCalloc1(size, &sizes)); 15256a5217c0SMatthew G. Knepley else PetscCall(PetscCalloc1(3, &sizes)); 15266a5217c0SMatthew G. Knepley if (size < maxSize) { 15276a5217c0SMatthew G. Knepley PetscCallMPI(MPI_Gather(&Np, 1, MPIU_INT, sizes, 1, MPIU_INT, 0, comm)); 15286a5217c0SMatthew G. Knepley PetscCall(PetscViewerASCIIPrintf(viewer, " Number of particles per rank:")); 15296a5217c0SMatthew G. Knepley for (p = 0; p < size; ++p) { 15306a5217c0SMatthew G. Knepley if (rank == 0) PetscCall(PetscViewerASCIIPrintf(viewer, " %" PetscInt_FMT, sizes[p])); 15316a5217c0SMatthew G. Knepley } 15326a5217c0SMatthew G. Knepley } else { 15336a5217c0SMatthew G. Knepley PetscInt locMinMax[2] = {Np, Np}; 15346a5217c0SMatthew G. Knepley 15356a5217c0SMatthew G. Knepley PetscCall(PetscGlobalMinMaxInt(comm, locMinMax, sizes)); 15366a5217c0SMatthew G. Knepley PetscCall(PetscViewerASCIIPrintf(viewer, " Min/Max of particles per rank: %" PetscInt_FMT "/%" PetscInt_FMT, sizes[0], sizes[1])); 15376a5217c0SMatthew G. Knepley } 15386a5217c0SMatthew G. Knepley PetscCall(PetscViewerASCIIPrintf(viewer, "\n")); 15396a5217c0SMatthew G. Knepley PetscCall(PetscFree(sizes)); 15406a5217c0SMatthew G. Knepley if (format == PETSC_VIEWER_ASCII_INFO) { 15416a5217c0SMatthew G. Knepley PetscInt *cell; 15426a5217c0SMatthew G. Knepley 15436a5217c0SMatthew G. Knepley PetscCall(PetscViewerASCIIPrintf(viewer, " Cells containing each particle:\n")); 15446a5217c0SMatthew G. Knepley PetscCall(PetscViewerASCIIPushSynchronized(viewer)); 15456a5217c0SMatthew G. Knepley PetscCall(DMSwarmGetField(dm, DMSwarmPICField_cellid, NULL, NULL, (void **)&cell)); 154663a3b9bcSJacob Faibussowitsch for (p = 0; p < Np; ++p) PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, " p%d: %" PetscInt_FMT "\n", p, cell[p])); 15476a5217c0SMatthew G. Knepley PetscCall(PetscViewerFlush(viewer)); 15486a5217c0SMatthew G. Knepley PetscCall(PetscViewerASCIIPopSynchronized(viewer)); 15496a5217c0SMatthew G. Knepley PetscCall(DMSwarmRestoreField(dm, DMSwarmPICField_cellid, NULL, NULL, (void **)&cell)); 15506a5217c0SMatthew G. Knepley } 15516a5217c0SMatthew G. Knepley PetscFunctionReturn(0); 15526a5217c0SMatthew G. Knepley } 15536a5217c0SMatthew G. Knepley 15549371c9d4SSatish Balay PetscErrorCode DMView_Swarm(DM dm, PetscViewer viewer) { 15555f50eb2eSDave May DM_Swarm *swarm = (DM_Swarm *)dm->data; 15565627991aSBarry Smith PetscBool iascii, ibinary, isvtk, isdraw; 15575627991aSBarry Smith #if defined(PETSC_HAVE_HDF5) 15585627991aSBarry Smith PetscBool ishdf5; 15595627991aSBarry Smith #endif 15605f50eb2eSDave May 15615f50eb2eSDave May PetscFunctionBegin; 15625f50eb2eSDave May PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 15635f50eb2eSDave May PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 15649566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 15659566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &ibinary)); 15669566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERVTK, &isvtk)); 15675627991aSBarry Smith #if defined(PETSC_HAVE_HDF5) 15689566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5, &ishdf5)); 15695627991aSBarry Smith #endif 15709566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw)); 15715f50eb2eSDave May if (iascii) { 15726a5217c0SMatthew G. Knepley PetscViewerFormat format; 15736a5217c0SMatthew G. Knepley 15746a5217c0SMatthew G. Knepley PetscCall(PetscViewerGetFormat(viewer, &format)); 15756a5217c0SMatthew G. Knepley switch (format) { 15769371c9d4SSatish Balay case PETSC_VIEWER_ASCII_INFO_DETAIL: PetscCall(DMSwarmDataBucketView(PetscObjectComm((PetscObject)dm), swarm->db, NULL, DATABUCKET_VIEW_STDOUT)); break; 15776a5217c0SMatthew G. Knepley default: PetscCall(DMView_Swarm_Ascii(dm, viewer)); 15786a5217c0SMatthew G. Knepley } 1579f7d195e4SLawrence Mitchell } else { 15805f50eb2eSDave May #if defined(PETSC_HAVE_HDF5) 158148a46eb9SPierre Jolivet if (ishdf5) PetscCall(DMSwarmView_HDF5(dm, viewer)); 15825f50eb2eSDave May #endif 158348a46eb9SPierre Jolivet if (isdraw) PetscCall(DMSwarmView_Draw(dm, viewer)); 1584f7d195e4SLawrence Mitchell } 15855f50eb2eSDave May PetscFunctionReturn(0); 15865f50eb2eSDave May } 15875f50eb2eSDave May 1588d0c080abSJoseph Pusztay /*@C 1589d0c080abSJoseph Pusztay DMSwarmGetCellSwarm - Extracts a single cell from the DMSwarm object, returns it as a single cell DMSwarm. 1590d0c080abSJoseph Pusztay The cell DM is filtered for fields of that cell, and the filtered DM is used as the cell DM of the new swarm object. 1591d0c080abSJoseph Pusztay 1592d0c080abSJoseph Pusztay Important: Changes to this cell of the swarm will be lost if they are made prior to restoring this cell. 1593d0c080abSJoseph Pusztay 1594d0c080abSJoseph Pusztay Noncollective 1595d0c080abSJoseph Pusztay 1596d0c080abSJoseph Pusztay Input parameters: 1597d0c080abSJoseph Pusztay + sw - the DMSwarm 15985627991aSBarry Smith . cellID - the integer id of the cell to be extracted and filtered 15995627991aSBarry Smith - cellswarm - The DMSwarm to receive the cell 1600d0c080abSJoseph Pusztay 1601d0c080abSJoseph Pusztay Level: beginner 1602d0c080abSJoseph Pusztay 16035627991aSBarry Smith Notes: 16045627991aSBarry Smith This presently only supports DMSWARM_PIC type 16055627991aSBarry Smith 16065627991aSBarry Smith Should be restored with DMSwarmRestoreCellSwarm() 1607d0c080abSJoseph Pusztay 1608db781477SPatrick Sanan .seealso: `DMSwarmRestoreCellSwarm()` 1609d0c080abSJoseph Pusztay @*/ 16109371c9d4SSatish Balay PETSC_EXTERN PetscErrorCode DMSwarmGetCellSwarm(DM sw, PetscInt cellID, DM cellswarm) { 1611d0c080abSJoseph Pusztay DM_Swarm *original = (DM_Swarm *)sw->data; 1612d0c080abSJoseph Pusztay DMLabel label; 1613d0c080abSJoseph Pusztay DM dmc, subdmc; 1614d0c080abSJoseph Pusztay PetscInt *pids, particles, dim; 1615d0c080abSJoseph Pusztay 1616d0c080abSJoseph Pusztay PetscFunctionBegin; 1617d0c080abSJoseph Pusztay /* Configure new swarm */ 16189566063dSJacob Faibussowitsch PetscCall(DMSetType(cellswarm, DMSWARM)); 16199566063dSJacob Faibussowitsch PetscCall(DMGetDimension(sw, &dim)); 16209566063dSJacob Faibussowitsch PetscCall(DMSetDimension(cellswarm, dim)); 16219566063dSJacob Faibussowitsch PetscCall(DMSwarmSetType(cellswarm, DMSWARM_PIC)); 1622d0c080abSJoseph Pusztay /* Destroy the unused, unconfigured data bucket to prevent stragglers in memory */ 16239566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketDestroy(&((DM_Swarm *)cellswarm->data)->db)); 16249566063dSJacob Faibussowitsch PetscCall(DMSwarmSortGetAccess(sw)); 16259566063dSJacob Faibussowitsch PetscCall(DMSwarmSortGetNumberOfPointsPerCell(sw, cellID, &particles)); 16269566063dSJacob Faibussowitsch PetscCall(DMSwarmSortGetPointsPerCell(sw, cellID, &particles, &pids)); 16279566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketCreateFromSubset(original->db, particles, pids, &((DM_Swarm *)cellswarm->data)->db)); 16289566063dSJacob Faibussowitsch PetscCall(DMSwarmSortRestoreAccess(sw)); 16299566063dSJacob Faibussowitsch PetscCall(PetscFree(pids)); 16309566063dSJacob Faibussowitsch PetscCall(DMSwarmGetCellDM(sw, &dmc)); 16319566063dSJacob Faibussowitsch PetscCall(DMLabelCreate(PetscObjectComm((PetscObject)sw), "singlecell", &label)); 16329566063dSJacob Faibussowitsch PetscCall(DMAddLabel(dmc, label)); 16339566063dSJacob Faibussowitsch PetscCall(DMLabelSetValue(label, cellID, 1)); 16349566063dSJacob Faibussowitsch PetscCall(DMPlexFilter(dmc, label, 1, &subdmc)); 16359566063dSJacob Faibussowitsch PetscCall(DMSwarmSetCellDM(cellswarm, subdmc)); 16369566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&label)); 1637d0c080abSJoseph Pusztay PetscFunctionReturn(0); 1638d0c080abSJoseph Pusztay } 1639d0c080abSJoseph Pusztay 1640d0c080abSJoseph Pusztay /*@C 16415627991aSBarry Smith DMSwarmRestoreCellSwarm - Restores a DMSwarm object obtained with DMSwarmGetCellSwarm(). All fields are copied back into the parent swarm. 1642d0c080abSJoseph Pusztay 1643d0c080abSJoseph Pusztay Noncollective 1644d0c080abSJoseph Pusztay 1645d0c080abSJoseph Pusztay Input parameters: 1646d0c080abSJoseph Pusztay + sw - the parent DMSwarm 1647d0c080abSJoseph Pusztay . cellID - the integer id of the cell to be copied back into the parent swarm 1648d0c080abSJoseph Pusztay - cellswarm - the cell swarm object 1649d0c080abSJoseph Pusztay 1650d0c080abSJoseph Pusztay Level: beginner 1651d0c080abSJoseph Pusztay 16525627991aSBarry Smith Note: 16535627991aSBarry Smith This only supports DMSWARM_PIC types of DMSwarms 1654d0c080abSJoseph Pusztay 1655db781477SPatrick Sanan .seealso: `DMSwarmGetCellSwarm()` 1656d0c080abSJoseph Pusztay @*/ 16579371c9d4SSatish Balay PETSC_EXTERN PetscErrorCode DMSwarmRestoreCellSwarm(DM sw, PetscInt cellID, DM cellswarm) { 1658d0c080abSJoseph Pusztay DM dmc; 1659d0c080abSJoseph Pusztay PetscInt *pids, particles, p; 1660d0c080abSJoseph Pusztay 1661d0c080abSJoseph Pusztay PetscFunctionBegin; 16629566063dSJacob Faibussowitsch PetscCall(DMSwarmSortGetAccess(sw)); 16639566063dSJacob Faibussowitsch PetscCall(DMSwarmSortGetPointsPerCell(sw, cellID, &particles, &pids)); 16649566063dSJacob Faibussowitsch PetscCall(DMSwarmSortRestoreAccess(sw)); 1665d0c080abSJoseph Pusztay /* Pointwise copy of each particle based on pid. The parent swarm may not be altered during this process. */ 166648a46eb9SPierre Jolivet for (p = 0; p < particles; ++p) PetscCall(DMSwarmDataBucketCopyPoint(((DM_Swarm *)cellswarm->data)->db, pids[p], ((DM_Swarm *)sw->data)->db, pids[p])); 1667d0c080abSJoseph Pusztay /* Free memory, destroy cell dm */ 16689566063dSJacob Faibussowitsch PetscCall(DMSwarmGetCellDM(cellswarm, &dmc)); 16699566063dSJacob Faibussowitsch PetscCall(DMDestroy(&dmc)); 16709566063dSJacob Faibussowitsch PetscCall(PetscFree(pids)); 1671d0c080abSJoseph Pusztay PetscFunctionReturn(0); 1672d0c080abSJoseph Pusztay } 1673d0c080abSJoseph Pusztay 1674d0c080abSJoseph Pusztay PETSC_INTERN PetscErrorCode DMClone_Swarm(DM, DM *); 1675d0c080abSJoseph Pusztay 16769371c9d4SSatish Balay static PetscErrorCode DMInitialize_Swarm(DM sw) { 1677d0c080abSJoseph Pusztay PetscFunctionBegin; 1678d0c080abSJoseph Pusztay sw->dim = 0; 1679d0c080abSJoseph Pusztay sw->ops->view = DMView_Swarm; 1680d0c080abSJoseph Pusztay sw->ops->load = NULL; 1681d0c080abSJoseph Pusztay sw->ops->setfromoptions = NULL; 1682d0c080abSJoseph Pusztay sw->ops->clone = DMClone_Swarm; 1683d0c080abSJoseph Pusztay sw->ops->setup = DMSetup_Swarm; 1684d0c080abSJoseph Pusztay sw->ops->createlocalsection = NULL; 1685d0c080abSJoseph Pusztay sw->ops->createdefaultconstraints = NULL; 1686d0c080abSJoseph Pusztay sw->ops->createglobalvector = DMCreateGlobalVector_Swarm; 1687d0c080abSJoseph Pusztay sw->ops->createlocalvector = DMCreateLocalVector_Swarm; 1688d0c080abSJoseph Pusztay sw->ops->getlocaltoglobalmapping = NULL; 1689d0c080abSJoseph Pusztay sw->ops->createfieldis = NULL; 1690d0c080abSJoseph Pusztay sw->ops->createcoordinatedm = NULL; 1691d0c080abSJoseph Pusztay sw->ops->getcoloring = NULL; 1692d0c080abSJoseph Pusztay sw->ops->creatematrix = DMCreateMatrix_Swarm; 1693d0c080abSJoseph Pusztay sw->ops->createinterpolation = NULL; 1694d0c080abSJoseph Pusztay sw->ops->createinjection = NULL; 1695d0c080abSJoseph Pusztay sw->ops->createmassmatrix = DMCreateMassMatrix_Swarm; 1696d0c080abSJoseph Pusztay sw->ops->refine = NULL; 1697d0c080abSJoseph Pusztay sw->ops->coarsen = NULL; 1698d0c080abSJoseph Pusztay sw->ops->refinehierarchy = NULL; 1699d0c080abSJoseph Pusztay sw->ops->coarsenhierarchy = NULL; 1700d0c080abSJoseph Pusztay sw->ops->globaltolocalbegin = NULL; 1701d0c080abSJoseph Pusztay sw->ops->globaltolocalend = NULL; 1702d0c080abSJoseph Pusztay sw->ops->localtoglobalbegin = NULL; 1703d0c080abSJoseph Pusztay sw->ops->localtoglobalend = NULL; 1704d0c080abSJoseph Pusztay sw->ops->destroy = DMDestroy_Swarm; 1705d0c080abSJoseph Pusztay sw->ops->createsubdm = NULL; 1706d0c080abSJoseph Pusztay sw->ops->getdimpoints = NULL; 1707d0c080abSJoseph Pusztay sw->ops->locatepoints = NULL; 1708d0c080abSJoseph Pusztay PetscFunctionReturn(0); 1709d0c080abSJoseph Pusztay } 1710d0c080abSJoseph Pusztay 17119371c9d4SSatish Balay PETSC_INTERN PetscErrorCode DMClone_Swarm(DM dm, DM *newdm) { 1712d0c080abSJoseph Pusztay DM_Swarm *swarm = (DM_Swarm *)dm->data; 1713d0c080abSJoseph Pusztay 1714d0c080abSJoseph Pusztay PetscFunctionBegin; 1715d0c080abSJoseph Pusztay swarm->refct++; 1716d0c080abSJoseph Pusztay (*newdm)->data = swarm; 17179566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject)*newdm, DMSWARM)); 17189566063dSJacob Faibussowitsch PetscCall(DMInitialize_Swarm(*newdm)); 17192e56dffeSJoe Pusztay (*newdm)->dim = dm->dim; 1720d0c080abSJoseph Pusztay PetscFunctionReturn(0); 1721d0c080abSJoseph Pusztay } 1722d0c080abSJoseph Pusztay 1723d3a51819SDave May /*MC 1724d3a51819SDave May 1725d3a51819SDave May DMSWARM = "swarm" - A DM object used to represent arrays of data (fields) of arbitrary data type. 172662741f57SDave May This implementation was designed for particle methods in which the underlying 1727d3a51819SDave May data required to be represented is both (i) dynamic in length, (ii) and of arbitrary data type. 1728d3a51819SDave May 172962741f57SDave May User data can be represented by DMSwarm through a registering "fields". 173062741f57SDave May To register a field, the user must provide; 173162741f57SDave May (a) a unique name; 173262741f57SDave May (b) the data type (or size in bytes); 173362741f57SDave May (c) the block size of the data. 1734d3a51819SDave May 1735d3a51819SDave May For example, suppose the application requires a unique id, energy, momentum and density to be stored 1736c215a47eSMatthew Knepley on a set of particles. Then the following code could be used 1737d3a51819SDave May 173862741f57SDave May $ DMSwarmInitializeFieldRegister(dm) 173962741f57SDave May $ DMSwarmRegisterPetscDatatypeField(dm,"uid",1,PETSC_LONG); 174062741f57SDave May $ DMSwarmRegisterPetscDatatypeField(dm,"energy",1,PETSC_REAL); 174162741f57SDave May $ DMSwarmRegisterPetscDatatypeField(dm,"momentum",3,PETSC_REAL); 174262741f57SDave May $ DMSwarmRegisterPetscDatatypeField(dm,"density",1,PETSC_FLOAT); 174362741f57SDave May $ DMSwarmFinalizeFieldRegister(dm) 1744d3a51819SDave May 1745d3a51819SDave May The fields represented by DMSwarm are dynamic and can be re-sized at any time. 174662741f57SDave May The only restriction imposed by DMSwarm is that all fields contain the same number of points. 1747d3a51819SDave May 1748d3a51819SDave May To support particle methods, "migration" techniques are provided. These methods migrate data 17495627991aSBarry Smith between ranks. 1750d3a51819SDave May 1751d3a51819SDave May DMSwarm supports the methods DMCreateGlobalVector() and DMCreateLocalVector(). 1752d3a51819SDave May As a DMSwarm may internally define and store values of different data types, 175362741f57SDave May before calling DMCreateGlobalVector() or DMCreateLocalVector(), the user must inform DMSwarm which 1754d3a51819SDave May fields should be used to define a Vec object via 1755d3a51819SDave May DMSwarmVectorDefineField() 1756c215a47eSMatthew Knepley The specified field can be changed at any time - thereby permitting vectors 1757c215a47eSMatthew Knepley compatible with different fields to be created. 1758d3a51819SDave May 175962741f57SDave May A dual representation of fields in the DMSwarm and a Vec object is permitted via 1760d3a51819SDave May DMSwarmCreateGlobalVectorFromField() 1761d3a51819SDave May Here the data defining the field in the DMSwarm is shared with a Vec. 1762d3a51819SDave May This is inherently unsafe if you alter the size of the field at any time between 1763d3a51819SDave May calls to DMSwarmCreateGlobalVectorFromField() and DMSwarmDestroyGlobalVectorFromField(). 1764cc651181SDave May If the local size of the DMSwarm does not match the local size of the global vector 1765cc651181SDave May when DMSwarmDestroyGlobalVectorFromField() is called, an error is thrown. 1766d3a51819SDave May 176762741f57SDave May Additional high-level support is provided for Particle-In-Cell methods. 176862741f57SDave May Please refer to the man page for DMSwarmSetType(). 176962741f57SDave May 1770d3a51819SDave May Level: beginner 1771d3a51819SDave May 1772db781477SPatrick Sanan .seealso: `DMType`, `DMCreate()`, `DMSetType()` 1773d3a51819SDave May M*/ 17749371c9d4SSatish Balay PETSC_EXTERN PetscErrorCode DMCreate_Swarm(DM dm) { 177557795646SDave May DM_Swarm *swarm; 177657795646SDave May 177757795646SDave May PetscFunctionBegin; 177857795646SDave May PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 1779*4dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&swarm)); 1780f0cdbbbaSDave May dm->data = swarm; 17819566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketCreate(&swarm->db)); 17829566063dSJacob Faibussowitsch PetscCall(DMSwarmInitializeFieldRegister(dm)); 1783d0c080abSJoseph Pusztay swarm->refct = 1; 1784b5bcf523SDave May swarm->vec_field_set = PETSC_FALSE; 17853454631fSDave May swarm->issetup = PETSC_FALSE; 1786480eef7bSDave May swarm->swarm_type = DMSWARM_BASIC; 1787480eef7bSDave May swarm->migrate_type = DMSWARM_MIGRATE_BASIC; 1788480eef7bSDave May swarm->collect_type = DMSWARM_COLLECT_BASIC; 178940c453e9SDave May swarm->migrate_error_on_missing_point = PETSC_FALSE; 1790f0cdbbbaSDave May swarm->dmcell = NULL; 1791f0cdbbbaSDave May swarm->collect_view_active = PETSC_FALSE; 1792f0cdbbbaSDave May swarm->collect_view_reset_nlocal = -1; 17939566063dSJacob Faibussowitsch PetscCall(DMInitialize_Swarm(dm)); 17942e956fe4SStefano Zampini if (SwarmDataFieldId == -1) PetscCall(PetscObjectComposedDataRegister(&SwarmDataFieldId)); 179557795646SDave May PetscFunctionReturn(0); 179657795646SDave May } 1797