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