xref: /petsc/src/ts/utils/dmplexlandau/tutorials/ex1.c (revision e0bd6ad43e162eb8eb9a20e20f63cb6ac4a25bf8)
1e0eea495SMark static char help[] = "Landau collision operator driver\n\n";
2e0eea495SMark 
3e0eea495SMark #include <petscts.h>
4e0eea495SMark #include <petsclandau.h>
5e0eea495SMark 
624ded41bSmarkadams4 typedef struct {
724ded41bSmarkadams4   PetscInt  grid_target, batch_target, field_target;
824ded41bSmarkadams4   PetscBool init;
924ded41bSmarkadams4 } ex1Ctx;
1024ded41bSmarkadams4 
1124ded41bSmarkadams4 /*
12f53e7263SMark Adams  call back method for DMPlexLandauAccess:
1324ded41bSmarkadams4 
1424ded41bSmarkadams4 Input Parameters:
1524ded41bSmarkadams4  .   dm - a DM for this field
1624ded41bSmarkadams4  -   local_field - the local index in the grid for this field
1724ded41bSmarkadams4  .   grid - the grid index
1824ded41bSmarkadams4  +   b_id - the batch index
1924ded41bSmarkadams4  -   vctx - a user context
2024ded41bSmarkadams4 
2124ded41bSmarkadams4  Input/Output Parameters:
2224ded41bSmarkadams4  +   x - Vector to data to
2324ded41bSmarkadams4 
2424ded41bSmarkadams4  */
25f53e7263SMark Adams PetscErrorCode landau_field_print_access_callback(DM dm, Vec x, PetscInt local_field, PetscInt grid, PetscInt b_id, void *vctx)
26d71ae5a4SJacob Faibussowitsch {
2724ded41bSmarkadams4   ex1Ctx    *user = (ex1Ctx *)vctx;
28f53e7263SMark Adams   LandauCtx *ctx;
2924ded41bSmarkadams4 
3024ded41bSmarkadams4   PetscFunctionBegin;
31f53e7263SMark Adams   PetscCall(DMGetApplicationContext(dm, &ctx));
3224ded41bSmarkadams4   if (grid == user->grid_target && b_id == user->batch_target && local_field == user->field_target) {
33f53e7263SMark Adams     PetscScalar one = 1.0e10;
34f53e7263SMark Adams 
3524ded41bSmarkadams4     PetscCall(VecSet(x, one));
3624ded41bSmarkadams4     if (!user->init) {
3724ded41bSmarkadams4       PetscCall(PetscObjectSetName((PetscObject)dm, "single"));
38f53e7263SMark Adams       PetscCall(DMViewFromOptions(dm, NULL, "-ex1_dm_view")); // DMCreateSubDM does seem to give the DM's fild the name from the original DM
3924ded41bSmarkadams4       user->init = PETSC_TRUE;
4024ded41bSmarkadams4     }
41f53e7263SMark Adams     PetscCall(PetscObjectSetName((PetscObject)x, "u"));      // this gives the vector a nicer name, DMCreateSubDM could do this for us and get the correct name
4224ded41bSmarkadams4     PetscCall(VecViewFromOptions(x, NULL, "-ex1_vec_view")); // this causes diffs with Kokkos, etc
43f53e7263SMark Adams     PetscCall(PetscInfo(dm, "DMPlexLandauAccess user 'add' method to grid %" PetscInt_FMT ", batch %" PetscInt_FMT " and species %" PetscInt_FMT "\n", grid, b_id, ctx->species_offset[grid] + local_field));
4424ded41bSmarkadams4   }
4524ded41bSmarkadams4   PetscFunctionReturn(0);
4624ded41bSmarkadams4 }
4724ded41bSmarkadams4 
48d71ae5a4SJacob Faibussowitsch int main(int argc, char **argv)
49d71ae5a4SJacob Faibussowitsch {
5024ded41bSmarkadams4   DM             pack;
51e0eea495SMark   Vec            X, X_0;
52e0eea495SMark   PetscInt       dim = 2;
53e0eea495SMark   TS             ts;
54e0eea495SMark   Mat            J;
55e0eea495SMark   SNES           snes;
56e0eea495SMark   KSP            ksp;
57e0eea495SMark   PC             pc;
58e0eea495SMark   SNESLineSearch linesearch;
59e0eea495SMark   PetscReal      time;
60e0eea495SMark 
61327415f7SBarry Smith   PetscFunctionBeginUser;
629566063dSJacob Faibussowitsch   PetscCall(PetscInitialize(&argc, &argv, NULL, help));
639566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetInt(NULL, NULL, "-dim", &dim, NULL));
64e0eea495SMark   /* Create a mesh */
6524ded41bSmarkadams4   PetscCall(DMPlexLandauCreateVelocitySpace(PETSC_COMM_SELF, dim, "", &X, &J, &pack));
6624ded41bSmarkadams4   PetscCall(DMSetUp(pack));
679566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(X, &X_0));
689566063dSJacob Faibussowitsch   PetscCall(VecCopy(X, X_0));
699566063dSJacob Faibussowitsch   PetscCall(DMPlexLandauPrintNorms(X, 0));
7024ded41bSmarkadams4   PetscCall(DMSetOutputSequenceNumber(pack, 0, 0.0));
71e0eea495SMark   /* Create timestepping solver context */
729566063dSJacob Faibussowitsch   PetscCall(TSCreate(PETSC_COMM_SELF, &ts));
7324ded41bSmarkadams4   PetscCall(TSSetDM(ts, pack));
749566063dSJacob Faibussowitsch   PetscCall(TSGetSNES(ts, &snes));
759566063dSJacob Faibussowitsch   PetscCall(SNESGetLineSearch(snes, &linesearch));
769566063dSJacob Faibussowitsch   PetscCall(SNESLineSearchSetType(linesearch, SNESLINESEARCHBASIC));
779566063dSJacob Faibussowitsch   PetscCall(TSSetIFunction(ts, NULL, DMPlexLandauIFunction, NULL));
789566063dSJacob Faibussowitsch   PetscCall(TSSetIJacobian(ts, J, J, DMPlexLandauIJacobian, NULL));
799566063dSJacob Faibussowitsch   PetscCall(TSSetExactFinalTime(ts, TS_EXACTFINALTIME_STEPOVER));
809566063dSJacob Faibussowitsch   PetscCall(SNESGetKSP(snes, &ksp));
819566063dSJacob Faibussowitsch   PetscCall(KSPGetPC(ksp, &pc));
829566063dSJacob Faibussowitsch   PetscCall(TSSetFromOptions(ts));
839566063dSJacob Faibussowitsch   PetscCall(TSSetSolution(ts, X));
849566063dSJacob Faibussowitsch   PetscCall(TSSolve(ts, X));
859566063dSJacob Faibussowitsch   PetscCall(DMPlexLandauPrintNorms(X, 1));
869566063dSJacob Faibussowitsch   PetscCall(TSGetTime(ts, &time));
8724ded41bSmarkadams4   PetscCall(DMSetOutputSequenceNumber(pack, 1, time));
889566063dSJacob Faibussowitsch   PetscCall(VecAXPY(X, -1, X_0));
8924ded41bSmarkadams4   { /* test add field method */
9024ded41bSmarkadams4     ex1Ctx    *user;
91f53e7263SMark Adams     LandauCtx *ctx;
92f53e7263SMark Adams     PetscCall(DMGetApplicationContext(pack, &ctx));
9324ded41bSmarkadams4     PetscCall(PetscNew(&user));
9424ded41bSmarkadams4     user->grid_target  = 1; // 2nd ion species
9524ded41bSmarkadams4     user->field_target = 1;
96f53e7263SMark Adams     PetscCall(DMPlexLandauAccess(pack, X, landau_field_print_access_callback, user));
9724ded41bSmarkadams4     PetscCall(PetscFree(user));
9824ded41bSmarkadams4   }
99e0eea495SMark   /* clean up */
10024ded41bSmarkadams4   PetscCall(DMPlexLandauDestroyVelocitySpace(&pack));
1019566063dSJacob Faibussowitsch   PetscCall(TSDestroy(&ts));
1029566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&X));
1039566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&X_0));
1049566063dSJacob Faibussowitsch   PetscCall(PetscFinalize());
105b122ec5aSJacob Faibussowitsch   return 0;
106e0eea495SMark }
107e0eea495SMark 
108e0eea495SMark /*TEST
1095dac466eSMark Adams   testset:
110984ed092SMark Adams     requires: p4est !complex double defined(PETSC_USE_DMLANDAU_2D)
1115dac466eSMark Adams     output_file: output/ex1_0.out
112b6fb460bSmarkadams4     filter: grep -v "%  type: seq"
113531b49fdSmarkadams4     args: -dm_landau_num_species_grid 1,2 -petscspace_degree 3 -petscspace_poly_tensor 1 -dm_landau_type p4est -dm_landau_ion_masses 2,4 -dm_landau_ion_charges 1,18 -dm_landau_thermal_temps 5,5,.5 -dm_landau_n 1.00018,1,1e-5 -dm_landau_n_0 1e20 -ts_monitor -snes_rtol 1.e-14 -snes_stol 1.e-14 -snes_monitor -snes_converged_reason -ts_type arkimex -ts_arkimex_type 1bee -ts_max_snes_failures -1 -ts_rtol 1e-1 -ts_dt 1.e-1 -ts_max_time 1 -ts_adapt_clip .5,1.25 -ts_adapt_scale_solve_failed 0.75 -ts_adapt_time_step_increase_delay 5 -ts_max_steps 1 -pc_type lu -ksp_type preonly -dm_landau_amr_levels_max 2,1 -ex1_dm_view  -ex1_vec_view ::ascii_matlab -dm_landau_num_cells 2,2 -dm_landau_domain_max_par 6,6 -dm_landau_domain_max_perp 4,4
114e0eea495SMark     test:
1155dac466eSMark Adams       suffix: cpu
1165dac466eSMark Adams       args: -dm_landau_device_type cpu
1175dac466eSMark Adams     test:
1185dac466eSMark Adams       suffix: kokkos
119*e0bd6ad4SStefano Zampini       requires: kokkos_kernels !defined(PETSC_HAVE_CUDA_CLANG)
1205dac466eSMark Adams       args: -dm_landau_device_type kokkos -dm_mat_type aijkokkos -dm_vec_type kokkos
1215dac466eSMark Adams     test:
1225dac466eSMark Adams       suffix: cuda
123*e0bd6ad4SStefano Zampini       requires: cuda !defined(PETSC_HAVE_CUDA_CLANG)
1245dac466eSMark Adams       args: -dm_landau_device_type cuda -dm_mat_type aijcusparse -dm_vec_type cuda -mat_cusparse_use_cpu_solve
125e0eea495SMark 
126e0eea495SMark TEST*/
127