xref: /petsc/src/ts/tutorials/hamiltonian/ex2.c (revision 3ba1676111f5c958fe6c2729b46ca4d523958bb3)
1b80bf5b1SJoe Pusztay static char help[] = "Two stream instability from Birdsal and Langdon with DMSwarm and TS basic symplectic integrators\n";
2b80bf5b1SJoe Pusztay 
3b80bf5b1SJoe Pusztay #include <petscdmplex.h>
4b80bf5b1SJoe Pusztay #include <petscfe.h>
5b80bf5b1SJoe Pusztay #include <petscdmswarm.h>
6b80bf5b1SJoe Pusztay #include <petscds.h>
7b80bf5b1SJoe Pusztay #include <petscksp.h>
8b80bf5b1SJoe Pusztay #include <petsc/private/petscfeimpl.h>
9b80bf5b1SJoe Pusztay #include <petsc/private/tsimpl.h>
10b80bf5b1SJoe Pusztay #include <petscts.h>
11b80bf5b1SJoe Pusztay #include <petscmath.h>
12b80bf5b1SJoe Pusztay 
13b80bf5b1SJoe Pusztay typedef struct {
14b80bf5b1SJoe Pusztay   PetscInt  dim;                              /* The topological mesh dimension */
15b80bf5b1SJoe Pusztay   PetscBool simplex;                          /* Flag for simplices or tensor cells */
16b80bf5b1SJoe Pusztay   PetscBool bdm;                              /* Flag for mixed form poisson */
17b80bf5b1SJoe Pusztay   PetscBool monitor;                          /* Flag for use of the TS monitor */
18b80bf5b1SJoe Pusztay   PetscBool uniform;                          /* Flag to uniformly space particles in x */
19b80bf5b1SJoe Pusztay   char      meshFilename[PETSC_MAX_PATH_LEN]; /* Name of the mesh filename if any */
20b80bf5b1SJoe Pusztay   PetscReal sigma;                            /* Linear charge per box length */
21b80bf5b1SJoe Pusztay   PetscReal timeScale;                        /* Nondimensionalizing time scaling */
22b80bf5b1SJoe Pusztay   PetscInt  particlesPerCell;                 /* The number of partices per cell */
23b80bf5b1SJoe Pusztay   PetscReal particleRelDx;                    /* Relative particle position perturbation compared to average cell diameter h */
24b80bf5b1SJoe Pusztay   PetscInt  k;                                /* Mode number for test function */
25b80bf5b1SJoe Pusztay   PetscReal momentTol;                        /* Tolerance for checking moment conservation */
26b80bf5b1SJoe Pusztay   SNES      snes;                             /* SNES object */
27b80bf5b1SJoe Pusztay   PetscInt  steps;                            /* TS iterations */
28b80bf5b1SJoe Pusztay   PetscReal stepSize;                         /* Time stepper step size */
29b80bf5b1SJoe Pusztay   PetscErrorCode (*func)(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar *, void *);
30b80bf5b1SJoe Pusztay } AppCtx;
31b80bf5b1SJoe Pusztay 
32d71ae5a4SJacob Faibussowitsch static PetscErrorCode ProcessOptions(MPI_Comm comm, AppCtx *options)
33d71ae5a4SJacob Faibussowitsch {
34b80bf5b1SJoe Pusztay   PetscFunctionBeginUser;
35b80bf5b1SJoe Pusztay   options->dim              = 2;
36b80bf5b1SJoe Pusztay   options->simplex          = PETSC_TRUE;
37b80bf5b1SJoe Pusztay   options->monitor          = PETSC_TRUE;
38b80bf5b1SJoe Pusztay   options->particlesPerCell = 1;
39b80bf5b1SJoe Pusztay   options->k                = 1;
40b80bf5b1SJoe Pusztay   options->particleRelDx    = 1.e-20;
41b80bf5b1SJoe Pusztay   options->momentTol        = 100. * PETSC_MACHINE_EPSILON;
42b80bf5b1SJoe Pusztay   options->sigma            = 1.;
43b80bf5b1SJoe Pusztay   options->timeScale        = 1.0e-6;
44b80bf5b1SJoe Pusztay   options->uniform          = PETSC_FALSE;
45b80bf5b1SJoe Pusztay   options->steps            = 1;
46b80bf5b1SJoe Pusztay   options->stepSize         = 0.01;
47b80bf5b1SJoe Pusztay   options->bdm              = PETSC_FALSE;
48b80bf5b1SJoe Pusztay 
49d0609cedSBarry Smith   PetscOptionsBegin(comm, "", "Two Stream options", "DMPLEX");
509566063dSJacob Faibussowitsch   PetscCall(PetscStrcpy(options->meshFilename, ""));
519566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-dim", "The topological mesh dimension", "ex2.c", options->dim, &options->dim, NULL));
529566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-steps", "TS steps to take", "ex2.c", options->steps, &options->steps, NULL));
539566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-monitor", "To use the TS monitor or not", "ex2.c", options->monitor, &options->monitor, NULL));
549566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-simplex", "The flag for simplices or tensor cells", "ex2.c", options->simplex, &options->simplex, NULL));
559566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-uniform", "Uniform particle spacing", "ex2.c", options->uniform, &options->uniform, NULL));
569566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-bdm", "Use H1 instead of C0", "ex2.c", options->bdm, &options->bdm, NULL));
579566063dSJacob Faibussowitsch   PetscCall(PetscOptionsString("-mesh", "Name of the mesh filename if any", "ex2.c", options->meshFilename, options->meshFilename, PETSC_MAX_PATH_LEN, NULL));
589566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-k", "Mode number of test", "ex5.c", options->k, &options->k, NULL));
599566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-particlesPerCell", "Number of particles per cell", "ex2.c", options->particlesPerCell, &options->particlesPerCell, NULL));
60f3fa974cSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-sigma", "parameter", "<1>", options->sigma, &options->sigma, NULL));
61f3fa974cSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-stepSize", "parameter", "<1e-2>", options->stepSize, &options->stepSize, NULL));
62f3fa974cSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-timeScale", "parameter", "<1>", options->timeScale, &options->timeScale, NULL));
639566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-particle_perturbation", "Relative perturbation of particles (0,1)", "ex2.c", options->particleRelDx, &options->particleRelDx, NULL));
64d0609cedSBarry Smith   PetscOptionsEnd();
65*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
66b80bf5b1SJoe Pusztay }
67b80bf5b1SJoe Pusztay 
68d71ae5a4SJacob Faibussowitsch static PetscErrorCode CreateMesh(MPI_Comm comm, DM *dm, AppCtx *user)
69d71ae5a4SJacob Faibussowitsch {
70b80bf5b1SJoe Pusztay   PetscFunctionBeginUser;
719566063dSJacob Faibussowitsch   PetscCall(DMCreate(comm, dm));
729566063dSJacob Faibussowitsch   PetscCall(DMSetType(*dm, DMPLEX));
739566063dSJacob Faibussowitsch   PetscCall(DMSetFromOptions(*dm));
749566063dSJacob Faibussowitsch   PetscCall(DMViewFromOptions(*dm, NULL, "-dm_view"));
75*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
76b80bf5b1SJoe Pusztay }
77b80bf5b1SJoe Pusztay 
78d71ae5a4SJacob Faibussowitsch static void laplacian_f1(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f1[])
79d71ae5a4SJacob Faibussowitsch {
80b80bf5b1SJoe Pusztay   PetscInt d;
81ad540459SPierre Jolivet   for (d = 0; d < dim; ++d) f1[d] = u_x[d];
82b80bf5b1SJoe Pusztay }
83b80bf5b1SJoe Pusztay 
84d71ae5a4SJacob Faibussowitsch static void laplacian(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[])
85d71ae5a4SJacob Faibussowitsch {
86b80bf5b1SJoe Pusztay   PetscInt d;
87ad540459SPierre Jolivet   for (d = 0; d < dim; ++d) g3[d * dim + d] = 1.0;
88b80bf5b1SJoe Pusztay }
89b80bf5b1SJoe Pusztay 
90d71ae5a4SJacob Faibussowitsch static PetscErrorCode CreateFEM(DM dm, AppCtx *user)
91d71ae5a4SJacob Faibussowitsch {
92b80bf5b1SJoe Pusztay   PetscFE        fe;
93b80bf5b1SJoe Pusztay   PetscDS        ds;
94b80bf5b1SJoe Pusztay   DMPolytopeType ct;
95b80bf5b1SJoe Pusztay   PetscBool      simplex;
96b80bf5b1SJoe Pusztay   PetscInt       dim, cStart;
97b80bf5b1SJoe Pusztay 
98b80bf5b1SJoe Pusztay   PetscFunctionBeginUser;
999566063dSJacob Faibussowitsch   PetscCall(DMGetDimension(dm, &dim));
1009566063dSJacob Faibussowitsch   PetscCall(DMPlexGetHeightStratum(dm, 0, &cStart, NULL));
1019566063dSJacob Faibussowitsch   PetscCall(DMPlexGetCellType(dm, cStart, &ct));
102b80bf5b1SJoe Pusztay   simplex = DMPolytopeTypeGetNumVertices(ct) == DMPolytopeTypeGetDim(ct) + 1 ? PETSC_TRUE : PETSC_FALSE;
1039566063dSJacob Faibussowitsch   PetscCall(PetscFECreateDefault(PetscObjectComm((PetscObject)dm), dim, 1, simplex, NULL, -1, &fe));
1049566063dSJacob Faibussowitsch   PetscCall(PetscObjectSetName((PetscObject)fe, "potential"));
1059566063dSJacob Faibussowitsch   PetscCall(DMSetField(dm, 0, NULL, (PetscObject)fe));
1069566063dSJacob Faibussowitsch   PetscCall(DMCreateDS(dm));
1079566063dSJacob Faibussowitsch   PetscCall(PetscFEDestroy(&fe));
1089566063dSJacob Faibussowitsch   PetscCall(DMGetDS(dm, &ds));
1099566063dSJacob Faibussowitsch   PetscCall(PetscDSSetResidual(ds, 0, NULL, laplacian_f1));
1109566063dSJacob Faibussowitsch   PetscCall(PetscDSSetJacobian(ds, 0, 0, NULL, NULL, NULL, laplacian));
111*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
112b80bf5b1SJoe Pusztay }
113b80bf5b1SJoe Pusztay 
114b80bf5b1SJoe Pusztay /*
115b80bf5b1SJoe Pusztay   Initialize particle coordinates uniformly and with opposing velocities
116b80bf5b1SJoe Pusztay */
117d71ae5a4SJacob Faibussowitsch static PetscErrorCode CreateParticles(DM dm, DM *sw, AppCtx *user)
118d71ae5a4SJacob Faibussowitsch {
119b80bf5b1SJoe Pusztay   PetscRandom rnd, rndp;
120b80bf5b1SJoe Pusztay   PetscReal   interval = user->particleRelDx;
121b80bf5b1SJoe Pusztay   PetscScalar value, *vals;
122b80bf5b1SJoe Pusztay   PetscReal  *centroid, *coords, *xi0, *v0, *J, *invJ, detJ, *initialConditions, normalized_vel;
123b80bf5b1SJoe Pusztay   PetscInt   *cellid, cStart;
124b80bf5b1SJoe Pusztay   PetscInt    Ncell, Np = user->particlesPerCell, p, c, dim, d;
125b80bf5b1SJoe Pusztay 
126b80bf5b1SJoe Pusztay   PetscFunctionBeginUser;
1279566063dSJacob Faibussowitsch   PetscCall(DMGetDimension(dm, &dim));
1289566063dSJacob Faibussowitsch   PetscCall(DMCreate(PetscObjectComm((PetscObject)dm), sw));
1299566063dSJacob Faibussowitsch   PetscCall(DMSetType(*sw, DMSWARM));
1309566063dSJacob Faibussowitsch   PetscCall(DMSetDimension(*sw, dim));
1319566063dSJacob Faibussowitsch   PetscCall(PetscRandomCreate(PetscObjectComm((PetscObject)dm), &rnd));
1329566063dSJacob Faibussowitsch   PetscCall(PetscRandomSetInterval(rnd, 0.0, 1.0));
1339566063dSJacob Faibussowitsch   PetscCall(PetscRandomSetFromOptions(rnd));
1349566063dSJacob Faibussowitsch   PetscCall(PetscRandomCreate(PetscObjectComm((PetscObject)dm), &rndp));
1359566063dSJacob Faibussowitsch   PetscCall(PetscRandomSetInterval(rndp, -interval, interval));
1369566063dSJacob Faibussowitsch   PetscCall(PetscRandomSetFromOptions(rndp));
1379566063dSJacob Faibussowitsch   PetscCall(DMSwarmSetType(*sw, DMSWARM_PIC));
1389566063dSJacob Faibussowitsch   PetscCall(DMSwarmSetCellDM(*sw, dm));
1399566063dSJacob Faibussowitsch   PetscCall(DMSwarmRegisterPetscDatatypeField(*sw, "w_q", 1, PETSC_SCALAR));
1409566063dSJacob Faibussowitsch   PetscCall(DMSwarmRegisterPetscDatatypeField(*sw, "kinematics", dim, PETSC_REAL));
1419566063dSJacob Faibussowitsch   PetscCall(DMSwarmFinalizeFieldRegister(*sw));
1429566063dSJacob Faibussowitsch   PetscCall(DMPlexGetHeightStratum(dm, 0, &cStart, &Ncell));
1439566063dSJacob Faibussowitsch   PetscCall(DMSwarmSetLocalSizes(*sw, Ncell * Np, 0));
1449566063dSJacob Faibussowitsch   PetscCall(DMSetFromOptions(*sw));
1459566063dSJacob Faibussowitsch   PetscCall(DMSwarmGetField(*sw, DMSwarmPICField_coor, NULL, NULL, (void **)&coords));
1469566063dSJacob Faibussowitsch   PetscCall(DMSwarmGetField(*sw, DMSwarmPICField_cellid, NULL, NULL, (void **)&cellid));
1479566063dSJacob Faibussowitsch   PetscCall(DMSwarmGetField(*sw, "w_q", NULL, NULL, (void **)&vals));
1489566063dSJacob Faibussowitsch   PetscCall(DMSwarmGetField(*sw, "kinematics", NULL, NULL, (void **)&initialConditions));
1499566063dSJacob Faibussowitsch   PetscCall(PetscMalloc5(dim, &centroid, dim, &xi0, dim, &v0, dim * dim, &J, dim * dim, &invJ));
150b80bf5b1SJoe Pusztay   for (c = cStart; c < Ncell; c++) {
151b80bf5b1SJoe Pusztay     if (Np == 1) {
1529566063dSJacob Faibussowitsch       PetscCall(DMPlexComputeCellGeometryFVM(dm, c, NULL, centroid, NULL));
153b80bf5b1SJoe Pusztay       cellid[c] = c;
154b80bf5b1SJoe Pusztay       for (d = 0; d < dim; ++d) coords[c * dim + d] = centroid[d];
155b80bf5b1SJoe Pusztay     } else {
156b80bf5b1SJoe Pusztay       for (d = 0; d < dim; ++d) xi0[d] = -1.0;
1579566063dSJacob Faibussowitsch       PetscCall(DMPlexComputeCellGeometryFEM(dm, c, NULL, v0, J, invJ, &detJ)); /* affine */
158b80bf5b1SJoe Pusztay       for (p = 0; p < Np; ++p) {
159b80bf5b1SJoe Pusztay         const PetscInt n = c * Np + p;
160b80bf5b1SJoe Pusztay         PetscReal      refcoords[3], spacing;
161b80bf5b1SJoe Pusztay 
162b80bf5b1SJoe Pusztay         cellid[n] = c;
163b80bf5b1SJoe Pusztay         if (user->uniform) {
164b80bf5b1SJoe Pusztay           spacing = 2. / Np;
1659566063dSJacob Faibussowitsch           PetscCall(PetscRandomGetValue(rnd, &value));
166b80bf5b1SJoe Pusztay           for (d = 0; d < dim; ++d) refcoords[d] = d == 0 ? -1. + spacing / 2. + p * spacing + value / 100. : 0.;
1679371c9d4SSatish Balay         } else {
1689371c9d4SSatish Balay           for (d = 0; d < dim; ++d) {
1699371c9d4SSatish Balay             PetscCall(PetscRandomGetValue(rnd, &value));
1709371c9d4SSatish Balay             refcoords[d] = d == 0 ? PetscRealPart(value) : 0.;
171b80bf5b1SJoe Pusztay           }
172b80bf5b1SJoe Pusztay         }
173b80bf5b1SJoe Pusztay         CoordinatesRefToReal(dim, dim, xi0, v0, J, refcoords, &coords[n * dim]);
174b80bf5b1SJoe Pusztay         /* constant particle weights */
175b80bf5b1SJoe Pusztay         for (d = 0; d < dim; ++d) vals[n] = user->sigma / Np;
176b80bf5b1SJoe Pusztay       }
177b80bf5b1SJoe Pusztay     }
178b80bf5b1SJoe Pusztay   }
1799566063dSJacob Faibussowitsch   PetscCall(PetscFree5(centroid, xi0, v0, J, invJ));
180b80bf5b1SJoe Pusztay   normalized_vel = 1.;
181b80bf5b1SJoe Pusztay   for (c = 0; c < Ncell; ++c) {
182b80bf5b1SJoe Pusztay     for (p = 0; p < Np; ++p) {
183b80bf5b1SJoe Pusztay       if (p % 2 == 0) {
184b80bf5b1SJoe Pusztay         for (d = 0; d < dim; ++d) initialConditions[(c * Np + p) * dim + d] = d == 0 ? normalized_vel : 0.;
1859371c9d4SSatish Balay       } else {
186b80bf5b1SJoe Pusztay         for (d = 0; d < dim; ++d) initialConditions[(c * Np + p) * dim + d] = d == 0 ? -(normalized_vel) : 0.;
187b80bf5b1SJoe Pusztay       }
188b80bf5b1SJoe Pusztay     }
189b80bf5b1SJoe Pusztay   }
1909566063dSJacob Faibussowitsch   PetscCall(DMSwarmRestoreField(*sw, DMSwarmPICField_coor, NULL, NULL, (void **)&coords));
1919566063dSJacob Faibussowitsch   PetscCall(DMSwarmRestoreField(*sw, DMSwarmPICField_cellid, NULL, NULL, (void **)&cellid));
1929566063dSJacob Faibussowitsch   PetscCall(DMSwarmRestoreField(*sw, "w_q", NULL, NULL, (void **)&vals));
1939566063dSJacob Faibussowitsch   PetscCall(DMSwarmRestoreField(*sw, "kinematics", NULL, NULL, (void **)&initialConditions));
1949566063dSJacob Faibussowitsch   PetscCall(PetscRandomDestroy(&rnd));
1959566063dSJacob Faibussowitsch   PetscCall(PetscRandomDestroy(&rndp));
1969566063dSJacob Faibussowitsch   PetscCall(PetscObjectSetName((PetscObject)*sw, "Particles"));
1979566063dSJacob Faibussowitsch   PetscCall(DMViewFromOptions(*sw, NULL, "-sw_view"));
1989566063dSJacob Faibussowitsch   PetscCall(DMLocalizeCoordinates(*sw));
199*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
200b80bf5b1SJoe Pusztay }
201b80bf5b1SJoe Pusztay 
202b80bf5b1SJoe Pusztay /* Solve for particle position updates */
203d71ae5a4SJacob Faibussowitsch static PetscErrorCode RHSFunction1(TS ts, PetscReal t, Vec V, Vec Posres, void *ctx)
204d71ae5a4SJacob Faibussowitsch {
205b80bf5b1SJoe Pusztay   const PetscScalar *v;
206b80bf5b1SJoe Pusztay   PetscScalar       *posres;
207b80bf5b1SJoe Pusztay   PetscInt           Np, p, dim, d;
208b80bf5b1SJoe Pusztay   DM                 dm;
209b80bf5b1SJoe Pusztay 
210b80bf5b1SJoe Pusztay   PetscFunctionBeginUser;
2119566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(Posres, &Np));
2129566063dSJacob Faibussowitsch   PetscCall(VecGetArray(Posres, &posres));
2139566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(V, &v));
2149566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
2159566063dSJacob Faibussowitsch   PetscCall(DMGetDimension(dm, &dim));
216b80bf5b1SJoe Pusztay   Np /= dim;
217b80bf5b1SJoe Pusztay   for (p = 0; p < Np; ++p) {
218ad540459SPierre Jolivet     for (d = 0; d < dim; ++d) posres[p * dim + d] = v[p * dim + d];
219b80bf5b1SJoe Pusztay   }
2209566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(V, &v));
2219566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(Posres, &posres));
222*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
223b80bf5b1SJoe Pusztay }
224b80bf5b1SJoe Pusztay 
225b80bf5b1SJoe Pusztay /*
226b80bf5b1SJoe Pusztay   Solve for the gradient of the electric field and apply force to particles.
227b80bf5b1SJoe Pusztay  */
228d71ae5a4SJacob Faibussowitsch static PetscErrorCode RHSFunction2(TS ts, PetscReal t, Vec X, Vec Vres, void *ctx)
229d71ae5a4SJacob Faibussowitsch {
230b80bf5b1SJoe Pusztay   AppCtx            *user = (AppCtx *)ctx;
231b80bf5b1SJoe Pusztay   DM                 dm, plex;
232b80bf5b1SJoe Pusztay   PetscDS            prob;
233b80bf5b1SJoe Pusztay   PetscFE            fe;
234b80bf5b1SJoe Pusztay   Mat                M_p;
235b80bf5b1SJoe Pusztay   Vec                phi, locPhi, rho, f;
236b80bf5b1SJoe Pusztay   const PetscScalar *x;
237b80bf5b1SJoe Pusztay   PetscScalar       *vres;
238b80bf5b1SJoe Pusztay   PetscReal         *coords, phi_0;
239b80bf5b1SJoe Pusztay   PetscInt           dim, d, cStart, cEnd, cell, cdim;
240b80bf5b1SJoe Pusztay   PetscReal          m_e = 9.11e-31, q_e = 1.60e-19, epsi_0 = 8.85e-12;
241b80bf5b1SJoe Pusztay 
242b80bf5b1SJoe Pusztay   PetscFunctionBeginUser;
243*3ba16761SJacob Faibussowitsch   PetscCall(PetscObjectSetName((PetscObject)X, "rhsf2 position"));
244*3ba16761SJacob Faibussowitsch   PetscCall(VecViewFromOptions(X, NULL, "-rhsf2_x_view"));
2459566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(X, &x));
2469566063dSJacob Faibussowitsch   PetscCall(VecGetArray(Vres, &vres));
2479566063dSJacob Faibussowitsch   PetscCall(TSGetDM(ts, &dm));
2489566063dSJacob Faibussowitsch   PetscCall(DMGetDimension(dm, &dim));
2499566063dSJacob Faibussowitsch   PetscCall(SNESGetDM(user->snes, &plex));
2509566063dSJacob Faibussowitsch   PetscCall(DMGetCoordinateDim(plex, &cdim));
2519566063dSJacob Faibussowitsch   PetscCall(DMGetDS(plex, &prob));
2529566063dSJacob Faibussowitsch   PetscCall(PetscDSGetDiscretization(prob, 0, (PetscObject *)&fe));
2539566063dSJacob Faibussowitsch   PetscCall(DMGetGlobalVector(plex, &phi));
2549566063dSJacob Faibussowitsch   PetscCall(DMGetLocalVector(plex, &locPhi));
2559566063dSJacob Faibussowitsch   PetscCall(DMCreateMassMatrix(dm, plex, &M_p));
2569566063dSJacob Faibussowitsch   PetscCall(MatViewFromOptions(M_p, NULL, "-mp_view"));
2579566063dSJacob Faibussowitsch   PetscCall(DMGetGlobalVector(plex, &rho));
2589566063dSJacob Faibussowitsch   PetscCall(DMSwarmCreateGlobalVectorFromField(dm, "w_q", &f));
2599566063dSJacob Faibussowitsch   PetscCall(PetscObjectSetName((PetscObject)f, "weights vector"));
2609566063dSJacob Faibussowitsch   PetscCall(VecViewFromOptions(f, NULL, "-weights_view"));
2619566063dSJacob Faibussowitsch   PetscCall(MatMultTranspose(M_p, f, rho));
2629566063dSJacob Faibussowitsch   PetscCall(DMSwarmDestroyGlobalVectorFromField(dm, "w_q", &f));
2639566063dSJacob Faibussowitsch   PetscCall(PetscObjectSetName((PetscObject)rho, "rho"));
2649566063dSJacob Faibussowitsch   PetscCall(VecViewFromOptions(rho, NULL, "-poisson_rho_view"));
265b80bf5b1SJoe Pusztay   /* Take nullspace out of rhs */
266b80bf5b1SJoe Pusztay   {
267b80bf5b1SJoe Pusztay     PetscScalar sum;
268b80bf5b1SJoe Pusztay     PetscInt    n;
269b80bf5b1SJoe Pusztay     phi_0 = (user->sigma * user->sigma * user->sigma) * (user->timeScale * user->timeScale) / (m_e * q_e * epsi_0);
270b80bf5b1SJoe Pusztay 
2719566063dSJacob Faibussowitsch     PetscCall(VecGetSize(rho, &n));
2729566063dSJacob Faibussowitsch     PetscCall(VecSum(rho, &sum));
2739566063dSJacob Faibussowitsch     PetscCall(VecShift(rho, -sum / n));
274b80bf5b1SJoe Pusztay 
2759566063dSJacob Faibussowitsch     PetscCall(VecSum(rho, &sum));
27663a3b9bcSJacob Faibussowitsch     PetscCheck(PetscAbsScalar(sum) <= 1.0e-10, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Charge should have no DC component %g", (double)PetscAbsScalar(sum));
2779566063dSJacob Faibussowitsch     PetscCall(VecScale(rho, phi_0));
278b80bf5b1SJoe Pusztay   }
2799566063dSJacob Faibussowitsch   PetscCall(VecSet(phi, 0.0));
2809566063dSJacob Faibussowitsch   PetscCall(SNESSolve(user->snes, rho, phi));
2819566063dSJacob Faibussowitsch   PetscCall(VecViewFromOptions(phi, NULL, "-phi_view"));
2829566063dSJacob Faibussowitsch   PetscCall(DMRestoreGlobalVector(plex, &rho));
2839566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&M_p));
2849566063dSJacob Faibussowitsch   PetscCall(DMGlobalToLocalBegin(plex, phi, INSERT_VALUES, locPhi));
2859566063dSJacob Faibussowitsch   PetscCall(DMGlobalToLocalEnd(plex, phi, INSERT_VALUES, locPhi));
2869566063dSJacob Faibussowitsch   PetscCall(DMSwarmSortGetAccess(dm));
2879566063dSJacob Faibussowitsch   PetscCall(DMSwarmGetField(dm, DMSwarmPICField_coor, NULL, NULL, (void **)&coords));
2889566063dSJacob Faibussowitsch   PetscCall(DMPlexGetHeightStratum(plex, 0, &cStart, &cEnd));
289b80bf5b1SJoe Pusztay   for (cell = cStart; cell < cEnd; ++cell) {
290b80bf5b1SJoe Pusztay     PetscTabulation tab;
291b80bf5b1SJoe Pusztay     PetscReal       v[3], J[9], invJ[9], detJ;
292f3fa974cSJacob Faibussowitsch     PetscScalar    *ph       = NULL;
293f3fa974cSJacob Faibussowitsch     PetscReal      *pcoord   = NULL;
294f3fa974cSJacob Faibussowitsch     PetscReal      *refcoord = NULL;
295f3fa974cSJacob Faibussowitsch     PetscInt       *points   = NULL, Ncp, cp;
296b80bf5b1SJoe Pusztay     PetscScalar     gradPhi[3];
297b80bf5b1SJoe Pusztay 
2989566063dSJacob Faibussowitsch     PetscCall(DMPlexComputeCellGeometryFEM(plex, cell, NULL, v, J, invJ, &detJ));
2999566063dSJacob Faibussowitsch     PetscCall(DMSwarmSortGetPointsPerCell(dm, cell, &Ncp, &points));
3009566063dSJacob Faibussowitsch     PetscCall(DMGetWorkArray(dm, Ncp * cdim, MPIU_REAL, &pcoord));
3019566063dSJacob Faibussowitsch     PetscCall(DMGetWorkArray(dm, Ncp * cdim, MPIU_REAL, &refcoord));
302b80bf5b1SJoe Pusztay     for (cp = 0; cp < Ncp; ++cp) {
303ad540459SPierre Jolivet       for (d = 0; d < cdim; ++d) pcoord[cp * cdim + d] = coords[points[cp] * cdim + d];
304b80bf5b1SJoe Pusztay     }
3059566063dSJacob Faibussowitsch     PetscCall(DMPlexCoordinatesToReference(plex, cell, Ncp, pcoord, refcoord));
3069566063dSJacob Faibussowitsch     PetscCall(PetscFECreateTabulation(fe, 1, Ncp, refcoord, 1, &tab));
3079566063dSJacob Faibussowitsch     PetscCall(DMPlexVecGetClosure(plex, NULL, locPhi, cell, NULL, &ph));
308b80bf5b1SJoe Pusztay     for (cp = 0; cp < Ncp; ++cp) {
309b80bf5b1SJoe Pusztay       const PetscInt p          = points[cp];
310b80bf5b1SJoe Pusztay       gradPhi[0]                = 0.0;
311b80bf5b1SJoe Pusztay       gradPhi[1]                = 0.0;
312b80bf5b1SJoe Pusztay       gradPhi[2]                = 0.0;
313b80bf5b1SJoe Pusztay       const PetscReal *basisDer = tab->T[1];
314b80bf5b1SJoe Pusztay 
3159566063dSJacob Faibussowitsch       PetscCall(PetscFEFreeInterpolateGradient_Static(fe, basisDer, ph, cdim, invJ, NULL, cp, gradPhi));
316ad540459SPierre Jolivet       for (d = 0; d < cdim; ++d) vres[p * cdim + d] = d == 0 ? gradPhi[d] : 0.;
317b80bf5b1SJoe Pusztay     }
3189566063dSJacob Faibussowitsch     PetscCall(DMPlexVecRestoreClosure(plex, NULL, locPhi, cell, NULL, &ph));
3199566063dSJacob Faibussowitsch     PetscCall(PetscTabulationDestroy(&tab));
3209566063dSJacob Faibussowitsch     PetscCall(DMRestoreWorkArray(dm, Ncp * cdim, MPIU_REAL, &pcoord));
3219566063dSJacob Faibussowitsch     PetscCall(DMRestoreWorkArray(dm, Ncp * cdim, MPIU_REAL, &refcoord));
3229566063dSJacob Faibussowitsch     PetscCall(PetscFree(points));
323b80bf5b1SJoe Pusztay   }
3249566063dSJacob Faibussowitsch   PetscCall(DMSwarmRestoreField(dm, DMSwarmPICField_coor, NULL, NULL, (void **)&coords));
3259566063dSJacob Faibussowitsch   PetscCall(DMSwarmSortRestoreAccess(dm));
3269566063dSJacob Faibussowitsch   PetscCall(DMRestoreLocalVector(plex, &locPhi));
3279566063dSJacob Faibussowitsch   PetscCall(DMRestoreGlobalVector(plex, &phi));
3289566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(Vres, &vres));
3299566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(X, &x));
3309566063dSJacob Faibussowitsch   PetscCall(VecViewFromOptions(Vres, NULL, "-vel_res_view"));
331*3ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
332b80bf5b1SJoe Pusztay }
333b80bf5b1SJoe Pusztay 
334d71ae5a4SJacob Faibussowitsch int main(int argc, char **argv)
335d71ae5a4SJacob Faibussowitsch {
336b80bf5b1SJoe Pusztay   PetscInt           i, par;
337b80bf5b1SJoe Pusztay   PetscInt           locSize, p, d, dim, Np, step, *idx1, *idx2;
338b80bf5b1SJoe Pusztay   TS                 ts;
339b80bf5b1SJoe Pusztay   DM                 dm, sw;
340b80bf5b1SJoe Pusztay   AppCtx             user;
341b80bf5b1SJoe Pusztay   MPI_Comm           comm;
342b80bf5b1SJoe Pusztay   Vec                coorVec, kinVec, probVec, solution, position, momentum;
343b80bf5b1SJoe Pusztay   const PetscScalar *coorArr, *kinArr;
344b80bf5b1SJoe Pusztay   PetscReal          ftime = 10., *probArr, *probVecArr;
345b80bf5b1SJoe Pusztay   IS                 is1, is2;
346b80bf5b1SJoe Pusztay   PetscReal         *coor, *kin, *pos, *mom;
347b80bf5b1SJoe Pusztay 
348327415f7SBarry Smith   PetscFunctionBeginUser;
3499566063dSJacob Faibussowitsch   PetscCall(PetscInitialize(&argc, &argv, NULL, help));
350b80bf5b1SJoe Pusztay   comm = PETSC_COMM_WORLD;
3519566063dSJacob Faibussowitsch   PetscCall(ProcessOptions(comm, &user));
352b80bf5b1SJoe Pusztay   /* Create dm and particles */
3539566063dSJacob Faibussowitsch   PetscCall(CreateMesh(comm, &dm, &user));
3549566063dSJacob Faibussowitsch   PetscCall(CreateFEM(dm, &user));
3559566063dSJacob Faibussowitsch   PetscCall(CreateParticles(dm, &sw, &user));
3569566063dSJacob Faibussowitsch   PetscCall(SNESCreate(comm, &user.snes));
3579566063dSJacob Faibussowitsch   PetscCall(SNESSetDM(user.snes, dm));
3589566063dSJacob Faibussowitsch   PetscCall(DMPlexSetSNESLocalFEM(dm, &user, &user, &user));
3599566063dSJacob Faibussowitsch   PetscCall(SNESSetFromOptions(user.snes));
360b80bf5b1SJoe Pusztay   {
361b80bf5b1SJoe Pusztay     Mat          J;
362b80bf5b1SJoe Pusztay     MatNullSpace nullSpace;
363b80bf5b1SJoe Pusztay 
3649566063dSJacob Faibussowitsch     PetscCall(DMCreateMatrix(dm, &J));
3659566063dSJacob Faibussowitsch     PetscCall(MatNullSpaceCreate(PetscObjectComm((PetscObject)dm), PETSC_TRUE, 0, NULL, &nullSpace));
3669566063dSJacob Faibussowitsch     PetscCall(MatSetNullSpace(J, nullSpace));
3679566063dSJacob Faibussowitsch     PetscCall(MatNullSpaceDestroy(&nullSpace));
3689566063dSJacob Faibussowitsch     PetscCall(SNESSetJacobian(user.snes, J, J, NULL, NULL));
3699566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&J));
370b80bf5b1SJoe Pusztay   }
371b80bf5b1SJoe Pusztay   /* Place TSSolve in a loop to handle resetting the TS at every manual call of TSStep() */
3729566063dSJacob Faibussowitsch   PetscCall(TSCreate(comm, &ts));
3739566063dSJacob Faibussowitsch   PetscCall(TSSetMaxTime(ts, ftime));
3749566063dSJacob Faibussowitsch   PetscCall(TSSetTimeStep(ts, user.stepSize));
3759566063dSJacob Faibussowitsch   PetscCall(TSSetMaxSteps(ts, 100000));
3769566063dSJacob Faibussowitsch   PetscCall(TSSetExactFinalTime(ts, TS_EXACTFINALTIME_MATCHSTEP));
377b80bf5b1SJoe Pusztay   for (step = 0; step < user.steps; ++step) {
3789566063dSJacob Faibussowitsch     PetscCall(DMSwarmCreateGlobalVectorFromField(sw, "kinematics", &kinVec));
3799566063dSJacob Faibussowitsch     PetscCall(DMSwarmCreateGlobalVectorFromField(sw, DMSwarmPICField_coor, &coorVec));
3809566063dSJacob Faibussowitsch     PetscCall(VecViewFromOptions(kinVec, NULL, "-ic_vec_view"));
3819566063dSJacob Faibussowitsch     PetscCall(DMGetDimension(sw, &dim));
3829566063dSJacob Faibussowitsch     PetscCall(VecGetLocalSize(kinVec, &locSize));
3839566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(locSize, &idx1));
3849566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(locSize, &idx2));
3859566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(2 * locSize, &probArr));
386b80bf5b1SJoe Pusztay     Np = locSize / dim;
3879566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(kinVec, &kinArr));
3889566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(coorVec, &coorArr));
389b80bf5b1SJoe Pusztay     for (p = 0; p < Np; ++p) {
390b80bf5b1SJoe Pusztay       for (d = 0; d < dim; ++d) {
391b80bf5b1SJoe Pusztay         probArr[p * 2 * dim + d]       = coorArr[p * dim + d];
392b80bf5b1SJoe Pusztay         probArr[(p * 2 + 1) * dim + d] = kinArr[p * dim + d];
393b80bf5b1SJoe Pusztay       }
394b80bf5b1SJoe Pusztay     }
3959566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(kinVec, &kinArr));
3969566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(coorVec, &coorArr));
397b80bf5b1SJoe Pusztay     /* Allocate for IS Strides that will contain x, y and vx, vy */
398b80bf5b1SJoe Pusztay     for (p = 0; p < Np; ++p) {
399b80bf5b1SJoe Pusztay       for (d = 0; d < dim; ++d) {
400b80bf5b1SJoe Pusztay         idx1[p * dim + d] = (p * 2 + 0) * dim + d;
401b80bf5b1SJoe Pusztay         idx2[p * dim + d] = (p * 2 + 1) * dim + d;
402b80bf5b1SJoe Pusztay       }
403b80bf5b1SJoe Pusztay     }
404b80bf5b1SJoe Pusztay 
4059566063dSJacob Faibussowitsch     PetscCall(ISCreateGeneral(comm, locSize, idx1, PETSC_OWN_POINTER, &is1));
4069566063dSJacob Faibussowitsch     PetscCall(ISCreateGeneral(comm, locSize, idx2, PETSC_OWN_POINTER, &is2));
407d5b43468SJose E. Roman     /* DM needs to be set before splits so it propagates to sub TSs */
4089566063dSJacob Faibussowitsch     PetscCall(TSSetDM(ts, sw));
4099566063dSJacob Faibussowitsch     PetscCall(TSSetType(ts, TSBASICSYMPLECTIC));
4109566063dSJacob Faibussowitsch     PetscCall(TSRHSSplitSetIS(ts, "position", is1));
4119566063dSJacob Faibussowitsch     PetscCall(TSRHSSplitSetIS(ts, "momentum", is2));
4129566063dSJacob Faibussowitsch     PetscCall(TSRHSSplitSetRHSFunction(ts, "position", NULL, RHSFunction1, &user));
4139566063dSJacob Faibussowitsch     PetscCall(TSRHSSplitSetRHSFunction(ts, "momentum", NULL, RHSFunction2, &user));
4149566063dSJacob Faibussowitsch     PetscCall(TSSetTime(ts, step * user.stepSize));
41548a46eb9SPierre Jolivet     if (step == 0) PetscCall(TSSetFromOptions(ts));
416b80bf5b1SJoe Pusztay     /* Compose vector from array for TS solve with all kinematic variables */
4179566063dSJacob Faibussowitsch     PetscCall(VecCreate(comm, &probVec));
4189566063dSJacob Faibussowitsch     PetscCall(VecSetBlockSize(probVec, 1));
4199566063dSJacob Faibussowitsch     PetscCall(VecSetSizes(probVec, PETSC_DECIDE, 2 * locSize));
4209566063dSJacob Faibussowitsch     PetscCall(VecSetUp(probVec));
4219566063dSJacob Faibussowitsch     PetscCall(VecGetArray(probVec, &probVecArr));
4225f80ce2aSJacob Faibussowitsch     for (i = 0; i < 2 * locSize; ++i) probVecArr[i] = probArr[i];
4239566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray(probVec, &probVecArr));
4249566063dSJacob Faibussowitsch     PetscCall(TSSetSolution(ts, probVec));
4259566063dSJacob Faibussowitsch     PetscCall(PetscFree(probArr));
4269566063dSJacob Faibussowitsch     PetscCall(VecViewFromOptions(kinVec, NULL, "-ic_view"));
4279566063dSJacob Faibussowitsch     PetscCall(DMSwarmDestroyGlobalVectorFromField(sw, "kinematics", &kinVec));
4289566063dSJacob Faibussowitsch     PetscCall(DMSwarmDestroyGlobalVectorFromField(sw, DMSwarmPICField_coor, &coorVec));
4299566063dSJacob Faibussowitsch     PetscCall(TSMonitor(ts, step, ts->ptime, ts->vec_sol));
43048a46eb9SPierre Jolivet     if (!ts->steprollback) PetscCall(TSPreStep(ts));
4319566063dSJacob Faibussowitsch     PetscCall(TSStep(ts));
4321baa6e33SBarry Smith     if (ts->steprollback) PetscCall(TSPostEvaluate(ts));
433b80bf5b1SJoe Pusztay     if (!ts->steprollback) {
434*3ba16761SJacob Faibussowitsch       PetscCall(TSPostStep(ts));
4359566063dSJacob Faibussowitsch       PetscCall(DMSwarmGetField(sw, DMSwarmPICField_coor, NULL, NULL, (void **)&coor));
4369566063dSJacob Faibussowitsch       PetscCall(DMSwarmGetField(sw, "kinematics", NULL, NULL, (void **)&kin));
4379566063dSJacob Faibussowitsch       PetscCall(TSGetSolution(ts, &solution));
4389566063dSJacob Faibussowitsch       PetscCall(VecGetSubVector(solution, is1, &position));
4399566063dSJacob Faibussowitsch       PetscCall(VecGetSubVector(solution, is2, &momentum));
4409566063dSJacob Faibussowitsch       PetscCall(VecGetArray(position, &pos));
4419566063dSJacob Faibussowitsch       PetscCall(VecGetArray(momentum, &mom));
442b80bf5b1SJoe Pusztay       for (par = 0; par < Np; ++par) {
443b80bf5b1SJoe Pusztay         for (d = 0; d < dim; ++d) {
444b80bf5b1SJoe Pusztay           if (pos[par * dim + d] < 0.) {
445b80bf5b1SJoe Pusztay             coor[par * dim + d] = pos[par * dim + d] + 2. * PETSC_PI;
4469371c9d4SSatish Balay           } else if (pos[par * dim + d] > 2. * PETSC_PI) {
447b80bf5b1SJoe Pusztay             coor[par * dim + d] = pos[par * dim + d] - 2. * PETSC_PI;
4489371c9d4SSatish Balay           } else {
449b80bf5b1SJoe Pusztay             coor[par * dim + d] = pos[par * dim + d];
450b80bf5b1SJoe Pusztay           }
451b80bf5b1SJoe Pusztay           kin[par * dim + d] = mom[par * dim + d];
452b80bf5b1SJoe Pusztay         }
453b80bf5b1SJoe Pusztay       }
4549566063dSJacob Faibussowitsch       PetscCall(VecRestoreArray(position, &pos));
4559566063dSJacob Faibussowitsch       PetscCall(VecRestoreArray(momentum, &mom));
4569566063dSJacob Faibussowitsch       PetscCall(VecRestoreSubVector(solution, is1, &position));
4579566063dSJacob Faibussowitsch       PetscCall(VecRestoreSubVector(solution, is2, &momentum));
4589566063dSJacob Faibussowitsch       PetscCall(DMSwarmRestoreField(sw, DMSwarmPICField_coor, NULL, NULL, (void **)&coor));
4599566063dSJacob Faibussowitsch       PetscCall(DMSwarmRestoreField(sw, "kinematics", NULL, NULL, (void **)&kin));
460b80bf5b1SJoe Pusztay     }
4619566063dSJacob Faibussowitsch     PetscCall(DMSwarmMigrate(sw, PETSC_TRUE));
4629566063dSJacob Faibussowitsch     PetscCall(DMLocalizeCoordinates(sw));
4639566063dSJacob Faibussowitsch     PetscCall(TSReset(ts));
4649566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&probVec));
4659566063dSJacob Faibussowitsch     PetscCall(ISDestroy(&is1));
4669566063dSJacob Faibussowitsch     PetscCall(ISDestroy(&is2));
467b80bf5b1SJoe Pusztay   }
4689566063dSJacob Faibussowitsch   PetscCall(SNESDestroy(&user.snes));
4699566063dSJacob Faibussowitsch   PetscCall(TSDestroy(&ts));
4709566063dSJacob Faibussowitsch   PetscCall(DMDestroy(&sw));
4719566063dSJacob Faibussowitsch   PetscCall(DMDestroy(&dm));
4729566063dSJacob Faibussowitsch   PetscCall(PetscFinalize());
473b122ec5aSJacob Faibussowitsch   return 0;
474b80bf5b1SJoe Pusztay }
475b80bf5b1SJoe Pusztay 
476b80bf5b1SJoe Pusztay /*TEST
477b80bf5b1SJoe Pusztay 
478b80bf5b1SJoe Pusztay    build:
479b80bf5b1SJoe Pusztay      requires: triangle !single !complex
480b80bf5b1SJoe Pusztay    test:
481b80bf5b1SJoe Pusztay      suffix: bsi1q3
482b80bf5b1SJoe Pusztay      args: -particlesPerCell 200\
483b80bf5b1SJoe Pusztay       -petscspace_degree 2\
484b80bf5b1SJoe Pusztay       -petscfe_default_quadrature_order 3\
485b80bf5b1SJoe Pusztay       -ts_basicsymplectic_type 1\
486b80bf5b1SJoe Pusztay       -pc_type svd\
487b80bf5b1SJoe Pusztay       -uniform\
488b80bf5b1SJoe Pusztay       -sigma 1.0e-8\
489b80bf5b1SJoe Pusztay       -timeScale 2.0e-14\
490b80bf5b1SJoe Pusztay       -stepSize 1.0e-2\
491b80bf5b1SJoe Pusztay       -ts_monitor_sp_swarm\
492b80bf5b1SJoe Pusztay       -steps 10\
493b80bf5b1SJoe Pusztay       -dm_view\
494b80bf5b1SJoe Pusztay       -dm_plex_simplex 0 -dm_plex_dim 2\
495b80bf5b1SJoe Pusztay       -dm_plex_box_lower 0,-1\
496b80bf5b1SJoe Pusztay       -dm_plex_box_upper 6.283185307179586,1\
497b80bf5b1SJoe Pusztay       -dm_plex_box_bd periodic,none\
498b80bf5b1SJoe Pusztay       -dm_plex_box_faces 4,1
499b80bf5b1SJoe Pusztay    test:
500b80bf5b1SJoe Pusztay      suffix: bsi2q3
501b80bf5b1SJoe Pusztay      args: -particlesPerCell 200\
502b80bf5b1SJoe Pusztay       -petscspace_degree 2\
503b80bf5b1SJoe Pusztay       -petscfe_default_quadrature_order 3\
504b80bf5b1SJoe Pusztay       -ts_basicsymplectic_type 2\
505b80bf5b1SJoe Pusztay       -pc_type svd\
506b80bf5b1SJoe Pusztay       -uniform\
507b80bf5b1SJoe Pusztay       -sigma 1.0e-8\
508b80bf5b1SJoe Pusztay       -timeScale 2.0e-14\
509b80bf5b1SJoe Pusztay       -stepSize 1.0e-2\
510b80bf5b1SJoe Pusztay       -ts_monitor_sp_swarm\
511b80bf5b1SJoe Pusztay       -steps 10\
512b80bf5b1SJoe Pusztay       -dm_view\
513b80bf5b1SJoe Pusztay       -dm_plex_simplex 0 -dm_plex_dim 2\
514b80bf5b1SJoe Pusztay       -dm_plex_box_lower 0,-1\
515b80bf5b1SJoe Pusztay       -dm_plex_box_upper 6.283185307179586,1\
516b80bf5b1SJoe Pusztay       -dm_plex_box_bd periodic,none\
517b80bf5b1SJoe Pusztay       -dm_plex_box_faces 4,1
518b80bf5b1SJoe Pusztay TEST*/
519