MOM6
MOM_transcribe_grid.F90
Go to the documentation of this file.
2 
3 !***********************************************************************
4 !* GNU General Public License *
5 !* This file is a part of MOM. *
6 !* *
7 !* MOM is free software; you can redistribute it and/or modify it and *
8 !* are expected to follow the terms of the GNU General Public License *
9 !* as published by the Free Software Foundation; either version 2 of *
10 !* the License, or (at your option) any later version. *
11 !* *
12 !* MOM is distributed in the hope that it will be useful, but WITHOUT *
13 !* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
14 !* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public *
15 !* License for more details. *
16 !* *
17 !* For the full text of the GNU General Public License, *
18 !* write to: Free Software Foundation, Inc., *
19 !* 675 Mass Ave, Cambridge, MA 02139, USA. *
20 !* or see: http://www.gnu.org/licenses/gpl.html *
21 !***********************************************************************
22 
23 use mom_domains, only : pass_var, pass_vector
24 use mom_domains, only : to_all, scalar_pair, cgrid_ne, agrid, bgrid_ne, corner
26 use mom_error_handler, only : mom_error, mom_mesg, fatal, warning
28 
29 implicit none ; private
30 
32 
33 contains
34 
35 !> Copies information from a dynamic (shared) horizontal grid type into an
36 !! ocean_grid_type.
37 subroutine copy_dyngrid_to_mom_grid(dG, oG)
38  type(dyn_horgrid_type), intent(in) :: dG !< Common horizontal grid type
39  type(ocean_grid_type), intent(inout) :: oG !< Ocean grid type
40 
41  integer :: isd, ied, jsd, jed ! Common data domains.
42  integer :: IsdB, IedB, JsdB, JedB ! Common data domains.
43  integer :: ido, jdo, Ido2, Jdo2 ! Indexing offsets between the grids.
44  integer :: Igst, Jgst ! Global starting indices.
45  integer :: i, j
46 
47  ! MOM_grid_init and create_dyn_horgrid are called outside of this routine.
48  ! This routine copies over the fields that were set by MOM_initialized_fixed.
49 
50  ! Determine the indexing offsets between the grids.
51  ido = dg%idg_offset - og%idg_offset
52  jdo = dg%jdg_offset - og%jdg_offset
53 
54  isd = max(og%isd, dg%isd+ido) ; jsd = max(og%jsd, dg%jsd+jdo)
55  ied = min(og%ied, dg%ied+ido) ; jed = min(og%jed, dg%jed+jdo)
56  isdb = max(og%IsdB, dg%IsdB+ido) ; jsdb = max(og%JsdB, dg%JsdB+jdo)
57  iedb = min(og%IedB, dg%IedB+ido) ; jedb = min(og%JedB, dg%JedB+jdo)
58 
59  ! Check that the grids conform.
60  if ((isd > og%isc) .or. (ied < og%ied) .or. (jsd > og%jsc) .or. (jed > og%jed)) &
61  call mom_error(fatal, "copy_dyngrid_to_MOM_grid called with incompatible grids.")
62 
63  do i=isd,ied ; do j=jsd,jed
64  og%geoLonT(i,j) = dg%geoLonT(i+ido,j+jdo)
65  og%geoLatT(i,j) = dg%geoLatT(i+ido,j+jdo)
66  og%dxT(i,j) = dg%dxT(i+ido,j+jdo)
67  og%dyT(i,j) = dg%dyT(i+ido,j+jdo)
68  og%areaT(i,j) = dg%areaT(i+ido,j+jdo)
69  og%bathyT(i,j) = dg%bathyT(i+ido,j+jdo)
70 
71  og%dF_dx(i,j) = dg%dF_dx(i+ido,j+jdo)
72  og%dF_dy(i,j) = dg%dF_dy(i+ido,j+jdo)
73  og%sin_rot(i,j) = dg%sin_rot(i+ido,j+jdo)
74  og%cos_rot(i,j) = dg%cos_rot(i+ido,j+jdo)
75  og%mask2dT(i,j) = dg%mask2dT(i+ido,j+jdo)
76  enddo ; enddo
77 
78  do i=isdb,iedb ; do j=jsd,jed
79  og%geoLonCu(i,j) = dg%geoLonCu(i+ido,j+jdo)
80  og%geoLatCu(i,j) = dg%geoLatCu(i+ido,j+jdo)
81  og%dxCu(i,j) = dg%dxCu(i+ido,j+jdo)
82  og%dyCu(i,j) = dg%dyCu(i+ido,j+jdo)
83  og%dy_Cu(i,j) = dg%dy_Cu(i+ido,j+jdo)
84  og%dy_Cu_obc(i,j) = dg%dy_Cu_obc(i+ido,j+jdo)
85 
86  og%mask2dCu(i,j) = dg%mask2dCu(i+ido,j+jdo)
87  og%areaCu(i,j) = dg%areaCu(i+ido,j+jdo)
88  og%IareaCu(i,j) = dg%IareaCu(i+ido,j+jdo)
89  enddo ; enddo
90 
91  do i=isd,ied ; do j=jsdb,jedb
92  og%geoLonCv(i,j) = dg%geoLonCv(i+ido,j+jdo)
93  og%geoLatCv(i,j) = dg%geoLatCv(i+ido,j+jdo)
94  og%dxCv(i,j) = dg%dxCv(i+ido,j+jdo)
95  og%dyCv(i,j) = dg%dyCv(i+ido,j+jdo)
96  og%dx_Cv(i,j) = dg%dx_Cv(i+ido,j+jdo)
97  og%dx_Cv_obc(i,j) = dg%dx_Cv_obc(i+ido,j+jdo)
98 
99  og%mask2dCv(i,j) = dg%mask2dCv(i+ido,j+jdo)
100  og%areaCv(i,j) = dg%areaCv(i+ido,j+jdo)
101  og%IareaCv(i,j) = dg%IareaCv(i+ido,j+jdo)
102  enddo ; enddo
103 
104  do i=isdb,iedb ; do j=jsdb,jedb
105  og%geoLonBu(i,j) = dg%geoLonBu(i+ido,j+jdo)
106  og%geoLatBu(i,j) = dg%geoLatBu(i+ido,j+jdo)
107  og%dxBu(i,j) = dg%dxBu(i+ido,j+jdo)
108  og%dyBu(i,j) = dg%dyBu(i+ido,j+jdo)
109  og%areaBu(i,j) = dg%areaBu(i+ido,j+jdo)
110  og%CoriolisBu(i,j) = dg%CoriolisBu(i+ido,j+jdo)
111  og%mask2dBu(i,j) = dg%mask2dBu(i+ido,j+jdo)
112  enddo ; enddo
113 
114  og%bathymetry_at_vel = dg%bathymetry_at_vel
115  if (og%bathymetry_at_vel) then
116  do i=isdb,iedb ; do j=jsd,jed
117  og%Dblock_u(i,j) = dg%Dblock_u(i+ido,j+jdo)
118  og%Dopen_u(i,j) = dg%Dopen_u(i+ido,j+jdo)
119  enddo ; enddo
120  do i=isd,ied ; do j=jsdb,jedb
121  og%Dblock_v(i,j) = dg%Dblock_v(i+ido,j+jdo)
122  og%Dopen_v(i,j) = dg%Dopen_v(i+ido,j+jdo)
123  enddo ; enddo
124  endif
125 
126  og%gridLonT(og%isg:og%ieg) = dg%gridLonT(dg%isg:dg%ieg)
127  og%gridLatT(og%jsg:og%jeg) = dg%gridLatT(dg%jsg:dg%jeg)
128  ! The more complicated logic here avoids segmentation faults if one grid uses
129  ! global symmetric memory while the other does not. Because a northeast grid
130  ! convention is being used, the upper bounds for each array correspond.
131  ! Note that the dynamic grid always uses symmetric memory.
132  ido2 = dg%IegB-og%IegB ; igst = max(og%IsgB, (dg%isg-1)-ido2)
133  jdo2 = dg%JegB-og%JegB ; jgst = max(og%JsgB, (dg%jsg-1)-jdo2)
134  do i=igst,og%IegB ; og%gridLonB(i) = dg%gridLonB(i+ido2) ; enddo
135  do j=jgst,og%JegB ; og%gridLatB(j) = dg%gridLatB(j+jdo2) ; enddo
136 
137  ! Copy various scalar variables and strings.
138  og%x_axis_units = dg%x_axis_units ; og%y_axis_units = dg%y_axis_units
139  og%areaT_global = dg%areaT_global ; og%IareaT_global = dg%IareaT_global
140  og%south_lat = dg%south_lat ; og%west_lon = dg%west_lon
141  og%len_lat = dg%len_lat ; og%len_lon = dg%len_lon
142  og%Rad_Earth = dg%Rad_Earth ; og%max_depth = dg%max_depth
143 
144 ! Update the halos in case the dynamic grid has smaller halos than the ocean grid.
145  call pass_var(og%areaT, og%Domain)
146  call pass_var(og%bathyT, og%Domain)
147  call pass_var(og%geoLonT, og%Domain)
148  call pass_var(og%geoLatT, og%Domain)
149  call pass_vector(og%dxT, og%dyT, og%Domain, to_all+scalar_pair, agrid)
150  call pass_vector(og%dF_dx, og%dF_dy, og%Domain, to_all, agrid)
151  call pass_vector(og%cos_rot, og%sin_rot, og%Domain, to_all, agrid)
152  call pass_var(og%mask2dT, og%Domain)
153 
154  call pass_vector(og%areaCu, og%areaCv, og%Domain, to_all+scalar_pair, cgrid_ne)
155  call pass_vector(og%dyCu, og%dxCv, og%Domain, to_all+scalar_pair, cgrid_ne)
156  call pass_vector(og%dxCu, og%dyCv, og%Domain, to_all+scalar_pair, cgrid_ne)
157  call pass_vector(og%dy_Cu, og%dx_Cv, og%Domain, to_all+scalar_pair, cgrid_ne)
158  call pass_vector(og%dy_Cu_obc, og%dx_Cv_obc, og%Domain, to_all+scalar_pair, cgrid_ne)
159  call pass_vector(og%mask2dCu, og%mask2dCv, og%Domain, to_all+scalar_pair, cgrid_ne)
160  call pass_vector(og%IareaCu, og%IareaCv, og%Domain, to_all+scalar_pair, cgrid_ne)
161  call pass_vector(og%IareaCu, og%IareaCv, og%Domain, to_all+scalar_pair, cgrid_ne)
162  call pass_vector(og%geoLatCu, og%geoLatCv, og%Domain, to_all+scalar_pair, cgrid_ne)
163 
164  call pass_var(og%areaBu, og%Domain, position=corner)
165  call pass_var(og%geoLonBu, og%Domain, position=corner)
166  call pass_var(og%geoLatBu, og%Domain, position=corner)
167  call pass_vector(og%dxBu, og%dyBu, og%Domain, to_all+scalar_pair, bgrid_ne)
168  call pass_var(og%CoriolisBu, og%Domain, position=corner)
169  call pass_var(og%mask2dBu, og%Domain, position=corner)
170 
171  if (og%bathymetry_at_vel) then
172  call pass_vector(og%Dblock_u, og%Dblock_v, og%Domain, to_all+scalar_pair, cgrid_ne)
173  call pass_vector(og%Dopen_u, og%Dopen_v, og%Domain, to_all+scalar_pair, cgrid_ne)
174  endif
175 
176  call set_derived_metrics(og)
177 
178 end subroutine copy_dyngrid_to_mom_grid
179 
180 
181 !> Copies information from an ocean_grid_type into a dynamic (shared)
182 !! horizontal grid type.
183 subroutine copy_mom_grid_to_dyngrid(oG, dG)
184  type(ocean_grid_type), intent(in) :: oG !< Ocean grid type
185  type(dyn_horgrid_type), intent(inout) :: dG !< Common horizontal grid type
186 
187  integer :: isd, ied, jsd, jed ! Common data domains.
188  integer :: IsdB, IedB, JsdB, JedB ! Common data domains.
189  integer :: ido, jdo, Ido2, Jdo2 ! Indexing offsets between the grids.
190  integer :: Igst, Jgst ! Global starting indices.
191  integer :: i, j
192 
193  ! MOM_grid_init and create_dyn_horgrid are called outside of this routine.
194  ! This routine copies over the fields that were set by MOM_initialized_fixed.
195 
196  ! Determine the indexing offsets between the grids.
197  ido = og%idG_offset - dg%idG_offset
198  jdo = og%jdG_offset - dg%jdG_offset
199 
200  isd = max(dg%isd, og%isd+ido) ; jsd = max(dg%jsd, og%jsd+jdo)
201  ied = min(dg%ied, og%ied+ido) ; jed = min(dg%jed, og%jed+jdo)
202  isdb = max(dg%IsdB, og%IsdB+ido) ; jsdb = max(dg%JsdB, og%JsdB+jdo)
203  iedb = min(dg%IedB, og%IedB+ido) ; jedb = min(dg%JedB, og%JedB+jdo)
204 
205  ! Check that the grids conform.
206  if ((isd > dg%isc) .or. (ied < dg%ied) .or. (jsd > dg%jsc) .or. (jed > dg%jed)) &
207  call mom_error(fatal, "copy_dyngrid_to_MOM_grid called with incompatible grids.")
208 
209  do i=isd,ied ; do j=jsd,jed
210  dg%geoLonT(i,j) = og%geoLonT(i+ido,j+jdo)
211  dg%geoLatT(i,j) = og%geoLatT(i+ido,j+jdo)
212  dg%dxT(i,j) = og%dxT(i+ido,j+jdo)
213  dg%dyT(i,j) = og%dyT(i+ido,j+jdo)
214  dg%areaT(i,j) = og%areaT(i+ido,j+jdo)
215  dg%bathyT(i,j) = og%bathyT(i+ido,j+jdo)
216 
217  dg%dF_dx(i,j) = og%dF_dx(i+ido,j+jdo)
218  dg%dF_dy(i,j) = og%dF_dy(i+ido,j+jdo)
219  dg%sin_rot(i,j) = og%sin_rot(i+ido,j+jdo)
220  dg%cos_rot(i,j) = og%cos_rot(i+ido,j+jdo)
221  dg%mask2dT(i,j) = og%mask2dT(i+ido,j+jdo)
222  enddo ; enddo
223 
224  do i=isdb,iedb ; do j=jsd,jed
225  dg%geoLonCu(i,j) = og%geoLonCu(i+ido,j+jdo)
226  dg%geoLatCu(i,j) = og%geoLatCu(i+ido,j+jdo)
227  dg%dxCu(i,j) = og%dxCu(i+ido,j+jdo)
228  dg%dyCu(i,j) = og%dyCu(i+ido,j+jdo)
229  dg%dy_Cu(i,j) = og%dy_Cu(i+ido,j+jdo)
230  dg%dy_Cu_obc(i,j) = og%dy_Cu_obc(i+ido,j+jdo)
231 
232  dg%mask2dCu(i,j) = og%mask2dCu(i+ido,j+jdo)
233  dg%areaCu(i,j) = og%areaCu(i+ido,j+jdo)
234  dg%IareaCu(i,j) = og%IareaCu(i+ido,j+jdo)
235  enddo ; enddo
236 
237  do i=isd,ied ; do j=jsdb,jedb
238  dg%geoLonCv(i,j) = og%geoLonCv(i+ido,j+jdo)
239  dg%geoLatCv(i,j) = og%geoLatCv(i+ido,j+jdo)
240  dg%dxCv(i,j) = og%dxCv(i+ido,j+jdo)
241  dg%dyCv(i,j) = og%dyCv(i+ido,j+jdo)
242  dg%dx_Cv(i,j) = og%dx_Cv(i+ido,j+jdo)
243  dg%dx_Cv_obc(i,j) = og%dx_Cv_obc(i+ido,j+jdo)
244 
245  dg%mask2dCv(i,j) = og%mask2dCv(i+ido,j+jdo)
246  dg%areaCv(i,j) = og%areaCv(i+ido,j+jdo)
247  dg%IareaCv(i,j) = og%IareaCv(i+ido,j+jdo)
248  enddo ; enddo
249 
250  do i=isdb,iedb ; do j=jsdb,jedb
251  dg%geoLonBu(i,j) = og%geoLonBu(i+ido,j+jdo)
252  dg%geoLatBu(i,j) = og%geoLatBu(i+ido,j+jdo)
253  dg%dxBu(i,j) = og%dxBu(i+ido,j+jdo)
254  dg%dyBu(i,j) = og%dyBu(i+ido,j+jdo)
255  dg%areaBu(i,j) = og%areaBu(i+ido,j+jdo)
256  dg%CoriolisBu(i,j) = og%CoriolisBu(i+ido,j+jdo)
257  dg%mask2dBu(i,j) = og%mask2dBu(i+ido,j+jdo)
258  enddo ; enddo
259 
260  dg%bathymetry_at_vel = og%bathymetry_at_vel
261  if (dg%bathymetry_at_vel) then
262  do i=isdb,iedb ; do j=jsd,jed
263  dg%Dblock_u(i,j) = og%Dblock_u(i+ido,j+jdo)
264  dg%Dopen_u(i,j) = og%Dopen_u(i+ido,j+jdo)
265  enddo ; enddo
266  do i=isd,ied ; do j=jsdb,jedb
267  dg%Dblock_v(i,j) = og%Dblock_v(i+ido,j+jdo)
268  dg%Dopen_v(i,j) = og%Dopen_v(i+ido,j+jdo)
269  enddo ; enddo
270  endif
271 
272  dg%gridLonT(dg%isg:dg%ieg) = og%gridLonT(og%isg:og%ieg)
273  dg%gridLatT(dg%jsg:dg%jeg) = og%gridLatT(og%jsg:og%jeg)
274 
275  ! The more complicated logic here avoids segmentation faults if one grid uses
276  ! global symmetric memory while the other does not. Because a northeast grid
277  ! convention is being used, the upper bounds for each array correspond.
278  ! Note that the dynamic grid always uses symmetric memory.
279  ido2 = og%IegB-dg%IegB ; igst = max(dg%isg-1, og%IsgB-ido2)
280  jdo2 = og%JegB-dg%JegB ; jgst = max(dg%jsg-1, og%JsgB-jdo2)
281  do i=igst,dg%IegB ; dg%gridLonB(i) = og%gridLonB(i+ido2) ; enddo
282  do j=jgst,dg%JegB ; dg%gridLatB(j) = og%gridLatB(j+jdo2) ; enddo
283 
284  ! Copy various scalar variables and strings.
285  dg%x_axis_units = og%x_axis_units ; dg%y_axis_units = og%y_axis_units
286  dg%areaT_global = og%areaT_global ; dg%IareaT_global = og%IareaT_global
287  dg%south_lat = og%south_lat ; dg%west_lon = og%west_lon
288  dg%len_lat = og%len_lat ; dg%len_lon = og%len_lon
289  dg%Rad_Earth = og%Rad_Earth ; dg%max_depth = og%max_depth
290 
291 ! Update the halos in case the dynamic grid has smaller halos than the ocean grid.
292  call pass_var(dg%areaT, dg%Domain)
293  call pass_var(dg%bathyT, dg%Domain)
294  call pass_var(dg%geoLonT, dg%Domain)
295  call pass_var(dg%geoLatT, dg%Domain)
296  call pass_vector(dg%dxT, dg%dyT, dg%Domain, to_all+scalar_pair, agrid)
297  call pass_vector(dg%dF_dx, dg%dF_dy, dg%Domain, to_all, agrid)
298  call pass_vector(dg%cos_rot, dg%sin_rot, dg%Domain, to_all, agrid)
299  call pass_var(dg%mask2dT, dg%Domain)
300 
301  call pass_vector(dg%areaCu, dg%areaCv, dg%Domain, to_all+scalar_pair, cgrid_ne)
302  call pass_vector(dg%dyCu, dg%dxCv, dg%Domain, to_all+scalar_pair, cgrid_ne)
303  call pass_vector(dg%dxCu, dg%dyCv, dg%Domain, to_all+scalar_pair, cgrid_ne)
304  call pass_vector(dg%dy_Cu, dg%dx_Cv, dg%Domain, to_all+scalar_pair, cgrid_ne)
305  call pass_vector(dg%dy_Cu_obc, dg%dx_Cv_obc, dg%Domain, to_all+scalar_pair, cgrid_ne)
306  call pass_vector(dg%mask2dCu, dg%mask2dCv, dg%Domain, to_all+scalar_pair, cgrid_ne)
307  call pass_vector(dg%IareaCu, dg%IareaCv, dg%Domain, to_all+scalar_pair, cgrid_ne)
308  call pass_vector(dg%IareaCu, dg%IareaCv, dg%Domain, to_all+scalar_pair, cgrid_ne)
309  call pass_vector(dg%geoLatCu, dg%geoLatCv, dg%Domain, to_all+scalar_pair, cgrid_ne)
310 
311  call pass_var(dg%areaBu, dg%Domain, position=corner)
312  call pass_var(dg%geoLonBu, dg%Domain, position=corner)
313  call pass_var(dg%geoLatBu, dg%Domain, position=corner)
314  call pass_vector(dg%dxBu, dg%dyBu, dg%Domain, to_all+scalar_pair, bgrid_ne)
315  call pass_var(dg%CoriolisBu, dg%Domain, position=corner)
316  call pass_var(dg%mask2dBu, dg%Domain, position=corner)
317 
318  if (dg%bathymetry_at_vel) then
319  call pass_vector(dg%Dblock_u, dg%Dblock_v, dg%Domain, to_all+scalar_pair, cgrid_ne)
320  call pass_vector(dg%Dopen_u, dg%Dopen_v, dg%Domain, to_all+scalar_pair, cgrid_ne)
321  endif
322 
323  call set_derived_dyn_horgrid(dg)
324 
325 end subroutine copy_mom_grid_to_dyngrid
326 
327 end module mom_transcribe_grid
integer, parameter, public to_all
Ocean grid type. See mom_grid for details.
Definition: MOM_grid.F90:19
subroutine, public set_derived_dyn_horgrid(G)
set_derived_dyn_horgrid calculates metric terms that are derived from other metrics.
Provides the ocean grid type.
Definition: MOM_grid.F90:2
subroutine, public copy_dyngrid_to_mom_grid(dG, oG)
Copies information from a dynamic (shared) horizontal grid type into an ocean_grid_type.
subroutine, public mom_mesg(message, verb, all_print)
subroutine, public copy_mom_grid_to_dyngrid(oG, dG)
Copies information from an ocean_grid_type into a dynamic (shared) horizontal grid type...
subroutine, public set_derived_metrics(G)
set_derived_metrics calculates metric terms that are derived from other metrics.
Definition: MOM_grid.F90:353
subroutine, public mom_error(level, message, all_print)