DISPATCH
global_mod.f90
1 !===============================================================================
2 !> Data type for computing global average, while using only nearest node nbor
3 !> communication
4 !===============================================================================
5 MODULE global_mod
6  USE io_mod
7  USE trace_mod
8  USE lagrange_mod
9  USE mpi_mod
10  implicit none
11  private
12  type, public:: global_t
13  integer:: nmpi, nt
14  integer:: order=2
15  integer:: istep=0
16  real(8):: cadence
17  real(8), dimension(:,:), allocatable:: v, w, t
18  character(len=80):: label
19  contains
20  procedure:: init
21  procedure:: update
22  procedure:: merge
23  procedure:: average
24  end type
25 CONTAINS
26 
27 !===============================================================================
28 !> Initialize -- one instance is needed for each global average
29 !===============================================================================
30 SUBROUTINE init (self, label, nMPI, nt, cadence)
31  class(global_t):: self
32  character(len=*):: label
33  integer:: nMPI, nt
34  real:: cadence
35  !.............................................................................
36  call trace%begin ('global_t%init')
37  self%label = label
38  self%cadence = cadence
39  self%nMPI = nmpi
40  self%nt = nt
41  allocate (self%v(nt,nmpi))
42  allocate (self%w(nt,nmpi))
43  allocate (self%t(nt,nmpi))
44  self%v = 0d0
45  self%w = 0d0
46  self%t = 0d0
47  call trace%end()
48 END SUBROUTINE init
49 
50 !===============================================================================
51 !> Keep updating the first time slot until it ís more than "cadence" ahead,
52 !> then rotate.
53 !===============================================================================
54 SUBROUTINE update (self, v, w, t)
55  class(global_t):: self
56  real(8):: v, w, t, t1
57  !.............................................................................
58  call trace%begin ('global_t%update')
59  if (t > self%t(self%nt-1,mpi%rank)+self%cadence) then
60  self%v(1:self%nt-1,mpi%rank) = self%v(2:self%nt,mpi%rank)
61  self%w(1:self%nt-1,mpi%rank) = self%w(2:self%nt,mpi%rank)
62  self%t(1:self%nt-1,mpi%rank) = self%t(2:self%nt,mpi%rank)
63  self%v(self%nt,mpi%rank) = v
64  self%w(self%nt,mpi%rank) = w
65  self%t(self%nt,mpi%rank) = t
66  t1 = (t+self%t(self%nt-1,mpi%rank))/2d0
67  self%istep = self%istep + 1
68  if (io%master) then
69  print '(a,9f12.6)', 'new times:', self%t(:,mpi%rank), t1
70  print '(a,9f12.6)', ' averages:', self%v(:,mpi%rank), self%average (t1)
71  end if
72  else
73  self%v(self%nt,mpi%rank) = v
74  self%w(self%nt,mpi%rank) = w
75  self%t(self%nt,mpi%rank) = t
76  end if
77  call trace%end()
78 END SUBROUTINE update
79 
80 !===============================================================================
81 !> Merge information with that from a node neighbor
82 !===============================================================================
83 SUBROUTINE merge (self, nbor)
84  class(global_t):: self, nbor
85  !.............................................................................
86  integer:: i, j
87  !-----------------------------------------------------------------------------
88  call trace%begin ('global_t%merge')
89  do j=1,self%nMPI
90  do i=1,self%nt
91  if (nbor%t(i,j) > self%t(i,j)) then
92  self%v(i,j) = nbor%v(i,j)
93  self%w(i,j) = nbor%w(i,j)
94  self%t(i,j) = nbor%t(i,j)
95  end if
96  end do
97  end do
98  call trace%end()
99 END SUBROUTINE merge
100 
101 !===============================================================================
102 !> Return a global average
103 !===============================================================================
104 FUNCTION average (self, t)
105  class(global_t):: self
106  real(8):: t, average
107  !.............................................................................
108  real(8):: v, w, weight
109  integer:: i, j
110  !-----------------------------------------------------------------------------
111  call trace%begin ('global_t%average')
112  weight = 0d0
113  average = 0d0
114  do j=1,self%nMPI
115  v = lagrange%sequence(t, self%t(:,i), self%v(:,i), min(self%order,self%istep))
116  w = lagrange%sequence(t, self%t(:,i), self%w(:,i), min(self%order,self%istep))
117  weight = weight + w
118  average = average + v*w
119  end do
120  average = average
121  call trace%end()
122 END FUNCTION average
123 
124 END MODULE global_mod
Data type for computing global average, while using only nearest node nbor communication.
Definition: global_mod.f90:5
Module for Lagrange interpolation.
Definition: lagrange_mod.f90:4
Definition: io_mod.f90:4