SOCA
Model2GeoVaLs.F90
Go to the documentation of this file.
1 ! (C) Copyright 2020-2021 UCAR
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 
6 !> C++ interface for converting model variables to geovals (mostly identity function)
8 
9 use iso_c_binding
10 use kinds, only: kind_real
11 
12 ! soca modules
13 use soca_fields_mod, only: soca_field
15 use soca_geom_mod, only: soca_geom
18 use soca_state_mod, only: soca_state
20 
21 implicit none
22 private
23 
24 
25 !-------------------------------------------------------------------------------
26 contains
27 !-------------------------------------------------------------------------------
28 
29 
30 !-------------------------------------------------------------------------------
31 !> C++ interface for linear change of variables from model to geovals
32 !!
33 !! Only the identity operator is needed for the linear variables
34 !! \throws abor1_ftn aborts if the field name cannot be in the "getval_name*"
35 !! section of the variable metadata
36 subroutine soca_model2geovals_linear_changevar_f90(c_key_geom, c_key_dxin, c_key_dxout) &
37  bind(c,name='soca_model2geovals_linear_changevar_f90')
38  integer(c_int), intent(in) :: c_key_geom, c_key_dxin, c_key_dxout
39 
40  type(soca_geom), pointer :: geom
41  type(soca_increment), pointer :: dxin, dxout
42  type(soca_field), pointer :: field
43  integer :: i
44 
45  call soca_geom_registry%get(c_key_geom, geom)
46  call soca_increment_registry%get(c_key_dxin, dxin)
47  call soca_increment_registry%get(c_key_dxout, dxout)
48 
49  ! identity operators
50  do i=1, size(dxout%fields)
51  call dxin%get(dxout%fields(i)%metadata%name, field)
52 
53  if (field%metadata%getval_name == dxout%fields(i)%name) then
54  dxout%fields(i)%val(:,:,:) = field%val(:,:,:) !< full field
55  elseif (field%metadata%getval_name_surface == dxout%fields(i)%name) then
56  dxout%fields(i)%val(:,:,1) = field%val(:,:,1) !< surface only of a 3D field
57  else
58  call abor1_ftn( 'error in soca_model2geovals_linear_changevar_f90 processing ' &
59  // dxout%fields(i)%name )
60  endif
61 
62  end do
63 end subroutine
64 
65 
66 !-------------------------------------------------------------------------------
67 !> C++ interface for linear change of variables from geovals to model
68 !!
69 !! Only the identity operator is need for the linear variables.
70 !! \throws abor1_ftn aborts if the field name cannot be in the "getval_name*"
71 !! section of the variable metadata
72 subroutine soca_model2geovals_linear_changevarad_f90(c_key_geom, c_key_dxin, c_key_dxout) &
73  bind(c,name='soca_model2geovals_linear_changevarAD_f90')
74  integer(c_int), intent(in) :: c_key_geom, c_key_dxin, c_key_dxout
75 
76  type(soca_geom), pointer :: geom
77  type(soca_increment), pointer :: dxin, dxout
78  type(soca_field), pointer :: field
79  integer :: i
80 
81  call soca_geom_registry%get(c_key_geom, geom)
82  call soca_increment_registry%get(c_key_dxin, dxin)
83  call soca_increment_registry%get(c_key_dxout, dxout)
84 
85  ! identity operators
86  do i=1, size(dxin%fields)
87  call dxout%get(dxin%fields(i)%metadata%name, field)
88 
89  if(field%metadata%getval_name == dxin%fields(i)%name) then
90  field%val = field%val + dxin%fields(i)%val !< full field
91  elseif(field%metadata%getval_name_surface == dxin%fields(i)%name) then
92  field%val(:,:,1) = field%val(:,:,1) + dxin%fields(i)%val(:,:,1) !< surface only
93  else
94  call abor1_ftn( 'error in soca_model2geovals_linear_changevarAD_f90 processing ' &
95  // dxin%fields(i)%name )
96  end if
97 
98  end do
99 end subroutine
100 
101 
102 !-------------------------------------------------------------------------------
103 !> C++ interface for the non-linear change of variables from model to geovals
104 !!
105 !! This is *mostly* an identity operator, except for a small number of derived variables
106 !! that are to be calculated here ("distance_from_coast", "sea_area_fraction", etc.)
107 !! \throws abor1_ftn aborts if field name is not handled.
108 subroutine soca_model2geovals_changevar_f90(c_key_geom, c_key_xin, c_key_xout) &
109  bind(c,name='soca_model2geovals_changevar_f90')
110  integer(c_int), intent(in) :: c_key_geom, c_key_xin, c_key_xout
111 
112  type(soca_geom), pointer :: geom
113  type(soca_state), pointer :: xin, xout
114  type(soca_field), pointer :: field
115  integer :: i
116 
117  call soca_geom_registry%get(c_key_geom, geom)
118  call soca_state_registry%get(c_key_xin, xin)
119  call soca_state_registry%get(c_key_xout, xout)
120 !
121  do i=1, size(xout%fields)
122  ! Skip dummy fields related to the CRTM hacks.
123  ! REMOVE this once a proper coupled h(x) is implemented
124  if (xout%fields(i)%metadata%dummy_atm) cycle
125 
126  ! special cases
127  select case (xout%fields(i)%name)
128 
129  ! fields that are obtained from geometry
130  case ('distance_from_coast')
131  xout%fields(i)%val(:,:,1) = real(geom%distance_from_coast, kind=kind_real)
132 
133  case ('sea_area_fraction')
134  xout%fields(i)%val(:,:,1) = real(geom%mask2d, kind=kind_real)
135 
136  case ('mesoscale_representation_error')
137  ! Representation errors: dx/R
138  ! TODO, why is the halo left to 0 for RR ??
139  xout%fields(i)%val(geom%isc:geom%iec, geom%jsc:geom%jec, 1) = &
140  geom%mask2d(geom%isc:geom%iec, geom%jsc:geom%jec) * &
141  sqrt(geom%cell_area(geom%isc:geom%iec, geom%jsc:geom%jec) / &
142  geom%rossby_radius(geom%isc:geom%iec, geom%jsc:geom%jec))
143 
144  ! special derived state variables
145  case ('surface_temperature_where_sea')
146  call xin%get('tocn', field)
147  xout%fields(i)%val(:,:,1) = field%val(:,:,1) + 273.15_kind_real
148 
149  case ('sea_floor_depth_below_sea_surface')
150  call xin%get('hocn', field)
151  xout%fields(i)%val(:,:,1) = sum(field%val, dim=3)
152 
153  ! identity operators
154  case default
155  call xin%get(xout%fields(i)%metadata%name, field)
156  if (field%metadata%getval_name == xout%fields(i)%name) then
157  xout%fields(i)%val(:,:,:) = field%val(:,:,:) !< full field
158  elseif (field%metadata%getval_name_surface == xout%fields(i)%name) then
159  xout%fields(i)%val(:,:,1) = field%val(:,:,1) !< surface only of a 3D field
160  else
161  call abor1_ftn( 'error in soca_model2geovals_changevar_f90 processing ' &
162  // xout%fields(i)%name )
163  endif
164 
165  end select
166 
167  end do
168 end subroutine
169 
170 !-------------------------------------------------------------------------------
171 
172 end module
Handle fields for the model.
C++ interfaces for soca_geom_mod::soca_geom.
type(registry_t), public soca_geom_registry
Linked list interface - defines registry_t type.
Geometry module.
Increment fields.
registry for soca_increment_mod::soca_increment instances for use in Fortran/C++ interface of soca_in...
type(registry_t), public soca_increment_registry
Linked list interface - defines registry_t type.
C++ interface for converting model variables to geovals (mostly identity function)
subroutine soca_model2geovals_changevar_f90(c_key_geom, c_key_xin, c_key_xout)
C++ interface for the non-linear change of variables from model to geovals.
subroutine soca_model2geovals_linear_changevar_f90(c_key_geom, c_key_dxin, c_key_dxout)
C++ interface for linear change of variables from model to geovals.
subroutine soca_model2geovals_linear_changevarad_f90(c_key_geom, c_key_dxin, c_key_dxout)
C++ interface for linear change of variables from geovals to model.
State fields.
registry for soca_state_mod::soca_state instances for use in Fortran/C++ interfaces of soca_state_mod...
type(registry_t), public soca_state_registry
Linked list interface - defines registry_t type.
Holds all data and metadata related to a single field variable.
Geometry data structure.