EMPIRE DA  v1.9.1
Data assimilation codes using EMPIRE communication
 All Classes Files Functions Variables Pages
Lorenz63_empire.f90
Go to the documentation of this file.
1 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
2 ! Lorenz63_empire.f90 Implements Lorenz 1963 model with EMPIRE coupling
3 !
4 !The MIT License (MIT)
5 !
6 !Copyright (c) 2014 Philip A. Browne
7 !
8 !Permission is hereby granted, free of charge, to any person obtaining a copy
9 !of this software and associated documentation files (the "Software"), to deal
10 !in the Software without restriction, including without limitation the rights
11 !to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 !copies of the Software, and to permit persons to whom the Software is
13 !furnished to do so, subject to the following conditions:
14 !
15 !The above copyright notice and this permission notice shall be included in all
16 !copies or substantial portions of the Software.
17 !
18 !THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 !IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 !FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 !AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 !LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 !OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 !SOFTWARE.
25 !
26 !Email: p.browne@reading.ac.uk
27 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
28 
29 program lorenz63
30  implicit none
31  include 'mpif.h'
32  real(kind=kind(1.0D0)) :: t,sigma,rho,beta,dt,tstart,tstop
33  real(kind=kind(1.0D0)), dimension(3) :: x,k1,k2,k3,k4
34  integer :: mpi_err,mdl_id,cpl_root,cpl_mpi_comm
35  integer, dimension(MPI_STATUS_SIZE) :: mpi_status
36  call initialise_mpi(mdl_id,cpl_root,cpl_mpi_comm)
37  tstart =0.0d0 ; dt = 0.01d0 ; tstop = real(24)*dt
38  sigma = 10.0d0 ; rho = 28.0d0 ; beta = 8.0d0 /3.0d0
39  x = (/ 1.508870d0, -1.531271d0 , 25.46091d0 /)
40  call mpi_send(x,3,mpi_double_precision,cpl_root&
41  &,1,cpl_mpi_comm,mpi_err)
42  call mpi_recv(x,3,mpi_double_precision,cpl_root&
43  &,mpi_any_tag,cpl_mpi_comm,mpi_status,mpi_err)
44 2 continue
45  t = tstart
46  print*,t,x
47  do; if ( t .ge. tstop -1.0d-10) exit
48  k1 = f(x , sigma , rho , beta )
49  k2 = f(x +0.5d0 * dt * k1 , sigma , rho , beta )
50  k3 = f(x +0.5d0 * dt * k2 , sigma , rho , beta )
51  k4 = f(x + dt * k3 , sigma , rho , beta )
52  x = x + dt *( k1 + 2.0d0 *( k2 + k3 ) + k4 )/6.0d0
53  call mpi_send(x,3,mpi_double_precision,cpl_root&
54  &,1,cpl_mpi_comm,mpi_err)
55  call mpi_recv(x,3,mpi_double_precision,cpl_root&
56  &,mpi_any_tag,cpl_mpi_comm,mpi_status,mpi_err)
57  t = t + dt
58  print*,t,x(1),x(2),x(3)
59  select case(mpi_status(mpi_tag))
60  case(1)
61  continue
62  case(2)
63  go to 2
64  case(3)
65  go to 3
66  case default
67  print*,'Unknown mpi tag received: ',mpi_status(mpi_tag)
68  stop 4
69  end select
70  end do
71 3 continue
72  call mpi_finalize(mpi_err)
73 contains
74  function f (x , sigma , rho , beta )
75  implicit none
76  real(kind=kind(1.0D0)),intent(in),dimension (3) :: x
77  real(kind=kind(1.0D0)),dimension(3) :: f
78  real(kind=kind(1.0D0)),intent(in) :: sigma , rho , beta
79  f = (/sigma *(x(2)-x(1)),x(1)*(rho-x(3)) -x(2),x(1)*x(2)-beta*x(3)/)
80  end function f
81  subroutine initialise_mpi(mdl_id,cpl_root,cpl_mpi_comm)
82  implicit none
83  include 'mpif.h'
84  integer, intent(out) :: mdl_id,cpl_root,cpl_mpi_comm
85  integer :: mdl_num_proc=1
86  integer :: mpi_err,world_size,world_id
87  integer :: cpl_colour
88  integer :: particle_id,nens, da, nda
89  integer :: mdl_mpi_comm,mdlcolour
90  integer :: tmp_mdls_comm,models_id,models_size
91  call mpi_init(mpi_err)
92  da = 0
93  call mpi_comm_rank(mpi_comm_world,world_id,mpi_err)
94  call mpi_comm_size(mpi_comm_world,world_size,mpi_err)
95  call mpi_comm_split(mpi_comm_world,da,world_id,tmp_mdls_comm,mpi_err)
96  call mpi_comm_size(tmp_mdls_comm,models_size,mpi_err)
97  call mpi_comm_rank(tmp_mdls_comm,models_id, mpi_err)
98  mdlcolour = models_id/mdl_num_proc
99  call mpi_comm_split(tmp_mdls_comm,mdlcolour,models_id,mdl_mpi_comm,mpi_err)
100  call mpi_comm_rank(mdl_mpi_comm,mdl_id,mpi_err)
101  if(mdl_id .eq. 0) then
102  cpl_colour = 9999
103  else
104  cpl_colour = mpi_undefined
105  end if
106  call mpi_comm_split(mpi_comm_world,cpl_colour,mdlcolour,cpl_mpi_comm,mpi_err)
107  if(mdl_id .eq. 0) then
108  call mpi_comm_size(cpl_mpi_comm,nens,mpi_err)
109  call mpi_comm_rank(cpl_mpi_comm,particle_id,mpi_err)
110  nda = world_size-models_size;nens = nens - nda
111  cpl_root = ((nda*particle_id)/nens)+nens
112  else
113  cpl_root = -1
114  end if
115  end subroutine initialise_mpi
116 end program lorenz63
subroutine initialise_mpi(mdl_id, cpl_root, cpl_mpi_comm)
real(kind=kind(1.0d0)) function, dimension(n) f(n, x)
program lorenz63