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 27*2e956fe4SStefano Zampini PetscInt SwarmDataFieldId = -1; 28*2e956fe4SStefano Zampini 2974d0cae8SMatthew G. Knepley #if defined(PETSC_HAVE_HDF5) 3074d0cae8SMatthew G. Knepley #include <petscviewerhdf5.h> 3174d0cae8SMatthew G. Knepley 3274d0cae8SMatthew G. Knepley PetscErrorCode VecView_Swarm_HDF5_Internal(Vec v, PetscViewer viewer) 3374d0cae8SMatthew G. Knepley { 3474d0cae8SMatthew G. Knepley DM dm; 3574d0cae8SMatthew G. Knepley PetscReal seqval; 3674d0cae8SMatthew G. Knepley PetscInt seqnum, bs; 3774d0cae8SMatthew G. Knepley PetscBool isseq; 3874d0cae8SMatthew G. Knepley 3974d0cae8SMatthew G. Knepley PetscFunctionBegin; 409566063dSJacob Faibussowitsch PetscCall(VecGetDM(v, &dm)); 419566063dSJacob Faibussowitsch PetscCall(VecGetBlockSize(v, &bs)); 429566063dSJacob Faibussowitsch PetscCall(PetscViewerHDF5PushGroup(viewer, "/particle_fields")); 439566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject) v, VECSEQ, &isseq)); 449566063dSJacob Faibussowitsch PetscCall(DMGetOutputSequenceNumber(dm, &seqnum, &seqval)); 459566063dSJacob Faibussowitsch PetscCall(PetscViewerHDF5SetTimestep(viewer, seqnum)); 469566063dSJacob Faibussowitsch /* PetscCall(DMSequenceView_HDF5(dm, "time", seqnum, (PetscScalar) seqval, viewer)); */ 479566063dSJacob Faibussowitsch PetscCall(VecViewNative(v, viewer)); 489566063dSJacob Faibussowitsch PetscCall(PetscViewerHDF5WriteObjectAttribute(viewer, (PetscObject) v, "Nc", PETSC_INT, (void *) &bs)); 499566063dSJacob Faibussowitsch PetscCall(PetscViewerHDF5PopGroup(viewer)); 5074d0cae8SMatthew G. Knepley PetscFunctionReturn(0); 5174d0cae8SMatthew G. Knepley } 5274d0cae8SMatthew G. Knepley 5374d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmView_HDF5(DM dm, PetscViewer viewer) 5474d0cae8SMatthew G. Knepley { 5574d0cae8SMatthew G. Knepley Vec coordinates; 5674d0cae8SMatthew G. Knepley PetscInt Np; 5774d0cae8SMatthew G. Knepley PetscBool isseq; 5874d0cae8SMatthew G. Knepley 5974d0cae8SMatthew G. Knepley PetscFunctionBegin; 609566063dSJacob Faibussowitsch PetscCall(DMSwarmGetSize(dm, &Np)); 619566063dSJacob Faibussowitsch PetscCall(DMSwarmCreateGlobalVectorFromField(dm, DMSwarmPICField_coor, &coordinates)); 629566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject) coordinates, "coordinates")); 639566063dSJacob Faibussowitsch PetscCall(PetscViewerHDF5PushGroup(viewer, "/particles")); 649566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject) coordinates, VECSEQ, &isseq)); 659566063dSJacob Faibussowitsch PetscCall(VecViewNative(coordinates, viewer)); 669566063dSJacob Faibussowitsch PetscCall(PetscViewerHDF5WriteObjectAttribute(viewer, (PetscObject) coordinates, "Np", PETSC_INT, (void *) &Np)); 679566063dSJacob Faibussowitsch PetscCall(PetscViewerHDF5PopGroup(viewer)); 689566063dSJacob Faibussowitsch PetscCall(DMSwarmDestroyGlobalVectorFromField(dm, DMSwarmPICField_coor, &coordinates)); 6974d0cae8SMatthew G. Knepley PetscFunctionReturn(0); 7074d0cae8SMatthew G. Knepley } 7174d0cae8SMatthew G. Knepley #endif 7274d0cae8SMatthew G. Knepley 7374d0cae8SMatthew G. Knepley PetscErrorCode VecView_Swarm(Vec v, PetscViewer viewer) 7474d0cae8SMatthew G. Knepley { 7574d0cae8SMatthew G. Knepley DM dm; 76f9558f5cSBarry Smith #if defined(PETSC_HAVE_HDF5) 7774d0cae8SMatthew G. Knepley PetscBool ishdf5; 78f9558f5cSBarry Smith #endif 7974d0cae8SMatthew G. Knepley 8074d0cae8SMatthew G. Knepley PetscFunctionBegin; 819566063dSJacob Faibussowitsch PetscCall(VecGetDM(v, &dm)); 8228b400f6SJacob Faibussowitsch PetscCheck(dm,PetscObjectComm((PetscObject)v), PETSC_ERR_ARG_WRONG, "Vector not generated from a DM"); 83f9558f5cSBarry Smith #if defined(PETSC_HAVE_HDF5) 849566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERHDF5, &ishdf5)); 8574d0cae8SMatthew G. Knepley if (ishdf5) { 869566063dSJacob Faibussowitsch PetscCall(VecView_Swarm_HDF5_Internal(v, viewer)); 87f9558f5cSBarry Smith PetscFunctionReturn(0); 8874d0cae8SMatthew G. Knepley } 89f9558f5cSBarry Smith #endif 909566063dSJacob Faibussowitsch PetscCall(VecViewNative(v, viewer)); 9174d0cae8SMatthew G. Knepley PetscFunctionReturn(0); 9274d0cae8SMatthew G. Knepley } 9374d0cae8SMatthew G. Knepley 94d3a51819SDave May /*@C 9562741f57SDave May DMSwarmVectorDefineField - Sets the field from which to define a Vec object 9662741f57SDave May when DMCreateLocalVector(), or DMCreateGlobalVector() is called 9757795646SDave May 98d083f849SBarry Smith Collective on dm 9957795646SDave May 100d3a51819SDave May Input parameters: 10162741f57SDave May + dm - a DMSwarm 10262741f57SDave May - fieldname - the textual name given to a registered field 10357795646SDave May 104d3a51819SDave May Level: beginner 10557795646SDave May 106d3a51819SDave May Notes: 107e7af74c8SDave May 10862741f57SDave May The field with name fieldname must be defined as having a data type of PetscScalar. 109e7af74c8SDave May 110d3a51819SDave May This function must be called prior to calling DMCreateLocalVector(), DMCreateGlobalVector(). 111d3a51819SDave May Mutiple calls to DMSwarmVectorDefineField() are permitted. 11257795646SDave May 113db781477SPatrick Sanan .seealso: `DMSwarmRegisterPetscDatatypeField()`, `DMCreateGlobalVector()`, `DMCreateLocalVector()` 114d3a51819SDave May @*/ 11574d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmVectorDefineField(DM dm,const char fieldname[]) 116b5bcf523SDave May { 117b5bcf523SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 118b5bcf523SDave May PetscInt bs,n; 119b5bcf523SDave May PetscScalar *array; 120b5bcf523SDave May PetscDataType type; 121b5bcf523SDave May 122a9cbaee5SMatthew G. Knepley PetscFunctionBegin; 1239566063dSJacob Faibussowitsch if (!swarm->issetup) PetscCall(DMSetUp(dm)); 1249566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketGetSizes(swarm->db,&n,NULL,NULL)); 1259566063dSJacob Faibussowitsch PetscCall(DMSwarmGetField(dm,fieldname,&bs,&type,(void**)&array)); 126b5bcf523SDave May 127b5bcf523SDave May /* Check all fields are of type PETSC_REAL or PETSC_SCALAR */ 12808401ef6SPierre Jolivet PetscCheck(type == PETSC_REAL,PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Only valid for PETSC_REAL"); 1299566063dSJacob Faibussowitsch PetscCall(PetscSNPrintf(swarm->vec_field_name,PETSC_MAX_PATH_LEN-1,"%s",fieldname)); 130b5bcf523SDave May swarm->vec_field_set = PETSC_TRUE; 1311b1ea282SDave May swarm->vec_field_bs = bs; 132b5bcf523SDave May swarm->vec_field_nlocal = n; 1339566063dSJacob Faibussowitsch PetscCall(DMSwarmRestoreField(dm,fieldname,&bs,&type,(void**)&array)); 134b5bcf523SDave May PetscFunctionReturn(0); 135b5bcf523SDave May } 136b5bcf523SDave May 137cc651181SDave May /* requires DMSwarmDefineFieldVector has been called */ 138b5bcf523SDave May PetscErrorCode DMCreateGlobalVector_Swarm(DM dm,Vec *vec) 139b5bcf523SDave May { 140b5bcf523SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 141b5bcf523SDave May Vec x; 142b5bcf523SDave May char name[PETSC_MAX_PATH_LEN]; 143b5bcf523SDave May 144a9cbaee5SMatthew G. Knepley PetscFunctionBegin; 1459566063dSJacob Faibussowitsch if (!swarm->issetup) PetscCall(DMSetUp(dm)); 14628b400f6SJacob Faibussowitsch PetscCheck(swarm->vec_field_set,PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMSwarmVectorDefineField first"); 14708401ef6SPierre 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 */ 148cc651181SDave May 1499566063dSJacob Faibussowitsch PetscCall(PetscSNPrintf(name,PETSC_MAX_PATH_LEN-1,"DMSwarmField_%s",swarm->vec_field_name)); 1509566063dSJacob Faibussowitsch PetscCall(VecCreate(PetscObjectComm((PetscObject)dm),&x)); 1519566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)x,name)); 1529566063dSJacob Faibussowitsch PetscCall(VecSetSizes(x,swarm->db->L*swarm->vec_field_bs,PETSC_DETERMINE)); 1539566063dSJacob Faibussowitsch PetscCall(VecSetBlockSize(x,swarm->vec_field_bs)); 1549566063dSJacob Faibussowitsch PetscCall(VecSetDM(x,dm)); 1559566063dSJacob Faibussowitsch PetscCall(VecSetFromOptions(x)); 1569566063dSJacob Faibussowitsch PetscCall(VecSetDM(x, dm)); 1579566063dSJacob Faibussowitsch PetscCall(VecSetOperation(x, VECOP_VIEW, (void (*)(void)) VecView_Swarm)); 158b5bcf523SDave May *vec = x; 159b5bcf523SDave May PetscFunctionReturn(0); 160b5bcf523SDave May } 161b5bcf523SDave May 162b5bcf523SDave May /* requires DMSwarmDefineFieldVector has been called */ 163b5bcf523SDave May PetscErrorCode DMCreateLocalVector_Swarm(DM dm,Vec *vec) 164b5bcf523SDave May { 165b5bcf523SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 166b5bcf523SDave May Vec x; 167b5bcf523SDave May char name[PETSC_MAX_PATH_LEN]; 168b5bcf523SDave May 169a9cbaee5SMatthew G. Knepley PetscFunctionBegin; 1709566063dSJacob Faibussowitsch if (!swarm->issetup) PetscCall(DMSetUp(dm)); 17128b400f6SJacob Faibussowitsch PetscCheck(swarm->vec_field_set,PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMSwarmVectorDefineField first"); 17208401ef6SPierre 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"); 173cc651181SDave May 1749566063dSJacob Faibussowitsch PetscCall(PetscSNPrintf(name,PETSC_MAX_PATH_LEN-1,"DMSwarmField_%s",swarm->vec_field_name)); 1759566063dSJacob Faibussowitsch PetscCall(VecCreate(PETSC_COMM_SELF,&x)); 1769566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject)x,name)); 1779566063dSJacob Faibussowitsch PetscCall(VecSetSizes(x,swarm->db->L*swarm->vec_field_bs,PETSC_DETERMINE)); 1789566063dSJacob Faibussowitsch PetscCall(VecSetBlockSize(x,swarm->vec_field_bs)); 1799566063dSJacob Faibussowitsch PetscCall(VecSetDM(x,dm)); 1809566063dSJacob Faibussowitsch PetscCall(VecSetFromOptions(x)); 181b5bcf523SDave May *vec = x; 182b5bcf523SDave May PetscFunctionReturn(0); 183b5bcf523SDave May } 184b5bcf523SDave May 185fb1bcc12SMatthew G. Knepley static PetscErrorCode DMSwarmDestroyVectorFromField_Private(DM dm, const char fieldname[], Vec *vec) 186fb1bcc12SMatthew G. Knepley { 187fb1bcc12SMatthew G. Knepley DM_Swarm *swarm = (DM_Swarm *) dm->data; 18877048351SPatrick Sanan DMSwarmDataField gfield; 189*2e956fe4SStefano Zampini PetscInt bs, nlocal, fid = -1, cfid = -2; 190*2e956fe4SStefano Zampini PetscBool flg; 191d3a51819SDave May 192fb1bcc12SMatthew G. Knepley PetscFunctionBegin; 193*2e956fe4SStefano Zampini /* check vector is an inplace array */ 194*2e956fe4SStefano Zampini PetscCall(DMSwarmDataBucketGetDMSwarmDataFieldIdByName(swarm->db, fieldname, &fid)); 195*2e956fe4SStefano Zampini PetscCall(PetscObjectComposedDataGetInt((PetscObject)*vec, SwarmDataFieldId, cfid, flg)); 196*2e956fe4SStefano 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); 1979566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(*vec, &nlocal)); 1989566063dSJacob Faibussowitsch PetscCall(VecGetBlockSize(*vec, &bs)); 19908401ef6SPierre 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"); 2009566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketGetDMSwarmDataFieldByName(swarm->db, fieldname, &gfield)); 2019566063dSJacob Faibussowitsch PetscCall(DMSwarmDataFieldRestoreAccess(gfield)); 2028df78e51SMark Adams PetscCall(VecResetArray(*vec)); 2039566063dSJacob Faibussowitsch PetscCall(VecDestroy(vec)); 204fb1bcc12SMatthew G. Knepley PetscFunctionReturn(0); 205fb1bcc12SMatthew G. Knepley } 206fb1bcc12SMatthew G. Knepley 207fb1bcc12SMatthew G. Knepley static PetscErrorCode DMSwarmCreateVectorFromField_Private(DM dm, const char fieldname[], MPI_Comm comm, Vec *vec) 208fb1bcc12SMatthew G. Knepley { 209fb1bcc12SMatthew G. Knepley DM_Swarm *swarm = (DM_Swarm *) dm->data; 210fb1bcc12SMatthew G. Knepley PetscDataType type; 211fb1bcc12SMatthew G. Knepley PetscScalar *array; 212*2e956fe4SStefano Zampini PetscInt bs, n, fid; 213fb1bcc12SMatthew G. Knepley char name[PETSC_MAX_PATH_LEN]; 214e4fbd051SBarry Smith PetscMPIInt size; 2158df78e51SMark Adams PetscBool iscuda,iskokkos; 216fb1bcc12SMatthew G. Knepley 217fb1bcc12SMatthew G. Knepley PetscFunctionBegin; 2189566063dSJacob Faibussowitsch if (!swarm->issetup) PetscCall(DMSetUp(dm)); 2199566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketGetSizes(swarm->db, &n, NULL, NULL)); 2209566063dSJacob Faibussowitsch PetscCall(DMSwarmGetField(dm, fieldname, &bs, &type, (void **) &array)); 22108401ef6SPierre Jolivet PetscCheck(type == PETSC_REAL,PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Only valid for PETSC_REAL"); 222fb1bcc12SMatthew G. Knepley 2239566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(comm, &size)); 2248df78e51SMark Adams PetscCall(PetscStrcmp(dm->vectype,VECKOKKOS,&iskokkos)); 2258df78e51SMark Adams PetscCall(PetscStrcmp(dm->vectype,VECCUDA,&iscuda)); 2268df78e51SMark Adams PetscCall(VecCreate(comm,vec)); 2278df78e51SMark Adams PetscCall(VecSetSizes(*vec,n*bs,PETSC_DETERMINE)); 2288df78e51SMark Adams PetscCall(VecSetBlockSize(*vec,bs)); 2298df78e51SMark Adams if (iskokkos) PetscCall(VecSetType(*vec,VECKOKKOS)); 2308df78e51SMark Adams else if (iscuda) PetscCall(VecSetType(*vec,VECCUDA)); 2318df78e51SMark Adams else PetscCall(VecSetType(*vec,VECSTANDARD)); 2328df78e51SMark Adams PetscCall(VecPlaceArray(*vec,array)); 2338df78e51SMark Adams 2349566063dSJacob Faibussowitsch PetscCall(PetscSNPrintf(name, PETSC_MAX_PATH_LEN-1, "DMSwarmSharedField_%s", fieldname)); 2359566063dSJacob Faibussowitsch PetscCall(PetscObjectSetName((PetscObject) *vec, name)); 236fb1bcc12SMatthew G. Knepley 237fb1bcc12SMatthew G. Knepley /* Set guard */ 238*2e956fe4SStefano Zampini PetscCall(DMSwarmDataBucketGetDMSwarmDataFieldIdByName(swarm->db, fieldname, &fid)); 239*2e956fe4SStefano Zampini PetscCall(PetscObjectComposedDataSetInt((PetscObject)*vec, SwarmDataFieldId, fid)); 24074d0cae8SMatthew G. Knepley 2419566063dSJacob Faibussowitsch PetscCall(VecSetDM(*vec, dm)); 2429566063dSJacob Faibussowitsch PetscCall(VecSetOperation(*vec, VECOP_VIEW, (void (*)(void)) VecView_Swarm)); 243fb1bcc12SMatthew G. Knepley PetscFunctionReturn(0); 244fb1bcc12SMatthew G. Knepley } 245fb1bcc12SMatthew G. Knepley 2460643ed39SMatthew G. Knepley /* This creates a "mass matrix" between a finite element and particle space. If a finite element interpolant is given by 2470643ed39SMatthew G. Knepley 2480643ed39SMatthew G. Knepley \hat f = \sum_i f_i \phi_i 2490643ed39SMatthew G. Knepley 2500643ed39SMatthew G. Knepley and a particle function is given by 2510643ed39SMatthew G. Knepley 2520643ed39SMatthew G. Knepley f = \sum_i w_i \delta(x - x_i) 2530643ed39SMatthew G. Knepley 2540643ed39SMatthew G. Knepley then we want to require that 2550643ed39SMatthew G. Knepley 2560643ed39SMatthew G. Knepley M \hat f = M_p f 2570643ed39SMatthew G. Knepley 2580643ed39SMatthew G. Knepley where the particle mass matrix is given by 2590643ed39SMatthew G. Knepley 2600643ed39SMatthew G. Knepley (M_p)_{ij} = \int \phi_i \delta(x - x_j) 2610643ed39SMatthew G. Knepley 2620643ed39SMatthew G. Knepley The way Dave May does particles, they amount to quadratue weights rather than delta functions, so he has |J| is in 2630643ed39SMatthew G. Knepley his integral. We allow this with the boolean flag. 2640643ed39SMatthew G. Knepley */ 2650643ed39SMatthew G. Knepley static PetscErrorCode DMSwarmComputeMassMatrix_Private(DM dmc, DM dmf, Mat mass, PetscBool useDeltaFunction, void *ctx) 26683c47955SMatthew G. Knepley { 26783c47955SMatthew G. Knepley const char *name = "Mass Matrix"; 2680643ed39SMatthew G. Knepley MPI_Comm comm; 26983c47955SMatthew G. Knepley PetscDS prob; 27083c47955SMatthew G. Knepley PetscSection fsection, globalFSection; 271e8f14785SLisandro Dalcin PetscHSetIJ ht; 2720643ed39SMatthew G. Knepley PetscLayout rLayout, colLayout; 27383c47955SMatthew G. Knepley PetscInt *dnz, *onz; 274adb2528bSMark Adams PetscInt locRows, locCols, rStart, colStart, colEnd, *rowIDXs; 2750643ed39SMatthew G. Knepley PetscReal *xi, *v0, *J, *invJ, detJ = 1.0, v0ref[3] = {-1.0, -1.0, -1.0}; 27683c47955SMatthew G. Knepley PetscScalar *elemMat; 2770643ed39SMatthew G. Knepley PetscInt dim, Nf, field, cStart, cEnd, cell, totDim, maxC = 0; 27883c47955SMatthew G. Knepley 27983c47955SMatthew G. Knepley PetscFunctionBegin; 2809566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject) mass, &comm)); 2819566063dSJacob Faibussowitsch PetscCall(DMGetCoordinateDim(dmf, &dim)); 2829566063dSJacob Faibussowitsch PetscCall(DMGetDS(dmf, &prob)); 2839566063dSJacob Faibussowitsch PetscCall(PetscDSGetNumFields(prob, &Nf)); 2849566063dSJacob Faibussowitsch PetscCall(PetscDSGetTotalDimension(prob, &totDim)); 2859566063dSJacob Faibussowitsch PetscCall(PetscMalloc3(dim, &v0, dim*dim, &J, dim*dim,&invJ)); 2869566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dmf, &fsection)); 2879566063dSJacob Faibussowitsch PetscCall(DMGetGlobalSection(dmf, &globalFSection)); 2889566063dSJacob Faibussowitsch PetscCall(DMPlexGetHeightStratum(dmf, 0, &cStart, &cEnd)); 2899566063dSJacob Faibussowitsch PetscCall(MatGetLocalSize(mass, &locRows, &locCols)); 29083c47955SMatthew G. Knepley 2919566063dSJacob Faibussowitsch PetscCall(PetscLayoutCreate(comm, &colLayout)); 2929566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetLocalSize(colLayout, locCols)); 2939566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetBlockSize(colLayout, 1)); 2949566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(colLayout)); 2959566063dSJacob Faibussowitsch PetscCall(PetscLayoutGetRange(colLayout, &colStart, &colEnd)); 2969566063dSJacob Faibussowitsch PetscCall(PetscLayoutDestroy(&colLayout)); 2970643ed39SMatthew G. Knepley 2989566063dSJacob Faibussowitsch PetscCall(PetscLayoutCreate(comm, &rLayout)); 2999566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetLocalSize(rLayout, locRows)); 3009566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetBlockSize(rLayout, 1)); 3019566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(rLayout)); 3029566063dSJacob Faibussowitsch PetscCall(PetscLayoutGetRange(rLayout, &rStart, NULL)); 3039566063dSJacob Faibussowitsch PetscCall(PetscLayoutDestroy(&rLayout)); 3040643ed39SMatthew G. Knepley 3059566063dSJacob Faibussowitsch PetscCall(PetscCalloc2(locRows, &dnz, locRows, &onz)); 3069566063dSJacob Faibussowitsch PetscCall(PetscHSetIJCreate(&ht)); 30753e60ab4SJoseph Pusztay 3089566063dSJacob Faibussowitsch PetscCall(PetscSynchronizedFlush(comm, NULL)); 3090643ed39SMatthew G. Knepley /* count non-zeros */ 3109566063dSJacob Faibussowitsch PetscCall(DMSwarmSortGetAccess(dmc)); 31183c47955SMatthew G. Knepley for (field = 0; field < Nf; ++field) { 31283c47955SMatthew G. Knepley for (cell = cStart; cell < cEnd; ++cell) { 3130643ed39SMatthew G. Knepley PetscInt c, i; 3140643ed39SMatthew G. Knepley PetscInt *findices, *cindices; /* fine is vertices, coarse is particles */ 31583c47955SMatthew G. Knepley PetscInt numFIndices, numCIndices; 31683c47955SMatthew G. Knepley 3179566063dSJacob Faibussowitsch PetscCall(DMPlexGetClosureIndices(dmf, fsection, globalFSection, cell, PETSC_FALSE, &numFIndices, &findices, NULL, NULL)); 3189566063dSJacob Faibussowitsch PetscCall(DMSwarmSortGetPointsPerCell(dmc, cell, &numCIndices, &cindices)); 319fc7c92abSMatthew G. Knepley maxC = PetscMax(maxC, numCIndices); 32083c47955SMatthew G. Knepley { 321e8f14785SLisandro Dalcin PetscHashIJKey key; 322e8f14785SLisandro Dalcin PetscBool missing; 32383c47955SMatthew G. Knepley for (i = 0; i < numFIndices; ++i) { 324adb2528bSMark Adams key.j = findices[i]; /* global column (from Plex) */ 325adb2528bSMark Adams if (key.j >= 0) { 32683c47955SMatthew G. Knepley /* Get indices for coarse elements */ 32783c47955SMatthew G. Knepley for (c = 0; c < numCIndices; ++c) { 328adb2528bSMark Adams key.i = cindices[c] + rStart; /* global cols (from Swarm) */ 329adb2528bSMark Adams if (key.i < 0) continue; 3309566063dSJacob Faibussowitsch PetscCall(PetscHSetIJQueryAdd(ht, key, &missing)); 33183c47955SMatthew G. Knepley if (missing) { 3320643ed39SMatthew G. Knepley if ((key.j >= colStart) && (key.j < colEnd)) ++dnz[key.i - rStart]; 333e8f14785SLisandro Dalcin else ++onz[key.i - rStart]; 33463a3b9bcSJacob Faibussowitsch } else SETERRQ(PetscObjectComm((PetscObject) dmf), PETSC_ERR_SUP, "Set new value at %" PetscInt_FMT ",%" PetscInt_FMT, key.i, key.j); 33583c47955SMatthew G. Knepley } 336fc7c92abSMatthew G. Knepley } 337fc7c92abSMatthew G. Knepley } 3389566063dSJacob Faibussowitsch PetscCall(PetscFree(cindices)); 33983c47955SMatthew G. Knepley } 3409566063dSJacob Faibussowitsch PetscCall(DMPlexRestoreClosureIndices(dmf, fsection, globalFSection, cell, PETSC_FALSE, &numFIndices, &findices, NULL, NULL)); 34183c47955SMatthew G. Knepley } 34283c47955SMatthew G. Knepley } 3439566063dSJacob Faibussowitsch PetscCall(PetscHSetIJDestroy(&ht)); 3449566063dSJacob Faibussowitsch PetscCall(MatXAIJSetPreallocation(mass, 1, dnz, onz, NULL, NULL)); 3459566063dSJacob Faibussowitsch PetscCall(MatSetOption(mass, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_TRUE)); 3469566063dSJacob Faibussowitsch PetscCall(PetscFree2(dnz, onz)); 3479566063dSJacob Faibussowitsch PetscCall(PetscMalloc3(maxC*totDim, &elemMat, maxC, &rowIDXs, maxC*dim, &xi)); 34883c47955SMatthew G. Knepley for (field = 0; field < Nf; ++field) { 349ef0bb6c7SMatthew G. Knepley PetscTabulation Tcoarse; 35083c47955SMatthew G. Knepley PetscObject obj; 351ef0bb6c7SMatthew G. Knepley PetscReal *coords; 3520643ed39SMatthew G. Knepley PetscInt Nc, i; 35383c47955SMatthew G. Knepley 3549566063dSJacob Faibussowitsch PetscCall(PetscDSGetDiscretization(prob, field, &obj)); 3559566063dSJacob Faibussowitsch PetscCall(PetscFEGetNumComponents((PetscFE) obj, &Nc)); 35663a3b9bcSJacob Faibussowitsch PetscCheck(Nc == 1,PetscObjectComm((PetscObject) dmf), PETSC_ERR_SUP, "Can only interpolate a scalar field from particles, Nc = %" PetscInt_FMT, Nc); 3579566063dSJacob Faibussowitsch PetscCall(DMSwarmGetField(dmc, DMSwarmPICField_coor, NULL, NULL, (void **) &coords)); 35883c47955SMatthew G. Knepley for (cell = cStart; cell < cEnd; ++cell) { 35983c47955SMatthew G. Knepley PetscInt *findices , *cindices; 36083c47955SMatthew G. Knepley PetscInt numFIndices, numCIndices; 3610643ed39SMatthew G. Knepley PetscInt p, c; 36283c47955SMatthew G. Knepley 3630643ed39SMatthew G. Knepley /* TODO: Use DMField instead of assuming affine */ 3649566063dSJacob Faibussowitsch PetscCall(DMPlexComputeCellGeometryFEM(dmf, cell, NULL, v0, J, invJ, &detJ)); 3659566063dSJacob Faibussowitsch PetscCall(DMPlexGetClosureIndices(dmf, fsection, globalFSection, cell, PETSC_FALSE, &numFIndices, &findices, NULL, NULL)); 3669566063dSJacob Faibussowitsch PetscCall(DMSwarmSortGetPointsPerCell(dmc, cell, &numCIndices, &cindices)); 3670643ed39SMatthew G. Knepley for (p = 0; p < numCIndices; ++p) { 3680643ed39SMatthew G. Knepley CoordinatesRealToRef(dim, dim, v0ref, v0, invJ, &coords[cindices[p]*dim], &xi[p*dim]); 3690643ed39SMatthew G. Knepley } 3709566063dSJacob Faibussowitsch PetscCall(PetscFECreateTabulation((PetscFE) obj, 1, numCIndices, xi, 0, &Tcoarse)); 37183c47955SMatthew G. Knepley /* Get elemMat entries by multiplying by weight */ 3729566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(elemMat, numCIndices*totDim)); 37383c47955SMatthew G. Knepley for (i = 0; i < numFIndices; ++i) { 3740643ed39SMatthew G. Knepley for (p = 0; p < numCIndices; ++p) { 3750643ed39SMatthew G. Knepley for (c = 0; c < Nc; ++c) { 3760643ed39SMatthew G. Knepley /* B[(p*pdim + i)*Nc + c] is the value at point p for basis function i and component c */ 377ef0bb6c7SMatthew G. Knepley elemMat[p*numFIndices+i] += Tcoarse->T[0][(p*numFIndices + i)*Nc + c]*(useDeltaFunction ? 1.0 : detJ); 37883c47955SMatthew G. Knepley } 3790643ed39SMatthew G. Knepley } 3800643ed39SMatthew G. Knepley } 381adb2528bSMark Adams for (p = 0; p < numCIndices; ++p) rowIDXs[p] = cindices[p] + rStart; 3829566063dSJacob Faibussowitsch if (0) PetscCall(DMPrintCellMatrix(cell, name, 1, numCIndices, elemMat)); 3839566063dSJacob Faibussowitsch PetscCall(MatSetValues(mass, numCIndices, rowIDXs, numFIndices, findices, elemMat, ADD_VALUES)); 3849566063dSJacob Faibussowitsch PetscCall(PetscFree(cindices)); 3859566063dSJacob Faibussowitsch PetscCall(DMPlexRestoreClosureIndices(dmf, fsection, globalFSection, cell, PETSC_FALSE, &numFIndices, &findices, NULL, NULL)); 3869566063dSJacob Faibussowitsch PetscCall(PetscTabulationDestroy(&Tcoarse)); 38783c47955SMatthew G. Knepley } 3889566063dSJacob Faibussowitsch PetscCall(DMSwarmRestoreField(dmc, DMSwarmPICField_coor, NULL, NULL, (void **) &coords)); 38983c47955SMatthew G. Knepley } 3909566063dSJacob Faibussowitsch PetscCall(PetscFree3(elemMat, rowIDXs, xi)); 3919566063dSJacob Faibussowitsch PetscCall(DMSwarmSortRestoreAccess(dmc)); 3929566063dSJacob Faibussowitsch PetscCall(PetscFree3(v0, J, invJ)); 3939566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(mass, MAT_FINAL_ASSEMBLY)); 3949566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(mass, MAT_FINAL_ASSEMBLY)); 39583c47955SMatthew G. Knepley PetscFunctionReturn(0); 39683c47955SMatthew G. Knepley } 39783c47955SMatthew G. Knepley 398d0c080abSJoseph Pusztay /* Returns empty matrix for use with SNES FD */ 39970a7d78aSStefano Zampini static PetscErrorCode DMCreateMatrix_Swarm(DM sw, Mat* m) 40070a7d78aSStefano Zampini { 401d0c080abSJoseph Pusztay Vec field; 402d0c080abSJoseph Pusztay PetscInt size; 403d0c080abSJoseph Pusztay 404d0c080abSJoseph Pusztay PetscFunctionBegin; 4059566063dSJacob Faibussowitsch PetscCall(DMGetGlobalVector(sw, &field)); 4069566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(field, &size)); 4079566063dSJacob Faibussowitsch PetscCall(DMRestoreGlobalVector(sw, &field)); 4089566063dSJacob Faibussowitsch PetscCall(MatCreate(PETSC_COMM_WORLD, m)); 4099566063dSJacob Faibussowitsch PetscCall(MatSetFromOptions(*m)); 4109566063dSJacob Faibussowitsch PetscCall(MatSetSizes(*m, PETSC_DECIDE, PETSC_DECIDE, size, size)); 4119566063dSJacob Faibussowitsch PetscCall(MatSeqAIJSetPreallocation(*m, 1, NULL)); 4129566063dSJacob Faibussowitsch PetscCall(MatZeroEntries(*m)); 4139566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(*m, MAT_FINAL_ASSEMBLY)); 4149566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(*m, MAT_FINAL_ASSEMBLY)); 4159566063dSJacob Faibussowitsch PetscCall(MatShift(*m, 1.0)); 4169566063dSJacob Faibussowitsch PetscCall(MatSetDM(*m, sw)); 417d0c080abSJoseph Pusztay PetscFunctionReturn(0); 418d0c080abSJoseph Pusztay } 419d0c080abSJoseph Pusztay 420adb2528bSMark Adams /* FEM cols, Particle rows */ 42183c47955SMatthew G. Knepley static PetscErrorCode DMCreateMassMatrix_Swarm(DM dmCoarse, DM dmFine, Mat *mass) 42283c47955SMatthew G. Knepley { 423895a1698SMatthew G. Knepley PetscSection gsf; 42483c47955SMatthew G. Knepley PetscInt m, n; 42583c47955SMatthew G. Knepley void *ctx; 42683c47955SMatthew G. Knepley 42783c47955SMatthew G. Knepley PetscFunctionBegin; 4289566063dSJacob Faibussowitsch PetscCall(DMGetGlobalSection(dmFine, &gsf)); 4299566063dSJacob Faibussowitsch PetscCall(PetscSectionGetConstrainedStorageSize(gsf, &m)); 4309566063dSJacob Faibussowitsch PetscCall(DMSwarmGetLocalSize(dmCoarse, &n)); 4319566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject) dmCoarse), mass)); 4329566063dSJacob Faibussowitsch PetscCall(MatSetSizes(*mass, n, m, PETSC_DETERMINE, PETSC_DETERMINE)); 4339566063dSJacob Faibussowitsch PetscCall(MatSetType(*mass, dmCoarse->mattype)); 4349566063dSJacob Faibussowitsch PetscCall(DMGetApplicationContext(dmFine, &ctx)); 43583c47955SMatthew G. Knepley 4369566063dSJacob Faibussowitsch PetscCall(DMSwarmComputeMassMatrix_Private(dmCoarse, dmFine, *mass, PETSC_TRUE, ctx)); 4379566063dSJacob Faibussowitsch PetscCall(MatViewFromOptions(*mass, NULL, "-mass_mat_view")); 43883c47955SMatthew G. Knepley PetscFunctionReturn(0); 43983c47955SMatthew G. Knepley } 44083c47955SMatthew G. Knepley 4414cc7f7b2SMatthew G. Knepley static PetscErrorCode DMSwarmComputeMassMatrixSquare_Private(DM dmc, DM dmf, Mat mass, PetscBool useDeltaFunction, void *ctx) 4424cc7f7b2SMatthew G. Knepley { 4434cc7f7b2SMatthew G. Knepley const char *name = "Mass Matrix Square"; 4444cc7f7b2SMatthew G. Knepley MPI_Comm comm; 4454cc7f7b2SMatthew G. Knepley PetscDS prob; 4464cc7f7b2SMatthew G. Knepley PetscSection fsection, globalFSection; 4474cc7f7b2SMatthew G. Knepley PetscHSetIJ ht; 4484cc7f7b2SMatthew G. Knepley PetscLayout rLayout, colLayout; 4494cc7f7b2SMatthew G. Knepley PetscInt *dnz, *onz, *adj, depth, maxConeSize, maxSupportSize, maxAdjSize; 4504cc7f7b2SMatthew G. Knepley PetscInt locRows, locCols, rStart, colStart, colEnd, *rowIDXs; 4514cc7f7b2SMatthew G. Knepley PetscReal *xi, *v0, *J, *invJ, detJ = 1.0, v0ref[3] = {-1.0, -1.0, -1.0}; 4524cc7f7b2SMatthew G. Knepley PetscScalar *elemMat, *elemMatSq; 4534cc7f7b2SMatthew G. Knepley PetscInt cdim, Nf, field, cStart, cEnd, cell, totDim, maxC = 0; 4544cc7f7b2SMatthew G. Knepley 4554cc7f7b2SMatthew G. Knepley PetscFunctionBegin; 4569566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject) mass, &comm)); 4579566063dSJacob Faibussowitsch PetscCall(DMGetCoordinateDim(dmf, &cdim)); 4589566063dSJacob Faibussowitsch PetscCall(DMGetDS(dmf, &prob)); 4599566063dSJacob Faibussowitsch PetscCall(PetscDSGetNumFields(prob, &Nf)); 4609566063dSJacob Faibussowitsch PetscCall(PetscDSGetTotalDimension(prob, &totDim)); 4619566063dSJacob Faibussowitsch PetscCall(PetscMalloc3(cdim, &v0, cdim*cdim, &J, cdim*cdim,&invJ)); 4629566063dSJacob Faibussowitsch PetscCall(DMGetLocalSection(dmf, &fsection)); 4639566063dSJacob Faibussowitsch PetscCall(DMGetGlobalSection(dmf, &globalFSection)); 4649566063dSJacob Faibussowitsch PetscCall(DMPlexGetHeightStratum(dmf, 0, &cStart, &cEnd)); 4659566063dSJacob Faibussowitsch PetscCall(MatGetLocalSize(mass, &locRows, &locCols)); 4664cc7f7b2SMatthew G. Knepley 4679566063dSJacob Faibussowitsch PetscCall(PetscLayoutCreate(comm, &colLayout)); 4689566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetLocalSize(colLayout, locCols)); 4699566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetBlockSize(colLayout, 1)); 4709566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(colLayout)); 4719566063dSJacob Faibussowitsch PetscCall(PetscLayoutGetRange(colLayout, &colStart, &colEnd)); 4729566063dSJacob Faibussowitsch PetscCall(PetscLayoutDestroy(&colLayout)); 4734cc7f7b2SMatthew G. Knepley 4749566063dSJacob Faibussowitsch PetscCall(PetscLayoutCreate(comm, &rLayout)); 4759566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetLocalSize(rLayout, locRows)); 4769566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetBlockSize(rLayout, 1)); 4779566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(rLayout)); 4789566063dSJacob Faibussowitsch PetscCall(PetscLayoutGetRange(rLayout, &rStart, NULL)); 4799566063dSJacob Faibussowitsch PetscCall(PetscLayoutDestroy(&rLayout)); 4804cc7f7b2SMatthew G. Knepley 4819566063dSJacob Faibussowitsch PetscCall(DMPlexGetDepth(dmf, &depth)); 4829566063dSJacob Faibussowitsch PetscCall(DMPlexGetMaxSizes(dmf, &maxConeSize, &maxSupportSize)); 4834cc7f7b2SMatthew G. Knepley maxAdjSize = PetscPowInt(maxConeSize*maxSupportSize, depth); 4849566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(maxAdjSize, &adj)); 4854cc7f7b2SMatthew G. Knepley 4869566063dSJacob Faibussowitsch PetscCall(PetscCalloc2(locRows, &dnz, locRows, &onz)); 4879566063dSJacob Faibussowitsch PetscCall(PetscHSetIJCreate(&ht)); 4884cc7f7b2SMatthew G. Knepley /* Count nonzeros 4894cc7f7b2SMatthew G. Knepley This is just FVM++, but we cannot use the Plex P0 allocation since unknowns in a cell will not be contiguous 4904cc7f7b2SMatthew G. Knepley */ 4919566063dSJacob Faibussowitsch PetscCall(DMSwarmSortGetAccess(dmc)); 4924cc7f7b2SMatthew G. Knepley for (cell = cStart; cell < cEnd; ++cell) { 4934cc7f7b2SMatthew G. Knepley PetscInt i; 4944cc7f7b2SMatthew G. Knepley PetscInt *cindices; 4954cc7f7b2SMatthew G. Knepley PetscInt numCIndices; 4964cc7f7b2SMatthew G. Knepley #if 0 4974cc7f7b2SMatthew G. Knepley PetscInt adjSize = maxAdjSize, a, j; 4984cc7f7b2SMatthew G. Knepley #endif 4994cc7f7b2SMatthew G. Knepley 5009566063dSJacob Faibussowitsch PetscCall(DMSwarmSortGetPointsPerCell(dmc, cell, &numCIndices, &cindices)); 5014cc7f7b2SMatthew G. Knepley maxC = PetscMax(maxC, numCIndices); 5024cc7f7b2SMatthew G. Knepley /* Diagonal block */ 5034cc7f7b2SMatthew G. Knepley for (i = 0; i < numCIndices; ++i) {dnz[cindices[i]] += numCIndices;} 5044cc7f7b2SMatthew G. Knepley #if 0 5054cc7f7b2SMatthew G. Knepley /* Off-diagonal blocks */ 5069566063dSJacob Faibussowitsch PetscCall(DMPlexGetAdjacency(dmf, cell, &adjSize, &adj)); 5074cc7f7b2SMatthew G. Knepley for (a = 0; a < adjSize; ++a) { 5084cc7f7b2SMatthew G. Knepley if (adj[a] >= cStart && adj[a] < cEnd && adj[a] != cell) { 5094cc7f7b2SMatthew G. Knepley const PetscInt ncell = adj[a]; 5104cc7f7b2SMatthew G. Knepley PetscInt *ncindices; 5114cc7f7b2SMatthew G. Knepley PetscInt numNCIndices; 5124cc7f7b2SMatthew G. Knepley 5139566063dSJacob Faibussowitsch PetscCall(DMSwarmSortGetPointsPerCell(dmc, ncell, &numNCIndices, &ncindices)); 5144cc7f7b2SMatthew G. Knepley { 5154cc7f7b2SMatthew G. Knepley PetscHashIJKey key; 5164cc7f7b2SMatthew G. Knepley PetscBool missing; 5174cc7f7b2SMatthew G. Knepley 5184cc7f7b2SMatthew G. Knepley for (i = 0; i < numCIndices; ++i) { 5194cc7f7b2SMatthew G. Knepley key.i = cindices[i] + rStart; /* global rows (from Swarm) */ 5204cc7f7b2SMatthew G. Knepley if (key.i < 0) continue; 5214cc7f7b2SMatthew G. Knepley for (j = 0; j < numNCIndices; ++j) { 5224cc7f7b2SMatthew G. Knepley key.j = ncindices[j] + rStart; /* global column (from Swarm) */ 5234cc7f7b2SMatthew G. Knepley if (key.j < 0) continue; 5249566063dSJacob Faibussowitsch PetscCall(PetscHSetIJQueryAdd(ht, key, &missing)); 5254cc7f7b2SMatthew G. Knepley if (missing) { 5264cc7f7b2SMatthew G. Knepley if ((key.j >= colStart) && (key.j < colEnd)) ++dnz[key.i - rStart]; 5274cc7f7b2SMatthew G. Knepley else ++onz[key.i - rStart]; 5284cc7f7b2SMatthew G. Knepley } 5294cc7f7b2SMatthew G. Knepley } 5304cc7f7b2SMatthew G. Knepley } 5314cc7f7b2SMatthew G. Knepley } 5329566063dSJacob Faibussowitsch PetscCall(PetscFree(ncindices)); 5334cc7f7b2SMatthew G. Knepley } 5344cc7f7b2SMatthew G. Knepley } 5354cc7f7b2SMatthew G. Knepley #endif 5369566063dSJacob Faibussowitsch PetscCall(PetscFree(cindices)); 5374cc7f7b2SMatthew G. Knepley } 5389566063dSJacob Faibussowitsch PetscCall(PetscHSetIJDestroy(&ht)); 5399566063dSJacob Faibussowitsch PetscCall(MatXAIJSetPreallocation(mass, 1, dnz, onz, NULL, NULL)); 5409566063dSJacob Faibussowitsch PetscCall(MatSetOption(mass, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_TRUE)); 5419566063dSJacob Faibussowitsch PetscCall(PetscFree2(dnz, onz)); 5429566063dSJacob Faibussowitsch PetscCall(PetscMalloc4(maxC*totDim, &elemMat, maxC*maxC, &elemMatSq, maxC, &rowIDXs, maxC*cdim, &xi)); 5434cc7f7b2SMatthew G. Knepley /* Fill in values 5444cc7f7b2SMatthew G. Knepley Each entry is a sum of terms \phi_i(x_p) \phi_i(x_q) 5454cc7f7b2SMatthew G. Knepley Start just by producing block diagonal 5464cc7f7b2SMatthew G. Knepley Could loop over adjacent cells 5474cc7f7b2SMatthew G. Knepley Produce neighboring element matrix 5484cc7f7b2SMatthew G. Knepley TODO Determine which columns and rows correspond to shared dual vector 5494cc7f7b2SMatthew G. Knepley Do MatMatMult with rectangular matrices 5504cc7f7b2SMatthew G. Knepley Insert block 5514cc7f7b2SMatthew G. Knepley */ 5524cc7f7b2SMatthew G. Knepley for (field = 0; field < Nf; ++field) { 5534cc7f7b2SMatthew G. Knepley PetscTabulation Tcoarse; 5544cc7f7b2SMatthew G. Knepley PetscObject obj; 5554cc7f7b2SMatthew G. Knepley PetscReal *coords; 5564cc7f7b2SMatthew G. Knepley PetscInt Nc, i; 5574cc7f7b2SMatthew G. Knepley 5589566063dSJacob Faibussowitsch PetscCall(PetscDSGetDiscretization(prob, field, &obj)); 5599566063dSJacob Faibussowitsch PetscCall(PetscFEGetNumComponents((PetscFE) obj, &Nc)); 56063a3b9bcSJacob Faibussowitsch PetscCheck(Nc == 1,PetscObjectComm((PetscObject) dmf), PETSC_ERR_SUP, "Can only interpolate a scalar field from particles, Nc = %" PetscInt_FMT, Nc); 5619566063dSJacob Faibussowitsch PetscCall(DMSwarmGetField(dmc, DMSwarmPICField_coor, NULL, NULL, (void **) &coords)); 5624cc7f7b2SMatthew G. Knepley for (cell = cStart; cell < cEnd; ++cell) { 5634cc7f7b2SMatthew G. Knepley PetscInt *findices , *cindices; 5644cc7f7b2SMatthew G. Knepley PetscInt numFIndices, numCIndices; 5654cc7f7b2SMatthew G. Knepley PetscInt p, c; 5664cc7f7b2SMatthew G. Knepley 5674cc7f7b2SMatthew G. Knepley /* TODO: Use DMField instead of assuming affine */ 5689566063dSJacob Faibussowitsch PetscCall(DMPlexComputeCellGeometryFEM(dmf, cell, NULL, v0, J, invJ, &detJ)); 5699566063dSJacob Faibussowitsch PetscCall(DMPlexGetClosureIndices(dmf, fsection, globalFSection, cell, PETSC_FALSE, &numFIndices, &findices, NULL, NULL)); 5709566063dSJacob Faibussowitsch PetscCall(DMSwarmSortGetPointsPerCell(dmc, cell, &numCIndices, &cindices)); 5714cc7f7b2SMatthew G. Knepley for (p = 0; p < numCIndices; ++p) { 5724cc7f7b2SMatthew G. Knepley CoordinatesRealToRef(cdim, cdim, v0ref, v0, invJ, &coords[cindices[p]*cdim], &xi[p*cdim]); 5734cc7f7b2SMatthew G. Knepley } 5749566063dSJacob Faibussowitsch PetscCall(PetscFECreateTabulation((PetscFE) obj, 1, numCIndices, xi, 0, &Tcoarse)); 5754cc7f7b2SMatthew G. Knepley /* Get elemMat entries by multiplying by weight */ 5769566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(elemMat, numCIndices*totDim)); 5774cc7f7b2SMatthew G. Knepley for (i = 0; i < numFIndices; ++i) { 5784cc7f7b2SMatthew G. Knepley for (p = 0; p < numCIndices; ++p) { 5794cc7f7b2SMatthew G. Knepley for (c = 0; c < Nc; ++c) { 5804cc7f7b2SMatthew G. Knepley /* B[(p*pdim + i)*Nc + c] is the value at point p for basis function i and component c */ 5814cc7f7b2SMatthew G. Knepley elemMat[p*numFIndices+i] += Tcoarse->T[0][(p*numFIndices + i)*Nc + c]*(useDeltaFunction ? 1.0 : detJ); 5824cc7f7b2SMatthew G. Knepley } 5834cc7f7b2SMatthew G. Knepley } 5844cc7f7b2SMatthew G. Knepley } 5859566063dSJacob Faibussowitsch PetscCall(PetscTabulationDestroy(&Tcoarse)); 5864cc7f7b2SMatthew G. Knepley for (p = 0; p < numCIndices; ++p) rowIDXs[p] = cindices[p] + rStart; 5879566063dSJacob Faibussowitsch if (0) PetscCall(DMPrintCellMatrix(cell, name, 1, numCIndices, elemMat)); 5884cc7f7b2SMatthew G. Knepley /* Block diagonal */ 58978884ca7SMatthew G. Knepley if (numCIndices) { 5904cc7f7b2SMatthew G. Knepley PetscBLASInt blasn, blask; 5914cc7f7b2SMatthew G. Knepley PetscScalar one = 1.0, zero = 0.0; 5924cc7f7b2SMatthew G. Knepley 5939566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(numCIndices, &blasn)); 5949566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(numFIndices, &blask)); 5954cc7f7b2SMatthew G. Knepley PetscStackCallBLAS("BLASgemm",BLASgemm_("T","N",&blasn,&blasn,&blask,&one,elemMat,&blask,elemMat,&blask,&zero,elemMatSq,&blasn)); 5964cc7f7b2SMatthew G. Knepley } 5979566063dSJacob Faibussowitsch PetscCall(MatSetValues(mass, numCIndices, rowIDXs, numCIndices, rowIDXs, elemMatSq, ADD_VALUES)); 5984cc7f7b2SMatthew G. Knepley /* TODO Off-diagonal */ 5999566063dSJacob Faibussowitsch PetscCall(PetscFree(cindices)); 6009566063dSJacob Faibussowitsch PetscCall(DMPlexRestoreClosureIndices(dmf, fsection, globalFSection, cell, PETSC_FALSE, &numFIndices, &findices, NULL, NULL)); 6014cc7f7b2SMatthew G. Knepley } 6029566063dSJacob Faibussowitsch PetscCall(DMSwarmRestoreField(dmc, DMSwarmPICField_coor, NULL, NULL, (void **) &coords)); 6034cc7f7b2SMatthew G. Knepley } 6049566063dSJacob Faibussowitsch PetscCall(PetscFree4(elemMat, elemMatSq, rowIDXs, xi)); 6059566063dSJacob Faibussowitsch PetscCall(PetscFree(adj)); 6069566063dSJacob Faibussowitsch PetscCall(DMSwarmSortRestoreAccess(dmc)); 6079566063dSJacob Faibussowitsch PetscCall(PetscFree3(v0, J, invJ)); 6089566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(mass, MAT_FINAL_ASSEMBLY)); 6099566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(mass, MAT_FINAL_ASSEMBLY)); 6104cc7f7b2SMatthew G. Knepley PetscFunctionReturn(0); 6114cc7f7b2SMatthew G. Knepley } 6124cc7f7b2SMatthew G. Knepley 6134cc7f7b2SMatthew G. Knepley /*@C 6144cc7f7b2SMatthew G. Knepley DMSwarmCreateMassMatrixSquare - Creates the block-diagonal of the square, M^T_p M_p, of the particle mass matrix M_p 6154cc7f7b2SMatthew G. Knepley 6164cc7f7b2SMatthew G. Knepley Collective on dmCoarse 6174cc7f7b2SMatthew G. Knepley 6184cc7f7b2SMatthew G. Knepley Input parameters: 6194cc7f7b2SMatthew G. Knepley + dmCoarse - a DMSwarm 6204cc7f7b2SMatthew G. Knepley - dmFine - a DMPlex 6214cc7f7b2SMatthew G. Knepley 6224cc7f7b2SMatthew G. Knepley Output parameter: 6234cc7f7b2SMatthew G. Knepley . mass - the square of the particle mass matrix 6244cc7f7b2SMatthew G. Knepley 6254cc7f7b2SMatthew G. Knepley Level: advanced 6264cc7f7b2SMatthew G. Knepley 6274cc7f7b2SMatthew G. Knepley Notes: 6284cc7f7b2SMatthew G. Knepley We only compute the block diagonal since this provides a good preconditioner and is completely local. It would be possible in the 6294cc7f7b2SMatthew G. Knepley future to compute the full normal equations. 6304cc7f7b2SMatthew G. Knepley 631db781477SPatrick Sanan .seealso: `DMCreateMassMatrix()` 6324cc7f7b2SMatthew G. Knepley @*/ 6334cc7f7b2SMatthew G. Knepley PetscErrorCode DMSwarmCreateMassMatrixSquare(DM dmCoarse, DM dmFine, Mat *mass) 6344cc7f7b2SMatthew G. Knepley { 6354cc7f7b2SMatthew G. Knepley PetscInt n; 6364cc7f7b2SMatthew G. Knepley void *ctx; 6374cc7f7b2SMatthew G. Knepley 6384cc7f7b2SMatthew G. Knepley PetscFunctionBegin; 6399566063dSJacob Faibussowitsch PetscCall(DMSwarmGetLocalSize(dmCoarse, &n)); 6409566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject) dmCoarse), mass)); 6419566063dSJacob Faibussowitsch PetscCall(MatSetSizes(*mass, n, n, PETSC_DETERMINE, PETSC_DETERMINE)); 6429566063dSJacob Faibussowitsch PetscCall(MatSetType(*mass, dmCoarse->mattype)); 6439566063dSJacob Faibussowitsch PetscCall(DMGetApplicationContext(dmFine, &ctx)); 6444cc7f7b2SMatthew G. Knepley 6459566063dSJacob Faibussowitsch PetscCall(DMSwarmComputeMassMatrixSquare_Private(dmCoarse, dmFine, *mass, PETSC_TRUE, ctx)); 6469566063dSJacob Faibussowitsch PetscCall(MatViewFromOptions(*mass, NULL, "-mass_sq_mat_view")); 6474cc7f7b2SMatthew G. Knepley PetscFunctionReturn(0); 6484cc7f7b2SMatthew G. Knepley } 6494cc7f7b2SMatthew G. Knepley 650fb1bcc12SMatthew G. Knepley /*@C 651d3a51819SDave May DMSwarmCreateGlobalVectorFromField - Creates a Vec object sharing the array associated with a given field 652d3a51819SDave May 653d083f849SBarry Smith Collective on dm 654d3a51819SDave May 655d3a51819SDave May Input parameters: 65662741f57SDave May + dm - a DMSwarm 65762741f57SDave May - fieldname - the textual name given to a registered field 658d3a51819SDave May 6598b8a3813SDave May Output parameter: 660d3a51819SDave May . vec - the vector 661d3a51819SDave May 662d3a51819SDave May Level: beginner 663d3a51819SDave May 6648b8a3813SDave May Notes: 6658b8a3813SDave May The vector must be returned using a matching call to DMSwarmDestroyGlobalVectorFromField(). 6668b8a3813SDave May 667db781477SPatrick Sanan .seealso: `DMSwarmRegisterPetscDatatypeField()`, `DMSwarmDestroyGlobalVectorFromField()` 668d3a51819SDave May @*/ 66974d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmCreateGlobalVectorFromField(DM dm,const char fieldname[],Vec *vec) 670b5bcf523SDave May { 671fb1bcc12SMatthew G. Knepley MPI_Comm comm = PetscObjectComm((PetscObject) dm); 672b5bcf523SDave May 673fb1bcc12SMatthew G. Knepley PetscFunctionBegin; 6749566063dSJacob Faibussowitsch PetscCall(DMSwarmCreateVectorFromField_Private(dm, fieldname, comm, vec)); 675b5bcf523SDave May PetscFunctionReturn(0); 676b5bcf523SDave May } 677b5bcf523SDave May 678d3a51819SDave May /*@C 679d3a51819SDave May DMSwarmDestroyGlobalVectorFromField - Destroys the Vec object which share the array associated with a given field 680d3a51819SDave May 681d083f849SBarry Smith Collective on dm 682d3a51819SDave May 683d3a51819SDave May Input parameters: 68462741f57SDave May + dm - a DMSwarm 68562741f57SDave May - fieldname - the textual name given to a registered field 686d3a51819SDave May 6878b8a3813SDave May Output parameter: 688d3a51819SDave May . vec - the vector 689d3a51819SDave May 690d3a51819SDave May Level: beginner 691d3a51819SDave May 692db781477SPatrick Sanan .seealso: `DMSwarmRegisterPetscDatatypeField()`, `DMSwarmCreateGlobalVectorFromField()` 693d3a51819SDave May @*/ 69474d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmDestroyGlobalVectorFromField(DM dm,const char fieldname[],Vec *vec) 695b5bcf523SDave May { 696fb1bcc12SMatthew G. Knepley PetscFunctionBegin; 6979566063dSJacob Faibussowitsch PetscCall(DMSwarmDestroyVectorFromField_Private(dm, fieldname, vec)); 698b5bcf523SDave May PetscFunctionReturn(0); 699b5bcf523SDave May } 700b5bcf523SDave May 701fb1bcc12SMatthew G. Knepley /*@C 702fb1bcc12SMatthew G. Knepley DMSwarmCreateLocalVectorFromField - Creates a Vec object sharing the array associated with a given field 703fb1bcc12SMatthew G. Knepley 704d083f849SBarry Smith Collective on dm 705fb1bcc12SMatthew G. Knepley 706fb1bcc12SMatthew G. Knepley Input parameters: 70762741f57SDave May + dm - a DMSwarm 70862741f57SDave May - fieldname - the textual name given to a registered field 709fb1bcc12SMatthew G. Knepley 7108b8a3813SDave May Output parameter: 711fb1bcc12SMatthew G. Knepley . vec - the vector 712fb1bcc12SMatthew G. Knepley 713fb1bcc12SMatthew G. Knepley Level: beginner 714fb1bcc12SMatthew G. Knepley 7158b8a3813SDave May Notes: 7168b8a3813SDave May The vector must be returned using a matching call to DMSwarmDestroyLocalVectorFromField(). 7178b8a3813SDave May 718db781477SPatrick Sanan .seealso: `DMSwarmRegisterPetscDatatypeField()`, `DMSwarmDestroyLocalVectorFromField()` 719fb1bcc12SMatthew G. Knepley @*/ 72074d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmCreateLocalVectorFromField(DM dm,const char fieldname[],Vec *vec) 721bbe8250bSMatthew G. Knepley { 722fb1bcc12SMatthew G. Knepley MPI_Comm comm = PETSC_COMM_SELF; 723bbe8250bSMatthew G. Knepley 724fb1bcc12SMatthew G. Knepley PetscFunctionBegin; 7259566063dSJacob Faibussowitsch PetscCall(DMSwarmCreateVectorFromField_Private(dm, fieldname, comm, vec)); 726fb1bcc12SMatthew G. Knepley PetscFunctionReturn(0); 727bbe8250bSMatthew G. Knepley } 728fb1bcc12SMatthew G. Knepley 729fb1bcc12SMatthew G. Knepley /*@C 730fb1bcc12SMatthew G. Knepley DMSwarmDestroyLocalVectorFromField - Destroys the Vec object which share the array associated with a given field 731fb1bcc12SMatthew G. Knepley 732d083f849SBarry Smith Collective on dm 733fb1bcc12SMatthew G. Knepley 734fb1bcc12SMatthew G. Knepley Input parameters: 73562741f57SDave May + dm - a DMSwarm 73662741f57SDave May - fieldname - the textual name given to a registered field 737fb1bcc12SMatthew G. Knepley 7388b8a3813SDave May Output parameter: 739fb1bcc12SMatthew G. Knepley . vec - the vector 740fb1bcc12SMatthew G. Knepley 741fb1bcc12SMatthew G. Knepley Level: beginner 742fb1bcc12SMatthew G. Knepley 743db781477SPatrick Sanan .seealso: `DMSwarmRegisterPetscDatatypeField()`, `DMSwarmCreateLocalVectorFromField()` 744fb1bcc12SMatthew G. Knepley @*/ 74574d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmDestroyLocalVectorFromField(DM dm,const char fieldname[],Vec *vec) 746fb1bcc12SMatthew G. Knepley { 747fb1bcc12SMatthew G. Knepley PetscFunctionBegin; 7489566063dSJacob Faibussowitsch PetscCall(DMSwarmDestroyVectorFromField_Private(dm, fieldname, vec)); 749bbe8250bSMatthew G. Knepley PetscFunctionReturn(0); 750bbe8250bSMatthew G. Knepley } 751bbe8250bSMatthew G. Knepley 752d3a51819SDave May /*@C 753d3a51819SDave May DMSwarmInitializeFieldRegister - Initiates the registration of fields to a DMSwarm 754d3a51819SDave May 755d083f849SBarry Smith Collective on dm 756d3a51819SDave May 757d3a51819SDave May Input parameter: 758d3a51819SDave May . dm - a DMSwarm 759d3a51819SDave May 760d3a51819SDave May Level: beginner 761d3a51819SDave May 762d3a51819SDave May Notes: 7638b8a3813SDave May After all fields have been registered, you must call DMSwarmFinalizeFieldRegister(). 764d3a51819SDave May 765db781477SPatrick Sanan .seealso: `DMSwarmFinalizeFieldRegister()`, `DMSwarmRegisterPetscDatatypeField()`, 766db781477SPatrick Sanan `DMSwarmRegisterUserStructField()`, `DMSwarmRegisterUserDatatypeField()` 767d3a51819SDave May @*/ 76874d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmInitializeFieldRegister(DM dm) 7695f50eb2eSDave May { 7705f50eb2eSDave May DM_Swarm *swarm = (DM_Swarm *) dm->data; 7713454631fSDave May 772521f74f9SMatthew G. Knepley PetscFunctionBegin; 773cc651181SDave May if (!swarm->field_registration_initialized) { 7745f50eb2eSDave May swarm->field_registration_initialized = PETSC_TRUE; 7759566063dSJacob Faibussowitsch PetscCall(DMSwarmRegisterPetscDatatypeField(dm,DMSwarmField_pid,1,PETSC_INT64)); /* unique identifer */ 7769566063dSJacob Faibussowitsch PetscCall(DMSwarmRegisterPetscDatatypeField(dm,DMSwarmField_rank,1,PETSC_INT)); /* used for communication */ 777cc651181SDave May } 7785f50eb2eSDave May PetscFunctionReturn(0); 7795f50eb2eSDave May } 7805f50eb2eSDave May 78174d0cae8SMatthew G. Knepley /*@ 782d3a51819SDave May DMSwarmFinalizeFieldRegister - Finalizes the registration of fields to a DMSwarm 783d3a51819SDave May 784d083f849SBarry Smith Collective on dm 785d3a51819SDave May 786d3a51819SDave May Input parameter: 787d3a51819SDave May . dm - a DMSwarm 788d3a51819SDave May 789d3a51819SDave May Level: beginner 790d3a51819SDave May 791d3a51819SDave May Notes: 79262741f57SDave May After DMSwarmFinalizeFieldRegister() has been called, no new fields can be defined on the DMSwarm. 793d3a51819SDave May 794db781477SPatrick Sanan .seealso: `DMSwarmInitializeFieldRegister()`, `DMSwarmRegisterPetscDatatypeField()`, 795db781477SPatrick Sanan `DMSwarmRegisterUserStructField()`, `DMSwarmRegisterUserDatatypeField()` 796d3a51819SDave May @*/ 79774d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmFinalizeFieldRegister(DM dm) 7985f50eb2eSDave May { 7995f50eb2eSDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 8006845f8f5SDave May 801521f74f9SMatthew G. Knepley PetscFunctionBegin; 802f0cdbbbaSDave May if (!swarm->field_registration_finalized) { 8039566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketFinalize(swarm->db)); 804f0cdbbbaSDave May } 805f0cdbbbaSDave May swarm->field_registration_finalized = PETSC_TRUE; 8065f50eb2eSDave May PetscFunctionReturn(0); 8075f50eb2eSDave May } 8085f50eb2eSDave May 80974d0cae8SMatthew G. Knepley /*@ 810d3a51819SDave May DMSwarmSetLocalSizes - Sets the length of all registered fields on the DMSwarm 811d3a51819SDave May 812d3a51819SDave May Not collective 813d3a51819SDave May 814d3a51819SDave May Input parameters: 81562741f57SDave May + dm - a DMSwarm 816d3a51819SDave May . nlocal - the length of each registered field 81762741f57SDave May - buffer - the length of the buffer used to efficient dynamic re-sizing 818d3a51819SDave May 819d3a51819SDave May Level: beginner 820d3a51819SDave May 821db781477SPatrick Sanan .seealso: `DMSwarmGetLocalSize()` 822d3a51819SDave May @*/ 82374d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmSetLocalSizes(DM dm,PetscInt nlocal,PetscInt buffer) 8245f50eb2eSDave May { 8255f50eb2eSDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 8265f50eb2eSDave May 827521f74f9SMatthew G. Knepley PetscFunctionBegin; 8289566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(DMSWARM_SetSizes,0,0,0,0)); 8299566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketSetSizes(swarm->db,nlocal,buffer)); 8309566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(DMSWARM_SetSizes,0,0,0,0)); 8315f50eb2eSDave May PetscFunctionReturn(0); 8325f50eb2eSDave May } 8335f50eb2eSDave May 83474d0cae8SMatthew G. Knepley /*@ 835d3a51819SDave May DMSwarmSetCellDM - Attachs a DM to a DMSwarm 836d3a51819SDave May 837d083f849SBarry Smith Collective on dm 838d3a51819SDave May 839d3a51819SDave May Input parameters: 84062741f57SDave May + dm - a DMSwarm 84162741f57SDave May - dmcell - the DM to attach to the DMSwarm 842d3a51819SDave May 843d3a51819SDave May Level: beginner 844d3a51819SDave May 845d3a51819SDave May Notes: 846d3a51819SDave May The attached DM (dmcell) will be queried for point location and 8478b8a3813SDave May neighbor MPI-rank information if DMSwarmMigrate() is called. 848d3a51819SDave May 849db781477SPatrick Sanan .seealso: `DMSwarmSetType()`, `DMSwarmGetCellDM()`, `DMSwarmMigrate()` 850d3a51819SDave May @*/ 85174d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmSetCellDM(DM dm,DM dmcell) 852b16650c8SDave May { 853b16650c8SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 854521f74f9SMatthew G. Knepley 855521f74f9SMatthew G. Knepley PetscFunctionBegin; 856b16650c8SDave May swarm->dmcell = dmcell; 857b16650c8SDave May PetscFunctionReturn(0); 858b16650c8SDave May } 859b16650c8SDave May 86074d0cae8SMatthew G. Knepley /*@ 861d3a51819SDave May DMSwarmGetCellDM - Fetches the attached cell DM 862d3a51819SDave May 863d083f849SBarry Smith Collective on dm 864d3a51819SDave May 865d3a51819SDave May Input parameter: 866d3a51819SDave May . dm - a DMSwarm 867d3a51819SDave May 868d3a51819SDave May Output parameter: 869d3a51819SDave May . dmcell - the DM which was attached to the DMSwarm 870d3a51819SDave May 871d3a51819SDave May Level: beginner 872d3a51819SDave May 873db781477SPatrick Sanan .seealso: `DMSwarmSetCellDM()` 874d3a51819SDave May @*/ 87574d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmGetCellDM(DM dm,DM *dmcell) 876fe39f135SDave May { 877fe39f135SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 878521f74f9SMatthew G. Knepley 879521f74f9SMatthew G. Knepley PetscFunctionBegin; 880fe39f135SDave May *dmcell = swarm->dmcell; 881fe39f135SDave May PetscFunctionReturn(0); 882fe39f135SDave May } 883fe39f135SDave May 88474d0cae8SMatthew G. Knepley /*@ 885d3a51819SDave May DMSwarmGetLocalSize - Retrives the local length of fields registered 886d3a51819SDave May 887d3a51819SDave May Not collective 888d3a51819SDave May 889d3a51819SDave May Input parameter: 890d3a51819SDave May . dm - a DMSwarm 891d3a51819SDave May 892d3a51819SDave May Output parameter: 893d3a51819SDave May . nlocal - the length of each registered field 894d3a51819SDave May 895d3a51819SDave May Level: beginner 896d3a51819SDave May 897db781477SPatrick Sanan .seealso: `DMSwarmGetSize()`, `DMSwarmSetLocalSizes()` 898d3a51819SDave May @*/ 89974d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmGetLocalSize(DM dm,PetscInt *nlocal) 900dcf43ee8SDave May { 901dcf43ee8SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 902dcf43ee8SDave May 903521f74f9SMatthew G. Knepley PetscFunctionBegin; 9049566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketGetSizes(swarm->db,nlocal,NULL,NULL)); 905dcf43ee8SDave May PetscFunctionReturn(0); 906dcf43ee8SDave May } 907dcf43ee8SDave May 90874d0cae8SMatthew G. Knepley /*@ 909d3a51819SDave May DMSwarmGetSize - Retrives the total length of fields registered 910d3a51819SDave May 911d083f849SBarry Smith Collective on dm 912d3a51819SDave May 913d3a51819SDave May Input parameter: 914d3a51819SDave May . dm - a DMSwarm 915d3a51819SDave May 916d3a51819SDave May Output parameter: 917d3a51819SDave May . n - the total length of each registered field 918d3a51819SDave May 919d3a51819SDave May Level: beginner 920d3a51819SDave May 921d3a51819SDave May Note: 922d3a51819SDave May This calls MPI_Allreduce upon each call (inefficient but safe) 923d3a51819SDave May 924db781477SPatrick Sanan .seealso: `DMSwarmGetLocalSize()`, `DMSwarmSetLocalSizes()` 925d3a51819SDave May @*/ 92674d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmGetSize(DM dm,PetscInt *n) 927dcf43ee8SDave May { 928dcf43ee8SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 9295627991aSBarry Smith PetscInt nlocal; 930dcf43ee8SDave May 931521f74f9SMatthew G. Knepley PetscFunctionBegin; 9329566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketGetSizes(swarm->db,&nlocal,NULL,NULL)); 9339566063dSJacob Faibussowitsch PetscCallMPI(MPI_Allreduce(&nlocal,n,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)dm))); 934dcf43ee8SDave May PetscFunctionReturn(0); 935dcf43ee8SDave May } 936dcf43ee8SDave May 937d3a51819SDave May /*@C 9388b8a3813SDave May DMSwarmRegisterPetscDatatypeField - Register a field to a DMSwarm with a native PETSc data type 939d3a51819SDave May 940d083f849SBarry Smith Collective on dm 941d3a51819SDave May 942d3a51819SDave May Input parameters: 94362741f57SDave May + dm - a DMSwarm 944d3a51819SDave May . fieldname - the textual name to identify this field 945d3a51819SDave May . blocksize - the number of each data type 94662741f57SDave May - type - a valid PETSc data type (PETSC_CHAR, PETSC_SHORT, PETSC_INT, PETSC_FLOAT, PETSC_REAL, PETSC_LONG) 947d3a51819SDave May 948d3a51819SDave May Level: beginner 949d3a51819SDave May 950d3a51819SDave May Notes: 9518b8a3813SDave May The textual name for each registered field must be unique. 952d3a51819SDave May 953db781477SPatrick Sanan .seealso: `DMSwarmRegisterUserStructField()`, `DMSwarmRegisterUserDatatypeField()` 954d3a51819SDave May @*/ 95574d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmRegisterPetscDatatypeField(DM dm,const char fieldname[],PetscInt blocksize,PetscDataType type) 956b62e03f8SDave May { 957b62e03f8SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 958b62e03f8SDave May size_t size; 959b62e03f8SDave May 960521f74f9SMatthew G. Knepley PetscFunctionBegin; 96128b400f6SJacob Faibussowitsch PetscCheck(swarm->field_registration_initialized,PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMSwarmInitializeFieldRegister() first"); 96228b400f6SJacob Faibussowitsch PetscCheck(!swarm->field_registration_finalized,PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Cannot register additional fields after calling DMSwarmFinalizeFieldRegister() first"); 9635f50eb2eSDave May 96408401ef6SPierre Jolivet PetscCheck(type != PETSC_OBJECT,PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}"); 96508401ef6SPierre Jolivet PetscCheck(type != PETSC_FUNCTION,PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}"); 96608401ef6SPierre Jolivet PetscCheck(type != PETSC_STRING,PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}"); 96708401ef6SPierre Jolivet PetscCheck(type != PETSC_STRUCT,PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}"); 96808401ef6SPierre Jolivet PetscCheck(type != PETSC_DATATYPE_UNKNOWN,PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}"); 969b62e03f8SDave May 9709566063dSJacob Faibussowitsch PetscCall(PetscDataTypeGetSize(type, &size)); 971b62e03f8SDave May /* Load a specific data type into data bucket, specifying textual name and its size in bytes */ 9729566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketRegisterField(swarm->db,"DMSwarmRegisterPetscDatatypeField",fieldname,blocksize*size,NULL)); 97352c3ed93SDave May { 97477048351SPatrick Sanan DMSwarmDataField gfield; 97552c3ed93SDave May 9769566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketGetDMSwarmDataFieldByName(swarm->db,fieldname,&gfield)); 9779566063dSJacob Faibussowitsch PetscCall(DMSwarmDataFieldSetBlockSize(gfield,blocksize)); 97852c3ed93SDave May } 979b62e03f8SDave May swarm->db->field[swarm->db->nfields-1]->petsc_type = type; 980b62e03f8SDave May PetscFunctionReturn(0); 981b62e03f8SDave May } 982b62e03f8SDave May 983d3a51819SDave May /*@C 984d3a51819SDave May DMSwarmRegisterUserStructField - Register a user defined struct to a DMSwarm 985d3a51819SDave May 986d083f849SBarry Smith Collective on dm 987d3a51819SDave May 988d3a51819SDave May Input parameters: 98962741f57SDave May + dm - a DMSwarm 990d3a51819SDave May . fieldname - the textual name to identify this field 99162741f57SDave May - size - the size in bytes of the user struct of each data type 992d3a51819SDave May 993d3a51819SDave May Level: beginner 994d3a51819SDave May 995d3a51819SDave May Notes: 9968b8a3813SDave May The textual name for each registered field must be unique. 997d3a51819SDave May 998db781477SPatrick Sanan .seealso: `DMSwarmRegisterPetscDatatypeField()`, `DMSwarmRegisterUserDatatypeField()` 999d3a51819SDave May @*/ 100074d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmRegisterUserStructField(DM dm,const char fieldname[],size_t size) 1001b62e03f8SDave May { 1002b62e03f8SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 1003b62e03f8SDave May 1004521f74f9SMatthew G. Knepley PetscFunctionBegin; 10059566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketRegisterField(swarm->db,"DMSwarmRegisterUserStructField",fieldname,size,NULL)); 1006b62e03f8SDave May swarm->db->field[swarm->db->nfields-1]->petsc_type = PETSC_STRUCT ; 1007b62e03f8SDave May PetscFunctionReturn(0); 1008b62e03f8SDave May } 1009b62e03f8SDave May 1010d3a51819SDave May /*@C 1011d3a51819SDave May DMSwarmRegisterUserDatatypeField - Register a user defined data type to a DMSwarm 1012d3a51819SDave May 1013d083f849SBarry Smith Collective on dm 1014d3a51819SDave May 1015d3a51819SDave May Input parameters: 101662741f57SDave May + dm - a DMSwarm 1017d3a51819SDave May . fieldname - the textual name to identify this field 1018d3a51819SDave May . size - the size in bytes of the user data type 101962741f57SDave May - blocksize - the number of each data type 1020d3a51819SDave May 1021d3a51819SDave May Level: beginner 1022d3a51819SDave May 1023d3a51819SDave May Notes: 10248b8a3813SDave May The textual name for each registered field must be unique. 1025d3a51819SDave May 1026db781477SPatrick Sanan .seealso: `DMSwarmRegisterPetscDatatypeField()`, `DMSwarmRegisterUserStructField()`, `DMSwarmRegisterUserDatatypeField()` 1027d3a51819SDave May @*/ 102874d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmRegisterUserDatatypeField(DM dm,const char fieldname[],size_t size,PetscInt blocksize) 1029b62e03f8SDave May { 1030b62e03f8SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 1031b62e03f8SDave May 1032521f74f9SMatthew G. Knepley PetscFunctionBegin; 10339566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketRegisterField(swarm->db,"DMSwarmRegisterUserDatatypeField",fieldname,blocksize*size,NULL)); 1034320740a0SDave May { 103577048351SPatrick Sanan DMSwarmDataField gfield; 1036320740a0SDave May 10379566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketGetDMSwarmDataFieldByName(swarm->db,fieldname,&gfield)); 10389566063dSJacob Faibussowitsch PetscCall(DMSwarmDataFieldSetBlockSize(gfield,blocksize)); 1039320740a0SDave May } 1040b62e03f8SDave May swarm->db->field[swarm->db->nfields-1]->petsc_type = PETSC_DATATYPE_UNKNOWN; 1041b62e03f8SDave May PetscFunctionReturn(0); 1042b62e03f8SDave May } 1043b62e03f8SDave May 1044d3a51819SDave May /*@C 1045d3a51819SDave May DMSwarmGetField - Get access to the underlying array storing all entries associated with a registered field 1046d3a51819SDave May 1047d3a51819SDave May Not collective 1048d3a51819SDave May 1049d3a51819SDave May Input parameters: 105062741f57SDave May + dm - a DMSwarm 105162741f57SDave May - fieldname - the textual name to identify this field 1052d3a51819SDave May 1053d3a51819SDave May Output parameters: 105462741f57SDave May + blocksize - the number of each data type 1055d3a51819SDave May . type - the data type 105662741f57SDave May - data - pointer to raw array 1057d3a51819SDave May 1058d3a51819SDave May Level: beginner 1059d3a51819SDave May 1060d3a51819SDave May Notes: 10618b8a3813SDave May The array must be returned using a matching call to DMSwarmRestoreField(). 1062d3a51819SDave May 1063db781477SPatrick Sanan .seealso: `DMSwarmRestoreField()` 1064d3a51819SDave May @*/ 106574d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmGetField(DM dm,const char fieldname[],PetscInt *blocksize,PetscDataType *type,void **data) 1066b62e03f8SDave May { 1067b62e03f8SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 106877048351SPatrick Sanan DMSwarmDataField gfield; 1069b62e03f8SDave May 1070521f74f9SMatthew G. Knepley PetscFunctionBegin; 10719566063dSJacob Faibussowitsch if (!swarm->issetup) PetscCall(DMSetUp(dm)); 10729566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketGetDMSwarmDataFieldByName(swarm->db,fieldname,&gfield)); 10739566063dSJacob Faibussowitsch PetscCall(DMSwarmDataFieldGetAccess(gfield)); 10749566063dSJacob Faibussowitsch PetscCall(DMSwarmDataFieldGetEntries(gfield,data)); 10751b1ea282SDave May if (blocksize) {*blocksize = gfield->bs; } 1076b5bcf523SDave May if (type) { *type = gfield->petsc_type; } 1077b62e03f8SDave May PetscFunctionReturn(0); 1078b62e03f8SDave May } 1079b62e03f8SDave May 1080d3a51819SDave May /*@C 1081d3a51819SDave May DMSwarmRestoreField - Restore access to the underlying array storing all entries associated with a registered field 1082d3a51819SDave May 1083d3a51819SDave May Not collective 1084d3a51819SDave May 1085d3a51819SDave May Input parameters: 108662741f57SDave May + dm - a DMSwarm 108762741f57SDave May - fieldname - the textual name to identify this field 1088d3a51819SDave May 1089d3a51819SDave May Output parameters: 109062741f57SDave May + blocksize - the number of each data type 1091d3a51819SDave May . type - the data type 109262741f57SDave May - data - pointer to raw array 1093d3a51819SDave May 1094d3a51819SDave May Level: beginner 1095d3a51819SDave May 1096d3a51819SDave May Notes: 10978b8a3813SDave May The user must call DMSwarmGetField() prior to calling DMSwarmRestoreField(). 1098d3a51819SDave May 1099db781477SPatrick Sanan .seealso: `DMSwarmGetField()` 1100d3a51819SDave May @*/ 110174d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmRestoreField(DM dm,const char fieldname[],PetscInt *blocksize,PetscDataType *type,void **data) 1102b62e03f8SDave May { 1103b62e03f8SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 110477048351SPatrick Sanan DMSwarmDataField gfield; 1105b62e03f8SDave May 1106521f74f9SMatthew G. Knepley PetscFunctionBegin; 11079566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketGetDMSwarmDataFieldByName(swarm->db,fieldname,&gfield)); 11089566063dSJacob Faibussowitsch PetscCall(DMSwarmDataFieldRestoreAccess(gfield)); 1109b62e03f8SDave May if (data) *data = NULL; 1110b62e03f8SDave May PetscFunctionReturn(0); 1111b62e03f8SDave May } 1112b62e03f8SDave May 111374d0cae8SMatthew G. Knepley /*@ 1114d3a51819SDave May DMSwarmAddPoint - Add space for one new point in the DMSwarm 1115d3a51819SDave May 1116d3a51819SDave May Not collective 1117d3a51819SDave May 1118d3a51819SDave May Input parameter: 1119d3a51819SDave May . dm - a DMSwarm 1120d3a51819SDave May 1121d3a51819SDave May Level: beginner 1122d3a51819SDave May 1123d3a51819SDave May Notes: 11248b8a3813SDave May The new point will have all fields initialized to zero. 1125d3a51819SDave May 1126db781477SPatrick Sanan .seealso: `DMSwarmAddNPoints()` 1127d3a51819SDave May @*/ 112874d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmAddPoint(DM dm) 1129cb1d1399SDave May { 1130cb1d1399SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 1131cb1d1399SDave May 1132521f74f9SMatthew G. Knepley PetscFunctionBegin; 11339566063dSJacob Faibussowitsch if (!swarm->issetup) PetscCall(DMSetUp(dm)); 11349566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(DMSWARM_AddPoints,0,0,0,0)); 11359566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketAddPoint(swarm->db)); 11369566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(DMSWARM_AddPoints,0,0,0,0)); 1137cb1d1399SDave May PetscFunctionReturn(0); 1138cb1d1399SDave May } 1139cb1d1399SDave May 114074d0cae8SMatthew G. Knepley /*@ 1141d3a51819SDave May DMSwarmAddNPoints - Add space for a number of new points in the DMSwarm 1142d3a51819SDave May 1143d3a51819SDave May Not collective 1144d3a51819SDave May 1145d3a51819SDave May Input parameters: 114662741f57SDave May + dm - a DMSwarm 114762741f57SDave May - npoints - the number of new points to add 1148d3a51819SDave May 1149d3a51819SDave May Level: beginner 1150d3a51819SDave May 1151d3a51819SDave May Notes: 11528b8a3813SDave May The new point will have all fields initialized to zero. 1153d3a51819SDave May 1154db781477SPatrick Sanan .seealso: `DMSwarmAddPoint()` 1155d3a51819SDave May @*/ 115674d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmAddNPoints(DM dm,PetscInt npoints) 1157cb1d1399SDave May { 1158cb1d1399SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 1159cb1d1399SDave May PetscInt nlocal; 1160cb1d1399SDave May 1161521f74f9SMatthew G. Knepley PetscFunctionBegin; 11629566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(DMSWARM_AddPoints,0,0,0,0)); 11639566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketGetSizes(swarm->db,&nlocal,NULL,NULL)); 1164cb1d1399SDave May nlocal = nlocal + npoints; 11659566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketSetSizes(swarm->db,nlocal,DMSWARM_DATA_BUCKET_BUFFER_DEFAULT)); 11669566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(DMSWARM_AddPoints,0,0,0,0)); 1167cb1d1399SDave May PetscFunctionReturn(0); 1168cb1d1399SDave May } 1169cb1d1399SDave May 117074d0cae8SMatthew G. Knepley /*@ 1171d3a51819SDave May DMSwarmRemovePoint - Remove the last point from the DMSwarm 1172d3a51819SDave May 1173d3a51819SDave May Not collective 1174d3a51819SDave May 1175d3a51819SDave May Input parameter: 1176d3a51819SDave May . dm - a DMSwarm 1177d3a51819SDave May 1178d3a51819SDave May Level: beginner 1179d3a51819SDave May 1180db781477SPatrick Sanan .seealso: `DMSwarmRemovePointAtIndex()` 1181d3a51819SDave May @*/ 118274d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmRemovePoint(DM dm) 1183cb1d1399SDave May { 1184cb1d1399SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 1185cb1d1399SDave May 1186521f74f9SMatthew G. Knepley PetscFunctionBegin; 11879566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(DMSWARM_RemovePoints,0,0,0,0)); 11889566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketRemovePoint(swarm->db)); 11899566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(DMSWARM_RemovePoints,0,0,0,0)); 1190cb1d1399SDave May PetscFunctionReturn(0); 1191cb1d1399SDave May } 1192cb1d1399SDave May 119374d0cae8SMatthew G. Knepley /*@ 1194d3a51819SDave May DMSwarmRemovePointAtIndex - Removes a specific point from the DMSwarm 1195d3a51819SDave May 1196d3a51819SDave May Not collective 1197d3a51819SDave May 1198d3a51819SDave May Input parameters: 119962741f57SDave May + dm - a DMSwarm 120062741f57SDave May - idx - index of point to remove 1201d3a51819SDave May 1202d3a51819SDave May Level: beginner 1203d3a51819SDave May 1204db781477SPatrick Sanan .seealso: `DMSwarmRemovePoint()` 1205d3a51819SDave May @*/ 120674d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmRemovePointAtIndex(DM dm,PetscInt idx) 1207cb1d1399SDave May { 1208cb1d1399SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 1209cb1d1399SDave May 1210521f74f9SMatthew G. Knepley PetscFunctionBegin; 12119566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(DMSWARM_RemovePoints,0,0,0,0)); 12129566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketRemovePointAtIndex(swarm->db,idx)); 12139566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(DMSWARM_RemovePoints,0,0,0,0)); 1214cb1d1399SDave May PetscFunctionReturn(0); 1215cb1d1399SDave May } 1216b62e03f8SDave May 121774d0cae8SMatthew G. Knepley /*@ 1218ba4fc9c6SDave May DMSwarmCopyPoint - Copy point pj to point pi in the DMSwarm 1219ba4fc9c6SDave May 1220ba4fc9c6SDave May Not collective 1221ba4fc9c6SDave May 1222ba4fc9c6SDave May Input parameters: 1223ba4fc9c6SDave May + dm - a DMSwarm 1224ba4fc9c6SDave May . pi - the index of the point to copy 1225ba4fc9c6SDave May - pj - the point index where the copy should be located 1226ba4fc9c6SDave May 1227ba4fc9c6SDave May Level: beginner 1228ba4fc9c6SDave May 1229db781477SPatrick Sanan .seealso: `DMSwarmRemovePoint()` 1230ba4fc9c6SDave May @*/ 123174d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmCopyPoint(DM dm,PetscInt pi,PetscInt pj) 1232ba4fc9c6SDave May { 1233ba4fc9c6SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 1234ba4fc9c6SDave May 1235ba4fc9c6SDave May PetscFunctionBegin; 12369566063dSJacob Faibussowitsch if (!swarm->issetup) PetscCall(DMSetUp(dm)); 12379566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketCopyPoint(swarm->db,pi,swarm->db,pj)); 1238ba4fc9c6SDave May PetscFunctionReturn(0); 1239ba4fc9c6SDave May } 1240ba4fc9c6SDave May 1241095059a4SDave May PetscErrorCode DMSwarmMigrate_Basic(DM dm,PetscBool remove_sent_points) 12423454631fSDave May { 1243521f74f9SMatthew G. Knepley PetscFunctionBegin; 12449566063dSJacob Faibussowitsch PetscCall(DMSwarmMigrate_Push_Basic(dm,remove_sent_points)); 12453454631fSDave May PetscFunctionReturn(0); 12463454631fSDave May } 12473454631fSDave May 124874d0cae8SMatthew G. Knepley /*@ 1249d3a51819SDave May DMSwarmMigrate - Relocates points defined in the DMSwarm to other MPI-ranks 1250d3a51819SDave May 1251d083f849SBarry Smith Collective on dm 1252d3a51819SDave May 1253d3a51819SDave May Input parameters: 125462741f57SDave May + dm - the DMSwarm 125562741f57SDave May - remove_sent_points - flag indicating if sent points should be removed from the current MPI-rank 1256d3a51819SDave May 1257d3a51819SDave May Notes: 1258a5b23f4aSJose E. Roman The DM will be modified to accommodate received points. 12598b8a3813SDave May If remove_sent_points = PETSC_TRUE, any points that were sent will be removed from the DM. 12608b8a3813SDave May Different styles of migration are supported. See DMSwarmSetMigrateType(). 1261d3a51819SDave May 1262d3a51819SDave May Level: advanced 1263d3a51819SDave May 1264db781477SPatrick Sanan .seealso: `DMSwarmSetMigrateType()` 1265d3a51819SDave May @*/ 126674d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmMigrate(DM dm,PetscBool remove_sent_points) 12673454631fSDave May { 1268f0cdbbbaSDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 1269f0cdbbbaSDave May 1270521f74f9SMatthew G. Knepley PetscFunctionBegin; 12719566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(DMSWARM_Migrate,0,0,0,0)); 1272f0cdbbbaSDave May switch (swarm->migrate_type) { 1273f0cdbbbaSDave May case DMSWARM_MIGRATE_BASIC: 12749566063dSJacob Faibussowitsch PetscCall(DMSwarmMigrate_Basic(dm,remove_sent_points)); 1275f0cdbbbaSDave May break; 1276f0cdbbbaSDave May case DMSWARM_MIGRATE_DMCELLNSCATTER: 12779566063dSJacob Faibussowitsch PetscCall(DMSwarmMigrate_CellDMScatter(dm,remove_sent_points)); 1278f0cdbbbaSDave May break; 1279f0cdbbbaSDave May case DMSWARM_MIGRATE_DMCELLEXACT: 1280f0cdbbbaSDave May SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_MIGRATE_DMCELLEXACT not implemented"); 1281f0cdbbbaSDave May case DMSWARM_MIGRATE_USER: 1282f0cdbbbaSDave May SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_MIGRATE_USER not implemented"); 1283f0cdbbbaSDave May default: 1284f0cdbbbaSDave May SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_MIGRATE type unknown"); 1285f0cdbbbaSDave May } 12869566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(DMSWARM_Migrate,0,0,0,0)); 12879566063dSJacob Faibussowitsch PetscCall(DMClearGlobalVectors(dm)); 12883454631fSDave May PetscFunctionReturn(0); 12893454631fSDave May } 12903454631fSDave May 1291f0cdbbbaSDave May PetscErrorCode DMSwarmMigrate_GlobalToLocal_Basic(DM dm,PetscInt *globalsize); 1292f0cdbbbaSDave May 1293d3a51819SDave May /* 1294d3a51819SDave May DMSwarmCollectViewCreate 1295d3a51819SDave May 1296d3a51819SDave May * Applies a collection method and gathers point neighbour points into dm 1297d3a51819SDave May 1298d3a51819SDave May Notes: 12998b8a3813SDave May Users should call DMSwarmCollectViewDestroy() after 1300d3a51819SDave May they have finished computations associated with the collected points 1301d3a51819SDave May */ 1302d3a51819SDave May 130374d0cae8SMatthew G. Knepley /*@ 1304d3a51819SDave May DMSwarmCollectViewCreate - Applies a collection method and gathers points 13055627991aSBarry Smith in neighbour ranks into the DMSwarm 1306d3a51819SDave May 1307d083f849SBarry Smith Collective on dm 1308d3a51819SDave May 1309d3a51819SDave May Input parameter: 1310d3a51819SDave May . dm - the DMSwarm 1311d3a51819SDave May 1312d3a51819SDave May Notes: 1313d3a51819SDave May Users should call DMSwarmCollectViewDestroy() after 1314d3a51819SDave May they have finished computations associated with the collected points 13158b8a3813SDave May Different collect methods are supported. See DMSwarmSetCollectType(). 1316d3a51819SDave May 1317d3a51819SDave May Level: advanced 1318d3a51819SDave May 1319db781477SPatrick Sanan .seealso: `DMSwarmCollectViewDestroy()`, `DMSwarmSetCollectType()` 1320d3a51819SDave May @*/ 132174d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmCollectViewCreate(DM dm) 13222712d1f2SDave May { 13232712d1f2SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 13242712d1f2SDave May PetscInt ng; 13252712d1f2SDave May 1326521f74f9SMatthew G. Knepley PetscFunctionBegin; 132728b400f6SJacob Faibussowitsch PetscCheck(!swarm->collect_view_active,PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"CollectView currently active"); 13289566063dSJacob Faibussowitsch PetscCall(DMSwarmGetLocalSize(dm,&ng)); 1329480eef7bSDave May switch (swarm->collect_type) { 1330f0cdbbbaSDave May 1331480eef7bSDave May case DMSWARM_COLLECT_BASIC: 13329566063dSJacob Faibussowitsch PetscCall(DMSwarmMigrate_GlobalToLocal_Basic(dm,&ng)); 1333480eef7bSDave May break; 1334480eef7bSDave May case DMSWARM_COLLECT_DMDABOUNDINGBOX: 1335f0cdbbbaSDave May SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_COLLECT_DMDABOUNDINGBOX not implemented"); 1336480eef7bSDave May case DMSWARM_COLLECT_GENERAL: 1337f0cdbbbaSDave May SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_COLLECT_GENERAL not implemented"); 1338480eef7bSDave May default: 1339f0cdbbbaSDave May SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_COLLECT type unknown"); 1340480eef7bSDave May } 1341480eef7bSDave May swarm->collect_view_active = PETSC_TRUE; 1342480eef7bSDave May swarm->collect_view_reset_nlocal = ng; 13432712d1f2SDave May PetscFunctionReturn(0); 13442712d1f2SDave May } 13452712d1f2SDave May 134674d0cae8SMatthew G. Knepley /*@ 1347d3a51819SDave May DMSwarmCollectViewDestroy - Resets the DMSwarm to the size prior to calling DMSwarmCollectViewCreate() 1348d3a51819SDave May 1349d083f849SBarry Smith Collective on dm 1350d3a51819SDave May 1351d3a51819SDave May Input parameters: 1352d3a51819SDave May . dm - the DMSwarm 1353d3a51819SDave May 1354d3a51819SDave May Notes: 1355d3a51819SDave May Users should call DMSwarmCollectViewCreate() before this function is called. 1356d3a51819SDave May 1357d3a51819SDave May Level: advanced 1358d3a51819SDave May 1359db781477SPatrick Sanan .seealso: `DMSwarmCollectViewCreate()`, `DMSwarmSetCollectType()` 1360d3a51819SDave May @*/ 136174d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmCollectViewDestroy(DM dm) 13622712d1f2SDave May { 13632712d1f2SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 13642712d1f2SDave May 1365521f74f9SMatthew G. Knepley PetscFunctionBegin; 136628b400f6SJacob Faibussowitsch PetscCheck(swarm->collect_view_active,PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"CollectView is currently not active"); 13679566063dSJacob Faibussowitsch PetscCall(DMSwarmSetLocalSizes(dm,swarm->collect_view_reset_nlocal,-1)); 1368480eef7bSDave May swarm->collect_view_active = PETSC_FALSE; 13692712d1f2SDave May PetscFunctionReturn(0); 13702712d1f2SDave May } 13713454631fSDave May 1372f0cdbbbaSDave May PetscErrorCode DMSwarmSetUpPIC(DM dm) 1373f0cdbbbaSDave May { 1374f0cdbbbaSDave May PetscInt dim; 1375f0cdbbbaSDave May 1376521f74f9SMatthew G. Knepley PetscFunctionBegin; 13779566063dSJacob Faibussowitsch PetscCall(DMSwarmSetNumSpecies(dm, 1)); 13789566063dSJacob Faibussowitsch PetscCall(DMGetDimension(dm,&dim)); 137963a3b9bcSJacob Faibussowitsch PetscCheck(dim >= 1,PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Dimension must be 1,2,3 - found %" PetscInt_FMT,dim); 138063a3b9bcSJacob Faibussowitsch PetscCheck(dim <= 3,PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Dimension must be 1,2,3 - found %" PetscInt_FMT,dim); 13819566063dSJacob Faibussowitsch PetscCall(DMSwarmRegisterPetscDatatypeField(dm,DMSwarmPICField_coor,dim,PETSC_DOUBLE)); 13829566063dSJacob Faibussowitsch PetscCall(DMSwarmRegisterPetscDatatypeField(dm,DMSwarmPICField_cellid,1,PETSC_INT)); 1383f0cdbbbaSDave May PetscFunctionReturn(0); 1384f0cdbbbaSDave May } 1385f0cdbbbaSDave May 138674d0cae8SMatthew G. Knepley /*@ 138731403186SMatthew G. Knepley DMSwarmSetPointCoordinatesRandom - Sets initial coordinates for particles in each cell 138831403186SMatthew G. Knepley 138931403186SMatthew G. Knepley Collective on dm 139031403186SMatthew G. Knepley 139131403186SMatthew G. Knepley Input parameters: 139231403186SMatthew G. Knepley + dm - the DMSwarm 139331403186SMatthew G. Knepley - Npc - The number of particles per cell in the cell DM 139431403186SMatthew G. Knepley 139531403186SMatthew G. Knepley Notes: 139631403186SMatthew G. Knepley The user must use DMSwarmSetCellDM() to set the cell DM first. The particles are placed randomly inside each cell. If only 139731403186SMatthew G. Knepley one particle is in each cell, it is placed at the centroid. 139831403186SMatthew G. Knepley 139931403186SMatthew G. Knepley Level: intermediate 140031403186SMatthew G. Knepley 1401db781477SPatrick Sanan .seealso: `DMSwarmSetCellDM()` 140231403186SMatthew G. Knepley @*/ 140331403186SMatthew G. Knepley PetscErrorCode DMSwarmSetPointCoordinatesRandom(DM dm, PetscInt Npc) 140431403186SMatthew G. Knepley { 140531403186SMatthew G. Knepley DM cdm; 140631403186SMatthew G. Knepley PetscRandom rnd; 140731403186SMatthew G. Knepley DMPolytopeType ct; 140831403186SMatthew G. Knepley PetscBool simplex; 140931403186SMatthew G. Knepley PetscReal *centroid, *coords, *xi0, *v0, *J, *invJ, detJ; 141031403186SMatthew G. Knepley PetscInt dim, d, cStart, cEnd, c, p; 141131403186SMatthew G. Knepley 141231403186SMatthew G. Knepley PetscFunctionBeginUser; 14139566063dSJacob Faibussowitsch PetscCall(PetscRandomCreate(PetscObjectComm((PetscObject) dm), &rnd)); 14149566063dSJacob Faibussowitsch PetscCall(PetscRandomSetInterval(rnd, -1.0, 1.0)); 14159566063dSJacob Faibussowitsch PetscCall(PetscRandomSetType(rnd, PETSCRAND48)); 141631403186SMatthew G. Knepley 14179566063dSJacob Faibussowitsch PetscCall(DMSwarmGetCellDM(dm, &cdm)); 14189566063dSJacob Faibussowitsch PetscCall(DMGetDimension(cdm, &dim)); 14199566063dSJacob Faibussowitsch PetscCall(DMPlexGetHeightStratum(cdm, 0, &cStart, &cEnd)); 14209566063dSJacob Faibussowitsch PetscCall(DMPlexGetCellType(cdm, cStart, &ct)); 142131403186SMatthew G. Knepley simplex = DMPolytopeTypeGetNumVertices(ct) == DMPolytopeTypeGetDim(ct)+1 ? PETSC_TRUE : PETSC_FALSE; 142231403186SMatthew G. Knepley 14239566063dSJacob Faibussowitsch PetscCall(PetscMalloc5(dim, ¢roid, dim, &xi0, dim, &v0, dim*dim, &J, dim*dim, &invJ)); 142431403186SMatthew G. Knepley for (d = 0; d < dim; ++d) xi0[d] = -1.0; 14259566063dSJacob Faibussowitsch PetscCall(DMSwarmGetField(dm, DMSwarmPICField_coor, NULL, NULL, (void **) &coords)); 142631403186SMatthew G. Knepley for (c = cStart; c < cEnd; ++c) { 142731403186SMatthew G. Knepley if (Npc == 1) { 14289566063dSJacob Faibussowitsch PetscCall(DMPlexComputeCellGeometryFVM(cdm, c, NULL, centroid, NULL)); 142931403186SMatthew G. Knepley for (d = 0; d < dim; ++d) coords[c*dim+d] = centroid[d]; 143031403186SMatthew G. Knepley } else { 14319566063dSJacob Faibussowitsch PetscCall(DMPlexComputeCellGeometryFEM(cdm, c, NULL, v0, J, invJ, &detJ)); /* affine */ 143231403186SMatthew G. Knepley for (p = 0; p < Npc; ++p) { 143331403186SMatthew G. Knepley const PetscInt n = c*Npc + p; 143431403186SMatthew G. Knepley PetscReal sum = 0.0, refcoords[3]; 143531403186SMatthew G. Knepley 143631403186SMatthew G. Knepley for (d = 0; d < dim; ++d) { 14379566063dSJacob Faibussowitsch PetscCall(PetscRandomGetValueReal(rnd, &refcoords[d])); 143831403186SMatthew G. Knepley sum += refcoords[d]; 143931403186SMatthew G. Knepley } 144031403186SMatthew G. Knepley if (simplex && sum > 0.0) for (d = 0; d < dim; ++d) refcoords[d] -= PetscSqrtReal(dim)*sum; 144131403186SMatthew G. Knepley CoordinatesRefToReal(dim, dim, xi0, v0, J, refcoords, &coords[n*dim]); 144231403186SMatthew G. Knepley } 144331403186SMatthew G. Knepley } 144431403186SMatthew G. Knepley } 14459566063dSJacob Faibussowitsch PetscCall(DMSwarmRestoreField(dm, DMSwarmPICField_coor, NULL, NULL, (void **) &coords)); 14469566063dSJacob Faibussowitsch PetscCall(PetscFree5(centroid, xi0, v0, J, invJ)); 14479566063dSJacob Faibussowitsch PetscCall(PetscRandomDestroy(&rnd)); 144831403186SMatthew G. Knepley PetscFunctionReturn(0); 144931403186SMatthew G. Knepley } 145031403186SMatthew G. Knepley 145131403186SMatthew G. Knepley /*@ 1452d3a51819SDave May DMSwarmSetType - Set particular flavor of DMSwarm 1453d3a51819SDave May 1454d083f849SBarry Smith Collective on dm 1455d3a51819SDave May 1456d3a51819SDave May Input parameters: 145762741f57SDave May + dm - the DMSwarm 145862741f57SDave May - stype - the DMSwarm type (e.g. DMSWARM_PIC) 1459d3a51819SDave May 1460d3a51819SDave May Level: advanced 1461d3a51819SDave May 1462db781477SPatrick Sanan .seealso: `DMSwarmSetMigrateType()`, `DMSwarmSetCollectType()`, `DMSwarmType`, `DMSWARM_PIC`, `DMSWARM_BASIC` 1463d3a51819SDave May @*/ 146474d0cae8SMatthew G. Knepley PetscErrorCode DMSwarmSetType(DM dm,DMSwarmType stype) 1465f0cdbbbaSDave May { 1466f0cdbbbaSDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 1467f0cdbbbaSDave May 1468521f74f9SMatthew G. Knepley PetscFunctionBegin; 1469f0cdbbbaSDave May swarm->swarm_type = stype; 1470f0cdbbbaSDave May if (swarm->swarm_type == DMSWARM_PIC) { 14719566063dSJacob Faibussowitsch PetscCall(DMSwarmSetUpPIC(dm)); 1472f0cdbbbaSDave May } 1473f0cdbbbaSDave May PetscFunctionReturn(0); 1474f0cdbbbaSDave May } 1475f0cdbbbaSDave May 14763454631fSDave May PetscErrorCode DMSetup_Swarm(DM dm) 14773454631fSDave May { 14783454631fSDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 14793454631fSDave May PetscMPIInt rank; 14803454631fSDave May PetscInt p,npoints,*rankval; 14813454631fSDave May 1482521f74f9SMatthew G. Knepley PetscFunctionBegin; 14833454631fSDave May if (swarm->issetup) PetscFunctionReturn(0); 14843454631fSDave May swarm->issetup = PETSC_TRUE; 14853454631fSDave May 1486f0cdbbbaSDave May if (swarm->swarm_type == DMSWARM_PIC) { 1487f0cdbbbaSDave May /* check dmcell exists */ 148828b400f6SJacob Faibussowitsch PetscCheck(swarm->dmcell,PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSWARM_PIC requires you call DMSwarmSetCellDM"); 1489f0cdbbbaSDave May 1490f0cdbbbaSDave May if (swarm->dmcell->ops->locatepointssubdomain) { 1491f0cdbbbaSDave May /* check methods exists for exact ownership identificiation */ 14929566063dSJacob Faibussowitsch PetscCall(PetscInfo(dm, "DMSWARM_PIC: Using method CellDM->ops->LocatePointsSubdomain\n")); 1493f0cdbbbaSDave May swarm->migrate_type = DMSWARM_MIGRATE_DMCELLEXACT; 1494f0cdbbbaSDave May } else { 1495f0cdbbbaSDave May /* check methods exist for point location AND rank neighbor identification */ 1496f0cdbbbaSDave May if (swarm->dmcell->ops->locatepoints) { 14979566063dSJacob Faibussowitsch PetscCall(PetscInfo(dm, "DMSWARM_PIC: Using method CellDM->LocatePoints\n")); 1498f0cdbbbaSDave May } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSWARM_PIC requires the method CellDM->ops->locatepoints be defined"); 1499f0cdbbbaSDave May 1500f0cdbbbaSDave May if (swarm->dmcell->ops->getneighbors) { 15019566063dSJacob Faibussowitsch PetscCall(PetscInfo(dm, "DMSWARM_PIC: Using method CellDM->GetNeigbors\n")); 1502f0cdbbbaSDave May } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSWARM_PIC requires the method CellDM->ops->getneighbors be defined"); 1503f0cdbbbaSDave May 1504f0cdbbbaSDave May swarm->migrate_type = DMSWARM_MIGRATE_DMCELLNSCATTER; 1505f0cdbbbaSDave May } 1506f0cdbbbaSDave May } 1507f0cdbbbaSDave May 15089566063dSJacob Faibussowitsch PetscCall(DMSwarmFinalizeFieldRegister(dm)); 1509f0cdbbbaSDave May 15103454631fSDave May /* check some fields were registered */ 151108401ef6SPierre Jolivet PetscCheck(swarm->db->nfields > 2,PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"At least one field user must be registered via DMSwarmRegisterXXX()"); 15123454631fSDave May 15133454631fSDave May /* check local sizes were set */ 151408401ef6SPierre Jolivet PetscCheck(swarm->db->L != -1,PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Local sizes must be set via DMSwarmSetLocalSizes()"); 15153454631fSDave May 15163454631fSDave May /* initialize values in pid and rank placeholders */ 15173454631fSDave May /* TODO: [pid - use MPI_Scan] */ 15189566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)dm),&rank)); 15199566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketGetSizes(swarm->db,&npoints,NULL,NULL)); 15209566063dSJacob Faibussowitsch PetscCall(DMSwarmGetField(dm,DMSwarmField_rank,NULL,NULL,(void**)&rankval)); 15213454631fSDave May for (p=0; p<npoints; p++) { 15223454631fSDave May rankval[p] = (PetscInt)rank; 15233454631fSDave May } 15249566063dSJacob Faibussowitsch PetscCall(DMSwarmRestoreField(dm,DMSwarmField_rank,NULL,NULL,(void**)&rankval)); 15253454631fSDave May PetscFunctionReturn(0); 15263454631fSDave May } 15273454631fSDave May 1528dc5f5ce9SDave May extern PetscErrorCode DMSwarmSortDestroy(DMSwarmSort *_ctx); 1529dc5f5ce9SDave May 153057795646SDave May PetscErrorCode DMDestroy_Swarm(DM dm) 153157795646SDave May { 153257795646SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 153357795646SDave May 153457795646SDave May PetscFunctionBegin; 1535d0c080abSJoseph Pusztay if (--swarm->refct > 0) PetscFunctionReturn(0); 15369566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketDestroy(&swarm->db)); 1537dc5f5ce9SDave May if (swarm->sort_context) { 15389566063dSJacob Faibussowitsch PetscCall(DMSwarmSortDestroy(&swarm->sort_context)); 1539dc5f5ce9SDave May } 15409566063dSJacob Faibussowitsch PetscCall(PetscFree(swarm)); 154157795646SDave May PetscFunctionReturn(0); 154257795646SDave May } 154357795646SDave May 1544a9ee3421SMatthew G. Knepley PetscErrorCode DMSwarmView_Draw(DM dm, PetscViewer viewer) 1545a9ee3421SMatthew G. Knepley { 1546a9ee3421SMatthew G. Knepley DM cdm; 1547a9ee3421SMatthew G. Knepley PetscDraw draw; 154831403186SMatthew G. Knepley PetscReal *coords, oldPause, radius = 0.01; 1549a9ee3421SMatthew G. Knepley PetscInt Np, p, bs; 1550a9ee3421SMatthew G. Knepley 1551a9ee3421SMatthew G. Knepley PetscFunctionBegin; 15529566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetReal(NULL, ((PetscObject) dm)->prefix, "-dm_view_swarm_radius", &radius, NULL)); 15539566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw)); 15549566063dSJacob Faibussowitsch PetscCall(DMSwarmGetCellDM(dm, &cdm)); 15559566063dSJacob Faibussowitsch PetscCall(PetscDrawGetPause(draw, &oldPause)); 15569566063dSJacob Faibussowitsch PetscCall(PetscDrawSetPause(draw, 0.0)); 15579566063dSJacob Faibussowitsch PetscCall(DMView(cdm, viewer)); 15589566063dSJacob Faibussowitsch PetscCall(PetscDrawSetPause(draw, oldPause)); 1559a9ee3421SMatthew G. Knepley 15609566063dSJacob Faibussowitsch PetscCall(DMSwarmGetLocalSize(dm, &Np)); 15619566063dSJacob Faibussowitsch PetscCall(DMSwarmGetField(dm, DMSwarmPICField_coor, &bs, NULL, (void **) &coords)); 1562a9ee3421SMatthew G. Knepley for (p = 0; p < Np; ++p) { 1563a9ee3421SMatthew G. Knepley const PetscInt i = p*bs; 1564a9ee3421SMatthew G. Knepley 15659566063dSJacob Faibussowitsch PetscCall(PetscDrawEllipse(draw, coords[i], coords[i+1], radius, radius, PETSC_DRAW_BLUE)); 1566a9ee3421SMatthew G. Knepley } 15679566063dSJacob Faibussowitsch PetscCall(DMSwarmRestoreField(dm, DMSwarmPICField_coor, &bs, NULL, (void **) &coords)); 15689566063dSJacob Faibussowitsch PetscCall(PetscDrawFlush(draw)); 15699566063dSJacob Faibussowitsch PetscCall(PetscDrawPause(draw)); 15709566063dSJacob Faibussowitsch PetscCall(PetscDrawSave(draw)); 1571a9ee3421SMatthew G. Knepley PetscFunctionReturn(0); 1572a9ee3421SMatthew G. Knepley } 1573a9ee3421SMatthew G. Knepley 15746a5217c0SMatthew G. Knepley static PetscErrorCode DMView_Swarm_Ascii(DM dm, PetscViewer viewer) 15756a5217c0SMatthew G. Knepley { 15766a5217c0SMatthew G. Knepley PetscViewerFormat format; 15776a5217c0SMatthew G. Knepley PetscInt *sizes; 15786a5217c0SMatthew G. Knepley PetscInt dim, Np, maxSize = 17; 15796a5217c0SMatthew G. Knepley MPI_Comm comm; 15806a5217c0SMatthew G. Knepley PetscMPIInt rank, size, p; 15816a5217c0SMatthew G. Knepley const char *name; 15826a5217c0SMatthew G. Knepley 15836a5217c0SMatthew G. Knepley PetscFunctionBegin; 15846a5217c0SMatthew G. Knepley PetscCall(PetscViewerGetFormat(viewer, &format)); 15856a5217c0SMatthew G. Knepley PetscCall(DMGetDimension(dm, &dim)); 15866a5217c0SMatthew G. Knepley PetscCall(DMSwarmGetLocalSize(dm, &Np)); 15876a5217c0SMatthew G. Knepley PetscCall(PetscObjectGetComm((PetscObject) dm, &comm)); 15886a5217c0SMatthew G. Knepley PetscCallMPI(MPI_Comm_rank(comm, &rank)); 15896a5217c0SMatthew G. Knepley PetscCallMPI(MPI_Comm_size(comm, &size)); 15906a5217c0SMatthew G. Knepley PetscCall(PetscObjectGetName((PetscObject) dm, &name)); 159163a3b9bcSJacob Faibussowitsch if (name) PetscCall(PetscViewerASCIIPrintf(viewer, "%s in %" PetscInt_FMT " dimension%s:\n", name, dim, dim == 1 ? "" : "s")); 159263a3b9bcSJacob Faibussowitsch else PetscCall(PetscViewerASCIIPrintf(viewer, "Swarm in %" PetscInt_FMT " dimension%s:\n", dim, dim == 1 ? "" : "s")); 15936a5217c0SMatthew G. Knepley if (size < maxSize) PetscCall(PetscCalloc1(size, &sizes)); 15946a5217c0SMatthew G. Knepley else PetscCall(PetscCalloc1(3, &sizes)); 15956a5217c0SMatthew G. Knepley if (size < maxSize) { 15966a5217c0SMatthew G. Knepley PetscCallMPI(MPI_Gather(&Np, 1, MPIU_INT, sizes, 1, MPIU_INT, 0, comm)); 15976a5217c0SMatthew G. Knepley PetscCall(PetscViewerASCIIPrintf(viewer, " Number of particles per rank:")); 15986a5217c0SMatthew G. Knepley for (p = 0; p < size; ++p) { 15996a5217c0SMatthew G. Knepley if (rank == 0) PetscCall(PetscViewerASCIIPrintf(viewer, " %" PetscInt_FMT, sizes[p])); 16006a5217c0SMatthew G. Knepley } 16016a5217c0SMatthew G. Knepley } else { 16026a5217c0SMatthew G. Knepley PetscInt locMinMax[2] = {Np, Np}; 16036a5217c0SMatthew G. Knepley 16046a5217c0SMatthew G. Knepley PetscCall(PetscGlobalMinMaxInt(comm, locMinMax, sizes)); 16056a5217c0SMatthew G. Knepley PetscCall(PetscViewerASCIIPrintf(viewer, " Min/Max of particles per rank: %" PetscInt_FMT "/%" PetscInt_FMT, sizes[0], sizes[1])); 16066a5217c0SMatthew G. Knepley } 16076a5217c0SMatthew G. Knepley PetscCall(PetscViewerASCIIPrintf(viewer, "\n")); 16086a5217c0SMatthew G. Knepley PetscCall(PetscFree(sizes)); 16096a5217c0SMatthew G. Knepley if (format == PETSC_VIEWER_ASCII_INFO) { 16106a5217c0SMatthew G. Knepley PetscInt *cell; 16116a5217c0SMatthew G. Knepley 16126a5217c0SMatthew G. Knepley PetscCall(PetscViewerASCIIPrintf(viewer, " Cells containing each particle:\n")); 16136a5217c0SMatthew G. Knepley PetscCall(PetscViewerASCIIPushSynchronized(viewer)); 16146a5217c0SMatthew G. Knepley PetscCall(DMSwarmGetField(dm, DMSwarmPICField_cellid, NULL, NULL, (void**) &cell)); 161563a3b9bcSJacob Faibussowitsch for (p = 0; p < Np; ++p) PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, " p%d: %" PetscInt_FMT "\n", p, cell[p])); 16166a5217c0SMatthew G. Knepley PetscCall(PetscViewerFlush(viewer)); 16176a5217c0SMatthew G. Knepley PetscCall(PetscViewerASCIIPopSynchronized(viewer)); 16186a5217c0SMatthew G. Knepley PetscCall(DMSwarmRestoreField(dm, DMSwarmPICField_cellid, NULL, NULL, (void**) &cell)); 16196a5217c0SMatthew G. Knepley } 16206a5217c0SMatthew G. Knepley PetscFunctionReturn(0); 16216a5217c0SMatthew G. Knepley } 16226a5217c0SMatthew G. Knepley 16235f50eb2eSDave May PetscErrorCode DMView_Swarm(DM dm, PetscViewer viewer) 16245f50eb2eSDave May { 16255f50eb2eSDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 16265627991aSBarry Smith PetscBool iascii,ibinary,isvtk,isdraw; 16275627991aSBarry Smith #if defined(PETSC_HAVE_HDF5) 16285627991aSBarry Smith PetscBool ishdf5; 16295627991aSBarry Smith #endif 16305f50eb2eSDave May 16315f50eb2eSDave May PetscFunctionBegin; 16325f50eb2eSDave May PetscValidHeaderSpecific(dm,DM_CLASSID,1); 16335f50eb2eSDave May PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 16349566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 16359566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY,&ibinary)); 16369566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERVTK, &isvtk)); 16375627991aSBarry Smith #if defined(PETSC_HAVE_HDF5) 16389566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5, &ishdf5)); 16395627991aSBarry Smith #endif 16409566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw)); 16415f50eb2eSDave May if (iascii) { 16426a5217c0SMatthew G. Knepley PetscViewerFormat format; 16436a5217c0SMatthew G. Knepley 16446a5217c0SMatthew G. Knepley PetscCall(PetscViewerGetFormat(viewer, &format)); 16456a5217c0SMatthew G. Knepley switch (format) { 16466a5217c0SMatthew G. Knepley case PETSC_VIEWER_ASCII_INFO_DETAIL: 16476a5217c0SMatthew G. Knepley PetscCall(DMSwarmDataBucketView(PetscObjectComm((PetscObject) dm), swarm->db, NULL, DATABUCKET_VIEW_STDOUT));break; 16486a5217c0SMatthew G. Knepley default: PetscCall(DMView_Swarm_Ascii(dm, viewer)); 16496a5217c0SMatthew G. Knepley } 165028b400f6SJacob Faibussowitsch } else PetscCheck(!ibinary,PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"NO Binary support"); 16515f50eb2eSDave May #if defined(PETSC_HAVE_HDF5) 165274d0cae8SMatthew G. Knepley else if (ishdf5) { 16539566063dSJacob Faibussowitsch PetscCall(DMSwarmView_HDF5(dm, viewer)); 165474d0cae8SMatthew G. Knepley } 16555f50eb2eSDave May #endif 1656298827fbSBarry Smith else if (isdraw) { 16579566063dSJacob Faibussowitsch PetscCall(DMSwarmView_Draw(dm, viewer)); 16585f50eb2eSDave May } 16595f50eb2eSDave May PetscFunctionReturn(0); 16605f50eb2eSDave May } 16615f50eb2eSDave May 1662d0c080abSJoseph Pusztay /*@C 1663d0c080abSJoseph Pusztay DMSwarmGetCellSwarm - Extracts a single cell from the DMSwarm object, returns it as a single cell DMSwarm. 1664d0c080abSJoseph 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. 1665d0c080abSJoseph Pusztay 1666d0c080abSJoseph Pusztay Important: Changes to this cell of the swarm will be lost if they are made prior to restoring this cell. 1667d0c080abSJoseph Pusztay 1668d0c080abSJoseph Pusztay Noncollective 1669d0c080abSJoseph Pusztay 1670d0c080abSJoseph Pusztay Input parameters: 1671d0c080abSJoseph Pusztay + sw - the DMSwarm 16725627991aSBarry Smith . cellID - the integer id of the cell to be extracted and filtered 16735627991aSBarry Smith - cellswarm - The DMSwarm to receive the cell 1674d0c080abSJoseph Pusztay 1675d0c080abSJoseph Pusztay Level: beginner 1676d0c080abSJoseph Pusztay 16775627991aSBarry Smith Notes: 16785627991aSBarry Smith This presently only supports DMSWARM_PIC type 16795627991aSBarry Smith 16805627991aSBarry Smith Should be restored with DMSwarmRestoreCellSwarm() 1681d0c080abSJoseph Pusztay 1682db781477SPatrick Sanan .seealso: `DMSwarmRestoreCellSwarm()` 1683d0c080abSJoseph Pusztay @*/ 1684d0c080abSJoseph Pusztay PETSC_EXTERN PetscErrorCode DMSwarmGetCellSwarm(DM sw, PetscInt cellID, DM cellswarm) 1685d0c080abSJoseph Pusztay { 1686d0c080abSJoseph Pusztay DM_Swarm *original = (DM_Swarm*) sw->data; 1687d0c080abSJoseph Pusztay DMLabel label; 1688d0c080abSJoseph Pusztay DM dmc, subdmc; 1689d0c080abSJoseph Pusztay PetscInt *pids, particles, dim; 1690d0c080abSJoseph Pusztay 1691d0c080abSJoseph Pusztay PetscFunctionBegin; 1692d0c080abSJoseph Pusztay /* Configure new swarm */ 16939566063dSJacob Faibussowitsch PetscCall(DMSetType(cellswarm, DMSWARM)); 16949566063dSJacob Faibussowitsch PetscCall(DMGetDimension(sw, &dim)); 16959566063dSJacob Faibussowitsch PetscCall(DMSetDimension(cellswarm, dim)); 16969566063dSJacob Faibussowitsch PetscCall(DMSwarmSetType(cellswarm, DMSWARM_PIC)); 1697d0c080abSJoseph Pusztay /* Destroy the unused, unconfigured data bucket to prevent stragglers in memory */ 16989566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketDestroy(&((DM_Swarm*)cellswarm->data)->db)); 16999566063dSJacob Faibussowitsch PetscCall(DMSwarmSortGetAccess(sw)); 17009566063dSJacob Faibussowitsch PetscCall(DMSwarmSortGetNumberOfPointsPerCell(sw, cellID, &particles)); 17019566063dSJacob Faibussowitsch PetscCall(DMSwarmSortGetPointsPerCell(sw, cellID, &particles, &pids)); 17029566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketCreateFromSubset(original->db, particles, pids, &((DM_Swarm*)cellswarm->data)->db)); 17039566063dSJacob Faibussowitsch PetscCall(DMSwarmSortRestoreAccess(sw)); 17049566063dSJacob Faibussowitsch PetscCall(PetscFree(pids)); 17059566063dSJacob Faibussowitsch PetscCall(DMSwarmGetCellDM(sw, &dmc)); 17069566063dSJacob Faibussowitsch PetscCall(DMLabelCreate(PetscObjectComm((PetscObject)sw), "singlecell", &label)); 17079566063dSJacob Faibussowitsch PetscCall(DMAddLabel(dmc, label)); 17089566063dSJacob Faibussowitsch PetscCall(DMLabelSetValue(label, cellID, 1)); 17099566063dSJacob Faibussowitsch PetscCall(DMPlexFilter(dmc, label, 1, &subdmc)); 17109566063dSJacob Faibussowitsch PetscCall(DMSwarmSetCellDM(cellswarm, subdmc)); 17119566063dSJacob Faibussowitsch PetscCall(DMLabelDestroy(&label)); 1712d0c080abSJoseph Pusztay PetscFunctionReturn(0); 1713d0c080abSJoseph Pusztay } 1714d0c080abSJoseph Pusztay 1715d0c080abSJoseph Pusztay /*@C 17165627991aSBarry Smith DMSwarmRestoreCellSwarm - Restores a DMSwarm object obtained with DMSwarmGetCellSwarm(). All fields are copied back into the parent swarm. 1717d0c080abSJoseph Pusztay 1718d0c080abSJoseph Pusztay Noncollective 1719d0c080abSJoseph Pusztay 1720d0c080abSJoseph Pusztay Input parameters: 1721d0c080abSJoseph Pusztay + sw - the parent DMSwarm 1722d0c080abSJoseph Pusztay . cellID - the integer id of the cell to be copied back into the parent swarm 1723d0c080abSJoseph Pusztay - cellswarm - the cell swarm object 1724d0c080abSJoseph Pusztay 1725d0c080abSJoseph Pusztay Level: beginner 1726d0c080abSJoseph Pusztay 17275627991aSBarry Smith Note: 17285627991aSBarry Smith This only supports DMSWARM_PIC types of DMSwarms 1729d0c080abSJoseph Pusztay 1730db781477SPatrick Sanan .seealso: `DMSwarmGetCellSwarm()` 1731d0c080abSJoseph Pusztay @*/ 1732d0c080abSJoseph Pusztay PETSC_EXTERN PetscErrorCode DMSwarmRestoreCellSwarm(DM sw, PetscInt cellID, DM cellswarm) 1733d0c080abSJoseph Pusztay { 1734d0c080abSJoseph Pusztay DM dmc; 1735d0c080abSJoseph Pusztay PetscInt *pids, particles, p; 1736d0c080abSJoseph Pusztay 1737d0c080abSJoseph Pusztay PetscFunctionBegin; 17389566063dSJacob Faibussowitsch PetscCall(DMSwarmSortGetAccess(sw)); 17399566063dSJacob Faibussowitsch PetscCall(DMSwarmSortGetPointsPerCell(sw, cellID, &particles, &pids)); 17409566063dSJacob Faibussowitsch PetscCall(DMSwarmSortRestoreAccess(sw)); 1741d0c080abSJoseph Pusztay /* Pointwise copy of each particle based on pid. The parent swarm may not be altered during this process. */ 1742d0c080abSJoseph Pusztay for (p=0; p<particles; ++p) { 17439566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketCopyPoint(((DM_Swarm*)cellswarm->data)->db,pids[p],((DM_Swarm*)sw->data)->db,pids[p])); 1744d0c080abSJoseph Pusztay } 1745d0c080abSJoseph Pusztay /* Free memory, destroy cell dm */ 17469566063dSJacob Faibussowitsch PetscCall(DMSwarmGetCellDM(cellswarm, &dmc)); 17479566063dSJacob Faibussowitsch PetscCall(DMDestroy(&dmc)); 17489566063dSJacob Faibussowitsch PetscCall(PetscFree(pids)); 1749d0c080abSJoseph Pusztay PetscFunctionReturn(0); 1750d0c080abSJoseph Pusztay } 1751d0c080abSJoseph Pusztay 1752d0c080abSJoseph Pusztay PETSC_INTERN PetscErrorCode DMClone_Swarm(DM, DM *); 1753d0c080abSJoseph Pusztay 1754d0c080abSJoseph Pusztay static PetscErrorCode DMInitialize_Swarm(DM sw) 1755d0c080abSJoseph Pusztay { 1756d0c080abSJoseph Pusztay PetscFunctionBegin; 1757d0c080abSJoseph Pusztay sw->dim = 0; 1758d0c080abSJoseph Pusztay sw->ops->view = DMView_Swarm; 1759d0c080abSJoseph Pusztay sw->ops->load = NULL; 1760d0c080abSJoseph Pusztay sw->ops->setfromoptions = NULL; 1761d0c080abSJoseph Pusztay sw->ops->clone = DMClone_Swarm; 1762d0c080abSJoseph Pusztay sw->ops->setup = DMSetup_Swarm; 1763d0c080abSJoseph Pusztay sw->ops->createlocalsection = NULL; 1764d0c080abSJoseph Pusztay sw->ops->createdefaultconstraints = NULL; 1765d0c080abSJoseph Pusztay sw->ops->createglobalvector = DMCreateGlobalVector_Swarm; 1766d0c080abSJoseph Pusztay sw->ops->createlocalvector = DMCreateLocalVector_Swarm; 1767d0c080abSJoseph Pusztay sw->ops->getlocaltoglobalmapping = NULL; 1768d0c080abSJoseph Pusztay sw->ops->createfieldis = NULL; 1769d0c080abSJoseph Pusztay sw->ops->createcoordinatedm = NULL; 1770d0c080abSJoseph Pusztay sw->ops->getcoloring = NULL; 1771d0c080abSJoseph Pusztay sw->ops->creatematrix = DMCreateMatrix_Swarm; 1772d0c080abSJoseph Pusztay sw->ops->createinterpolation = NULL; 1773d0c080abSJoseph Pusztay sw->ops->createinjection = NULL; 1774d0c080abSJoseph Pusztay sw->ops->createmassmatrix = DMCreateMassMatrix_Swarm; 1775d0c080abSJoseph Pusztay sw->ops->refine = NULL; 1776d0c080abSJoseph Pusztay sw->ops->coarsen = NULL; 1777d0c080abSJoseph Pusztay sw->ops->refinehierarchy = NULL; 1778d0c080abSJoseph Pusztay sw->ops->coarsenhierarchy = NULL; 1779d0c080abSJoseph Pusztay sw->ops->globaltolocalbegin = NULL; 1780d0c080abSJoseph Pusztay sw->ops->globaltolocalend = NULL; 1781d0c080abSJoseph Pusztay sw->ops->localtoglobalbegin = NULL; 1782d0c080abSJoseph Pusztay sw->ops->localtoglobalend = NULL; 1783d0c080abSJoseph Pusztay sw->ops->destroy = DMDestroy_Swarm; 1784d0c080abSJoseph Pusztay sw->ops->createsubdm = NULL; 1785d0c080abSJoseph Pusztay sw->ops->getdimpoints = NULL; 1786d0c080abSJoseph Pusztay sw->ops->locatepoints = NULL; 1787d0c080abSJoseph Pusztay PetscFunctionReturn(0); 1788d0c080abSJoseph Pusztay } 1789d0c080abSJoseph Pusztay 1790d0c080abSJoseph Pusztay PETSC_INTERN PetscErrorCode DMClone_Swarm(DM dm, DM *newdm) 1791d0c080abSJoseph Pusztay { 1792d0c080abSJoseph Pusztay DM_Swarm *swarm = (DM_Swarm *) dm->data; 1793d0c080abSJoseph Pusztay 1794d0c080abSJoseph Pusztay PetscFunctionBegin; 1795d0c080abSJoseph Pusztay swarm->refct++; 1796d0c080abSJoseph Pusztay (*newdm)->data = swarm; 17979566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject) *newdm, DMSWARM)); 17989566063dSJacob Faibussowitsch PetscCall(DMInitialize_Swarm(*newdm)); 17992e56dffeSJoe Pusztay (*newdm)->dim = dm->dim; 1800d0c080abSJoseph Pusztay PetscFunctionReturn(0); 1801d0c080abSJoseph Pusztay } 1802d0c080abSJoseph Pusztay 1803d3a51819SDave May /*MC 1804d3a51819SDave May 1805d3a51819SDave May DMSWARM = "swarm" - A DM object used to represent arrays of data (fields) of arbitrary data type. 180662741f57SDave May This implementation was designed for particle methods in which the underlying 1807d3a51819SDave May data required to be represented is both (i) dynamic in length, (ii) and of arbitrary data type. 1808d3a51819SDave May 180962741f57SDave May User data can be represented by DMSwarm through a registering "fields". 181062741f57SDave May To register a field, the user must provide; 181162741f57SDave May (a) a unique name; 181262741f57SDave May (b) the data type (or size in bytes); 181362741f57SDave May (c) the block size of the data. 1814d3a51819SDave May 1815d3a51819SDave May For example, suppose the application requires a unique id, energy, momentum and density to be stored 1816c215a47eSMatthew Knepley on a set of particles. Then the following code could be used 1817d3a51819SDave May 181862741f57SDave May $ DMSwarmInitializeFieldRegister(dm) 181962741f57SDave May $ DMSwarmRegisterPetscDatatypeField(dm,"uid",1,PETSC_LONG); 182062741f57SDave May $ DMSwarmRegisterPetscDatatypeField(dm,"energy",1,PETSC_REAL); 182162741f57SDave May $ DMSwarmRegisterPetscDatatypeField(dm,"momentum",3,PETSC_REAL); 182262741f57SDave May $ DMSwarmRegisterPetscDatatypeField(dm,"density",1,PETSC_FLOAT); 182362741f57SDave May $ DMSwarmFinalizeFieldRegister(dm) 1824d3a51819SDave May 1825d3a51819SDave May The fields represented by DMSwarm are dynamic and can be re-sized at any time. 182662741f57SDave May The only restriction imposed by DMSwarm is that all fields contain the same number of points. 1827d3a51819SDave May 1828d3a51819SDave May To support particle methods, "migration" techniques are provided. These methods migrate data 18295627991aSBarry Smith between ranks. 1830d3a51819SDave May 1831d3a51819SDave May DMSwarm supports the methods DMCreateGlobalVector() and DMCreateLocalVector(). 1832d3a51819SDave May As a DMSwarm may internally define and store values of different data types, 183362741f57SDave May before calling DMCreateGlobalVector() or DMCreateLocalVector(), the user must inform DMSwarm which 1834d3a51819SDave May fields should be used to define a Vec object via 1835d3a51819SDave May DMSwarmVectorDefineField() 1836c215a47eSMatthew Knepley The specified field can be changed at any time - thereby permitting vectors 1837c215a47eSMatthew Knepley compatible with different fields to be created. 1838d3a51819SDave May 183962741f57SDave May A dual representation of fields in the DMSwarm and a Vec object is permitted via 1840d3a51819SDave May DMSwarmCreateGlobalVectorFromField() 1841d3a51819SDave May Here the data defining the field in the DMSwarm is shared with a Vec. 1842d3a51819SDave May This is inherently unsafe if you alter the size of the field at any time between 1843d3a51819SDave May calls to DMSwarmCreateGlobalVectorFromField() and DMSwarmDestroyGlobalVectorFromField(). 1844cc651181SDave May If the local size of the DMSwarm does not match the local size of the global vector 1845cc651181SDave May when DMSwarmDestroyGlobalVectorFromField() is called, an error is thrown. 1846d3a51819SDave May 184762741f57SDave May Additional high-level support is provided for Particle-In-Cell methods. 184862741f57SDave May Please refer to the man page for DMSwarmSetType(). 184962741f57SDave May 1850d3a51819SDave May Level: beginner 1851d3a51819SDave May 1852db781477SPatrick Sanan .seealso: `DMType`, `DMCreate()`, `DMSetType()` 1853d3a51819SDave May M*/ 185457795646SDave May PETSC_EXTERN PetscErrorCode DMCreate_Swarm(DM dm) 185557795646SDave May { 185657795646SDave May DM_Swarm *swarm; 185757795646SDave May 185857795646SDave May PetscFunctionBegin; 185957795646SDave May PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 18609566063dSJacob Faibussowitsch PetscCall(PetscNewLog(dm,&swarm)); 1861f0cdbbbaSDave May dm->data = swarm; 18629566063dSJacob Faibussowitsch PetscCall(DMSwarmDataBucketCreate(&swarm->db)); 18639566063dSJacob Faibussowitsch PetscCall(DMSwarmInitializeFieldRegister(dm)); 1864d0c080abSJoseph Pusztay swarm->refct = 1; 1865b5bcf523SDave May swarm->vec_field_set = PETSC_FALSE; 18663454631fSDave May swarm->issetup = PETSC_FALSE; 1867480eef7bSDave May swarm->swarm_type = DMSWARM_BASIC; 1868480eef7bSDave May swarm->migrate_type = DMSWARM_MIGRATE_BASIC; 1869480eef7bSDave May swarm->collect_type = DMSWARM_COLLECT_BASIC; 187040c453e9SDave May swarm->migrate_error_on_missing_point = PETSC_FALSE; 1871f0cdbbbaSDave May swarm->dmcell = NULL; 1872f0cdbbbaSDave May swarm->collect_view_active = PETSC_FALSE; 1873f0cdbbbaSDave May swarm->collect_view_reset_nlocal = -1; 18749566063dSJacob Faibussowitsch PetscCall(DMInitialize_Swarm(dm)); 1875*2e956fe4SStefano Zampini if (SwarmDataFieldId == -1) PetscCall(PetscObjectComposedDataRegister(&SwarmDataFieldId)); 187657795646SDave May PetscFunctionReturn(0); 187757795646SDave May } 1878