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> 8279f676cSBarry Smith #include "../src/dm/impls/swarm/data_bucket.h" 957795646SDave May 10f2b2bee7SDave May PetscLogEvent DMSWARM_Migrate, DMSWARM_SetSizes, DMSWARM_AddPoints, DMSWARM_RemovePoints, DMSWARM_Sort; 11ed923d71SDave May PetscLogEvent DMSWARM_DataExchangerTopologySetup, DMSWARM_DataExchangerBegin, DMSWARM_DataExchangerEnd; 12ed923d71SDave May PetscLogEvent DMSWARM_DataExchangerSendCount, DMSWARM_DataExchangerPack; 13ed923d71SDave May 14f0cdbbbaSDave May const char* DMSwarmTypeNames[] = { "basic", "pic", 0 }; 15f0cdbbbaSDave May const char* DMSwarmMigrateTypeNames[] = { "basic", "dmcellnscatter", "dmcellexact", "user", 0 }; 16f0cdbbbaSDave May const char* DMSwarmCollectTypeNames[] = { "basic", "boundingbox", "general", "user", 0 }; 17e2d107dbSDave May const char* DMSwarmPICLayoutTypeNames[] = { "regular", "gauss", "subdivision", 0 }; 18f0cdbbbaSDave May 19f0cdbbbaSDave May const char DMSwarmField_pid[] = "DMSwarm_pid"; 20f0cdbbbaSDave May const char DMSwarmField_rank[] = "DMSwarm_rank"; 21f0cdbbbaSDave May const char DMSwarmPICField_coor[] = "DMSwarmPIC_coor"; 22e2d107dbSDave May const char DMSwarmPICField_cellid[] = "DMSwarm_cellid"; 23f0cdbbbaSDave May 24d3a51819SDave May /*@C 2562741f57SDave May DMSwarmVectorDefineField - Sets the field from which to define a Vec object 2662741f57SDave May when DMCreateLocalVector(), or DMCreateGlobalVector() is called 2757795646SDave May 28d3a51819SDave May Collective on DM 2957795646SDave May 30d3a51819SDave May Input parameters: 3162741f57SDave May + dm - a DMSwarm 3262741f57SDave May - fieldname - the textual name given to a registered field 3357795646SDave May 34d3a51819SDave May Level: beginner 3557795646SDave May 36d3a51819SDave May Notes: 37e7af74c8SDave May 3862741f57SDave May The field with name fieldname must be defined as having a data type of PetscScalar. 39e7af74c8SDave May 40d3a51819SDave May This function must be called prior to calling DMCreateLocalVector(), DMCreateGlobalVector(). 41d3a51819SDave May Mutiple calls to DMSwarmVectorDefineField() are permitted. 4257795646SDave May 438b8a3813SDave May .seealso: DMSwarmRegisterPetscDatatypeField(), DMCreateGlobalVector(), DMCreateLocalVector() 44d3a51819SDave May @*/ 45b5bcf523SDave May PETSC_EXTERN PetscErrorCode DMSwarmVectorDefineField(DM dm,const char fieldname[]) 46b5bcf523SDave May { 47b5bcf523SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 48b5bcf523SDave May PetscErrorCode ierr; 49b5bcf523SDave May PetscInt bs,n; 50b5bcf523SDave May PetscScalar *array; 51b5bcf523SDave May PetscDataType type; 52b5bcf523SDave May 53a9cbaee5SMatthew G. Knepley PetscFunctionBegin; 543454631fSDave May if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); } 5577048351SPatrick Sanan ierr = DMSwarmDataBucketGetSizes(swarm->db,&n,NULL,NULL);CHKERRQ(ierr); 56b5bcf523SDave May ierr = DMSwarmGetField(dm,fieldname,&bs,&type,(void**)&array);CHKERRQ(ierr); 57b5bcf523SDave May 58b5bcf523SDave May /* Check all fields are of type PETSC_REAL or PETSC_SCALAR */ 59b5bcf523SDave May if (type != PETSC_REAL) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Only valid for PETSC_REAL"); 60521f74f9SMatthew G. Knepley ierr = PetscSNPrintf(swarm->vec_field_name,PETSC_MAX_PATH_LEN-1,"%s",fieldname);CHKERRQ(ierr); 61b5bcf523SDave May swarm->vec_field_set = PETSC_TRUE; 621b1ea282SDave May swarm->vec_field_bs = bs; 63b5bcf523SDave May swarm->vec_field_nlocal = n; 64dcf43ee8SDave May ierr = DMSwarmRestoreField(dm,fieldname,&bs,&type,(void**)&array);CHKERRQ(ierr); 65b5bcf523SDave May PetscFunctionReturn(0); 66b5bcf523SDave May } 67b5bcf523SDave May 68cc651181SDave May /* requires DMSwarmDefineFieldVector has been called */ 69b5bcf523SDave May PetscErrorCode DMCreateGlobalVector_Swarm(DM dm,Vec *vec) 70b5bcf523SDave May { 71b5bcf523SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 72b5bcf523SDave May PetscErrorCode ierr; 73b5bcf523SDave May Vec x; 74b5bcf523SDave May char name[PETSC_MAX_PATH_LEN]; 75b5bcf523SDave May 76a9cbaee5SMatthew G. Knepley PetscFunctionBegin; 773454631fSDave May if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); } 78b5bcf523SDave May if (!swarm->vec_field_set) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMSwarmVectorDefineField first"); 79cc651181SDave May if (swarm->vec_field_nlocal != swarm->db->L) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSwarm sizes have changed since last call to VectorDefineField first"); /* Stale data */ 80cc651181SDave May 81521f74f9SMatthew G. Knepley ierr = PetscSNPrintf(name,PETSC_MAX_PATH_LEN-1,"DMSwarmField_%s",swarm->vec_field_name);CHKERRQ(ierr); 82b5bcf523SDave May ierr = VecCreate(PetscObjectComm((PetscObject)dm),&x);CHKERRQ(ierr); 83b5bcf523SDave May ierr = PetscObjectSetName((PetscObject)x,name);CHKERRQ(ierr); 841b1ea282SDave May ierr = VecSetSizes(x,swarm->db->L*swarm->vec_field_bs,PETSC_DETERMINE);CHKERRQ(ierr); 85b5bcf523SDave May ierr = VecSetBlockSize(x,swarm->vec_field_bs);CHKERRQ(ierr); 86b5bcf523SDave May ierr = VecSetFromOptions(x);CHKERRQ(ierr); 87b5bcf523SDave May *vec = x; 88b5bcf523SDave May PetscFunctionReturn(0); 89b5bcf523SDave May } 90b5bcf523SDave May 91b5bcf523SDave May /* requires DMSwarmDefineFieldVector has been called */ 92b5bcf523SDave May PetscErrorCode DMCreateLocalVector_Swarm(DM dm,Vec *vec) 93b5bcf523SDave May { 94b5bcf523SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 95b5bcf523SDave May PetscErrorCode ierr; 96b5bcf523SDave May Vec x; 97b5bcf523SDave May char name[PETSC_MAX_PATH_LEN]; 98b5bcf523SDave May 99a9cbaee5SMatthew G. Knepley PetscFunctionBegin; 1003454631fSDave May if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); } 101b5bcf523SDave May if (!swarm->vec_field_set) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMSwarmVectorDefineField first"); 102cc651181SDave May if (swarm->vec_field_nlocal != swarm->db->L) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSwarm sizes have changed since last call to VectorDefineField first"); /* Stale data */ 103cc651181SDave May 104521f74f9SMatthew G. Knepley ierr = PetscSNPrintf(name,PETSC_MAX_PATH_LEN-1,"DMSwarmField_%s",swarm->vec_field_name);CHKERRQ(ierr); 105b5bcf523SDave May ierr = VecCreate(PETSC_COMM_SELF,&x);CHKERRQ(ierr); 106b5bcf523SDave May ierr = PetscObjectSetName((PetscObject)x,name);CHKERRQ(ierr); 107071900c8SMatthew G. Knepley ierr = VecSetSizes(x,swarm->db->L*swarm->vec_field_bs,PETSC_DETERMINE);CHKERRQ(ierr); 108b5bcf523SDave May ierr = VecSetBlockSize(x,swarm->vec_field_bs);CHKERRQ(ierr); 109b5bcf523SDave May ierr = VecSetFromOptions(x);CHKERRQ(ierr); 110b5bcf523SDave May *vec = x; 111b5bcf523SDave May PetscFunctionReturn(0); 112b5bcf523SDave May } 113b5bcf523SDave May 114fb1bcc12SMatthew G. Knepley static PetscErrorCode DMSwarmDestroyVectorFromField_Private(DM dm, const char fieldname[], Vec *vec) 115fb1bcc12SMatthew G. Knepley { 116fb1bcc12SMatthew G. Knepley DM_Swarm *swarm = (DM_Swarm *) dm->data; 11777048351SPatrick Sanan DMSwarmDataField gfield; 118fb1bcc12SMatthew G. Knepley void (*fptr)(void); 119fb1bcc12SMatthew G. Knepley PetscInt bs, nlocal; 120fb1bcc12SMatthew G. Knepley char name[PETSC_MAX_PATH_LEN]; 121fb1bcc12SMatthew G. Knepley PetscErrorCode ierr; 122d3a51819SDave May 123fb1bcc12SMatthew G. Knepley PetscFunctionBegin; 124fb1bcc12SMatthew G. Knepley ierr = VecGetLocalSize(*vec, &nlocal);CHKERRQ(ierr); 125fb1bcc12SMatthew G. Knepley ierr = VecGetBlockSize(*vec, &bs);CHKERRQ(ierr); 126fb1bcc12SMatthew G. Knepley if (nlocal/bs != swarm->db->L) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSwarm sizes have changed since vector was created - cannot ensure pointers are valid"); /* Stale data */ 12777048351SPatrick Sanan ierr = DMSwarmDataBucketGetDMSwarmDataFieldByName(swarm->db, fieldname, &gfield);CHKERRQ(ierr); 128fb1bcc12SMatthew G. Knepley /* check vector is an inplace array */ 129521f74f9SMatthew G. Knepley ierr = PetscSNPrintf(name, PETSC_MAX_PATH_LEN-1, "DMSwarm_VecFieldInPlace_%s", fieldname);CHKERRQ(ierr); 130fb1bcc12SMatthew G. Knepley ierr = PetscObjectQueryFunction((PetscObject) *vec, name, &fptr);CHKERRQ(ierr); 131fb1bcc12SMatthew G. Knepley if (!fptr) SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_USER, "Vector being destroyed was not created from DMSwarm field(%s)", fieldname); 13277048351SPatrick Sanan ierr = DMSwarmDataFieldRestoreAccess(gfield);CHKERRQ(ierr); 133fb1bcc12SMatthew G. Knepley ierr = VecDestroy(vec);CHKERRQ(ierr); 134fb1bcc12SMatthew G. Knepley PetscFunctionReturn(0); 135fb1bcc12SMatthew G. Knepley } 136fb1bcc12SMatthew G. Knepley 137fb1bcc12SMatthew G. Knepley static PetscErrorCode DMSwarmCreateVectorFromField_Private(DM dm, const char fieldname[], MPI_Comm comm, Vec *vec) 138fb1bcc12SMatthew G. Knepley { 139fb1bcc12SMatthew G. Knepley DM_Swarm *swarm = (DM_Swarm *) dm->data; 140fb1bcc12SMatthew G. Knepley PetscDataType type; 141fb1bcc12SMatthew G. Knepley PetscScalar *array; 142fb1bcc12SMatthew G. Knepley PetscInt bs, n; 143fb1bcc12SMatthew G. Knepley char name[PETSC_MAX_PATH_LEN]; 144e4fbd051SBarry Smith PetscMPIInt size; 145fb1bcc12SMatthew G. Knepley PetscErrorCode ierr; 146fb1bcc12SMatthew G. Knepley 147fb1bcc12SMatthew G. Knepley PetscFunctionBegin; 148fb1bcc12SMatthew G. Knepley if (!swarm->issetup) {ierr = DMSetUp(dm);CHKERRQ(ierr);} 14977048351SPatrick Sanan ierr = DMSwarmDataBucketGetSizes(swarm->db, &n, NULL, NULL);CHKERRQ(ierr); 150fb1bcc12SMatthew G. Knepley ierr = DMSwarmGetField(dm, fieldname, &bs, &type, (void **) &array);CHKERRQ(ierr); 151fb1bcc12SMatthew G. Knepley if (type != PETSC_REAL) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Only valid for PETSC_REAL"); 152fb1bcc12SMatthew G. Knepley 153e4fbd051SBarry Smith ierr = MPI_Comm_size(comm, &size);CHKERRQ(ierr); 154e4fbd051SBarry Smith if (size == 1) { 155fb1bcc12SMatthew G. Knepley ierr = VecCreateSeqWithArray(comm, bs, n*bs, array, vec);CHKERRQ(ierr); 156fb1bcc12SMatthew G. Knepley } else { 157fb1bcc12SMatthew G. Knepley ierr = VecCreateMPIWithArray(comm, bs, n*bs, PETSC_DETERMINE, array, vec);CHKERRQ(ierr); 158fb1bcc12SMatthew G. Knepley } 159fb1bcc12SMatthew G. Knepley ierr = PetscSNPrintf(name, PETSC_MAX_PATH_LEN-1, "DMSwarmSharedField_%s", fieldname);CHKERRQ(ierr); 160fb1bcc12SMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) *vec, name);CHKERRQ(ierr); 161fb1bcc12SMatthew G. Knepley 162fb1bcc12SMatthew G. Knepley /* Set guard */ 163fb1bcc12SMatthew G. Knepley ierr = PetscSNPrintf(name, PETSC_MAX_PATH_LEN-1, "DMSwarm_VecFieldInPlace_%s", fieldname);CHKERRQ(ierr); 164fb1bcc12SMatthew G. Knepley ierr = PetscObjectComposeFunction((PetscObject) *vec, name, DMSwarmDestroyVectorFromField_Private);CHKERRQ(ierr); 165fb1bcc12SMatthew G. Knepley PetscFunctionReturn(0); 166fb1bcc12SMatthew G. Knepley } 167fb1bcc12SMatthew G. Knepley 1680643ed39SMatthew G. Knepley /* This creates a "mass matrix" between a finite element and particle space. If a finite element interpolant is given by 1690643ed39SMatthew G. Knepley 1700643ed39SMatthew G. Knepley \hat f = \sum_i f_i \phi_i 1710643ed39SMatthew G. Knepley 1720643ed39SMatthew G. Knepley and a particle function is given by 1730643ed39SMatthew G. Knepley 1740643ed39SMatthew G. Knepley f = \sum_i w_i \delta(x - x_i) 1750643ed39SMatthew G. Knepley 1760643ed39SMatthew G. Knepley then we want to require that 1770643ed39SMatthew G. Knepley 1780643ed39SMatthew G. Knepley M \hat f = M_p f 1790643ed39SMatthew G. Knepley 1800643ed39SMatthew G. Knepley where the particle mass matrix is given by 1810643ed39SMatthew G. Knepley 1820643ed39SMatthew G. Knepley (M_p)_{ij} = \int \phi_i \delta(x - x_j) 1830643ed39SMatthew G. Knepley 1840643ed39SMatthew G. Knepley The way Dave May does particles, they amount to quadratue weights rather than delta functions, so he has |J| is in 1850643ed39SMatthew G. Knepley his integral. We allow this with the boolean flag. 1860643ed39SMatthew G. Knepley */ 1870643ed39SMatthew G. Knepley static PetscErrorCode DMSwarmComputeMassMatrix_Private(DM dmc, DM dmf, Mat mass, PetscBool useDeltaFunction, void *ctx) 18883c47955SMatthew G. Knepley { 18983c47955SMatthew G. Knepley const char *name = "Mass Matrix"; 1900643ed39SMatthew G. Knepley MPI_Comm comm; 19183c47955SMatthew G. Knepley PetscDS prob; 19283c47955SMatthew G. Knepley PetscSection fsection, globalFSection; 193e8f14785SLisandro Dalcin PetscHSetIJ ht; 1940643ed39SMatthew G. Knepley PetscLayout rLayout, colLayout; 19583c47955SMatthew G. Knepley PetscInt *dnz, *onz; 196*adb2528bSMark Adams PetscInt locRows, locCols, rStart, colStart, colEnd, *rowIDXs; 1970643ed39SMatthew G. Knepley PetscReal *xi, *v0, *J, *invJ, detJ = 1.0, v0ref[3] = {-1.0, -1.0, -1.0}; 19883c47955SMatthew G. Knepley PetscScalar *elemMat; 1990643ed39SMatthew G. Knepley PetscInt dim, Nf, field, cStart, cEnd, cell, totDim, maxC = 0; 20083c47955SMatthew G. Knepley PetscErrorCode ierr; 20183c47955SMatthew G. Knepley 20283c47955SMatthew G. Knepley PetscFunctionBegin; 2030643ed39SMatthew G. Knepley ierr = PetscObjectGetComm((PetscObject) mass, &comm);CHKERRQ(ierr); 20483c47955SMatthew G. Knepley ierr = DMGetCoordinateDim(dmf, &dim);CHKERRQ(ierr); 20583c47955SMatthew G. Knepley ierr = DMGetDS(dmf, &prob);CHKERRQ(ierr); 20683c47955SMatthew G. Knepley ierr = PetscDSGetNumFields(prob, &Nf);CHKERRQ(ierr); 2070643ed39SMatthew G. Knepley ierr = PetscDSGetTotalDimension(prob, &totDim);CHKERRQ(ierr); 20883c47955SMatthew G. Knepley ierr = PetscMalloc3(dim, &v0, dim*dim, &J, dim*dim,&invJ);CHKERRQ(ierr); 20983c47955SMatthew G. Knepley ierr = DMGetDefaultSection(dmf, &fsection);CHKERRQ(ierr); 21083c47955SMatthew G. Knepley ierr = DMGetDefaultGlobalSection(dmf, &globalFSection);CHKERRQ(ierr); 21183c47955SMatthew G. Knepley ierr = DMPlexGetHeightStratum(dmf, 0, &cStart, &cEnd);CHKERRQ(ierr); 2120643ed39SMatthew G. Knepley ierr = MatGetLocalSize(mass, &locRows, &locCols);CHKERRQ(ierr); 21383c47955SMatthew G. Knepley 2140643ed39SMatthew G. Knepley ierr = PetscLayoutCreate(comm, &colLayout);CHKERRQ(ierr); 2150643ed39SMatthew G. Knepley ierr = PetscLayoutSetLocalSize(colLayout, locCols);CHKERRQ(ierr); 2160643ed39SMatthew G. Knepley ierr = PetscLayoutSetBlockSize(colLayout, 1);CHKERRQ(ierr); 2170643ed39SMatthew G. Knepley ierr = PetscLayoutSetUp(colLayout);CHKERRQ(ierr); 2180643ed39SMatthew G. Knepley ierr = PetscLayoutGetRange(colLayout, &colStart, &colEnd);CHKERRQ(ierr); 2190643ed39SMatthew G. Knepley ierr = PetscLayoutDestroy(&colLayout);CHKERRQ(ierr); 2200643ed39SMatthew G. Knepley 2210643ed39SMatthew G. Knepley ierr = PetscLayoutCreate(comm, &rLayout);CHKERRQ(ierr); 22283c47955SMatthew G. Knepley ierr = PetscLayoutSetLocalSize(rLayout, locRows);CHKERRQ(ierr); 22383c47955SMatthew G. Knepley ierr = PetscLayoutSetBlockSize(rLayout, 1);CHKERRQ(ierr); 22483c47955SMatthew G. Knepley ierr = PetscLayoutSetUp(rLayout);CHKERRQ(ierr); 2250643ed39SMatthew G. Knepley ierr = PetscLayoutGetRange(rLayout, &rStart, NULL);CHKERRQ(ierr); 22683c47955SMatthew G. Knepley ierr = PetscLayoutDestroy(&rLayout);CHKERRQ(ierr); 2270643ed39SMatthew G. Knepley 22883c47955SMatthew G. Knepley ierr = PetscCalloc2(locRows, &dnz, locRows, &onz);CHKERRQ(ierr); 229e8f14785SLisandro Dalcin ierr = PetscHSetIJCreate(&ht);CHKERRQ(ierr); 230*adb2528bSMark Adams /* ierr = PetscSynchronizedPrintf(comm, "DMSwarmComputeMassMatrix_Private: rStart = %D rEnd = %D colStart = %D colEnd = %D\n", rStart, rStart+locRows, colStart, colEnd);CHKERRQ(ierr); */ 2310643ed39SMatthew G. Knepley ierr = PetscSynchronizedFlush(comm, NULL);CHKERRQ(ierr); 2320643ed39SMatthew G. Knepley /* count non-zeros */ 2330643ed39SMatthew G. Knepley ierr = DMSwarmSortGetAccess(dmc);CHKERRQ(ierr); 23483c47955SMatthew G. Knepley for (field = 0; field < Nf; ++field) { 23583c47955SMatthew G. Knepley for (cell = cStart; cell < cEnd; ++cell) { 2360643ed39SMatthew G. Knepley PetscInt c, i; 2370643ed39SMatthew G. Knepley PetscInt *findices, *cindices; /* fine is vertices, coarse is particles */ 23883c47955SMatthew G. Knepley PetscInt numFIndices, numCIndices; 23983c47955SMatthew G. Knepley 24083c47955SMatthew G. Knepley ierr = DMPlexGetClosureIndices(dmf, fsection, globalFSection, cell, &numFIndices, &findices, NULL);CHKERRQ(ierr); 241fc7c92abSMatthew G. Knepley ierr = DMSwarmSortGetPointsPerCell(dmc, cell, &numCIndices, &cindices);CHKERRQ(ierr); 242fc7c92abSMatthew G. Knepley maxC = PetscMax(maxC, numCIndices); 24383c47955SMatthew G. Knepley { 244e8f14785SLisandro Dalcin PetscHashIJKey key; 245e8f14785SLisandro Dalcin PetscBool missing; 2460643ed39SMatthew G. Knepley /* PetscPrintf(PETSC_COMM_SELF, "\t[%D]DMSwarmComputeMassMatrix_Private: cell %D\n",rank,cell); */ 24783c47955SMatthew G. Knepley for (i = 0; i < numFIndices; ++i) { 248*adb2528bSMark Adams key.j = findices[i]; /* global column (from Plex) */ 2490643ed39SMatthew G. Knepley /* PetscPrintf(PETSC_COMM_SELF, "\t\t[%D]DMSwarmComputeMassMatrix_Private: j ('fine',vertices) = %D, num rows ('coarse',particles) = %D\n",rank,key.i,numCIndices); */ 250*adb2528bSMark Adams if (key.j >= 0) { 25183c47955SMatthew G. Knepley /* Get indices for coarse elements */ 25283c47955SMatthew G. Knepley for (c = 0; c < numCIndices; ++c) { 253*adb2528bSMark Adams key.i = cindices[c] + rStart; /* global cols (from Swarm) */ 254*adb2528bSMark Adams if (key.i < 0) continue; 255e8f14785SLisandro Dalcin ierr = PetscHSetIJQueryAdd(ht, key, &missing);CHKERRQ(ierr); 25683c47955SMatthew G. Knepley if (missing) { 257*adb2528bSMark Adams /* PetscPrintf(PETSC_COMM_SELF, "\t\t\t[%D]DMSwarmComputeMassMatrix_Private: new key j (row,particle) = %D, i (col,vertices) = %D\n",-1,key.j,key.i); */ 2580643ed39SMatthew G. Knepley if ((key.j >= colStart) && (key.j < colEnd)) ++dnz[key.i - rStart]; 259e8f14785SLisandro Dalcin else ++onz[key.i - rStart]; 2600643ed39SMatthew G. Knepley } else SETERRQ2(PetscObjectComm((PetscObject) dmf), PETSC_ERR_SUP, "Set new value at %D,%D", key.i, key.j); 26183c47955SMatthew G. Knepley } 262fc7c92abSMatthew G. Knepley } 263fc7c92abSMatthew G. Knepley } 26483c47955SMatthew G. Knepley ierr = PetscFree(cindices);CHKERRQ(ierr); 26583c47955SMatthew G. Knepley } 26683c47955SMatthew G. Knepley ierr = DMPlexRestoreClosureIndices(dmf, fsection, globalFSection, cell, &numFIndices, &findices, NULL);CHKERRQ(ierr); 26783c47955SMatthew G. Knepley } 26883c47955SMatthew G. Knepley } 269e8f14785SLisandro Dalcin ierr = PetscHSetIJDestroy(&ht);CHKERRQ(ierr); 27083c47955SMatthew G. Knepley ierr = MatXAIJSetPreallocation(mass, 1, dnz, onz, NULL, NULL);CHKERRQ(ierr); 27183c47955SMatthew G. Knepley ierr = MatSetOption(mass, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_TRUE);CHKERRQ(ierr); 27283c47955SMatthew G. Knepley ierr = PetscFree2(dnz, onz);CHKERRQ(ierr); 273*adb2528bSMark Adams ierr = PetscMalloc3(maxC*totDim, &elemMat, maxC, &rowIDXs, maxC*dim, &xi);CHKERRQ(ierr); 27483c47955SMatthew G. Knepley for (field = 0; field < Nf; ++field) { 27583c47955SMatthew G. Knepley PetscObject obj; 2760643ed39SMatthew G. Knepley PetscReal *Bcoarse, *coords; 2770643ed39SMatthew G. Knepley PetscInt Nc, i; 27883c47955SMatthew G. Knepley 27983c47955SMatthew G. Knepley ierr = PetscDSGetDiscretization(prob, field, &obj);CHKERRQ(ierr); 2800643ed39SMatthew G. Knepley ierr = PetscFEGetNumComponents((PetscFE) obj, &Nc);CHKERRQ(ierr); 2810643ed39SMatthew G. Knepley if (Nc != 1) SETERRQ1(PetscObjectComm((PetscObject) dmf), PETSC_ERR_SUP, "Can only interpolate a scalar field from particles, Nc = %D", Nc); 2820643ed39SMatthew G. Knepley ierr = DMSwarmGetField(dmc, DMSwarmPICField_coor, NULL, NULL, (void **) &coords);CHKERRQ(ierr); 28383c47955SMatthew G. Knepley for (cell = cStart; cell < cEnd; ++cell) { 28483c47955SMatthew G. Knepley PetscInt *findices , *cindices; 28583c47955SMatthew G. Knepley PetscInt numFIndices, numCIndices; 2860643ed39SMatthew G. Knepley PetscInt p, c; 28783c47955SMatthew G. Knepley 2880643ed39SMatthew G. Knepley /* TODO: Use DMField instead of assuming affine */ 28983c47955SMatthew G. Knepley ierr = DMPlexComputeCellGeometryFEM(dmf, cell, NULL, v0, J, invJ, &detJ);CHKERRQ(ierr); 29083c47955SMatthew G. Knepley ierr = DMPlexGetClosureIndices(dmf, fsection, globalFSection, cell, &numFIndices, &findices, NULL);CHKERRQ(ierr); 29183c47955SMatthew G. Knepley ierr = DMSwarmSortGetPointsPerCell(dmc, cell, &numCIndices, &cindices);CHKERRQ(ierr); 2920643ed39SMatthew G. Knepley for (p = 0; p < numCIndices; ++p) { 2930643ed39SMatthew G. Knepley CoordinatesRealToRef(dim, dim, v0ref, v0, invJ, &coords[cindices[p]*dim], &xi[p*dim]); 294b30fe131SMark Adams /* PetscPrintf(PETSC_COMM_SELF,"[%D]DMSwarmComputeMassMatrix_Private: %2D.%D) coord[%D] = (%12.5e, %12.5e) element coord = (%12.5e, %12.5e) cindices[%D]=%D detJ=%12.5e\n",-1,cell,p,cindices[p]*dim,coords[cindices[p]*dim],coords[cindices[p]*dim+1],xi[p*dim],xi[p*dim+1],p,cindices[p],detJ); */ 2950643ed39SMatthew G. Knepley } 2960643ed39SMatthew G. Knepley ierr = PetscFEGetTabulation((PetscFE) obj, numCIndices, xi, &Bcoarse, NULL, NULL);CHKERRQ(ierr); 29783c47955SMatthew G. Knepley /* Get elemMat entries by multiplying by weight */ 2980643ed39SMatthew G. Knepley ierr = PetscMemzero(elemMat, numCIndices*totDim * sizeof(PetscScalar));CHKERRQ(ierr); 29983c47955SMatthew G. Knepley for (i = 0; i < numFIndices; ++i) { 3000643ed39SMatthew G. Knepley for (p = 0; p < numCIndices; ++p) { 3010643ed39SMatthew G. Knepley for (c = 0; c < Nc; ++c) { 3020643ed39SMatthew G. Knepley /* B[(p*pdim + i)*Nc + c] is the value at point p for basis function i and component c */ 303*adb2528bSMark Adams elemMat[p*numFIndices+i] += Bcoarse[(p*numFIndices + i)*Nc + c]*(useDeltaFunction ? 1.0 : detJ); 3040643ed39SMatthew G. Knepley /* PetscPrintf(PETSC_COMM_SELF, "\t[%D]DMSwarmComputeMassMatrix_Private: %2D) findices[%D] (col) %D, particle (row) %D (nc=%D) Bcoarse[%2D]=%12.5e\n",rank,cell,i,findices[i],cindices[p],c,(p*numFIndices + i)*Nc + c,Bcoarse[(p*numFIndices + i)*Nc + c]); */ 30583c47955SMatthew G. Knepley } 3060643ed39SMatthew G. Knepley } 3070643ed39SMatthew G. Knepley } 308*adb2528bSMark Adams for (p = 0; p < numCIndices; ++p) rowIDXs[p] = cindices[p] + rStart; 30983c47955SMatthew G. Knepley if (0) {ierr = DMPrintCellMatrix(cell, name, 1, numCIndices, elemMat);CHKERRQ(ierr);} 310*adb2528bSMark Adams ierr = MatSetValues(mass, numCIndices, rowIDXs, numFIndices, findices, elemMat, ADD_VALUES);CHKERRQ(ierr); 31183c47955SMatthew G. Knepley ierr = PetscFree(cindices);CHKERRQ(ierr); 31283c47955SMatthew G. Knepley ierr = DMPlexRestoreClosureIndices(dmf, fsection, globalFSection, cell, &numFIndices, &findices, NULL);CHKERRQ(ierr); 3130643ed39SMatthew G. Knepley ierr = PetscFERestoreTabulation((PetscFE) obj, numCIndices, xi, &Bcoarse, NULL, NULL);CHKERRQ(ierr); 31483c47955SMatthew G. Knepley } 3150643ed39SMatthew G. Knepley ierr = DMSwarmRestoreField(dmc, DMSwarmPICField_coor, NULL, NULL, (void **) &coords);CHKERRQ(ierr); 31683c47955SMatthew G. Knepley } 317*adb2528bSMark Adams ierr = PetscFree3(elemMat, rowIDXs, xi);CHKERRQ(ierr); 31883c47955SMatthew G. Knepley ierr = DMSwarmSortRestoreAccess(dmc);CHKERRQ(ierr); 31983c47955SMatthew G. Knepley ierr = PetscFree3(v0, J, invJ);CHKERRQ(ierr); 32083c47955SMatthew G. Knepley ierr = MatAssemblyBegin(mass, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 32183c47955SMatthew G. Knepley ierr = MatAssemblyEnd(mass, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 32283c47955SMatthew G. Knepley PetscFunctionReturn(0); 32383c47955SMatthew G. Knepley } 32483c47955SMatthew G. Knepley 325*adb2528bSMark Adams /* FEM cols, Particle rows */ 32683c47955SMatthew G. Knepley static PetscErrorCode DMCreateMassMatrix_Swarm(DM dmCoarse, DM dmFine, Mat *mass) 32783c47955SMatthew G. Knepley { 328895a1698SMatthew G. Knepley PetscSection gsf; 32983c47955SMatthew G. Knepley PetscInt m, n; 33083c47955SMatthew G. Knepley void *ctx; 33183c47955SMatthew G. Knepley PetscErrorCode ierr; 33283c47955SMatthew G. Knepley 33383c47955SMatthew G. Knepley PetscFunctionBegin; 33483c47955SMatthew G. Knepley ierr = DMGetDefaultGlobalSection(dmFine, &gsf);CHKERRQ(ierr); 33583c47955SMatthew G. Knepley ierr = PetscSectionGetConstrainedStorageSize(gsf, &m);CHKERRQ(ierr); 336895a1698SMatthew G. Knepley ierr = DMSwarmGetLocalSize(dmCoarse, &n);CHKERRQ(ierr); 33783c47955SMatthew G. Knepley ierr = MatCreate(PetscObjectComm((PetscObject) dmCoarse), mass);CHKERRQ(ierr); 338*adb2528bSMark Adams ierr = MatSetSizes(*mass, n, m, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 33983c47955SMatthew G. Knepley ierr = MatSetType(*mass, dmCoarse->mattype);CHKERRQ(ierr); 34083c47955SMatthew G. Knepley ierr = DMGetApplicationContext(dmFine, &ctx);CHKERRQ(ierr); 34183c47955SMatthew G. Knepley 3420643ed39SMatthew G. Knepley ierr = DMSwarmComputeMassMatrix_Private(dmCoarse, dmFine, *mass, PETSC_TRUE, ctx);CHKERRQ(ierr); 34383c47955SMatthew G. Knepley ierr = MatViewFromOptions(*mass, NULL, "-mass_mat_view");CHKERRQ(ierr); 34483c47955SMatthew G. Knepley PetscFunctionReturn(0); 34583c47955SMatthew G. Knepley } 34683c47955SMatthew G. Knepley 347fb1bcc12SMatthew G. Knepley /*@C 348d3a51819SDave May DMSwarmCreateGlobalVectorFromField - Creates a Vec object sharing the array associated with a given field 349d3a51819SDave May 350d3a51819SDave May Collective on DM 351d3a51819SDave May 352d3a51819SDave May Input parameters: 35362741f57SDave May + dm - a DMSwarm 35462741f57SDave May - fieldname - the textual name given to a registered field 355d3a51819SDave May 3568b8a3813SDave May Output parameter: 357d3a51819SDave May . vec - the vector 358d3a51819SDave May 359d3a51819SDave May Level: beginner 360d3a51819SDave May 3618b8a3813SDave May Notes: 3628b8a3813SDave May The vector must be returned using a matching call to DMSwarmDestroyGlobalVectorFromField(). 3638b8a3813SDave May 3648b8a3813SDave May .seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmDestroyGlobalVectorFromField() 365d3a51819SDave May @*/ 366b5bcf523SDave May PETSC_EXTERN PetscErrorCode DMSwarmCreateGlobalVectorFromField(DM dm,const char fieldname[],Vec *vec) 367b5bcf523SDave May { 368fb1bcc12SMatthew G. Knepley MPI_Comm comm = PetscObjectComm((PetscObject) dm); 369b5bcf523SDave May PetscErrorCode ierr; 370b5bcf523SDave May 371fb1bcc12SMatthew G. Knepley PetscFunctionBegin; 372fb1bcc12SMatthew G. Knepley ierr = DMSwarmCreateVectorFromField_Private(dm, fieldname, comm, vec);CHKERRQ(ierr); 373b5bcf523SDave May PetscFunctionReturn(0); 374b5bcf523SDave May } 375b5bcf523SDave May 376d3a51819SDave May /*@C 377d3a51819SDave May DMSwarmDestroyGlobalVectorFromField - Destroys the Vec object which share the array associated with a given field 378d3a51819SDave May 379d3a51819SDave May Collective on DM 380d3a51819SDave May 381d3a51819SDave May Input parameters: 38262741f57SDave May + dm - a DMSwarm 38362741f57SDave May - fieldname - the textual name given to a registered field 384d3a51819SDave May 3858b8a3813SDave May Output parameter: 386d3a51819SDave May . vec - the vector 387d3a51819SDave May 388d3a51819SDave May Level: beginner 389d3a51819SDave May 3908b8a3813SDave May .seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmCreateGlobalVectorFromField() 391d3a51819SDave May @*/ 392b5bcf523SDave May PETSC_EXTERN PetscErrorCode DMSwarmDestroyGlobalVectorFromField(DM dm,const char fieldname[],Vec *vec) 393b5bcf523SDave May { 394b5bcf523SDave May PetscErrorCode ierr; 395cc651181SDave May 396fb1bcc12SMatthew G. Knepley PetscFunctionBegin; 397fb1bcc12SMatthew G. Knepley ierr = DMSwarmDestroyVectorFromField_Private(dm, fieldname, vec);CHKERRQ(ierr); 398b5bcf523SDave May PetscFunctionReturn(0); 399b5bcf523SDave May } 400b5bcf523SDave May 401fb1bcc12SMatthew G. Knepley /*@C 402fb1bcc12SMatthew G. Knepley DMSwarmCreateLocalVectorFromField - Creates a Vec object sharing the array associated with a given field 403fb1bcc12SMatthew G. Knepley 404fb1bcc12SMatthew G. Knepley Collective on DM 405fb1bcc12SMatthew G. Knepley 406fb1bcc12SMatthew G. Knepley Input parameters: 40762741f57SDave May + dm - a DMSwarm 40862741f57SDave May - fieldname - the textual name given to a registered field 409fb1bcc12SMatthew G. Knepley 4108b8a3813SDave May Output parameter: 411fb1bcc12SMatthew G. Knepley . vec - the vector 412fb1bcc12SMatthew G. Knepley 413fb1bcc12SMatthew G. Knepley Level: beginner 414fb1bcc12SMatthew G. Knepley 4158b8a3813SDave May Notes: 4168b8a3813SDave May The vector must be returned using a matching call to DMSwarmDestroyLocalVectorFromField(). 4178b8a3813SDave May 4188b8a3813SDave May .seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmDestroyLocalVectorFromField() 419fb1bcc12SMatthew G. Knepley @*/ 420fb1bcc12SMatthew G. Knepley PETSC_EXTERN PetscErrorCode DMSwarmCreateLocalVectorFromField(DM dm,const char fieldname[],Vec *vec) 421bbe8250bSMatthew G. Knepley { 422fb1bcc12SMatthew G. Knepley MPI_Comm comm = PETSC_COMM_SELF; 423bbe8250bSMatthew G. Knepley PetscErrorCode ierr; 424bbe8250bSMatthew G. Knepley 425fb1bcc12SMatthew G. Knepley PetscFunctionBegin; 426fb1bcc12SMatthew G. Knepley ierr = DMSwarmCreateVectorFromField_Private(dm, fieldname, comm, vec);CHKERRQ(ierr); 427fb1bcc12SMatthew G. Knepley PetscFunctionReturn(0); 428bbe8250bSMatthew G. Knepley } 429fb1bcc12SMatthew G. Knepley 430fb1bcc12SMatthew G. Knepley /*@C 431fb1bcc12SMatthew G. Knepley DMSwarmDestroyLocalVectorFromField - Destroys the Vec object which share the array associated with a given field 432fb1bcc12SMatthew G. Knepley 433fb1bcc12SMatthew G. Knepley Collective on DM 434fb1bcc12SMatthew G. Knepley 435fb1bcc12SMatthew G. Knepley Input parameters: 43662741f57SDave May + dm - a DMSwarm 43762741f57SDave May - fieldname - the textual name given to a registered field 438fb1bcc12SMatthew G. Knepley 4398b8a3813SDave May Output parameter: 440fb1bcc12SMatthew G. Knepley . vec - the vector 441fb1bcc12SMatthew G. Knepley 442fb1bcc12SMatthew G. Knepley Level: beginner 443fb1bcc12SMatthew G. Knepley 4448b8a3813SDave May .seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmCreateLocalVectorFromField() 445fb1bcc12SMatthew G. Knepley @*/ 446fb1bcc12SMatthew G. Knepley PETSC_EXTERN PetscErrorCode DMSwarmDestroyLocalVectorFromField(DM dm,const char fieldname[],Vec *vec) 447fb1bcc12SMatthew G. Knepley { 448fb1bcc12SMatthew G. Knepley PetscErrorCode ierr; 449fb1bcc12SMatthew G. Knepley 450fb1bcc12SMatthew G. Knepley PetscFunctionBegin; 451fb1bcc12SMatthew G. Knepley ierr = DMSwarmDestroyVectorFromField_Private(dm, fieldname, vec);CHKERRQ(ierr); 452bbe8250bSMatthew G. Knepley PetscFunctionReturn(0); 453bbe8250bSMatthew G. Knepley } 454bbe8250bSMatthew G. Knepley 455b5bcf523SDave May /* 456b5bcf523SDave May PETSC_EXTERN PetscErrorCode DMSwarmCreateGlobalVectorFromFields(DM dm,const PetscInt nf,const char *fieldnames[],Vec *vec) 457b5bcf523SDave May { 458b5bcf523SDave May PetscFunctionReturn(0); 459b5bcf523SDave May } 460b5bcf523SDave May 461b5bcf523SDave May PETSC_EXTERN PetscErrorCode DMSwarmRestoreGlobalVectorFromFields(DM dm,Vec *vec) 462b5bcf523SDave May { 463b5bcf523SDave May PetscFunctionReturn(0); 464b5bcf523SDave May } 465b5bcf523SDave May */ 466b5bcf523SDave May 467d3a51819SDave May /*@C 468d3a51819SDave May DMSwarmInitializeFieldRegister - Initiates the registration of fields to a DMSwarm 469d3a51819SDave May 470d3a51819SDave May Collective on DM 471d3a51819SDave May 472d3a51819SDave May Input parameter: 473d3a51819SDave May . dm - a DMSwarm 474d3a51819SDave May 475d3a51819SDave May Level: beginner 476d3a51819SDave May 477d3a51819SDave May Notes: 4788b8a3813SDave May After all fields have been registered, you must call DMSwarmFinalizeFieldRegister(). 479d3a51819SDave May 480d3a51819SDave May .seealso: DMSwarmFinalizeFieldRegister(), DMSwarmRegisterPetscDatatypeField(), 481d3a51819SDave May DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField() 482d3a51819SDave May @*/ 4835f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmInitializeFieldRegister(DM dm) 4845f50eb2eSDave May { 4855f50eb2eSDave May DM_Swarm *swarm = (DM_Swarm *) dm->data; 4863454631fSDave May PetscErrorCode ierr; 4873454631fSDave May 488521f74f9SMatthew G. Knepley PetscFunctionBegin; 489cc651181SDave May if (!swarm->field_registration_initialized) { 4905f50eb2eSDave May swarm->field_registration_initialized = PETSC_TRUE; 491f0cdbbbaSDave May ierr = DMSwarmRegisterPetscDatatypeField(dm,DMSwarmField_pid,1,PETSC_LONG);CHKERRQ(ierr); /* unique identifer */ 492f0cdbbbaSDave May ierr = DMSwarmRegisterPetscDatatypeField(dm,DMSwarmField_rank,1,PETSC_INT);CHKERRQ(ierr); /* used for communication */ 493cc651181SDave May } 4945f50eb2eSDave May PetscFunctionReturn(0); 4955f50eb2eSDave May } 4965f50eb2eSDave May 497d3a51819SDave May /*@C 498d3a51819SDave May DMSwarmFinalizeFieldRegister - Finalizes the registration of fields to a DMSwarm 499d3a51819SDave May 500d3a51819SDave May Collective on DM 501d3a51819SDave May 502d3a51819SDave May Input parameter: 503d3a51819SDave May . dm - a DMSwarm 504d3a51819SDave May 505d3a51819SDave May Level: beginner 506d3a51819SDave May 507d3a51819SDave May Notes: 50862741f57SDave May After DMSwarmFinalizeFieldRegister() has been called, no new fields can be defined on the DMSwarm. 509d3a51819SDave May 510d3a51819SDave May .seealso: DMSwarmInitializeFieldRegister(), DMSwarmRegisterPetscDatatypeField(), 511d3a51819SDave May DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField() 512d3a51819SDave May @*/ 5135f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmFinalizeFieldRegister(DM dm) 5145f50eb2eSDave May { 5155f50eb2eSDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 5166845f8f5SDave May PetscErrorCode ierr; 5176845f8f5SDave May 518521f74f9SMatthew G. Knepley PetscFunctionBegin; 519f0cdbbbaSDave May if (!swarm->field_registration_finalized) { 52077048351SPatrick Sanan ierr = DMSwarmDataBucketFinalize(swarm->db);CHKERRQ(ierr); 521f0cdbbbaSDave May } 522f0cdbbbaSDave May swarm->field_registration_finalized = PETSC_TRUE; 5235f50eb2eSDave May PetscFunctionReturn(0); 5245f50eb2eSDave May } 5255f50eb2eSDave May 526d3a51819SDave May /*@C 527d3a51819SDave May DMSwarmSetLocalSizes - Sets the length of all registered fields on the DMSwarm 528d3a51819SDave May 529d3a51819SDave May Not collective 530d3a51819SDave May 531d3a51819SDave May Input parameters: 53262741f57SDave May + dm - a DMSwarm 533d3a51819SDave May . nlocal - the length of each registered field 53462741f57SDave May - buffer - the length of the buffer used to efficient dynamic re-sizing 535d3a51819SDave May 536d3a51819SDave May Level: beginner 537d3a51819SDave May 538d3a51819SDave May .seealso: DMSwarmGetLocalSize() 539d3a51819SDave May @*/ 5405f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmSetLocalSizes(DM dm,PetscInt nlocal,PetscInt buffer) 5415f50eb2eSDave May { 5425f50eb2eSDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 5436845f8f5SDave May PetscErrorCode ierr; 5445f50eb2eSDave May 545521f74f9SMatthew G. Knepley PetscFunctionBegin; 546f2b2bee7SDave May ierr = PetscLogEventBegin(DMSWARM_SetSizes,0,0,0,0);CHKERRQ(ierr); 54777048351SPatrick Sanan ierr = DMSwarmDataBucketSetSizes(swarm->db,nlocal,buffer);CHKERRQ(ierr); 548f2b2bee7SDave May ierr = PetscLogEventEnd(DMSWARM_SetSizes,0,0,0,0);CHKERRQ(ierr); 5495f50eb2eSDave May PetscFunctionReturn(0); 5505f50eb2eSDave May } 5515f50eb2eSDave May 552d3a51819SDave May /*@C 553d3a51819SDave May DMSwarmSetCellDM - Attachs a DM to a DMSwarm 554d3a51819SDave May 555d3a51819SDave May Collective on DM 556d3a51819SDave May 557d3a51819SDave May Input parameters: 55862741f57SDave May + dm - a DMSwarm 55962741f57SDave May - dmcell - the DM to attach to the DMSwarm 560d3a51819SDave May 561d3a51819SDave May Level: beginner 562d3a51819SDave May 563d3a51819SDave May Notes: 564d3a51819SDave May The attached DM (dmcell) will be queried for point location and 5658b8a3813SDave May neighbor MPI-rank information if DMSwarmMigrate() is called. 566d3a51819SDave May 5678b8a3813SDave May .seealso: DMSwarmSetType(), DMSwarmGetCellDM(), DMSwarmMigrate() 568d3a51819SDave May @*/ 569b16650c8SDave May PETSC_EXTERN PetscErrorCode DMSwarmSetCellDM(DM dm,DM dmcell) 570b16650c8SDave May { 571b16650c8SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 572521f74f9SMatthew G. Knepley 573521f74f9SMatthew G. Knepley PetscFunctionBegin; 574b16650c8SDave May swarm->dmcell = dmcell; 575b16650c8SDave May PetscFunctionReturn(0); 576b16650c8SDave May } 577b16650c8SDave May 578d3a51819SDave May /*@C 579d3a51819SDave May DMSwarmGetCellDM - Fetches the attached cell DM 580d3a51819SDave May 581d3a51819SDave May Collective on DM 582d3a51819SDave May 583d3a51819SDave May Input parameter: 584d3a51819SDave May . dm - a DMSwarm 585d3a51819SDave May 586d3a51819SDave May Output parameter: 587d3a51819SDave May . dmcell - the DM which was attached to the DMSwarm 588d3a51819SDave May 589d3a51819SDave May Level: beginner 590d3a51819SDave May 591d3a51819SDave May .seealso: DMSwarmSetCellDM() 592d3a51819SDave May @*/ 593fe39f135SDave May PETSC_EXTERN PetscErrorCode DMSwarmGetCellDM(DM dm,DM *dmcell) 594fe39f135SDave May { 595fe39f135SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 596521f74f9SMatthew G. Knepley 597521f74f9SMatthew G. Knepley PetscFunctionBegin; 598fe39f135SDave May *dmcell = swarm->dmcell; 599fe39f135SDave May PetscFunctionReturn(0); 600fe39f135SDave May } 601fe39f135SDave May 602d3a51819SDave May /*@C 603d3a51819SDave May DMSwarmGetLocalSize - Retrives the local length of fields registered 604d3a51819SDave May 605d3a51819SDave May Not collective 606d3a51819SDave May 607d3a51819SDave May Input parameter: 608d3a51819SDave May . dm - a DMSwarm 609d3a51819SDave May 610d3a51819SDave May Output parameter: 611d3a51819SDave May . nlocal - the length of each registered field 612d3a51819SDave May 613d3a51819SDave May Level: beginner 614d3a51819SDave May 6158b8a3813SDave May .seealso: DMSwarmGetSize(), DMSwarmSetLocalSizes() 616d3a51819SDave May @*/ 617dcf43ee8SDave May PETSC_EXTERN PetscErrorCode DMSwarmGetLocalSize(DM dm,PetscInt *nlocal) 618dcf43ee8SDave May { 619dcf43ee8SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 620dcf43ee8SDave May PetscErrorCode ierr; 621dcf43ee8SDave May 622521f74f9SMatthew G. Knepley PetscFunctionBegin; 62377048351SPatrick Sanan if (nlocal) {ierr = DMSwarmDataBucketGetSizes(swarm->db,nlocal,NULL,NULL);CHKERRQ(ierr);} 624dcf43ee8SDave May PetscFunctionReturn(0); 625dcf43ee8SDave May } 626dcf43ee8SDave May 627d3a51819SDave May /*@C 628d3a51819SDave May DMSwarmGetSize - Retrives the total length of fields registered 629d3a51819SDave May 630d3a51819SDave May Collective on DM 631d3a51819SDave May 632d3a51819SDave May Input parameter: 633d3a51819SDave May . dm - a DMSwarm 634d3a51819SDave May 635d3a51819SDave May Output parameter: 636d3a51819SDave May . n - the total length of each registered field 637d3a51819SDave May 638d3a51819SDave May Level: beginner 639d3a51819SDave May 640d3a51819SDave May Note: 641d3a51819SDave May This calls MPI_Allreduce upon each call (inefficient but safe) 642d3a51819SDave May 6438b8a3813SDave May .seealso: DMSwarmGetLocalSize(), DMSwarmSetLocalSizes() 644d3a51819SDave May @*/ 645dcf43ee8SDave May PETSC_EXTERN PetscErrorCode DMSwarmGetSize(DM dm,PetscInt *n) 646dcf43ee8SDave May { 647dcf43ee8SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 648dcf43ee8SDave May PetscErrorCode ierr; 649dcf43ee8SDave May PetscInt nlocal,ng; 650dcf43ee8SDave May 651521f74f9SMatthew G. Knepley PetscFunctionBegin; 65277048351SPatrick Sanan ierr = DMSwarmDataBucketGetSizes(swarm->db,&nlocal,NULL,NULL);CHKERRQ(ierr); 653dcf43ee8SDave May ierr = MPI_Allreduce(&nlocal,&ng,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr); 654dcf43ee8SDave May if (n) { *n = ng; } 655dcf43ee8SDave May PetscFunctionReturn(0); 656dcf43ee8SDave May } 657dcf43ee8SDave May 658d3a51819SDave May /*@C 6598b8a3813SDave May DMSwarmRegisterPetscDatatypeField - Register a field to a DMSwarm with a native PETSc data type 660d3a51819SDave May 661d3a51819SDave May Collective on DM 662d3a51819SDave May 663d3a51819SDave May Input parameters: 66462741f57SDave May + dm - a DMSwarm 665d3a51819SDave May . fieldname - the textual name to identify this field 666d3a51819SDave May . blocksize - the number of each data type 66762741f57SDave May - type - a valid PETSc data type (PETSC_CHAR, PETSC_SHORT, PETSC_INT, PETSC_FLOAT, PETSC_REAL, PETSC_LONG) 668d3a51819SDave May 669d3a51819SDave May Level: beginner 670d3a51819SDave May 671d3a51819SDave May Notes: 6728b8a3813SDave May The textual name for each registered field must be unique. 673d3a51819SDave May 674d3a51819SDave May .seealso: DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField() 675d3a51819SDave May @*/ 6765f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmRegisterPetscDatatypeField(DM dm,const char fieldname[],PetscInt blocksize,PetscDataType type) 677b62e03f8SDave May { 6782eac95f8SDave May PetscErrorCode ierr; 679b62e03f8SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 680b62e03f8SDave May size_t size; 681b62e03f8SDave May 682521f74f9SMatthew G. Knepley PetscFunctionBegin; 6835f50eb2eSDave May if (!swarm->field_registration_initialized) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMSwarmInitializeFieldRegister() first"); 6845f50eb2eSDave May if (swarm->field_registration_finalized) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Cannot register additional fields after calling DMSwarmFinalizeFieldRegister() first"); 6855f50eb2eSDave May 6865f50eb2eSDave May if (type == PETSC_OBJECT) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}"); 6875f50eb2eSDave May if (type == PETSC_FUNCTION) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}"); 6885f50eb2eSDave May if (type == PETSC_STRING) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}"); 6895f50eb2eSDave May if (type == PETSC_STRUCT) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}"); 6905f50eb2eSDave May if (type == PETSC_DATATYPE_UNKNOWN) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}"); 691b62e03f8SDave May 6922ddcf43eSMatthew G. Knepley ierr = PetscDataTypeGetSize(type, &size);CHKERRQ(ierr); 693b62e03f8SDave May /* Load a specific data type into data bucket, specifying textual name and its size in bytes */ 69477048351SPatrick Sanan ierr = DMSwarmDataBucketRegisterField(swarm->db,"DMSwarmRegisterPetscDatatypeField",fieldname,blocksize*size,NULL);CHKERRQ(ierr); 69552c3ed93SDave May { 69677048351SPatrick Sanan DMSwarmDataField gfield; 69752c3ed93SDave May 69877048351SPatrick Sanan ierr = DMSwarmDataBucketGetDMSwarmDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr); 69977048351SPatrick Sanan ierr = DMSwarmDataFieldSetBlockSize(gfield,blocksize);CHKERRQ(ierr); 70052c3ed93SDave May } 701b62e03f8SDave May swarm->db->field[swarm->db->nfields-1]->petsc_type = type; 702b62e03f8SDave May PetscFunctionReturn(0); 703b62e03f8SDave May } 704b62e03f8SDave May 705d3a51819SDave May /*@C 706d3a51819SDave May DMSwarmRegisterUserStructField - Register a user defined struct to a DMSwarm 707d3a51819SDave May 708d3a51819SDave May Collective on DM 709d3a51819SDave May 710d3a51819SDave May Input parameters: 71162741f57SDave May + dm - a DMSwarm 712d3a51819SDave May . fieldname - the textual name to identify this field 71362741f57SDave May - size - the size in bytes of the user struct of each data type 714d3a51819SDave May 715d3a51819SDave May Level: beginner 716d3a51819SDave May 717d3a51819SDave May Notes: 7188b8a3813SDave May The textual name for each registered field must be unique. 719d3a51819SDave May 720d3a51819SDave May .seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmRegisterUserDatatypeField() 721d3a51819SDave May @*/ 7225f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmRegisterUserStructField(DM dm,const char fieldname[],size_t size) 723b62e03f8SDave May { 7242eac95f8SDave May PetscErrorCode ierr; 725b62e03f8SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 726b62e03f8SDave May 727521f74f9SMatthew G. Knepley PetscFunctionBegin; 72877048351SPatrick Sanan ierr = DMSwarmDataBucketRegisterField(swarm->db,"DMSwarmRegisterUserStructField",fieldname,size,NULL);CHKERRQ(ierr); 729b62e03f8SDave May swarm->db->field[swarm->db->nfields-1]->petsc_type = PETSC_STRUCT ; 730b62e03f8SDave May PetscFunctionReturn(0); 731b62e03f8SDave May } 732b62e03f8SDave May 733d3a51819SDave May /*@C 734d3a51819SDave May DMSwarmRegisterUserDatatypeField - Register a user defined data type to a DMSwarm 735d3a51819SDave May 736d3a51819SDave May Collective on DM 737d3a51819SDave May 738d3a51819SDave May Input parameters: 73962741f57SDave May + dm - a DMSwarm 740d3a51819SDave May . fieldname - the textual name to identify this field 741d3a51819SDave May . size - the size in bytes of the user data type 74262741f57SDave May - blocksize - the number of each data type 743d3a51819SDave May 744d3a51819SDave May Level: beginner 745d3a51819SDave May 746d3a51819SDave May Notes: 7478b8a3813SDave May The textual name for each registered field must be unique. 748d3a51819SDave May 749d3a51819SDave May .seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField() 750d3a51819SDave May @*/ 751320740a0SDave May PETSC_EXTERN PetscErrorCode DMSwarmRegisterUserDatatypeField(DM dm,const char fieldname[],size_t size,PetscInt blocksize) 752b62e03f8SDave May { 753b62e03f8SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 7546845f8f5SDave May PetscErrorCode ierr; 755b62e03f8SDave May 756521f74f9SMatthew G. Knepley PetscFunctionBegin; 75777048351SPatrick Sanan ierr = DMSwarmDataBucketRegisterField(swarm->db,"DMSwarmRegisterUserDatatypeField",fieldname,blocksize*size,NULL);CHKERRQ(ierr); 758320740a0SDave May { 75977048351SPatrick Sanan DMSwarmDataField gfield; 760320740a0SDave May 76177048351SPatrick Sanan ierr = DMSwarmDataBucketGetDMSwarmDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr); 76277048351SPatrick Sanan ierr = DMSwarmDataFieldSetBlockSize(gfield,blocksize);CHKERRQ(ierr); 763320740a0SDave May } 764b62e03f8SDave May swarm->db->field[swarm->db->nfields-1]->petsc_type = PETSC_DATATYPE_UNKNOWN; 765b62e03f8SDave May PetscFunctionReturn(0); 766b62e03f8SDave May } 767b62e03f8SDave May 768d3a51819SDave May /*@C 769d3a51819SDave May DMSwarmGetField - Get access to the underlying array storing all entries associated with a registered field 770d3a51819SDave May 771d3a51819SDave May Not collective 772d3a51819SDave May 773d3a51819SDave May Input parameters: 77462741f57SDave May + dm - a DMSwarm 77562741f57SDave May - fieldname - the textual name to identify this field 776d3a51819SDave May 777d3a51819SDave May Output parameters: 77862741f57SDave May + blocksize - the number of each data type 779d3a51819SDave May . type - the data type 78062741f57SDave May - data - pointer to raw array 781d3a51819SDave May 782d3a51819SDave May Level: beginner 783d3a51819SDave May 784d3a51819SDave May Notes: 7858b8a3813SDave May The array must be returned using a matching call to DMSwarmRestoreField(). 786d3a51819SDave May 787d3a51819SDave May .seealso: DMSwarmRestoreField() 788d3a51819SDave May @*/ 7895f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmGetField(DM dm,const char fieldname[],PetscInt *blocksize,PetscDataType *type,void **data) 790b62e03f8SDave May { 791b62e03f8SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 79277048351SPatrick Sanan DMSwarmDataField gfield; 7932eac95f8SDave May PetscErrorCode ierr; 794b62e03f8SDave May 795521f74f9SMatthew G. Knepley PetscFunctionBegin; 7963454631fSDave May if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); } 79777048351SPatrick Sanan ierr = DMSwarmDataBucketGetDMSwarmDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr); 79877048351SPatrick Sanan ierr = DMSwarmDataFieldGetAccess(gfield);CHKERRQ(ierr); 79977048351SPatrick Sanan ierr = DMSwarmDataFieldGetEntries(gfield,data);CHKERRQ(ierr); 8001b1ea282SDave May if (blocksize) {*blocksize = gfield->bs; } 801b5bcf523SDave May if (type) { *type = gfield->petsc_type; } 802b62e03f8SDave May PetscFunctionReturn(0); 803b62e03f8SDave May } 804b62e03f8SDave May 805d3a51819SDave May /*@C 806d3a51819SDave May DMSwarmRestoreField - Restore access to the underlying array storing all entries associated with a registered field 807d3a51819SDave May 808d3a51819SDave May Not collective 809d3a51819SDave May 810d3a51819SDave May Input parameters: 81162741f57SDave May + dm - a DMSwarm 81262741f57SDave May - fieldname - the textual name to identify this field 813d3a51819SDave May 814d3a51819SDave May Output parameters: 81562741f57SDave May + blocksize - the number of each data type 816d3a51819SDave May . type - the data type 81762741f57SDave May - data - pointer to raw array 818d3a51819SDave May 819d3a51819SDave May Level: beginner 820d3a51819SDave May 821d3a51819SDave May Notes: 8228b8a3813SDave May The user must call DMSwarmGetField() prior to calling DMSwarmRestoreField(). 823d3a51819SDave May 824d3a51819SDave May .seealso: DMSwarmGetField() 825d3a51819SDave May @*/ 8265f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmRestoreField(DM dm,const char fieldname[],PetscInt *blocksize,PetscDataType *type,void **data) 827b62e03f8SDave May { 828b62e03f8SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 82977048351SPatrick Sanan DMSwarmDataField gfield; 8302eac95f8SDave May PetscErrorCode ierr; 831b62e03f8SDave May 832521f74f9SMatthew G. Knepley PetscFunctionBegin; 83377048351SPatrick Sanan ierr = DMSwarmDataBucketGetDMSwarmDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr); 83477048351SPatrick Sanan ierr = DMSwarmDataFieldRestoreAccess(gfield);CHKERRQ(ierr); 835b62e03f8SDave May if (data) *data = NULL; 836b62e03f8SDave May PetscFunctionReturn(0); 837b62e03f8SDave May } 838b62e03f8SDave May 839d3a51819SDave May /*@C 840d3a51819SDave May DMSwarmAddPoint - Add space for one new point in the DMSwarm 841d3a51819SDave May 842d3a51819SDave May Not collective 843d3a51819SDave May 844d3a51819SDave May Input parameter: 845d3a51819SDave May . dm - a DMSwarm 846d3a51819SDave May 847d3a51819SDave May Level: beginner 848d3a51819SDave May 849d3a51819SDave May Notes: 8508b8a3813SDave May The new point will have all fields initialized to zero. 851d3a51819SDave May 852d3a51819SDave May .seealso: DMSwarmAddNPoints() 853d3a51819SDave May @*/ 854cb1d1399SDave May PETSC_EXTERN PetscErrorCode DMSwarmAddPoint(DM dm) 855cb1d1399SDave May { 856cb1d1399SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 857cb1d1399SDave May PetscErrorCode ierr; 858cb1d1399SDave May 859521f74f9SMatthew G. Knepley PetscFunctionBegin; 8603454631fSDave May if (!swarm->issetup) {ierr = DMSetUp(dm);CHKERRQ(ierr);} 861f2b2bee7SDave May ierr = PetscLogEventBegin(DMSWARM_AddPoints,0,0,0,0);CHKERRQ(ierr); 86277048351SPatrick Sanan ierr = DMSwarmDataBucketAddPoint(swarm->db);CHKERRQ(ierr); 863f2b2bee7SDave May ierr = PetscLogEventEnd(DMSWARM_AddPoints,0,0,0,0);CHKERRQ(ierr); 864cb1d1399SDave May PetscFunctionReturn(0); 865cb1d1399SDave May } 866cb1d1399SDave May 867d3a51819SDave May /*@C 868d3a51819SDave May DMSwarmAddNPoints - Add space for a number of new points in the DMSwarm 869d3a51819SDave May 870d3a51819SDave May Not collective 871d3a51819SDave May 872d3a51819SDave May Input parameters: 87362741f57SDave May + dm - a DMSwarm 87462741f57SDave May - npoints - the number of new points to add 875d3a51819SDave May 876d3a51819SDave May Level: beginner 877d3a51819SDave May 878d3a51819SDave May Notes: 8798b8a3813SDave May The new point will have all fields initialized to zero. 880d3a51819SDave May 881d3a51819SDave May .seealso: DMSwarmAddPoint() 882d3a51819SDave May @*/ 883cb1d1399SDave May PETSC_EXTERN PetscErrorCode DMSwarmAddNPoints(DM dm,PetscInt npoints) 884cb1d1399SDave May { 885cb1d1399SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 886cb1d1399SDave May PetscErrorCode ierr; 887cb1d1399SDave May PetscInt nlocal; 888cb1d1399SDave May 889521f74f9SMatthew G. Knepley PetscFunctionBegin; 890f2b2bee7SDave May ierr = PetscLogEventBegin(DMSWARM_AddPoints,0,0,0,0);CHKERRQ(ierr); 89177048351SPatrick Sanan ierr = DMSwarmDataBucketGetSizes(swarm->db,&nlocal,NULL,NULL);CHKERRQ(ierr); 892cb1d1399SDave May nlocal = nlocal + npoints; 89377048351SPatrick Sanan ierr = DMSwarmDataBucketSetSizes(swarm->db,nlocal,DMSWARM_DATA_BUCKET_BUFFER_DEFAULT);CHKERRQ(ierr); 894f2b2bee7SDave May ierr = PetscLogEventEnd(DMSWARM_AddPoints,0,0,0,0);CHKERRQ(ierr); 895cb1d1399SDave May PetscFunctionReturn(0); 896cb1d1399SDave May } 897cb1d1399SDave May 898d3a51819SDave May /*@C 899d3a51819SDave May DMSwarmRemovePoint - Remove the last point from the DMSwarm 900d3a51819SDave May 901d3a51819SDave May Not collective 902d3a51819SDave May 903d3a51819SDave May Input parameter: 904d3a51819SDave May . dm - a DMSwarm 905d3a51819SDave May 906d3a51819SDave May Level: beginner 907d3a51819SDave May 908d3a51819SDave May .seealso: DMSwarmRemovePointAtIndex() 909d3a51819SDave May @*/ 910cb1d1399SDave May PETSC_EXTERN PetscErrorCode DMSwarmRemovePoint(DM dm) 911cb1d1399SDave May { 912cb1d1399SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 913cb1d1399SDave May PetscErrorCode ierr; 914cb1d1399SDave May 915521f74f9SMatthew G. Knepley PetscFunctionBegin; 916f2b2bee7SDave May ierr = PetscLogEventBegin(DMSWARM_RemovePoints,0,0,0,0);CHKERRQ(ierr); 91777048351SPatrick Sanan ierr = DMSwarmDataBucketRemovePoint(swarm->db);CHKERRQ(ierr); 918f2b2bee7SDave May ierr = PetscLogEventEnd(DMSWARM_RemovePoints,0,0,0,0);CHKERRQ(ierr); 919cb1d1399SDave May PetscFunctionReturn(0); 920cb1d1399SDave May } 921cb1d1399SDave May 922d3a51819SDave May /*@C 923d3a51819SDave May DMSwarmRemovePointAtIndex - Removes a specific point from the DMSwarm 924d3a51819SDave May 925d3a51819SDave May Not collective 926d3a51819SDave May 927d3a51819SDave May Input parameters: 92862741f57SDave May + dm - a DMSwarm 92962741f57SDave May - idx - index of point to remove 930d3a51819SDave May 931d3a51819SDave May Level: beginner 932d3a51819SDave May 933d3a51819SDave May .seealso: DMSwarmRemovePoint() 934d3a51819SDave May @*/ 935cb1d1399SDave May PETSC_EXTERN PetscErrorCode DMSwarmRemovePointAtIndex(DM dm,PetscInt idx) 936cb1d1399SDave May { 937cb1d1399SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 938cb1d1399SDave May PetscErrorCode ierr; 939cb1d1399SDave May 940521f74f9SMatthew G. Knepley PetscFunctionBegin; 941f2b2bee7SDave May ierr = PetscLogEventBegin(DMSWARM_RemovePoints,0,0,0,0);CHKERRQ(ierr); 94277048351SPatrick Sanan ierr = DMSwarmDataBucketRemovePointAtIndex(swarm->db,idx);CHKERRQ(ierr); 943f2b2bee7SDave May ierr = PetscLogEventEnd(DMSWARM_RemovePoints,0,0,0,0);CHKERRQ(ierr); 944cb1d1399SDave May PetscFunctionReturn(0); 945cb1d1399SDave May } 946b62e03f8SDave May 947ba4fc9c6SDave May /*@C 948ba4fc9c6SDave May DMSwarmCopyPoint - Copy point pj to point pi in the DMSwarm 949ba4fc9c6SDave May 950ba4fc9c6SDave May Not collective 951ba4fc9c6SDave May 952ba4fc9c6SDave May Input parameters: 953ba4fc9c6SDave May + dm - a DMSwarm 954ba4fc9c6SDave May . pi - the index of the point to copy 955ba4fc9c6SDave May - pj - the point index where the copy should be located 956ba4fc9c6SDave May 957ba4fc9c6SDave May Level: beginner 958ba4fc9c6SDave May 959ba4fc9c6SDave May .seealso: DMSwarmRemovePoint() 960ba4fc9c6SDave May @*/ 961ba4fc9c6SDave May PETSC_EXTERN PetscErrorCode DMSwarmCopyPoint(DM dm,PetscInt pi,PetscInt pj) 962ba4fc9c6SDave May { 963ba4fc9c6SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 964ba4fc9c6SDave May PetscErrorCode ierr; 965ba4fc9c6SDave May 966ba4fc9c6SDave May PetscFunctionBegin; 967ba4fc9c6SDave May if (!swarm->issetup) {ierr = DMSetUp(dm);CHKERRQ(ierr);} 96877048351SPatrick Sanan ierr = DMSwarmDataBucketCopyPoint(swarm->db,pi,swarm->db,pj);CHKERRQ(ierr); 969ba4fc9c6SDave May PetscFunctionReturn(0); 970ba4fc9c6SDave May } 971ba4fc9c6SDave May 972095059a4SDave May PetscErrorCode DMSwarmMigrate_Basic(DM dm,PetscBool remove_sent_points) 9733454631fSDave May { 974dcf43ee8SDave May PetscErrorCode ierr; 975521f74f9SMatthew G. Knepley 976521f74f9SMatthew G. Knepley PetscFunctionBegin; 977dcf43ee8SDave May ierr = DMSwarmMigrate_Push_Basic(dm,remove_sent_points);CHKERRQ(ierr); 9783454631fSDave May PetscFunctionReturn(0); 9793454631fSDave May } 9803454631fSDave May 981d3a51819SDave May /*@C 982d3a51819SDave May DMSwarmMigrate - Relocates points defined in the DMSwarm to other MPI-ranks 983d3a51819SDave May 984d3a51819SDave May Collective on DM 985d3a51819SDave May 986d3a51819SDave May Input parameters: 98762741f57SDave May + dm - the DMSwarm 98862741f57SDave May - remove_sent_points - flag indicating if sent points should be removed from the current MPI-rank 989d3a51819SDave May 990d3a51819SDave May Notes: 9918b8a3813SDave May The DM will be modified to accomodate received points. 9928b8a3813SDave May If remove_sent_points = PETSC_TRUE, any points that were sent will be removed from the DM. 9938b8a3813SDave May Different styles of migration are supported. See DMSwarmSetMigrateType(). 994d3a51819SDave May 995d3a51819SDave May Level: advanced 996d3a51819SDave May 997d3a51819SDave May .seealso: DMSwarmSetMigrateType() 998d3a51819SDave May @*/ 999095059a4SDave May PETSC_EXTERN PetscErrorCode DMSwarmMigrate(DM dm,PetscBool remove_sent_points) 10003454631fSDave May { 1001f0cdbbbaSDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 10023454631fSDave May PetscErrorCode ierr; 1003f0cdbbbaSDave May 1004521f74f9SMatthew G. Knepley PetscFunctionBegin; 1005ed923d71SDave May ierr = PetscLogEventBegin(DMSWARM_Migrate,0,0,0,0);CHKERRQ(ierr); 1006f0cdbbbaSDave May switch (swarm->migrate_type) { 1007f0cdbbbaSDave May case DMSWARM_MIGRATE_BASIC: 1008095059a4SDave May ierr = DMSwarmMigrate_Basic(dm,remove_sent_points);CHKERRQ(ierr); 1009f0cdbbbaSDave May break; 1010f0cdbbbaSDave May case DMSWARM_MIGRATE_DMCELLNSCATTER: 1011f0cdbbbaSDave May ierr = DMSwarmMigrate_CellDMScatter(dm,remove_sent_points);CHKERRQ(ierr); 1012f0cdbbbaSDave May break; 1013f0cdbbbaSDave May case DMSWARM_MIGRATE_DMCELLEXACT: 1014f0cdbbbaSDave May SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_MIGRATE_DMCELLEXACT not implemented"); 1015521f74f9SMatthew G. Knepley /*ierr = DMSwarmMigrate_CellDMExact(dm,remove_sent_points);CHKERRQ(ierr);*/ 1016f0cdbbbaSDave May break; 1017f0cdbbbaSDave May case DMSWARM_MIGRATE_USER: 1018f0cdbbbaSDave May SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_MIGRATE_USER not implemented"); 1019521f74f9SMatthew G. Knepley /*ierr = swarm->migrate(dm,remove_sent_points);CHKERRQ(ierr);*/ 1020f0cdbbbaSDave May break; 1021f0cdbbbaSDave May default: 1022f0cdbbbaSDave May SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_MIGRATE type unknown"); 1023f0cdbbbaSDave May break; 1024f0cdbbbaSDave May } 1025ed923d71SDave May ierr = PetscLogEventEnd(DMSWARM_Migrate,0,0,0,0);CHKERRQ(ierr); 10263454631fSDave May PetscFunctionReturn(0); 10273454631fSDave May } 10283454631fSDave May 1029f0cdbbbaSDave May PetscErrorCode DMSwarmMigrate_GlobalToLocal_Basic(DM dm,PetscInt *globalsize); 1030f0cdbbbaSDave May 1031d3a51819SDave May /* 1032d3a51819SDave May DMSwarmCollectViewCreate 1033d3a51819SDave May 1034d3a51819SDave May * Applies a collection method and gathers point neighbour points into dm 1035d3a51819SDave May 1036d3a51819SDave May Notes: 10378b8a3813SDave May Users should call DMSwarmCollectViewDestroy() after 1038d3a51819SDave May they have finished computations associated with the collected points 1039d3a51819SDave May */ 1040d3a51819SDave May 1041d3a51819SDave May /*@C 1042d3a51819SDave May DMSwarmCollectViewCreate - Applies a collection method and gathers points 1043d3a51819SDave May in neighbour MPI-ranks into the DMSwarm 1044d3a51819SDave May 1045d3a51819SDave May Collective on DM 1046d3a51819SDave May 1047d3a51819SDave May Input parameter: 1048d3a51819SDave May . dm - the DMSwarm 1049d3a51819SDave May 1050d3a51819SDave May Notes: 1051d3a51819SDave May Users should call DMSwarmCollectViewDestroy() after 1052d3a51819SDave May they have finished computations associated with the collected points 10538b8a3813SDave May Different collect methods are supported. See DMSwarmSetCollectType(). 1054d3a51819SDave May 1055d3a51819SDave May Level: advanced 1056d3a51819SDave May 1057d3a51819SDave May .seealso: DMSwarmCollectViewDestroy(), DMSwarmSetCollectType() 1058d3a51819SDave May @*/ 1059fe39f135SDave May PETSC_EXTERN PetscErrorCode DMSwarmCollectViewCreate(DM dm) 10602712d1f2SDave May { 10612712d1f2SDave May PetscErrorCode ierr; 10622712d1f2SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 10632712d1f2SDave May PetscInt ng; 10642712d1f2SDave May 1065521f74f9SMatthew G. Knepley PetscFunctionBegin; 1066480eef7bSDave May if (swarm->collect_view_active) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"CollectView currently active"); 1067480eef7bSDave May ierr = DMSwarmGetLocalSize(dm,&ng);CHKERRQ(ierr); 1068480eef7bSDave May switch (swarm->collect_type) { 1069f0cdbbbaSDave May 1070480eef7bSDave May case DMSWARM_COLLECT_BASIC: 10712712d1f2SDave May ierr = DMSwarmMigrate_GlobalToLocal_Basic(dm,&ng);CHKERRQ(ierr); 1072480eef7bSDave May break; 1073480eef7bSDave May case DMSWARM_COLLECT_DMDABOUNDINGBOX: 1074f0cdbbbaSDave May SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_COLLECT_DMDABOUNDINGBOX not implemented"); 1075521f74f9SMatthew G. Knepley /*ierr = DMSwarmCollect_DMDABoundingBox(dm,&ng);CHKERRQ(ierr);*/ 1076480eef7bSDave May break; 1077480eef7bSDave May case DMSWARM_COLLECT_GENERAL: 1078f0cdbbbaSDave May SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_COLLECT_GENERAL not implemented"); 1079521f74f9SMatthew G. Knepley /*ierr = DMSwarmCollect_General(dm,..,,..,&ng);CHKERRQ(ierr);*/ 1080480eef7bSDave May break; 1081480eef7bSDave May default: 1082f0cdbbbaSDave May SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_COLLECT type unknown"); 1083480eef7bSDave May break; 1084480eef7bSDave May } 1085480eef7bSDave May swarm->collect_view_active = PETSC_TRUE; 1086480eef7bSDave May swarm->collect_view_reset_nlocal = ng; 10872712d1f2SDave May PetscFunctionReturn(0); 10882712d1f2SDave May } 10892712d1f2SDave May 1090d3a51819SDave May /*@C 1091d3a51819SDave May DMSwarmCollectViewDestroy - Resets the DMSwarm to the size prior to calling DMSwarmCollectViewCreate() 1092d3a51819SDave May 1093d3a51819SDave May Collective on DM 1094d3a51819SDave May 1095d3a51819SDave May Input parameters: 1096d3a51819SDave May . dm - the DMSwarm 1097d3a51819SDave May 1098d3a51819SDave May Notes: 1099d3a51819SDave May Users should call DMSwarmCollectViewCreate() before this function is called. 1100d3a51819SDave May 1101d3a51819SDave May Level: advanced 1102d3a51819SDave May 1103d3a51819SDave May .seealso: DMSwarmCollectViewCreate(), DMSwarmSetCollectType() 1104d3a51819SDave May @*/ 1105fe39f135SDave May PETSC_EXTERN PetscErrorCode DMSwarmCollectViewDestroy(DM dm) 11062712d1f2SDave May { 11072712d1f2SDave May PetscErrorCode ierr; 11082712d1f2SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 11092712d1f2SDave May 1110521f74f9SMatthew G. Knepley PetscFunctionBegin; 1111480eef7bSDave May if (!swarm->collect_view_active) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"CollectView is currently not active"); 1112480eef7bSDave May ierr = DMSwarmSetLocalSizes(dm,swarm->collect_view_reset_nlocal,-1);CHKERRQ(ierr); 1113480eef7bSDave May swarm->collect_view_active = PETSC_FALSE; 11142712d1f2SDave May PetscFunctionReturn(0); 11152712d1f2SDave May } 11163454631fSDave May 1117f0cdbbbaSDave May PetscErrorCode DMSwarmSetUpPIC(DM dm) 1118f0cdbbbaSDave May { 1119f0cdbbbaSDave May PetscInt dim; 1120f0cdbbbaSDave May PetscErrorCode ierr; 1121f0cdbbbaSDave May 1122521f74f9SMatthew G. Knepley PetscFunctionBegin; 1123f0cdbbbaSDave May ierr = DMGetDimension(dm,&dim);CHKERRQ(ierr); 1124f0cdbbbaSDave May if (dim < 1) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Dimension must be 1,2,3 - found %D",dim); 1125f0cdbbbaSDave May if (dim > 3) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Dimension must be 1,2,3 - found %D",dim); 1126f0cdbbbaSDave May ierr = DMSwarmRegisterPetscDatatypeField(dm,DMSwarmPICField_coor,dim,PETSC_DOUBLE);CHKERRQ(ierr); 1127e2d107dbSDave May ierr = DMSwarmRegisterPetscDatatypeField(dm,DMSwarmPICField_cellid,1,PETSC_INT);CHKERRQ(ierr); 1128f0cdbbbaSDave May PetscFunctionReturn(0); 1129f0cdbbbaSDave May } 1130f0cdbbbaSDave May 1131d3a51819SDave May /*@C 1132d3a51819SDave May DMSwarmSetType - Set particular flavor of DMSwarm 1133d3a51819SDave May 1134d3a51819SDave May Collective on DM 1135d3a51819SDave May 1136d3a51819SDave May Input parameters: 113762741f57SDave May + dm - the DMSwarm 113862741f57SDave May - stype - the DMSwarm type (e.g. DMSWARM_PIC) 1139d3a51819SDave May 1140d3a51819SDave May Level: advanced 1141d3a51819SDave May 1142d3a51819SDave May .seealso: DMSwarmSetMigrateType(), DMSwarmSetCollectType() 1143d3a51819SDave May @*/ 1144f0cdbbbaSDave May PETSC_EXTERN PetscErrorCode DMSwarmSetType(DM dm,DMSwarmType stype) 1145f0cdbbbaSDave May { 1146f0cdbbbaSDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 1147f0cdbbbaSDave May PetscErrorCode ierr; 1148f0cdbbbaSDave May 1149521f74f9SMatthew G. Knepley PetscFunctionBegin; 1150f0cdbbbaSDave May swarm->swarm_type = stype; 1151f0cdbbbaSDave May if (swarm->swarm_type == DMSWARM_PIC) { 1152f0cdbbbaSDave May ierr = DMSwarmSetUpPIC(dm);CHKERRQ(ierr); 1153f0cdbbbaSDave May } 1154f0cdbbbaSDave May PetscFunctionReturn(0); 1155f0cdbbbaSDave May } 1156f0cdbbbaSDave May 11573454631fSDave May PetscErrorCode DMSetup_Swarm(DM dm) 11583454631fSDave May { 11593454631fSDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 11603454631fSDave May PetscErrorCode ierr; 11613454631fSDave May PetscMPIInt rank; 11623454631fSDave May PetscInt p,npoints,*rankval; 11633454631fSDave May 1164521f74f9SMatthew G. Knepley PetscFunctionBegin; 11653454631fSDave May if (swarm->issetup) PetscFunctionReturn(0); 11663454631fSDave May 11673454631fSDave May swarm->issetup = PETSC_TRUE; 11683454631fSDave May 1169f0cdbbbaSDave May if (swarm->swarm_type == DMSWARM_PIC) { 1170f0cdbbbaSDave May /* check dmcell exists */ 1171f0cdbbbaSDave May if (!swarm->dmcell) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSWARM_PIC requires you call DMSwarmSetCellDM"); 1172f0cdbbbaSDave May 1173f0cdbbbaSDave May if (swarm->dmcell->ops->locatepointssubdomain) { 1174f0cdbbbaSDave May /* check methods exists for exact ownership identificiation */ 1175521f74f9SMatthew G. Knepley ierr = PetscPrintf(PetscObjectComm((PetscObject)dm)," DMSWARM_PIC: Using method CellDM->ops->LocatePointsSubdomain\n");CHKERRQ(ierr); 1176f0cdbbbaSDave May swarm->migrate_type = DMSWARM_MIGRATE_DMCELLEXACT; 1177f0cdbbbaSDave May } else { 1178f0cdbbbaSDave May /* check methods exist for point location AND rank neighbor identification */ 1179f0cdbbbaSDave May if (swarm->dmcell->ops->locatepoints) { 1180521f74f9SMatthew G. Knepley ierr = PetscPrintf(PetscObjectComm((PetscObject)dm)," DMSWARM_PIC: Using method CellDM->LocatePoints\n");CHKERRQ(ierr); 1181f0cdbbbaSDave May } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSWARM_PIC requires the method CellDM->ops->locatepoints be defined"); 1182f0cdbbbaSDave May 1183f0cdbbbaSDave May if (swarm->dmcell->ops->getneighbors) { 1184521f74f9SMatthew G. Knepley ierr = PetscPrintf(PetscObjectComm((PetscObject)dm)," DMSWARM_PIC: Using method CellDM->GetNeigbors\n");CHKERRQ(ierr); 1185f0cdbbbaSDave May } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSWARM_PIC requires the method CellDM->ops->getneighbors be defined"); 1186f0cdbbbaSDave May 1187f0cdbbbaSDave May swarm->migrate_type = DMSWARM_MIGRATE_DMCELLNSCATTER; 1188f0cdbbbaSDave May } 1189f0cdbbbaSDave May } 1190f0cdbbbaSDave May 1191f0cdbbbaSDave May ierr = DMSwarmFinalizeFieldRegister(dm);CHKERRQ(ierr); 1192f0cdbbbaSDave May 11933454631fSDave May /* check some fields were registered */ 11943454631fSDave May if (swarm->db->nfields <= 2) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"At least one field user must be registered via DMSwarmRegisterXXX()"); 11953454631fSDave May 11963454631fSDave May /* check local sizes were set */ 11973454631fSDave May if (swarm->db->L == -1) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Local sizes must be set via DMSwarmSetLocalSizes()"); 11983454631fSDave May 11993454631fSDave May /* initialize values in pid and rank placeholders */ 12003454631fSDave May /* TODO: [pid - use MPI_Scan] */ 12013454631fSDave May ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm),&rank);CHKERRQ(ierr); 120277048351SPatrick Sanan ierr = DMSwarmDataBucketGetSizes(swarm->db,&npoints,NULL,NULL);CHKERRQ(ierr); 1203f0cdbbbaSDave May ierr = DMSwarmGetField(dm,DMSwarmField_rank,NULL,NULL,(void**)&rankval);CHKERRQ(ierr); 12043454631fSDave May for (p=0; p<npoints; p++) { 12053454631fSDave May rankval[p] = (PetscInt)rank; 12063454631fSDave May } 1207f0cdbbbaSDave May ierr = DMSwarmRestoreField(dm,DMSwarmField_rank,NULL,NULL,(void**)&rankval);CHKERRQ(ierr); 12083454631fSDave May PetscFunctionReturn(0); 12093454631fSDave May } 12103454631fSDave May 1211dc5f5ce9SDave May extern PetscErrorCode DMSwarmSortDestroy(DMSwarmSort *_ctx); 1212dc5f5ce9SDave May 121357795646SDave May PetscErrorCode DMDestroy_Swarm(DM dm) 121457795646SDave May { 121557795646SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 121657795646SDave May PetscErrorCode ierr; 121757795646SDave May 121857795646SDave May PetscFunctionBegin; 121977048351SPatrick Sanan ierr = DMSwarmDataBucketDestroy(&swarm->db);CHKERRQ(ierr); 1220dc5f5ce9SDave May if (swarm->sort_context) { 1221dc5f5ce9SDave May ierr = DMSwarmSortDestroy(&swarm->sort_context);CHKERRQ(ierr); 1222dc5f5ce9SDave May } 122357795646SDave May ierr = PetscFree(swarm);CHKERRQ(ierr); 122457795646SDave May PetscFunctionReturn(0); 122557795646SDave May } 122657795646SDave May 1227a9ee3421SMatthew G. Knepley PetscErrorCode DMSwarmView_Draw(DM dm, PetscViewer viewer) 1228a9ee3421SMatthew G. Knepley { 1229a9ee3421SMatthew G. Knepley DM cdm; 1230a9ee3421SMatthew G. Knepley PetscDraw draw; 1231a9ee3421SMatthew G. Knepley PetscReal *coords, oldPause; 1232a9ee3421SMatthew G. Knepley PetscInt Np, p, bs; 1233a9ee3421SMatthew G. Knepley PetscErrorCode ierr; 1234a9ee3421SMatthew G. Knepley 1235a9ee3421SMatthew G. Knepley PetscFunctionBegin; 1236a9ee3421SMatthew G. Knepley ierr = PetscViewerDrawGetDraw(viewer, 0, &draw);CHKERRQ(ierr); 1237a9ee3421SMatthew G. Knepley ierr = DMSwarmGetCellDM(dm, &cdm);CHKERRQ(ierr); 1238a9ee3421SMatthew G. Knepley ierr = PetscDrawGetPause(draw, &oldPause);CHKERRQ(ierr); 1239a9ee3421SMatthew G. Knepley ierr = PetscDrawSetPause(draw, 0.0);CHKERRQ(ierr); 1240a9ee3421SMatthew G. Knepley ierr = DMView(cdm, viewer);CHKERRQ(ierr); 1241a9ee3421SMatthew G. Knepley ierr = PetscDrawSetPause(draw, oldPause);CHKERRQ(ierr); 1242a9ee3421SMatthew G. Knepley 1243a9ee3421SMatthew G. Knepley ierr = DMSwarmGetLocalSize(dm, &Np);CHKERRQ(ierr); 1244a9ee3421SMatthew G. Knepley ierr = DMSwarmGetField(dm, DMSwarmPICField_coor, &bs, NULL, (void **) &coords);CHKERRQ(ierr); 1245a9ee3421SMatthew G. Knepley for (p = 0; p < Np; ++p) { 1246a9ee3421SMatthew G. Knepley const PetscInt i = p*bs; 1247a9ee3421SMatthew G. Knepley 1248a9ee3421SMatthew G. Knepley ierr = PetscDrawEllipse(draw, coords[i], coords[i+1], 0.01, 0.01, PETSC_DRAW_BLUE);CHKERRQ(ierr); 1249a9ee3421SMatthew G. Knepley } 1250a9ee3421SMatthew G. Knepley ierr = DMSwarmRestoreField(dm, DMSwarmPICField_coor, &bs, NULL, (void **) &coords);CHKERRQ(ierr); 1251a9ee3421SMatthew G. Knepley ierr = PetscDrawFlush(draw);CHKERRQ(ierr); 1252a9ee3421SMatthew G. Knepley ierr = PetscDrawPause(draw);CHKERRQ(ierr); 1253a9ee3421SMatthew G. Knepley ierr = PetscDrawSave(draw);CHKERRQ(ierr); 1254a9ee3421SMatthew G. Knepley PetscFunctionReturn(0); 1255a9ee3421SMatthew G. Knepley } 1256a9ee3421SMatthew G. Knepley 12575f50eb2eSDave May PetscErrorCode DMView_Swarm(DM dm, PetscViewer viewer) 12585f50eb2eSDave May { 12595f50eb2eSDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 1260a9ee3421SMatthew G. Knepley PetscBool iascii,ibinary,ishdf5,isvtk,isdraw; 12615f50eb2eSDave May PetscErrorCode ierr; 12625f50eb2eSDave May 12635f50eb2eSDave May PetscFunctionBegin; 12645f50eb2eSDave May PetscValidHeaderSpecific(dm,DM_CLASSID,1); 12655f50eb2eSDave May PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 12665f50eb2eSDave May ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr); 12675f50eb2eSDave May ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY,&ibinary);CHKERRQ(ierr); 12685f50eb2eSDave May ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERVTK, &isvtk);CHKERRQ(ierr); 12695f50eb2eSDave May ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 1270a9ee3421SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw);CHKERRQ(ierr); 12715f50eb2eSDave May if (iascii) { 127277048351SPatrick Sanan ierr = DMSwarmDataBucketView(PetscObjectComm((PetscObject)dm),swarm->db,NULL,DATABUCKET_VIEW_STDOUT);CHKERRQ(ierr); 1273298827fbSBarry Smith } else if (ibinary) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"NO Binary support"); 12745f50eb2eSDave May #if defined(PETSC_HAVE_HDF5) 1275298827fbSBarry Smith else if (ishdf5) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"NO HDF5 support"); 12765f50eb2eSDave May #else 1277298827fbSBarry Smith else if (ishdf5) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"HDF5 not supported. Please reconfigure using --download-hdf5"); 12785f50eb2eSDave May #endif 1279298827fbSBarry Smith else if (isvtk) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"NO VTK support"); 1280298827fbSBarry Smith else if (isdraw) { 1281a9ee3421SMatthew G. Knepley ierr = DMSwarmView_Draw(dm, viewer);CHKERRQ(ierr); 12825f50eb2eSDave May } 12835f50eb2eSDave May PetscFunctionReturn(0); 12845f50eb2eSDave May } 12855f50eb2eSDave May 1286d3a51819SDave May /*MC 1287d3a51819SDave May 1288d3a51819SDave May DMSWARM = "swarm" - A DM object used to represent arrays of data (fields) of arbitrary data type. 128962741f57SDave May This implementation was designed for particle methods in which the underlying 1290d3a51819SDave May data required to be represented is both (i) dynamic in length, (ii) and of arbitrary data type. 1291d3a51819SDave May 129262741f57SDave May User data can be represented by DMSwarm through a registering "fields". 129362741f57SDave May To register a field, the user must provide; 129462741f57SDave May (a) a unique name; 129562741f57SDave May (b) the data type (or size in bytes); 129662741f57SDave May (c) the block size of the data. 1297d3a51819SDave May 1298d3a51819SDave May For example, suppose the application requires a unique id, energy, momentum and density to be stored 129962741f57SDave May on a set of of particles. Then the following code could be used 1300d3a51819SDave May 130162741f57SDave May $ DMSwarmInitializeFieldRegister(dm) 130262741f57SDave May $ DMSwarmRegisterPetscDatatypeField(dm,"uid",1,PETSC_LONG); 130362741f57SDave May $ DMSwarmRegisterPetscDatatypeField(dm,"energy",1,PETSC_REAL); 130462741f57SDave May $ DMSwarmRegisterPetscDatatypeField(dm,"momentum",3,PETSC_REAL); 130562741f57SDave May $ DMSwarmRegisterPetscDatatypeField(dm,"density",1,PETSC_FLOAT); 130662741f57SDave May $ DMSwarmFinalizeFieldRegister(dm) 1307d3a51819SDave May 1308d3a51819SDave May The fields represented by DMSwarm are dynamic and can be re-sized at any time. 130962741f57SDave May The only restriction imposed by DMSwarm is that all fields contain the same number of points. 1310d3a51819SDave May 1311d3a51819SDave May To support particle methods, "migration" techniques are provided. These methods migrate data 1312d3a51819SDave May between MPI-ranks. 1313d3a51819SDave May 1314d3a51819SDave May DMSwarm supports the methods DMCreateGlobalVector() and DMCreateLocalVector(). 1315d3a51819SDave May As a DMSwarm may internally define and store values of different data types, 131662741f57SDave May before calling DMCreateGlobalVector() or DMCreateLocalVector(), the user must inform DMSwarm which 1317d3a51819SDave May fields should be used to define a Vec object via 1318d3a51819SDave May DMSwarmVectorDefineField() 1319d3a51819SDave May The specified field can can changed be changed at any time - thereby permitting vectors 1320d3a51819SDave May compatable with different fields to be created. 1321d3a51819SDave May 132262741f57SDave May A dual representation of fields in the DMSwarm and a Vec object is permitted via 1323d3a51819SDave May DMSwarmCreateGlobalVectorFromField() 1324d3a51819SDave May Here the data defining the field in the DMSwarm is shared with a Vec. 1325d3a51819SDave May This is inherently unsafe if you alter the size of the field at any time between 1326d3a51819SDave May calls to DMSwarmCreateGlobalVectorFromField() and DMSwarmDestroyGlobalVectorFromField(). 1327cc651181SDave May If the local size of the DMSwarm does not match the local size of the global vector 1328cc651181SDave May when DMSwarmDestroyGlobalVectorFromField() is called, an error is thrown. 1329d3a51819SDave May 133062741f57SDave May Additional high-level support is provided for Particle-In-Cell methods. 133162741f57SDave May Please refer to the man page for DMSwarmSetType(). 133262741f57SDave May 1333d3a51819SDave May Level: beginner 1334d3a51819SDave May 1335d3a51819SDave May .seealso: DMType, DMCreate(), DMSetType() 1336d3a51819SDave May M*/ 133757795646SDave May PETSC_EXTERN PetscErrorCode DMCreate_Swarm(DM dm) 133857795646SDave May { 133957795646SDave May DM_Swarm *swarm; 134057795646SDave May PetscErrorCode ierr; 134157795646SDave May 134257795646SDave May PetscFunctionBegin; 134357795646SDave May PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 134457795646SDave May ierr = PetscNewLog(dm,&swarm);CHKERRQ(ierr); 1345f0cdbbbaSDave May dm->data = swarm; 134657795646SDave May 134777048351SPatrick Sanan ierr = DMSwarmDataBucketCreate(&swarm->db);CHKERRQ(ierr); 1348f0cdbbbaSDave May ierr = DMSwarmInitializeFieldRegister(dm);CHKERRQ(ierr); 1349f0cdbbbaSDave May 1350b5bcf523SDave May swarm->vec_field_set = PETSC_FALSE; 13513454631fSDave May swarm->issetup = PETSC_FALSE; 1352480eef7bSDave May swarm->swarm_type = DMSWARM_BASIC; 1353480eef7bSDave May swarm->migrate_type = DMSWARM_MIGRATE_BASIC; 1354480eef7bSDave May swarm->collect_type = DMSWARM_COLLECT_BASIC; 135540c453e9SDave May swarm->migrate_error_on_missing_point = PETSC_FALSE; 1356b62e03f8SDave May 1357f0cdbbbaSDave May swarm->dmcell = NULL; 1358f0cdbbbaSDave May swarm->collect_view_active = PETSC_FALSE; 1359f0cdbbbaSDave May swarm->collect_view_reset_nlocal = -1; 136057795646SDave May 1361f0cdbbbaSDave May dm->dim = 0; 13625f50eb2eSDave May dm->ops->view = DMView_Swarm; 136357795646SDave May dm->ops->load = NULL; 136457795646SDave May dm->ops->setfromoptions = NULL; 136557795646SDave May dm->ops->clone = NULL; 13663454631fSDave May dm->ops->setup = DMSetup_Swarm; 136757795646SDave May dm->ops->createdefaultsection = NULL; 136857795646SDave May dm->ops->createdefaultconstraints = NULL; 1369b5bcf523SDave May dm->ops->createglobalvector = DMCreateGlobalVector_Swarm; 1370b5bcf523SDave May dm->ops->createlocalvector = DMCreateLocalVector_Swarm; 137157795646SDave May dm->ops->getlocaltoglobalmapping = NULL; 137257795646SDave May dm->ops->createfieldis = NULL; 137357795646SDave May dm->ops->createcoordinatedm = NULL; 137457795646SDave May dm->ops->getcoloring = NULL; 137557795646SDave May dm->ops->creatematrix = NULL; 137657795646SDave May dm->ops->createinterpolation = NULL; 137757795646SDave May dm->ops->getaggregates = NULL; 137857795646SDave May dm->ops->getinjection = NULL; 137983c47955SMatthew G. Knepley dm->ops->createmassmatrix = DMCreateMassMatrix_Swarm; 138057795646SDave May dm->ops->refine = NULL; 138157795646SDave May dm->ops->coarsen = NULL; 138257795646SDave May dm->ops->refinehierarchy = NULL; 138357795646SDave May dm->ops->coarsenhierarchy = NULL; 138457795646SDave May dm->ops->globaltolocalbegin = NULL; 138557795646SDave May dm->ops->globaltolocalend = NULL; 138657795646SDave May dm->ops->localtoglobalbegin = NULL; 138757795646SDave May dm->ops->localtoglobalend = NULL; 138857795646SDave May dm->ops->destroy = DMDestroy_Swarm; 138957795646SDave May dm->ops->createsubdm = NULL; 139057795646SDave May dm->ops->getdimpoints = NULL; 139157795646SDave May dm->ops->locatepoints = NULL; 139257795646SDave May PetscFunctionReturn(0); 139357795646SDave May } 1394