Skip to content

Commit 3b2cfba

Browse files
authored
Merge pull request #954 from GEOS-ESM/feature/wjiang/GEOS_GigaTraj
Add gigatraj grid comp
2 parents a57e1ac + ffbd9fc commit 3b2cfba

File tree

11 files changed

+2044
-0
lines changed

11 files changed

+2044
-0
lines changed

CMakeLists.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@ set (alldirs
88
GEOSwgcm_GridComp
99
)
1010

11+
option(BUILD_WITH_GIGATRAJ "Build GEOSgcm with Gigatraj" OFF)
12+
13+
if (BUILD_WITH_GIGATRAJ)
14+
list(APPEND alldirs GEOSgigatraj_GridComp)
15+
endif()
1116

1217
if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/GEOS_GcmGridComp.F90)
1318

@@ -17,6 +22,8 @@ if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/GEOS_GcmGridComp.F90)
1722
SUBCOMPONENTS ${alldirs}
1823
DEPENDENCIES MAPL ESMF::ESMF)
1924

25+
target_compile_definitions (${this} PRIVATE $<$<BOOL:${BUILD_WITH_GIGATRAJ}>:HAS_GIGATRAJ>)
26+
2027
ecbuild_install_project( NAME GEOSgcm_GridComp)
2128

2229
else ()

GEOS_GcmGridComp.F90

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ module GEOS_GcmGridCompMod
2020
use GEOS_AgcmGridCompMod, only: AGCM_SetServices => SetServices
2121
use GEOS_mkiauGridCompMod, only: AIAU_SetServices => SetServices
2222
use DFI_GridCompMod, only: ADFI_SetServices => SetServices
23+
#ifdef HAS_GIGATRAJ
24+
use GEOS_GigatrajGridCompMod, only: GigaTraj_SetServices => SetServices
25+
#endif
26+
2327
use GEOS_OgcmGridCompMod, only: OGCM_SetServices => SetServices
2428
use GEOS_WgcmGridCompMod, only: WGCM_SetServices => SetServices
2529
use MAPL_HistoryGridCompMod, only: Hist_SetServices => SetServices
@@ -58,6 +62,7 @@ module GEOS_GcmGridCompMod
5862
integer :: ADFI
5963
integer :: WGCM
6064
integer :: hist
65+
integer :: gigatraj
6166

6267
integer :: bypass_ogcm
6368
integer :: k
@@ -251,6 +256,10 @@ subroutine SetServices ( GC, RC )
251256
else
252257
AGCM = MAPL_AddChild(GC, NAME='AGCM', SS=Agcm_SetServices, RC=STATUS)
253258
VERIFY_(STATUS)
259+
#ifdef HAS_GIGATRAJ
260+
gigatraj = MAPL_AddChild(GC, NAME='GIGATRAJ', SS=GigaTraj_SetServices, RC=STATUS)
261+
VERIFY_(STATUS)
262+
#endif
254263
AIAU = MAPL_AddChild(GC, NAME='AIAU', SS=AIAU_SetServices, RC=STATUS)
255264
VERIFY_(STATUS)
256265
ADFI = MAPL_AddChild(GC, NAME='ADFI', SS=ADFI_SetServices, RC=STATUS)
@@ -955,6 +964,10 @@ subroutine Initialize ( GC, IMPORT, EXPORT, CLOCK, RC )
955964
! Recursive setup of grids (should be disabled)
956965
call ESMF_GridCompSet(GCS(AGCM), grid=agrid, rc=status)
957966
VERIFY_(STATUS)
967+
#ifdef HAS_GIGATRAJ
968+
call ESMF_GridCompSet(GCS(gigatraj), grid=agrid, rc=status)
969+
VERIFY_(STATUS)
970+
#endif
958971
call ESMF_GridCompSet(GCS(OGCM), grid=ogrid, rc=status)
959972
VERIFY_(STATUS)
960973
if(.not. DO_DATA_ATM4OCN) then
@@ -2019,10 +2032,23 @@ subroutine Run ( GC, IMPORT, EXPORT, CLOCK, RC )
20192032
else
20202033
call MAPL_TimerOn(MAPL,"AGCM" )
20212034
endif
2035+
2036+
#ifdef HAS_GIGATRAJ
2037+
! use agcm export as gigatraj's import to get the initial state.
2038+
! it only runs at the begining of the first time step
2039+
call ESMF_GridCompRun ( GCS(gigatraj), importState=GEX(AGCM), exportState=GEX(gigatraj), clock=clock, phase=1, userRC=status )
2040+
VERIFY_(STATUS)
2041+
#endif
20222042

