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 28d083f849SBarry Smith 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; 196adb2528bSMark 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); 20992fd8e1eSJed Brown ierr = DMGetLocalSection(dmf, &fsection);CHKERRQ(ierr); 210e87a4003SBarry Smith ierr = DMGetGlobalSection(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); 23053e60ab4SJoseph Pusztay 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; 24683c47955SMatthew G. Knepley for (i = 0; i < numFIndices; ++i) { 247adb2528bSMark Adams key.j = findices[i]; /* global column (from Plex) */ 248adb2528bSMark Adams if (key.j >= 0) { 24983c47955SMatthew G. Knepley /* Get indices for coarse elements */ 25083c47955SMatthew G. Knepley for (c = 0; c < numCIndices; ++c) { 251adb2528bSMark Adams key.i = cindices[c] + rStart; /* global cols (from Swarm) */ 252adb2528bSMark Adams if (key.i < 0) continue; 253e8f14785SLisandro Dalcin ierr = PetscHSetIJQueryAdd(ht, key, &missing);CHKERRQ(ierr); 25483c47955SMatthew G. Knepley if (missing) { 2550643ed39SMatthew G. Knepley if ((key.j >= colStart) && (key.j < colEnd)) ++dnz[key.i - rStart]; 256e8f14785SLisandro Dalcin else ++onz[key.i - rStart]; 2570643ed39SMatthew G. Knepley } else SETERRQ2(PetscObjectComm((PetscObject) dmf), PETSC_ERR_SUP, "Set new value at %D,%D", key.i, key.j); 25883c47955SMatthew G. Knepley } 259fc7c92abSMatthew G. Knepley } 260fc7c92abSMatthew G. Knepley } 26183c47955SMatthew G. Knepley ierr = PetscFree(cindices);CHKERRQ(ierr); 26283c47955SMatthew G. Knepley } 26383c47955SMatthew G. Knepley ierr = DMPlexRestoreClosureIndices(dmf, fsection, globalFSection, cell, &numFIndices, &findices, NULL);CHKERRQ(ierr); 26483c47955SMatthew G. Knepley } 26583c47955SMatthew G. Knepley } 266e8f14785SLisandro Dalcin ierr = PetscHSetIJDestroy(&ht);CHKERRQ(ierr); 26783c47955SMatthew G. Knepley ierr = MatXAIJSetPreallocation(mass, 1, dnz, onz, NULL, NULL);CHKERRQ(ierr); 26883c47955SMatthew G. Knepley ierr = MatSetOption(mass, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_TRUE);CHKERRQ(ierr); 26983c47955SMatthew G. Knepley ierr = PetscFree2(dnz, onz);CHKERRQ(ierr); 270adb2528bSMark Adams ierr = PetscMalloc3(maxC*totDim, &elemMat, maxC, &rowIDXs, maxC*dim, &xi);CHKERRQ(ierr); 27183c47955SMatthew G. Knepley for (field = 0; field < Nf; ++field) { 27283c47955SMatthew G. Knepley PetscObject obj; 2730643ed39SMatthew G. Knepley PetscReal *Bcoarse, *coords; 2740643ed39SMatthew G. Knepley PetscInt Nc, i; 27583c47955SMatthew G. Knepley 27683c47955SMatthew G. Knepley ierr = PetscDSGetDiscretization(prob, field, &obj);CHKERRQ(ierr); 2770643ed39SMatthew G. Knepley ierr = PetscFEGetNumComponents((PetscFE) obj, &Nc);CHKERRQ(ierr); 2780643ed39SMatthew G. Knepley if (Nc != 1) SETERRQ1(PetscObjectComm((PetscObject) dmf), PETSC_ERR_SUP, "Can only interpolate a scalar field from particles, Nc = %D", Nc); 2790643ed39SMatthew G. Knepley ierr = DMSwarmGetField(dmc, DMSwarmPICField_coor, NULL, NULL, (void **) &coords);CHKERRQ(ierr); 28083c47955SMatthew G. Knepley for (cell = cStart; cell < cEnd; ++cell) { 28183c47955SMatthew G. Knepley PetscInt *findices , *cindices; 28283c47955SMatthew G. Knepley PetscInt numFIndices, numCIndices; 2830643ed39SMatthew G. Knepley PetscInt p, c; 28483c47955SMatthew G. Knepley 2850643ed39SMatthew G. Knepley /* TODO: Use DMField instead of assuming affine */ 28683c47955SMatthew G. Knepley ierr = DMPlexComputeCellGeometryFEM(dmf, cell, NULL, v0, J, invJ, &detJ);CHKERRQ(ierr); 28783c47955SMatthew G. Knepley ierr = DMPlexGetClosureIndices(dmf, fsection, globalFSection, cell, &numFIndices, &findices, NULL);CHKERRQ(ierr); 28883c47955SMatthew G. Knepley ierr = DMSwarmSortGetPointsPerCell(dmc, cell, &numCIndices, &cindices);CHKERRQ(ierr); 2890643ed39SMatthew G. Knepley for (p = 0; p < numCIndices; ++p) { 2900643ed39SMatthew G. Knepley CoordinatesRealToRef(dim, dim, v0ref, v0, invJ, &coords[cindices[p]*dim], &xi[p*dim]); 2910643ed39SMatthew G. Knepley } 2920643ed39SMatthew G. Knepley ierr = PetscFEGetTabulation((PetscFE) obj, numCIndices, xi, &Bcoarse, NULL, NULL);CHKERRQ(ierr); 29383c47955SMatthew G. Knepley /* Get elemMat entries by multiplying by weight */ 294580bdb30SBarry Smith ierr = PetscArrayzero(elemMat, numCIndices*totDim);CHKERRQ(ierr); 29583c47955SMatthew G. Knepley for (i = 0; i < numFIndices; ++i) { 2960643ed39SMatthew G. Knepley for (p = 0; p < numCIndices; ++p) { 2970643ed39SMatthew G. Knepley for (c = 0; c < Nc; ++c) { 2980643ed39SMatthew G. Knepley /* B[(p*pdim + i)*Nc + c] is the value at point p for basis function i and component c */ 299adb2528bSMark Adams elemMat[p*numFIndices+i] += Bcoarse[(p*numFIndices + i)*Nc + c]*(useDeltaFunction ? 1.0 : detJ); 30083c47955SMatthew G. Knepley } 3010643ed39SMatthew G. Knepley } 3020643ed39SMatthew G. Knepley } 303adb2528bSMark Adams for (p = 0; p < numCIndices; ++p) rowIDXs[p] = cindices[p] + rStart; 30483c47955SMatthew G. Knepley if (0) {ierr = DMPrintCellMatrix(cell, name, 1, numCIndices, elemMat);CHKERRQ(ierr);} 305adb2528bSMark Adams ierr = MatSetValues(mass, numCIndices, rowIDXs, numFIndices, findices, elemMat, ADD_VALUES);CHKERRQ(ierr); 30683c47955SMatthew G. Knepley ierr = PetscFree(cindices);CHKERRQ(ierr); 30783c47955SMatthew G. Knepley ierr = DMPlexRestoreClosureIndices(dmf, fsection, globalFSection, cell, &numFIndices, &findices, NULL);CHKERRQ(ierr); 3080643ed39SMatthew G. Knepley ierr = PetscFERestoreTabulation((PetscFE) obj, numCIndices, xi, &Bcoarse, NULL, NULL);CHKERRQ(ierr); 30983c47955SMatthew G. Knepley } 3100643ed39SMatthew G. Knepley ierr = DMSwarmRestoreField(dmc, DMSwarmPICField_coor, NULL, NULL, (void **) &coords);CHKERRQ(ierr); 31183c47955SMatthew G. Knepley } 312adb2528bSMark Adams ierr = PetscFree3(elemMat, rowIDXs, xi);CHKERRQ(ierr); 31383c47955SMatthew G. Knepley ierr = DMSwarmSortRestoreAccess(dmc);CHKERRQ(ierr); 31483c47955SMatthew G. Knepley ierr = PetscFree3(v0, J, invJ);CHKERRQ(ierr); 31583c47955SMatthew G. Knepley ierr = MatAssemblyBegin(mass, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 31683c47955SMatthew G. Knepley ierr = MatAssemblyEnd(mass, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 31783c47955SMatthew G. Knepley PetscFunctionReturn(0); 31883c47955SMatthew G. Knepley } 31983c47955SMatthew G. Knepley 320adb2528bSMark Adams /* FEM cols, Particle rows */ 32183c47955SMatthew G. Knepley static PetscErrorCode DMCreateMassMatrix_Swarm(DM dmCoarse, DM dmFine, Mat *mass) 32283c47955SMatthew G. Knepley { 323895a1698SMatthew G. Knepley PetscSection gsf; 32483c47955SMatthew G. Knepley PetscInt m, n; 32583c47955SMatthew G. Knepley void *ctx; 32683c47955SMatthew G. Knepley PetscErrorCode ierr; 32783c47955SMatthew G. Knepley 32883c47955SMatthew G. Knepley PetscFunctionBegin; 329e87a4003SBarry Smith ierr = DMGetGlobalSection(dmFine, &gsf);CHKERRQ(ierr); 33083c47955SMatthew G. Knepley ierr = PetscSectionGetConstrainedStorageSize(gsf, &m);CHKERRQ(ierr); 331895a1698SMatthew G. Knepley ierr = DMSwarmGetLocalSize(dmCoarse, &n);CHKERRQ(ierr); 33283c47955SMatthew G. Knepley ierr = MatCreate(PetscObjectComm((PetscObject) dmCoarse), mass);CHKERRQ(ierr); 333adb2528bSMark Adams ierr = MatSetSizes(*mass, n, m, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr); 33483c47955SMatthew G. Knepley ierr = MatSetType(*mass, dmCoarse->mattype);CHKERRQ(ierr); 33583c47955SMatthew G. Knepley ierr = DMGetApplicationContext(dmFine, &ctx);CHKERRQ(ierr); 33683c47955SMatthew G. Knepley 3370643ed39SMatthew G. Knepley ierr = DMSwarmComputeMassMatrix_Private(dmCoarse, dmFine, *mass, PETSC_TRUE, ctx);CHKERRQ(ierr); 33883c47955SMatthew G. Knepley ierr = MatViewFromOptions(*mass, NULL, "-mass_mat_view");CHKERRQ(ierr); 33983c47955SMatthew G. Knepley PetscFunctionReturn(0); 34083c47955SMatthew G. Knepley } 34183c47955SMatthew G. Knepley 342fb1bcc12SMatthew G. Knepley /*@C 343d3a51819SDave May DMSwarmCreateGlobalVectorFromField - Creates a Vec object sharing the array associated with a given field 344d3a51819SDave May 345d083f849SBarry Smith Collective on dm 346d3a51819SDave May 347d3a51819SDave May Input parameters: 34862741f57SDave May + dm - a DMSwarm 34962741f57SDave May - fieldname - the textual name given to a registered field 350d3a51819SDave May 3518b8a3813SDave May Output parameter: 352d3a51819SDave May . vec - the vector 353d3a51819SDave May 354d3a51819SDave May Level: beginner 355d3a51819SDave May 3568b8a3813SDave May Notes: 3578b8a3813SDave May The vector must be returned using a matching call to DMSwarmDestroyGlobalVectorFromField(). 3588b8a3813SDave May 3598b8a3813SDave May .seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmDestroyGlobalVectorFromField() 360d3a51819SDave May @*/ 361b5bcf523SDave May PETSC_EXTERN PetscErrorCode DMSwarmCreateGlobalVectorFromField(DM dm,const char fieldname[],Vec *vec) 362b5bcf523SDave May { 363fb1bcc12SMatthew G. Knepley MPI_Comm comm = PetscObjectComm((PetscObject) dm); 364b5bcf523SDave May PetscErrorCode ierr; 365b5bcf523SDave May 366fb1bcc12SMatthew G. Knepley PetscFunctionBegin; 367fb1bcc12SMatthew G. Knepley ierr = DMSwarmCreateVectorFromField_Private(dm, fieldname, comm, vec);CHKERRQ(ierr); 368b5bcf523SDave May PetscFunctionReturn(0); 369b5bcf523SDave May } 370b5bcf523SDave May 371d3a51819SDave May /*@C 372d3a51819SDave May DMSwarmDestroyGlobalVectorFromField - Destroys the Vec object which share the array associated with a given field 373d3a51819SDave May 374d083f849SBarry Smith Collective on dm 375d3a51819SDave May 376d3a51819SDave May Input parameters: 37762741f57SDave May + dm - a DMSwarm 37862741f57SDave May - fieldname - the textual name given to a registered field 379d3a51819SDave May 3808b8a3813SDave May Output parameter: 381d3a51819SDave May . vec - the vector 382d3a51819SDave May 383d3a51819SDave May Level: beginner 384d3a51819SDave May 3858b8a3813SDave May .seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmCreateGlobalVectorFromField() 386d3a51819SDave May @*/ 387b5bcf523SDave May PETSC_EXTERN PetscErrorCode DMSwarmDestroyGlobalVectorFromField(DM dm,const char fieldname[],Vec *vec) 388b5bcf523SDave May { 389b5bcf523SDave May PetscErrorCode ierr; 390cc651181SDave May 391fb1bcc12SMatthew G. Knepley PetscFunctionBegin; 392fb1bcc12SMatthew G. Knepley ierr = DMSwarmDestroyVectorFromField_Private(dm, fieldname, vec);CHKERRQ(ierr); 393b5bcf523SDave May PetscFunctionReturn(0); 394b5bcf523SDave May } 395b5bcf523SDave May 396fb1bcc12SMatthew G. Knepley /*@C 397fb1bcc12SMatthew G. Knepley DMSwarmCreateLocalVectorFromField - Creates a Vec object sharing the array associated with a given field 398fb1bcc12SMatthew G. Knepley 399d083f849SBarry Smith Collective on dm 400fb1bcc12SMatthew G. Knepley 401fb1bcc12SMatthew G. Knepley Input parameters: 40262741f57SDave May + dm - a DMSwarm 40362741f57SDave May - fieldname - the textual name given to a registered field 404fb1bcc12SMatthew G. Knepley 4058b8a3813SDave May Output parameter: 406fb1bcc12SMatthew G. Knepley . vec - the vector 407fb1bcc12SMatthew G. Knepley 408fb1bcc12SMatthew G. Knepley Level: beginner 409fb1bcc12SMatthew G. Knepley 4108b8a3813SDave May Notes: 4118b8a3813SDave May The vector must be returned using a matching call to DMSwarmDestroyLocalVectorFromField(). 4128b8a3813SDave May 4138b8a3813SDave May .seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmDestroyLocalVectorFromField() 414fb1bcc12SMatthew G. Knepley @*/ 415fb1bcc12SMatthew G. Knepley PETSC_EXTERN PetscErrorCode DMSwarmCreateLocalVectorFromField(DM dm,const char fieldname[],Vec *vec) 416bbe8250bSMatthew G. Knepley { 417fb1bcc12SMatthew G. Knepley MPI_Comm comm = PETSC_COMM_SELF; 418bbe8250bSMatthew G. Knepley PetscErrorCode ierr; 419bbe8250bSMatthew G. Knepley 420fb1bcc12SMatthew G. Knepley PetscFunctionBegin; 421fb1bcc12SMatthew G. Knepley ierr = DMSwarmCreateVectorFromField_Private(dm, fieldname, comm, vec);CHKERRQ(ierr); 422fb1bcc12SMatthew G. Knepley PetscFunctionReturn(0); 423bbe8250bSMatthew G. Knepley } 424fb1bcc12SMatthew G. Knepley 425fb1bcc12SMatthew G. Knepley /*@C 426fb1bcc12SMatthew G. Knepley DMSwarmDestroyLocalVectorFromField - Destroys the Vec object which share the array associated with a given field 427fb1bcc12SMatthew G. Knepley 428d083f849SBarry Smith Collective on dm 429fb1bcc12SMatthew G. Knepley 430fb1bcc12SMatthew G. Knepley Input parameters: 43162741f57SDave May + dm - a DMSwarm 43262741f57SDave May - fieldname - the textual name given to a registered field 433fb1bcc12SMatthew G. Knepley 4348b8a3813SDave May Output parameter: 435fb1bcc12SMatthew G. Knepley . vec - the vector 436fb1bcc12SMatthew G. Knepley 437fb1bcc12SMatthew G. Knepley Level: beginner 438fb1bcc12SMatthew G. Knepley 4398b8a3813SDave May .seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmCreateLocalVectorFromField() 440fb1bcc12SMatthew G. Knepley @*/ 441fb1bcc12SMatthew G. Knepley PETSC_EXTERN PetscErrorCode DMSwarmDestroyLocalVectorFromField(DM dm,const char fieldname[],Vec *vec) 442fb1bcc12SMatthew G. Knepley { 443fb1bcc12SMatthew G. Knepley PetscErrorCode ierr; 444fb1bcc12SMatthew G. Knepley 445fb1bcc12SMatthew G. Knepley PetscFunctionBegin; 446fb1bcc12SMatthew G. Knepley ierr = DMSwarmDestroyVectorFromField_Private(dm, fieldname, vec);CHKERRQ(ierr); 447bbe8250bSMatthew G. Knepley PetscFunctionReturn(0); 448bbe8250bSMatthew G. Knepley } 449bbe8250bSMatthew G. Knepley 450b5bcf523SDave May /* 451b5bcf523SDave May PETSC_EXTERN PetscErrorCode DMSwarmCreateGlobalVectorFromFields(DM dm,const PetscInt nf,const char *fieldnames[],Vec *vec) 452b5bcf523SDave May { 453b5bcf523SDave May PetscFunctionReturn(0); 454b5bcf523SDave May } 455b5bcf523SDave May 456b5bcf523SDave May PETSC_EXTERN PetscErrorCode DMSwarmRestoreGlobalVectorFromFields(DM dm,Vec *vec) 457b5bcf523SDave May { 458b5bcf523SDave May PetscFunctionReturn(0); 459b5bcf523SDave May } 460b5bcf523SDave May */ 461b5bcf523SDave May 462d3a51819SDave May /*@C 463d3a51819SDave May DMSwarmInitializeFieldRegister - Initiates the registration of fields to a DMSwarm 464d3a51819SDave May 465d083f849SBarry Smith Collective on dm 466d3a51819SDave May 467d3a51819SDave May Input parameter: 468d3a51819SDave May . dm - a DMSwarm 469d3a51819SDave May 470d3a51819SDave May Level: beginner 471d3a51819SDave May 472d3a51819SDave May Notes: 4738b8a3813SDave May After all fields have been registered, you must call DMSwarmFinalizeFieldRegister(). 474d3a51819SDave May 475d3a51819SDave May .seealso: DMSwarmFinalizeFieldRegister(), DMSwarmRegisterPetscDatatypeField(), 476d3a51819SDave May DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField() 477d3a51819SDave May @*/ 4785f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmInitializeFieldRegister(DM dm) 4795f50eb2eSDave May { 4805f50eb2eSDave May DM_Swarm *swarm = (DM_Swarm *) dm->data; 4813454631fSDave May PetscErrorCode ierr; 4823454631fSDave May 483521f74f9SMatthew G. Knepley PetscFunctionBegin; 484cc651181SDave May if (!swarm->field_registration_initialized) { 4855f50eb2eSDave May swarm->field_registration_initialized = PETSC_TRUE; 486*43f984edSMatthew G. Knepley ierr = DMSwarmRegisterPetscDatatypeField(dm,DMSwarmField_pid,1,PETSC_INT64);CHKERRQ(ierr); /* unique identifer */ 487f0cdbbbaSDave May ierr = DMSwarmRegisterPetscDatatypeField(dm,DMSwarmField_rank,1,PETSC_INT);CHKERRQ(ierr); /* used for communication */ 488cc651181SDave May } 4895f50eb2eSDave May PetscFunctionReturn(0); 4905f50eb2eSDave May } 4915f50eb2eSDave May 492d3a51819SDave May /*@C 493d3a51819SDave May DMSwarmFinalizeFieldRegister - Finalizes the registration of fields to a DMSwarm 494d3a51819SDave May 495d083f849SBarry Smith Collective on dm 496d3a51819SDave May 497d3a51819SDave May Input parameter: 498d3a51819SDave May . dm - a DMSwarm 499d3a51819SDave May 500d3a51819SDave May Level: beginner 501d3a51819SDave May 502d3a51819SDave May Notes: 50362741f57SDave May After DMSwarmFinalizeFieldRegister() has been called, no new fields can be defined on the DMSwarm. 504d3a51819SDave May 505d3a51819SDave May .seealso: DMSwarmInitializeFieldRegister(), DMSwarmRegisterPetscDatatypeField(), 506d3a51819SDave May DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField() 507d3a51819SDave May @*/ 5085f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmFinalizeFieldRegister(DM dm) 5095f50eb2eSDave May { 5105f50eb2eSDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 5116845f8f5SDave May PetscErrorCode ierr; 5126845f8f5SDave May 513521f74f9SMatthew G. Knepley PetscFunctionBegin; 514f0cdbbbaSDave May if (!swarm->field_registration_finalized) { 51577048351SPatrick Sanan ierr = DMSwarmDataBucketFinalize(swarm->db);CHKERRQ(ierr); 516f0cdbbbaSDave May } 517f0cdbbbaSDave May swarm->field_registration_finalized = PETSC_TRUE; 5185f50eb2eSDave May PetscFunctionReturn(0); 5195f50eb2eSDave May } 5205f50eb2eSDave May 521d3a51819SDave May /*@C 522d3a51819SDave May DMSwarmSetLocalSizes - Sets the length of all registered fields on the DMSwarm 523d3a51819SDave May 524d3a51819SDave May Not collective 525d3a51819SDave May 526d3a51819SDave May Input parameters: 52762741f57SDave May + dm - a DMSwarm 528d3a51819SDave May . nlocal - the length of each registered field 52962741f57SDave May - buffer - the length of the buffer used to efficient dynamic re-sizing 530d3a51819SDave May 531d3a51819SDave May Level: beginner 532d3a51819SDave May 533d3a51819SDave May .seealso: DMSwarmGetLocalSize() 534d3a51819SDave May @*/ 5355f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmSetLocalSizes(DM dm,PetscInt nlocal,PetscInt buffer) 5365f50eb2eSDave May { 5375f50eb2eSDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 5386845f8f5SDave May PetscErrorCode ierr; 5395f50eb2eSDave May 540521f74f9SMatthew G. Knepley PetscFunctionBegin; 541f2b2bee7SDave May ierr = PetscLogEventBegin(DMSWARM_SetSizes,0,0,0,0);CHKERRQ(ierr); 54277048351SPatrick Sanan ierr = DMSwarmDataBucketSetSizes(swarm->db,nlocal,buffer);CHKERRQ(ierr); 543f2b2bee7SDave May ierr = PetscLogEventEnd(DMSWARM_SetSizes,0,0,0,0);CHKERRQ(ierr); 5445f50eb2eSDave May PetscFunctionReturn(0); 5455f50eb2eSDave May } 5465f50eb2eSDave May 547d3a51819SDave May /*@C 548d3a51819SDave May DMSwarmSetCellDM - Attachs a DM to a DMSwarm 549d3a51819SDave May 550d083f849SBarry Smith Collective on dm 551d3a51819SDave May 552d3a51819SDave May Input parameters: 55362741f57SDave May + dm - a DMSwarm 55462741f57SDave May - dmcell - the DM to attach to the DMSwarm 555d3a51819SDave May 556d3a51819SDave May Level: beginner 557d3a51819SDave May 558d3a51819SDave May Notes: 559d3a51819SDave May The attached DM (dmcell) will be queried for point location and 5608b8a3813SDave May neighbor MPI-rank information if DMSwarmMigrate() is called. 561d3a51819SDave May 5628b8a3813SDave May .seealso: DMSwarmSetType(), DMSwarmGetCellDM(), DMSwarmMigrate() 563d3a51819SDave May @*/ 564b16650c8SDave May PETSC_EXTERN PetscErrorCode DMSwarmSetCellDM(DM dm,DM dmcell) 565b16650c8SDave May { 566b16650c8SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 567521f74f9SMatthew G. Knepley 568521f74f9SMatthew G. Knepley PetscFunctionBegin; 569b16650c8SDave May swarm->dmcell = dmcell; 570b16650c8SDave May PetscFunctionReturn(0); 571b16650c8SDave May } 572b16650c8SDave May 573d3a51819SDave May /*@C 574d3a51819SDave May DMSwarmGetCellDM - Fetches the attached cell DM 575d3a51819SDave May 576d083f849SBarry Smith Collective on dm 577d3a51819SDave May 578d3a51819SDave May Input parameter: 579d3a51819SDave May . dm - a DMSwarm 580d3a51819SDave May 581d3a51819SDave May Output parameter: 582d3a51819SDave May . dmcell - the DM which was attached to the DMSwarm 583d3a51819SDave May 584d3a51819SDave May Level: beginner 585d3a51819SDave May 586d3a51819SDave May .seealso: DMSwarmSetCellDM() 587d3a51819SDave May @*/ 588fe39f135SDave May PETSC_EXTERN PetscErrorCode DMSwarmGetCellDM(DM dm,DM *dmcell) 589fe39f135SDave May { 590fe39f135SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 591521f74f9SMatthew G. Knepley 592521f74f9SMatthew G. Knepley PetscFunctionBegin; 593fe39f135SDave May *dmcell = swarm->dmcell; 594fe39f135SDave May PetscFunctionReturn(0); 595fe39f135SDave May } 596fe39f135SDave May 597d3a51819SDave May /*@C 598d3a51819SDave May DMSwarmGetLocalSize - Retrives the local length of fields registered 599d3a51819SDave May 600d3a51819SDave May Not collective 601d3a51819SDave May 602d3a51819SDave May Input parameter: 603d3a51819SDave May . dm - a DMSwarm 604d3a51819SDave May 605d3a51819SDave May Output parameter: 606d3a51819SDave May . nlocal - the length of each registered field 607d3a51819SDave May 608d3a51819SDave May Level: beginner 609d3a51819SDave May 6108b8a3813SDave May .seealso: DMSwarmGetSize(), DMSwarmSetLocalSizes() 611d3a51819SDave May @*/ 612dcf43ee8SDave May PETSC_EXTERN PetscErrorCode DMSwarmGetLocalSize(DM dm,PetscInt *nlocal) 613dcf43ee8SDave May { 614dcf43ee8SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 615dcf43ee8SDave May PetscErrorCode ierr; 616dcf43ee8SDave May 617521f74f9SMatthew G. Knepley PetscFunctionBegin; 61877048351SPatrick Sanan if (nlocal) {ierr = DMSwarmDataBucketGetSizes(swarm->db,nlocal,NULL,NULL);CHKERRQ(ierr);} 619dcf43ee8SDave May PetscFunctionReturn(0); 620dcf43ee8SDave May } 621dcf43ee8SDave May 622d3a51819SDave May /*@C 623d3a51819SDave May DMSwarmGetSize - Retrives the total length of fields registered 624d3a51819SDave May 625d083f849SBarry Smith Collective on dm 626d3a51819SDave May 627d3a51819SDave May Input parameter: 628d3a51819SDave May . dm - a DMSwarm 629d3a51819SDave May 630d3a51819SDave May Output parameter: 631d3a51819SDave May . n - the total length of each registered field 632d3a51819SDave May 633d3a51819SDave May Level: beginner 634d3a51819SDave May 635d3a51819SDave May Note: 636d3a51819SDave May This calls MPI_Allreduce upon each call (inefficient but safe) 637d3a51819SDave May 6388b8a3813SDave May .seealso: DMSwarmGetLocalSize(), DMSwarmSetLocalSizes() 639d3a51819SDave May @*/ 640dcf43ee8SDave May PETSC_EXTERN PetscErrorCode DMSwarmGetSize(DM dm,PetscInt *n) 641dcf43ee8SDave May { 642dcf43ee8SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 643dcf43ee8SDave May PetscErrorCode ierr; 644dcf43ee8SDave May PetscInt nlocal,ng; 645dcf43ee8SDave May 646521f74f9SMatthew G. Knepley PetscFunctionBegin; 64777048351SPatrick Sanan ierr = DMSwarmDataBucketGetSizes(swarm->db,&nlocal,NULL,NULL);CHKERRQ(ierr); 648dcf43ee8SDave May ierr = MPI_Allreduce(&nlocal,&ng,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr); 649dcf43ee8SDave May if (n) { *n = ng; } 650dcf43ee8SDave May PetscFunctionReturn(0); 651dcf43ee8SDave May } 652dcf43ee8SDave May 653d3a51819SDave May /*@C 6548b8a3813SDave May DMSwarmRegisterPetscDatatypeField - Register a field to a DMSwarm with a native PETSc data type 655d3a51819SDave May 656d083f849SBarry Smith Collective on dm 657d3a51819SDave May 658d3a51819SDave May Input parameters: 65962741f57SDave May + dm - a DMSwarm 660d3a51819SDave May . fieldname - the textual name to identify this field 661d3a51819SDave May . blocksize - the number of each data type 66262741f57SDave May - type - a valid PETSc data type (PETSC_CHAR, PETSC_SHORT, PETSC_INT, PETSC_FLOAT, PETSC_REAL, PETSC_LONG) 663d3a51819SDave May 664d3a51819SDave May Level: beginner 665d3a51819SDave May 666d3a51819SDave May Notes: 6678b8a3813SDave May The textual name for each registered field must be unique. 668d3a51819SDave May 669d3a51819SDave May .seealso: DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField() 670d3a51819SDave May @*/ 6715f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmRegisterPetscDatatypeField(DM dm,const char fieldname[],PetscInt blocksize,PetscDataType type) 672b62e03f8SDave May { 6732eac95f8SDave May PetscErrorCode ierr; 674b62e03f8SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 675b62e03f8SDave May size_t size; 676b62e03f8SDave May 677521f74f9SMatthew G. Knepley PetscFunctionBegin; 6785f50eb2eSDave May if (!swarm->field_registration_initialized) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMSwarmInitializeFieldRegister() first"); 6795f50eb2eSDave May if (swarm->field_registration_finalized) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Cannot register additional fields after calling DMSwarmFinalizeFieldRegister() first"); 6805f50eb2eSDave May 6815f50eb2eSDave May if (type == PETSC_OBJECT) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}"); 6825f50eb2eSDave May if (type == PETSC_FUNCTION) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}"); 6835f50eb2eSDave May if (type == PETSC_STRING) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}"); 6845f50eb2eSDave May if (type == PETSC_STRUCT) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}"); 6855f50eb2eSDave May if (type == PETSC_DATATYPE_UNKNOWN) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}"); 686b62e03f8SDave May 6872ddcf43eSMatthew G. Knepley ierr = PetscDataTypeGetSize(type, &size);CHKERRQ(ierr); 688b62e03f8SDave May /* Load a specific data type into data bucket, specifying textual name and its size in bytes */ 68977048351SPatrick Sanan ierr = DMSwarmDataBucketRegisterField(swarm->db,"DMSwarmRegisterPetscDatatypeField",fieldname,blocksize*size,NULL);CHKERRQ(ierr); 69052c3ed93SDave May { 69177048351SPatrick Sanan DMSwarmDataField gfield; 69252c3ed93SDave May 69377048351SPatrick Sanan ierr = DMSwarmDataBucketGetDMSwarmDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr); 69477048351SPatrick Sanan ierr = DMSwarmDataFieldSetBlockSize(gfield,blocksize);CHKERRQ(ierr); 69552c3ed93SDave May } 696b62e03f8SDave May swarm->db->field[swarm->db->nfields-1]->petsc_type = type; 697b62e03f8SDave May PetscFunctionReturn(0); 698b62e03f8SDave May } 699b62e03f8SDave May 700d3a51819SDave May /*@C 701d3a51819SDave May DMSwarmRegisterUserStructField - Register a user defined struct to a DMSwarm 702d3a51819SDave May 703d083f849SBarry Smith Collective on dm 704d3a51819SDave May 705d3a51819SDave May Input parameters: 70662741f57SDave May + dm - a DMSwarm 707d3a51819SDave May . fieldname - the textual name to identify this field 70862741f57SDave May - size - the size in bytes of the user struct of each data type 709d3a51819SDave May 710d3a51819SDave May Level: beginner 711d3a51819SDave May 712d3a51819SDave May Notes: 7138b8a3813SDave May The textual name for each registered field must be unique. 714d3a51819SDave May 715d3a51819SDave May .seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmRegisterUserDatatypeField() 716d3a51819SDave May @*/ 7175f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmRegisterUserStructField(DM dm,const char fieldname[],size_t size) 718b62e03f8SDave May { 7192eac95f8SDave May PetscErrorCode ierr; 720b62e03f8SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 721b62e03f8SDave May 722521f74f9SMatthew G. Knepley PetscFunctionBegin; 72377048351SPatrick Sanan ierr = DMSwarmDataBucketRegisterField(swarm->db,"DMSwarmRegisterUserStructField",fieldname,size,NULL);CHKERRQ(ierr); 724b62e03f8SDave May swarm->db->field[swarm->db->nfields-1]->petsc_type = PETSC_STRUCT ; 725b62e03f8SDave May PetscFunctionReturn(0); 726b62e03f8SDave May } 727b62e03f8SDave May 728d3a51819SDave May /*@C 729d3a51819SDave May DMSwarmRegisterUserDatatypeField - Register a user defined data type to a DMSwarm 730d3a51819SDave May 731d083f849SBarry Smith Collective on dm 732d3a51819SDave May 733d3a51819SDave May Input parameters: 73462741f57SDave May + dm - a DMSwarm 735d3a51819SDave May . fieldname - the textual name to identify this field 736d3a51819SDave May . size - the size in bytes of the user data type 73762741f57SDave May - blocksize - the number of each data type 738d3a51819SDave May 739d3a51819SDave May Level: beginner 740d3a51819SDave May 741d3a51819SDave May Notes: 7428b8a3813SDave May The textual name for each registered field must be unique. 743d3a51819SDave May 744d3a51819SDave May .seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField() 745d3a51819SDave May @*/ 746320740a0SDave May PETSC_EXTERN PetscErrorCode DMSwarmRegisterUserDatatypeField(DM dm,const char fieldname[],size_t size,PetscInt blocksize) 747b62e03f8SDave May { 748b62e03f8SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 7496845f8f5SDave May PetscErrorCode ierr; 750b62e03f8SDave May 751521f74f9SMatthew G. Knepley PetscFunctionBegin; 75277048351SPatrick Sanan ierr = DMSwarmDataBucketRegisterField(swarm->db,"DMSwarmRegisterUserDatatypeField",fieldname,blocksize*size,NULL);CHKERRQ(ierr); 753320740a0SDave May { 75477048351SPatrick Sanan DMSwarmDataField gfield; 755320740a0SDave May 75677048351SPatrick Sanan ierr = DMSwarmDataBucketGetDMSwarmDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr); 75777048351SPatrick Sanan ierr = DMSwarmDataFieldSetBlockSize(gfield,blocksize);CHKERRQ(ierr); 758320740a0SDave May } 759b62e03f8SDave May swarm->db->field[swarm->db->nfields-1]->petsc_type = PETSC_DATATYPE_UNKNOWN; 760b62e03f8SDave May PetscFunctionReturn(0); 761b62e03f8SDave May } 762b62e03f8SDave May 763d3a51819SDave May /*@C 764d3a51819SDave May DMSwarmGetField - Get access to the underlying array storing all entries associated with a registered field 765d3a51819SDave May 766d3a51819SDave May Not collective 767d3a51819SDave May 768d3a51819SDave May Input parameters: 76962741f57SDave May + dm - a DMSwarm 77062741f57SDave May - fieldname - the textual name to identify this field 771d3a51819SDave May 772d3a51819SDave May Output parameters: 77362741f57SDave May + blocksize - the number of each data type 774d3a51819SDave May . type - the data type 77562741f57SDave May - data - pointer to raw array 776d3a51819SDave May 777d3a51819SDave May Level: beginner 778d3a51819SDave May 779d3a51819SDave May Notes: 7808b8a3813SDave May The array must be returned using a matching call to DMSwarmRestoreField(). 781d3a51819SDave May 782d3a51819SDave May .seealso: DMSwarmRestoreField() 783d3a51819SDave May @*/ 7845f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmGetField(DM dm,const char fieldname[],PetscInt *blocksize,PetscDataType *type,void **data) 785b62e03f8SDave May { 786b62e03f8SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 78777048351SPatrick Sanan DMSwarmDataField gfield; 7882eac95f8SDave May PetscErrorCode ierr; 789b62e03f8SDave May 790521f74f9SMatthew G. Knepley PetscFunctionBegin; 7913454631fSDave May if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); } 79277048351SPatrick Sanan ierr = DMSwarmDataBucketGetDMSwarmDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr); 79377048351SPatrick Sanan ierr = DMSwarmDataFieldGetAccess(gfield);CHKERRQ(ierr); 79477048351SPatrick Sanan ierr = DMSwarmDataFieldGetEntries(gfield,data);CHKERRQ(ierr); 7951b1ea282SDave May if (blocksize) {*blocksize = gfield->bs; } 796b5bcf523SDave May if (type) { *type = gfield->petsc_type; } 797b62e03f8SDave May PetscFunctionReturn(0); 798b62e03f8SDave May } 799b62e03f8SDave May 800d3a51819SDave May /*@C 801d3a51819SDave May DMSwarmRestoreField - Restore access to the underlying array storing all entries associated with a registered field 802d3a51819SDave May 803d3a51819SDave May Not collective 804d3a51819SDave May 805d3a51819SDave May Input parameters: 80662741f57SDave May + dm - a DMSwarm 80762741f57SDave May - fieldname - the textual name to identify this field 808d3a51819SDave May 809d3a51819SDave May Output parameters: 81062741f57SDave May + blocksize - the number of each data type 811d3a51819SDave May . type - the data type 81262741f57SDave May - data - pointer to raw array 813d3a51819SDave May 814d3a51819SDave May Level: beginner 815d3a51819SDave May 816d3a51819SDave May Notes: 8178b8a3813SDave May The user must call DMSwarmGetField() prior to calling DMSwarmRestoreField(). 818d3a51819SDave May 819d3a51819SDave May .seealso: DMSwarmGetField() 820d3a51819SDave May @*/ 8215f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmRestoreField(DM dm,const char fieldname[],PetscInt *blocksize,PetscDataType *type,void **data) 822b62e03f8SDave May { 823b62e03f8SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 82477048351SPatrick Sanan DMSwarmDataField gfield; 8252eac95f8SDave May PetscErrorCode ierr; 826b62e03f8SDave May 827521f74f9SMatthew G. Knepley PetscFunctionBegin; 82877048351SPatrick Sanan ierr = DMSwarmDataBucketGetDMSwarmDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr); 82977048351SPatrick Sanan ierr = DMSwarmDataFieldRestoreAccess(gfield);CHKERRQ(ierr); 830b62e03f8SDave May if (data) *data = NULL; 831b62e03f8SDave May PetscFunctionReturn(0); 832b62e03f8SDave May } 833b62e03f8SDave May 834d3a51819SDave May /*@C 835d3a51819SDave May DMSwarmAddPoint - Add space for one new point in the DMSwarm 836d3a51819SDave May 837d3a51819SDave May Not collective 838d3a51819SDave May 839d3a51819SDave May Input parameter: 840d3a51819SDave May . dm - a DMSwarm 841d3a51819SDave May 842d3a51819SDave May Level: beginner 843d3a51819SDave May 844d3a51819SDave May Notes: 8458b8a3813SDave May The new point will have all fields initialized to zero. 846d3a51819SDave May 847d3a51819SDave May .seealso: DMSwarmAddNPoints() 848d3a51819SDave May @*/ 849cb1d1399SDave May PETSC_EXTERN PetscErrorCode DMSwarmAddPoint(DM dm) 850cb1d1399SDave May { 851cb1d1399SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 852cb1d1399SDave May PetscErrorCode ierr; 853cb1d1399SDave May 854521f74f9SMatthew G. Knepley PetscFunctionBegin; 8553454631fSDave May if (!swarm->issetup) {ierr = DMSetUp(dm);CHKERRQ(ierr);} 856f2b2bee7SDave May ierr = PetscLogEventBegin(DMSWARM_AddPoints,0,0,0,0);CHKERRQ(ierr); 85777048351SPatrick Sanan ierr = DMSwarmDataBucketAddPoint(swarm->db);CHKERRQ(ierr); 858f2b2bee7SDave May ierr = PetscLogEventEnd(DMSWARM_AddPoints,0,0,0,0);CHKERRQ(ierr); 859cb1d1399SDave May PetscFunctionReturn(0); 860cb1d1399SDave May } 861cb1d1399SDave May 862d3a51819SDave May /*@C 863d3a51819SDave May DMSwarmAddNPoints - Add space for a number of new points in the DMSwarm 864d3a51819SDave May 865d3a51819SDave May Not collective 866d3a51819SDave May 867d3a51819SDave May Input parameters: 86862741f57SDave May + dm - a DMSwarm 86962741f57SDave May - npoints - the number of new points to add 870d3a51819SDave May 871d3a51819SDave May Level: beginner 872d3a51819SDave May 873d3a51819SDave May Notes: 8748b8a3813SDave May The new point will have all fields initialized to zero. 875d3a51819SDave May 876d3a51819SDave May .seealso: DMSwarmAddPoint() 877d3a51819SDave May @*/ 878cb1d1399SDave May PETSC_EXTERN PetscErrorCode DMSwarmAddNPoints(DM dm,PetscInt npoints) 879cb1d1399SDave May { 880cb1d1399SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 881cb1d1399SDave May PetscErrorCode ierr; 882cb1d1399SDave May PetscInt nlocal; 883cb1d1399SDave May 884521f74f9SMatthew G. Knepley PetscFunctionBegin; 885f2b2bee7SDave May ierr = PetscLogEventBegin(DMSWARM_AddPoints,0,0,0,0);CHKERRQ(ierr); 88677048351SPatrick Sanan ierr = DMSwarmDataBucketGetSizes(swarm->db,&nlocal,NULL,NULL);CHKERRQ(ierr); 887cb1d1399SDave May nlocal = nlocal + npoints; 88877048351SPatrick Sanan ierr = DMSwarmDataBucketSetSizes(swarm->db,nlocal,DMSWARM_DATA_BUCKET_BUFFER_DEFAULT);CHKERRQ(ierr); 889f2b2bee7SDave May ierr = PetscLogEventEnd(DMSWARM_AddPoints,0,0,0,0);CHKERRQ(ierr); 890cb1d1399SDave May PetscFunctionReturn(0); 891cb1d1399SDave May } 892cb1d1399SDave May 893d3a51819SDave May /*@C 894d3a51819SDave May DMSwarmRemovePoint - Remove the last point from the DMSwarm 895d3a51819SDave May 896d3a51819SDave May Not collective 897d3a51819SDave May 898d3a51819SDave May Input parameter: 899d3a51819SDave May . dm - a DMSwarm 900d3a51819SDave May 901d3a51819SDave May Level: beginner 902d3a51819SDave May 903d3a51819SDave May .seealso: DMSwarmRemovePointAtIndex() 904d3a51819SDave May @*/ 905cb1d1399SDave May PETSC_EXTERN PetscErrorCode DMSwarmRemovePoint(DM dm) 906cb1d1399SDave May { 907cb1d1399SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 908cb1d1399SDave May PetscErrorCode ierr; 909cb1d1399SDave May 910521f74f9SMatthew G. Knepley PetscFunctionBegin; 911f2b2bee7SDave May ierr = PetscLogEventBegin(DMSWARM_RemovePoints,0,0,0,0);CHKERRQ(ierr); 91277048351SPatrick Sanan ierr = DMSwarmDataBucketRemovePoint(swarm->db);CHKERRQ(ierr); 913f2b2bee7SDave May ierr = PetscLogEventEnd(DMSWARM_RemovePoints,0,0,0,0);CHKERRQ(ierr); 914cb1d1399SDave May PetscFunctionReturn(0); 915cb1d1399SDave May } 916cb1d1399SDave May 917d3a51819SDave May /*@C 918d3a51819SDave May DMSwarmRemovePointAtIndex - Removes a specific point from the DMSwarm 919d3a51819SDave May 920d3a51819SDave May Not collective 921d3a51819SDave May 922d3a51819SDave May Input parameters: 92362741f57SDave May + dm - a DMSwarm 92462741f57SDave May - idx - index of point to remove 925d3a51819SDave May 926d3a51819SDave May Level: beginner 927d3a51819SDave May 928d3a51819SDave May .seealso: DMSwarmRemovePoint() 929d3a51819SDave May @*/ 930cb1d1399SDave May PETSC_EXTERN PetscErrorCode DMSwarmRemovePointAtIndex(DM dm,PetscInt idx) 931cb1d1399SDave May { 932cb1d1399SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 933cb1d1399SDave May PetscErrorCode ierr; 934cb1d1399SDave May 935521f74f9SMatthew G. Knepley PetscFunctionBegin; 936f2b2bee7SDave May ierr = PetscLogEventBegin(DMSWARM_RemovePoints,0,0,0,0);CHKERRQ(ierr); 93777048351SPatrick Sanan ierr = DMSwarmDataBucketRemovePointAtIndex(swarm->db,idx);CHKERRQ(ierr); 938f2b2bee7SDave May ierr = PetscLogEventEnd(DMSWARM_RemovePoints,0,0,0,0);CHKERRQ(ierr); 939cb1d1399SDave May PetscFunctionReturn(0); 940cb1d1399SDave May } 941b62e03f8SDave May 942ba4fc9c6SDave May /*@C 943ba4fc9c6SDave May DMSwarmCopyPoint - Copy point pj to point pi in the DMSwarm 944ba4fc9c6SDave May 945ba4fc9c6SDave May Not collective 946ba4fc9c6SDave May 947ba4fc9c6SDave May Input parameters: 948ba4fc9c6SDave May + dm - a DMSwarm 949ba4fc9c6SDave May . pi - the index of the point to copy 950ba4fc9c6SDave May - pj - the point index where the copy should be located 951ba4fc9c6SDave May 952ba4fc9c6SDave May Level: beginner 953ba4fc9c6SDave May 954ba4fc9c6SDave May .seealso: DMSwarmRemovePoint() 955ba4fc9c6SDave May @*/ 956ba4fc9c6SDave May PETSC_EXTERN PetscErrorCode DMSwarmCopyPoint(DM dm,PetscInt pi,PetscInt pj) 957ba4fc9c6SDave May { 958ba4fc9c6SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 959ba4fc9c6SDave May PetscErrorCode ierr; 960ba4fc9c6SDave May 961ba4fc9c6SDave May PetscFunctionBegin; 962ba4fc9c6SDave May if (!swarm->issetup) {ierr = DMSetUp(dm);CHKERRQ(ierr);} 96377048351SPatrick Sanan ierr = DMSwarmDataBucketCopyPoint(swarm->db,pi,swarm->db,pj);CHKERRQ(ierr); 964ba4fc9c6SDave May PetscFunctionReturn(0); 965ba4fc9c6SDave May } 966ba4fc9c6SDave May 967095059a4SDave May PetscErrorCode DMSwarmMigrate_Basic(DM dm,PetscBool remove_sent_points) 9683454631fSDave May { 969dcf43ee8SDave May PetscErrorCode ierr; 970521f74f9SMatthew G. Knepley 971521f74f9SMatthew G. Knepley PetscFunctionBegin; 972dcf43ee8SDave May ierr = DMSwarmMigrate_Push_Basic(dm,remove_sent_points);CHKERRQ(ierr); 9733454631fSDave May PetscFunctionReturn(0); 9743454631fSDave May } 9753454631fSDave May 976d3a51819SDave May /*@C 977d3a51819SDave May DMSwarmMigrate - Relocates points defined in the DMSwarm to other MPI-ranks 978d3a51819SDave May 979d083f849SBarry Smith Collective on dm 980d3a51819SDave May 981d3a51819SDave May Input parameters: 98262741f57SDave May + dm - the DMSwarm 98362741f57SDave May - remove_sent_points - flag indicating if sent points should be removed from the current MPI-rank 984d3a51819SDave May 985d3a51819SDave May Notes: 9868b8a3813SDave May The DM will be modified to accomodate received points. 9878b8a3813SDave May If remove_sent_points = PETSC_TRUE, any points that were sent will be removed from the DM. 9888b8a3813SDave May Different styles of migration are supported. See DMSwarmSetMigrateType(). 989d3a51819SDave May 990d3a51819SDave May Level: advanced 991d3a51819SDave May 992d3a51819SDave May .seealso: DMSwarmSetMigrateType() 993d3a51819SDave May @*/ 994095059a4SDave May PETSC_EXTERN PetscErrorCode DMSwarmMigrate(DM dm,PetscBool remove_sent_points) 9953454631fSDave May { 996f0cdbbbaSDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 9973454631fSDave May PetscErrorCode ierr; 998f0cdbbbaSDave May 999521f74f9SMatthew G. Knepley PetscFunctionBegin; 1000ed923d71SDave May ierr = PetscLogEventBegin(DMSWARM_Migrate,0,0,0,0);CHKERRQ(ierr); 1001f0cdbbbaSDave May switch (swarm->migrate_type) { 1002f0cdbbbaSDave May case DMSWARM_MIGRATE_BASIC: 1003095059a4SDave May ierr = DMSwarmMigrate_Basic(dm,remove_sent_points);CHKERRQ(ierr); 1004f0cdbbbaSDave May break; 1005f0cdbbbaSDave May case DMSWARM_MIGRATE_DMCELLNSCATTER: 1006f0cdbbbaSDave May ierr = DMSwarmMigrate_CellDMScatter(dm,remove_sent_points);CHKERRQ(ierr); 1007f0cdbbbaSDave May break; 1008f0cdbbbaSDave May case DMSWARM_MIGRATE_DMCELLEXACT: 1009f0cdbbbaSDave May SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_MIGRATE_DMCELLEXACT not implemented"); 1010f0cdbbbaSDave May break; 1011f0cdbbbaSDave May case DMSWARM_MIGRATE_USER: 1012f0cdbbbaSDave May SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_MIGRATE_USER not implemented"); 1013f0cdbbbaSDave May break; 1014f0cdbbbaSDave May default: 1015f0cdbbbaSDave May SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_MIGRATE type unknown"); 1016f0cdbbbaSDave May break; 1017f0cdbbbaSDave May } 1018ed923d71SDave May ierr = PetscLogEventEnd(DMSWARM_Migrate,0,0,0,0);CHKERRQ(ierr); 10193454631fSDave May PetscFunctionReturn(0); 10203454631fSDave May } 10213454631fSDave May 1022f0cdbbbaSDave May PetscErrorCode DMSwarmMigrate_GlobalToLocal_Basic(DM dm,PetscInt *globalsize); 1023f0cdbbbaSDave May 1024d3a51819SDave May /* 1025d3a51819SDave May DMSwarmCollectViewCreate 1026d3a51819SDave May 1027d3a51819SDave May * Applies a collection method and gathers point neighbour points into dm 1028d3a51819SDave May 1029d3a51819SDave May Notes: 10308b8a3813SDave May Users should call DMSwarmCollectViewDestroy() after 1031d3a51819SDave May they have finished computations associated with the collected points 1032d3a51819SDave May */ 1033d3a51819SDave May 1034d3a51819SDave May /*@C 1035d3a51819SDave May DMSwarmCollectViewCreate - Applies a collection method and gathers points 1036d3a51819SDave May in neighbour MPI-ranks into the DMSwarm 1037d3a51819SDave May 1038d083f849SBarry Smith Collective on dm 1039d3a51819SDave May 1040d3a51819SDave May Input parameter: 1041d3a51819SDave May . dm - the DMSwarm 1042d3a51819SDave May 1043d3a51819SDave May Notes: 1044d3a51819SDave May Users should call DMSwarmCollectViewDestroy() after 1045d3a51819SDave May they have finished computations associated with the collected points 10468b8a3813SDave May Different collect methods are supported. See DMSwarmSetCollectType(). 1047d3a51819SDave May 1048d3a51819SDave May Level: advanced 1049d3a51819SDave May 1050d3a51819SDave May .seealso: DMSwarmCollectViewDestroy(), DMSwarmSetCollectType() 1051d3a51819SDave May @*/ 1052fe39f135SDave May PETSC_EXTERN PetscErrorCode DMSwarmCollectViewCreate(DM dm) 10532712d1f2SDave May { 10542712d1f2SDave May PetscErrorCode ierr; 10552712d1f2SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 10562712d1f2SDave May PetscInt ng; 10572712d1f2SDave May 1058521f74f9SMatthew G. Knepley PetscFunctionBegin; 1059480eef7bSDave May if (swarm->collect_view_active) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"CollectView currently active"); 1060480eef7bSDave May ierr = DMSwarmGetLocalSize(dm,&ng);CHKERRQ(ierr); 1061480eef7bSDave May switch (swarm->collect_type) { 1062f0cdbbbaSDave May 1063480eef7bSDave May case DMSWARM_COLLECT_BASIC: 10642712d1f2SDave May ierr = DMSwarmMigrate_GlobalToLocal_Basic(dm,&ng);CHKERRQ(ierr); 1065480eef7bSDave May break; 1066480eef7bSDave May case DMSWARM_COLLECT_DMDABOUNDINGBOX: 1067f0cdbbbaSDave May SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_COLLECT_DMDABOUNDINGBOX not implemented"); 1068480eef7bSDave May break; 1069480eef7bSDave May case DMSWARM_COLLECT_GENERAL: 1070f0cdbbbaSDave May SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_COLLECT_GENERAL not implemented"); 1071480eef7bSDave May break; 1072480eef7bSDave May default: 1073f0cdbbbaSDave May SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_COLLECT type unknown"); 1074480eef7bSDave May break; 1075480eef7bSDave May } 1076480eef7bSDave May swarm->collect_view_active = PETSC_TRUE; 1077480eef7bSDave May swarm->collect_view_reset_nlocal = ng; 10782712d1f2SDave May PetscFunctionReturn(0); 10792712d1f2SDave May } 10802712d1f2SDave May 1081d3a51819SDave May /*@C 1082d3a51819SDave May DMSwarmCollectViewDestroy - Resets the DMSwarm to the size prior to calling DMSwarmCollectViewCreate() 1083d3a51819SDave May 1084d083f849SBarry Smith Collective on dm 1085d3a51819SDave May 1086d3a51819SDave May Input parameters: 1087d3a51819SDave May . dm - the DMSwarm 1088d3a51819SDave May 1089d3a51819SDave May Notes: 1090d3a51819SDave May Users should call DMSwarmCollectViewCreate() before this function is called. 1091d3a51819SDave May 1092d3a51819SDave May Level: advanced 1093d3a51819SDave May 1094d3a51819SDave May .seealso: DMSwarmCollectViewCreate(), DMSwarmSetCollectType() 1095d3a51819SDave May @*/ 1096fe39f135SDave May PETSC_EXTERN PetscErrorCode DMSwarmCollectViewDestroy(DM dm) 10972712d1f2SDave May { 10982712d1f2SDave May PetscErrorCode ierr; 10992712d1f2SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 11002712d1f2SDave May 1101521f74f9SMatthew G. Knepley PetscFunctionBegin; 1102480eef7bSDave May if (!swarm->collect_view_active) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"CollectView is currently not active"); 1103480eef7bSDave May ierr = DMSwarmSetLocalSizes(dm,swarm->collect_view_reset_nlocal,-1);CHKERRQ(ierr); 1104480eef7bSDave May swarm->collect_view_active = PETSC_FALSE; 11052712d1f2SDave May PetscFunctionReturn(0); 11062712d1f2SDave May } 11073454631fSDave May 1108f0cdbbbaSDave May PetscErrorCode DMSwarmSetUpPIC(DM dm) 1109f0cdbbbaSDave May { 1110f0cdbbbaSDave May PetscInt dim; 1111f0cdbbbaSDave May PetscErrorCode ierr; 1112f0cdbbbaSDave May 1113521f74f9SMatthew G. Knepley PetscFunctionBegin; 1114f0cdbbbaSDave May ierr = DMGetDimension(dm,&dim);CHKERRQ(ierr); 1115f0cdbbbaSDave May if (dim < 1) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Dimension must be 1,2,3 - found %D",dim); 1116f0cdbbbaSDave May if (dim > 3) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Dimension must be 1,2,3 - found %D",dim); 1117f0cdbbbaSDave May ierr = DMSwarmRegisterPetscDatatypeField(dm,DMSwarmPICField_coor,dim,PETSC_DOUBLE);CHKERRQ(ierr); 1118e2d107dbSDave May ierr = DMSwarmRegisterPetscDatatypeField(dm,DMSwarmPICField_cellid,1,PETSC_INT);CHKERRQ(ierr); 1119f0cdbbbaSDave May PetscFunctionReturn(0); 1120f0cdbbbaSDave May } 1121f0cdbbbaSDave May 1122d3a51819SDave May /*@C 1123d3a51819SDave May DMSwarmSetType - Set particular flavor of DMSwarm 1124d3a51819SDave May 1125d083f849SBarry Smith Collective on dm 1126d3a51819SDave May 1127d3a51819SDave May Input parameters: 112862741f57SDave May + dm - the DMSwarm 112962741f57SDave May - stype - the DMSwarm type (e.g. DMSWARM_PIC) 1130d3a51819SDave May 1131d3a51819SDave May Level: advanced 1132d3a51819SDave May 1133d3a51819SDave May .seealso: DMSwarmSetMigrateType(), DMSwarmSetCollectType() 1134d3a51819SDave May @*/ 1135f0cdbbbaSDave May PETSC_EXTERN PetscErrorCode DMSwarmSetType(DM dm,DMSwarmType stype) 1136f0cdbbbaSDave May { 1137f0cdbbbaSDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 1138f0cdbbbaSDave May PetscErrorCode ierr; 1139f0cdbbbaSDave May 1140521f74f9SMatthew G. Knepley PetscFunctionBegin; 1141f0cdbbbaSDave May swarm->swarm_type = stype; 1142f0cdbbbaSDave May if (swarm->swarm_type == DMSWARM_PIC) { 1143f0cdbbbaSDave May ierr = DMSwarmSetUpPIC(dm);CHKERRQ(ierr); 1144f0cdbbbaSDave May } 1145f0cdbbbaSDave May PetscFunctionReturn(0); 1146f0cdbbbaSDave May } 1147f0cdbbbaSDave May 11483454631fSDave May PetscErrorCode DMSetup_Swarm(DM dm) 11493454631fSDave May { 11503454631fSDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 11513454631fSDave May PetscErrorCode ierr; 11523454631fSDave May PetscMPIInt rank; 11533454631fSDave May PetscInt p,npoints,*rankval; 11543454631fSDave May 1155521f74f9SMatthew G. Knepley PetscFunctionBegin; 11563454631fSDave May if (swarm->issetup) PetscFunctionReturn(0); 11573454631fSDave May 11583454631fSDave May swarm->issetup = PETSC_TRUE; 11593454631fSDave May 1160f0cdbbbaSDave May if (swarm->swarm_type == DMSWARM_PIC) { 1161f0cdbbbaSDave May /* check dmcell exists */ 1162f0cdbbbaSDave May if (!swarm->dmcell) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSWARM_PIC requires you call DMSwarmSetCellDM"); 1163f0cdbbbaSDave May 1164f0cdbbbaSDave May if (swarm->dmcell->ops->locatepointssubdomain) { 1165f0cdbbbaSDave May /* check methods exists for exact ownership identificiation */ 116677b6ec44SMatthew G. Knepley ierr = PetscInfo(dm, "DMSWARM_PIC: Using method CellDM->ops->LocatePointsSubdomain\n");CHKERRQ(ierr); 1167f0cdbbbaSDave May swarm->migrate_type = DMSWARM_MIGRATE_DMCELLEXACT; 1168f0cdbbbaSDave May } else { 1169f0cdbbbaSDave May /* check methods exist for point location AND rank neighbor identification */ 1170f0cdbbbaSDave May if (swarm->dmcell->ops->locatepoints) { 117177b6ec44SMatthew G. Knepley ierr = PetscInfo(dm, "DMSWARM_PIC: Using method CellDM->LocatePoints\n");CHKERRQ(ierr); 1172f0cdbbbaSDave May } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSWARM_PIC requires the method CellDM->ops->locatepoints be defined"); 1173f0cdbbbaSDave May 1174f0cdbbbaSDave May if (swarm->dmcell->ops->getneighbors) { 117577b6ec44SMatthew G. Knepley ierr = PetscInfo(dm, "DMSWARM_PIC: Using method CellDM->GetNeigbors\n");CHKERRQ(ierr); 1176f0cdbbbaSDave May } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSWARM_PIC requires the method CellDM->ops->getneighbors be defined"); 1177f0cdbbbaSDave May 1178f0cdbbbaSDave May swarm->migrate_type = DMSWARM_MIGRATE_DMCELLNSCATTER; 1179f0cdbbbaSDave May } 1180f0cdbbbaSDave May } 1181f0cdbbbaSDave May 1182f0cdbbbaSDave May ierr = DMSwarmFinalizeFieldRegister(dm);CHKERRQ(ierr); 1183f0cdbbbaSDave May 11843454631fSDave May /* check some fields were registered */ 11853454631fSDave May if (swarm->db->nfields <= 2) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"At least one field user must be registered via DMSwarmRegisterXXX()"); 11863454631fSDave May 11873454631fSDave May /* check local sizes were set */ 11883454631fSDave May if (swarm->db->L == -1) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Local sizes must be set via DMSwarmSetLocalSizes()"); 11893454631fSDave May 11903454631fSDave May /* initialize values in pid and rank placeholders */ 11913454631fSDave May /* TODO: [pid - use MPI_Scan] */ 11923454631fSDave May ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm),&rank);CHKERRQ(ierr); 119377048351SPatrick Sanan ierr = DMSwarmDataBucketGetSizes(swarm->db,&npoints,NULL,NULL);CHKERRQ(ierr); 1194f0cdbbbaSDave May ierr = DMSwarmGetField(dm,DMSwarmField_rank,NULL,NULL,(void**)&rankval);CHKERRQ(ierr); 11953454631fSDave May for (p=0; p<npoints; p++) { 11963454631fSDave May rankval[p] = (PetscInt)rank; 11973454631fSDave May } 1198f0cdbbbaSDave May ierr = DMSwarmRestoreField(dm,DMSwarmField_rank,NULL,NULL,(void**)&rankval);CHKERRQ(ierr); 11993454631fSDave May PetscFunctionReturn(0); 12003454631fSDave May } 12013454631fSDave May 1202dc5f5ce9SDave May extern PetscErrorCode DMSwarmSortDestroy(DMSwarmSort *_ctx); 1203dc5f5ce9SDave May 120457795646SDave May PetscErrorCode DMDestroy_Swarm(DM dm) 120557795646SDave May { 120657795646SDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 120757795646SDave May PetscErrorCode ierr; 120857795646SDave May 120957795646SDave May PetscFunctionBegin; 121077048351SPatrick Sanan ierr = DMSwarmDataBucketDestroy(&swarm->db);CHKERRQ(ierr); 1211dc5f5ce9SDave May if (swarm->sort_context) { 1212dc5f5ce9SDave May ierr = DMSwarmSortDestroy(&swarm->sort_context);CHKERRQ(ierr); 1213dc5f5ce9SDave May } 121457795646SDave May ierr = PetscFree(swarm);CHKERRQ(ierr); 121557795646SDave May PetscFunctionReturn(0); 121657795646SDave May } 121757795646SDave May 1218a9ee3421SMatthew G. Knepley PetscErrorCode DMSwarmView_Draw(DM dm, PetscViewer viewer) 1219a9ee3421SMatthew G. Knepley { 1220a9ee3421SMatthew G. Knepley DM cdm; 1221a9ee3421SMatthew G. Knepley PetscDraw draw; 1222a9ee3421SMatthew G. Knepley PetscReal *coords, oldPause; 1223a9ee3421SMatthew G. Knepley PetscInt Np, p, bs; 1224a9ee3421SMatthew G. Knepley PetscErrorCode ierr; 1225a9ee3421SMatthew G. Knepley 1226a9ee3421SMatthew G. Knepley PetscFunctionBegin; 1227a9ee3421SMatthew G. Knepley ierr = PetscViewerDrawGetDraw(viewer, 0, &draw);CHKERRQ(ierr); 1228a9ee3421SMatthew G. Knepley ierr = DMSwarmGetCellDM(dm, &cdm);CHKERRQ(ierr); 1229a9ee3421SMatthew G. Knepley ierr = PetscDrawGetPause(draw, &oldPause);CHKERRQ(ierr); 1230a9ee3421SMatthew G. Knepley ierr = PetscDrawSetPause(draw, 0.0);CHKERRQ(ierr); 1231a9ee3421SMatthew G. Knepley ierr = DMView(cdm, viewer);CHKERRQ(ierr); 1232a9ee3421SMatthew G. Knepley ierr = PetscDrawSetPause(draw, oldPause);CHKERRQ(ierr); 1233a9ee3421SMatthew G. Knepley 1234a9ee3421SMatthew G. Knepley ierr = DMSwarmGetLocalSize(dm, &Np);CHKERRQ(ierr); 1235a9ee3421SMatthew G. Knepley ierr = DMSwarmGetField(dm, DMSwarmPICField_coor, &bs, NULL, (void **) &coords);CHKERRQ(ierr); 1236a9ee3421SMatthew G. Knepley for (p = 0; p < Np; ++p) { 1237a9ee3421SMatthew G. Knepley const PetscInt i = p*bs; 1238a9ee3421SMatthew G. Knepley 1239a9ee3421SMatthew G. Knepley ierr = PetscDrawEllipse(draw, coords[i], coords[i+1], 0.01, 0.01, PETSC_DRAW_BLUE);CHKERRQ(ierr); 1240a9ee3421SMatthew G. Knepley } 1241a9ee3421SMatthew G. Knepley ierr = DMSwarmRestoreField(dm, DMSwarmPICField_coor, &bs, NULL, (void **) &coords);CHKERRQ(ierr); 1242a9ee3421SMatthew G. Knepley ierr = PetscDrawFlush(draw);CHKERRQ(ierr); 1243a9ee3421SMatthew G. Knepley ierr = PetscDrawPause(draw);CHKERRQ(ierr); 1244a9ee3421SMatthew G. Knepley ierr = PetscDrawSave(draw);CHKERRQ(ierr); 1245a9ee3421SMatthew G. Knepley PetscFunctionReturn(0); 1246a9ee3421SMatthew G. Knepley } 1247a9ee3421SMatthew G. Knepley 12485f50eb2eSDave May PetscErrorCode DMView_Swarm(DM dm, PetscViewer viewer) 12495f50eb2eSDave May { 12505f50eb2eSDave May DM_Swarm *swarm = (DM_Swarm*)dm->data; 1251a9ee3421SMatthew G. Knepley PetscBool iascii,ibinary,ishdf5,isvtk,isdraw; 12525f50eb2eSDave May PetscErrorCode ierr; 12535f50eb2eSDave May 12545f50eb2eSDave May PetscFunctionBegin; 12555f50eb2eSDave May PetscValidHeaderSpecific(dm,DM_CLASSID,1); 12565f50eb2eSDave May PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 12575f50eb2eSDave May ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr); 12585f50eb2eSDave May ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY,&ibinary);CHKERRQ(ierr); 12595f50eb2eSDave May ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERVTK, &isvtk);CHKERRQ(ierr); 12605f50eb2eSDave May ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 1261a9ee3421SMatthew G. Knepley ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw);CHKERRQ(ierr); 12625f50eb2eSDave May if (iascii) { 126377048351SPatrick Sanan ierr = DMSwarmDataBucketView(PetscObjectComm((PetscObject)dm),swarm->db,NULL,DATABUCKET_VIEW_STDOUT);CHKERRQ(ierr); 1264298827fbSBarry Smith } else if (ibinary) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"NO Binary support"); 12655f50eb2eSDave May #if defined(PETSC_HAVE_HDF5) 1266298827fbSBarry Smith else if (ishdf5) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"NO HDF5 support"); 12675f50eb2eSDave May #else 1268298827fbSBarry Smith else if (ishdf5) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"HDF5 not supported. Please reconfigure using --download-hdf5"); 12695f50eb2eSDave May #endif 1270298827fbSBarry Smith else if (isvtk) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"NO VTK support"); 1271298827fbSBarry Smith else if (isdraw) { 1272a9ee3421SMatthew G. Knepley ierr = DMSwarmView_Draw(dm, viewer);CHKERRQ(ierr); 12735f50eb2eSDave May } 12745f50eb2eSDave May PetscFunctionReturn(0); 12755f50eb2eSDave May } 12765f50eb2eSDave May 1277d3a51819SDave May /*MC 1278d3a51819SDave May 1279d3a51819SDave May DMSWARM = "swarm" - A DM object used to represent arrays of data (fields) of arbitrary data type. 128062741f57SDave May This implementation was designed for particle methods in which the underlying 1281d3a51819SDave May data required to be represented is both (i) dynamic in length, (ii) and of arbitrary data type. 1282d3a51819SDave May 128362741f57SDave May User data can be represented by DMSwarm through a registering "fields". 128462741f57SDave May To register a field, the user must provide; 128562741f57SDave May (a) a unique name; 128662741f57SDave May (b) the data type (or size in bytes); 128762741f57SDave May (c) the block size of the data. 1288d3a51819SDave May 1289d3a51819SDave May For example, suppose the application requires a unique id, energy, momentum and density to be stored 1290c215a47eSMatthew Knepley on a set of particles. Then the following code could be used 1291d3a51819SDave May 129262741f57SDave May $ DMSwarmInitializeFieldRegister(dm) 129362741f57SDave May $ DMSwarmRegisterPetscDatatypeField(dm,"uid",1,PETSC_LONG); 129462741f57SDave May $ DMSwarmRegisterPetscDatatypeField(dm,"energy",1,PETSC_REAL); 129562741f57SDave May $ DMSwarmRegisterPetscDatatypeField(dm,"momentum",3,PETSC_REAL); 129662741f57SDave May $ DMSwarmRegisterPetscDatatypeField(dm,"density",1,PETSC_FLOAT); 129762741f57SDave May $ DMSwarmFinalizeFieldRegister(dm) 1298d3a51819SDave May 1299d3a51819SDave May The fields represented by DMSwarm are dynamic and can be re-sized at any time. 130062741f57SDave May The only restriction imposed by DMSwarm is that all fields contain the same number of points. 1301d3a51819SDave May 1302d3a51819SDave May To support particle methods, "migration" techniques are provided. These methods migrate data 1303d3a51819SDave May between MPI-ranks. 1304d3a51819SDave May 1305d3a51819SDave May DMSwarm supports the methods DMCreateGlobalVector() and DMCreateLocalVector(). 1306d3a51819SDave May As a DMSwarm may internally define and store values of different data types, 130762741f57SDave May before calling DMCreateGlobalVector() or DMCreateLocalVector(), the user must inform DMSwarm which 1308d3a51819SDave May fields should be used to define a Vec object via 1309d3a51819SDave May DMSwarmVectorDefineField() 1310c215a47eSMatthew Knepley The specified field can be changed at any time - thereby permitting vectors 1311c215a47eSMatthew Knepley compatible with different fields to be created. 1312d3a51819SDave May 131362741f57SDave May A dual representation of fields in the DMSwarm and a Vec object is permitted via 1314d3a51819SDave May DMSwarmCreateGlobalVectorFromField() 1315d3a51819SDave May Here the data defining the field in the DMSwarm is shared with a Vec. 1316d3a51819SDave May This is inherently unsafe if you alter the size of the field at any time between 1317d3a51819SDave May calls to DMSwarmCreateGlobalVectorFromField() and DMSwarmDestroyGlobalVectorFromField(). 1318cc651181SDave May If the local size of the DMSwarm does not match the local size of the global vector 1319cc651181SDave May when DMSwarmDestroyGlobalVectorFromField() is called, an error is thrown. 1320d3a51819SDave May 132162741f57SDave May Additional high-level support is provided for Particle-In-Cell methods. 132262741f57SDave May Please refer to the man page for DMSwarmSetType(). 132362741f57SDave May 1324d3a51819SDave May Level: beginner 1325d3a51819SDave May 1326d3a51819SDave May .seealso: DMType, DMCreate(), DMSetType() 1327d3a51819SDave May M*/ 132857795646SDave May PETSC_EXTERN PetscErrorCode DMCreate_Swarm(DM dm) 132957795646SDave May { 133057795646SDave May DM_Swarm *swarm; 133157795646SDave May PetscErrorCode ierr; 133257795646SDave May 133357795646SDave May PetscFunctionBegin; 133457795646SDave May PetscValidHeaderSpecific(dm, DM_CLASSID, 1); 133557795646SDave May ierr = PetscNewLog(dm,&swarm);CHKERRQ(ierr); 1336f0cdbbbaSDave May dm->data = swarm; 133757795646SDave May 133877048351SPatrick Sanan ierr = DMSwarmDataBucketCreate(&swarm->db);CHKERRQ(ierr); 1339f0cdbbbaSDave May ierr = DMSwarmInitializeFieldRegister(dm);CHKERRQ(ierr); 1340f0cdbbbaSDave May 1341b5bcf523SDave May swarm->vec_field_set = PETSC_FALSE; 13423454631fSDave May swarm->issetup = PETSC_FALSE; 1343480eef7bSDave May swarm->swarm_type = DMSWARM_BASIC; 1344480eef7bSDave May swarm->migrate_type = DMSWARM_MIGRATE_BASIC; 1345480eef7bSDave May swarm->collect_type = DMSWARM_COLLECT_BASIC; 134640c453e9SDave May swarm->migrate_error_on_missing_point = PETSC_FALSE; 1347b62e03f8SDave May 1348f0cdbbbaSDave May swarm->dmcell = NULL; 1349f0cdbbbaSDave May swarm->collect_view_active = PETSC_FALSE; 1350f0cdbbbaSDave May swarm->collect_view_reset_nlocal = -1; 135157795646SDave May 1352f0cdbbbaSDave May dm->dim = 0; 13535f50eb2eSDave May dm->ops->view = DMView_Swarm; 135457795646SDave May dm->ops->load = NULL; 135557795646SDave May dm->ops->setfromoptions = NULL; 135657795646SDave May dm->ops->clone = NULL; 13573454631fSDave May dm->ops->setup = DMSetup_Swarm; 13581bb6d2a8SBarry Smith dm->ops->createlocalsection = NULL; 135957795646SDave May dm->ops->createdefaultconstraints = NULL; 1360b5bcf523SDave May dm->ops->createglobalvector = DMCreateGlobalVector_Swarm; 1361b5bcf523SDave May dm->ops->createlocalvector = DMCreateLocalVector_Swarm; 136257795646SDave May dm->ops->getlocaltoglobalmapping = NULL; 136357795646SDave May dm->ops->createfieldis = NULL; 136457795646SDave May dm->ops->createcoordinatedm = NULL; 136557795646SDave May dm->ops->getcoloring = NULL; 136657795646SDave May dm->ops->creatematrix = NULL; 136757795646SDave May dm->ops->createinterpolation = NULL; 13685a84ad33SLisandro Dalcin dm->ops->createinjection = NULL; 136983c47955SMatthew G. Knepley dm->ops->createmassmatrix = DMCreateMassMatrix_Swarm; 137057795646SDave May dm->ops->refine = NULL; 137157795646SDave May dm->ops->coarsen = NULL; 137257795646SDave May dm->ops->refinehierarchy = NULL; 137357795646SDave May dm->ops->coarsenhierarchy = NULL; 137457795646SDave May dm->ops->globaltolocalbegin = NULL; 137557795646SDave May dm->ops->globaltolocalend = NULL; 137657795646SDave May dm->ops->localtoglobalbegin = NULL; 137757795646SDave May dm->ops->localtoglobalend = NULL; 137857795646SDave May dm->ops->destroy = DMDestroy_Swarm; 137957795646SDave May dm->ops->createsubdm = NULL; 138057795646SDave May dm->ops->getdimpoints = NULL; 138157795646SDave May dm->ops->locatepoints = NULL; 138257795646SDave May PetscFunctionReturn(0); 138357795646SDave May } 1384