DISPATCH
forces_mod.f90
1 !===============================================================================
2 !> This is a bare minimum interface to the new extras module, showing how to
3 !> interface with a pre-existing force_mod%selected() function.
4 !>
5 !> In this version, the force_per_unit_mass array is allocated in %init, and its
6 !> values are set by a call to the previous standard force_t interface, in order
7 !> for the new arrangement to be as non-intrusive as possible, relative to pre-
8 !> existing experiments.
9 !>
10 !> In the future, external forces should NOT use this interface. Instead, each
11 !> type of force should use its own data type (primarily to hold parameters
12 !> specific to that force), while the resulting force should be addded to
13 !> (not overwrite) the generic patch_t%force_per_unit_mass or _volume arrays.
14 !>
15 !> To comply with that policy, this interface also adds the force, and thus
16 !> assumes that the generic array is set to zero elsewhere, before each timestep.
17 !> The proper place to do that is in the extras_t data type, which is where the
18 !> user chooses which forces to include and combine.
19 !===============================================================================
20 MODULE forces_mod
21  USE io_mod
22  USE trace_mod
23  USE patch_mod
24  USE force_mod
25  USE link_mod
26  implicit none
27  private
28  type, public:: forces_t
29  type(force_t):: force
30  class(patch_t), pointer:: patch
31  real, dimension(:,:,:), pointer:: ux=>null(), uy=>null(), uz=>null()
32  contains
33  procedure:: init
34  procedure:: dealloc
35  procedure:: pre_update
36  procedure:: post_update
37  end type
38 CONTAINS
39 
40 !===============================================================================
41 !> Initialize forces_t interface to force_t
42 !===============================================================================
43 SUBROUTINE init (self, link)
44  class(forces_t):: self
45  class(link_t):: link
46  !.............................................................................
47  call trace%begin ('forces_t%init')
48  self%patch => task2patch(link%task)
49  call self%force%init (self%patch%kind, self%patch%id, self%patch%mesh)
50  call trace%end
51 END SUBROUTINE init
52 
53 !===============================================================================
54 !> Deallocate
55 !===============================================================================
56 SUBROUTINE dealloc (self)
57  class(forces_t):: self
58  !.............................................................................
59  call trace%begin ('forces_t%dealloc')
60  call self%force%dealloc
61  call trace%end
62 END SUBROUTINE dealloc
63 
64 !===============================================================================
65 !> Use the pre-existing force%selected () function to set or add the force
66 !===============================================================================
67 SUBROUTINE pre_update (self)
68  class(forces_t):: self
69  !.............................................................................
70  real, dimension(:,:,:), pointer:: d
71  real, dimension(:,:,:,:), pointer:: p
72  !-----------------------------------------------------------------------------
73  ! Use existing function call
74  !-----------------------------------------------------------------------------
75  associate(patch => self%patch, m => self%patch%gn)
76  d => patch%mem(:,:,:,patch%idx%d,patch%it,1)
77  p => patch%mem(:,:,:,patch%idx%px:patch%idx%pz,patch%it,1)
78  if (.not.allocated(patch%force_per_unit_mass)) then
79  allocate (patch%force_per_unit_mass(m(1),m(2),m(3),3))
80  call io%bits_mem (storage_size(patch%force_per_unit_mass), &
81  product(shape(patch%force_per_unit_mass)), 'fpm')
82  end if
83  patch%force_per_unit_mass = &
84  self%force%selected(patch%time, d, p, self%Ux, self%Uy, self%Uz, patch%mesh)
85  end associate
86 END SUBROUTINE pre_update
87 
88 !===============================================================================
89 !> Save on node memory, by deallocating
90 !===============================================================================
91 SUBROUTINE post_update (self)
92  class(forces_t):: self
93  !-----------------------------------------------------------------------------
94  if (allocated(self%patch%force_per_unit_mass)) then
95  call io%bits_mem (-storage_size(self%patch%force_per_unit_mass), &
96  product(shape(self%patch%force_per_unit_mass)), '-fpm')
97  deallocate (self%patch%force_per_unit_mass)
98  end if
99 END SUBROUTINE post_update
100 
101 END MODULE forces_mod
This is a bare minimum interface to the new extras module, showing how to interface with a pre-existi...
Definition: forces_mod.f90:20
Template module for patches, which adds pointers to memory and mesh, and number of dimensions and var...
Definition: patch_mod.f90:6
Definition: io_mod.f90:4
Simple forcing module for tests.
Definition: force_mod.f90:4