FV3 Bundle
qg_geom_mod.F90
Go to the documentation of this file.
1 ! (C) Copyright 2009-2016 ECMWF.
2 !
3 ! This software is licensed under the terms of the Apache Licence Version 2.0
4 ! which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
5 ! In applying this licence, ECMWF does not waive the privileges and immunities
6 ! granted to it by virtue of its status as an intergovernmental organisation nor
7 ! does it submit to any jurisdiction.
8 
9 !> Fortran module handling geometry for the QG model
10 
12 
13 use iso_c_binding
14 use qg_constants
15 use config_mod
16 use kinds
17 
18 implicit none
19 private
20 public :: qg_geom
21 public :: qg_geom_registry
22 
23 ! ------------------------------------------------------------------------------
24 
25 !> Fortran derived type to hold geometry data for the QG model
26 type :: qg_geom
27  integer :: nx
28  integer :: ny
29  real(kind=kind_real),allocatable :: lat(:)
30  real(kind=kind_real),allocatable :: lon(:)
31  real(kind=kind_real),allocatable :: area(:,:)
32 end type qg_geom
33 
34 #define LISTED_TYPE qg_geom
35 
36 !> Linked list interface - defines registry_t type
37 #include "oops/util/linkedList_i.f"
38 
39 !> Global registry
40 type(registry_t) :: qg_geom_registry
41 
42 ! ------------------------------------------------------------------------------
43 contains
44 ! ------------------------------------------------------------------------------
45 
46 !> Linked list implementation
47 #include "oops/util/linkedList_c.f"
48 
49 ! ------------------------------------------------------------------------------
50 
51 subroutine c_qg_geo_setup(c_key_self, c_conf) bind(c,name='qg_geo_setup_f90')
52 implicit none
53 integer(c_int), intent(inout) :: c_key_self
54 type(c_ptr), intent(in) :: c_conf
55 
56 integer :: ix,iy
57 real(kind=kind_real) :: lat_center,lat_south, lat_north, lon_west, lon_east, full_area
58 type(qg_geom), pointer :: self
59 
60 call qg_geom_registry%init()
61 call qg_geom_registry%add(c_key_self)
62 call qg_geom_registry%get(c_key_self,self)
63 
64 self%nx = config_get_int(c_conf, "nx")
65 self%ny = config_get_int(c_conf, "ny")
66 
67 ! Allocate
68 allocate(self%lon(self%nx))
69 allocate(self%lat(self%ny))
70 allocate(self%area(self%nx,self%ny))
71 
72 ! Define longitude/latitude
73 lat_center = 0.0! asin(f0/(2.0*omega))
74 lat_south = lat_center-0.5*domain_meridional/req ! 28 deg S
75 lat_north = lat_center+0.5*domain_meridional/req ! 28 deg N
76 lon_west = 0.0 ! 0 deg
77 lon_east = lon_west+domain_zonal/(req*cos(lat_center)) ! 107 deg E
78 do ix=1,self%nx
79  self%lon(ix) = lon_west+real(ix-1,kind=kind_real)/real(self%nx-1,kind=kind_real)*(lon_east-lon_west)
80 end do
81 do iy=1,self%ny
82  self%lat(iy) = lat_south+real(iy-1,kind=kind_real)/real(self%ny-1,kind=kind_real)*(lat_north-lat_south)
83 end do
84 
85 ! Convert longitude/latitude to degrees
86 self%lon = self%lon*180_kind_real/pi
87 self%lat = self%lat*180_kind_real/pi
88 
89 ! Define area (approximate)
91 self%area = full_area/real(self%nx*self%ny,kind=kind_real)
92 
93 end subroutine c_qg_geo_setup
94 
95 ! ------------------------------------------------------------------------------
96 
97 subroutine c_qg_geo_clone(c_key_self, c_key_other) bind(c,name='qg_geo_clone_f90')
98 implicit none
99 integer(c_int), intent(in ) :: c_key_self
100 integer(c_int), intent(inout) :: c_key_other
101 
102 type(qg_geom), pointer :: self, other
103 
104 call qg_geom_registry%add(c_key_other)
105 call qg_geom_registry%get(c_key_other, other)
106 call qg_geom_registry%get(c_key_self , self )
107 other%nx = self%nx
108 other%ny = self%ny
109 allocate(other%lon(other%nx))
110 allocate(other%lat(other%ny))
111 allocate(other%area(other%nx,other%ny))
112 other%lon = self%lon
113 other%lat = self%lat
114 other%area = self%area
115 
116 end subroutine c_qg_geo_clone
117 
118 ! ------------------------------------------------------------------------------
119 
120 subroutine c_qg_geo_delete(c_key_self) bind(c,name='qg_geo_delete_f90')
122 implicit none
123 integer(c_int), intent(inout) :: c_key_self
124 
125 call qg_geom_registry%remove(c_key_self)
126 
127 end subroutine c_qg_geo_delete
128 
129 ! ------------------------------------------------------------------------------
130 
131 subroutine c_qg_geo_info(c_key_self, c_nx, c_ny) bind(c,name='qg_geo_info_f90')
132 implicit none
133 integer(c_int), intent(in ) :: c_key_self
134 integer(c_int), intent(inout) :: c_nx
135 integer(c_int), intent(inout) :: c_ny
136 type(qg_geom), pointer :: self
137 
138 call qg_geom_registry%get(c_key_self , self )
139 c_nx = self%nx
140 c_ny = self%ny
141 
142 end subroutine c_qg_geo_info
143 
144 ! ------------------------------------------------------------------------------
145 
146 end module qg_geom_mod
real(kind=kind_real), parameter domain_meridional
meridional model domain (m)
subroutine c_qg_geo_clone(c_key_self, c_key_other)
Definition: qg_geom_mod.F90:98
Fortran derived type to hold geometry data for the QG model.
Definition: qg_geom_mod.F90:26
type(registry_t), public qg_geom_registry
Linked list interface - defines registry_t type.
Definition: qg_geom_mod.F90:40
Constants for the QG model.
subroutine c_qg_geo_info(c_key_self, c_nx, c_ny)
Fortran module handling geometry for the QG model.
Definition: qg_geom_mod.F90:11
subroutine c_qg_geo_delete(c_key_self)
real(kind=kind_real), parameter req
Earth radius at equator (m)
subroutine c_qg_geo_setup(c_key_self, c_conf)
Linked list implementation.
Definition: qg_geom_mod.F90:52
real(kind=kind_real), parameter domain_zonal
model domain (m) in zonal direction
integer, parameter, public kind_real
real(fp), parameter, public pi