20232043
call ESMF_GridCompRun ( GCS(AGCM), importState=GIM(AGCM), exportState=GEX(AGCM), clock=clock, userRC=status )
20242044
VERIFY_(STATUS)
20252045

2046+
#ifdef HAS_GIGATRAJ
2047+
! use agcm export as gigatraj's import
2048+
call ESMF_GridCompRun ( GCS(gigatraj), importState=GEX(AGCM), exportState=GEX(gigatraj), clock=clock, phase=2, userRC=status )
2049+
VERIFY_(STATUS)
2050+
#endif
2051+
20262052
if(DO_DATA_ATM4OCN) then
20272053
call MAPL_TimerOff(MAPL,"DATAATM" )
20282054
else

GEOSagcm_GridComp/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ elseif (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/GEOS_AgcmGridComp.F90)
2020
SUBCOMPONENTS ${alldirs}
2121
DEPENDENCIES MAPL GEOS_Shared Chem_Shared ESMF::ESMF)
2222

23+
target_compile_definitions (${this} PRIVATE $<$<BOOL:${BUILD_WITH_GIGATRAJ}>:HAS_GIGATRAJ>)
24+
2325
else ()
2426

2527
esma_add_subdirectories (${alldirs})

GEOSagcm_GridComp/GEOS_AgcmGridComp.F90

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -790,6 +790,34 @@ subroutine SetServices ( GC, RC )
790790
RC = STATUS)
791791
VERIFY_(STATUS)
792792

793+
#ifdef HAS_GIGATRAJ
794+
call MAPL_AddExportSpec(GC, &
795+
SHORT_NAME = 'PL', &
796+
CHILD_ID = SDYN, &
797+
RC = STATUS)
798+
VERIFY_(STATUS)
799+
call MAPL_AddExportSpec(GC, &
800+
SHORT_NAME = 'OMEGA', &
801+
CHILD_ID = SDYN, &
802+
RC = STATUS)
803+
VERIFY_(STATUS)
804+
call MAPL_AddExportSpec(GC, &
805+
SHORT_NAME = 'TH', &
806+
CHILD_ID = SDYN, &
807+
RC = STATUS)
808+
VERIFY_(STATUS)
809+
call MAPL_AddExportSpec(GC, &
810+
SHORT_NAME = 'DTDTDYN', &
811+
CHILD_ID = SDYN, &
812+
RC = STATUS)
813+
VERIFY_(STATUS)
814+
call MAPL_AddExportSpec(GC, &
815+
SHORT_NAME = 'ZL', &
816+
CHILD_ID = SDYN, &
817+
RC = STATUS)
818+
VERIFY_(STATUS)
819+
#endif
820+
793821
call MAPL_AddExportSpec( GC, &
794822
SHORT_NAME = 'PS', &
795823
CHILD_ID = SDYN, &

GEOSagcm_GridComp/GEOSsuperdyn_GridComp/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/GEOS_SuperdynGridComp.F90)
2020
SUBCOMPONENTS ${alldirs}
2121
DEPENDENCIES MAPL GEOS_Shared ESMF::ESMF)
2222

