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