xref: /petsc/src/dm/impls/swarm/swarm.c (revision d985efec992c7cb91ce1ebff70350a7a4472da39)
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;
1960643ed39SMatthew G. Knepley   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);
2300643ed39SMatthew G. Knepley   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;
24683c47955SMatthew G. Knepley 
2470643ed39SMatthew G. Knepley         /* PetscPrintf(PETSC_COMM_SELF, "\t[%D]DMSwarmComputeMassMatrix_Private: cell %D\n",rank,cell); */
24883c47955SMatthew G. Knepley         for (i = 0; i < numFIndices; ++i) {
2490643ed39SMatthew G. Knepley           key.i = findices[i]; /* global row (from Plex) */
2500643ed39SMatthew 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); */
251e8f14785SLisandro Dalcin           if (key.i >= 0) {
25283c47955SMatthew G. Knepley             /* Get indices for coarse elements */
25383c47955SMatthew G. Knepley             for (c = 0; c < numCIndices; ++c) {
2540643ed39SMatthew G. Knepley               key.j = cindices[c] + colStart; /* global cols (from Swarm) */
255e8f14785SLisandro Dalcin               if (key.j < 0) continue;
256e8f14785SLisandro Dalcin               ierr = PetscHSetIJQueryAdd(ht, key, &missing);CHKERRQ(ierr);
25783c47955SMatthew G. Knepley               if (missing) {
2580643ed39SMatthew G. Knepley                 /* PetscPrintf(PETSC_COMM_SELF, "\t\t\t[%D]DMSwarmComputeMassMatrix_Private: new key j (row,particle) = %D, i (col,vertices) = %D\n",rank,key.j,key.i); */
2590643ed39SMatthew G. Knepley                 if ((key.j >= colStart) && (key.j < colEnd)) ++dnz[key.i - rStart];
260e8f14785SLisandro Dalcin                 else                                         ++onz[key.i - rStart];
2610643ed39SMatthew G. Knepley               } else SETERRQ2(PetscObjectComm((PetscObject) dmf), PETSC_ERR_SUP, "Set new value at %D,%D", key.i, key.j);
26283c47955SMatthew G. Knepley             }
263fc7c92abSMatthew G. Knepley           }
264fc7c92abSMatthew G. Knepley         }
26583c47955SMatthew G. Knepley         ierr = PetscFree(cindices);CHKERRQ(ierr);
26683c47955SMatthew G. Knepley       }
26783c47955SMatthew G. Knepley       ierr = DMPlexRestoreClosureIndices(dmf, fsection, globalFSection, cell, &numFIndices, &findices, NULL);CHKERRQ(ierr);
26883c47955SMatthew G. Knepley     }
26983c47955SMatthew G. Knepley   }
270e8f14785SLisandro Dalcin   ierr = PetscHSetIJDestroy(&ht);CHKERRQ(ierr);
27183c47955SMatthew G. Knepley   ierr = MatXAIJSetPreallocation(mass, 1, dnz, onz, NULL, NULL);CHKERRQ(ierr);
27283c47955SMatthew G. Knepley   ierr = MatSetOption(mass, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_TRUE);CHKERRQ(ierr);
27383c47955SMatthew G. Knepley   ierr = PetscFree2(dnz, onz);CHKERRQ(ierr);
274*d985efecSMark Adams   ierr = PetscMalloc3(maxC*totDim, &elemMat, maxC, &rowIDXs, maxC*dim, &xi);CHKERRQ(ierr);
27583c47955SMatthew G. Knepley   for (field = 0; field < Nf; ++field) {
27683c47955SMatthew G. Knepley     PetscObject     obj;
2770643ed39SMatthew G. Knepley     PetscReal      *Bcoarse, *coords;
2780643ed39SMatthew G. Knepley     PetscInt        Nc, i;
27983c47955SMatthew G. Knepley 
28083c47955SMatthew G. Knepley     ierr = PetscDSGetDiscretization(prob, field, &obj);CHKERRQ(ierr);
2810643ed39SMatthew G. Knepley     ierr = PetscFEGetNumComponents((PetscFE) obj, &Nc);CHKERRQ(ierr);
2820643ed39SMatthew G. Knepley     if (Nc != 1) SETERRQ1(PetscObjectComm((PetscObject) dmf), PETSC_ERR_SUP, "Can only interpolate a scalar field from particles, Nc = %D", Nc);
2830643ed39SMatthew G. Knepley     ierr = DMSwarmGetField(dmc, DMSwarmPICField_coor, NULL, NULL, (void **) &coords);CHKERRQ(ierr);
28483c47955SMatthew G. Knepley     for (cell = cStart; cell < cEnd; ++cell) {
28583c47955SMatthew G. Knepley       PetscInt *findices  , *cindices;
28683c47955SMatthew G. Knepley       PetscInt  numFIndices, numCIndices;
2870643ed39SMatthew G. Knepley       PetscInt  p, c;
28883c47955SMatthew G. Knepley 
2890643ed39SMatthew G. Knepley       /* TODO: Use DMField instead of assuming affine */
29083c47955SMatthew G. Knepley       ierr = DMPlexComputeCellGeometryFEM(dmf, cell, NULL, v0, J, invJ, &detJ);CHKERRQ(ierr);
29183c47955SMatthew G. Knepley       ierr = DMPlexGetClosureIndices(dmf, fsection, globalFSection, cell, &numFIndices, &findices, NULL);CHKERRQ(ierr);
29283c47955SMatthew G. Knepley       ierr = DMSwarmSortGetPointsPerCell(dmc, cell, &numCIndices, &cindices);CHKERRQ(ierr);
2930643ed39SMatthew G. Knepley       for (p = 0; p < numCIndices; ++p) {
2940643ed39SMatthew G. Knepley         CoordinatesRealToRef(dim, dim, v0ref, v0, invJ, &coords[cindices[p]*dim], &xi[p*dim]);
2950643ed39SMatthew G. Knepley         /* PetscPrintf(PETSC_COMM_SELF,"[%D]DMSwarmComputeMassMatrix_Private: %2D.%D) coord = (%12.5e, %12.5e) element coord = (%12.5e, %12.5e) cindices[%D]=%D detJ=%12.5e\n",rank,cell,p,pxx[0],pxx[1],pxi[0],pxi[1],p,cindices[p],detJ); */
2960643ed39SMatthew G. Knepley       }
2970643ed39SMatthew G. Knepley       ierr = PetscFEGetTabulation((PetscFE) obj, numCIndices, xi, &Bcoarse, NULL, NULL);CHKERRQ(ierr);
29883c47955SMatthew G. Knepley       /* Get elemMat entries by multiplying by weight */
2990643ed39SMatthew G. Knepley       ierr = PetscMemzero(elemMat, numCIndices*totDim * sizeof(PetscScalar));CHKERRQ(ierr);
30083c47955SMatthew G. Knepley       for (i = 0; i < numFIndices; ++i) {
3010643ed39SMatthew G. Knepley         for (p = 0; p < numCIndices; ++p) {
3020643ed39SMatthew G. Knepley           for (c = 0; c < Nc; ++c) {
3030643ed39SMatthew G. Knepley             /* B[(p*pdim + i)*Nc + c] is the value at point p for basis function i and component c */
3040643ed39SMatthew G. Knepley             elemMat[i*numCIndices+p] += Bcoarse[(p*numFIndices + i)*Nc + c]*(useDeltaFunction ? 1.0 : detJ);
3050643ed39SMatthew 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]); */
30683c47955SMatthew G. Knepley           }
3070643ed39SMatthew G. Knepley         }
3080643ed39SMatthew G. Knepley       }
3090643ed39SMatthew G. Knepley       for (p = 0; p < numCIndices; ++p) rowIDXs[p] = cindices[p] + rStart;
31083c47955SMatthew G. Knepley       if (0) {ierr = DMPrintCellMatrix(cell, name, 1, numCIndices, elemMat);CHKERRQ(ierr);}
3110643ed39SMatthew G. Knepley       ierr = MatSetValues(mass, numFIndices, findices, numCIndices, rowIDXs, elemMat, ADD_VALUES);CHKERRQ(ierr);
31283c47955SMatthew G. Knepley       ierr = PetscFree(cindices);CHKERRQ(ierr);
31383c47955SMatthew G. Knepley       ierr = DMPlexRestoreClosureIndices(dmf, fsection, globalFSection, cell, &numFIndices, &findices, NULL);CHKERRQ(ierr);
3140643ed39SMatthew G. Knepley       ierr = PetscFERestoreTabulation((PetscFE) obj, numCIndices, xi, &Bcoarse, NULL, NULL);CHKERRQ(ierr);
31583c47955SMatthew G. Knepley     }
3160643ed39SMatthew G. Knepley     ierr = DMSwarmRestoreField(dmc, DMSwarmPICField_coor, NULL, NULL, (void **) &coords);CHKERRQ(ierr);
31783c47955SMatthew G. Knepley   }
3180643ed39SMatthew G. Knepley   ierr = PetscFree3(elemMat, rowIDXs, xi);CHKERRQ(ierr);
31983c47955SMatthew G. Knepley   ierr = DMSwarmSortRestoreAccess(dmc);CHKERRQ(ierr);
32083c47955SMatthew G. Knepley   ierr = PetscFree3(v0, J, invJ);CHKERRQ(ierr);
32183c47955SMatthew G. Knepley   ierr = MatAssemblyBegin(mass, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
32283c47955SMatthew G. Knepley   ierr = MatAssemblyEnd(mass, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
32383c47955SMatthew G. Knepley   PetscFunctionReturn(0);
32483c47955SMatthew G. Knepley }
32583c47955SMatthew G. Knepley 
3260643ed39SMatthew G. Knepley /* FEM rows, Particle cols */
32783c47955SMatthew G. Knepley static PetscErrorCode DMCreateMassMatrix_Swarm(DM dmCoarse, DM dmFine, Mat *mass)
32883c47955SMatthew G. Knepley {
329895a1698SMatthew G. Knepley   PetscSection   gsf;
33083c47955SMatthew G. Knepley   PetscInt       m, n;
33183c47955SMatthew G. Knepley   void          *ctx;
33283c47955SMatthew G. Knepley   PetscErrorCode ierr;
33383c47955SMatthew G. Knepley 
33483c47955SMatthew G. Knepley   PetscFunctionBegin;
33583c47955SMatthew G. Knepley   ierr = DMGetDefaultGlobalSection(dmFine, &gsf);CHKERRQ(ierr);
33683c47955SMatthew G. Knepley   ierr = PetscSectionGetConstrainedStorageSize(gsf, &m);CHKERRQ(ierr);
337895a1698SMatthew G. Knepley   ierr = DMSwarmGetLocalSize(dmCoarse, &n);CHKERRQ(ierr);
33883c47955SMatthew G. Knepley 
33983c47955SMatthew G. Knepley   ierr = MatCreate(PetscObjectComm((PetscObject) dmCoarse), mass);CHKERRQ(ierr);
34083c47955SMatthew G. Knepley   ierr = MatSetSizes(*mass, m, n, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr);
34183c47955SMatthew G. Knepley   ierr = MatSetType(*mass, dmCoarse->mattype);CHKERRQ(ierr);
34283c47955SMatthew G. Knepley   ierr = DMGetApplicationContext(dmFine, &ctx);CHKERRQ(ierr);
34383c47955SMatthew G. Knepley 
3440643ed39SMatthew G. Knepley   ierr = DMSwarmComputeMassMatrix_Private(dmCoarse, dmFine, *mass, PETSC_TRUE, ctx);CHKERRQ(ierr);
34583c47955SMatthew G. Knepley   ierr = MatViewFromOptions(*mass, NULL, "-mass_mat_view");CHKERRQ(ierr);
34683c47955SMatthew G. Knepley   PetscFunctionReturn(0);
34783c47955SMatthew G. Knepley }
34883c47955SMatthew G. Knepley 
349fb1bcc12SMatthew G. Knepley /*@C
350d3a51819SDave May    DMSwarmCreateGlobalVectorFromField - Creates a Vec object sharing the array associated with a given field
351d3a51819SDave May 
352d3a51819SDave May    Collective on DM
353d3a51819SDave May 
354d3a51819SDave May    Input parameters:
35562741f57SDave May +  dm - a DMSwarm
35662741f57SDave May -  fieldname - the textual name given to a registered field
357d3a51819SDave May 
3588b8a3813SDave May    Output parameter:
359d3a51819SDave May .  vec - the vector
360d3a51819SDave May 
361d3a51819SDave May    Level: beginner
362d3a51819SDave May 
3638b8a3813SDave May    Notes:
3648b8a3813SDave May    The vector must be returned using a matching call to DMSwarmDestroyGlobalVectorFromField().
3658b8a3813SDave May 
3668b8a3813SDave May .seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmDestroyGlobalVectorFromField()
367d3a51819SDave May @*/
368b5bcf523SDave May PETSC_EXTERN PetscErrorCode DMSwarmCreateGlobalVectorFromField(DM dm,const char fieldname[],Vec *vec)
369b5bcf523SDave May {
370fb1bcc12SMatthew G. Knepley   MPI_Comm       comm = PetscObjectComm((PetscObject) dm);
371b5bcf523SDave May   PetscErrorCode ierr;
372b5bcf523SDave May 
373fb1bcc12SMatthew G. Knepley   PetscFunctionBegin;
374fb1bcc12SMatthew G. Knepley   ierr = DMSwarmCreateVectorFromField_Private(dm, fieldname, comm, vec);CHKERRQ(ierr);
375b5bcf523SDave May   PetscFunctionReturn(0);
376b5bcf523SDave May }
377b5bcf523SDave May 
378d3a51819SDave May /*@C
379d3a51819SDave May    DMSwarmDestroyGlobalVectorFromField - Destroys the Vec object which share the array associated with a given field
380d3a51819SDave May 
381d3a51819SDave May    Collective on DM
382d3a51819SDave May 
383d3a51819SDave May    Input parameters:
38462741f57SDave May +  dm - a DMSwarm
38562741f57SDave May -  fieldname - the textual name given to a registered field
386d3a51819SDave May 
3878b8a3813SDave May    Output parameter:
388d3a51819SDave May .  vec - the vector
389d3a51819SDave May 
390d3a51819SDave May    Level: beginner
391d3a51819SDave May 
3928b8a3813SDave May .seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmCreateGlobalVectorFromField()
393d3a51819SDave May @*/
394b5bcf523SDave May PETSC_EXTERN PetscErrorCode DMSwarmDestroyGlobalVectorFromField(DM dm,const char fieldname[],Vec *vec)
395b5bcf523SDave May {
396b5bcf523SDave May   PetscErrorCode ierr;
397cc651181SDave May 
398fb1bcc12SMatthew G. Knepley   PetscFunctionBegin;
399fb1bcc12SMatthew G. Knepley   ierr = DMSwarmDestroyVectorFromField_Private(dm, fieldname, vec);CHKERRQ(ierr);
400b5bcf523SDave May   PetscFunctionReturn(0);
401b5bcf523SDave May }
402b5bcf523SDave May 
403fb1bcc12SMatthew G. Knepley /*@C
404fb1bcc12SMatthew G. Knepley    DMSwarmCreateLocalVectorFromField - Creates a Vec object sharing the array associated with a given field
405fb1bcc12SMatthew G. Knepley 
406fb1bcc12SMatthew G. Knepley    Collective on DM
407fb1bcc12SMatthew G. Knepley 
408fb1bcc12SMatthew G. Knepley    Input parameters:
40962741f57SDave May +  dm - a DMSwarm
41062741f57SDave May -  fieldname - the textual name given to a registered field
411fb1bcc12SMatthew G. Knepley 
4128b8a3813SDave May    Output parameter:
413fb1bcc12SMatthew G. Knepley .  vec - the vector
414fb1bcc12SMatthew G. Knepley 
415fb1bcc12SMatthew G. Knepley    Level: beginner
416fb1bcc12SMatthew G. Knepley 
4178b8a3813SDave May    Notes:
4188b8a3813SDave May    The vector must be returned using a matching call to DMSwarmDestroyLocalVectorFromField().
4198b8a3813SDave May 
4208b8a3813SDave May .seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmDestroyLocalVectorFromField()
421fb1bcc12SMatthew G. Knepley @*/
422fb1bcc12SMatthew G. Knepley PETSC_EXTERN PetscErrorCode DMSwarmCreateLocalVectorFromField(DM dm,const char fieldname[],Vec *vec)
423bbe8250bSMatthew G. Knepley {
424fb1bcc12SMatthew G. Knepley   MPI_Comm       comm = PETSC_COMM_SELF;
425bbe8250bSMatthew G. Knepley   PetscErrorCode ierr;
426bbe8250bSMatthew G. Knepley 
427fb1bcc12SMatthew G. Knepley   PetscFunctionBegin;
428fb1bcc12SMatthew G. Knepley   ierr = DMSwarmCreateVectorFromField_Private(dm, fieldname, comm, vec);CHKERRQ(ierr);
429fb1bcc12SMatthew G. Knepley   PetscFunctionReturn(0);
430bbe8250bSMatthew G. Knepley }
431fb1bcc12SMatthew G. Knepley 
432fb1bcc12SMatthew G. Knepley /*@C
433fb1bcc12SMatthew G. Knepley    DMSwarmDestroyLocalVectorFromField - Destroys the Vec object which share the array associated with a given field
434fb1bcc12SMatthew G. Knepley 
435fb1bcc12SMatthew G. Knepley    Collective on DM
436fb1bcc12SMatthew G. Knepley 
437fb1bcc12SMatthew G. Knepley    Input parameters:
43862741f57SDave May +  dm - a DMSwarm
43962741f57SDave May -  fieldname - the textual name given to a registered field
440fb1bcc12SMatthew G. Knepley 
4418b8a3813SDave May    Output parameter:
442fb1bcc12SMatthew G. Knepley .  vec - the vector
443fb1bcc12SMatthew G. Knepley 
444fb1bcc12SMatthew G. Knepley    Level: beginner
445fb1bcc12SMatthew G. Knepley 
4468b8a3813SDave May .seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmCreateLocalVectorFromField()
447fb1bcc12SMatthew G. Knepley @*/
448fb1bcc12SMatthew G. Knepley PETSC_EXTERN PetscErrorCode DMSwarmDestroyLocalVectorFromField(DM dm,const char fieldname[],Vec *vec)
449fb1bcc12SMatthew G. Knepley {
450fb1bcc12SMatthew G. Knepley   PetscErrorCode ierr;
451fb1bcc12SMatthew G. Knepley 
452fb1bcc12SMatthew G. Knepley   PetscFunctionBegin;
453fb1bcc12SMatthew G. Knepley   ierr = DMSwarmDestroyVectorFromField_Private(dm, fieldname, vec);CHKERRQ(ierr);
454bbe8250bSMatthew G. Knepley   PetscFunctionReturn(0);
455bbe8250bSMatthew G. Knepley }
456bbe8250bSMatthew G. Knepley 
457b5bcf523SDave May /*
458b5bcf523SDave May PETSC_EXTERN PetscErrorCode DMSwarmCreateGlobalVectorFromFields(DM dm,const PetscInt nf,const char *fieldnames[],Vec *vec)
459b5bcf523SDave May {
460b5bcf523SDave May   PetscFunctionReturn(0);
461b5bcf523SDave May }
462b5bcf523SDave May 
463b5bcf523SDave May PETSC_EXTERN PetscErrorCode DMSwarmRestoreGlobalVectorFromFields(DM dm,Vec *vec)
464b5bcf523SDave May {
465b5bcf523SDave May   PetscFunctionReturn(0);
466b5bcf523SDave May }
467b5bcf523SDave May */
468b5bcf523SDave May 
469d3a51819SDave May /*@C
470d3a51819SDave May    DMSwarmInitializeFieldRegister - Initiates the registration of fields to a DMSwarm
471d3a51819SDave May 
472d3a51819SDave May    Collective on DM
473d3a51819SDave May 
474d3a51819SDave May    Input parameter:
475d3a51819SDave May .  dm - a DMSwarm
476d3a51819SDave May 
477d3a51819SDave May    Level: beginner
478d3a51819SDave May 
479d3a51819SDave May    Notes:
4808b8a3813SDave May    After all fields have been registered, you must call DMSwarmFinalizeFieldRegister().
481d3a51819SDave May 
482d3a51819SDave May .seealso: DMSwarmFinalizeFieldRegister(), DMSwarmRegisterPetscDatatypeField(),
483d3a51819SDave May  DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField()
484d3a51819SDave May @*/
4855f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmInitializeFieldRegister(DM dm)
4865f50eb2eSDave May {
4875f50eb2eSDave May   DM_Swarm      *swarm = (DM_Swarm *) dm->data;
4883454631fSDave May   PetscErrorCode ierr;
4893454631fSDave May 
490521f74f9SMatthew G. Knepley   PetscFunctionBegin;
491cc651181SDave May   if (!swarm->field_registration_initialized) {
4925f50eb2eSDave May     swarm->field_registration_initialized = PETSC_TRUE;
493f0cdbbbaSDave May     ierr = DMSwarmRegisterPetscDatatypeField(dm,DMSwarmField_pid,1,PETSC_LONG);CHKERRQ(ierr); /* unique identifer */
494f0cdbbbaSDave May     ierr = DMSwarmRegisterPetscDatatypeField(dm,DMSwarmField_rank,1,PETSC_INT);CHKERRQ(ierr); /* used for communication */
495cc651181SDave May   }
4965f50eb2eSDave May   PetscFunctionReturn(0);
4975f50eb2eSDave May }
4985f50eb2eSDave May 
499d3a51819SDave May /*@C
500d3a51819SDave May    DMSwarmFinalizeFieldRegister - Finalizes the registration of fields to a DMSwarm
501d3a51819SDave May 
502d3a51819SDave May    Collective on DM
503d3a51819SDave May 
504d3a51819SDave May    Input parameter:
505d3a51819SDave May .  dm - a DMSwarm
506d3a51819SDave May 
507d3a51819SDave May    Level: beginner
508d3a51819SDave May 
509d3a51819SDave May    Notes:
51062741f57SDave May    After DMSwarmFinalizeFieldRegister() has been called, no new fields can be defined on the DMSwarm.
511d3a51819SDave May 
512d3a51819SDave May .seealso: DMSwarmInitializeFieldRegister(), DMSwarmRegisterPetscDatatypeField(),
513d3a51819SDave May  DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField()
514d3a51819SDave May @*/
5155f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmFinalizeFieldRegister(DM dm)
5165f50eb2eSDave May {
5175f50eb2eSDave May   DM_Swarm       *swarm = (DM_Swarm*)dm->data;
5186845f8f5SDave May   PetscErrorCode ierr;
5196845f8f5SDave May 
520521f74f9SMatthew G. Knepley   PetscFunctionBegin;
521f0cdbbbaSDave May   if (!swarm->field_registration_finalized) {
52277048351SPatrick Sanan     ierr = DMSwarmDataBucketFinalize(swarm->db);CHKERRQ(ierr);
523f0cdbbbaSDave May   }
524f0cdbbbaSDave May   swarm->field_registration_finalized = PETSC_TRUE;
5255f50eb2eSDave May   PetscFunctionReturn(0);
5265f50eb2eSDave May }
5275f50eb2eSDave May 
528d3a51819SDave May /*@C
529d3a51819SDave May    DMSwarmSetLocalSizes - Sets the length of all registered fields on the DMSwarm
530d3a51819SDave May 
531d3a51819SDave May    Not collective
532d3a51819SDave May 
533d3a51819SDave May    Input parameters:
53462741f57SDave May +  dm - a DMSwarm
535d3a51819SDave May .  nlocal - the length of each registered field
53662741f57SDave May -  buffer - the length of the buffer used to efficient dynamic re-sizing
537d3a51819SDave May 
538d3a51819SDave May    Level: beginner
539d3a51819SDave May 
540d3a51819SDave May .seealso: DMSwarmGetLocalSize()
541d3a51819SDave May @*/
5425f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmSetLocalSizes(DM dm,PetscInt nlocal,PetscInt buffer)
5435f50eb2eSDave May {
5445f50eb2eSDave May   DM_Swarm       *swarm = (DM_Swarm*)dm->data;
5456845f8f5SDave May   PetscErrorCode ierr;
5465f50eb2eSDave May 
547521f74f9SMatthew G. Knepley   PetscFunctionBegin;
548f2b2bee7SDave May   ierr = PetscLogEventBegin(DMSWARM_SetSizes,0,0,0,0);CHKERRQ(ierr);
54977048351SPatrick Sanan   ierr = DMSwarmDataBucketSetSizes(swarm->db,nlocal,buffer);CHKERRQ(ierr);
550f2b2bee7SDave May   ierr = PetscLogEventEnd(DMSWARM_SetSizes,0,0,0,0);CHKERRQ(ierr);
5515f50eb2eSDave May   PetscFunctionReturn(0);
5525f50eb2eSDave May }
5535f50eb2eSDave May 
554d3a51819SDave May /*@C
555d3a51819SDave May    DMSwarmSetCellDM - Attachs a DM to a DMSwarm
556d3a51819SDave May 
557d3a51819SDave May    Collective on DM
558d3a51819SDave May 
559d3a51819SDave May    Input parameters:
56062741f57SDave May +  dm - a DMSwarm
56162741f57SDave May -  dmcell - the DM to attach to the DMSwarm
562d3a51819SDave May 
563d3a51819SDave May    Level: beginner
564d3a51819SDave May 
565d3a51819SDave May    Notes:
566d3a51819SDave May    The attached DM (dmcell) will be queried for point location and
5678b8a3813SDave May    neighbor MPI-rank information if DMSwarmMigrate() is called.
568d3a51819SDave May 
5698b8a3813SDave May .seealso: DMSwarmSetType(), DMSwarmGetCellDM(), DMSwarmMigrate()
570d3a51819SDave May @*/
571b16650c8SDave May PETSC_EXTERN PetscErrorCode DMSwarmSetCellDM(DM dm,DM dmcell)
572b16650c8SDave May {
573b16650c8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
574521f74f9SMatthew G. Knepley 
575521f74f9SMatthew G. Knepley   PetscFunctionBegin;
576b16650c8SDave May   swarm->dmcell = dmcell;
577b16650c8SDave May   PetscFunctionReturn(0);
578b16650c8SDave May }
579b16650c8SDave May 
580d3a51819SDave May /*@C
581d3a51819SDave May    DMSwarmGetCellDM - Fetches the attached cell DM
582d3a51819SDave May 
583d3a51819SDave May    Collective on DM
584d3a51819SDave May 
585d3a51819SDave May    Input parameter:
586d3a51819SDave May .  dm - a DMSwarm
587d3a51819SDave May 
588d3a51819SDave May    Output parameter:
589d3a51819SDave May .  dmcell - the DM which was attached to the DMSwarm
590d3a51819SDave May 
591d3a51819SDave May    Level: beginner
592d3a51819SDave May 
593d3a51819SDave May .seealso: DMSwarmSetCellDM()
594d3a51819SDave May @*/
595fe39f135SDave May PETSC_EXTERN PetscErrorCode DMSwarmGetCellDM(DM dm,DM *dmcell)
596fe39f135SDave May {
597fe39f135SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
598521f74f9SMatthew G. Knepley 
599521f74f9SMatthew G. Knepley   PetscFunctionBegin;
600fe39f135SDave May   *dmcell = swarm->dmcell;
601fe39f135SDave May   PetscFunctionReturn(0);
602fe39f135SDave May }
603fe39f135SDave May 
604d3a51819SDave May /*@C
605d3a51819SDave May    DMSwarmGetLocalSize - Retrives the local length of fields registered
606d3a51819SDave May 
607d3a51819SDave May    Not collective
608d3a51819SDave May 
609d3a51819SDave May    Input parameter:
610d3a51819SDave May .  dm - a DMSwarm
611d3a51819SDave May 
612d3a51819SDave May    Output parameter:
613d3a51819SDave May .  nlocal - the length of each registered field
614d3a51819SDave May 
615d3a51819SDave May    Level: beginner
616d3a51819SDave May 
6178b8a3813SDave May .seealso: DMSwarmGetSize(), DMSwarmSetLocalSizes()
618d3a51819SDave May @*/
619dcf43ee8SDave May PETSC_EXTERN PetscErrorCode DMSwarmGetLocalSize(DM dm,PetscInt *nlocal)
620dcf43ee8SDave May {
621dcf43ee8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
622dcf43ee8SDave May   PetscErrorCode ierr;
623dcf43ee8SDave May 
624521f74f9SMatthew G. Knepley   PetscFunctionBegin;
62577048351SPatrick Sanan   if (nlocal) {ierr = DMSwarmDataBucketGetSizes(swarm->db,nlocal,NULL,NULL);CHKERRQ(ierr);}
626dcf43ee8SDave May   PetscFunctionReturn(0);
627dcf43ee8SDave May }
628dcf43ee8SDave May 
629d3a51819SDave May /*@C
630d3a51819SDave May    DMSwarmGetSize - Retrives the total length of fields registered
631d3a51819SDave May 
632d3a51819SDave May    Collective on DM
633d3a51819SDave May 
634d3a51819SDave May    Input parameter:
635d3a51819SDave May .  dm - a DMSwarm
636d3a51819SDave May 
637d3a51819SDave May    Output parameter:
638d3a51819SDave May .  n - the total length of each registered field
639d3a51819SDave May 
640d3a51819SDave May    Level: beginner
641d3a51819SDave May 
642d3a51819SDave May    Note:
643d3a51819SDave May    This calls MPI_Allreduce upon each call (inefficient but safe)
644d3a51819SDave May 
6458b8a3813SDave May .seealso: DMSwarmGetLocalSize(), DMSwarmSetLocalSizes()
646d3a51819SDave May @*/
647dcf43ee8SDave May PETSC_EXTERN PetscErrorCode DMSwarmGetSize(DM dm,PetscInt *n)
648dcf43ee8SDave May {
649dcf43ee8SDave May   DM_Swarm       *swarm = (DM_Swarm*)dm->data;
650dcf43ee8SDave May   PetscErrorCode ierr;
651dcf43ee8SDave May   PetscInt       nlocal,ng;
652dcf43ee8SDave May 
653521f74f9SMatthew G. Knepley   PetscFunctionBegin;
65477048351SPatrick Sanan   ierr = DMSwarmDataBucketGetSizes(swarm->db,&nlocal,NULL,NULL);CHKERRQ(ierr);
655dcf43ee8SDave May   ierr = MPI_Allreduce(&nlocal,&ng,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr);
656dcf43ee8SDave May   if (n) { *n = ng; }
657dcf43ee8SDave May   PetscFunctionReturn(0);
658dcf43ee8SDave May }
659dcf43ee8SDave May 
660d3a51819SDave May /*@C
6618b8a3813SDave May    DMSwarmRegisterPetscDatatypeField - Register a field to a DMSwarm with a native PETSc data type
662d3a51819SDave May 
663d3a51819SDave May    Collective on DM
664d3a51819SDave May 
665d3a51819SDave May    Input parameters:
66662741f57SDave May +  dm - a DMSwarm
667d3a51819SDave May .  fieldname - the textual name to identify this field
668d3a51819SDave May .  blocksize - the number of each data type
66962741f57SDave May -  type - a valid PETSc data type (PETSC_CHAR, PETSC_SHORT, PETSC_INT, PETSC_FLOAT, PETSC_REAL, PETSC_LONG)
670d3a51819SDave May 
671d3a51819SDave May    Level: beginner
672d3a51819SDave May 
673d3a51819SDave May    Notes:
6748b8a3813SDave May    The textual name for each registered field must be unique.
675d3a51819SDave May 
676d3a51819SDave May .seealso: DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField()
677d3a51819SDave May @*/
6785f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmRegisterPetscDatatypeField(DM dm,const char fieldname[],PetscInt blocksize,PetscDataType type)
679b62e03f8SDave May {
6802eac95f8SDave May   PetscErrorCode ierr;
681b62e03f8SDave May   DM_Swarm       *swarm = (DM_Swarm*)dm->data;
682b62e03f8SDave May   size_t         size;
683b62e03f8SDave May 
684521f74f9SMatthew G. Knepley   PetscFunctionBegin;
6855f50eb2eSDave May   if (!swarm->field_registration_initialized) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMSwarmInitializeFieldRegister() first");
6865f50eb2eSDave May   if (swarm->field_registration_finalized) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Cannot register additional fields after calling DMSwarmFinalizeFieldRegister() first");
6875f50eb2eSDave May 
6885f50eb2eSDave May   if (type == PETSC_OBJECT) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
6895f50eb2eSDave May   if (type == PETSC_FUNCTION) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
6905f50eb2eSDave May   if (type == PETSC_STRING) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
6915f50eb2eSDave May   if (type == PETSC_STRUCT) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
6925f50eb2eSDave May   if (type == PETSC_DATATYPE_UNKNOWN) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
693b62e03f8SDave May 
6942ddcf43eSMatthew G. Knepley   ierr = PetscDataTypeGetSize(type, &size);CHKERRQ(ierr);
695b62e03f8SDave May   /* Load a specific data type into data bucket, specifying textual name and its size in bytes */
69677048351SPatrick Sanan   ierr = DMSwarmDataBucketRegisterField(swarm->db,"DMSwarmRegisterPetscDatatypeField",fieldname,blocksize*size,NULL);CHKERRQ(ierr);
69752c3ed93SDave May   {
69877048351SPatrick Sanan     DMSwarmDataField gfield;
69952c3ed93SDave May 
70077048351SPatrick Sanan     ierr = DMSwarmDataBucketGetDMSwarmDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr);
70177048351SPatrick Sanan     ierr = DMSwarmDataFieldSetBlockSize(gfield,blocksize);CHKERRQ(ierr);
70252c3ed93SDave May   }
703b62e03f8SDave May   swarm->db->field[swarm->db->nfields-1]->petsc_type = type;
704b62e03f8SDave May   PetscFunctionReturn(0);
705b62e03f8SDave May }
706b62e03f8SDave May 
707d3a51819SDave May /*@C
708d3a51819SDave May    DMSwarmRegisterUserStructField - Register a user defined struct to a DMSwarm
709d3a51819SDave May 
710d3a51819SDave May    Collective on DM
711d3a51819SDave May 
712d3a51819SDave May    Input parameters:
71362741f57SDave May +  dm - a DMSwarm
714d3a51819SDave May .  fieldname - the textual name to identify this field
71562741f57SDave May -  size - the size in bytes of the user struct of each data type
716d3a51819SDave May 
717d3a51819SDave May    Level: beginner
718d3a51819SDave May 
719d3a51819SDave May    Notes:
7208b8a3813SDave May    The textual name for each registered field must be unique.
721d3a51819SDave May 
722d3a51819SDave May .seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmRegisterUserDatatypeField()
723d3a51819SDave May @*/
7245f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmRegisterUserStructField(DM dm,const char fieldname[],size_t size)
725b62e03f8SDave May {
7262eac95f8SDave May   PetscErrorCode ierr;
727b62e03f8SDave May   DM_Swarm       *swarm = (DM_Swarm*)dm->data;
728b62e03f8SDave May 
729521f74f9SMatthew G. Knepley   PetscFunctionBegin;
73077048351SPatrick Sanan   ierr = DMSwarmDataBucketRegisterField(swarm->db,"DMSwarmRegisterUserStructField",fieldname,size,NULL);CHKERRQ(ierr);
731b62e03f8SDave May   swarm->db->field[swarm->db->nfields-1]->petsc_type = PETSC_STRUCT ;
732b62e03f8SDave May   PetscFunctionReturn(0);
733b62e03f8SDave May }
734b62e03f8SDave May 
735d3a51819SDave May /*@C
736d3a51819SDave May    DMSwarmRegisterUserDatatypeField - Register a user defined data type to a DMSwarm
737d3a51819SDave May 
738d3a51819SDave May    Collective on DM
739d3a51819SDave May 
740d3a51819SDave May    Input parameters:
74162741f57SDave May +  dm - a DMSwarm
742d3a51819SDave May .  fieldname - the textual name to identify this field
743d3a51819SDave May .  size - the size in bytes of the user data type
74462741f57SDave May -  blocksize - the number of each data type
745d3a51819SDave May 
746d3a51819SDave May    Level: beginner
747d3a51819SDave May 
748d3a51819SDave May    Notes:
7498b8a3813SDave May    The textual name for each registered field must be unique.
750d3a51819SDave May 
751d3a51819SDave May .seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField()
752d3a51819SDave May @*/
753320740a0SDave May PETSC_EXTERN PetscErrorCode DMSwarmRegisterUserDatatypeField(DM dm,const char fieldname[],size_t size,PetscInt blocksize)
754b62e03f8SDave May {
755b62e03f8SDave May   DM_Swarm       *swarm = (DM_Swarm*)dm->data;
7566845f8f5SDave May   PetscErrorCode ierr;
757b62e03f8SDave May 
758521f74f9SMatthew G. Knepley   PetscFunctionBegin;
75977048351SPatrick Sanan   ierr = DMSwarmDataBucketRegisterField(swarm->db,"DMSwarmRegisterUserDatatypeField",fieldname,blocksize*size,NULL);CHKERRQ(ierr);
760320740a0SDave May   {
76177048351SPatrick Sanan     DMSwarmDataField gfield;
762320740a0SDave May 
76377048351SPatrick Sanan     ierr = DMSwarmDataBucketGetDMSwarmDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr);
76477048351SPatrick Sanan     ierr = DMSwarmDataFieldSetBlockSize(gfield,blocksize);CHKERRQ(ierr);
765320740a0SDave May   }
766b62e03f8SDave May   swarm->db->field[swarm->db->nfields-1]->petsc_type = PETSC_DATATYPE_UNKNOWN;
767b62e03f8SDave May   PetscFunctionReturn(0);
768b62e03f8SDave May }
769b62e03f8SDave May 
770d3a51819SDave May /*@C
771d3a51819SDave May    DMSwarmGetField - Get access to the underlying array storing all entries associated with a registered field
772d3a51819SDave May 
773d3a51819SDave May    Not collective
774d3a51819SDave May 
775d3a51819SDave May    Input parameters:
77662741f57SDave May +  dm - a DMSwarm
77762741f57SDave May -  fieldname - the textual name to identify this field
778d3a51819SDave May 
779d3a51819SDave May    Output parameters:
78062741f57SDave May +  blocksize - the number of each data type
781d3a51819SDave May .  type - the data type
78262741f57SDave May -  data - pointer to raw array
783d3a51819SDave May 
784d3a51819SDave May    Level: beginner
785d3a51819SDave May 
786d3a51819SDave May    Notes:
7878b8a3813SDave May    The array must be returned using a matching call to DMSwarmRestoreField().
788d3a51819SDave May 
789d3a51819SDave May .seealso: DMSwarmRestoreField()
790d3a51819SDave May @*/
7915f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmGetField(DM dm,const char fieldname[],PetscInt *blocksize,PetscDataType *type,void **data)
792b62e03f8SDave May {
793b62e03f8SDave May   DM_Swarm         *swarm = (DM_Swarm*)dm->data;
79477048351SPatrick Sanan   DMSwarmDataField gfield;
7952eac95f8SDave May   PetscErrorCode ierr;
796b62e03f8SDave May 
797521f74f9SMatthew G. Knepley   PetscFunctionBegin;
7983454631fSDave May   if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); }
79977048351SPatrick Sanan   ierr = DMSwarmDataBucketGetDMSwarmDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr);
80077048351SPatrick Sanan   ierr = DMSwarmDataFieldGetAccess(gfield);CHKERRQ(ierr);
80177048351SPatrick Sanan   ierr = DMSwarmDataFieldGetEntries(gfield,data);CHKERRQ(ierr);
8021b1ea282SDave May   if (blocksize) {*blocksize = gfield->bs; }
803b5bcf523SDave May   if (type) { *type = gfield->petsc_type; }
804b62e03f8SDave May   PetscFunctionReturn(0);
805b62e03f8SDave May }
806b62e03f8SDave May 
807d3a51819SDave May /*@C
808d3a51819SDave May    DMSwarmRestoreField - Restore access to the underlying array storing all entries associated with a registered field
809d3a51819SDave May 
810d3a51819SDave May    Not collective
811d3a51819SDave May 
812d3a51819SDave May    Input parameters:
81362741f57SDave May +  dm - a DMSwarm
81462741f57SDave May -  fieldname - the textual name to identify this field
815d3a51819SDave May 
816d3a51819SDave May    Output parameters:
81762741f57SDave May +  blocksize - the number of each data type
818d3a51819SDave May .  type - the data type
81962741f57SDave May -  data - pointer to raw array
820d3a51819SDave May 
821d3a51819SDave May    Level: beginner
822d3a51819SDave May 
823d3a51819SDave May    Notes:
8248b8a3813SDave May    The user must call DMSwarmGetField() prior to calling DMSwarmRestoreField().
825d3a51819SDave May 
826d3a51819SDave May .seealso: DMSwarmGetField()
827d3a51819SDave May @*/
8285f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmRestoreField(DM dm,const char fieldname[],PetscInt *blocksize,PetscDataType *type,void **data)
829b62e03f8SDave May {
830b62e03f8SDave May   DM_Swarm         *swarm = (DM_Swarm*)dm->data;
83177048351SPatrick Sanan   DMSwarmDataField gfield;
8322eac95f8SDave May   PetscErrorCode ierr;
833b62e03f8SDave May 
834521f74f9SMatthew G. Knepley   PetscFunctionBegin;
83577048351SPatrick Sanan   ierr = DMSwarmDataBucketGetDMSwarmDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr);
83677048351SPatrick Sanan   ierr = DMSwarmDataFieldRestoreAccess(gfield);CHKERRQ(ierr);
837b62e03f8SDave May   if (data) *data = NULL;
838b62e03f8SDave May   PetscFunctionReturn(0);
839b62e03f8SDave May }
840b62e03f8SDave May 
841d3a51819SDave May /*@C
842d3a51819SDave May    DMSwarmAddPoint - Add space for one new point in the DMSwarm
843d3a51819SDave May 
844d3a51819SDave May    Not collective
845d3a51819SDave May 
846d3a51819SDave May    Input parameter:
847d3a51819SDave May .  dm - a DMSwarm
848d3a51819SDave May 
849d3a51819SDave May    Level: beginner
850d3a51819SDave May 
851d3a51819SDave May    Notes:
8528b8a3813SDave May    The new point will have all fields initialized to zero.
853d3a51819SDave May 
854d3a51819SDave May .seealso: DMSwarmAddNPoints()
855d3a51819SDave May @*/
856cb1d1399SDave May PETSC_EXTERN PetscErrorCode DMSwarmAddPoint(DM dm)
857cb1d1399SDave May {
858cb1d1399SDave May   DM_Swarm       *swarm = (DM_Swarm*)dm->data;
859cb1d1399SDave May   PetscErrorCode ierr;
860cb1d1399SDave May 
861521f74f9SMatthew G. Knepley   PetscFunctionBegin;
8623454631fSDave May   if (!swarm->issetup) {ierr = DMSetUp(dm);CHKERRQ(ierr);}
863f2b2bee7SDave May   ierr = PetscLogEventBegin(DMSWARM_AddPoints,0,0,0,0);CHKERRQ(ierr);
86477048351SPatrick Sanan   ierr = DMSwarmDataBucketAddPoint(swarm->db);CHKERRQ(ierr);
865f2b2bee7SDave May   ierr = PetscLogEventEnd(DMSWARM_AddPoints,0,0,0,0);CHKERRQ(ierr);
866cb1d1399SDave May   PetscFunctionReturn(0);
867cb1d1399SDave May }
868cb1d1399SDave May 
869d3a51819SDave May /*@C
870d3a51819SDave May    DMSwarmAddNPoints - Add space for a number of new points in the DMSwarm
871d3a51819SDave May 
872d3a51819SDave May    Not collective
873d3a51819SDave May 
874d3a51819SDave May    Input parameters:
87562741f57SDave May +  dm - a DMSwarm
87662741f57SDave May -  npoints - the number of new points to add
877d3a51819SDave May 
878d3a51819SDave May    Level: beginner
879d3a51819SDave May 
880d3a51819SDave May    Notes:
8818b8a3813SDave May    The new point will have all fields initialized to zero.
882d3a51819SDave May 
883d3a51819SDave May .seealso: DMSwarmAddPoint()
884d3a51819SDave May @*/
885cb1d1399SDave May PETSC_EXTERN PetscErrorCode DMSwarmAddNPoints(DM dm,PetscInt npoints)
886cb1d1399SDave May {
887cb1d1399SDave May   DM_Swarm       *swarm = (DM_Swarm*)dm->data;
888cb1d1399SDave May   PetscErrorCode ierr;
889cb1d1399SDave May   PetscInt       nlocal;
890cb1d1399SDave May 
891521f74f9SMatthew G. Knepley   PetscFunctionBegin;
892f2b2bee7SDave May   ierr = PetscLogEventBegin(DMSWARM_AddPoints,0,0,0,0);CHKERRQ(ierr);
89377048351SPatrick Sanan   ierr = DMSwarmDataBucketGetSizes(swarm->db,&nlocal,NULL,NULL);CHKERRQ(ierr);
894cb1d1399SDave May   nlocal = nlocal + npoints;
89577048351SPatrick Sanan   ierr = DMSwarmDataBucketSetSizes(swarm->db,nlocal,DMSWARM_DATA_BUCKET_BUFFER_DEFAULT);CHKERRQ(ierr);
896f2b2bee7SDave May   ierr = PetscLogEventEnd(DMSWARM_AddPoints,0,0,0,0);CHKERRQ(ierr);
897cb1d1399SDave May   PetscFunctionReturn(0);
898cb1d1399SDave May }
899cb1d1399SDave May 
900d3a51819SDave May /*@C
901d3a51819SDave May    DMSwarmRemovePoint - Remove the last point from the DMSwarm
902d3a51819SDave May 
903d3a51819SDave May    Not collective
904d3a51819SDave May 
905d3a51819SDave May    Input parameter:
906d3a51819SDave May .  dm - a DMSwarm
907d3a51819SDave May 
908d3a51819SDave May    Level: beginner
909d3a51819SDave May 
910d3a51819SDave May .seealso: DMSwarmRemovePointAtIndex()
911d3a51819SDave May @*/
912cb1d1399SDave May PETSC_EXTERN PetscErrorCode DMSwarmRemovePoint(DM dm)
913cb1d1399SDave May {
914cb1d1399SDave May   DM_Swarm       *swarm = (DM_Swarm*)dm->data;
915cb1d1399SDave May   PetscErrorCode ierr;
916cb1d1399SDave May 
917521f74f9SMatthew G. Knepley   PetscFunctionBegin;
918f2b2bee7SDave May   ierr = PetscLogEventBegin(DMSWARM_RemovePoints,0,0,0,0);CHKERRQ(ierr);
91977048351SPatrick Sanan   ierr = DMSwarmDataBucketRemovePoint(swarm->db);CHKERRQ(ierr);
920f2b2bee7SDave May   ierr = PetscLogEventEnd(DMSWARM_RemovePoints,0,0,0,0);CHKERRQ(ierr);
921cb1d1399SDave May   PetscFunctionReturn(0);
922cb1d1399SDave May }
923cb1d1399SDave May 
924d3a51819SDave May /*@C
925d3a51819SDave May    DMSwarmRemovePointAtIndex - Removes a specific point from the DMSwarm
926d3a51819SDave May 
927d3a51819SDave May    Not collective
928d3a51819SDave May 
929d3a51819SDave May    Input parameters:
93062741f57SDave May +  dm - a DMSwarm
93162741f57SDave May -  idx - index of point to remove
932d3a51819SDave May 
933d3a51819SDave May    Level: beginner
934d3a51819SDave May 
935d3a51819SDave May .seealso: DMSwarmRemovePoint()
936d3a51819SDave May @*/
937cb1d1399SDave May PETSC_EXTERN PetscErrorCode DMSwarmRemovePointAtIndex(DM dm,PetscInt idx)
938cb1d1399SDave May {
939cb1d1399SDave May   DM_Swarm       *swarm = (DM_Swarm*)dm->data;
940cb1d1399SDave May   PetscErrorCode ierr;
941cb1d1399SDave May 
942521f74f9SMatthew G. Knepley   PetscFunctionBegin;
943f2b2bee7SDave May   ierr = PetscLogEventBegin(DMSWARM_RemovePoints,0,0,0,0);CHKERRQ(ierr);
94477048351SPatrick Sanan   ierr = DMSwarmDataBucketRemovePointAtIndex(swarm->db,idx);CHKERRQ(ierr);
945f2b2bee7SDave May   ierr = PetscLogEventEnd(DMSWARM_RemovePoints,0,0,0,0);CHKERRQ(ierr);
946cb1d1399SDave May   PetscFunctionReturn(0);
947cb1d1399SDave May }
948b62e03f8SDave May 
949ba4fc9c6SDave May /*@C
950ba4fc9c6SDave May    DMSwarmCopyPoint - Copy point pj to point pi in the DMSwarm
951ba4fc9c6SDave May 
952ba4fc9c6SDave May    Not collective
953ba4fc9c6SDave May 
954ba4fc9c6SDave May    Input parameters:
955ba4fc9c6SDave May +  dm - a DMSwarm
956ba4fc9c6SDave May .  pi - the index of the point to copy
957ba4fc9c6SDave May -  pj - the point index where the copy should be located
958ba4fc9c6SDave May 
959ba4fc9c6SDave May  Level: beginner
960ba4fc9c6SDave May 
961ba4fc9c6SDave May .seealso: DMSwarmRemovePoint()
962ba4fc9c6SDave May @*/
963ba4fc9c6SDave May PETSC_EXTERN PetscErrorCode DMSwarmCopyPoint(DM dm,PetscInt pi,PetscInt pj)
964ba4fc9c6SDave May {
965ba4fc9c6SDave May   DM_Swarm       *swarm = (DM_Swarm*)dm->data;
966ba4fc9c6SDave May   PetscErrorCode ierr;
967ba4fc9c6SDave May 
968ba4fc9c6SDave May   PetscFunctionBegin;
969ba4fc9c6SDave May   if (!swarm->issetup) {ierr = DMSetUp(dm);CHKERRQ(ierr);}
97077048351SPatrick Sanan   ierr = DMSwarmDataBucketCopyPoint(swarm->db,pi,swarm->db,pj);CHKERRQ(ierr);
971ba4fc9c6SDave May   PetscFunctionReturn(0);
972ba4fc9c6SDave May }
973ba4fc9c6SDave May 
974095059a4SDave May PetscErrorCode DMSwarmMigrate_Basic(DM dm,PetscBool remove_sent_points)
9753454631fSDave May {
976dcf43ee8SDave May   PetscErrorCode ierr;
977521f74f9SMatthew G. Knepley 
978521f74f9SMatthew G. Knepley   PetscFunctionBegin;
979dcf43ee8SDave May   ierr = DMSwarmMigrate_Push_Basic(dm,remove_sent_points);CHKERRQ(ierr);
9803454631fSDave May   PetscFunctionReturn(0);
9813454631fSDave May }
9823454631fSDave May 
983d3a51819SDave May /*@C
984d3a51819SDave May    DMSwarmMigrate - Relocates points defined in the DMSwarm to other MPI-ranks
985d3a51819SDave May 
986d3a51819SDave May    Collective on DM
987d3a51819SDave May 
988d3a51819SDave May    Input parameters:
98962741f57SDave May +  dm - the DMSwarm
99062741f57SDave May -  remove_sent_points - flag indicating if sent points should be removed from the current MPI-rank
991d3a51819SDave May 
992d3a51819SDave May    Notes:
9938b8a3813SDave May    The DM will be modified to accomodate received points.
9948b8a3813SDave May    If remove_sent_points = PETSC_TRUE, any points that were sent will be removed from the DM.
9958b8a3813SDave May    Different styles of migration are supported. See DMSwarmSetMigrateType().
996d3a51819SDave May 
997d3a51819SDave May    Level: advanced
998d3a51819SDave May 
999d3a51819SDave May .seealso: DMSwarmSetMigrateType()
1000d3a51819SDave May @*/
1001095059a4SDave May PETSC_EXTERN PetscErrorCode DMSwarmMigrate(DM dm,PetscBool remove_sent_points)
10023454631fSDave May {
1003f0cdbbbaSDave May   DM_Swarm       *swarm = (DM_Swarm*)dm->data;
10043454631fSDave May   PetscErrorCode ierr;
1005f0cdbbbaSDave May 
1006521f74f9SMatthew G. Knepley   PetscFunctionBegin;
1007ed923d71SDave May   ierr = PetscLogEventBegin(DMSWARM_Migrate,0,0,0,0);CHKERRQ(ierr);
1008f0cdbbbaSDave May   switch (swarm->migrate_type) {
1009f0cdbbbaSDave May     case DMSWARM_MIGRATE_BASIC:
1010095059a4SDave May       ierr = DMSwarmMigrate_Basic(dm,remove_sent_points);CHKERRQ(ierr);
1011f0cdbbbaSDave May       break;
1012f0cdbbbaSDave May     case DMSWARM_MIGRATE_DMCELLNSCATTER:
1013f0cdbbbaSDave May       ierr = DMSwarmMigrate_CellDMScatter(dm,remove_sent_points);CHKERRQ(ierr);
1014f0cdbbbaSDave May       break;
1015f0cdbbbaSDave May     case DMSWARM_MIGRATE_DMCELLEXACT:
1016f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_MIGRATE_DMCELLEXACT not implemented");
1017521f74f9SMatthew G. Knepley       /*ierr = DMSwarmMigrate_CellDMExact(dm,remove_sent_points);CHKERRQ(ierr);*/
1018f0cdbbbaSDave May       break;
1019f0cdbbbaSDave May     case DMSWARM_MIGRATE_USER:
1020f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_MIGRATE_USER not implemented");
1021521f74f9SMatthew G. Knepley       /*ierr = swarm->migrate(dm,remove_sent_points);CHKERRQ(ierr);*/
1022f0cdbbbaSDave May       break;
1023f0cdbbbaSDave May     default:
1024f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_MIGRATE type unknown");
1025f0cdbbbaSDave May       break;
1026f0cdbbbaSDave May   }
1027ed923d71SDave May   ierr = PetscLogEventEnd(DMSWARM_Migrate,0,0,0,0);CHKERRQ(ierr);
10283454631fSDave May   PetscFunctionReturn(0);
10293454631fSDave May }
10303454631fSDave May 
1031f0cdbbbaSDave May PetscErrorCode DMSwarmMigrate_GlobalToLocal_Basic(DM dm,PetscInt *globalsize);
1032f0cdbbbaSDave May 
1033d3a51819SDave May /*
1034d3a51819SDave May  DMSwarmCollectViewCreate
1035d3a51819SDave May 
1036d3a51819SDave May  * Applies a collection method and gathers point neighbour points into dm
1037d3a51819SDave May 
1038d3a51819SDave May  Notes:
10398b8a3813SDave May  Users should call DMSwarmCollectViewDestroy() after
1040d3a51819SDave May  they have finished computations associated with the collected points
1041d3a51819SDave May */
1042d3a51819SDave May 
1043d3a51819SDave May /*@C
1044d3a51819SDave May    DMSwarmCollectViewCreate - Applies a collection method and gathers points
1045d3a51819SDave May    in neighbour MPI-ranks into the DMSwarm
1046d3a51819SDave May 
1047d3a51819SDave May    Collective on DM
1048d3a51819SDave May 
1049d3a51819SDave May    Input parameter:
1050d3a51819SDave May .  dm - the DMSwarm
1051d3a51819SDave May 
1052d3a51819SDave May    Notes:
1053d3a51819SDave May    Users should call DMSwarmCollectViewDestroy() after
1054d3a51819SDave May    they have finished computations associated with the collected points
10558b8a3813SDave May    Different collect methods are supported. See DMSwarmSetCollectType().
1056d3a51819SDave May 
1057d3a51819SDave May    Level: advanced
1058d3a51819SDave May 
1059d3a51819SDave May .seealso: DMSwarmCollectViewDestroy(), DMSwarmSetCollectType()
1060d3a51819SDave May @*/
1061fe39f135SDave May PETSC_EXTERN PetscErrorCode DMSwarmCollectViewCreate(DM dm)
10622712d1f2SDave May {
10632712d1f2SDave May   PetscErrorCode ierr;
10642712d1f2SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
10652712d1f2SDave May   PetscInt ng;
10662712d1f2SDave May 
1067521f74f9SMatthew G. Knepley   PetscFunctionBegin;
1068480eef7bSDave May   if (swarm->collect_view_active) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"CollectView currently active");
1069480eef7bSDave May   ierr = DMSwarmGetLocalSize(dm,&ng);CHKERRQ(ierr);
1070480eef7bSDave May   switch (swarm->collect_type) {
1071f0cdbbbaSDave May 
1072480eef7bSDave May     case DMSWARM_COLLECT_BASIC:
10732712d1f2SDave May       ierr = DMSwarmMigrate_GlobalToLocal_Basic(dm,&ng);CHKERRQ(ierr);
1074480eef7bSDave May       break;
1075480eef7bSDave May     case DMSWARM_COLLECT_DMDABOUNDINGBOX:
1076f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_COLLECT_DMDABOUNDINGBOX not implemented");
1077521f74f9SMatthew G. Knepley       /*ierr = DMSwarmCollect_DMDABoundingBox(dm,&ng);CHKERRQ(ierr);*/
1078480eef7bSDave May       break;
1079480eef7bSDave May     case DMSWARM_COLLECT_GENERAL:
1080f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_COLLECT_GENERAL not implemented");
1081521f74f9SMatthew G. Knepley       /*ierr = DMSwarmCollect_General(dm,..,,..,&ng);CHKERRQ(ierr);*/
1082480eef7bSDave May       break;
1083480eef7bSDave May     default:
1084f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_COLLECT type unknown");
1085480eef7bSDave May       break;
1086480eef7bSDave May   }
1087480eef7bSDave May   swarm->collect_view_active = PETSC_TRUE;
1088480eef7bSDave May   swarm->collect_view_reset_nlocal = ng;
10892712d1f2SDave May   PetscFunctionReturn(0);
10902712d1f2SDave May }
10912712d1f2SDave May 
1092d3a51819SDave May /*@C
1093d3a51819SDave May    DMSwarmCollectViewDestroy - Resets the DMSwarm to the size prior to calling DMSwarmCollectViewCreate()
1094d3a51819SDave May 
1095d3a51819SDave May    Collective on DM
1096d3a51819SDave May 
1097d3a51819SDave May    Input parameters:
1098d3a51819SDave May .  dm - the DMSwarm
1099d3a51819SDave May 
1100d3a51819SDave May    Notes:
1101d3a51819SDave May    Users should call DMSwarmCollectViewCreate() before this function is called.
1102d3a51819SDave May 
1103d3a51819SDave May    Level: advanced
1104d3a51819SDave May 
1105d3a51819SDave May .seealso: DMSwarmCollectViewCreate(), DMSwarmSetCollectType()
1106d3a51819SDave May @*/
1107fe39f135SDave May PETSC_EXTERN PetscErrorCode DMSwarmCollectViewDestroy(DM dm)
11082712d1f2SDave May {
11092712d1f2SDave May   PetscErrorCode ierr;
11102712d1f2SDave May   DM_Swarm       *swarm = (DM_Swarm*)dm->data;
11112712d1f2SDave May 
1112521f74f9SMatthew G. Knepley   PetscFunctionBegin;
1113480eef7bSDave May   if (!swarm->collect_view_active) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"CollectView is currently not active");
1114480eef7bSDave May   ierr = DMSwarmSetLocalSizes(dm,swarm->collect_view_reset_nlocal,-1);CHKERRQ(ierr);
1115480eef7bSDave May   swarm->collect_view_active = PETSC_FALSE;
11162712d1f2SDave May   PetscFunctionReturn(0);
11172712d1f2SDave May }
11183454631fSDave May 
1119f0cdbbbaSDave May PetscErrorCode DMSwarmSetUpPIC(DM dm)
1120f0cdbbbaSDave May {
1121f0cdbbbaSDave May   PetscInt       dim;
1122f0cdbbbaSDave May   PetscErrorCode ierr;
1123f0cdbbbaSDave May 
1124521f74f9SMatthew G. Knepley   PetscFunctionBegin;
1125f0cdbbbaSDave May   ierr = DMGetDimension(dm,&dim);CHKERRQ(ierr);
1126f0cdbbbaSDave May   if (dim < 1) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Dimension must be 1,2,3 - found %D",dim);
1127f0cdbbbaSDave May   if (dim > 3) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Dimension must be 1,2,3 - found %D",dim);
1128f0cdbbbaSDave May   ierr = DMSwarmRegisterPetscDatatypeField(dm,DMSwarmPICField_coor,dim,PETSC_DOUBLE);CHKERRQ(ierr);
1129e2d107dbSDave May   ierr = DMSwarmRegisterPetscDatatypeField(dm,DMSwarmPICField_cellid,1,PETSC_INT);CHKERRQ(ierr);
1130f0cdbbbaSDave May   PetscFunctionReturn(0);
1131f0cdbbbaSDave May }
1132f0cdbbbaSDave May 
1133d3a51819SDave May /*@C
1134d3a51819SDave May    DMSwarmSetType - Set particular flavor of DMSwarm
1135d3a51819SDave May 
1136d3a51819SDave May    Collective on DM
1137d3a51819SDave May 
1138d3a51819SDave May    Input parameters:
113962741f57SDave May +  dm - the DMSwarm
114062741f57SDave May -  stype - the DMSwarm type (e.g. DMSWARM_PIC)
1141d3a51819SDave May 
1142d3a51819SDave May    Level: advanced
1143d3a51819SDave May 
1144d3a51819SDave May .seealso: DMSwarmSetMigrateType(), DMSwarmSetCollectType()
1145d3a51819SDave May @*/
1146f0cdbbbaSDave May PETSC_EXTERN PetscErrorCode DMSwarmSetType(DM dm,DMSwarmType stype)
1147f0cdbbbaSDave May {
1148f0cdbbbaSDave May   DM_Swarm       *swarm = (DM_Swarm*)dm->data;
1149f0cdbbbaSDave May   PetscErrorCode ierr;
1150f0cdbbbaSDave May 
1151521f74f9SMatthew G. Knepley   PetscFunctionBegin;
1152f0cdbbbaSDave May   swarm->swarm_type = stype;
1153f0cdbbbaSDave May   if (swarm->swarm_type == DMSWARM_PIC) {
1154f0cdbbbaSDave May     ierr = DMSwarmSetUpPIC(dm);CHKERRQ(ierr);
1155f0cdbbbaSDave May   }
1156f0cdbbbaSDave May   PetscFunctionReturn(0);
1157f0cdbbbaSDave May }
1158f0cdbbbaSDave May 
11593454631fSDave May PetscErrorCode DMSetup_Swarm(DM dm)
11603454631fSDave May {
11613454631fSDave May   DM_Swarm       *swarm = (DM_Swarm*)dm->data;
11623454631fSDave May   PetscErrorCode ierr;
11633454631fSDave May   PetscMPIInt    rank;
11643454631fSDave May   PetscInt       p,npoints,*rankval;
11653454631fSDave May 
1166521f74f9SMatthew G. Knepley   PetscFunctionBegin;
11673454631fSDave May   if (swarm->issetup) PetscFunctionReturn(0);
11683454631fSDave May 
11693454631fSDave May   swarm->issetup = PETSC_TRUE;
11703454631fSDave May 
1171f0cdbbbaSDave May   if (swarm->swarm_type == DMSWARM_PIC) {
1172f0cdbbbaSDave May     /* check dmcell exists */
1173f0cdbbbaSDave May     if (!swarm->dmcell) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSWARM_PIC requires you call DMSwarmSetCellDM");
1174f0cdbbbaSDave May 
1175f0cdbbbaSDave May     if (swarm->dmcell->ops->locatepointssubdomain) {
1176f0cdbbbaSDave May       /* check methods exists for exact ownership identificiation */
1177521f74f9SMatthew G. Knepley       ierr = PetscPrintf(PetscObjectComm((PetscObject)dm),"  DMSWARM_PIC: Using method CellDM->ops->LocatePointsSubdomain\n");CHKERRQ(ierr);
1178f0cdbbbaSDave May       swarm->migrate_type = DMSWARM_MIGRATE_DMCELLEXACT;
1179f0cdbbbaSDave May     } else {
1180f0cdbbbaSDave May       /* check methods exist for point location AND rank neighbor identification */
1181f0cdbbbaSDave May       if (swarm->dmcell->ops->locatepoints) {
1182521f74f9SMatthew G. Knepley         ierr = PetscPrintf(PetscObjectComm((PetscObject)dm),"  DMSWARM_PIC: Using method CellDM->LocatePoints\n");CHKERRQ(ierr);
1183f0cdbbbaSDave May       } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSWARM_PIC requires the method CellDM->ops->locatepoints be defined");
1184f0cdbbbaSDave May 
1185f0cdbbbaSDave May       if (swarm->dmcell->ops->getneighbors) {
1186521f74f9SMatthew G. Knepley         ierr = PetscPrintf(PetscObjectComm((PetscObject)dm),"  DMSWARM_PIC: Using method CellDM->GetNeigbors\n");CHKERRQ(ierr);
1187f0cdbbbaSDave May       } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSWARM_PIC requires the method CellDM->ops->getneighbors be defined");
1188f0cdbbbaSDave May 
1189f0cdbbbaSDave May       swarm->migrate_type = DMSWARM_MIGRATE_DMCELLNSCATTER;
1190f0cdbbbaSDave May     }
1191f0cdbbbaSDave May   }
1192f0cdbbbaSDave May 
1193f0cdbbbaSDave May   ierr = DMSwarmFinalizeFieldRegister(dm);CHKERRQ(ierr);
1194f0cdbbbaSDave May 
11953454631fSDave May   /* check some fields were registered */
11963454631fSDave May   if (swarm->db->nfields <= 2) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"At least one field user must be registered via DMSwarmRegisterXXX()");
11973454631fSDave May 
11983454631fSDave May   /* check local sizes were set */
11993454631fSDave May   if (swarm->db->L == -1) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Local sizes must be set via DMSwarmSetLocalSizes()");
12003454631fSDave May 
12013454631fSDave May   /* initialize values in pid and rank placeholders */
12023454631fSDave May   /* TODO: [pid - use MPI_Scan] */
12033454631fSDave May   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm),&rank);CHKERRQ(ierr);
120477048351SPatrick Sanan   ierr = DMSwarmDataBucketGetSizes(swarm->db,&npoints,NULL,NULL);CHKERRQ(ierr);
1205f0cdbbbaSDave May   ierr = DMSwarmGetField(dm,DMSwarmField_rank,NULL,NULL,(void**)&rankval);CHKERRQ(ierr);
12063454631fSDave May   for (p=0; p<npoints; p++) {
12073454631fSDave May     rankval[p] = (PetscInt)rank;
12083454631fSDave May   }
1209f0cdbbbaSDave May   ierr = DMSwarmRestoreField(dm,DMSwarmField_rank,NULL,NULL,(void**)&rankval);CHKERRQ(ierr);
12103454631fSDave May   PetscFunctionReturn(0);
12113454631fSDave May }
12123454631fSDave May 
1213dc5f5ce9SDave May extern PetscErrorCode DMSwarmSortDestroy(DMSwarmSort *_ctx);
1214dc5f5ce9SDave May 
121557795646SDave May PetscErrorCode DMDestroy_Swarm(DM dm)
121657795646SDave May {
121757795646SDave May   DM_Swarm       *swarm = (DM_Swarm*)dm->data;
121857795646SDave May   PetscErrorCode ierr;
121957795646SDave May 
122057795646SDave May   PetscFunctionBegin;
122177048351SPatrick Sanan   ierr = DMSwarmDataBucketDestroy(&swarm->db);CHKERRQ(ierr);
1222dc5f5ce9SDave May   if (swarm->sort_context) {
1223dc5f5ce9SDave May     ierr = DMSwarmSortDestroy(&swarm->sort_context);CHKERRQ(ierr);
1224dc5f5ce9SDave May   }
122557795646SDave May   ierr = PetscFree(swarm);CHKERRQ(ierr);
122657795646SDave May   PetscFunctionReturn(0);
122757795646SDave May }
122857795646SDave May 
1229a9ee3421SMatthew G. Knepley PetscErrorCode DMSwarmView_Draw(DM dm, PetscViewer viewer)
1230a9ee3421SMatthew G. Knepley {
1231a9ee3421SMatthew G. Knepley   DM             cdm;
1232a9ee3421SMatthew G. Knepley   PetscDraw      draw;
1233a9ee3421SMatthew G. Knepley   PetscReal     *coords, oldPause;
1234a9ee3421SMatthew G. Knepley   PetscInt       Np, p, bs;
1235a9ee3421SMatthew G. Knepley   PetscErrorCode ierr;
1236a9ee3421SMatthew G. Knepley 
1237a9ee3421SMatthew G. Knepley   PetscFunctionBegin;
1238a9ee3421SMatthew G. Knepley   ierr = PetscViewerDrawGetDraw(viewer, 0, &draw);CHKERRQ(ierr);
1239a9ee3421SMatthew G. Knepley   ierr = DMSwarmGetCellDM(dm, &cdm);CHKERRQ(ierr);
1240a9ee3421SMatthew G. Knepley   ierr = PetscDrawGetPause(draw, &oldPause);CHKERRQ(ierr);
1241a9ee3421SMatthew G. Knepley   ierr = PetscDrawSetPause(draw, 0.0);CHKERRQ(ierr);
1242a9ee3421SMatthew G. Knepley   ierr = DMView(cdm, viewer);CHKERRQ(ierr);
1243a9ee3421SMatthew G. Knepley   ierr = PetscDrawSetPause(draw, oldPause);CHKERRQ(ierr);
1244a9ee3421SMatthew G. Knepley 
1245a9ee3421SMatthew G. Knepley   ierr = DMSwarmGetLocalSize(dm, &Np);CHKERRQ(ierr);
1246a9ee3421SMatthew G. Knepley   ierr = DMSwarmGetField(dm, DMSwarmPICField_coor, &bs, NULL, (void **) &coords);CHKERRQ(ierr);
1247a9ee3421SMatthew G. Knepley   for (p = 0; p < Np; ++p) {
1248a9ee3421SMatthew G. Knepley     const PetscInt i = p*bs;
1249a9ee3421SMatthew G. Knepley 
1250a9ee3421SMatthew G. Knepley     ierr = PetscDrawEllipse(draw, coords[i], coords[i+1], 0.01, 0.01, PETSC_DRAW_BLUE);CHKERRQ(ierr);
1251a9ee3421SMatthew G. Knepley   }
1252a9ee3421SMatthew G. Knepley   ierr = DMSwarmRestoreField(dm, DMSwarmPICField_coor, &bs, NULL, (void **) &coords);CHKERRQ(ierr);
1253a9ee3421SMatthew G. Knepley   ierr = PetscDrawFlush(draw);CHKERRQ(ierr);
1254a9ee3421SMatthew G. Knepley   ierr = PetscDrawPause(draw);CHKERRQ(ierr);
1255a9ee3421SMatthew G. Knepley   ierr = PetscDrawSave(draw);CHKERRQ(ierr);
1256a9ee3421SMatthew G. Knepley   PetscFunctionReturn(0);
1257a9ee3421SMatthew G. Knepley }
1258a9ee3421SMatthew G. Knepley 
12595f50eb2eSDave May PetscErrorCode DMView_Swarm(DM dm, PetscViewer viewer)
12605f50eb2eSDave May {
12615f50eb2eSDave May   DM_Swarm       *swarm = (DM_Swarm*)dm->data;
1262a9ee3421SMatthew G. Knepley   PetscBool      iascii,ibinary,ishdf5,isvtk,isdraw;
12635f50eb2eSDave May   PetscErrorCode ierr;
12645f50eb2eSDave May 
12655f50eb2eSDave May   PetscFunctionBegin;
12665f50eb2eSDave May   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
12675f50eb2eSDave May   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
12685f50eb2eSDave May   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr);
12695f50eb2eSDave May   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY,&ibinary);CHKERRQ(ierr);
12705f50eb2eSDave May   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERVTK,   &isvtk);CHKERRQ(ierr);
12715f50eb2eSDave May   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5,  &ishdf5);CHKERRQ(ierr);
1272a9ee3421SMatthew G. Knepley   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW,  &isdraw);CHKERRQ(ierr);
12735f50eb2eSDave May   if (iascii) {
127477048351SPatrick Sanan     ierr = DMSwarmDataBucketView(PetscObjectComm((PetscObject)dm),swarm->db,NULL,DATABUCKET_VIEW_STDOUT);CHKERRQ(ierr);
1275298827fbSBarry Smith   } else if (ibinary) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"NO Binary support");
12765f50eb2eSDave May #if defined(PETSC_HAVE_HDF5)
1277298827fbSBarry Smith   else if (ishdf5) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"NO HDF5 support");
12785f50eb2eSDave May #else
1279298827fbSBarry Smith   else if (ishdf5) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"HDF5 not supported. Please reconfigure using --download-hdf5");
12805f50eb2eSDave May #endif
1281298827fbSBarry Smith   else if (isvtk) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"NO VTK support");
1282298827fbSBarry Smith   else if (isdraw) {
1283a9ee3421SMatthew G. Knepley     ierr = DMSwarmView_Draw(dm, viewer);CHKERRQ(ierr);
12845f50eb2eSDave May   }
12855f50eb2eSDave May   PetscFunctionReturn(0);
12865f50eb2eSDave May }
12875f50eb2eSDave May 
1288d3a51819SDave May /*MC
1289d3a51819SDave May 
1290d3a51819SDave May  DMSWARM = "swarm" - A DM object used to represent arrays of data (fields) of arbitrary data type.
129162741f57SDave May  This implementation was designed for particle methods in which the underlying
1292d3a51819SDave May  data required to be represented is both (i) dynamic in length, (ii) and of arbitrary data type.
1293d3a51819SDave May 
129462741f57SDave May  User data can be represented by DMSwarm through a registering "fields".
129562741f57SDave May  To register a field, the user must provide;
129662741f57SDave May  (a) a unique name;
129762741f57SDave May  (b) the data type (or size in bytes);
129862741f57SDave May  (c) the block size of the data.
1299d3a51819SDave May 
1300d3a51819SDave May  For example, suppose the application requires a unique id, energy, momentum and density to be stored
130162741f57SDave May  on a set of of particles. Then the following code could be used
1302d3a51819SDave May 
130362741f57SDave May $    DMSwarmInitializeFieldRegister(dm)
130462741f57SDave May $    DMSwarmRegisterPetscDatatypeField(dm,"uid",1,PETSC_LONG);
130562741f57SDave May $    DMSwarmRegisterPetscDatatypeField(dm,"energy",1,PETSC_REAL);
130662741f57SDave May $    DMSwarmRegisterPetscDatatypeField(dm,"momentum",3,PETSC_REAL);
130762741f57SDave May $    DMSwarmRegisterPetscDatatypeField(dm,"density",1,PETSC_FLOAT);
130862741f57SDave May $    DMSwarmFinalizeFieldRegister(dm)
1309d3a51819SDave May 
1310d3a51819SDave May  The fields represented by DMSwarm are dynamic and can be re-sized at any time.
131162741f57SDave May  The only restriction imposed by DMSwarm is that all fields contain the same number of points.
1312d3a51819SDave May 
1313d3a51819SDave May  To support particle methods, "migration" techniques are provided. These methods migrate data
1314d3a51819SDave May  between MPI-ranks.
1315d3a51819SDave May 
1316d3a51819SDave May  DMSwarm supports the methods DMCreateGlobalVector() and DMCreateLocalVector().
1317d3a51819SDave May  As a DMSwarm may internally define and store values of different data types,
131862741f57SDave May  before calling DMCreateGlobalVector() or DMCreateLocalVector(), the user must inform DMSwarm which
1319d3a51819SDave May  fields should be used to define a Vec object via
1320d3a51819SDave May    DMSwarmVectorDefineField()
1321d3a51819SDave May  The specified field can can changed be changed at any time - thereby permitting vectors
1322d3a51819SDave May  compatable with different fields to be created.
1323d3a51819SDave May 
132462741f57SDave May  A dual representation of fields in the DMSwarm and a Vec object is permitted via
1325d3a51819SDave May    DMSwarmCreateGlobalVectorFromField()
1326d3a51819SDave May  Here the data defining the field in the DMSwarm is shared with a Vec.
1327d3a51819SDave May  This is inherently unsafe if you alter the size of the field at any time between
1328d3a51819SDave May  calls to DMSwarmCreateGlobalVectorFromField() and DMSwarmDestroyGlobalVectorFromField().
1329cc651181SDave May  If the local size of the DMSwarm does not match the local size of the global vector
1330cc651181SDave May  when DMSwarmDestroyGlobalVectorFromField() is called, an error is thrown.
1331d3a51819SDave May 
133262741f57SDave May  Additional high-level support is provided for Particle-In-Cell methods.
133362741f57SDave May  Please refer to the man page for DMSwarmSetType().
133462741f57SDave May 
1335d3a51819SDave May  Level: beginner
1336d3a51819SDave May 
1337d3a51819SDave May .seealso: DMType, DMCreate(), DMSetType()
1338d3a51819SDave May M*/
133957795646SDave May PETSC_EXTERN PetscErrorCode DMCreate_Swarm(DM dm)
134057795646SDave May {
134157795646SDave May   DM_Swarm      *swarm;
134257795646SDave May   PetscErrorCode ierr;
134357795646SDave May 
134457795646SDave May   PetscFunctionBegin;
134557795646SDave May   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
134657795646SDave May   ierr     = PetscNewLog(dm,&swarm);CHKERRQ(ierr);
1347f0cdbbbaSDave May   dm->data = swarm;
134857795646SDave May 
134977048351SPatrick Sanan   ierr = DMSwarmDataBucketCreate(&swarm->db);CHKERRQ(ierr);
1350f0cdbbbaSDave May   ierr = DMSwarmInitializeFieldRegister(dm);CHKERRQ(ierr);
1351f0cdbbbaSDave May 
1352b5bcf523SDave May   swarm->vec_field_set = PETSC_FALSE;
13533454631fSDave May   swarm->issetup = PETSC_FALSE;
1354480eef7bSDave May   swarm->swarm_type = DMSWARM_BASIC;
1355480eef7bSDave May   swarm->migrate_type = DMSWARM_MIGRATE_BASIC;
1356480eef7bSDave May   swarm->collect_type = DMSWARM_COLLECT_BASIC;
135740c453e9SDave May   swarm->migrate_error_on_missing_point = PETSC_FALSE;
1358b62e03f8SDave May 
1359f0cdbbbaSDave May   swarm->dmcell = NULL;
1360f0cdbbbaSDave May   swarm->collect_view_active = PETSC_FALSE;
1361f0cdbbbaSDave May   swarm->collect_view_reset_nlocal = -1;
136257795646SDave May 
1363f0cdbbbaSDave May   dm->dim  = 0;
13645f50eb2eSDave May   dm->ops->view                            = DMView_Swarm;
136557795646SDave May   dm->ops->load                            = NULL;
136657795646SDave May   dm->ops->setfromoptions                  = NULL;
136757795646SDave May   dm->ops->clone                           = NULL;
13683454631fSDave May   dm->ops->setup                           = DMSetup_Swarm;
136957795646SDave May   dm->ops->createdefaultsection            = NULL;
137057795646SDave May   dm->ops->createdefaultconstraints        = NULL;
1371b5bcf523SDave May   dm->ops->createglobalvector              = DMCreateGlobalVector_Swarm;
1372b5bcf523SDave May   dm->ops->createlocalvector               = DMCreateLocalVector_Swarm;
137357795646SDave May   dm->ops->getlocaltoglobalmapping         = NULL;
137457795646SDave May   dm->ops->createfieldis                   = NULL;
137557795646SDave May   dm->ops->createcoordinatedm              = NULL;
137657795646SDave May   dm->ops->getcoloring                     = NULL;
137757795646SDave May   dm->ops->creatematrix                    = NULL;
137857795646SDave May   dm->ops->createinterpolation             = NULL;
137957795646SDave May   dm->ops->getaggregates                   = NULL;
138057795646SDave May   dm->ops->getinjection                    = NULL;
138183c47955SMatthew G. Knepley   dm->ops->createmassmatrix                = DMCreateMassMatrix_Swarm;
138257795646SDave May   dm->ops->refine                          = NULL;
138357795646SDave May   dm->ops->coarsen                         = NULL;
138457795646SDave May   dm->ops->refinehierarchy                 = NULL;
138557795646SDave May   dm->ops->coarsenhierarchy                = NULL;
138657795646SDave May   dm->ops->globaltolocalbegin              = NULL;
138757795646SDave May   dm->ops->globaltolocalend                = NULL;
138857795646SDave May   dm->ops->localtoglobalbegin              = NULL;
138957795646SDave May   dm->ops->localtoglobalend                = NULL;
139057795646SDave May   dm->ops->destroy                         = DMDestroy_Swarm;
139157795646SDave May   dm->ops->createsubdm                     = NULL;
139257795646SDave May   dm->ops->getdimpoints                    = NULL;
139357795646SDave May   dm->ops->locatepoints                    = NULL;
139457795646SDave May   PetscFunctionReturn(0);
139557795646SDave May }
1396