1*b80bf5b1SJoe Pusztay static char help[] = "Two stream instability from Birdsal and Langdon with DMSwarm and TS basic symplectic integrators\n"; 2*b80bf5b1SJoe Pusztay 3*b80bf5b1SJoe Pusztay #include <petscdmplex.h> 4*b80bf5b1SJoe Pusztay #include <petscfe.h> 5*b80bf5b1SJoe Pusztay #include <petscdmswarm.h> 6*b80bf5b1SJoe Pusztay #include <petscds.h> 7*b80bf5b1SJoe Pusztay #include <petscksp.h> 8*b80bf5b1SJoe Pusztay #include <petsc/private/petscfeimpl.h> 9*b80bf5b1SJoe Pusztay #include <petsc/private/tsimpl.h> 10*b80bf5b1SJoe Pusztay #include <petscts.h> 11*b80bf5b1SJoe Pusztay #include <petscmath.h> 12*b80bf5b1SJoe Pusztay 13*b80bf5b1SJoe Pusztay typedef struct { 14*b80bf5b1SJoe Pusztay PetscInt dim; /* The topological mesh dimension */ 15*b80bf5b1SJoe Pusztay PetscBool simplex; /* Flag for simplices or tensor cells */ 16*b80bf5b1SJoe Pusztay PetscBool bdm; /* Flag for mixed form poisson */ 17*b80bf5b1SJoe Pusztay PetscBool monitor; /* Flag for use of the TS monitor */ 18*b80bf5b1SJoe Pusztay PetscBool uniform; /* Flag to uniformly space particles in x */ 19*b80bf5b1SJoe Pusztay char meshFilename[PETSC_MAX_PATH_LEN]; /* Name of the mesh filename if any */ 20*b80bf5b1SJoe Pusztay PetscReal sigma; /* Linear charge per box length */ 21*b80bf5b1SJoe Pusztay PetscReal timeScale; /* Nondimensionalizing time scaling */ 22*b80bf5b1SJoe Pusztay PetscInt particlesPerCell; /* The number of partices per cell */ 23*b80bf5b1SJoe Pusztay PetscReal particleRelDx; /* Relative particle position perturbation compared to average cell diameter h */ 24*b80bf5b1SJoe Pusztay PetscInt k; /* Mode number for test function */ 25*b80bf5b1SJoe Pusztay PetscReal momentTol; /* Tolerance for checking moment conservation */ 26*b80bf5b1SJoe Pusztay SNES snes; /* SNES object */ 27*b80bf5b1SJoe Pusztay PetscInt steps; /* TS iterations */ 28*b80bf5b1SJoe Pusztay PetscReal stepSize; /* Time stepper step size */ 29*b80bf5b1SJoe Pusztay PetscErrorCode (*func)(PetscInt, PetscReal, const PetscReal [], PetscInt, PetscScalar *, void *); 30*b80bf5b1SJoe Pusztay } AppCtx; 31*b80bf5b1SJoe Pusztay 32*b80bf5b1SJoe Pusztay static PetscErrorCode ProcessOptions(MPI_Comm comm, AppCtx *options) 33*b80bf5b1SJoe Pusztay { 34*b80bf5b1SJoe Pusztay PetscErrorCode ierr; 35*b80bf5b1SJoe Pusztay 36*b80bf5b1SJoe Pusztay PetscFunctionBeginUser; 37*b80bf5b1SJoe Pusztay options->dim = 2; 38*b80bf5b1SJoe Pusztay options->simplex = PETSC_TRUE; 39*b80bf5b1SJoe Pusztay options->monitor = PETSC_TRUE; 40*b80bf5b1SJoe Pusztay options->particlesPerCell = 1; 41*b80bf5b1SJoe Pusztay options->k = 1; 42*b80bf5b1SJoe Pusztay options->particleRelDx = 1.e-20; 43*b80bf5b1SJoe Pusztay options->momentTol = 100.*PETSC_MACHINE_EPSILON; 44*b80bf5b1SJoe Pusztay options->sigma = 1.; 45*b80bf5b1SJoe Pusztay options->timeScale = 1.0e-6; 46*b80bf5b1SJoe Pusztay options->uniform = PETSC_FALSE; 47*b80bf5b1SJoe Pusztay options->steps = 1; 48*b80bf5b1SJoe Pusztay options->stepSize = 0.01; 49*b80bf5b1SJoe Pusztay options->bdm = PETSC_FALSE; 50*b80bf5b1SJoe Pusztay 51*b80bf5b1SJoe Pusztay ierr = PetscOptionsBegin(comm, "", "Two Stream options", "DMPLEX");CHKERRQ(ierr); 52*b80bf5b1SJoe Pusztay ierr = PetscStrcpy(options->meshFilename, "");CHKERRQ(ierr); 53*b80bf5b1SJoe Pusztay ierr = PetscOptionsInt("-dim", "The topological mesh dimension", "ex2.c", options->dim, &options->dim, NULL);CHKERRQ(ierr); 54*b80bf5b1SJoe Pusztay ierr = PetscOptionsInt("-steps", "TS steps to take", "ex2.c", options->steps, &options->steps, NULL);CHKERRQ(ierr); 55*b80bf5b1SJoe Pusztay ierr = PetscOptionsBool("-monitor", "To use the TS monitor or not", "ex2.c", options->monitor, &options->monitor, NULL);CHKERRQ(ierr); 56*b80bf5b1SJoe Pusztay ierr = PetscOptionsBool("-simplex", "The flag for simplices or tensor cells", "ex2.c", options->simplex, &options->simplex, NULL);CHKERRQ(ierr); 57*b80bf5b1SJoe Pusztay ierr = PetscOptionsBool("-uniform", "Uniform particle spacing", "ex2.c", options->uniform, &options->uniform, NULL);CHKERRQ(ierr); 58*b80bf5b1SJoe Pusztay ierr = PetscOptionsBool("-bdm", "Use H1 instead of C0", "ex2.c", options->bdm, &options->bdm, NULL);CHKERRQ(ierr); 59*b80bf5b1SJoe Pusztay ierr = PetscOptionsString("-mesh", "Name of the mesh filename if any", "ex2.c", options->meshFilename, options->meshFilename, PETSC_MAX_PATH_LEN, NULL);CHKERRQ(ierr); 60*b80bf5b1SJoe Pusztay ierr = PetscOptionsInt("-k", "Mode number of test", "ex5.c", options->k, &options->k, NULL);CHKERRQ(ierr); 61*b80bf5b1SJoe Pusztay ierr = PetscOptionsInt("-particlesPerCell", "Number of particles per cell", "ex2.c", options->particlesPerCell, &options->particlesPerCell, NULL);CHKERRQ(ierr); 62*b80bf5b1SJoe Pusztay ierr = PetscOptionsReal("-sigma","parameter","<1>",options->sigma,&options->sigma,PETSC_NULL);CHKERRQ(ierr); 63*b80bf5b1SJoe Pusztay ierr = PetscOptionsReal("-stepSize","parameter","<1e-2>",options->stepSize,&options->stepSize,PETSC_NULL);CHKERRQ(ierr); 64*b80bf5b1SJoe Pusztay ierr = PetscOptionsReal("-timeScale","parameter","<1>",options->timeScale,&options->timeScale,PETSC_NULL);CHKERRQ(ierr); 65*b80bf5b1SJoe Pusztay ierr = PetscOptionsReal("-particle_perturbation", "Relative perturbation of particles (0,1)", "ex2.c", options->particleRelDx, &options->particleRelDx, NULL);CHKERRQ(ierr); 66*b80bf5b1SJoe Pusztay ierr = PetscOptionsEnd();CHKERRQ(ierr); 67*b80bf5b1SJoe Pusztay PetscFunctionReturn(0); 68*b80bf5b1SJoe Pusztay } 69*b80bf5b1SJoe Pusztay 70*b80bf5b1SJoe Pusztay static PetscErrorCode CreateMesh(MPI_Comm comm, DM *dm, AppCtx *user) 71*b80bf5b1SJoe Pusztay { 72*b80bf5b1SJoe Pusztay PetscErrorCode ierr; 73*b80bf5b1SJoe Pusztay 74*b80bf5b1SJoe Pusztay PetscFunctionBeginUser; 75*b80bf5b1SJoe Pusztay ierr = DMCreate(comm, dm);CHKERRQ(ierr); 76*b80bf5b1SJoe Pusztay ierr = DMSetType(*dm, DMPLEX);CHKERRQ(ierr); 77*b80bf5b1SJoe Pusztay ierr = DMSetFromOptions(*dm);CHKERRQ(ierr); 78*b80bf5b1SJoe Pusztay ierr = DMViewFromOptions(*dm, NULL, "-dm_view");CHKERRQ(ierr); 79*b80bf5b1SJoe Pusztay PetscFunctionReturn(0); 80*b80bf5b1SJoe Pusztay } 81*b80bf5b1SJoe Pusztay 82*b80bf5b1SJoe Pusztay static void laplacian_f1(PetscInt dim, PetscInt Nf, PetscInt NfAux, 83*b80bf5b1SJoe Pusztay const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 84*b80bf5b1SJoe Pusztay const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 85*b80bf5b1SJoe Pusztay PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f1[]) 86*b80bf5b1SJoe Pusztay { 87*b80bf5b1SJoe Pusztay PetscInt d; 88*b80bf5b1SJoe Pusztay for (d = 0; d < dim; ++d) {f1[d] = u_x[d];} 89*b80bf5b1SJoe Pusztay } 90*b80bf5b1SJoe Pusztay 91*b80bf5b1SJoe Pusztay static void laplacian(PetscInt dim, PetscInt Nf, PetscInt NfAux, 92*b80bf5b1SJoe Pusztay const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 93*b80bf5b1SJoe Pusztay const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 94*b80bf5b1SJoe Pusztay PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g3[]) 95*b80bf5b1SJoe Pusztay { 96*b80bf5b1SJoe Pusztay PetscInt d; 97*b80bf5b1SJoe Pusztay for (d = 0; d < dim; ++d) {g3[d*dim+d] = 1.0;} 98*b80bf5b1SJoe Pusztay } 99*b80bf5b1SJoe Pusztay 100*b80bf5b1SJoe Pusztay static PetscErrorCode CreateFEM(DM dm, AppCtx *user) 101*b80bf5b1SJoe Pusztay { 102*b80bf5b1SJoe Pusztay PetscFE fe; 103*b80bf5b1SJoe Pusztay PetscDS ds; 104*b80bf5b1SJoe Pusztay DMPolytopeType ct; 105*b80bf5b1SJoe Pusztay PetscBool simplex; 106*b80bf5b1SJoe Pusztay PetscInt dim, cStart; 107*b80bf5b1SJoe Pusztay PetscErrorCode ierr; 108*b80bf5b1SJoe Pusztay 109*b80bf5b1SJoe Pusztay PetscFunctionBeginUser; 110*b80bf5b1SJoe Pusztay ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 111*b80bf5b1SJoe Pusztay ierr = DMPlexGetHeightStratum(dm, 0, &cStart, NULL);CHKERRQ(ierr); 112*b80bf5b1SJoe Pusztay ierr = DMPlexGetCellType(dm, cStart, &ct);CHKERRQ(ierr); 113*b80bf5b1SJoe Pusztay simplex = DMPolytopeTypeGetNumVertices(ct) == DMPolytopeTypeGetDim(ct)+1 ? PETSC_TRUE : PETSC_FALSE; 114*b80bf5b1SJoe Pusztay ierr = PetscFECreateDefault(PetscObjectComm((PetscObject) dm), dim, 1, simplex, NULL, -1, &fe);CHKERRQ(ierr); 115*b80bf5b1SJoe Pusztay ierr = PetscObjectSetName((PetscObject) fe, "potential");CHKERRQ(ierr); 116*b80bf5b1SJoe Pusztay ierr = DMSetField(dm, 0, NULL, (PetscObject) fe);CHKERRQ(ierr); 117*b80bf5b1SJoe Pusztay ierr = DMCreateDS(dm);CHKERRQ(ierr); 118*b80bf5b1SJoe Pusztay ierr = PetscFEDestroy(&fe);CHKERRQ(ierr); 119*b80bf5b1SJoe Pusztay ierr = DMGetDS(dm, &ds);CHKERRQ(ierr); 120*b80bf5b1SJoe Pusztay ierr = PetscDSSetResidual(ds, 0, NULL, laplacian_f1);CHKERRQ(ierr); 121*b80bf5b1SJoe Pusztay ierr = PetscDSSetJacobian(ds, 0, 0, NULL, NULL, NULL, laplacian);CHKERRQ(ierr); 122*b80bf5b1SJoe Pusztay PetscFunctionReturn(0); 123*b80bf5b1SJoe Pusztay } 124*b80bf5b1SJoe Pusztay 125*b80bf5b1SJoe Pusztay /* 126*b80bf5b1SJoe Pusztay Initialize particle coordinates uniformly and with opposing velocities 127*b80bf5b1SJoe Pusztay */ 128*b80bf5b1SJoe Pusztay static PetscErrorCode CreateParticles(DM dm, DM *sw, AppCtx *user) 129*b80bf5b1SJoe Pusztay { 130*b80bf5b1SJoe Pusztay PetscRandom rnd, rndp; 131*b80bf5b1SJoe Pusztay PetscReal interval = user->particleRelDx; 132*b80bf5b1SJoe Pusztay PetscScalar value, *vals; 133*b80bf5b1SJoe Pusztay PetscReal *centroid, *coords, *xi0, *v0, *J, *invJ, detJ, *initialConditions, normalized_vel; 134*b80bf5b1SJoe Pusztay PetscInt *cellid, cStart; 135*b80bf5b1SJoe Pusztay PetscInt Ncell, Np = user->particlesPerCell, p, c, dim, d; 136*b80bf5b1SJoe Pusztay PetscErrorCode ierr; 137*b80bf5b1SJoe Pusztay 138*b80bf5b1SJoe Pusztay PetscFunctionBeginUser; 139*b80bf5b1SJoe Pusztay ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 140*b80bf5b1SJoe Pusztay ierr = DMCreate(PetscObjectComm((PetscObject) dm), sw);CHKERRQ(ierr); 141*b80bf5b1SJoe Pusztay ierr = DMSetType(*sw, DMSWARM);CHKERRQ(ierr); 142*b80bf5b1SJoe Pusztay ierr = DMSetDimension(*sw, dim);CHKERRQ(ierr); 143*b80bf5b1SJoe Pusztay ierr = PetscRandomCreate(PetscObjectComm((PetscObject) dm), &rnd);CHKERRQ(ierr); 144*b80bf5b1SJoe Pusztay ierr = PetscRandomSetInterval(rnd, 0.0, 1.0);CHKERRQ(ierr); 145*b80bf5b1SJoe Pusztay ierr = PetscRandomSetFromOptions(rnd);CHKERRQ(ierr); 146*b80bf5b1SJoe Pusztay ierr = PetscRandomCreate(PetscObjectComm((PetscObject) dm), &rndp);CHKERRQ(ierr); 147*b80bf5b1SJoe Pusztay ierr = PetscRandomSetInterval(rndp, -interval, interval);CHKERRQ(ierr); 148*b80bf5b1SJoe Pusztay ierr = PetscRandomSetFromOptions(rndp);CHKERRQ(ierr); 149*b80bf5b1SJoe Pusztay ierr = DMSwarmSetType(*sw, DMSWARM_PIC);CHKERRQ(ierr); 150*b80bf5b1SJoe Pusztay ierr = DMSwarmSetCellDM(*sw, dm);CHKERRQ(ierr); 151*b80bf5b1SJoe Pusztay ierr = DMSwarmRegisterPetscDatatypeField(*sw, "w_q", 1, PETSC_SCALAR);CHKERRQ(ierr); 152*b80bf5b1SJoe Pusztay ierr = DMSwarmRegisterPetscDatatypeField(*sw, "kinematics", dim, PETSC_REAL);CHKERRQ(ierr); 153*b80bf5b1SJoe Pusztay ierr = DMSwarmFinalizeFieldRegister(*sw);CHKERRQ(ierr); 154*b80bf5b1SJoe Pusztay ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &Ncell);CHKERRQ(ierr); 155*b80bf5b1SJoe Pusztay ierr = DMSwarmSetLocalSizes(*sw, Ncell * Np, 0);CHKERRQ(ierr); 156*b80bf5b1SJoe Pusztay ierr = DMSetFromOptions(*sw);CHKERRQ(ierr); 157*b80bf5b1SJoe Pusztay ierr = DMSwarmGetField(*sw, DMSwarmPICField_coor, NULL, NULL, (void **) &coords);CHKERRQ(ierr); 158*b80bf5b1SJoe Pusztay ierr = DMSwarmGetField(*sw, DMSwarmPICField_cellid, NULL, NULL, (void **) &cellid);CHKERRQ(ierr); 159*b80bf5b1SJoe Pusztay ierr = DMSwarmGetField(*sw, "w_q", NULL, NULL, (void **) &vals);CHKERRQ(ierr); 160*b80bf5b1SJoe Pusztay ierr = DMSwarmGetField(*sw, "kinematics", NULL, NULL, (void **) &initialConditions);CHKERRQ(ierr); 161*b80bf5b1SJoe Pusztay ierr = PetscMalloc5(dim, ¢roid, dim, &xi0, dim, &v0, dim*dim, &J, dim*dim, &invJ);CHKERRQ(ierr); 162*b80bf5b1SJoe Pusztay for (c = cStart; c < Ncell; c++) { 163*b80bf5b1SJoe Pusztay if (Np == 1) { 164*b80bf5b1SJoe Pusztay ierr = DMPlexComputeCellGeometryFVM(dm, c, NULL, centroid, NULL);CHKERRQ(ierr); 165*b80bf5b1SJoe Pusztay cellid[c] = c; 166*b80bf5b1SJoe Pusztay for (d = 0; d < dim; ++d) coords[c*dim+d] = centroid[d]; 167*b80bf5b1SJoe Pusztay } else { 168*b80bf5b1SJoe Pusztay for (d = 0; d < dim; ++d) xi0[d] = -1.0; 169*b80bf5b1SJoe Pusztay ierr = DMPlexComputeCellGeometryFEM(dm, c, NULL, v0, J, invJ, &detJ);CHKERRQ(ierr); /* affine */ 170*b80bf5b1SJoe Pusztay for (p = 0; p < Np; ++p) { 171*b80bf5b1SJoe Pusztay const PetscInt n = c*Np + p; 172*b80bf5b1SJoe Pusztay PetscReal refcoords[3], spacing; 173*b80bf5b1SJoe Pusztay 174*b80bf5b1SJoe Pusztay cellid[n] = c; 175*b80bf5b1SJoe Pusztay if (user->uniform) { 176*b80bf5b1SJoe Pusztay spacing = 2./Np; 177*b80bf5b1SJoe Pusztay ierr = PetscRandomGetValue(rnd, &value); 178*b80bf5b1SJoe Pusztay for (d=0; d<dim; ++d) refcoords[d] = d == 0 ? -1. + spacing/2. + p*spacing + value/100. : 0.; 179*b80bf5b1SJoe Pusztay } 180*b80bf5b1SJoe Pusztay else{ 181*b80bf5b1SJoe Pusztay for (d = 0; d < dim; ++d) {ierr = PetscRandomGetValue(rnd, &value);CHKERRQ(ierr); refcoords[d] = d == 0 ? PetscRealPart(value) : 0. ;} 182*b80bf5b1SJoe Pusztay } 183*b80bf5b1SJoe Pusztay CoordinatesRefToReal(dim, dim, xi0, v0, J, refcoords, &coords[n*dim]); 184*b80bf5b1SJoe Pusztay /* constant particle weights */ 185*b80bf5b1SJoe Pusztay for (d = 0; d < dim; ++d) vals[n] = user->sigma/Np; 186*b80bf5b1SJoe Pusztay } 187*b80bf5b1SJoe Pusztay } 188*b80bf5b1SJoe Pusztay } 189*b80bf5b1SJoe Pusztay ierr = PetscFree5(centroid, xi0, v0, J, invJ);CHKERRQ(ierr); 190*b80bf5b1SJoe Pusztay normalized_vel = 1.; 191*b80bf5b1SJoe Pusztay for (c = 0; c < Ncell; ++c) { 192*b80bf5b1SJoe Pusztay for (p = 0; p < Np; ++p) { 193*b80bf5b1SJoe Pusztay if (p%2 == 0) { 194*b80bf5b1SJoe Pusztay for (d = 0; d < dim; ++d) initialConditions[(c*Np + p)*dim + d] = d == 0 ? normalized_vel : 0.; 195*b80bf5b1SJoe Pusztay } 196*b80bf5b1SJoe Pusztay else { 197*b80bf5b1SJoe Pusztay for (d = 0; d < dim; ++d) initialConditions[(c*Np + p)*dim + d] = d == 0 ? -(normalized_vel) : 0.; 198*b80bf5b1SJoe Pusztay } 199*b80bf5b1SJoe Pusztay } 200*b80bf5b1SJoe Pusztay } 201*b80bf5b1SJoe Pusztay ierr = DMSwarmRestoreField(*sw, DMSwarmPICField_coor, NULL, NULL, (void **) &coords);CHKERRQ(ierr); 202*b80bf5b1SJoe Pusztay ierr = DMSwarmRestoreField(*sw, DMSwarmPICField_cellid, NULL, NULL, (void **) &cellid);CHKERRQ(ierr); 203*b80bf5b1SJoe Pusztay ierr = DMSwarmRestoreField(*sw, "w_q", NULL, NULL, (void **) &vals);CHKERRQ(ierr); 204*b80bf5b1SJoe Pusztay ierr = DMSwarmRestoreField(*sw, "kinematics", NULL, NULL, (void **) &initialConditions);CHKERRQ(ierr); 205*b80bf5b1SJoe Pusztay ierr = PetscRandomDestroy(&rnd);CHKERRQ(ierr); 206*b80bf5b1SJoe Pusztay ierr = PetscRandomDestroy(&rndp);CHKERRQ(ierr); 207*b80bf5b1SJoe Pusztay ierr = PetscObjectSetName((PetscObject) *sw, "Particles");CHKERRQ(ierr); 208*b80bf5b1SJoe Pusztay ierr = DMViewFromOptions(*sw, NULL, "-sw_view");CHKERRQ(ierr); 209*b80bf5b1SJoe Pusztay ierr = DMLocalizeCoordinates(*sw);CHKERRQ(ierr); 210*b80bf5b1SJoe Pusztay PetscFunctionReturn(0); 211*b80bf5b1SJoe Pusztay } 212*b80bf5b1SJoe Pusztay 213*b80bf5b1SJoe Pusztay /* Solve for particle position updates */ 214*b80bf5b1SJoe Pusztay static PetscErrorCode RHSFunction1(TS ts,PetscReal t,Vec V,Vec Posres,void *ctx) 215*b80bf5b1SJoe Pusztay { 216*b80bf5b1SJoe Pusztay const PetscScalar *v; 217*b80bf5b1SJoe Pusztay PetscScalar *posres; 218*b80bf5b1SJoe Pusztay PetscInt Np, p, dim, d; 219*b80bf5b1SJoe Pusztay DM dm; 220*b80bf5b1SJoe Pusztay PetscErrorCode ierr; 221*b80bf5b1SJoe Pusztay 222*b80bf5b1SJoe Pusztay PetscFunctionBeginUser; 223*b80bf5b1SJoe Pusztay ierr = VecGetLocalSize(Posres, &Np);CHKERRQ(ierr); 224*b80bf5b1SJoe Pusztay ierr = VecGetArray(Posres,&posres);CHKERRQ(ierr); 225*b80bf5b1SJoe Pusztay ierr = VecGetArrayRead(V,&v);CHKERRQ(ierr); 226*b80bf5b1SJoe Pusztay ierr = TSGetDM(ts, &dm);CHKERRQ(ierr); 227*b80bf5b1SJoe Pusztay ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 228*b80bf5b1SJoe Pusztay Np /= dim; 229*b80bf5b1SJoe Pusztay for (p = 0; p < Np; ++p) { 230*b80bf5b1SJoe Pusztay for (d = 0; d < dim; ++d) { 231*b80bf5b1SJoe Pusztay posres[p*dim+d] = v[p*dim+d]; 232*b80bf5b1SJoe Pusztay } 233*b80bf5b1SJoe Pusztay } 234*b80bf5b1SJoe Pusztay ierr = VecRestoreArrayRead(V,&v);CHKERRQ(ierr); 235*b80bf5b1SJoe Pusztay ierr = VecRestoreArray(Posres,&posres);CHKERRQ(ierr); 236*b80bf5b1SJoe Pusztay PetscFunctionReturn(0); 237*b80bf5b1SJoe Pusztay 238*b80bf5b1SJoe Pusztay } 239*b80bf5b1SJoe Pusztay 240*b80bf5b1SJoe Pusztay /* 241*b80bf5b1SJoe Pusztay Solve for the gradient of the electric field and apply force to particles. 242*b80bf5b1SJoe Pusztay */ 243*b80bf5b1SJoe Pusztay static PetscErrorCode RHSFunction2(TS ts,PetscReal t,Vec X,Vec Vres,void *ctx) 244*b80bf5b1SJoe Pusztay { 245*b80bf5b1SJoe Pusztay AppCtx *user = (AppCtx *) ctx; 246*b80bf5b1SJoe Pusztay DM dm, plex; 247*b80bf5b1SJoe Pusztay PetscDS prob; 248*b80bf5b1SJoe Pusztay PetscFE fe; 249*b80bf5b1SJoe Pusztay Mat M_p; 250*b80bf5b1SJoe Pusztay Vec phi, locPhi, rho, f; 251*b80bf5b1SJoe Pusztay const PetscScalar *x; 252*b80bf5b1SJoe Pusztay PetscScalar *vres; 253*b80bf5b1SJoe Pusztay PetscReal *coords, phi_0; 254*b80bf5b1SJoe Pusztay PetscInt dim, d, cStart, cEnd, cell, cdim; 255*b80bf5b1SJoe Pusztay PetscErrorCode ierr; 256*b80bf5b1SJoe Pusztay PetscReal m_e = 9.11e-31, q_e = 1.60e-19, epsi_0 = 8.85e-12; 257*b80bf5b1SJoe Pusztay 258*b80bf5b1SJoe Pusztay PetscFunctionBeginUser; 259*b80bf5b1SJoe Pusztay PetscObjectSetName((PetscObject) X, "rhsf2 position"); 260*b80bf5b1SJoe Pusztay VecViewFromOptions(X, NULL, "-rhsf2_x_view"); 261*b80bf5b1SJoe Pusztay ierr = VecGetArrayRead(X,&x);CHKERRQ(ierr); 262*b80bf5b1SJoe Pusztay ierr = VecGetArray(Vres,&vres);CHKERRQ(ierr); 263*b80bf5b1SJoe Pusztay ierr = TSGetDM(ts, &dm);CHKERRQ(ierr); 264*b80bf5b1SJoe Pusztay ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 265*b80bf5b1SJoe Pusztay ierr = SNESGetDM(user->snes, &plex);CHKERRQ(ierr); 266*b80bf5b1SJoe Pusztay ierr = DMGetCoordinateDim(plex, &cdim);CHKERRQ(ierr); 267*b80bf5b1SJoe Pusztay ierr = DMGetDS(plex, &prob);CHKERRQ(ierr); 268*b80bf5b1SJoe Pusztay ierr = PetscDSGetDiscretization(prob, 0, (PetscObject *) &fe);CHKERRQ(ierr); 269*b80bf5b1SJoe Pusztay ierr = DMGetGlobalVector(plex, &phi);CHKERRQ(ierr); 270*b80bf5b1SJoe Pusztay ierr = DMGetLocalVector(plex, &locPhi);CHKERRQ(ierr); 271*b80bf5b1SJoe Pusztay ierr = DMCreateMassMatrix(dm, plex, &M_p);CHKERRQ(ierr); 272*b80bf5b1SJoe Pusztay ierr = MatViewFromOptions(M_p, NULL, "-mp_view"); 273*b80bf5b1SJoe Pusztay ierr = DMGetGlobalVector(plex, &rho);CHKERRQ(ierr); 274*b80bf5b1SJoe Pusztay ierr = DMSwarmCreateGlobalVectorFromField(dm, "w_q", &f);CHKERRQ(ierr); 275*b80bf5b1SJoe Pusztay ierr = PetscObjectSetName((PetscObject) f, "weights vector"); 276*b80bf5b1SJoe Pusztay ierr = VecViewFromOptions(f, NULL, "-weights_view"); 277*b80bf5b1SJoe Pusztay ierr = MatMultTranspose(M_p, f, rho);CHKERRQ(ierr); 278*b80bf5b1SJoe Pusztay ierr = DMSwarmDestroyGlobalVectorFromField(dm, "w_q", &f);CHKERRQ(ierr); 279*b80bf5b1SJoe Pusztay ierr = PetscObjectSetName((PetscObject) rho, "rho");CHKERRQ(ierr); 280*b80bf5b1SJoe Pusztay ierr = VecViewFromOptions(rho, NULL, "-poisson_rho_view");CHKERRQ(ierr); 281*b80bf5b1SJoe Pusztay /* Take nullspace out of rhs */ 282*b80bf5b1SJoe Pusztay { 283*b80bf5b1SJoe Pusztay PetscScalar sum; 284*b80bf5b1SJoe Pusztay PetscInt n; 285*b80bf5b1SJoe Pusztay phi_0 = (user->sigma*user->sigma*user->sigma)*(user->timeScale*user->timeScale)/(m_e*q_e*epsi_0); 286*b80bf5b1SJoe Pusztay 287*b80bf5b1SJoe Pusztay ierr = VecGetSize(rho, &n);CHKERRQ(ierr); 288*b80bf5b1SJoe Pusztay ierr = VecSum(rho, &sum);CHKERRQ(ierr); 289*b80bf5b1SJoe Pusztay ierr = VecShift(rho, -sum/n);CHKERRQ(ierr); 290*b80bf5b1SJoe Pusztay 291*b80bf5b1SJoe Pusztay ierr = VecSum(rho, &sum);CHKERRQ(ierr); 292*b80bf5b1SJoe Pusztay if (PetscAbsScalar(sum) > 1.0e-10) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Charge should have no DC component %g", sum); 293*b80bf5b1SJoe Pusztay ierr = VecScale(rho, phi_0);CHKERRQ(ierr); 294*b80bf5b1SJoe Pusztay } 295*b80bf5b1SJoe Pusztay ierr = VecSet(phi, 0.0);CHKERRQ(ierr); 296*b80bf5b1SJoe Pusztay ierr = SNESSolve(user->snes, rho, phi);CHKERRQ(ierr); 297*b80bf5b1SJoe Pusztay ierr = VecViewFromOptions(phi, NULL, "-phi_view");CHKERRQ(ierr); 298*b80bf5b1SJoe Pusztay ierr = DMRestoreGlobalVector(plex, &rho);CHKERRQ(ierr); 299*b80bf5b1SJoe Pusztay ierr = MatDestroy(&M_p);CHKERRQ(ierr); 300*b80bf5b1SJoe Pusztay ierr = DMGlobalToLocalBegin(plex, phi, INSERT_VALUES, locPhi);CHKERRQ(ierr); 301*b80bf5b1SJoe Pusztay ierr = DMGlobalToLocalEnd(plex, phi, INSERT_VALUES, locPhi);CHKERRQ(ierr); 302*b80bf5b1SJoe Pusztay ierr = DMSwarmSortGetAccess(dm);CHKERRQ(ierr); 303*b80bf5b1SJoe Pusztay ierr = DMSwarmGetField(dm, DMSwarmPICField_coor, NULL, NULL, (void **) &coords);CHKERRQ(ierr); 304*b80bf5b1SJoe Pusztay ierr = DMPlexGetHeightStratum(plex, 0, &cStart, &cEnd);CHKERRQ(ierr); 305*b80bf5b1SJoe Pusztay for (cell = cStart; cell < cEnd; ++cell) { 306*b80bf5b1SJoe Pusztay PetscTabulation tab; 307*b80bf5b1SJoe Pusztay PetscReal v[3], J[9], invJ[9], detJ; 308*b80bf5b1SJoe Pusztay PetscScalar *ph = PETSC_NULL; 309*b80bf5b1SJoe Pusztay PetscReal *pcoord = PETSC_NULL; 310*b80bf5b1SJoe Pusztay PetscReal *refcoord = PETSC_NULL; 311*b80bf5b1SJoe Pusztay PetscInt *points = PETSC_NULL, Ncp, cp; 312*b80bf5b1SJoe Pusztay PetscScalar gradPhi[3]; 313*b80bf5b1SJoe Pusztay 314*b80bf5b1SJoe Pusztay ierr = DMPlexComputeCellGeometryFEM(plex, cell, NULL, v, J, invJ, &detJ);CHKERRQ(ierr); 315*b80bf5b1SJoe Pusztay ierr = DMSwarmSortGetPointsPerCell(dm, cell, &Ncp, &points);CHKERRQ(ierr); 316*b80bf5b1SJoe Pusztay ierr = DMGetWorkArray(dm, Ncp*cdim, MPIU_REAL, &pcoord);CHKERRQ(ierr); 317*b80bf5b1SJoe Pusztay ierr = DMGetWorkArray(dm, Ncp*cdim, MPIU_REAL, &refcoord);CHKERRQ(ierr); 318*b80bf5b1SJoe Pusztay for (cp = 0; cp < Ncp; ++cp) { 319*b80bf5b1SJoe Pusztay for (d = 0; d < cdim; ++d) { 320*b80bf5b1SJoe Pusztay pcoord[cp*cdim+d] = coords[points[cp]*cdim+d]; 321*b80bf5b1SJoe Pusztay } 322*b80bf5b1SJoe Pusztay } 323*b80bf5b1SJoe Pusztay ierr = DMPlexCoordinatesToReference(plex, cell, Ncp, pcoord, refcoord);CHKERRQ(ierr); 324*b80bf5b1SJoe Pusztay PetscFECreateTabulation(fe, 1, Ncp, refcoord, 1, &tab);CHKERRQ(ierr); 325*b80bf5b1SJoe Pusztay ierr = DMPlexVecGetClosure(plex, NULL, locPhi, cell, NULL, &ph);CHKERRQ(ierr); 326*b80bf5b1SJoe Pusztay for (cp = 0; cp < Ncp; ++cp) { 327*b80bf5b1SJoe Pusztay const PetscInt p = points[cp]; 328*b80bf5b1SJoe Pusztay gradPhi[0] = 0.0; 329*b80bf5b1SJoe Pusztay gradPhi[1] = 0.0; 330*b80bf5b1SJoe Pusztay gradPhi[2] = 0.0; 331*b80bf5b1SJoe Pusztay const PetscReal *basisDer = tab->T[1]; 332*b80bf5b1SJoe Pusztay 333*b80bf5b1SJoe Pusztay ierr = PetscFEFreeInterpolateGradient_Static(fe, basisDer, ph, cdim, invJ, NULL, cp, gradPhi);CHKERRQ(ierr); 334*b80bf5b1SJoe Pusztay for (d = 0; d < cdim; ++d) { 335*b80bf5b1SJoe Pusztay vres[p*cdim+d] = d == 0 ? gradPhi[d] : 0.; 336*b80bf5b1SJoe Pusztay } 337*b80bf5b1SJoe Pusztay } 338*b80bf5b1SJoe Pusztay ierr = DMPlexVecRestoreClosure(plex, NULL, locPhi, cell, NULL, &ph);CHKERRQ(ierr); 339*b80bf5b1SJoe Pusztay ierr = PetscTabulationDestroy(&tab);CHKERRQ(ierr); 340*b80bf5b1SJoe Pusztay ierr = DMRestoreWorkArray(dm, Ncp*cdim, MPIU_REAL, &pcoord);CHKERRQ(ierr); 341*b80bf5b1SJoe Pusztay ierr = DMRestoreWorkArray(dm, Ncp*cdim, MPIU_REAL, &refcoord);CHKERRQ(ierr); 342*b80bf5b1SJoe Pusztay ierr = PetscFree(points);CHKERRQ(ierr); 343*b80bf5b1SJoe Pusztay } 344*b80bf5b1SJoe Pusztay ierr = DMSwarmRestoreField(dm, DMSwarmPICField_coor, NULL, NULL, (void **) &coords);CHKERRQ(ierr); 345*b80bf5b1SJoe Pusztay ierr = DMSwarmSortRestoreAccess(dm);CHKERRQ(ierr); 346*b80bf5b1SJoe Pusztay ierr = DMRestoreLocalVector(plex, &locPhi);CHKERRQ(ierr); 347*b80bf5b1SJoe Pusztay ierr = DMRestoreGlobalVector(plex, &phi);CHKERRQ(ierr); 348*b80bf5b1SJoe Pusztay ierr = VecRestoreArray(Vres,&vres);CHKERRQ(ierr); 349*b80bf5b1SJoe Pusztay ierr = VecRestoreArrayRead(X,&x);CHKERRQ(ierr); 350*b80bf5b1SJoe Pusztay ierr = VecViewFromOptions(Vres, NULL, "-vel_res_view");CHKERRQ(ierr); 351*b80bf5b1SJoe Pusztay PetscFunctionReturn(0); 352*b80bf5b1SJoe Pusztay } 353*b80bf5b1SJoe Pusztay 354*b80bf5b1SJoe Pusztay int main(int argc,char **argv) 355*b80bf5b1SJoe Pusztay { 356*b80bf5b1SJoe Pusztay PetscInt i, par; 357*b80bf5b1SJoe Pusztay PetscInt locSize, p, d, dim, Np, step, *idx1, *idx2; 358*b80bf5b1SJoe Pusztay TS ts; 359*b80bf5b1SJoe Pusztay DM dm, sw; 360*b80bf5b1SJoe Pusztay AppCtx user; 361*b80bf5b1SJoe Pusztay MPI_Comm comm; 362*b80bf5b1SJoe Pusztay PetscErrorCode ierr; 363*b80bf5b1SJoe Pusztay Vec coorVec, kinVec, probVec, solution, position, momentum; 364*b80bf5b1SJoe Pusztay const PetscScalar *coorArr, *kinArr; 365*b80bf5b1SJoe Pusztay PetscReal ftime = 10., *probArr, *probVecArr; 366*b80bf5b1SJoe Pusztay IS is1,is2; 367*b80bf5b1SJoe Pusztay PetscReal *coor, *kin, *pos, *mom; 368*b80bf5b1SJoe Pusztay 369*b80bf5b1SJoe Pusztay ierr = PetscInitialize(&argc,&argv,NULL,help);if (ierr) return ierr; 370*b80bf5b1SJoe Pusztay comm = PETSC_COMM_WORLD; 371*b80bf5b1SJoe Pusztay ierr = ProcessOptions(comm, &user);CHKERRQ(ierr); 372*b80bf5b1SJoe Pusztay /* Create dm and particles */ 373*b80bf5b1SJoe Pusztay ierr = CreateMesh(comm, &dm, &user);CHKERRQ(ierr); 374*b80bf5b1SJoe Pusztay ierr = CreateFEM(dm, &user);CHKERRQ(ierr); 375*b80bf5b1SJoe Pusztay ierr = CreateParticles(dm, &sw, &user);CHKERRQ(ierr); 376*b80bf5b1SJoe Pusztay ierr = SNESCreate(comm, &user.snes);CHKERRQ(ierr); 377*b80bf5b1SJoe Pusztay ierr = SNESSetDM(user.snes, dm);CHKERRQ(ierr); 378*b80bf5b1SJoe Pusztay ierr = DMPlexSetSNESLocalFEM(dm,&user,&user,&user);CHKERRQ(ierr); 379*b80bf5b1SJoe Pusztay ierr = SNESSetFromOptions(user.snes);CHKERRQ(ierr); 380*b80bf5b1SJoe Pusztay { 381*b80bf5b1SJoe Pusztay Mat J; 382*b80bf5b1SJoe Pusztay MatNullSpace nullSpace; 383*b80bf5b1SJoe Pusztay 384*b80bf5b1SJoe Pusztay ierr = DMCreateMatrix(dm, &J);CHKERRQ(ierr); 385*b80bf5b1SJoe Pusztay ierr = MatNullSpaceCreate(PetscObjectComm((PetscObject) dm), PETSC_TRUE, 0, NULL, &nullSpace);CHKERRQ(ierr); 386*b80bf5b1SJoe Pusztay ierr = MatSetNullSpace(J, nullSpace);CHKERRQ(ierr); 387*b80bf5b1SJoe Pusztay ierr = MatNullSpaceDestroy(&nullSpace);CHKERRQ(ierr); 388*b80bf5b1SJoe Pusztay ierr = SNESSetJacobian(user.snes, J, J, NULL, NULL);CHKERRQ(ierr); 389*b80bf5b1SJoe Pusztay ierr = MatDestroy(&J);CHKERRQ(ierr); 390*b80bf5b1SJoe Pusztay } 391*b80bf5b1SJoe Pusztay /* Place TSSolve in a loop to handle resetting the TS at every manual call of TSStep() */ 392*b80bf5b1SJoe Pusztay ierr = TSCreate(comm, &ts);CHKERRQ(ierr); 393*b80bf5b1SJoe Pusztay ierr = TSSetMaxTime(ts,ftime);CHKERRQ(ierr); 394*b80bf5b1SJoe Pusztay ierr = TSSetTimeStep(ts,user.stepSize);CHKERRQ(ierr); 395*b80bf5b1SJoe Pusztay ierr = TSSetMaxSteps(ts,100000);CHKERRQ(ierr); 396*b80bf5b1SJoe Pusztay ierr = TSSetExactFinalTime(ts,TS_EXACTFINALTIME_MATCHSTEP);CHKERRQ(ierr); 397*b80bf5b1SJoe Pusztay for (step = 0; step < user.steps ; ++step){ 398*b80bf5b1SJoe Pusztay 399*b80bf5b1SJoe Pusztay ierr = DMSwarmCreateGlobalVectorFromField(sw, "kinematics", &kinVec);CHKERRQ(ierr); 400*b80bf5b1SJoe Pusztay ierr = DMSwarmCreateGlobalVectorFromField(sw, DMSwarmPICField_coor, &coorVec);CHKERRQ(ierr); 401*b80bf5b1SJoe Pusztay ierr = VecViewFromOptions(kinVec, NULL, "-ic_vec_view"); 402*b80bf5b1SJoe Pusztay ierr = DMGetDimension(sw, &dim);CHKERRQ(ierr); 403*b80bf5b1SJoe Pusztay ierr = VecGetLocalSize(kinVec, &locSize);CHKERRQ(ierr); 404*b80bf5b1SJoe Pusztay ierr = PetscMalloc1(locSize, &idx1);CHKERRQ(ierr); 405*b80bf5b1SJoe Pusztay ierr = PetscMalloc1(locSize, &idx2);CHKERRQ(ierr); 406*b80bf5b1SJoe Pusztay ierr = PetscMalloc1(2*locSize, &probArr);CHKERRQ(ierr); 407*b80bf5b1SJoe Pusztay Np = locSize/dim; 408*b80bf5b1SJoe Pusztay ierr = VecGetArrayRead(kinVec, &kinArr);CHKERRQ(ierr); 409*b80bf5b1SJoe Pusztay ierr = VecGetArrayRead(coorVec, &coorArr);CHKERRQ(ierr); 410*b80bf5b1SJoe Pusztay for (p=0; p<Np; ++p){ 411*b80bf5b1SJoe Pusztay for (d=0; d<dim;++d) { 412*b80bf5b1SJoe Pusztay probArr[p*2*dim + d] = coorArr[p*dim+d]; 413*b80bf5b1SJoe Pusztay probArr[(p*2+1)*dim + d] = kinArr[p*dim+d]; 414*b80bf5b1SJoe Pusztay } 415*b80bf5b1SJoe Pusztay } 416*b80bf5b1SJoe Pusztay ierr = VecRestoreArrayRead(kinVec, &kinArr);CHKERRQ(ierr); 417*b80bf5b1SJoe Pusztay ierr = VecRestoreArrayRead(coorVec, &coorArr);CHKERRQ(ierr); 418*b80bf5b1SJoe Pusztay /* Allocate for IS Strides that will contain x, y and vx, vy */ 419*b80bf5b1SJoe Pusztay for (p = 0; p < Np; ++p) { 420*b80bf5b1SJoe Pusztay for (d = 0; d < dim; ++d) { 421*b80bf5b1SJoe Pusztay idx1[p*dim+d] = (p*2+0)*dim + d; 422*b80bf5b1SJoe Pusztay idx2[p*dim+d] = (p*2+1)*dim + d; 423*b80bf5b1SJoe Pusztay } 424*b80bf5b1SJoe Pusztay } 425*b80bf5b1SJoe Pusztay 426*b80bf5b1SJoe Pusztay ierr = ISCreateGeneral(comm, locSize, idx1, PETSC_OWN_POINTER, &is1);CHKERRQ(ierr); 427*b80bf5b1SJoe Pusztay ierr = ISCreateGeneral(comm, locSize, idx2, PETSC_OWN_POINTER, &is2);CHKERRQ(ierr); 428*b80bf5b1SJoe Pusztay /* DM needs to be set before splits so it propogates to sub TSs */ 429*b80bf5b1SJoe Pusztay ierr = TSSetDM(ts, sw);CHKERRQ(ierr); 430*b80bf5b1SJoe Pusztay ierr = TSSetType(ts,TSBASICSYMPLECTIC);CHKERRQ(ierr); 431*b80bf5b1SJoe Pusztay ierr = TSRHSSplitSetIS(ts,"position",is1);CHKERRQ(ierr); 432*b80bf5b1SJoe Pusztay ierr = TSRHSSplitSetIS(ts,"momentum",is2);CHKERRQ(ierr); 433*b80bf5b1SJoe Pusztay ierr = TSRHSSplitSetRHSFunction(ts,"position",NULL,RHSFunction1,&user);CHKERRQ(ierr); 434*b80bf5b1SJoe Pusztay ierr = TSRHSSplitSetRHSFunction(ts,"momentum",NULL,RHSFunction2,&user);CHKERRQ(ierr); 435*b80bf5b1SJoe Pusztay ierr = TSSetTime(ts, step*user.stepSize);CHKERRQ(ierr); 436*b80bf5b1SJoe Pusztay if (step == 0) { 437*b80bf5b1SJoe Pusztay ierr = TSSetFromOptions(ts);CHKERRQ(ierr); 438*b80bf5b1SJoe Pusztay } 439*b80bf5b1SJoe Pusztay /* Compose vector from array for TS solve with all kinematic variables */ 440*b80bf5b1SJoe Pusztay ierr = VecCreate(comm,&probVec);CHKERRQ(ierr); 441*b80bf5b1SJoe Pusztay ierr = VecSetBlockSize(probVec,1);CHKERRQ(ierr); 442*b80bf5b1SJoe Pusztay ierr = VecSetSizes(probVec,PETSC_DECIDE,2*locSize);CHKERRQ(ierr); 443*b80bf5b1SJoe Pusztay ierr = VecSetUp(probVec);CHKERRQ(ierr); 444*b80bf5b1SJoe Pusztay ierr = VecGetArray(probVec,&probVecArr); 445*b80bf5b1SJoe Pusztay for (i=0; i < 2*locSize; ++i) { 446*b80bf5b1SJoe Pusztay probVecArr[i] = probArr[i]; 447*b80bf5b1SJoe Pusztay } 448*b80bf5b1SJoe Pusztay ierr = VecRestoreArray(probVec,&probVecArr);CHKERRQ(ierr); 449*b80bf5b1SJoe Pusztay ierr = TSSetSolution(ts, probVec);CHKERRQ(ierr); 450*b80bf5b1SJoe Pusztay ierr = PetscFree(probArr);CHKERRQ(ierr); 451*b80bf5b1SJoe Pusztay ierr = VecViewFromOptions(kinVec, NULL, "-ic_view"); 452*b80bf5b1SJoe Pusztay ierr = DMSwarmDestroyGlobalVectorFromField(sw, "kinematics", &kinVec);CHKERRQ(ierr); 453*b80bf5b1SJoe Pusztay ierr = DMSwarmDestroyGlobalVectorFromField(sw, DMSwarmPICField_coor, &coorVec);CHKERRQ(ierr); 454*b80bf5b1SJoe Pusztay ierr = TSMonitor(ts, step, ts->ptime, ts->vec_sol);CHKERRQ(ierr); 455*b80bf5b1SJoe Pusztay if (!ts->steprollback) { 456*b80bf5b1SJoe Pusztay ierr = TSPreStep(ts);CHKERRQ(ierr); 457*b80bf5b1SJoe Pusztay } 458*b80bf5b1SJoe Pusztay ierr = TSStep(ts);CHKERRQ(ierr); 459*b80bf5b1SJoe Pusztay if (ts->steprollback) { 460*b80bf5b1SJoe Pusztay ierr = TSPostEvaluate(ts);CHKERRQ(ierr); 461*b80bf5b1SJoe Pusztay } 462*b80bf5b1SJoe Pusztay if (!ts->steprollback) { 463*b80bf5b1SJoe Pusztay 464*b80bf5b1SJoe Pusztay TSPostStep(ts); 465*b80bf5b1SJoe Pusztay ierr = DMSwarmGetField(sw, DMSwarmPICField_coor, NULL, NULL, (void **) &coor);CHKERRQ(ierr); 466*b80bf5b1SJoe Pusztay ierr = DMSwarmGetField(sw, "kinematics", NULL, NULL, (void **) &kin);CHKERRQ(ierr); 467*b80bf5b1SJoe Pusztay ierr = TSGetSolution(ts, &solution);CHKERRQ(ierr); 468*b80bf5b1SJoe Pusztay ierr = VecGetSubVector(solution,is1,&position);CHKERRQ(ierr); 469*b80bf5b1SJoe Pusztay ierr = VecGetSubVector(solution,is2,&momentum);CHKERRQ(ierr); 470*b80bf5b1SJoe Pusztay ierr = VecGetArray(position, &pos);CHKERRQ(ierr); 471*b80bf5b1SJoe Pusztay ierr = VecGetArray(momentum, &mom);CHKERRQ(ierr); 472*b80bf5b1SJoe Pusztay for (par = 0; par < Np; ++par){ 473*b80bf5b1SJoe Pusztay for (d=0; d<dim; ++d){ 474*b80bf5b1SJoe Pusztay if (pos[par*dim+d] < 0.) { 475*b80bf5b1SJoe Pusztay coor[par*dim+d] = pos[par*dim+d] + 2.*PETSC_PI; 476*b80bf5b1SJoe Pusztay } 477*b80bf5b1SJoe Pusztay else if (pos[par*dim+d] > 2.*PETSC_PI) { 478*b80bf5b1SJoe Pusztay coor[par*dim+d] = pos[par*dim+d] - 2.*PETSC_PI; 479*b80bf5b1SJoe Pusztay } 480*b80bf5b1SJoe Pusztay else{ 481*b80bf5b1SJoe Pusztay coor[par*dim+d] = pos[par*dim+d]; 482*b80bf5b1SJoe Pusztay } 483*b80bf5b1SJoe Pusztay kin[par*dim+d] = mom[par*dim+d]; 484*b80bf5b1SJoe Pusztay } 485*b80bf5b1SJoe Pusztay } 486*b80bf5b1SJoe Pusztay ierr = VecRestoreArray(position, &pos);CHKERRQ(ierr); 487*b80bf5b1SJoe Pusztay ierr = VecRestoreArray(momentum, &mom);CHKERRQ(ierr); 488*b80bf5b1SJoe Pusztay ierr = VecRestoreSubVector(solution,is1,&position);CHKERRQ(ierr); 489*b80bf5b1SJoe Pusztay ierr = VecRestoreSubVector(solution,is2,&momentum);CHKERRQ(ierr); 490*b80bf5b1SJoe Pusztay ierr = DMSwarmRestoreField(sw, DMSwarmPICField_coor, NULL, NULL, (void **) &coor);CHKERRQ(ierr); 491*b80bf5b1SJoe Pusztay ierr = DMSwarmRestoreField(sw, "kinematics", NULL, NULL, (void **) &kin);CHKERRQ(ierr); 492*b80bf5b1SJoe Pusztay } 493*b80bf5b1SJoe Pusztay ierr = DMSwarmMigrate(sw, PETSC_TRUE);CHKERRQ(ierr); 494*b80bf5b1SJoe Pusztay ierr = DMLocalizeCoordinates(sw);CHKERRQ(ierr); 495*b80bf5b1SJoe Pusztay ierr = TSReset(ts);CHKERRQ(ierr); 496*b80bf5b1SJoe Pusztay ierr = VecDestroy(&probVec);CHKERRQ(ierr); 497*b80bf5b1SJoe Pusztay ierr = ISDestroy(&is1);CHKERRQ(ierr); 498*b80bf5b1SJoe Pusztay ierr = ISDestroy(&is2);CHKERRQ(ierr); 499*b80bf5b1SJoe Pusztay } 500*b80bf5b1SJoe Pusztay ierr = SNESDestroy(&user.snes);CHKERRQ(ierr); 501*b80bf5b1SJoe Pusztay ierr = TSDestroy(&ts);CHKERRQ(ierr); 502*b80bf5b1SJoe Pusztay ierr = DMDestroy(&sw);CHKERRQ(ierr); 503*b80bf5b1SJoe Pusztay ierr = DMDestroy(&dm);CHKERRQ(ierr); 504*b80bf5b1SJoe Pusztay ierr = PetscFinalize(); 505*b80bf5b1SJoe Pusztay return ierr; 506*b80bf5b1SJoe Pusztay } 507*b80bf5b1SJoe Pusztay 508*b80bf5b1SJoe Pusztay /*TEST 509*b80bf5b1SJoe Pusztay 510*b80bf5b1SJoe Pusztay build: 511*b80bf5b1SJoe Pusztay requires: triangle !single !complex 512*b80bf5b1SJoe Pusztay test: 513*b80bf5b1SJoe Pusztay suffix: bsi1q3 514*b80bf5b1SJoe Pusztay args: -particlesPerCell 200\ 515*b80bf5b1SJoe Pusztay -petscspace_degree 2\ 516*b80bf5b1SJoe Pusztay -petscfe_default_quadrature_order 3\ 517*b80bf5b1SJoe Pusztay -ts_basicsymplectic_type 1\ 518*b80bf5b1SJoe Pusztay -pc_type svd\ 519*b80bf5b1SJoe Pusztay -uniform\ 520*b80bf5b1SJoe Pusztay -sigma 1.0e-8\ 521*b80bf5b1SJoe Pusztay -timeScale 2.0e-14\ 522*b80bf5b1SJoe Pusztay -stepSize 1.0e-2\ 523*b80bf5b1SJoe Pusztay -ts_monitor_sp_swarm\ 524*b80bf5b1SJoe Pusztay -steps 10\ 525*b80bf5b1SJoe Pusztay -dm_view\ 526*b80bf5b1SJoe Pusztay -dm_plex_simplex 0 -dm_plex_dim 2\ 527*b80bf5b1SJoe Pusztay -dm_plex_box_lower 0,-1\ 528*b80bf5b1SJoe Pusztay -dm_plex_box_upper 6.283185307179586,1\ 529*b80bf5b1SJoe Pusztay -dm_plex_box_bd periodic,none\ 530*b80bf5b1SJoe Pusztay -dm_plex_box_faces 4,1 531*b80bf5b1SJoe Pusztay test: 532*b80bf5b1SJoe Pusztay suffix: bsi2q3 533*b80bf5b1SJoe Pusztay args: -particlesPerCell 200\ 534*b80bf5b1SJoe Pusztay -petscspace_degree 2\ 535*b80bf5b1SJoe Pusztay -petscfe_default_quadrature_order 3\ 536*b80bf5b1SJoe Pusztay -ts_basicsymplectic_type 2\ 537*b80bf5b1SJoe Pusztay -pc_type svd\ 538*b80bf5b1SJoe Pusztay -uniform\ 539*b80bf5b1SJoe Pusztay -sigma 1.0e-8\ 540*b80bf5b1SJoe Pusztay -timeScale 2.0e-14\ 541*b80bf5b1SJoe Pusztay -stepSize 1.0e-2\ 542*b80bf5b1SJoe Pusztay -ts_monitor_sp_swarm\ 543*b80bf5b1SJoe Pusztay -steps 10\ 544*b80bf5b1SJoe Pusztay -dm_view\ 545*b80bf5b1SJoe Pusztay -dm_plex_simplex 0 -dm_plex_dim 2\ 546*b80bf5b1SJoe Pusztay -dm_plex_box_lower 0,-1\ 547*b80bf5b1SJoe Pusztay -dm_plex_box_upper 6.283185307179586,1\ 548*b80bf5b1SJoe Pusztay -dm_plex_box_bd periodic,none\ 549*b80bf5b1SJoe Pusztay -dm_plex_box_faces 4,1 550*b80bf5b1SJoe Pusztay TEST*/ 551