xref: /petsc/src/dm/impls/swarm/swarm.c (revision c6b011d851020aae3807fa5f825aff12985b499d)
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);
86*c6b011d8SStefano Zampini   ierr = VecSetDM(x,dm);CHKERRQ(ierr);
87b5bcf523SDave May   ierr = VecSetFromOptions(x);CHKERRQ(ierr);
88b5bcf523SDave May   *vec = x;
89b5bcf523SDave May   PetscFunctionReturn(0);
90b5bcf523SDave May }
91b5bcf523SDave May 
92b5bcf523SDave May /* requires DMSwarmDefineFieldVector has been called */
93b5bcf523SDave May PetscErrorCode DMCreateLocalVector_Swarm(DM dm,Vec *vec)
94b5bcf523SDave May {
95b5bcf523SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
96b5bcf523SDave May   PetscErrorCode ierr;
97b5bcf523SDave May   Vec x;
98b5bcf523SDave May   char name[PETSC_MAX_PATH_LEN];
99b5bcf523SDave May 
100a9cbaee5SMatthew G. Knepley   PetscFunctionBegin;
1013454631fSDave May   if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); }
102b5bcf523SDave May   if (!swarm->vec_field_set) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMSwarmVectorDefineField first");
103cc651181SDave 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 */
104cc651181SDave May 
105521f74f9SMatthew G. Knepley   ierr = PetscSNPrintf(name,PETSC_MAX_PATH_LEN-1,"DMSwarmField_%s",swarm->vec_field_name);CHKERRQ(ierr);
106b5bcf523SDave May   ierr = VecCreate(PETSC_COMM_SELF,&x);CHKERRQ(ierr);
107b5bcf523SDave May   ierr = PetscObjectSetName((PetscObject)x,name);CHKERRQ(ierr);
108071900c8SMatthew G. Knepley   ierr = VecSetSizes(x,swarm->db->L*swarm->vec_field_bs,PETSC_DETERMINE);CHKERRQ(ierr);
109b5bcf523SDave May   ierr = VecSetBlockSize(x,swarm->vec_field_bs);CHKERRQ(ierr);
110*c6b011d8SStefano Zampini   ierr = VecSetDM(x,dm);CHKERRQ(ierr);
111b5bcf523SDave May   ierr = VecSetFromOptions(x);CHKERRQ(ierr);
112b5bcf523SDave May   *vec = x;
113b5bcf523SDave May   PetscFunctionReturn(0);
114b5bcf523SDave May }
115b5bcf523SDave May 
116fb1bcc12SMatthew G. Knepley static PetscErrorCode DMSwarmDestroyVectorFromField_Private(DM dm, const char fieldname[], Vec *vec)
117fb1bcc12SMatthew G. Knepley {
118fb1bcc12SMatthew G. Knepley   DM_Swarm      *swarm = (DM_Swarm *) dm->data;
11977048351SPatrick Sanan   DMSwarmDataField      gfield;
120fb1bcc12SMatthew G. Knepley   void         (*fptr)(void);
121fb1bcc12SMatthew G. Knepley   PetscInt       bs, nlocal;
122fb1bcc12SMatthew G. Knepley   char           name[PETSC_MAX_PATH_LEN];
123fb1bcc12SMatthew G. Knepley   PetscErrorCode ierr;
124d3a51819SDave May 
125fb1bcc12SMatthew G. Knepley   PetscFunctionBegin;
126fb1bcc12SMatthew G. Knepley   ierr = VecGetLocalSize(*vec, &nlocal);CHKERRQ(ierr);
127fb1bcc12SMatthew G. Knepley   ierr = VecGetBlockSize(*vec, &bs);CHKERRQ(ierr);
128fb1bcc12SMatthew 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 */
12977048351SPatrick Sanan   ierr = DMSwarmDataBucketGetDMSwarmDataFieldByName(swarm->db, fieldname, &gfield);CHKERRQ(ierr);
130fb1bcc12SMatthew G. Knepley   /* check vector is an inplace array */
131521f74f9SMatthew G. Knepley   ierr = PetscSNPrintf(name, PETSC_MAX_PATH_LEN-1, "DMSwarm_VecFieldInPlace_%s", fieldname);CHKERRQ(ierr);
132fb1bcc12SMatthew G. Knepley   ierr = PetscObjectQueryFunction((PetscObject) *vec, name, &fptr);CHKERRQ(ierr);
133fb1bcc12SMatthew G. Knepley   if (!fptr) SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_USER, "Vector being destroyed was not created from DMSwarm field(%s)", fieldname);
13477048351SPatrick Sanan   ierr = DMSwarmDataFieldRestoreAccess(gfield);CHKERRQ(ierr);
135fb1bcc12SMatthew G. Knepley   ierr = VecDestroy(vec);CHKERRQ(ierr);
136fb1bcc12SMatthew G. Knepley   PetscFunctionReturn(0);
137fb1bcc12SMatthew G. Knepley }
138fb1bcc12SMatthew G. Knepley 
139fb1bcc12SMatthew G. Knepley static PetscErrorCode DMSwarmCreateVectorFromField_Private(DM dm, const char fieldname[], MPI_Comm comm, Vec *vec)
140fb1bcc12SMatthew G. Knepley {
141fb1bcc12SMatthew G. Knepley   DM_Swarm      *swarm = (DM_Swarm *) dm->data;
142fb1bcc12SMatthew G. Knepley   PetscDataType  type;
143fb1bcc12SMatthew G. Knepley   PetscScalar   *array;
144fb1bcc12SMatthew G. Knepley   PetscInt       bs, n;
145fb1bcc12SMatthew G. Knepley   char           name[PETSC_MAX_PATH_LEN];
146e4fbd051SBarry Smith   PetscMPIInt    size;
147fb1bcc12SMatthew G. Knepley   PetscErrorCode ierr;
148fb1bcc12SMatthew G. Knepley 
149fb1bcc12SMatthew G. Knepley   PetscFunctionBegin;
150fb1bcc12SMatthew G. Knepley   if (!swarm->issetup) {ierr = DMSetUp(dm);CHKERRQ(ierr);}
15177048351SPatrick Sanan   ierr = DMSwarmDataBucketGetSizes(swarm->db, &n, NULL, NULL);CHKERRQ(ierr);
152fb1bcc12SMatthew G. Knepley   ierr = DMSwarmGetField(dm, fieldname, &bs, &type, (void **) &array);CHKERRQ(ierr);
153fb1bcc12SMatthew G. Knepley   if (type != PETSC_REAL) SETERRQ(PetscObjectComm((PetscObject) dm), PETSC_ERR_SUP, "Only valid for PETSC_REAL");
154fb1bcc12SMatthew G. Knepley 
155e4fbd051SBarry Smith   ierr = MPI_Comm_size(comm, &size);CHKERRQ(ierr);
156e4fbd051SBarry Smith   if (size == 1) {
157fb1bcc12SMatthew G. Knepley     ierr = VecCreateSeqWithArray(comm, bs, n*bs, array, vec);CHKERRQ(ierr);
158fb1bcc12SMatthew G. Knepley   } else {
159fb1bcc12SMatthew G. Knepley     ierr = VecCreateMPIWithArray(comm, bs, n*bs, PETSC_DETERMINE, array, vec);CHKERRQ(ierr);
160fb1bcc12SMatthew G. Knepley   }
161fb1bcc12SMatthew G. Knepley   ierr = PetscSNPrintf(name, PETSC_MAX_PATH_LEN-1, "DMSwarmSharedField_%s", fieldname);CHKERRQ(ierr);
162fb1bcc12SMatthew G. Knepley   ierr = PetscObjectSetName((PetscObject) *vec, name);CHKERRQ(ierr);
163fb1bcc12SMatthew G. Knepley 
164fb1bcc12SMatthew G. Knepley   /* Set guard */
165fb1bcc12SMatthew G. Knepley   ierr = PetscSNPrintf(name, PETSC_MAX_PATH_LEN-1, "DMSwarm_VecFieldInPlace_%s", fieldname);CHKERRQ(ierr);
166fb1bcc12SMatthew G. Knepley   ierr = PetscObjectComposeFunction((PetscObject) *vec, name, DMSwarmDestroyVectorFromField_Private);CHKERRQ(ierr);
167fb1bcc12SMatthew G. Knepley   PetscFunctionReturn(0);
168fb1bcc12SMatthew G. Knepley }
169fb1bcc12SMatthew G. Knepley 
1700643ed39SMatthew G. Knepley /* This creates a "mass matrix" between a finite element and particle space. If a finite element interpolant is given by
1710643ed39SMatthew G. Knepley 
1720643ed39SMatthew G. Knepley      \hat f = \sum_i f_i \phi_i
1730643ed39SMatthew G. Knepley 
1740643ed39SMatthew G. Knepley    and a particle function is given by
1750643ed39SMatthew G. Knepley 
1760643ed39SMatthew G. Knepley      f = \sum_i w_i \delta(x - x_i)
1770643ed39SMatthew G. Knepley 
1780643ed39SMatthew G. Knepley    then we want to require that
1790643ed39SMatthew G. Knepley 
1800643ed39SMatthew G. Knepley      M \hat f = M_p f
1810643ed39SMatthew G. Knepley 
1820643ed39SMatthew G. Knepley    where the particle mass matrix is given by
1830643ed39SMatthew G. Knepley 
1840643ed39SMatthew G. Knepley      (M_p)_{ij} = \int \phi_i \delta(x - x_j)
1850643ed39SMatthew G. Knepley 
1860643ed39SMatthew G. Knepley    The way Dave May does particles, they amount to quadratue weights rather than delta functions, so he has |J| is in
1870643ed39SMatthew G. Knepley    his integral. We allow this with the boolean flag.
1880643ed39SMatthew G. Knepley */
1890643ed39SMatthew G. Knepley static PetscErrorCode DMSwarmComputeMassMatrix_Private(DM dmc, DM dmf, Mat mass, PetscBool useDeltaFunction, void *ctx)
19083c47955SMatthew G. Knepley {
19183c47955SMatthew G. Knepley   const char    *name = "Mass Matrix";
1920643ed39SMatthew G. Knepley   MPI_Comm       comm;
19383c47955SMatthew G. Knepley   PetscDS        prob;
19483c47955SMatthew G. Knepley   PetscSection   fsection, globalFSection;
195e8f14785SLisandro Dalcin   PetscHSetIJ    ht;
1960643ed39SMatthew G. Knepley   PetscLayout    rLayout, colLayout;
19783c47955SMatthew G. Knepley   PetscInt      *dnz, *onz;
198adb2528bSMark Adams   PetscInt       locRows, locCols, rStart, colStart, colEnd, *rowIDXs;
1990643ed39SMatthew G. Knepley   PetscReal     *xi, *v0, *J, *invJ, detJ = 1.0, v0ref[3] = {-1.0, -1.0, -1.0};
20083c47955SMatthew G. Knepley   PetscScalar   *elemMat;
2010643ed39SMatthew G. Knepley   PetscInt       dim, Nf, field, cStart, cEnd, cell, totDim, maxC = 0;
20283c47955SMatthew G. Knepley   PetscErrorCode ierr;
20383c47955SMatthew G. Knepley 
20483c47955SMatthew G. Knepley   PetscFunctionBegin;
2050643ed39SMatthew G. Knepley   ierr = PetscObjectGetComm((PetscObject) mass, &comm);CHKERRQ(ierr);
20683c47955SMatthew G. Knepley   ierr = DMGetCoordinateDim(dmf, &dim);CHKERRQ(ierr);
20783c47955SMatthew G. Knepley   ierr = DMGetDS(dmf, &prob);CHKERRQ(ierr);
20883c47955SMatthew G. Knepley   ierr = PetscDSGetNumFields(prob, &Nf);CHKERRQ(ierr);
2090643ed39SMatthew G. Knepley   ierr = PetscDSGetTotalDimension(prob, &totDim);CHKERRQ(ierr);
21083c47955SMatthew G. Knepley   ierr = PetscMalloc3(dim, &v0, dim*dim, &J, dim*dim,&invJ);CHKERRQ(ierr);
21192fd8e1eSJed Brown   ierr = DMGetLocalSection(dmf, &fsection);CHKERRQ(ierr);
212e87a4003SBarry Smith   ierr = DMGetGlobalSection(dmf, &globalFSection);CHKERRQ(ierr);
21383c47955SMatthew G. Knepley   ierr = DMPlexGetHeightStratum(dmf, 0, &cStart, &cEnd);CHKERRQ(ierr);
2140643ed39SMatthew G. Knepley   ierr = MatGetLocalSize(mass, &locRows, &locCols);CHKERRQ(ierr);
21583c47955SMatthew G. Knepley 
2160643ed39SMatthew G. Knepley   ierr = PetscLayoutCreate(comm, &colLayout);CHKERRQ(ierr);
2170643ed39SMatthew G. Knepley   ierr = PetscLayoutSetLocalSize(colLayout, locCols);CHKERRQ(ierr);
2180643ed39SMatthew G. Knepley   ierr = PetscLayoutSetBlockSize(colLayout, 1);CHKERRQ(ierr);
2190643ed39SMatthew G. Knepley   ierr = PetscLayoutSetUp(colLayout);CHKERRQ(ierr);
2200643ed39SMatthew G. Knepley   ierr = PetscLayoutGetRange(colLayout, &colStart, &colEnd);CHKERRQ(ierr);
2210643ed39SMatthew G. Knepley   ierr = PetscLayoutDestroy(&colLayout);CHKERRQ(ierr);
2220643ed39SMatthew G. Knepley 
2230643ed39SMatthew G. Knepley   ierr = PetscLayoutCreate(comm, &rLayout);CHKERRQ(ierr);
22483c47955SMatthew G. Knepley   ierr = PetscLayoutSetLocalSize(rLayout, locRows);CHKERRQ(ierr);
22583c47955SMatthew G. Knepley   ierr = PetscLayoutSetBlockSize(rLayout, 1);CHKERRQ(ierr);
22683c47955SMatthew G. Knepley   ierr = PetscLayoutSetUp(rLayout);CHKERRQ(ierr);
2270643ed39SMatthew G. Knepley   ierr = PetscLayoutGetRange(rLayout, &rStart, NULL);CHKERRQ(ierr);
22883c47955SMatthew G. Knepley   ierr = PetscLayoutDestroy(&rLayout);CHKERRQ(ierr);
2290643ed39SMatthew G. Knepley 
23083c47955SMatthew G. Knepley   ierr = PetscCalloc2(locRows, &dnz, locRows, &onz);CHKERRQ(ierr);
231e8f14785SLisandro Dalcin   ierr = PetscHSetIJCreate(&ht);CHKERRQ(ierr);
23253e60ab4SJoseph Pusztay 
2330643ed39SMatthew G. Knepley   ierr = PetscSynchronizedFlush(comm, NULL);CHKERRQ(ierr);
2340643ed39SMatthew G. Knepley   /* count non-zeros */
2350643ed39SMatthew G. Knepley   ierr = DMSwarmSortGetAccess(dmc);CHKERRQ(ierr);
23683c47955SMatthew G. Knepley   for (field = 0; field < Nf; ++field) {
23783c47955SMatthew G. Knepley     for (cell = cStart; cell < cEnd; ++cell) {
2380643ed39SMatthew G. Knepley       PetscInt  c, i;
2390643ed39SMatthew G. Knepley       PetscInt *findices,   *cindices; /* fine is vertices, coarse is particles */
24083c47955SMatthew G. Knepley       PetscInt  numFIndices, numCIndices;
24183c47955SMatthew G. Knepley 
24283c47955SMatthew G. Knepley       ierr = DMPlexGetClosureIndices(dmf, fsection, globalFSection, cell, &numFIndices, &findices, NULL);CHKERRQ(ierr);
243fc7c92abSMatthew G. Knepley       ierr = DMSwarmSortGetPointsPerCell(dmc, cell, &numCIndices, &cindices);CHKERRQ(ierr);
244fc7c92abSMatthew G. Knepley       maxC = PetscMax(maxC, numCIndices);
24583c47955SMatthew G. Knepley       {
246e8f14785SLisandro Dalcin         PetscHashIJKey key;
247e8f14785SLisandro Dalcin         PetscBool      missing;
24883c47955SMatthew G. Knepley         for (i = 0; i < numFIndices; ++i) {
249adb2528bSMark Adams           key.j = findices[i]; /* global column (from Plex) */
250adb2528bSMark Adams           if (key.j >= 0) {
25183c47955SMatthew G. Knepley             /* Get indices for coarse elements */
25283c47955SMatthew G. Knepley             for (c = 0; c < numCIndices; ++c) {
253adb2528bSMark Adams               key.i = cindices[c] + rStart; /* global cols (from Swarm) */
254adb2528bSMark Adams               if (key.i < 0) continue;
255e8f14785SLisandro Dalcin               ierr = PetscHSetIJQueryAdd(ht, key, &missing);CHKERRQ(ierr);
25683c47955SMatthew G. Knepley               if (missing) {
2570643ed39SMatthew G. Knepley                 if ((key.j >= colStart) && (key.j < colEnd)) ++dnz[key.i - rStart];
258e8f14785SLisandro Dalcin                 else                                         ++onz[key.i - rStart];
2590643ed39SMatthew G. Knepley               } else SETERRQ2(PetscObjectComm((PetscObject) dmf), PETSC_ERR_SUP, "Set new value at %D,%D", key.i, key.j);
26083c47955SMatthew G. Knepley             }
261fc7c92abSMatthew G. Knepley           }
262fc7c92abSMatthew G. Knepley         }
26383c47955SMatthew G. Knepley         ierr = PetscFree(cindices);CHKERRQ(ierr);
26483c47955SMatthew G. Knepley       }
26583c47955SMatthew G. Knepley       ierr = DMPlexRestoreClosureIndices(dmf, fsection, globalFSection, cell, &numFIndices, &findices, NULL);CHKERRQ(ierr);
26683c47955SMatthew G. Knepley     }
26783c47955SMatthew G. Knepley   }
268e8f14785SLisandro Dalcin   ierr = PetscHSetIJDestroy(&ht);CHKERRQ(ierr);
26983c47955SMatthew G. Knepley   ierr = MatXAIJSetPreallocation(mass, 1, dnz, onz, NULL, NULL);CHKERRQ(ierr);
27083c47955SMatthew G. Knepley   ierr = MatSetOption(mass, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_TRUE);CHKERRQ(ierr);
27183c47955SMatthew G. Knepley   ierr = PetscFree2(dnz, onz);CHKERRQ(ierr);
272adb2528bSMark Adams   ierr = PetscMalloc3(maxC*totDim, &elemMat, maxC, &rowIDXs, maxC*dim, &xi);CHKERRQ(ierr);
27383c47955SMatthew G. Knepley   for (field = 0; field < Nf; ++field) {
274ef0bb6c7SMatthew G. Knepley     PetscTabulation Tcoarse;
27583c47955SMatthew G. Knepley     PetscObject       obj;
276ef0bb6c7SMatthew G. Knepley     PetscReal        *coords;
2770643ed39SMatthew G. Knepley     PetscInt          Nc, i;
27883c47955SMatthew G. Knepley 
27983c47955SMatthew G. Knepley     ierr = PetscDSGetDiscretization(prob, field, &obj);CHKERRQ(ierr);
2800643ed39SMatthew G. Knepley     ierr = PetscFEGetNumComponents((PetscFE) obj, &Nc);CHKERRQ(ierr);
2810643ed39SMatthew G. Knepley     if (Nc != 1) SETERRQ1(PetscObjectComm((PetscObject) dmf), PETSC_ERR_SUP, "Can only interpolate a scalar field from particles, Nc = %D", Nc);
2820643ed39SMatthew G. Knepley     ierr = DMSwarmGetField(dmc, DMSwarmPICField_coor, NULL, NULL, (void **) &coords);CHKERRQ(ierr);
28383c47955SMatthew G. Knepley     for (cell = cStart; cell < cEnd; ++cell) {
28483c47955SMatthew G. Knepley       PetscInt *findices  , *cindices;
28583c47955SMatthew G. Knepley       PetscInt  numFIndices, numCIndices;
2860643ed39SMatthew G. Knepley       PetscInt  p, c;
28783c47955SMatthew G. Knepley 
2880643ed39SMatthew G. Knepley       /* TODO: Use DMField instead of assuming affine */
28983c47955SMatthew G. Knepley       ierr = DMPlexComputeCellGeometryFEM(dmf, cell, NULL, v0, J, invJ, &detJ);CHKERRQ(ierr);
29083c47955SMatthew G. Knepley       ierr = DMPlexGetClosureIndices(dmf, fsection, globalFSection, cell, &numFIndices, &findices, NULL);CHKERRQ(ierr);
29183c47955SMatthew G. Knepley       ierr = DMSwarmSortGetPointsPerCell(dmc, cell, &numCIndices, &cindices);CHKERRQ(ierr);
2920643ed39SMatthew G. Knepley       for (p = 0; p < numCIndices; ++p) {
2930643ed39SMatthew G. Knepley         CoordinatesRealToRef(dim, dim, v0ref, v0, invJ, &coords[cindices[p]*dim], &xi[p*dim]);
2940643ed39SMatthew G. Knepley       }
295ef0bb6c7SMatthew G. Knepley       ierr = PetscFECreateTabulation((PetscFE) obj, 1, numCIndices, xi, 0, &Tcoarse);CHKERRQ(ierr);
29683c47955SMatthew G. Knepley       /* Get elemMat entries by multiplying by weight */
297580bdb30SBarry Smith       ierr = PetscArrayzero(elemMat, numCIndices*totDim);CHKERRQ(ierr);
29883c47955SMatthew G. Knepley       for (i = 0; i < numFIndices; ++i) {
2990643ed39SMatthew G. Knepley         for (p = 0; p < numCIndices; ++p) {
3000643ed39SMatthew G. Knepley           for (c = 0; c < Nc; ++c) {
3010643ed39SMatthew G. Knepley             /* B[(p*pdim + i)*Nc + c] is the value at point p for basis function i and component c */
302ef0bb6c7SMatthew G. Knepley             elemMat[p*numFIndices+i] += Tcoarse->T[0][(p*numFIndices + i)*Nc + c]*(useDeltaFunction ? 1.0 : detJ);
30383c47955SMatthew G. Knepley           }
3040643ed39SMatthew G. Knepley         }
3050643ed39SMatthew G. Knepley       }
306adb2528bSMark Adams       for (p = 0; p < numCIndices; ++p) rowIDXs[p] = cindices[p] + rStart;
30783c47955SMatthew G. Knepley       if (0) {ierr = DMPrintCellMatrix(cell, name, 1, numCIndices, elemMat);CHKERRQ(ierr);}
308adb2528bSMark Adams       ierr = MatSetValues(mass, numCIndices, rowIDXs, numFIndices, findices, elemMat, ADD_VALUES);CHKERRQ(ierr);
30983c47955SMatthew G. Knepley       ierr = PetscFree(cindices);CHKERRQ(ierr);
31083c47955SMatthew G. Knepley       ierr = DMPlexRestoreClosureIndices(dmf, fsection, globalFSection, cell, &numFIndices, &findices, NULL);CHKERRQ(ierr);
311ef0bb6c7SMatthew G. Knepley       ierr = PetscTabulationDestroy(&Tcoarse);CHKERRQ(ierr);
31283c47955SMatthew G. Knepley     }
3130643ed39SMatthew G. Knepley     ierr = DMSwarmRestoreField(dmc, DMSwarmPICField_coor, NULL, NULL, (void **) &coords);CHKERRQ(ierr);
31483c47955SMatthew G. Knepley   }
315adb2528bSMark Adams   ierr = PetscFree3(elemMat, rowIDXs, xi);CHKERRQ(ierr);
31683c47955SMatthew G. Knepley   ierr = DMSwarmSortRestoreAccess(dmc);CHKERRQ(ierr);
31783c47955SMatthew G. Knepley   ierr = PetscFree3(v0, J, invJ);CHKERRQ(ierr);
31883c47955SMatthew G. Knepley   ierr = MatAssemblyBegin(mass, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
31983c47955SMatthew G. Knepley   ierr = MatAssemblyEnd(mass, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
32083c47955SMatthew G. Knepley   PetscFunctionReturn(0);
32183c47955SMatthew G. Knepley }
32283c47955SMatthew G. Knepley 
323adb2528bSMark Adams /* FEM cols, Particle rows */
32483c47955SMatthew G. Knepley static PetscErrorCode DMCreateMassMatrix_Swarm(DM dmCoarse, DM dmFine, Mat *mass)
32583c47955SMatthew G. Knepley {
326895a1698SMatthew G. Knepley   PetscSection   gsf;
32783c47955SMatthew G. Knepley   PetscInt       m, n;
32883c47955SMatthew G. Knepley   void          *ctx;
32983c47955SMatthew G. Knepley   PetscErrorCode ierr;
33083c47955SMatthew G. Knepley 
33183c47955SMatthew G. Knepley   PetscFunctionBegin;
332e87a4003SBarry Smith   ierr = DMGetGlobalSection(dmFine, &gsf);CHKERRQ(ierr);
33383c47955SMatthew G. Knepley   ierr = PetscSectionGetConstrainedStorageSize(gsf, &m);CHKERRQ(ierr);
334895a1698SMatthew G. Knepley   ierr = DMSwarmGetLocalSize(dmCoarse, &n);CHKERRQ(ierr);
33583c47955SMatthew G. Knepley   ierr = MatCreate(PetscObjectComm((PetscObject) dmCoarse), mass);CHKERRQ(ierr);
336adb2528bSMark Adams   ierr = MatSetSizes(*mass, n, m, PETSC_DETERMINE, PETSC_DETERMINE);CHKERRQ(ierr);
33783c47955SMatthew G. Knepley   ierr = MatSetType(*mass, dmCoarse->mattype);CHKERRQ(ierr);
33883c47955SMatthew G. Knepley   ierr = DMGetApplicationContext(dmFine, &ctx);CHKERRQ(ierr);
33983c47955SMatthew G. Knepley 
3400643ed39SMatthew G. Knepley   ierr = DMSwarmComputeMassMatrix_Private(dmCoarse, dmFine, *mass, PETSC_TRUE, ctx);CHKERRQ(ierr);
34183c47955SMatthew G. Knepley   ierr = MatViewFromOptions(*mass, NULL, "-mass_mat_view");CHKERRQ(ierr);
34283c47955SMatthew G. Knepley   PetscFunctionReturn(0);
34383c47955SMatthew G. Knepley }
34483c47955SMatthew G. Knepley 
345fb1bcc12SMatthew G. Knepley /*@C
346d3a51819SDave May    DMSwarmCreateGlobalVectorFromField - Creates a Vec object sharing the array associated with a given field
347d3a51819SDave May 
348d083f849SBarry Smith    Collective on dm
349d3a51819SDave May 
350d3a51819SDave May    Input parameters:
35162741f57SDave May +  dm - a DMSwarm
35262741f57SDave May -  fieldname - the textual name given to a registered field
353d3a51819SDave May 
3548b8a3813SDave May    Output parameter:
355d3a51819SDave May .  vec - the vector
356d3a51819SDave May 
357d3a51819SDave May    Level: beginner
358d3a51819SDave May 
3598b8a3813SDave May    Notes:
3608b8a3813SDave May    The vector must be returned using a matching call to DMSwarmDestroyGlobalVectorFromField().
3618b8a3813SDave May 
3628b8a3813SDave May .seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmDestroyGlobalVectorFromField()
363d3a51819SDave May @*/
364b5bcf523SDave May PETSC_EXTERN PetscErrorCode DMSwarmCreateGlobalVectorFromField(DM dm,const char fieldname[],Vec *vec)
365b5bcf523SDave May {
366fb1bcc12SMatthew G. Knepley   MPI_Comm       comm = PetscObjectComm((PetscObject) dm);
367b5bcf523SDave May   PetscErrorCode ierr;
368b5bcf523SDave May 
369fb1bcc12SMatthew G. Knepley   PetscFunctionBegin;
370fb1bcc12SMatthew G. Knepley   ierr = DMSwarmCreateVectorFromField_Private(dm, fieldname, comm, vec);CHKERRQ(ierr);
371b5bcf523SDave May   PetscFunctionReturn(0);
372b5bcf523SDave May }
373b5bcf523SDave May 
374d3a51819SDave May /*@C
375d3a51819SDave May    DMSwarmDestroyGlobalVectorFromField - Destroys the Vec object which share the array associated with a given field
376d3a51819SDave May 
377d083f849SBarry Smith    Collective on dm
378d3a51819SDave May 
379d3a51819SDave May    Input parameters:
38062741f57SDave May +  dm - a DMSwarm
38162741f57SDave May -  fieldname - the textual name given to a registered field
382d3a51819SDave May 
3838b8a3813SDave May    Output parameter:
384d3a51819SDave May .  vec - the vector
385d3a51819SDave May 
386d3a51819SDave May    Level: beginner
387d3a51819SDave May 
3888b8a3813SDave May .seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmCreateGlobalVectorFromField()
389d3a51819SDave May @*/
390b5bcf523SDave May PETSC_EXTERN PetscErrorCode DMSwarmDestroyGlobalVectorFromField(DM dm,const char fieldname[],Vec *vec)
391b5bcf523SDave May {
392b5bcf523SDave May   PetscErrorCode ierr;
393cc651181SDave May 
394fb1bcc12SMatthew G. Knepley   PetscFunctionBegin;
395fb1bcc12SMatthew G. Knepley   ierr = DMSwarmDestroyVectorFromField_Private(dm, fieldname, vec);CHKERRQ(ierr);
396b5bcf523SDave May   PetscFunctionReturn(0);
397b5bcf523SDave May }
398b5bcf523SDave May 
399fb1bcc12SMatthew G. Knepley /*@C
400fb1bcc12SMatthew G. Knepley    DMSwarmCreateLocalVectorFromField - Creates a Vec object sharing the array associated with a given field
401fb1bcc12SMatthew G. Knepley 
402d083f849SBarry Smith    Collective on dm
403fb1bcc12SMatthew G. Knepley 
404fb1bcc12SMatthew G. Knepley    Input parameters:
40562741f57SDave May +  dm - a DMSwarm
40662741f57SDave May -  fieldname - the textual name given to a registered field
407fb1bcc12SMatthew G. Knepley 
4088b8a3813SDave May    Output parameter:
409fb1bcc12SMatthew G. Knepley .  vec - the vector
410fb1bcc12SMatthew G. Knepley 
411fb1bcc12SMatthew G. Knepley    Level: beginner
412fb1bcc12SMatthew G. Knepley 
4138b8a3813SDave May    Notes:
4148b8a3813SDave May    The vector must be returned using a matching call to DMSwarmDestroyLocalVectorFromField().
4158b8a3813SDave May 
4168b8a3813SDave May .seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmDestroyLocalVectorFromField()
417fb1bcc12SMatthew G. Knepley @*/
418fb1bcc12SMatthew G. Knepley PETSC_EXTERN PetscErrorCode DMSwarmCreateLocalVectorFromField(DM dm,const char fieldname[],Vec *vec)
419bbe8250bSMatthew G. Knepley {
420fb1bcc12SMatthew G. Knepley   MPI_Comm       comm = PETSC_COMM_SELF;
421bbe8250bSMatthew G. Knepley   PetscErrorCode ierr;
422bbe8250bSMatthew G. Knepley 
423fb1bcc12SMatthew G. Knepley   PetscFunctionBegin;
424fb1bcc12SMatthew G. Knepley   ierr = DMSwarmCreateVectorFromField_Private(dm, fieldname, comm, vec);CHKERRQ(ierr);
425fb1bcc12SMatthew G. Knepley   PetscFunctionReturn(0);
426bbe8250bSMatthew G. Knepley }
427fb1bcc12SMatthew G. Knepley 
428fb1bcc12SMatthew G. Knepley /*@C
429fb1bcc12SMatthew G. Knepley    DMSwarmDestroyLocalVectorFromField - Destroys the Vec object which share the array associated with a given field
430fb1bcc12SMatthew G. Knepley 
431d083f849SBarry Smith    Collective on dm
432fb1bcc12SMatthew G. Knepley 
433fb1bcc12SMatthew G. Knepley    Input parameters:
43462741f57SDave May +  dm - a DMSwarm
43562741f57SDave May -  fieldname - the textual name given to a registered field
436fb1bcc12SMatthew G. Knepley 
4378b8a3813SDave May    Output parameter:
438fb1bcc12SMatthew G. Knepley .  vec - the vector
439fb1bcc12SMatthew G. Knepley 
440fb1bcc12SMatthew G. Knepley    Level: beginner
441fb1bcc12SMatthew G. Knepley 
4428b8a3813SDave May .seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmCreateLocalVectorFromField()
443fb1bcc12SMatthew G. Knepley @*/
444fb1bcc12SMatthew G. Knepley PETSC_EXTERN PetscErrorCode DMSwarmDestroyLocalVectorFromField(DM dm,const char fieldname[],Vec *vec)
445fb1bcc12SMatthew G. Knepley {
446fb1bcc12SMatthew G. Knepley   PetscErrorCode ierr;
447fb1bcc12SMatthew G. Knepley 
448fb1bcc12SMatthew G. Knepley   PetscFunctionBegin;
449fb1bcc12SMatthew G. Knepley   ierr = DMSwarmDestroyVectorFromField_Private(dm, fieldname, vec);CHKERRQ(ierr);
450bbe8250bSMatthew G. Knepley   PetscFunctionReturn(0);
451bbe8250bSMatthew G. Knepley }
452bbe8250bSMatthew G. Knepley 
453b5bcf523SDave May /*
454b5bcf523SDave May PETSC_EXTERN PetscErrorCode DMSwarmCreateGlobalVectorFromFields(DM dm,const PetscInt nf,const char *fieldnames[],Vec *vec)
455b5bcf523SDave May {
456b5bcf523SDave May   PetscFunctionReturn(0);
457b5bcf523SDave May }
458b5bcf523SDave May 
459b5bcf523SDave May PETSC_EXTERN PetscErrorCode DMSwarmRestoreGlobalVectorFromFields(DM dm,Vec *vec)
460b5bcf523SDave May {
461b5bcf523SDave May   PetscFunctionReturn(0);
462b5bcf523SDave May }
463b5bcf523SDave May */
464b5bcf523SDave May 
465d3a51819SDave May /*@C
466d3a51819SDave May    DMSwarmInitializeFieldRegister - Initiates the registration of fields to a DMSwarm
467d3a51819SDave May 
468d083f849SBarry Smith    Collective on dm
469d3a51819SDave May 
470d3a51819SDave May    Input parameter:
471d3a51819SDave May .  dm - a DMSwarm
472d3a51819SDave May 
473d3a51819SDave May    Level: beginner
474d3a51819SDave May 
475d3a51819SDave May    Notes:
4768b8a3813SDave May    After all fields have been registered, you must call DMSwarmFinalizeFieldRegister().
477d3a51819SDave May 
478d3a51819SDave May .seealso: DMSwarmFinalizeFieldRegister(), DMSwarmRegisterPetscDatatypeField(),
479d3a51819SDave May  DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField()
480d3a51819SDave May @*/
4815f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmInitializeFieldRegister(DM dm)
4825f50eb2eSDave May {
4835f50eb2eSDave May   DM_Swarm      *swarm = (DM_Swarm *) dm->data;
4843454631fSDave May   PetscErrorCode ierr;
4853454631fSDave May 
486521f74f9SMatthew G. Knepley   PetscFunctionBegin;
487cc651181SDave May   if (!swarm->field_registration_initialized) {
4885f50eb2eSDave May     swarm->field_registration_initialized = PETSC_TRUE;
48943f984edSMatthew G. Knepley     ierr = DMSwarmRegisterPetscDatatypeField(dm,DMSwarmField_pid,1,PETSC_INT64);CHKERRQ(ierr); /* unique identifer */
490f0cdbbbaSDave May     ierr = DMSwarmRegisterPetscDatatypeField(dm,DMSwarmField_rank,1,PETSC_INT);CHKERRQ(ierr); /* used for communication */
491cc651181SDave May   }
4925f50eb2eSDave May   PetscFunctionReturn(0);
4935f50eb2eSDave May }
4945f50eb2eSDave May 
495d3a51819SDave May /*@C
496d3a51819SDave May    DMSwarmFinalizeFieldRegister - Finalizes the registration of fields to a DMSwarm
497d3a51819SDave May 
498d083f849SBarry Smith    Collective on dm
499d3a51819SDave May 
500d3a51819SDave May    Input parameter:
501d3a51819SDave May .  dm - a DMSwarm
502d3a51819SDave May 
503d3a51819SDave May    Level: beginner
504d3a51819SDave May 
505d3a51819SDave May    Notes:
50662741f57SDave May    After DMSwarmFinalizeFieldRegister() has been called, no new fields can be defined on the DMSwarm.
507d3a51819SDave May 
508d3a51819SDave May .seealso: DMSwarmInitializeFieldRegister(), DMSwarmRegisterPetscDatatypeField(),
509d3a51819SDave May  DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField()
510d3a51819SDave May @*/
5115f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmFinalizeFieldRegister(DM dm)
5125f50eb2eSDave May {
5135f50eb2eSDave May   DM_Swarm       *swarm = (DM_Swarm*)dm->data;
5146845f8f5SDave May   PetscErrorCode ierr;
5156845f8f5SDave May 
516521f74f9SMatthew G. Knepley   PetscFunctionBegin;
517f0cdbbbaSDave May   if (!swarm->field_registration_finalized) {
51877048351SPatrick Sanan     ierr = DMSwarmDataBucketFinalize(swarm->db);CHKERRQ(ierr);
519f0cdbbbaSDave May   }
520f0cdbbbaSDave May   swarm->field_registration_finalized = PETSC_TRUE;
5215f50eb2eSDave May   PetscFunctionReturn(0);
5225f50eb2eSDave May }
5235f50eb2eSDave May 
524d3a51819SDave May /*@C
525d3a51819SDave May    DMSwarmSetLocalSizes - Sets the length of all registered fields on the DMSwarm
526d3a51819SDave May 
527d3a51819SDave May    Not collective
528d3a51819SDave May 
529d3a51819SDave May    Input parameters:
53062741f57SDave May +  dm - a DMSwarm
531d3a51819SDave May .  nlocal - the length of each registered field
53262741f57SDave May -  buffer - the length of the buffer used to efficient dynamic re-sizing
533d3a51819SDave May 
534d3a51819SDave May    Level: beginner
535d3a51819SDave May 
536d3a51819SDave May .seealso: DMSwarmGetLocalSize()
537d3a51819SDave May @*/
5385f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmSetLocalSizes(DM dm,PetscInt nlocal,PetscInt buffer)
5395f50eb2eSDave May {
5405f50eb2eSDave May   DM_Swarm       *swarm = (DM_Swarm*)dm->data;
5416845f8f5SDave May   PetscErrorCode ierr;
5425f50eb2eSDave May 
543521f74f9SMatthew G. Knepley   PetscFunctionBegin;
544f2b2bee7SDave May   ierr = PetscLogEventBegin(DMSWARM_SetSizes,0,0,0,0);CHKERRQ(ierr);
54577048351SPatrick Sanan   ierr = DMSwarmDataBucketSetSizes(swarm->db,nlocal,buffer);CHKERRQ(ierr);
546f2b2bee7SDave May   ierr = PetscLogEventEnd(DMSWARM_SetSizes,0,0,0,0);CHKERRQ(ierr);
5475f50eb2eSDave May   PetscFunctionReturn(0);
5485f50eb2eSDave May }
5495f50eb2eSDave May 
550d3a51819SDave May /*@C
551d3a51819SDave May    DMSwarmSetCellDM - Attachs a DM to a DMSwarm
552d3a51819SDave May 
553d083f849SBarry Smith    Collective on dm
554d3a51819SDave May 
555d3a51819SDave May    Input parameters:
55662741f57SDave May +  dm - a DMSwarm
55762741f57SDave May -  dmcell - the DM to attach to the DMSwarm
558d3a51819SDave May 
559d3a51819SDave May    Level: beginner
560d3a51819SDave May 
561d3a51819SDave May    Notes:
562d3a51819SDave May    The attached DM (dmcell) will be queried for point location and
5638b8a3813SDave May    neighbor MPI-rank information if DMSwarmMigrate() is called.
564d3a51819SDave May 
5658b8a3813SDave May .seealso: DMSwarmSetType(), DMSwarmGetCellDM(), DMSwarmMigrate()
566d3a51819SDave May @*/
567b16650c8SDave May PETSC_EXTERN PetscErrorCode DMSwarmSetCellDM(DM dm,DM dmcell)
568b16650c8SDave May {
569b16650c8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
570521f74f9SMatthew G. Knepley 
571521f74f9SMatthew G. Knepley   PetscFunctionBegin;
572b16650c8SDave May   swarm->dmcell = dmcell;
573b16650c8SDave May   PetscFunctionReturn(0);
574b16650c8SDave May }
575b16650c8SDave May 
576d3a51819SDave May /*@C
577d3a51819SDave May    DMSwarmGetCellDM - Fetches the attached cell DM
578d3a51819SDave May 
579d083f849SBarry Smith    Collective on dm
580d3a51819SDave May 
581d3a51819SDave May    Input parameter:
582d3a51819SDave May .  dm - a DMSwarm
583d3a51819SDave May 
584d3a51819SDave May    Output parameter:
585d3a51819SDave May .  dmcell - the DM which was attached to the DMSwarm
586d3a51819SDave May 
587d3a51819SDave May    Level: beginner
588d3a51819SDave May 
589d3a51819SDave May .seealso: DMSwarmSetCellDM()
590d3a51819SDave May @*/
591fe39f135SDave May PETSC_EXTERN PetscErrorCode DMSwarmGetCellDM(DM dm,DM *dmcell)
592fe39f135SDave May {
593fe39f135SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
594521f74f9SMatthew G. Knepley 
595521f74f9SMatthew G. Knepley   PetscFunctionBegin;
596fe39f135SDave May   *dmcell = swarm->dmcell;
597fe39f135SDave May   PetscFunctionReturn(0);
598fe39f135SDave May }
599fe39f135SDave May 
600d3a51819SDave May /*@C
601d3a51819SDave May    DMSwarmGetLocalSize - Retrives the local length of fields registered
602d3a51819SDave May 
603d3a51819SDave May    Not collective
604d3a51819SDave May 
605d3a51819SDave May    Input parameter:
606d3a51819SDave May .  dm - a DMSwarm
607d3a51819SDave May 
608d3a51819SDave May    Output parameter:
609d3a51819SDave May .  nlocal - the length of each registered field
610d3a51819SDave May 
611d3a51819SDave May    Level: beginner
612d3a51819SDave May 
6138b8a3813SDave May .seealso: DMSwarmGetSize(), DMSwarmSetLocalSizes()
614d3a51819SDave May @*/
615dcf43ee8SDave May PETSC_EXTERN PetscErrorCode DMSwarmGetLocalSize(DM dm,PetscInt *nlocal)
616dcf43ee8SDave May {
617dcf43ee8SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
618dcf43ee8SDave May   PetscErrorCode ierr;
619dcf43ee8SDave May 
620521f74f9SMatthew G. Knepley   PetscFunctionBegin;
62177048351SPatrick Sanan   if (nlocal) {ierr = DMSwarmDataBucketGetSizes(swarm->db,nlocal,NULL,NULL);CHKERRQ(ierr);}
622dcf43ee8SDave May   PetscFunctionReturn(0);
623dcf43ee8SDave May }
624dcf43ee8SDave May 
625d3a51819SDave May /*@C
626d3a51819SDave May    DMSwarmGetSize - Retrives the total length of fields registered
627d3a51819SDave May 
628d083f849SBarry Smith    Collective on dm
629d3a51819SDave May 
630d3a51819SDave May    Input parameter:
631d3a51819SDave May .  dm - a DMSwarm
632d3a51819SDave May 
633d3a51819SDave May    Output parameter:
634d3a51819SDave May .  n - the total length of each registered field
635d3a51819SDave May 
636d3a51819SDave May    Level: beginner
637d3a51819SDave May 
638d3a51819SDave May    Note:
639d3a51819SDave May    This calls MPI_Allreduce upon each call (inefficient but safe)
640d3a51819SDave May 
6418b8a3813SDave May .seealso: DMSwarmGetLocalSize(), DMSwarmSetLocalSizes()
642d3a51819SDave May @*/
643dcf43ee8SDave May PETSC_EXTERN PetscErrorCode DMSwarmGetSize(DM dm,PetscInt *n)
644dcf43ee8SDave May {
645dcf43ee8SDave May   DM_Swarm       *swarm = (DM_Swarm*)dm->data;
646dcf43ee8SDave May   PetscErrorCode ierr;
647dcf43ee8SDave May   PetscInt       nlocal,ng;
648dcf43ee8SDave May 
649521f74f9SMatthew G. Knepley   PetscFunctionBegin;
65077048351SPatrick Sanan   ierr = DMSwarmDataBucketGetSizes(swarm->db,&nlocal,NULL,NULL);CHKERRQ(ierr);
651dcf43ee8SDave May   ierr = MPI_Allreduce(&nlocal,&ng,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)dm));CHKERRQ(ierr);
652dcf43ee8SDave May   if (n) { *n = ng; }
653dcf43ee8SDave May   PetscFunctionReturn(0);
654dcf43ee8SDave May }
655dcf43ee8SDave May 
656d3a51819SDave May /*@C
6578b8a3813SDave May    DMSwarmRegisterPetscDatatypeField - Register a field to a DMSwarm with a native PETSc data type
658d3a51819SDave May 
659d083f849SBarry Smith    Collective on dm
660d3a51819SDave May 
661d3a51819SDave May    Input parameters:
66262741f57SDave May +  dm - a DMSwarm
663d3a51819SDave May .  fieldname - the textual name to identify this field
664d3a51819SDave May .  blocksize - the number of each data type
66562741f57SDave May -  type - a valid PETSc data type (PETSC_CHAR, PETSC_SHORT, PETSC_INT, PETSC_FLOAT, PETSC_REAL, PETSC_LONG)
666d3a51819SDave May 
667d3a51819SDave May    Level: beginner
668d3a51819SDave May 
669d3a51819SDave May    Notes:
6708b8a3813SDave May    The textual name for each registered field must be unique.
671d3a51819SDave May 
672d3a51819SDave May .seealso: DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField()
673d3a51819SDave May @*/
6745f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmRegisterPetscDatatypeField(DM dm,const char fieldname[],PetscInt blocksize,PetscDataType type)
675b62e03f8SDave May {
6762eac95f8SDave May   PetscErrorCode ierr;
677b62e03f8SDave May   DM_Swarm       *swarm = (DM_Swarm*)dm->data;
678b62e03f8SDave May   size_t         size;
679b62e03f8SDave May 
680521f74f9SMatthew G. Knepley   PetscFunctionBegin;
6815f50eb2eSDave May   if (!swarm->field_registration_initialized) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Must call DMSwarmInitializeFieldRegister() first");
6825f50eb2eSDave May   if (swarm->field_registration_finalized) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Cannot register additional fields after calling DMSwarmFinalizeFieldRegister() first");
6835f50eb2eSDave May 
6845f50eb2eSDave May   if (type == PETSC_OBJECT) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
6855f50eb2eSDave May   if (type == PETSC_FUNCTION) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
6865f50eb2eSDave May   if (type == PETSC_STRING) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
6875f50eb2eSDave May   if (type == PETSC_STRUCT) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
6885f50eb2eSDave May   if (type == PETSC_DATATYPE_UNKNOWN) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"Valid for {char,short,int,long,float,double}");
689b62e03f8SDave May 
6902ddcf43eSMatthew G. Knepley   ierr = PetscDataTypeGetSize(type, &size);CHKERRQ(ierr);
691b62e03f8SDave May   /* Load a specific data type into data bucket, specifying textual name and its size in bytes */
69277048351SPatrick Sanan   ierr = DMSwarmDataBucketRegisterField(swarm->db,"DMSwarmRegisterPetscDatatypeField",fieldname,blocksize*size,NULL);CHKERRQ(ierr);
69352c3ed93SDave May   {
69477048351SPatrick Sanan     DMSwarmDataField gfield;
69552c3ed93SDave May 
69677048351SPatrick Sanan     ierr = DMSwarmDataBucketGetDMSwarmDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr);
69777048351SPatrick Sanan     ierr = DMSwarmDataFieldSetBlockSize(gfield,blocksize);CHKERRQ(ierr);
69852c3ed93SDave May   }
699b62e03f8SDave May   swarm->db->field[swarm->db->nfields-1]->petsc_type = type;
700b62e03f8SDave May   PetscFunctionReturn(0);
701b62e03f8SDave May }
702b62e03f8SDave May 
703d3a51819SDave May /*@C
704d3a51819SDave May    DMSwarmRegisterUserStructField - Register a user defined struct to a DMSwarm
705d3a51819SDave May 
706d083f849SBarry Smith    Collective on dm
707d3a51819SDave May 
708d3a51819SDave May    Input parameters:
70962741f57SDave May +  dm - a DMSwarm
710d3a51819SDave May .  fieldname - the textual name to identify this field
71162741f57SDave May -  size - the size in bytes of the user struct of each data type
712d3a51819SDave May 
713d3a51819SDave May    Level: beginner
714d3a51819SDave May 
715d3a51819SDave May    Notes:
7168b8a3813SDave May    The textual name for each registered field must be unique.
717d3a51819SDave May 
718d3a51819SDave May .seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmRegisterUserDatatypeField()
719d3a51819SDave May @*/
7205f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmRegisterUserStructField(DM dm,const char fieldname[],size_t size)
721b62e03f8SDave May {
7222eac95f8SDave May   PetscErrorCode ierr;
723b62e03f8SDave May   DM_Swarm       *swarm = (DM_Swarm*)dm->data;
724b62e03f8SDave May 
725521f74f9SMatthew G. Knepley   PetscFunctionBegin;
72677048351SPatrick Sanan   ierr = DMSwarmDataBucketRegisterField(swarm->db,"DMSwarmRegisterUserStructField",fieldname,size,NULL);CHKERRQ(ierr);
727b62e03f8SDave May   swarm->db->field[swarm->db->nfields-1]->petsc_type = PETSC_STRUCT ;
728b62e03f8SDave May   PetscFunctionReturn(0);
729b62e03f8SDave May }
730b62e03f8SDave May 
731d3a51819SDave May /*@C
732d3a51819SDave May    DMSwarmRegisterUserDatatypeField - Register a user defined data type to a DMSwarm
733d3a51819SDave May 
734d083f849SBarry Smith    Collective on dm
735d3a51819SDave May 
736d3a51819SDave May    Input parameters:
73762741f57SDave May +  dm - a DMSwarm
738d3a51819SDave May .  fieldname - the textual name to identify this field
739d3a51819SDave May .  size - the size in bytes of the user data type
74062741f57SDave May -  blocksize - the number of each data type
741d3a51819SDave May 
742d3a51819SDave May    Level: beginner
743d3a51819SDave May 
744d3a51819SDave May    Notes:
7458b8a3813SDave May    The textual name for each registered field must be unique.
746d3a51819SDave May 
747d3a51819SDave May .seealso: DMSwarmRegisterPetscDatatypeField(), DMSwarmRegisterUserStructField(), DMSwarmRegisterUserDatatypeField()
748d3a51819SDave May @*/
749320740a0SDave May PETSC_EXTERN PetscErrorCode DMSwarmRegisterUserDatatypeField(DM dm,const char fieldname[],size_t size,PetscInt blocksize)
750b62e03f8SDave May {
751b62e03f8SDave May   DM_Swarm       *swarm = (DM_Swarm*)dm->data;
7526845f8f5SDave May   PetscErrorCode ierr;
753b62e03f8SDave May 
754521f74f9SMatthew G. Knepley   PetscFunctionBegin;
75577048351SPatrick Sanan   ierr = DMSwarmDataBucketRegisterField(swarm->db,"DMSwarmRegisterUserDatatypeField",fieldname,blocksize*size,NULL);CHKERRQ(ierr);
756320740a0SDave May   {
75777048351SPatrick Sanan     DMSwarmDataField gfield;
758320740a0SDave May 
75977048351SPatrick Sanan     ierr = DMSwarmDataBucketGetDMSwarmDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr);
76077048351SPatrick Sanan     ierr = DMSwarmDataFieldSetBlockSize(gfield,blocksize);CHKERRQ(ierr);
761320740a0SDave May   }
762b62e03f8SDave May   swarm->db->field[swarm->db->nfields-1]->petsc_type = PETSC_DATATYPE_UNKNOWN;
763b62e03f8SDave May   PetscFunctionReturn(0);
764b62e03f8SDave May }
765b62e03f8SDave May 
766d3a51819SDave May /*@C
767d3a51819SDave May    DMSwarmGetField - Get access to the underlying array storing all entries associated with a registered field
768d3a51819SDave May 
769d3a51819SDave May    Not collective
770d3a51819SDave May 
771d3a51819SDave May    Input parameters:
77262741f57SDave May +  dm - a DMSwarm
77362741f57SDave May -  fieldname - the textual name to identify this field
774d3a51819SDave May 
775d3a51819SDave May    Output parameters:
77662741f57SDave May +  blocksize - the number of each data type
777d3a51819SDave May .  type - the data type
77862741f57SDave May -  data - pointer to raw array
779d3a51819SDave May 
780d3a51819SDave May    Level: beginner
781d3a51819SDave May 
782d3a51819SDave May    Notes:
7838b8a3813SDave May    The array must be returned using a matching call to DMSwarmRestoreField().
784d3a51819SDave May 
785d3a51819SDave May .seealso: DMSwarmRestoreField()
786d3a51819SDave May @*/
7875f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmGetField(DM dm,const char fieldname[],PetscInt *blocksize,PetscDataType *type,void **data)
788b62e03f8SDave May {
789b62e03f8SDave May   DM_Swarm         *swarm = (DM_Swarm*)dm->data;
79077048351SPatrick Sanan   DMSwarmDataField gfield;
7912eac95f8SDave May   PetscErrorCode ierr;
792b62e03f8SDave May 
793521f74f9SMatthew G. Knepley   PetscFunctionBegin;
7943454631fSDave May   if (!swarm->issetup) { ierr = DMSetUp(dm);CHKERRQ(ierr); }
79577048351SPatrick Sanan   ierr = DMSwarmDataBucketGetDMSwarmDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr);
79677048351SPatrick Sanan   ierr = DMSwarmDataFieldGetAccess(gfield);CHKERRQ(ierr);
79777048351SPatrick Sanan   ierr = DMSwarmDataFieldGetEntries(gfield,data);CHKERRQ(ierr);
7981b1ea282SDave May   if (blocksize) {*blocksize = gfield->bs; }
799b5bcf523SDave May   if (type) { *type = gfield->petsc_type; }
800b62e03f8SDave May   PetscFunctionReturn(0);
801b62e03f8SDave May }
802b62e03f8SDave May 
803d3a51819SDave May /*@C
804d3a51819SDave May    DMSwarmRestoreField - Restore access to the underlying array storing all entries associated with a registered field
805d3a51819SDave May 
806d3a51819SDave May    Not collective
807d3a51819SDave May 
808d3a51819SDave May    Input parameters:
80962741f57SDave May +  dm - a DMSwarm
81062741f57SDave May -  fieldname - the textual name to identify this field
811d3a51819SDave May 
812d3a51819SDave May    Output parameters:
81362741f57SDave May +  blocksize - the number of each data type
814d3a51819SDave May .  type - the data type
81562741f57SDave May -  data - pointer to raw array
816d3a51819SDave May 
817d3a51819SDave May    Level: beginner
818d3a51819SDave May 
819d3a51819SDave May    Notes:
8208b8a3813SDave May    The user must call DMSwarmGetField() prior to calling DMSwarmRestoreField().
821d3a51819SDave May 
822d3a51819SDave May .seealso: DMSwarmGetField()
823d3a51819SDave May @*/
8245f50eb2eSDave May PETSC_EXTERN PetscErrorCode DMSwarmRestoreField(DM dm,const char fieldname[],PetscInt *blocksize,PetscDataType *type,void **data)
825b62e03f8SDave May {
826b62e03f8SDave May   DM_Swarm         *swarm = (DM_Swarm*)dm->data;
82777048351SPatrick Sanan   DMSwarmDataField gfield;
8282eac95f8SDave May   PetscErrorCode ierr;
829b62e03f8SDave May 
830521f74f9SMatthew G. Knepley   PetscFunctionBegin;
83177048351SPatrick Sanan   ierr = DMSwarmDataBucketGetDMSwarmDataFieldByName(swarm->db,fieldname,&gfield);CHKERRQ(ierr);
83277048351SPatrick Sanan   ierr = DMSwarmDataFieldRestoreAccess(gfield);CHKERRQ(ierr);
833b62e03f8SDave May   if (data) *data = NULL;
834b62e03f8SDave May   PetscFunctionReturn(0);
835b62e03f8SDave May }
836b62e03f8SDave May 
837d3a51819SDave May /*@C
838d3a51819SDave May    DMSwarmAddPoint - Add space for one new point in the DMSwarm
839d3a51819SDave May 
840d3a51819SDave May    Not collective
841d3a51819SDave May 
842d3a51819SDave May    Input parameter:
843d3a51819SDave May .  dm - a DMSwarm
844d3a51819SDave May 
845d3a51819SDave May    Level: beginner
846d3a51819SDave May 
847d3a51819SDave May    Notes:
8488b8a3813SDave May    The new point will have all fields initialized to zero.
849d3a51819SDave May 
850d3a51819SDave May .seealso: DMSwarmAddNPoints()
851d3a51819SDave May @*/
852cb1d1399SDave May PETSC_EXTERN PetscErrorCode DMSwarmAddPoint(DM dm)
853cb1d1399SDave May {
854cb1d1399SDave May   DM_Swarm       *swarm = (DM_Swarm*)dm->data;
855cb1d1399SDave May   PetscErrorCode ierr;
856cb1d1399SDave May 
857521f74f9SMatthew G. Knepley   PetscFunctionBegin;
8583454631fSDave May   if (!swarm->issetup) {ierr = DMSetUp(dm);CHKERRQ(ierr);}
859f2b2bee7SDave May   ierr = PetscLogEventBegin(DMSWARM_AddPoints,0,0,0,0);CHKERRQ(ierr);
86077048351SPatrick Sanan   ierr = DMSwarmDataBucketAddPoint(swarm->db);CHKERRQ(ierr);
861f2b2bee7SDave May   ierr = PetscLogEventEnd(DMSWARM_AddPoints,0,0,0,0);CHKERRQ(ierr);
862cb1d1399SDave May   PetscFunctionReturn(0);
863cb1d1399SDave May }
864cb1d1399SDave May 
865d3a51819SDave May /*@C
866d3a51819SDave May    DMSwarmAddNPoints - Add space for a number of new points in the DMSwarm
867d3a51819SDave May 
868d3a51819SDave May    Not collective
869d3a51819SDave May 
870d3a51819SDave May    Input parameters:
87162741f57SDave May +  dm - a DMSwarm
87262741f57SDave May -  npoints - the number of new points to add
873d3a51819SDave May 
874d3a51819SDave May    Level: beginner
875d3a51819SDave May 
876d3a51819SDave May    Notes:
8778b8a3813SDave May    The new point will have all fields initialized to zero.
878d3a51819SDave May 
879d3a51819SDave May .seealso: DMSwarmAddPoint()
880d3a51819SDave May @*/
881cb1d1399SDave May PETSC_EXTERN PetscErrorCode DMSwarmAddNPoints(DM dm,PetscInt npoints)
882cb1d1399SDave May {
883cb1d1399SDave May   DM_Swarm       *swarm = (DM_Swarm*)dm->data;
884cb1d1399SDave May   PetscErrorCode ierr;
885cb1d1399SDave May   PetscInt       nlocal;
886cb1d1399SDave May 
887521f74f9SMatthew G. Knepley   PetscFunctionBegin;
888f2b2bee7SDave May   ierr = PetscLogEventBegin(DMSWARM_AddPoints,0,0,0,0);CHKERRQ(ierr);
88977048351SPatrick Sanan   ierr = DMSwarmDataBucketGetSizes(swarm->db,&nlocal,NULL,NULL);CHKERRQ(ierr);
890cb1d1399SDave May   nlocal = nlocal + npoints;
89177048351SPatrick Sanan   ierr = DMSwarmDataBucketSetSizes(swarm->db,nlocal,DMSWARM_DATA_BUCKET_BUFFER_DEFAULT);CHKERRQ(ierr);
892f2b2bee7SDave May   ierr = PetscLogEventEnd(DMSWARM_AddPoints,0,0,0,0);CHKERRQ(ierr);
893cb1d1399SDave May   PetscFunctionReturn(0);
894cb1d1399SDave May }
895cb1d1399SDave May 
896d3a51819SDave May /*@C
897d3a51819SDave May    DMSwarmRemovePoint - Remove the last point from the DMSwarm
898d3a51819SDave May 
899d3a51819SDave May    Not collective
900d3a51819SDave May 
901d3a51819SDave May    Input parameter:
902d3a51819SDave May .  dm - a DMSwarm
903d3a51819SDave May 
904d3a51819SDave May    Level: beginner
905d3a51819SDave May 
906d3a51819SDave May .seealso: DMSwarmRemovePointAtIndex()
907d3a51819SDave May @*/
908cb1d1399SDave May PETSC_EXTERN PetscErrorCode DMSwarmRemovePoint(DM dm)
909cb1d1399SDave May {
910cb1d1399SDave May   DM_Swarm       *swarm = (DM_Swarm*)dm->data;
911cb1d1399SDave May   PetscErrorCode ierr;
912cb1d1399SDave May 
913521f74f9SMatthew G. Knepley   PetscFunctionBegin;
914f2b2bee7SDave May   ierr = PetscLogEventBegin(DMSWARM_RemovePoints,0,0,0,0);CHKERRQ(ierr);
91577048351SPatrick Sanan   ierr = DMSwarmDataBucketRemovePoint(swarm->db);CHKERRQ(ierr);
916f2b2bee7SDave May   ierr = PetscLogEventEnd(DMSWARM_RemovePoints,0,0,0,0);CHKERRQ(ierr);
917cb1d1399SDave May   PetscFunctionReturn(0);
918cb1d1399SDave May }
919cb1d1399SDave May 
920d3a51819SDave May /*@C
921d3a51819SDave May    DMSwarmRemovePointAtIndex - Removes a specific point from the DMSwarm
922d3a51819SDave May 
923d3a51819SDave May    Not collective
924d3a51819SDave May 
925d3a51819SDave May    Input parameters:
92662741f57SDave May +  dm - a DMSwarm
92762741f57SDave May -  idx - index of point to remove
928d3a51819SDave May 
929d3a51819SDave May    Level: beginner
930d3a51819SDave May 
931d3a51819SDave May .seealso: DMSwarmRemovePoint()
932d3a51819SDave May @*/
933cb1d1399SDave May PETSC_EXTERN PetscErrorCode DMSwarmRemovePointAtIndex(DM dm,PetscInt idx)
934cb1d1399SDave May {
935cb1d1399SDave May   DM_Swarm       *swarm = (DM_Swarm*)dm->data;
936cb1d1399SDave May   PetscErrorCode ierr;
937cb1d1399SDave May 
938521f74f9SMatthew G. Knepley   PetscFunctionBegin;
939f2b2bee7SDave May   ierr = PetscLogEventBegin(DMSWARM_RemovePoints,0,0,0,0);CHKERRQ(ierr);
94077048351SPatrick Sanan   ierr = DMSwarmDataBucketRemovePointAtIndex(swarm->db,idx);CHKERRQ(ierr);
941f2b2bee7SDave May   ierr = PetscLogEventEnd(DMSWARM_RemovePoints,0,0,0,0);CHKERRQ(ierr);
942cb1d1399SDave May   PetscFunctionReturn(0);
943cb1d1399SDave May }
944b62e03f8SDave May 
945ba4fc9c6SDave May /*@C
946ba4fc9c6SDave May    DMSwarmCopyPoint - Copy point pj to point pi in the DMSwarm
947ba4fc9c6SDave May 
948ba4fc9c6SDave May    Not collective
949ba4fc9c6SDave May 
950ba4fc9c6SDave May    Input parameters:
951ba4fc9c6SDave May +  dm - a DMSwarm
952ba4fc9c6SDave May .  pi - the index of the point to copy
953ba4fc9c6SDave May -  pj - the point index where the copy should be located
954ba4fc9c6SDave May 
955ba4fc9c6SDave May  Level: beginner
956ba4fc9c6SDave May 
957ba4fc9c6SDave May .seealso: DMSwarmRemovePoint()
958ba4fc9c6SDave May @*/
959ba4fc9c6SDave May PETSC_EXTERN PetscErrorCode DMSwarmCopyPoint(DM dm,PetscInt pi,PetscInt pj)
960ba4fc9c6SDave May {
961ba4fc9c6SDave May   DM_Swarm       *swarm = (DM_Swarm*)dm->data;
962ba4fc9c6SDave May   PetscErrorCode ierr;
963ba4fc9c6SDave May 
964ba4fc9c6SDave May   PetscFunctionBegin;
965ba4fc9c6SDave May   if (!swarm->issetup) {ierr = DMSetUp(dm);CHKERRQ(ierr);}
96677048351SPatrick Sanan   ierr = DMSwarmDataBucketCopyPoint(swarm->db,pi,swarm->db,pj);CHKERRQ(ierr);
967ba4fc9c6SDave May   PetscFunctionReturn(0);
968ba4fc9c6SDave May }
969ba4fc9c6SDave May 
970095059a4SDave May PetscErrorCode DMSwarmMigrate_Basic(DM dm,PetscBool remove_sent_points)
9713454631fSDave May {
972dcf43ee8SDave May   PetscErrorCode ierr;
973521f74f9SMatthew G. Knepley 
974521f74f9SMatthew G. Knepley   PetscFunctionBegin;
975dcf43ee8SDave May   ierr = DMSwarmMigrate_Push_Basic(dm,remove_sent_points);CHKERRQ(ierr);
9763454631fSDave May   PetscFunctionReturn(0);
9773454631fSDave May }
9783454631fSDave May 
979d3a51819SDave May /*@C
980d3a51819SDave May    DMSwarmMigrate - Relocates points defined in the DMSwarm to other MPI-ranks
981d3a51819SDave May 
982d083f849SBarry Smith    Collective on dm
983d3a51819SDave May 
984d3a51819SDave May    Input parameters:
98562741f57SDave May +  dm - the DMSwarm
98662741f57SDave May -  remove_sent_points - flag indicating if sent points should be removed from the current MPI-rank
987d3a51819SDave May 
988d3a51819SDave May    Notes:
9898b8a3813SDave May    The DM will be modified to accomodate received points.
9908b8a3813SDave May    If remove_sent_points = PETSC_TRUE, any points that were sent will be removed from the DM.
9918b8a3813SDave May    Different styles of migration are supported. See DMSwarmSetMigrateType().
992d3a51819SDave May 
993d3a51819SDave May    Level: advanced
994d3a51819SDave May 
995d3a51819SDave May .seealso: DMSwarmSetMigrateType()
996d3a51819SDave May @*/
997095059a4SDave May PETSC_EXTERN PetscErrorCode DMSwarmMigrate(DM dm,PetscBool remove_sent_points)
9983454631fSDave May {
999f0cdbbbaSDave May   DM_Swarm       *swarm = (DM_Swarm*)dm->data;
10003454631fSDave May   PetscErrorCode ierr;
1001f0cdbbbaSDave May 
1002521f74f9SMatthew G. Knepley   PetscFunctionBegin;
1003ed923d71SDave May   ierr = PetscLogEventBegin(DMSWARM_Migrate,0,0,0,0);CHKERRQ(ierr);
1004f0cdbbbaSDave May   switch (swarm->migrate_type) {
1005f0cdbbbaSDave May     case DMSWARM_MIGRATE_BASIC:
1006095059a4SDave May       ierr = DMSwarmMigrate_Basic(dm,remove_sent_points);CHKERRQ(ierr);
1007f0cdbbbaSDave May       break;
1008f0cdbbbaSDave May     case DMSWARM_MIGRATE_DMCELLNSCATTER:
1009f0cdbbbaSDave May       ierr = DMSwarmMigrate_CellDMScatter(dm,remove_sent_points);CHKERRQ(ierr);
1010f0cdbbbaSDave May       break;
1011f0cdbbbaSDave May     case DMSWARM_MIGRATE_DMCELLEXACT:
1012f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_MIGRATE_DMCELLEXACT not implemented");
1013f0cdbbbaSDave May       break;
1014f0cdbbbaSDave May     case DMSWARM_MIGRATE_USER:
1015f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_MIGRATE_USER not implemented");
1016f0cdbbbaSDave May       break;
1017f0cdbbbaSDave May     default:
1018f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_MIGRATE type unknown");
1019f0cdbbbaSDave May       break;
1020f0cdbbbaSDave May   }
1021ed923d71SDave May   ierr = PetscLogEventEnd(DMSWARM_Migrate,0,0,0,0);CHKERRQ(ierr);
10223454631fSDave May   PetscFunctionReturn(0);
10233454631fSDave May }
10243454631fSDave May 
1025f0cdbbbaSDave May PetscErrorCode DMSwarmMigrate_GlobalToLocal_Basic(DM dm,PetscInt *globalsize);
1026f0cdbbbaSDave May 
1027d3a51819SDave May /*
1028d3a51819SDave May  DMSwarmCollectViewCreate
1029d3a51819SDave May 
1030d3a51819SDave May  * Applies a collection method and gathers point neighbour points into dm
1031d3a51819SDave May 
1032d3a51819SDave May  Notes:
10338b8a3813SDave May  Users should call DMSwarmCollectViewDestroy() after
1034d3a51819SDave May  they have finished computations associated with the collected points
1035d3a51819SDave May */
1036d3a51819SDave May 
1037d3a51819SDave May /*@C
1038d3a51819SDave May    DMSwarmCollectViewCreate - Applies a collection method and gathers points
1039d3a51819SDave May    in neighbour MPI-ranks into the DMSwarm
1040d3a51819SDave May 
1041d083f849SBarry Smith    Collective on dm
1042d3a51819SDave May 
1043d3a51819SDave May    Input parameter:
1044d3a51819SDave May .  dm - the DMSwarm
1045d3a51819SDave May 
1046d3a51819SDave May    Notes:
1047d3a51819SDave May    Users should call DMSwarmCollectViewDestroy() after
1048d3a51819SDave May    they have finished computations associated with the collected points
10498b8a3813SDave May    Different collect methods are supported. See DMSwarmSetCollectType().
1050d3a51819SDave May 
1051d3a51819SDave May    Level: advanced
1052d3a51819SDave May 
1053d3a51819SDave May .seealso: DMSwarmCollectViewDestroy(), DMSwarmSetCollectType()
1054d3a51819SDave May @*/
1055fe39f135SDave May PETSC_EXTERN PetscErrorCode DMSwarmCollectViewCreate(DM dm)
10562712d1f2SDave May {
10572712d1f2SDave May   PetscErrorCode ierr;
10582712d1f2SDave May   DM_Swarm *swarm = (DM_Swarm*)dm->data;
10592712d1f2SDave May   PetscInt ng;
10602712d1f2SDave May 
1061521f74f9SMatthew G. Knepley   PetscFunctionBegin;
1062480eef7bSDave May   if (swarm->collect_view_active) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"CollectView currently active");
1063480eef7bSDave May   ierr = DMSwarmGetLocalSize(dm,&ng);CHKERRQ(ierr);
1064480eef7bSDave May   switch (swarm->collect_type) {
1065f0cdbbbaSDave May 
1066480eef7bSDave May     case DMSWARM_COLLECT_BASIC:
10672712d1f2SDave May       ierr = DMSwarmMigrate_GlobalToLocal_Basic(dm,&ng);CHKERRQ(ierr);
1068480eef7bSDave May       break;
1069480eef7bSDave May     case DMSWARM_COLLECT_DMDABOUNDINGBOX:
1070f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_COLLECT_DMDABOUNDINGBOX not implemented");
1071480eef7bSDave May       break;
1072480eef7bSDave May     case DMSWARM_COLLECT_GENERAL:
1073f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_COLLECT_GENERAL not implemented");
1074480eef7bSDave May       break;
1075480eef7bSDave May     default:
1076f0cdbbbaSDave May       SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"DMSWARM_COLLECT type unknown");
1077480eef7bSDave May       break;
1078480eef7bSDave May   }
1079480eef7bSDave May   swarm->collect_view_active = PETSC_TRUE;
1080480eef7bSDave May   swarm->collect_view_reset_nlocal = ng;
10812712d1f2SDave May   PetscFunctionReturn(0);
10822712d1f2SDave May }
10832712d1f2SDave May 
1084d3a51819SDave May /*@C
1085d3a51819SDave May    DMSwarmCollectViewDestroy - Resets the DMSwarm to the size prior to calling DMSwarmCollectViewCreate()
1086d3a51819SDave May 
1087d083f849SBarry Smith    Collective on dm
1088d3a51819SDave May 
1089d3a51819SDave May    Input parameters:
1090d3a51819SDave May .  dm - the DMSwarm
1091d3a51819SDave May 
1092d3a51819SDave May    Notes:
1093d3a51819SDave May    Users should call DMSwarmCollectViewCreate() before this function is called.
1094d3a51819SDave May 
1095d3a51819SDave May    Level: advanced
1096d3a51819SDave May 
1097d3a51819SDave May .seealso: DMSwarmCollectViewCreate(), DMSwarmSetCollectType()
1098d3a51819SDave May @*/
1099fe39f135SDave May PETSC_EXTERN PetscErrorCode DMSwarmCollectViewDestroy(DM dm)
11002712d1f2SDave May {
11012712d1f2SDave May   PetscErrorCode ierr;
11022712d1f2SDave May   DM_Swarm       *swarm = (DM_Swarm*)dm->data;
11032712d1f2SDave May 
1104521f74f9SMatthew G. Knepley   PetscFunctionBegin;
1105480eef7bSDave May   if (!swarm->collect_view_active) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"CollectView is currently not active");
1106480eef7bSDave May   ierr = DMSwarmSetLocalSizes(dm,swarm->collect_view_reset_nlocal,-1);CHKERRQ(ierr);
1107480eef7bSDave May   swarm->collect_view_active = PETSC_FALSE;
11082712d1f2SDave May   PetscFunctionReturn(0);
11092712d1f2SDave May }
11103454631fSDave May 
1111f0cdbbbaSDave May PetscErrorCode DMSwarmSetUpPIC(DM dm)
1112f0cdbbbaSDave May {
1113f0cdbbbaSDave May   PetscInt       dim;
1114f0cdbbbaSDave May   PetscErrorCode ierr;
1115f0cdbbbaSDave May 
1116521f74f9SMatthew G. Knepley   PetscFunctionBegin;
1117f0cdbbbaSDave May   ierr = DMGetDimension(dm,&dim);CHKERRQ(ierr);
1118f0cdbbbaSDave May   if (dim < 1) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Dimension must be 1,2,3 - found %D",dim);
1119f0cdbbbaSDave May   if (dim > 3) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Dimension must be 1,2,3 - found %D",dim);
1120f0cdbbbaSDave May   ierr = DMSwarmRegisterPetscDatatypeField(dm,DMSwarmPICField_coor,dim,PETSC_DOUBLE);CHKERRQ(ierr);
1121e2d107dbSDave May   ierr = DMSwarmRegisterPetscDatatypeField(dm,DMSwarmPICField_cellid,1,PETSC_INT);CHKERRQ(ierr);
1122f0cdbbbaSDave May   PetscFunctionReturn(0);
1123f0cdbbbaSDave May }
1124f0cdbbbaSDave May 
1125d3a51819SDave May /*@C
1126d3a51819SDave May    DMSwarmSetType - Set particular flavor of DMSwarm
1127d3a51819SDave May 
1128d083f849SBarry Smith    Collective on dm
1129d3a51819SDave May 
1130d3a51819SDave May    Input parameters:
113162741f57SDave May +  dm - the DMSwarm
113262741f57SDave May -  stype - the DMSwarm type (e.g. DMSWARM_PIC)
1133d3a51819SDave May 
1134d3a51819SDave May    Level: advanced
1135d3a51819SDave May 
1136d3a51819SDave May .seealso: DMSwarmSetMigrateType(), DMSwarmSetCollectType()
1137d3a51819SDave May @*/
1138f0cdbbbaSDave May PETSC_EXTERN PetscErrorCode DMSwarmSetType(DM dm,DMSwarmType stype)
1139f0cdbbbaSDave May {
1140f0cdbbbaSDave May   DM_Swarm       *swarm = (DM_Swarm*)dm->data;
1141f0cdbbbaSDave May   PetscErrorCode ierr;
1142f0cdbbbaSDave May 
1143521f74f9SMatthew G. Knepley   PetscFunctionBegin;
1144f0cdbbbaSDave May   swarm->swarm_type = stype;
1145f0cdbbbaSDave May   if (swarm->swarm_type == DMSWARM_PIC) {
1146f0cdbbbaSDave May     ierr = DMSwarmSetUpPIC(dm);CHKERRQ(ierr);
1147f0cdbbbaSDave May   }
1148f0cdbbbaSDave May   PetscFunctionReturn(0);
1149f0cdbbbaSDave May }
1150f0cdbbbaSDave May 
11513454631fSDave May PetscErrorCode DMSetup_Swarm(DM dm)
11523454631fSDave May {
11533454631fSDave May   DM_Swarm       *swarm = (DM_Swarm*)dm->data;
11543454631fSDave May   PetscErrorCode ierr;
11553454631fSDave May   PetscMPIInt    rank;
11563454631fSDave May   PetscInt       p,npoints,*rankval;
11573454631fSDave May 
1158521f74f9SMatthew G. Knepley   PetscFunctionBegin;
11593454631fSDave May   if (swarm->issetup) PetscFunctionReturn(0);
11603454631fSDave May 
11613454631fSDave May   swarm->issetup = PETSC_TRUE;
11623454631fSDave May 
1163f0cdbbbaSDave May   if (swarm->swarm_type == DMSWARM_PIC) {
1164f0cdbbbaSDave May     /* check dmcell exists */
1165f0cdbbbaSDave May     if (!swarm->dmcell) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSWARM_PIC requires you call DMSwarmSetCellDM");
1166f0cdbbbaSDave May 
1167f0cdbbbaSDave May     if (swarm->dmcell->ops->locatepointssubdomain) {
1168f0cdbbbaSDave May       /* check methods exists for exact ownership identificiation */
116977b6ec44SMatthew G. Knepley       ierr = PetscInfo(dm, "DMSWARM_PIC: Using method CellDM->ops->LocatePointsSubdomain\n");CHKERRQ(ierr);
1170f0cdbbbaSDave May       swarm->migrate_type = DMSWARM_MIGRATE_DMCELLEXACT;
1171f0cdbbbaSDave May     } else {
1172f0cdbbbaSDave May       /* check methods exist for point location AND rank neighbor identification */
1173f0cdbbbaSDave May       if (swarm->dmcell->ops->locatepoints) {
117477b6ec44SMatthew G. Knepley         ierr = PetscInfo(dm, "DMSWARM_PIC: Using method CellDM->LocatePoints\n");CHKERRQ(ierr);
1175f0cdbbbaSDave May       } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSWARM_PIC requires the method CellDM->ops->locatepoints be defined");
1176f0cdbbbaSDave May 
1177f0cdbbbaSDave May       if (swarm->dmcell->ops->getneighbors) {
117877b6ec44SMatthew G. Knepley         ierr = PetscInfo(dm, "DMSWARM_PIC: Using method CellDM->GetNeigbors\n");CHKERRQ(ierr);
1179f0cdbbbaSDave May       } else SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"DMSWARM_PIC requires the method CellDM->ops->getneighbors be defined");
1180f0cdbbbaSDave May 
1181f0cdbbbaSDave May       swarm->migrate_type = DMSWARM_MIGRATE_DMCELLNSCATTER;
1182f0cdbbbaSDave May     }
1183f0cdbbbaSDave May   }
1184f0cdbbbaSDave May 
1185f0cdbbbaSDave May   ierr = DMSwarmFinalizeFieldRegister(dm);CHKERRQ(ierr);
1186f0cdbbbaSDave May 
11873454631fSDave May   /* check some fields were registered */
11883454631fSDave May   if (swarm->db->nfields <= 2) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"At least one field user must be registered via DMSwarmRegisterXXX()");
11893454631fSDave May 
11903454631fSDave May   /* check local sizes were set */
11913454631fSDave May   if (swarm->db->L == -1) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_USER,"Local sizes must be set via DMSwarmSetLocalSizes()");
11923454631fSDave May 
11933454631fSDave May   /* initialize values in pid and rank placeholders */
11943454631fSDave May   /* TODO: [pid - use MPI_Scan] */
11953454631fSDave May   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)dm),&rank);CHKERRQ(ierr);
119677048351SPatrick Sanan   ierr = DMSwarmDataBucketGetSizes(swarm->db,&npoints,NULL,NULL);CHKERRQ(ierr);
1197f0cdbbbaSDave May   ierr = DMSwarmGetField(dm,DMSwarmField_rank,NULL,NULL,(void**)&rankval);CHKERRQ(ierr);
11983454631fSDave May   for (p=0; p<npoints; p++) {
11993454631fSDave May     rankval[p] = (PetscInt)rank;
12003454631fSDave May   }
1201f0cdbbbaSDave May   ierr = DMSwarmRestoreField(dm,DMSwarmField_rank,NULL,NULL,(void**)&rankval);CHKERRQ(ierr);
12023454631fSDave May   PetscFunctionReturn(0);
12033454631fSDave May }
12043454631fSDave May 
1205dc5f5ce9SDave May extern PetscErrorCode DMSwarmSortDestroy(DMSwarmSort *_ctx);
1206dc5f5ce9SDave May 
120757795646SDave May PetscErrorCode DMDestroy_Swarm(DM dm)
120857795646SDave May {
120957795646SDave May   DM_Swarm       *swarm = (DM_Swarm*)dm->data;
121057795646SDave May   PetscErrorCode ierr;
121157795646SDave May 
121257795646SDave May   PetscFunctionBegin;
121377048351SPatrick Sanan   ierr = DMSwarmDataBucketDestroy(&swarm->db);CHKERRQ(ierr);
1214dc5f5ce9SDave May   if (swarm->sort_context) {
1215dc5f5ce9SDave May     ierr = DMSwarmSortDestroy(&swarm->sort_context);CHKERRQ(ierr);
1216dc5f5ce9SDave May   }
121757795646SDave May   ierr = PetscFree(swarm);CHKERRQ(ierr);
121857795646SDave May   PetscFunctionReturn(0);
121957795646SDave May }
122057795646SDave May 
1221a9ee3421SMatthew G. Knepley PetscErrorCode DMSwarmView_Draw(DM dm, PetscViewer viewer)
1222a9ee3421SMatthew G. Knepley {
1223a9ee3421SMatthew G. Knepley   DM             cdm;
1224a9ee3421SMatthew G. Knepley   PetscDraw      draw;
1225a9ee3421SMatthew G. Knepley   PetscReal     *coords, oldPause;
1226a9ee3421SMatthew G. Knepley   PetscInt       Np, p, bs;
1227a9ee3421SMatthew G. Knepley   PetscErrorCode ierr;
1228a9ee3421SMatthew G. Knepley 
1229a9ee3421SMatthew G. Knepley   PetscFunctionBegin;
1230a9ee3421SMatthew G. Knepley   ierr = PetscViewerDrawGetDraw(viewer, 0, &draw);CHKERRQ(ierr);
1231a9ee3421SMatthew G. Knepley   ierr = DMSwarmGetCellDM(dm, &cdm);CHKERRQ(ierr);
1232a9ee3421SMatthew G. Knepley   ierr = PetscDrawGetPause(draw, &oldPause);CHKERRQ(ierr);
1233a9ee3421SMatthew G. Knepley   ierr = PetscDrawSetPause(draw, 0.0);CHKERRQ(ierr);
1234a9ee3421SMatthew G. Knepley   ierr = DMView(cdm, viewer);CHKERRQ(ierr);
1235a9ee3421SMatthew G. Knepley   ierr = PetscDrawSetPause(draw, oldPause);CHKERRQ(ierr);
1236a9ee3421SMatthew G. Knepley 
1237a9ee3421SMatthew G. Knepley   ierr = DMSwarmGetLocalSize(dm, &Np);CHKERRQ(ierr);
1238a9ee3421SMatthew G. Knepley   ierr = DMSwarmGetField(dm, DMSwarmPICField_coor, &bs, NULL, (void **) &coords);CHKERRQ(ierr);
1239a9ee3421SMatthew G. Knepley   for (p = 0; p < Np; ++p) {
1240a9ee3421SMatthew G. Knepley     const PetscInt i = p*bs;
1241a9ee3421SMatthew G. Knepley 
1242a9ee3421SMatthew G. Knepley     ierr = PetscDrawEllipse(draw, coords[i], coords[i+1], 0.01, 0.01, PETSC_DRAW_BLUE);CHKERRQ(ierr);
1243a9ee3421SMatthew G. Knepley   }
1244a9ee3421SMatthew G. Knepley   ierr = DMSwarmRestoreField(dm, DMSwarmPICField_coor, &bs, NULL, (void **) &coords);CHKERRQ(ierr);
1245a9ee3421SMatthew G. Knepley   ierr = PetscDrawFlush(draw);CHKERRQ(ierr);
1246a9ee3421SMatthew G. Knepley   ierr = PetscDrawPause(draw);CHKERRQ(ierr);
1247a9ee3421SMatthew G. Knepley   ierr = PetscDrawSave(draw);CHKERRQ(ierr);
1248a9ee3421SMatthew G. Knepley   PetscFunctionReturn(0);
1249a9ee3421SMatthew G. Knepley }
1250a9ee3421SMatthew G. Knepley 
12515f50eb2eSDave May PetscErrorCode DMView_Swarm(DM dm, PetscViewer viewer)
12525f50eb2eSDave May {
12535f50eb2eSDave May   DM_Swarm       *swarm = (DM_Swarm*)dm->data;
1254a9ee3421SMatthew G. Knepley   PetscBool      iascii,ibinary,ishdf5,isvtk,isdraw;
12555f50eb2eSDave May   PetscErrorCode ierr;
12565f50eb2eSDave May 
12575f50eb2eSDave May   PetscFunctionBegin;
12585f50eb2eSDave May   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
12595f50eb2eSDave May   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
12605f50eb2eSDave May   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii);CHKERRQ(ierr);
12615f50eb2eSDave May   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY,&ibinary);CHKERRQ(ierr);
12625f50eb2eSDave May   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERVTK,   &isvtk);CHKERRQ(ierr);
12635f50eb2eSDave May   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5,  &ishdf5);CHKERRQ(ierr);
1264a9ee3421SMatthew G. Knepley   ierr = PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW,  &isdraw);CHKERRQ(ierr);
12655f50eb2eSDave May   if (iascii) {
126677048351SPatrick Sanan     ierr = DMSwarmDataBucketView(PetscObjectComm((PetscObject)dm),swarm->db,NULL,DATABUCKET_VIEW_STDOUT);CHKERRQ(ierr);
1267298827fbSBarry Smith   } else if (ibinary) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"NO Binary support");
12685f50eb2eSDave May #if defined(PETSC_HAVE_HDF5)
1269298827fbSBarry Smith   else if (ishdf5) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"NO HDF5 support");
12705f50eb2eSDave May #else
1271298827fbSBarry Smith   else if (ishdf5) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"HDF5 not supported. Please reconfigure using --download-hdf5");
12725f50eb2eSDave May #endif
1273298827fbSBarry Smith   else if (isvtk) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_SUP,"NO VTK support");
1274298827fbSBarry Smith   else if (isdraw) {
1275a9ee3421SMatthew G. Knepley     ierr = DMSwarmView_Draw(dm, viewer);CHKERRQ(ierr);
12765f50eb2eSDave May   }
12775f50eb2eSDave May   PetscFunctionReturn(0);
12785f50eb2eSDave May }
12795f50eb2eSDave May 
1280d3a51819SDave May /*MC
1281d3a51819SDave May 
1282d3a51819SDave May  DMSWARM = "swarm" - A DM object used to represent arrays of data (fields) of arbitrary data type.
128362741f57SDave May  This implementation was designed for particle methods in which the underlying
1284d3a51819SDave May  data required to be represented is both (i) dynamic in length, (ii) and of arbitrary data type.
1285d3a51819SDave May 
128662741f57SDave May  User data can be represented by DMSwarm through a registering "fields".
128762741f57SDave May  To register a field, the user must provide;
128862741f57SDave May  (a) a unique name;
128962741f57SDave May  (b) the data type (or size in bytes);
129062741f57SDave May  (c) the block size of the data.
1291d3a51819SDave May 
1292d3a51819SDave May  For example, suppose the application requires a unique id, energy, momentum and density to be stored
1293c215a47eSMatthew Knepley  on a set of particles. Then the following code could be used
1294d3a51819SDave May 
129562741f57SDave May $    DMSwarmInitializeFieldRegister(dm)
129662741f57SDave May $    DMSwarmRegisterPetscDatatypeField(dm,"uid",1,PETSC_LONG);
129762741f57SDave May $    DMSwarmRegisterPetscDatatypeField(dm,"energy",1,PETSC_REAL);
129862741f57SDave May $    DMSwarmRegisterPetscDatatypeField(dm,"momentum",3,PETSC_REAL);
129962741f57SDave May $    DMSwarmRegisterPetscDatatypeField(dm,"density",1,PETSC_FLOAT);
130062741f57SDave May $    DMSwarmFinalizeFieldRegister(dm)
1301d3a51819SDave May 
1302d3a51819SDave May  The fields represented by DMSwarm are dynamic and can be re-sized at any time.
130362741f57SDave May  The only restriction imposed by DMSwarm is that all fields contain the same number of points.
1304d3a51819SDave May 
1305d3a51819SDave May  To support particle methods, "migration" techniques are provided. These methods migrate data
1306d3a51819SDave May  between MPI-ranks.
1307d3a51819SDave May 
1308d3a51819SDave May  DMSwarm supports the methods DMCreateGlobalVector() and DMCreateLocalVector().
1309d3a51819SDave May  As a DMSwarm may internally define and store values of different data types,
131062741f57SDave May  before calling DMCreateGlobalVector() or DMCreateLocalVector(), the user must inform DMSwarm which
1311d3a51819SDave May  fields should be used to define a Vec object via
1312d3a51819SDave May    DMSwarmVectorDefineField()
1313c215a47eSMatthew Knepley  The specified field can be changed at any time - thereby permitting vectors
1314c215a47eSMatthew Knepley  compatible with different fields to be created.
1315d3a51819SDave May 
131662741f57SDave May  A dual representation of fields in the DMSwarm and a Vec object is permitted via
1317d3a51819SDave May    DMSwarmCreateGlobalVectorFromField()
1318d3a51819SDave May  Here the data defining the field in the DMSwarm is shared with a Vec.
1319d3a51819SDave May  This is inherently unsafe if you alter the size of the field at any time between
1320d3a51819SDave May  calls to DMSwarmCreateGlobalVectorFromField() and DMSwarmDestroyGlobalVectorFromField().
1321cc651181SDave May  If the local size of the DMSwarm does not match the local size of the global vector
1322cc651181SDave May  when DMSwarmDestroyGlobalVectorFromField() is called, an error is thrown.
1323d3a51819SDave May 
132462741f57SDave May  Additional high-level support is provided for Particle-In-Cell methods.
132562741f57SDave May  Please refer to the man page for DMSwarmSetType().
132662741f57SDave May 
1327d3a51819SDave May  Level: beginner
1328d3a51819SDave May 
1329d3a51819SDave May .seealso: DMType, DMCreate(), DMSetType()
1330d3a51819SDave May M*/
133157795646SDave May PETSC_EXTERN PetscErrorCode DMCreate_Swarm(DM dm)
133257795646SDave May {
133357795646SDave May   DM_Swarm      *swarm;
133457795646SDave May   PetscErrorCode ierr;
133557795646SDave May 
133657795646SDave May   PetscFunctionBegin;
133757795646SDave May   PetscValidHeaderSpecific(dm, DM_CLASSID, 1);
133857795646SDave May   ierr     = PetscNewLog(dm,&swarm);CHKERRQ(ierr);
1339f0cdbbbaSDave May   dm->data = swarm;
134057795646SDave May 
134177048351SPatrick Sanan   ierr = DMSwarmDataBucketCreate(&swarm->db);CHKERRQ(ierr);
1342f0cdbbbaSDave May   ierr = DMSwarmInitializeFieldRegister(dm);CHKERRQ(ierr);
1343f0cdbbbaSDave May 
1344b5bcf523SDave May   swarm->vec_field_set = PETSC_FALSE;
13453454631fSDave May   swarm->issetup = PETSC_FALSE;
1346480eef7bSDave May   swarm->swarm_type = DMSWARM_BASIC;
1347480eef7bSDave May   swarm->migrate_type = DMSWARM_MIGRATE_BASIC;
1348480eef7bSDave May   swarm->collect_type = DMSWARM_COLLECT_BASIC;
134940c453e9SDave May   swarm->migrate_error_on_missing_point = PETSC_FALSE;
1350b62e03f8SDave May 
1351f0cdbbbaSDave May   swarm->dmcell = NULL;
1352f0cdbbbaSDave May   swarm->collect_view_active = PETSC_FALSE;
1353f0cdbbbaSDave May   swarm->collect_view_reset_nlocal = -1;
135457795646SDave May 
1355f0cdbbbaSDave May   dm->dim  = 0;
13565f50eb2eSDave May   dm->ops->view                            = DMView_Swarm;
135757795646SDave May   dm->ops->load                            = NULL;
135857795646SDave May   dm->ops->setfromoptions                  = NULL;
135957795646SDave May   dm->ops->clone                           = NULL;
13603454631fSDave May   dm->ops->setup                           = DMSetup_Swarm;
13611bb6d2a8SBarry Smith   dm->ops->createlocalsection              = NULL;
136257795646SDave May   dm->ops->createdefaultconstraints        = NULL;
1363b5bcf523SDave May   dm->ops->createglobalvector              = DMCreateGlobalVector_Swarm;
1364b5bcf523SDave May   dm->ops->createlocalvector               = DMCreateLocalVector_Swarm;
136557795646SDave May   dm->ops->getlocaltoglobalmapping         = NULL;
136657795646SDave May   dm->ops->createfieldis                   = NULL;
136757795646SDave May   dm->ops->createcoordinatedm              = NULL;
136857795646SDave May   dm->ops->getcoloring                     = NULL;
136957795646SDave May   dm->ops->creatematrix                    = NULL;
137057795646SDave May   dm->ops->createinterpolation             = NULL;
13715a84ad33SLisandro Dalcin   dm->ops->createinjection                 = NULL;
137283c47955SMatthew G. Knepley   dm->ops->createmassmatrix                = DMCreateMassMatrix_Swarm;
137357795646SDave May   dm->ops->refine                          = NULL;
137457795646SDave May   dm->ops->coarsen                         = NULL;
137557795646SDave May   dm->ops->refinehierarchy                 = NULL;
137657795646SDave May   dm->ops->coarsenhierarchy                = NULL;
137757795646SDave May   dm->ops->globaltolocalbegin              = NULL;
137857795646SDave May   dm->ops->globaltolocalend                = NULL;
137957795646SDave May   dm->ops->localtoglobalbegin              = NULL;
138057795646SDave May   dm->ops->localtoglobalend                = NULL;
138157795646SDave May   dm->ops->destroy                         = DMDestroy_Swarm;
138257795646SDave May   dm->ops->createsubdm                     = NULL;
138357795646SDave May   dm->ops->getdimpoints                    = NULL;
138457795646SDave May   dm->ops->locatepoints                    = NULL;
138557795646SDave May   PetscFunctionReturn(0);
138657795646SDave May }
1387