xref: /petsc/src/dm/impls/swarm/tutorials/ex1.c (revision b122ec5aa1bd4469eb4e0673542fb7de3f411254)
14cd81d59SMatthew G. Knepley static char help[] = "Example program demonstrating projection between particle and finite element spaces\n\n";
24cd81d59SMatthew G. Knepley 
34cd81d59SMatthew G. Knepley #include "petscdmplex.h"
44cd81d59SMatthew G. Knepley #include "petscds.h"
54cd81d59SMatthew G. Knepley #include "petscdmswarm.h"
64cd81d59SMatthew G. Knepley #include "petscksp.h"
74cd81d59SMatthew G. Knepley 
84cd81d59SMatthew G. Knepley int main(int argc, char **argv)
94cd81d59SMatthew G. Knepley {
103c611800SMark Adams   DM              dm, sw;
114cd81d59SMatthew G. Knepley   PetscFE         fe;
124cd81d59SMatthew G. Knepley   KSP             ksp;
133c611800SMark Adams   PC              pc;
143c611800SMark Adams   Mat             M_p, PM_p=NULL;
153c611800SMark Adams   Vec             f, rho, rhs;
163c611800SMark Adams   PetscInt        dim, Nc = 1, timestep = 0, i, faces[3];
1730602db0SMatthew G. Knepley   PetscInt        Np = 10, p, field = 0, zero = 0, bs;
183c611800SMark Adams   PetscReal       time = 0.0,  norm, energy_0, energy_1;
1930602db0SMatthew G. Knepley   PetscReal       lo[3], hi[3], h[3];
2030602db0SMatthew G. Knepley   PetscBool       removePoints = PETSC_TRUE;
2130602db0SMatthew G. Knepley   PetscReal       *wq, *coords;
224cd81d59SMatthew G. Knepley   PetscDataType   dtype;
233c611800SMark Adams   PetscBool       is_bjac;
244cd81d59SMatthew G. Knepley 
25*b122ec5aSJacob Faibussowitsch   CHKERRQ(PetscInitialize(&argc, &argv, NULL,help));
264cd81d59SMatthew G. Knepley   /* Create a mesh */
275f80ce2aSJacob Faibussowitsch   CHKERRQ(DMCreate(PETSC_COMM_WORLD, &dm));
285f80ce2aSJacob Faibussowitsch   CHKERRQ(DMSetType(dm, DMPLEX));
295f80ce2aSJacob Faibussowitsch   CHKERRQ(DMSetFromOptions(dm));
305f80ce2aSJacob Faibussowitsch   CHKERRQ(DMViewFromOptions(dm, NULL, "-dm_view"));
3130602db0SMatthew G. Knepley 
325f80ce2aSJacob Faibussowitsch   CHKERRQ(DMGetDimension(dm, &dim));
3330602db0SMatthew G. Knepley   i    = dim;
345f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsGetIntArray(NULL, NULL, "-dm_plex_box_faces", faces, &i, NULL));
355f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsGetInt(NULL, NULL, "-np", &Np, NULL));
365f80ce2aSJacob Faibussowitsch   CHKERRQ(DMGetBoundingBox(dm, lo, hi));
3730602db0SMatthew G. Knepley   for (i=0;i<dim;i++) {
3830602db0SMatthew G. Knepley     h[i] = (hi[i] - lo[i])/faces[i];
395f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscPrintf(PETSC_COMM_SELF," lo = %g hi = %g n = %D h = %g\n",lo[i],hi[i],faces[i],h[i]));
4030602db0SMatthew G. Knepley   }
4130602db0SMatthew G. Knepley 
425f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscFECreateDefault(PETSC_COMM_SELF, dim, Nc, PETSC_FALSE, "", PETSC_DECIDE, &fe));
435f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscFESetFromOptions(fe));
445f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscObjectSetName((PetscObject)fe, "fe"));
455f80ce2aSJacob Faibussowitsch   CHKERRQ(DMSetField(dm, field, NULL, (PetscObject)fe));
465f80ce2aSJacob Faibussowitsch   CHKERRQ(DMCreateDS(dm));
475f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscFEDestroy(&fe));
484cd81d59SMatthew G. Knepley   /* Create particle swarm */
495f80ce2aSJacob Faibussowitsch   CHKERRQ(DMCreate(PETSC_COMM_SELF, &sw));
505f80ce2aSJacob Faibussowitsch   CHKERRQ(DMSetType(sw, DMSWARM));
515f80ce2aSJacob Faibussowitsch   CHKERRQ(DMSetDimension(sw, dim));
525f80ce2aSJacob Faibussowitsch   CHKERRQ(DMSwarmSetType(sw, DMSWARM_PIC));
535f80ce2aSJacob Faibussowitsch   CHKERRQ(DMSwarmSetCellDM(sw, dm));
545f80ce2aSJacob Faibussowitsch   CHKERRQ(DMSwarmRegisterPetscDatatypeField(sw, "w_q", Nc, PETSC_SCALAR));
555f80ce2aSJacob Faibussowitsch   CHKERRQ(DMSwarmFinalizeFieldRegister(sw));
565f80ce2aSJacob Faibussowitsch   CHKERRQ(DMSwarmSetLocalSizes(sw, Np, zero));
575f80ce2aSJacob Faibussowitsch   CHKERRQ(DMSetFromOptions(sw));
585f80ce2aSJacob Faibussowitsch   CHKERRQ(DMSwarmGetField(sw, "w_q", &bs, &dtype, (void**)&wq));
595f80ce2aSJacob Faibussowitsch   CHKERRQ(DMSwarmGetField(sw, "DMSwarmPIC_coor", &bs, &dtype, (void**)&coords));
603c611800SMark Adams   for (p=0,energy_0=0;p<Np;p++) {
614cd81d59SMatthew G. Knepley     coords[p*2+0]  = -PetscCosReal((PetscReal)(p+1)/(PetscReal)(Np+1) * PETSC_PI);
624cd81d59SMatthew G. Knepley     coords[p*2+1] =   PetscSinReal((PetscReal)(p+1)/(PetscReal)(Np+1) * PETSC_PI);
634cd81d59SMatthew G. Knepley     wq[p]          = 1.0;
643c611800SMark Adams     energy_0 += wq[p]*(PetscSqr(coords[p*2+0])+PetscSqr(coords[p*2+1]));
654cd81d59SMatthew G. Knepley   }
665f80ce2aSJacob Faibussowitsch   CHKERRQ(DMSwarmRestoreField(sw, "DMSwarmPIC_coor", &bs, &dtype, (void**)&coords));
675f80ce2aSJacob Faibussowitsch   CHKERRQ(DMSwarmRestoreField(sw, "w_q", &bs, &dtype, (void**)&wq));
685f80ce2aSJacob Faibussowitsch   CHKERRQ(DMSwarmMigrate(sw, removePoints));
695f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscObjectSetName((PetscObject)sw, "Particle Grid"));
705f80ce2aSJacob Faibussowitsch   CHKERRQ(DMViewFromOptions(sw, NULL, "-swarm_view"));
713c611800SMark Adams 
724cd81d59SMatthew G. Knepley   /* Project particles to field */
734cd81d59SMatthew G. Knepley   /* This gives M f = \int_\Omega \phi f, which looks like a rhs for a PDE */
745f80ce2aSJacob Faibussowitsch   CHKERRQ(DMCreateMassMatrix(sw, dm, &M_p));
755f80ce2aSJacob Faibussowitsch   CHKERRQ(DMCreateGlobalVector(dm, &rho));
765f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscObjectSetName((PetscObject)rho, "rho"));
773c611800SMark Adams 
785f80ce2aSJacob Faibussowitsch   CHKERRQ(DMSwarmCreateGlobalVectorFromField(sw, "w_q", &f));
795f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscObjectSetName((PetscObject)f, "weights"));
805f80ce2aSJacob Faibussowitsch   CHKERRQ(MatMultTranspose(M_p, f, rho));
814cd81d59SMatthew G. Knepley 
824cd81d59SMatthew G. Knepley   /* Visualize mesh field */
835f80ce2aSJacob Faibussowitsch   CHKERRQ(DMSetOutputSequenceNumber(dm, timestep, time));
845f80ce2aSJacob Faibussowitsch   CHKERRQ(VecViewFromOptions(rho, NULL, "-rho_view"));
854cd81d59SMatthew G. Knepley 
864cd81d59SMatthew G. Knepley   /* Project field to particles */
874cd81d59SMatthew G. Knepley   /*   This gives f_p = M_p^+ M f */
885f80ce2aSJacob Faibussowitsch   CHKERRQ(DMCreateGlobalVector(dm, &rhs));
895f80ce2aSJacob Faibussowitsch   CHKERRQ(VecCopy(rho, rhs)); /* Identity: M^1 M rho */
903c611800SMark Adams 
915f80ce2aSJacob Faibussowitsch   CHKERRQ(KSPCreate(PETSC_COMM_WORLD, &ksp));
925f80ce2aSJacob Faibussowitsch   CHKERRQ(KSPSetOptionsPrefix(ksp, "ftop_"));
935f80ce2aSJacob Faibussowitsch   CHKERRQ(KSPSetFromOptions(ksp));
945f80ce2aSJacob Faibussowitsch   CHKERRQ(KSPGetPC(ksp,&pc));
95*b122ec5aSJacob Faibussowitsch   CHKERRQ(PetscObjectTypeCompare((PetscObject)pc,PCBJACOBI,&is_bjac));
963c611800SMark Adams   if (is_bjac) {
975f80ce2aSJacob Faibussowitsch     CHKERRQ(DMSwarmCreateMassMatrixSquare(sw, dm, &PM_p));
985f80ce2aSJacob Faibussowitsch     CHKERRQ(KSPSetOperators(ksp, M_p, PM_p));
993c611800SMark Adams   } else {
1005f80ce2aSJacob Faibussowitsch     CHKERRQ(KSPSetOperators(ksp, M_p, M_p));
1013c611800SMark Adams   }
1025f80ce2aSJacob Faibussowitsch   CHKERRQ(KSPSolveTranspose(ksp, rhs, f));
1035f80ce2aSJacob Faibussowitsch   CHKERRQ(KSPDestroy(&ksp));
1045f80ce2aSJacob Faibussowitsch   CHKERRQ(VecDestroy(&rhs));
1054cd81d59SMatthew G. Knepley 
1064cd81d59SMatthew G. Knepley   /* Visualize particle field */
1075f80ce2aSJacob Faibussowitsch   CHKERRQ(DMSetOutputSequenceNumber(sw, timestep, time));
1085f80ce2aSJacob Faibussowitsch   CHKERRQ(VecViewFromOptions(f, NULL, "-weights_view"));
1095f80ce2aSJacob Faibussowitsch   CHKERRQ(VecNorm(f,NORM_1,&norm));
1105f80ce2aSJacob Faibussowitsch   CHKERRQ(DMSwarmDestroyGlobalVectorFromField(sw, "w_q", &f));
1113c611800SMark Adams 
1123c611800SMark Adams   /* compute energy */
1135f80ce2aSJacob Faibussowitsch   CHKERRQ(DMSwarmGetField(sw, "w_q", &bs, &dtype, (void**)&wq));
1145f80ce2aSJacob Faibussowitsch   CHKERRQ(DMSwarmGetField(sw, "DMSwarmPIC_coor", &bs, &dtype, (void**)&coords));
1153c611800SMark Adams   for (p=0,energy_1=0;p<Np;p++) {
1163c611800SMark Adams     energy_1 += wq[p]*(PetscSqr(coords[p*2+0])+PetscSqr(coords[p*2+1]));
1173c611800SMark Adams   }
1185f80ce2aSJacob Faibussowitsch   CHKERRQ(DMSwarmRestoreField(sw, "DMSwarmPIC_coor", &bs, &dtype, (void**)&coords));
1195f80ce2aSJacob Faibussowitsch   CHKERRQ(DMSwarmRestoreField(sw, "w_q", &bs, &dtype, (void**)&wq));
1205f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscPrintf(PETSC_COMM_SELF,"Total number = %20.12e. energy = %20.12e error = %20.12e\n", norm, energy_0, (energy_1-energy_0)/energy_0));
1213c611800SMark Adams   /* Cleanup */
1225f80ce2aSJacob Faibussowitsch   CHKERRQ(MatDestroy(&M_p));
1235f80ce2aSJacob Faibussowitsch   CHKERRQ(MatDestroy(&PM_p));
1245f80ce2aSJacob Faibussowitsch   CHKERRQ(VecDestroy(&rho));
1255f80ce2aSJacob Faibussowitsch   CHKERRQ(DMDestroy(&sw));
1265f80ce2aSJacob Faibussowitsch   CHKERRQ(DMDestroy(&dm));
127*b122ec5aSJacob Faibussowitsch   CHKERRQ(PetscFinalize());
128*b122ec5aSJacob Faibussowitsch   return 0;
1294cd81d59SMatthew G. Knepley }
1304cd81d59SMatthew G. Knepley 
1314cd81d59SMatthew G. Knepley /*TEST
1324cd81d59SMatthew G. Knepley 
1334cd81d59SMatthew G. Knepley   build:
1344cd81d59SMatthew G. Knepley     requires: !complex
1354cd81d59SMatthew G. Knepley 
1364cd81d59SMatthew G. Knepley   test:
1374cd81d59SMatthew G. Knepley     suffix: 0
1383c611800SMark Adams     requires: double triangle
1393c611800SMark Adams     args: -dm_plex_simplex 0 -dm_plex_box_faces 4,2 -np 50 -dm_plex_box_lower -2.0,0.0 -dm_plex_box_upper 2.0,2.0 -petscspace_degree 2 -ftop_ksp_type lsqr -ftop_pc_type none -dm_view -swarm_view -ftop_ksp_rtol 1.e-14
1403c611800SMark Adams     filter: grep -v DM_ | grep -v atomic
1413c611800SMark Adams 
1423c611800SMark Adams   test:
1433c611800SMark Adams     suffix: bjacobi
1443c611800SMark Adams     requires: double triangle
1453c611800SMark Adams     args: -dm_plex_simplex 0 -dm_plex_box_faces 4,2 -np 50 -dm_plex_box_lower -2.0,0.0 -dm_plex_box_upper 2.0,2.0 -petscspace_degree 2 -dm_plex_hash_location -ftop_ksp_type lsqr -ftop_pc_type bjacobi -ftop_sub_pc_type lu -ftop_sub_pc_factor_shift_type nonzero -dm_view -swarm_view -ftop_ksp_rtol 1.e-14
1464cd81d59SMatthew G. Knepley     filter: grep -v DM_ | grep -v atomic
1474cd81d59SMatthew G. Knepley 
1484cd81d59SMatthew G. Knepley TEST*/
149