xref: /petsc/src/dm/impls/swarm/tutorials/ex1f90.F90 (revision d52c2f216e65d48d17427a896822b982b0e2da6e)
14cd81d59SMatthew G. Knepley! Example program demonstrating projection between particle and finite element spaces
24cd81d59SMatthew G. Knepley      program DMSwarmTestProjection
34cd81d59SMatthew G. Knepley#include "petsc/finclude/petscdmplex.h"
44cd81d59SMatthew G. Knepley#include "petsc/finclude/petscdmswarm.h"
54cd81d59SMatthew G. Knepley#include "petsc/finclude/petscksp.h"
64cd81d59SMatthew G. Knepley      use petscdmplex
74cd81d59SMatthew G. Knepley      use petscdmswarm
84cd81d59SMatthew G. Knepley      use petscdt
94cd81d59SMatthew G. Knepley      use petscksp
104cd81d59SMatthew G. Knepley      use petscsys
114cd81d59SMatthew G. Knepley      implicit none
124cd81d59SMatthew G. Knepley
134cd81d59SMatthew G. Knepley      DM ::          dm, sw
144cd81d59SMatthew G. Knepley      PetscFE ::     fe
154cd81d59SMatthew G. Knepley      KSP ::         ksp
164cd81d59SMatthew G. Knepley      Mat ::         M_p, M
174cd81d59SMatthew G. Knepley      Vec ::         f, rho, rhs
1830602db0SMatthew G. Knepley      PetscInt ::    dim, Nc = 1, degree = 1, timestep = 0
194cd81d59SMatthew G. Knepley      PetscInt ::    Np = 100, p, field = 0, zero = 0, bs
204cd81d59SMatthew G. Knepley      PetscReal ::   time = 0.0,  norm
214cd81d59SMatthew G. Knepley      PetscBool ::   removePoints = PETSC_TRUE
224cd81d59SMatthew G. Knepley      PetscDataType :: dtype
234cd81d59SMatthew G. Knepley      PetscScalar, pointer :: coords(:)
244cd81d59SMatthew G. Knepley      PetscScalar, pointer :: wq(:)
254cd81d59SMatthew G. Knepley      PetscErrorCode :: ierr
264cd81d59SMatthew G. Knepley
27d8606c27SBarry Smith      PetscCallA(PetscInitialize(PETSC_NULL_CHARACTER, ierr))
28d8606c27SBarry Smith      PetscCallA(DMCreate(PETSC_COMM_WORLD, dm, ierr))
29d8606c27SBarry Smith      PetscCallA(DMSetType(dm, DMPLEX, ierr))
30d8606c27SBarry Smith      PetscCallA(DMSetFromOptions(dm, ierr))
31d8606c27SBarry Smith      PetscCallA(DMGetDimension(dm, dim, ierr))
32d8606c27SBarry Smith      PetscCallA(DMViewFromOptions(dm, PETSC_NULL_VEC, '-dm_view', ierr))
334cd81d59SMatthew G. Knepley
344cd81d59SMatthew G. Knepley!     Create finite element space
35d8606c27SBarry Smith      PetscCallA(PetscFECreateLagrange(PETSC_COMM_SELF, dim, Nc, PETSC_FALSE, degree, PETSC_DETERMINE, fe, ierr))
36d8606c27SBarry Smith      PetscCallA(DMSetField(dm, field, PETSC_NULL_DMLABEL, fe, ierr))
37d8606c27SBarry Smith      PetscCallA(DMCreateDS(dm, ierr))
38d8606c27SBarry Smith      PetscCallA(PetscFEDestroy(fe, ierr))
394cd81d59SMatthew G. Knepley
404cd81d59SMatthew G. Knepley!     Create particle swarm
41d8606c27SBarry Smith      PetscCallA(DMCreate(PETSC_COMM_WORLD, sw, ierr))
42d8606c27SBarry Smith      PetscCallA(DMSetType(sw, DMSWARM, ierr))
43d8606c27SBarry Smith      PetscCallA(DMSetDimension(sw, dim, ierr))
44d8606c27SBarry Smith      PetscCallA(DMSwarmSetType(sw, DMSWARM_PIC, ierr))
45d8606c27SBarry Smith      PetscCallA(DMSwarmSetCellDM(sw, dm, ierr))
46d8606c27SBarry Smith      PetscCallA(DMSwarmRegisterPetscDatatypeField(sw, 'w_q', Nc, PETSC_SCALAR, ierr))
47d8606c27SBarry Smith      PetscCallA(DMSwarmFinalizeFieldRegister(sw, ierr))
48d8606c27SBarry Smith      PetscCallA(DMSwarmSetLocalSizes(sw, Np, zero, ierr))
49d8606c27SBarry Smith      PetscCallA(DMSetFromOptions(sw, ierr))
50d8606c27SBarry Smith      PetscCallA(DMSwarmGetField(sw, 'w_q', bs, dtype, wq, ierr))
51d8606c27SBarry Smith      PetscCallA(DMSwarmGetField(sw, 'DMSwarmPIC_coor', bs, dtype, coords, ierr))
524cd81d59SMatthew G. Knepley      do p = 1, Np
534cd81d59SMatthew G. Knepley        coords(p*2-1) = -cos(dble(p)/dble(Np+1) * PETSC_PI)
544cd81d59SMatthew G. Knepley        coords(p*2-0) =  sin(dble(p)/dble(Np+1) * PETSC_PI)
554cd81d59SMatthew G. Knepley        wq(p)         = 1.0
564cd81d59SMatthew G. Knepley      end do
57d8606c27SBarry Smith      PetscCallA(DMSwarmRestoreField(sw, 'DMSwarmPIC_coor', bs, dtype, coords, ierr))
58d8606c27SBarry Smith      PetscCallA(DMSwarmRestoreField(sw, 'w_q', bs, dtype, wq, ierr))
59d8606c27SBarry Smith      PetscCallA(DMSwarmMigrate(sw, removePoints, ierr))
60*d52c2f21SMatthew G. Knepley      PetscCallA(DMSwarmVectorDefineField(sw, 'w_q', ierr))
61d8606c27SBarry Smith      PetscCallA(DMViewFromOptions(sw, PETSC_NULL_VEC, '-swarm_view', ierr))
624cd81d59SMatthew G. Knepley
634cd81d59SMatthew G. Knepley!     Project particles to field
644cd81d59SMatthew G. Knepley!       This gives M f = \int_\Omega \phi f, which looks like a rhs for a PDE
65d8606c27SBarry Smith      PetscCallA(DMCreateMassMatrix(sw, dm, M_p, ierr))
66d8606c27SBarry Smith      PetscCallA(DMCreateGlobalVector(dm, rho, ierr))
67d8606c27SBarry Smith      PetscCallA(DMSwarmCreateGlobalVectorFromField(sw, 'w_q', f, ierr))
68d8606c27SBarry Smith      PetscCallA(MatMultTranspose(M_p, f, rho, ierr))
694cd81d59SMatthew G. Knepley
704cd81d59SMatthew G. Knepley!     Visualize mesh field
71d8606c27SBarry Smith      PetscCallA(DMSetOutputSequenceNumber(dm, timestep, time, ierr))
72d8606c27SBarry Smith      PetscCallA(PetscObjectViewFromOptions(rho, PETSC_NULL_VEC, '-rho_view', ierr))
734cd81d59SMatthew G. Knepley
744cd81d59SMatthew G. Knepley!     Project field to particles
754cd81d59SMatthew G. Knepley!       This gives f_p = M_p^+ M f
76d8606c27SBarry Smith      PetscCallA(DMCreateMassMatrix(dm, dm, M, ierr))
77d8606c27SBarry Smith      PetscCallA(DMCreateGlobalVector(dm, rhs, ierr))
784cd81d59SMatthew G. Knepley      if (.false.) then
79d8606c27SBarry Smith         PetscCallA(MatMult(M, rho, rhs, ierr)) ! this is what you would do for and FE solve
804cd81d59SMatthew G. Knepley      else
81d8606c27SBarry Smith         PetscCallA(VecCopy(rho, rhs, ierr)) ! Identity: M^1 M rho
824cd81d59SMatthew G. Knepley      end if
83d8606c27SBarry Smith      PetscCallA(KSPCreate(PETSC_COMM_WORLD, ksp, ierr))
84d8606c27SBarry Smith      PetscCallA(KSPSetOptionsPrefix(ksp, 'ftop_', ierr))
85d8606c27SBarry Smith      PetscCallA(KSPSetFromOptions(ksp, ierr))
86d8606c27SBarry Smith      PetscCallA(KSPSetOperators(ksp, M_p, M_p, ierr))
87d8606c27SBarry Smith      PetscCallA(KSPSolveTranspose(ksp, rhs, f, ierr))
88d8606c27SBarry Smith      PetscCallA(KSPDestroy(ksp, ierr))
89d8606c27SBarry Smith      PetscCallA(VecDestroy(rhs, ierr))
90d8606c27SBarry Smith      PetscCallA(MatDestroy(M_p, ierr))
91d8606c27SBarry Smith      PetscCallA(MatDestroy(M, ierr))
924cd81d59SMatthew G. Knepley
934cd81d59SMatthew G. Knepley!     Visualize particle field
94d8606c27SBarry Smith      PetscCallA(DMSetOutputSequenceNumber(sw, timestep, time, ierr))
95d8606c27SBarry Smith      PetscCallA(PetscObjectViewFromOptions(f, PETSC_NULL_VEC, '-weights_view', ierr))
96d8606c27SBarry Smith      PetscCallA(VecNorm(f,NORM_1,norm,ierr))
974cd81d59SMatthew G. Knepley      print *, 'Total number density = ', norm
984cd81d59SMatthew G. Knepley!     Cleanup
99d8606c27SBarry Smith      PetscCallA(DMSwarmDestroyGlobalVectorFromField(sw, 'w_q', f, ierr))
100d8606c27SBarry Smith      PetscCallA(VecDestroy(rho, ierr))
101d8606c27SBarry Smith      PetscCallA(DMDestroy(sw, ierr))
102d8606c27SBarry Smith      PetscCallA(DMDestroy(dm, ierr))
1034cd81d59SMatthew G. Knepley
104d8606c27SBarry Smith      PetscCallA(PetscFinalize(ierr))
1054cd81d59SMatthew G. Knepley      end program DMSwarmTestProjection
1064cd81d59SMatthew G. Knepley
1074cd81d59SMatthew G. Knepley!/*TEST
1084cd81d59SMatthew G. Knepley!  build:
109dfd57a17SPierre Jolivet!    requires: defined(PETSC_USING_F90FREEFORM) double !complex
1104cd81d59SMatthew G. Knepley!
1114cd81d59SMatthew G. Knepley!  test:
1124cd81d59SMatthew G. Knepley!    suffix: 0
1134cd81d59SMatthew G. Knepley!    requires: double
11430602db0SMatthew G. Knepley!    args: -dm_plex_simplex 0 -dm_plex_box_faces 40,20 -dm_plex_box_lower -2.0,0.0 -dm_plex_box_upper 2.0,2.0 -ftop_ksp_type lsqr -ftop_pc_type none -dm_view -swarm_view
1154cd81d59SMatthew G. Knepley!    filter: grep -v DM_ | grep -v atomic
1164cd81d59SMatthew G. Knepley!    filter_output: grep -v atomic
1174cd81d59SMatthew G. Knepley!
1184cd81d59SMatthew G. Knepley!TEST*/
119