23+
target_compile_definitions (${this} PRIVATE $<$<BOOL:${BUILD_WITH_GIGATRAJ}>:HAS_GIGATRAJ>)
24+
2325
else ()
2426

2527
esma_add_subdirectories (${alldirs})

GEOSagcm_GridComp/GEOSsuperdyn_GridComp/GEOS_SuperdynGridComp.F90

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,15 @@ subroutine SetServices ( GC, RC )
274274
RC=STATUS )
275275
VERIFY_(STATUS)
276276

277+
#ifdef HAS_GIGATRAJ
278+
call MAPL_AddExportSpec ( GC , &
279+
SHORT_NAME = 'ZL', &
280+
CHILD_ID = DYN, &
281+
RC=STATUS )
282+
VERIFY_(STATUS)
283+
#endif
284+
285+
277286
call MAPL_AddExportSpec ( GC , &
278287
SHORT_NAME = 'PREF', &
279288
CHILD_ID = DYN, &

GEOSgigatraj_GridComp/.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
@GigaTraj/
2+
GigaTraj/
3+
GigaTraj@/
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
esma_set_this()
2+
3+
set (dependencies MAPL ESMF::ESMF geos_giga metsources filters gigatraj)
4+
5+
esma_add_library (${this}
6+
SRCS GEOS_Giga_InterOp.F90 Gigatraj_Utils.F90 GEOS_GigatrajGridComp.F90
7+
DEPENDENCIES ${dependencies})
8+
9+
esma_add_subdirectories(GigaTraj)
Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
! This module define the interface bewteen GEOS and gigatraj
2+
! The functions are defined in gigatraj
3+
4+
module GEOS_Giga_InterOpMod
5+
use, intrinsic :: iso_c_binding, only : c_double, c_int, c_ptr, c_null_char, c_associated
6+
use, intrinsic :: iso_c_binding, only : c_loc, c_null_ptr
7+
use mpi
8+
implicit none
9+
private
10+
11+
public :: initMetGEOSDistributedLatLonData
12+
public :: initMetGEOSDistributedCubedData
13+
public :: updateFields
14+
public :: RK4_advance
15+
public :: setData
16+
public :: getData
17+
public :: getData2d
18+
19+
public :: test_Field3D
20+
public :: test_dataflow
21+
public :: test_metData
22+
23+
interface
24+
25+
function initMetGEOSDistributedCubedData(comm, ijToRank, Ig, lev, i1, i2, j1, j2, nzs, lons_ptr, lats_ptr, eta_ptr, ctime_ptr) result (metdata_ptr) bind(C, name="initGigaGridDistributedCubedData")
26+
import :: c_int, c_ptr
27+
implicit none
28+
integer(c_int), intent(in), value :: comm, Ig, lev, i1,i2,j1,j2, nzs
29+
type(c_ptr), intent(in), value :: ijToRank, lons_ptr, lats_ptr, eta_ptr, ctime_ptr
30+
type(c_ptr) :: metdata_ptr
31+
end function
32+
33+
function initMetGEOSDistributedLatLonData(comm, ijToRank, Ig, Jg,lev, nlon_local, nlat_local, nzs, lons_ptr, lats_ptr, eta_ptr, ctime_ptr) result (metdata_ptr) bind(C, name="initGigaGridDistributedLatLonData")
34+
import :: c_int, c_ptr
35+
implicit none
36+
integer(c_int), intent(in), value :: comm, Ig, Jg, lev, nlon_local, nlat_local, nzs
37+
type(c_ptr), intent(in), value :: ijToRank, lons_ptr, lats_ptr, eta_ptr, ctime_ptr
38+
type(c_ptr) :: metdata_ptr
39+
end function
40+
41+
subroutine updateFields( metSrc_ptr, ctime_ptr, u_ptr, v_ptr, w_ptr, p_ptr) bind(C, name="updateFields")
42+
import :: c_ptr
43+
implicit none
44+
type(c_ptr), intent(in), value :: metSrc_ptr, ctime_ptr, u_ptr, v_ptr, w_ptr, p_ptr
45+
end subroutine
46+
47+
subroutine RK4_advance(metsrc_ptr, ctime_ptr, dt, n, lons_ptr, lats_ptr, levs_ptr) bind( C, name='RK4_advance')
48+
import :: c_ptr, c_int, c_double
49+
type(c_ptr), intent(in), value :: metsrc_ptr
50+
real(c_double), intent(in), value :: dt
51+
integer(c_int), intent(in), value :: n
52+
type(c_ptr), intent(in), value :: ctime_ptr, lons_ptr, lats_ptr, levs_ptr
53+
end subroutine
54+
55+
subroutine test_Field3d(obj_ptr) bind(C, name="test_Field3D")
56+
import :: c_ptr
57+
implicit none
58+
type(c_ptr), intent(in), value :: obj_ptr
59+
end subroutine
60+
61+
subroutine test_metData(obj_ptr, time, n, lons_ptr, lats_ptr, levs_ptr, u_ptr, v_ptr, w_ptr) bind(C, name="test_metData")
62+
import :: c_ptr,c_int, c_double
63+
type(c_ptr), intent(in), value :: obj_ptr
64+
real(c_double), intent(in), value :: time
65+
integer(c_int), intent(in), value :: n
66+
type(c_ptr), intent(in), value :: lons_ptr, lats_ptr, levs_ptr, u_ptr, v_ptr, w_ptr
67+
end subroutine
68+
69+
subroutine setData ( metSrc_ptr, ctime, quantity_ptr, data_ptr) bind(C, name="setData")
70+
import :: c_ptr
71+
type(c_ptr), intent(in), value :: metSrc_ptr, ctime, quantity_ptr, data_ptr
72+
end subroutine setData
73+
74+
subroutine getData ( metSrc_ptr, ctime, quantity_ptr, n, lons_ptr, lats_ptr, levs_ptr, values_ptr) bind(C, name="getData")
75+
import :: c_ptr, c_int
76+
integer(c_int), intent(in), value :: n
77+
type(c_ptr), intent(in), value :: metSrc_ptr, ctime, quantity_ptr, lons_ptr, lats_ptr, levs_ptr, values_ptr
78+
end subroutine getData
79+
80+
subroutine getData2d ( metSrc_ptr, ctime, quantity_ptr, n, lons_ptr, lats_ptr, values_ptr) bind(C, name="getData2d")
81+
import :: c_ptr, c_int
82+
integer(c_int), intent(in), value :: n
83+
type(c_ptr), intent(in), value :: metSrc_ptr, ctime, quantity_ptr, lons_ptr, lats_ptr, values_ptr
84+
end subroutine getData2d
85+
end interface
86+
87+
contains
88+
89+
subroutine test_dataflow(num_parcels, lons, lats, zs, CellToRank, DIMS, comm)
90+
integer :: num_parcels, comm, DIMS(3)
91+
real, dimension(:), intent(in) :: lons, lats,zs
92+
integer, dimension(:,:), intent(in) :: CellToRank
93+
94+
integer :: i, npes, ierror, rank, my_rank
95+
real :: dlon, dlat
96+
real, allocatable :: lons_positive(:)
97+
98+
real, allocatable :: lons_send(:), lats_send(:), zs_send(:)
99+
real, allocatable :: lons_recv(:), lats_recv(:), zs_recv(:)
100+
real, allocatable :: U_recv(:), U_send(:)
101+
real, allocatable :: U(:), V(:), W(:), pos(:)
102+
103+
integer, allocatable :: counts_send(:),counts_recv(:), II(:), JJ(:), ranks(:)
104+
integer, allocatable :: disp_send(:), disp_recv(:), tmp_position(:)
105+
106+
dlon = 360.0 / DIMS(1)
107+
dlat = 180.0 / DIMS(2)
108+
109+
lons_positive = lons
110+
where (lons_positive < 0) lons_positive=lons_positive + 360.0
111+
II = min( max(ceiling (lons_positive/dlon),1), DIMS(1))
112+
JJ = min( max(ceiling ((lats + 90.0)/dlat),1), DIMS(2))
113+
114+
call MPI_Comm_size(comm, npes, ierror)
115+
call MPI_Comm_rank(comm, my_rank, ierror)
116+
117+
allocate(ranks(num_parcels))
118+
allocate(counts_send(npes))
119+
allocate(counts_recv(npes))
120+
allocate(disp_send(npes))
121+
allocate(disp_recv(npes))
122+
123+
do i = 1, num_parcels
124+
ranks(i) = CellToRank(II(i), JJ(i))
125+
enddo
126+
127+
!-- -------------------
128+
!step 4) Pack the location data and send them to where the metData sit
129+
!-- -------------------
130+
131+
do rank = 0, npes-1
132+
counts_send(rank+1) = count(ranks == rank)
133+
enddo
134+
135+
call MPI_AllToALL(counts_send, 1, MPI_INTEGER, counts_recv, 1, MPI_INTEGER, comm, ierror)
136+
137+
disp_send = 0
138+
do rank = 1, npes-1
139+
disp_send(rank+1) = disp_send(rank)+ counts_send(rank)
140+
enddo
141+
disp_recv = 0
142+
do rank = 1, npes-1
143+
disp_recv(rank+1) = disp_recv(rank)+ counts_recv(rank)
144+
enddo
145+
146+
147+
! re-arranged lats lons, and ids
148+
tmp_position = disp_send
149+
allocate(lons_send(num_parcels))
150+
allocate(lons_recv(sum(counts_recv)))
151+
allocate(lats_send(num_parcels))
152+
allocate(lats_recv(sum(counts_recv)))
153+
allocate(zs_send(num_parcels))
154+
allocate(zs_recv(sum(counts_recv)))
155+
156+
allocate(pos(num_parcels))
157+
do i = 1, num_parcels
158+
rank = ranks(i)
159+
pos(i) = tmp_position(rank+1) +1
160+
lons_send(pos(i)) = lons(i)
161+
lats_send(pos(i)) = lats(i)
162+
zs_send(pos(i)) = zs(i)
163+
tmp_position(rank+1) = tmp_position(rank+1) + 1
164+
enddo
165+
166+
call MPI_AllToALLv(lons_send, counts_send, disp_send, MPI_REAL, lons_recv, counts_recv, disp_recv, MPI_REAL, comm, ierror)
167+
call MPI_AllToALLv(lats_send, counts_send, disp_send, MPI_REAL, lats_recv, counts_recv, disp_recv, MPI_REAL, comm, ierror)
168+
call MPI_AllToALLv(zs_send, counts_send, disp_send, MPI_REAL, zs_recv, counts_recv, disp_recv, MPI_REAL, comm, ierror)
169+
!-- -------------------
170+
!step 5) Interpolate the data ( horiontally and vertically) and send back where they are from
171+
!-- -------------------
172+
allocate(U_recv(sum(counts_recv)), source = my_rank*1.0)
173+
allocate(U_send(num_parcels), source = -1.0)
174+
!
175+
! Horizontal and vertical interpolator here
176+
!
177+
call MPI_AllToALLv(U_recv, counts_recv, disp_recv, MPI_REAL, U_send, counts_send, disp_send, MPI_REAL, comm, ierror)
178+
179+
!---------------------
180+
!step 6) Rearrange data ( not necessary if ids was rearranged ins step 4)
181+
!---------------------
182+
183+
allocate(U(num_parcels))
184+
allocate(V(num_parcels))
185+
allocate(W(num_parcels))
186+
U(:) = U_send(pos(:))
187+
188+
end subroutine
189+
190+
end module GEOS_Giga_InterOpMod

0 commit comments

Comments
 (0)