WAVEWATCH III  beta 0.0.1
wmesmfmd.F90
Go to the documentation of this file.
1 
9 
10 #include "w3macros.h"
11 !/
12 !/ ------------------------------------------------------------------- /
13 !/ Macros for ESMF logging
14 !/
15 #define FILENAME "wmesmfmd.ftn"
16 #define CONTEXT line=__LINE__,file=FILENAME,method=METHOD
17 #define PASSTHRU msg=ESMF_LOGERR_PASSTHRU,CONTEXT
18 !/
19 !/ ------------------------------------------------------------------- /
20 !/ Define real kind for data passed through ESMF interface
21 !/
22 #if defined(ESMF_R8)
23 #define ESMF_KIND_RX ESMF_KIND_R8
24 #define ESMF_TYPEKIND_RX ESMF_TYPEKIND_R8
25 #else
26 #define ESMF_KIND_RX ESMF_KIND_R4
27 #define ESMF_TYPEKIND_RX ESMF_TYPEKIND_R4
28 #endif
29 !/
30 !/ ------------------------------------------------------------------- /
31 !/ Macro for enabling using W3OUTG to calculate export fields
32 !/
33 #define USE_W3OUTG_FOR_EXPORT___disabled
34 !/
35 !/ ------------------------------------------------------------------- /
36 !/ Macros for enabling test output
37 !/
38 #define TEST_WMESMFMD___disabled
39 #define TEST_WMESMFMD_GETIMPORT___disabled
40 #define TEST_WMESMFMD_SETEXPORT___disabled
41 #define TEST_WMESMFMD_CREATEIMPGRID___disabled
42 #define TEST_WMESMFMD_CREATEEXPGRID___disabled
43 #define TEST_WMESMFMD_SETUPIMPBMSK___disabled
44 #define TEST_WMESMFMD_SETUPIMPMMSK___disabled
45 #define TEST_WMESMFMD_CHARNK___disabled
46 #define TEST_WMESMFMD_ROUGHL___disabled
47 #define TEST_WMESMFMD_BOTCUR___disabled
48 #define TEST_WMESMFMD_RADSTR2D___disabled
49 #define TEST_WMESMFMD_STOKES3D___disabled
50 #define TEST_WMESMFMD_PSTOKES___disabled
51 #define TEST_WMESMFMD_READFROMFILE___disabled
52 
53 !/ ------------------------------------------------------------------- /
72 module wmesmfmd
73  !/
74  !/ +-----------------------------------+
75  !/ | WAVEWATCH III NOAA/NCEP |
76  !/ | T. J. Campbell, NRL |
77  !/ | J. Meixner, NCEP |
78  !/ | A. J. van der Westhuysen |
79  !/ | FORTRAN 90 |
80  !/ | Last update : 09-Aug-2017 |
81  !/ +-----------------------------------+
82  !/
83  !/ 20-Jan-2017 : Origination. ( version 6.02 )
84  !/ 09-Aug-2017 : Add ocean forcing export fields ( version 6.03 )
85  !/ 28-Feb-2018 : Modifications for unstruc meshes ( version 6.06 )
86  !/
87  !/ Copyright 2009-2014 National Weather Service (NWS),
88  !/ National Oceanic and Atmospheric Administration. All rights
89  !/ reserved. WAVEWATCH III is a trademark of the NWS.
90  !/ No unauthorized use without permission.
91  !/
92  ! 1. Purpose :
93  !
94  ! National Unified Prediction Capability (NUOPC) based
95  ! Earth System Modeling Framework (ESMF) interface module for
96  ! multi-grid wave model.
97  !
98  ! 2. Variables and types :
99  !
100  ! All module variables and types are scoped private by default.
101  ! The private module variables and types are not listed in this section.
102  !
103  ! Name Type Scope Description
104  ! ----------------------------------------------------------------
105  ! ----------------------------------------------------------------
106  !
107  ! 3. Subroutines and functions :
108  !
109  ! All module subroutines and functions are scoped private by default.
110  !
111  ! Name Type Scope Description
112  ! -----------------------------------------------------------------
113  ! SetServices Subr. Public Wave model ESMF Set Services
114  ! -----------------------------------------------------------------
115  ! InitializeP0 Subr. Private NUOPC/ESMF Initialize phase 0
116  ! InitializeP1 Subr. Private NUOPC/ESMF Initialize phase 1
117  ! InitializeP3 Subr. Private NUOPC/ESMF Initialize phase 3
118  ! Finalize Subr. Private NUOPC/ESMF Finalize
119  ! DataInitialize Subr. Private NUOPC/ESMF Data Initialize
120  ! ModelAdvance Subr. Private NUOPC/ESMF Model Advance
121  ! GetImport Subr. Private Get fields from import state
122  ! SetExport Subr. Private Set fields from export state
123  ! CreateImpGrid Subr. Private Create ESMF grid for import
124  ! CreateExpGrid Subr. Private Create ESMF grid for export
125  ! CreateImpMesh Subr. Private Create ESMF mesh for import
126  ! CreateExpMesh Subr. Private Create ESMF mesh for export
127  ! SetupImpBmsk Subr. Private Setup background blending mask
128  ! BlendImpField Subr. Private Blend import field with background
129  ! SetupImpMmsk Subr. Private Setup merging mask
130  ! FieldFill Subr. Private Fill ESMF field
131  ! FieldGather Subr. Private Gather ESMF field
132  ! FieldIndex Func. Private Return field index
133  ! PrintTimers Subr. Private Print wallclock timers
134  ! CalcDecomp Subr. Private Calculate a 2D processor layout
135  ! GetEnvValue Subr. Private Get value of env. variable
136  ! GetZlevels Subr. Private Get z-levels from file for SDC
137  ! CalcCharnk Subr. Private Calculate Charnock for export
138  ! CalcRoughl Subr. Private Calculate roughness length for export
139  ! CalcBotcur Subr. Private Calculate wave-bottom currents for export
140  ! CalcRadstr2D Subr. Private Calculate 2D radiation stresses for export
141  ! CalcStokes3D Subr. Private Calculate 3D Stokes drift current for export
142  ! CalcPStokes Subr. Private Calculate partitioned Stokes drift for export
143  ! ReadFromFile Subr. Private Read input file
144  ! ----------------------------------------------------------------
145  !
146  ! 4. Subroutines and functions used :
147  !
148  ! See subroutine documentation.
149  !
150  ! 5. Remarks :
151  !
152  ! 6. Switches :
153  !
154  ! See subroutine documentation.
155  !
156  ! !/MPI Switch for enabling Message Passing Interface API
157  ! !/SHRD Switch for shared memory architecture
158  ! !/DIST Switch for distributed memory architecture
159  ! !/ST3 WAM 4+ input and dissipation.
160  ! !/ST4 Ardhuin et al. (2009, 2010)
161  !
162  ! 7. Source code :
163  !
164  !/ ------------------------------------------------------------------- /
165  !/
166  !/ Use associated modules
167  !/
168  ! --- ESMF Module
169  use esmf
170 
171  ! --- NUOPC modules
172  use nuopc
173  use nuopc_model, parent_setservices => setservices
174 
175  ! --- WW3 modules
176  use constants
177  use wminitmd, only: wminit, wminitnml
178  use wmwavemd, only: wmwave
179  use wmfinlmd, only: wmfinl
180  use wmmdatmd
181  use w3gdatmd
182  use w3idatmd
183  use w3odatmd
184  use w3wdatmd
185  use w3adatmd
186  use w3timemd
187  use wmupdtmd, only: wmupd2
188  use w3updtmd, only: w3uini
189 #ifdef W3_ST3
190  use w3src3md, only: w3spr3
191 #endif
192 #ifdef W3_ST4
193  use w3src4md, only: w3spr4
194 #endif
195  use w3iogomd, only: w3outg
196 #ifdef W3_SCRIP
198 #endif
199  !/
200  !/ Specify default data typing
201  !/
202  implicit none
203  !/
204  !/ Include MPI definitions
205  !/
206 #ifdef W3_MPI
207  include "mpif.h"
208 #endif
209  !/
210  !/ Specify default accessibility
211  !/
212  private
213  save
214  !/
215  !/ Public module methods
216  !/
217  public setservices, setvm
218  !/
219  !/ Private module parameters
220  !/
221  ! --- Default Mask Convention for import/export fields
222  INTEGER, PARAMETER :: DEFAULT_MASK_WATER = 0
223  INTEGER, PARAMETER :: DEFAULT_MASK_LAND = 1
224 
225  ! --- Miscellaneous
226  integer, parameter :: stdo = 6
227  type(ESMF_VM) :: vm
228  integer :: lpet
229  integer :: npet
230  integer :: verbosity
231  logical :: realizeAllExport = .false.
232  integer :: maskValueWater = default_mask_water
233  integer :: maskValueLand = default_mask_land
234  integer :: nz
235  real(4), allocatable :: zl(:)
236  character(256) :: zlfile = 'none'
237  character(ESMF_MAXSTR) :: msg
238  real(ESMF_KIND_RX) :: zeroValue
239  real(ESMF_KIND_RX) :: missingValue
240  real(ESMF_KIND_RX) :: fillValue
241  !
242  ! --- Timing
243  integer, parameter :: numwt=10
244  character(32) :: wtnam(numwt)
245  integer :: wtcnt(numwt)
246  real(8) :: wtime(numwt)
247  !
248  ! --- Import fields
249  type(ESMF_ArraySpec) :: impArraySpec2D
250  type(ESMF_StaggerLoc) :: impStaggerLoc
251  type(ESMF_Index_Flag) :: impIndexFlag
252  type(ESMF_Grid) :: impGrid
253  integer :: impGridID
254  logical :: impGridIsLocal
255  integer, parameter :: impHaloWidth = 3
256  integer :: impHaloLWidth(2)
257  integer :: impHaloUWidth(2)
258  type(ESMF_RouteHandle) :: impHaloRH
259  type(ESMF_Field) :: impMask
260  logical :: noActiveImpFields
261  integer :: numImpFields
262  character(64), allocatable :: impFieldName(:)
263  character(128), allocatable :: impFieldStdName(:)
264  logical, allocatable :: impFieldInitRqrd(:)
265  logical, allocatable :: impFieldActive(:)
266  type(ESMF_Field), allocatable :: impField(:)
267  !
268  ! --- Background import fields
269  character(10), allocatable :: mbgFieldName(:)
270  character(128), allocatable :: mbgFieldStdName(:)
271  logical, allocatable :: mbgFieldActive(:)
272  type(ESMF_Field), allocatable :: mbgField(:)
273  type(ESMF_Field), allocatable :: bmskField(:)
274  !
275  ! --- Unstructured import meshes
276  type(ESMF_Mesh) :: impMesh
277  ! integer :: impMeshID !< impMeshID
278  ! logical :: impMeshIsLocal !< impMeshIsLocal
279  !
280  ! --- Export fields
281  type(ESMF_ArraySpec) :: expArraySpec2D
282  type(ESMF_ArraySpec) :: expArraySpec3D
283  type(ESMF_StaggerLoc) :: expStaggerLoc
284  type(ESMF_Index_Flag) :: expIndexFlag
285  type(ESMF_Grid) :: expGrid
286  integer :: expGridID = 1
287  logical :: expGridIsLocal
288  integer, parameter :: expHaloWidth = 3
289  integer :: expHaloLWidth(2)
290  integer :: expHaloUWidth(2)
291  type(ESMF_RouteHandle) :: expHaloRH
292  type(ESMF_Field) :: expMask
293  logical :: noActiveExpFields
294  integer :: numExpFields
295  character(64), allocatable :: expFieldName(:)
296  character(128), allocatable :: expFieldStdName(:)
297  integer, allocatable :: expFieldDim(:)
298  logical, allocatable :: expFieldActive(:)
299  type(ESMF_Field), allocatable :: expField(:)
300  !
301  ! --- Unstructured export meshes
302  type(ESMF_Mesh) :: expMesh
303  integer :: expMeshID
304  logical :: expMeshIsLocal
305  !
306  ! --- Native field stuff
307  type(ESMF_ArraySpec) :: natArraySpec1D
308  type(ESMF_ArraySpec) :: natArraySpec2D
309  type(ESMF_ArraySpec) :: natArraySpec3D
310  type(ESMF_StaggerLoc) :: natStaggerLoc
311  type(ESMF_Index_Flag) :: natIndexFlag
312  type(ESMF_Grid) :: natGrid
313  integer :: natGridID
314  logical :: natGridIsLocal
315  type(ESMF_RouteHandle):: n2eRH
316  !
317  ! --- Mediator
318  logical :: med_present = .false.
319  character(256) :: flds_scalar_name = ''
320  integer :: flds_scalar_num = 0
321  ! flds_scalar_index_nx and flds_scalar_index_nx are domain
322  ! metadata that allows CMEPS to convert a mesh back to 2d
323  ! space for mediator restart and history outputs
324  integer :: flds_scalar_index_nx = 0
325  integer :: flds_scalar_index_ny = 0
326  ! --- Memory Profiling
327  logical :: profile_memory = .false.
328  !
329  ! --- Coupling stuff for non completely overlapped domains
330  logical :: merge_import = .false.
331  logical, allocatable :: mmskCreated(:)
332  type(ESMF_Field), allocatable :: mmskField(:)
333  type(ESMF_Field), allocatable :: mdtField(:)
334  !/
335  !/ ------------------------------------------------------------------- /
336 
337 contains
338 
339  !/ ------------------------------------------------------------------- /
340  !/
341 #undef METHOD
342 #define METHOD "SetServices"
343 
351  subroutine setservices ( gcomp, rc )
352  !/
353  !/ +-----------------------------------+
354  !/ | WAVEWATCH III NOAA/NCEP |
355  !/ | T. J. Campbell, NRL |
356  !/ | FORTRAN 90 |
357  !/ | Last update : 20-Jan-2017 |
358  !/ +-----------------------------------+
359  !/
360  !/ 20-Jan-2017 : Origination. ( version 6.02 )
361  !/
362  ! 1. Purpose :
363  !
364  ! Wave model ESMF set services.
365  !
366  ! 2. Method :
367  !
368  ! 3. Parameters :
369  !
370  ! Parameter list
371  ! ----------------------------------------------------------------
372  ! gcomp Type I/O Gridded component
373  ! rc Int. O Return code
374  ! ----------------------------------------------------------------
375  !
376  ! 4. Subroutines used :
377  !
378  ! Name Type Module Description
379  ! ----------------------------------------------------------------
380  ! InitializeP0 Subr. WMESMFMD Wave model NUOPC/ESMF Initialize phase 0
381  ! InitializeP1 Subr. WMESMFMD Wave model NUOPC/ESMF Initialize phase 1
382  ! InitializeP3 Subr. WMESMFMD Wave model NUOPC/ESMF Initialize phase 3
383  ! Finalize Subr. WMESMFMD Wave model NUOPC/ESMF Finalize
384  ! DataInitialize Subr. WMESMFMD Wave model NUOPC/ESMF Data Initialize
385  ! ModelAdvance Subr. WMESMFMD Wave model NUOPC/ESMF Model Advance
386  ! ----------------------------------------------------------------
387  !
388  ! 5. Called by :
389  !
390  ! 6. Error messages :
391  !
392  ! 7. Remarks :
393  !
394  ! 8. Structure :
395  !
396  ! 9. Switches :
397  !
398  ! 10. Source code :
399  !
400  !/ ------------------------------------------------------------------- /
401  !/
402  !/ ------------------------------------------------------------------- /
403  !/ Parameter list
404  !/
405  implicit none
406  type(esmf_gridcomp) :: gcomp
407  integer,intent(out) :: rc
408  !/
409  !/ ------------------------------------------------------------------- /
410  !/ Local parameters
411  !/
412  !NONE
413  !
414  ! -------------------------------------------------------------------- /
415  ! Prep
416  !
417  rc = esmf_success
418 
419  ! --- Initialize wallclock timers
420 
421  wtnam( 1) = 'InitializeP0'
422  wtnam( 2) = 'InitializeP1'
423  wtnam( 3) = 'InitializeP3'
424  wtnam( 4) = 'DataInitialize'
425  wtnam( 5) = 'ModelAdvance'
426  wtnam( 6) = 'Finalize'
427  wtnam( 7) = 'GetImport'
428  wtnam( 8) = 'SetExport'
429  wtnam( 9) = 'FieldGather'
430  wtnam(10) = 'FieldFill'
431  wtcnt( :) = 0
432  wtime( :) = 0d0
433  !
434  ! -------------------------------------------------------------------- /
435  ! 1. NUOPC model component will register the generic methods
436  !
437  call nuopc_compderive(gcomp, parent_setservices, rc=rc)
438  if (esmf_logfounderror(rc, passthru)) return
439  !
440  ! -------------------------------------------------------------------- /
441  ! 2. Set model entry points
442  !
443  ! --- Initialize - phase 0 (requires use of ESMF method)
444 
445  call esmf_gridcompsetentrypoint(gcomp, esmf_method_initialize, &
446  userroutine=initializep0, phase=0, rc=rc)
447  if (esmf_logfounderror(rc, passthru)) return
448 
449  ! --- Set entry points for initialize methods
450 
451  ! >= IPDv03 supports satisfying inter-model data dependencies and
452  ! the transfer of ESMF Grid & Mesh objects between Model and/or
453  ! Mediator components during initialization
454  ! IPDv03p1: advertise import & export fields
455  call nuopc_compsetentrypoint(gcomp, esmf_method_initialize, &
456  phaselabellist=(/"IPDv03p1"/), userroutine=initializep1, rc=rc)
457  if (esmf_logfounderror(rc, passthru)) return
458  ! IPDv03p2: unspecified by NUOPC -- not required
459  ! IPDv03p3: realize import & export fields
460  call nuopc_compsetentrypoint(gcomp, esmf_method_initialize, &
461  phaselabellist=(/"IPDv03p3"/), userroutine=initializep3, rc=rc)
462  if (esmf_logfounderror(rc, passthru)) return
463  ! IPDv03p4: relevant for TransferActionGeomObject=="accept"
464  ! IPDv03p5: relevant for TransferActionGeomObject=="accept"
465  ! IPDv03p6: check compatibility of fields connected status
466  ! IPDv03p7: handle field data initialization
467 
468  !
469  ! -------------------------------------------------------------------- /
470  ! 3. Register specializing methods
471  !
472  ! --- Model initialize export data method
473 
474  call nuopc_compspecialize(gcomp, speclabel=label_datainitialize, &
475  specroutine=datainitialize, rc=rc)
476  if (esmf_logfounderror(rc, passthru)) return
477 
478  ! --- Model checkImport method (overriding default)
479 
480  call esmf_methodremove(gcomp, label_checkimport, rc=rc)
481  if (esmf_logfounderror(rc, passthru)) return
482  call nuopc_compspecialize(gcomp, speclabel=label_checkimport, &
483  specroutine=nuopc_noop, rc=rc)
484  if (esmf_logfounderror(rc, passthru)) return
485 
486  ! --- Model advance method
487 
488  call nuopc_compspecialize(gcomp, speclabel=label_advance, &
489  specroutine=modeladvance, rc=rc)
490  if (esmf_logfounderror(rc, passthru)) return
491 
492  ! --- Model finalize method
493 
494  call nuopc_compspecialize(gcomp, speclabel=label_finalize, &
495  specroutine=finalize, rc=rc)
496  if (esmf_logfounderror(rc, passthru)) return
497  !
498  ! -------------------------------------------------------------------- /
499  ! Post
500  !
501  rc = esmf_success
502  !/
503  !/ End of SetServices ------------------------------------------------ /
504  !/
505  end subroutine setservices
506  !/ ------------------------------------------------------------------- /
507 
508 #undef METHOD
509 #define METHOD "InitializeP0"
510 
523  subroutine initializep0 ( gcomp, impState, expState, extClock, rc )
524  !/
525  !/ +-----------------------------------+
526  !/ | WAVEWATCH III NOAA/NCEP |
527  !/ | T. J. Campbell, NRL |
528  !/ | FORTRAN 90 |
529  !/ | Last update : 20-Jan-2017 |
530  !/ +-----------------------------------+
531  !/
532  !/ 20-Jan-2017 : Origination. ( version 6.02 )
533  !/
534  ! 1. Purpose :
535  !
536  ! Initialize wave model (phase 0)
537  ! * Define the NUOPC Initialize Phase Mapping
538  !
539  ! 2. Method :
540  !
541  ! 3. Parameters :
542  !
543  ! Parameter list
544  ! ----------------------------------------------------------------
545  ! gcomp Type I/O Gridded component
546  ! impState Type I/O Import state
547  ! expState Type I/O Export state
548  ! extClock Type I External clock
549  ! rc Int. O Return code
550  ! ----------------------------------------------------------------
551  !
552  ! 4. Subroutines used :
553  !
554  ! Name Type Module Description
555  ! ----------------------------------------------------------------
556  ! NONE
557  ! ----------------------------------------------------------------
558  !
559  ! 5. Called by :
560  !
561  ! 6. Error messages :
562  !
563  ! 7. Remarks :
564  !
565  ! 8. Structure :
566  !
567  ! 9. Switches :
568  !
569  ! 10. Source code :
570  !
571  !/ ------------------------------------------------------------------- /
572  !/
573  !/ ------------------------------------------------------------------- /
574  !/ Parameter list
575  !/
576  implicit none
577  type(esmf_gridcomp) :: gcomp
578  type(esmf_state) :: impstate
579  type(esmf_state) :: expstate
580  type(esmf_clock) :: extclock
581  integer,intent(out) :: rc
582  !/
583  !/ ------------------------------------------------------------------- /
584  !/ Local parameters
585  !/
586  character(ESMF_MAXSTR) :: cname
587  character(ESMF_MAXSTR) :: valuestring
588  integer, parameter :: iwt=1
589  real(8) :: wstime, wftime
590  logical :: ispresent, isset
591  !
592  ! -------------------------------------------------------------------- /
593  ! Prep
594  !
595  rc = esmf_success
596  call esmf_vmwtime(wstime)
597  call esmf_gridcompget(gcomp, name=cname, rc=rc)
598  if (esmf_logfounderror(rc, passthru)) return
599  !
600  ! -------------------------------------------------------------------- /
601  ! Determine verbosity
602  !
603  call nuopc_compattributeget(gcomp, name='Verbosity', &
604  value=valuestring, rc=rc)
605  if (esmf_logfounderror(rc, passthru)) return
606  verbosity = esmf_utilstring2int( valuestring, &
607  specialstringlist=(/'high','max '/), &
608  specialvaluelist=(/ 255, 255/), rc=rc )
609  if (esmf_logfounderror(rc, passthru)) return
610 
611  if (verbosity.gt.0) call esmf_logwrite(trim(cname)// &
612  ': entered InitializeP0', esmf_logmsg_info)
613  !
614  ! -------------------------------------------------------------------- /
615  ! Define initialization phases
616  ! * switch to IPDv03 by filtering all other phaseMap entries
617  !
618  call nuopc_compfilterphasemap(gcomp, esmf_method_initialize, &
619  acceptstringlist=(/"IPDv03p"/), rc=rc)
620  if (esmf_logfounderror(rc, passthru)) return
621  !
622  ! -------------------------------------------------------------------- /
623  ! Check if coupled with CMEPS mediator or not
624  !
625  call nuopc_compattributeget(gcomp, name="mediator_present", &
626  value=valuestring, ispresent=ispresent, isset=isset, rc=rc)
627  if (esmf_logfounderror(rc, passthru)) return
628 
629  if (ispresent .and. isset) then
630  read(valuestring,*) med_present
631  call esmf_logwrite(trim(cname)//': mediator_present = '// &
632  trim(valuestring), esmf_logmsg_info, rc=rc)
633  if (esmf_logfounderror(rc, passthru)) return
634  end if
635  !
636  ! -------------------------------------------------------------------- /
637  ! Set memory profiling
638  !
639  call nuopc_compattributeget(gcomp, name="ProfileMemory", &
640  value=valuestring, ispresent=ispresent, isset=isset, rc=rc)
641  if (esmf_logfounderror(rc, passthru)) return
642 
643  if (ispresent .and. isset) then
644  read(valuestring,*) profile_memory
645  call esmf_logwrite(trim(cname)//': profile_memory = '// &
646  trim(valuestring), esmf_logmsg_info, rc=rc)
647  if (esmf_logfounderror(rc, passthru)) return
648  end if
649 
650  !
651  ! -------------------------------------------------------------------- /
652  ! Post
653  !
654  rc = esmf_success
655  call esmf_vmwtime(wftime)
656  wtime(iwt) = wtime(iwt) + wftime - wstime
657  wtcnt(iwt) = wtcnt(iwt) + 1
658  if (verbosity.gt.0) call esmf_logwrite(trim(cname)// &
659  ': leaving InitializeP0', esmf_logmsg_info)
660  !/
661  !/ End of InitializeP0 ----------------------------------------------- /
662  !/
663  end subroutine initializep0
664  !/ ------------------------------------------------------------------- /
665  !/
666 #undef METHOD
667 #define METHOD "InitializeP1"
668 
681  subroutine initializep1 ( gcomp, impState, expState, extClock, rc )
682  !/
683  !/ +-----------------------------------+
684  !/ | WAVEWATCH III NOAA/NCEP |
685  !/ | T. J. Campbell, NRL |
686  !/ | FORTRAN 90 |
687  !/ | Last update : 09-Aug-2017 |
688  !/ +-----------------------------------+
689  !/
690  !/ 20-Jan-2017 : Origination. ( version 6.02 )
691  !/ 09-Aug-2017 : Add ocean forcing export fields ( version 6.03 )
692  !/
693  ! 1. Purpose :
694  !
695  ! Initialize wave model (phase 1)
696  ! * Advertise fields in import and export states.
697  !
698  ! 2. Method :
699  !
700  ! 3. Parameters :
701  !
702  ! Parameter list
703  ! ----------------------------------------------------------------
704  ! gcomp Type I/O Gridded component
705  ! impState Type I/O Import state
706  ! expState Type I/O Export state
707  ! extClock Type I External clock
708  ! rc Int. O Return code
709  ! ----------------------------------------------------------------
710  !
711  ! 4. Subroutines used :
712  !
713  ! Name Type Module Description
714  ! ----------------------------------------------------------------
715  ! WMINIT Subr. WMINITMD Wave model initialization
716  ! WMINITNML Subr. WMINITMD Wave model initialization
717  ! ----------------------------------------------------------------
718  !
719  ! 5. Called by :
720  !
721  ! 6. Error messages :
722  !
723  ! 7. Remarks :
724  !
725  ! 8. Structure :
726  !
727  ! ----------------------------------------------------------------
728  ! 1. Initialization necessary for driver
729  ! a General I/O: (implicit in WMMDATMD)
730  ! b MPI environment
731  ! c Identifying output to "screen" unit
732  ! 2. Initialization of all wave models / grids
733  ! 3. Advertise import fields
734  ! 4. Advertise export fields
735  ! ----------------------------------------------------------------
736  !
737  ! 9. Switches :
738  !
739  ! 10. Source code :
740  !
741  !/ ------------------------------------------------------------------- /
742  !/
743  !/ ------------------------------------------------------------------- /
744  !/ Parameter list
745  !/
746  implicit none
747  type(esmf_gridcomp) :: gcomp
748  type(esmf_state) :: impstate
749  type(esmf_state) :: expstate
750  type(esmf_clock) :: extclock
751  integer,intent(out) :: rc
752  !/
753  !/ ------------------------------------------------------------------- /
754  !/ Local parameters
755  !/
756  character(ESMF_MAXSTR) :: cname
757  integer, parameter :: iwt=2
758  real(8) :: wstime, wftime
759  integer :: idsi, idso, idss, idst, idse
760  integer :: mpicomm = -99
761  logical :: configispresent
762  type(esmf_config) :: config
763  character(ESMF_MAXSTR) :: wrkdir = '.'
764  character(ESMF_MAXSTR) :: preamb = '.'
765  character(ESMF_MAXSTR) :: ifname = 'ww3_multi.inp'
766  logical :: lsep_ss = .true.
767  logical :: lsep_st = .true.
768  logical :: lsep_se = .true.
769  character(ESMF_MAXSTR) :: attstr
770  integer(ESMF_KIND_I4) :: yy,mm,dd,h,m,s
771  type(esmf_time) :: ttmp, cttmp
772  type(esmf_timeinterval) :: tstep, etstep
773  integer :: i, j, n, istep, imod, jmod
774  integer, allocatable :: cplmap(:,:)
775  logical :: includeobg, includeabg, includeibg
776  character(256) :: cvalue, logmsg
777  logical :: ispresent, isset
778  !
779  ! -------------------------------------------------------------------- /
780  ! Prep
781  !
782  rc = esmf_success
783  call esmf_vmwtime(wstime)
784  call esmf_gridcompget(gcomp, name=cname, rc=rc)
785  if (esmf_logfounderror(rc, passthru)) return
786  if (verbosity.gt.0) call esmf_logwrite(trim(cname)// &
787  ': entered InitializeP1', esmf_logmsg_info)
788  !
789  ! -------------------------------------------------------------------- /
790  ! Query mediator specific attributes
791  !
792  if (med_present) then
793  call nuopc_compattributeget(gcomp, name="ScalarFieldName", &
794  value=cvalue, ispresent=ispresent, isset=isset, rc=rc)
795  if (esmf_logfounderror(rc, passthru)) return
796  if (ispresent .and. isset) then
797  flds_scalar_name = trim(cvalue)
798  call esmf_logwrite(trim(cname)//': flds_scalar_name = '// &
799  trim(flds_scalar_name), esmf_logmsg_info, rc=rc)
800  if (esmf_logfounderror(rc, passthru)) return
801  end if
802 
803  call nuopc_compattributeget(gcomp, name="ScalarFieldCount", &
804  value=cvalue, ispresent=ispresent, isset=isset, rc=rc)
805  if (esmf_logfounderror(rc, passthru)) return
806  if (ispresent .and. isset) then
807  flds_scalar_num = esmf_utilstring2int(cvalue, rc=rc)
808  if (esmf_logfounderror(rc, passthru)) return
809  if (verbosity.gt.0) then
810  write(logmsg,*) flds_scalar_num
811  call esmf_logwrite(trim(cname)//': flds_scalar_num = '// &
812  trim(logmsg), esmf_logmsg_info, rc=rc)
813  if (esmf_logfounderror(rc, passthru)) return
814  end if
815  end if
816 
817  call nuopc_compattributeget(gcomp, name="ScalarFieldIdxGridNX", &
818  value=cvalue, ispresent=ispresent, isset=isset, rc=rc)
819  if (esmf_logfounderror(rc, passthru)) return
820  if (ispresent .and. isset) then
821  flds_scalar_index_nx = esmf_utilstring2int(cvalue, rc=rc)
822  if (esmf_logfounderror(rc, passthru)) return
823  if (verbosity.gt.0) then
824  write(logmsg,*) flds_scalar_index_nx
825  call esmf_logwrite(trim(cname)//': flds_scalar_index_nx = '// &
826  trim(logmsg), esmf_logmsg_info, rc=rc)
827  if (esmf_logfounderror(rc, passthru)) return
828  end if
829  end if
830 
831  call nuopc_compattributeget(gcomp, name="ScalarFieldIdxGridNY", &
832  value=cvalue, ispresent=ispresent, isset=isset, rc=rc)
833  if (esmf_logfounderror(rc, passthru)) return
834  if (ispresent .and. isset) then
835  flds_scalar_index_ny = esmf_utilstring2int(cvalue, rc=rc)
836  if (esmf_logfounderror(rc, passthru)) return
837  if (verbosity.gt.0) then
838  write(logmsg,*) flds_scalar_index_ny
839  call esmf_logwrite(trim(cname)//': flds_scalar_index_ny = '// &
840  trim(logmsg), esmf_logmsg_info, rc=rc)
841  if (esmf_logfounderror(rc, passthru)) return
842  end if
843  end if
844 
845  call nuopc_compattributeget(gcomp, name="mask_value_water", &
846  value=cvalue, ispresent=ispresent, isset=isset, rc=rc)
847  if (esmf_logfounderror(rc, passthru)) return
848  if (ispresent .and. isset) then
849  maskvaluewater = esmf_utilstring2int(cvalue, rc=rc)
850  if (esmf_logfounderror(rc, passthru)) return
851  if (verbosity.gt.0) then
852  write(logmsg,*) maskvaluewater
853  call esmf_logwrite(trim(cname)//': mask_value_water = '// &
854  trim(logmsg), esmf_logmsg_info, rc=rc)
855  if (esmf_logfounderror(rc, passthru)) return
856  end if
857  end if
858 
859  call nuopc_compattributeget(gcomp, name="mask_value_land", &
860  value=cvalue, ispresent=ispresent, isset=isset, rc=rc)
861  if (esmf_logfounderror(rc, passthru)) return
862  if (ispresent .and. isset) then
863  maskvalueland = esmf_utilstring2int(cvalue, rc=rc)
864  if (esmf_logfounderror(rc, passthru)) return
865  if (verbosity.gt.0) then
866  write(logmsg,*) maskvalueland
867  call esmf_logwrite(trim(cname)//': mask_value_land = '// &
868  trim(logmsg), esmf_logmsg_info, rc=rc)
869  if (esmf_logfounderror(rc, passthru)) return
870  end if
871  end if
872  end if
873  !
874  ! -------------------------------------------------------------------- /
875  ! 1. Initialization necessary for driver
876  !
877  ! 1.a Set global flag indicating that model is an ESMF Component
878  !
879  is_esmf_component = .true.
880  zerovalue = real(0,esmf_kind_rx)
881  missingvalue = real(0,esmf_kind_rx)
882  fillvalue = real(9.99e20,esmf_kind_rx)
883  !
884  !
885  ! 1.b Get MPI environment from ESMF VM and set WW3 MPI related variables
886  !
887  call esmf_gridcompget(gcomp, vm=vm, rc=rc)
888  if (esmf_logfounderror(rc, passthru)) return
889  call esmf_vmget(vm, petcount=npet, localpet=lpet, &
890  mpicommunicator=mpicomm, rc=rc)
891  if (esmf_logfounderror(rc, passthru)) return
892  nmproc = npet
893  improc = lpet + 1
894  nmpscr = 1
895  if ( improc .eq. nmpscr ) write (*,900)
896  !
897  ! 1.c Get background model info
898  !
899 #if defined(COAMPS)
900  call esmf_attributeget(gcomp, name="OcnBackground", &
901  value=attstr, defaultvalue="none", &
902  convention="COAMPS", purpose="General", rc=rc)
903  if (esmf_logfounderror(rc, passthru)) return
904  includeobg = trim(attstr).eq."model"
905  call esmf_attributeget(gcomp, name="AtmBackground", &
906  value=attstr, defaultvalue="none", &
907  convention="COAMPS", purpose="General", rc=rc)
908  if (esmf_logfounderror(rc, passthru)) return
909  includeabg = trim(attstr).eq."model"
910  call esmf_attributeget(gcomp, name="IceBackground", &
911  value=attstr, defaultvalue="none", &
912  convention="COAMPS", purpose="General", rc=rc)
913  if (esmf_logfounderror(rc, passthru)) return
914  includeibg = trim(attstr).eq."model"
915  call esmf_attributeget(gcomp, name="MissingValue", &
916  value=missingvalue, defaultvalue=real(0,esmf_kind_rx), &
917  convention="COAMPS", purpose="General", rc=rc)
918  if (esmf_logfounderror(rc, passthru)) return
919 #else
920  includeobg = .false.
921  includeabg = .false.
922  includeibg = .false.
923 #endif
924  !
925  ! 1.d Config input
926  !
927  call esmf_gridcompget(gcomp, configispresent=configispresent, rc=rc)
928  if (esmf_logfounderror(rc, passthru)) return
929  if (configispresent) then
930  call esmf_gridcompget(gcomp, config=config, rc=rc)
931  if (esmf_logfounderror(rc, passthru)) return
932  ! working directory
933  call esmf_configgetattribute(config, wrkdir, &
934  label=trim(cname)//'_work_dir:', default='.', rc=rc)
935  if (esmf_logfounderror(rc, passthru)) return
936  ! I/O options
937  call esmf_configgetattribute(config, ifname, &
938  label=trim(cname)//'_input_file_name:', &
939  default='ww3_multi.inp', rc=rc)
940  if (esmf_logfounderror(rc, passthru)) return
941  call esmf_configgetattribute(config, lsep_ss, &
942  label=trim(cname)//'_stdo_output_to_file:', default=.false., rc=rc)
943  if (esmf_logfounderror(rc, passthru)) return
944  call esmf_configgetattribute(config, lsep_st, &
945  label=trim(cname)//'_test_output_to_file:', default=.false., rc=rc)
946  if (esmf_logfounderror(rc, passthru)) return
947  call esmf_configgetattribute(config, lsep_se, &
948  label=trim(cname)//'_error_output_to_file:', default=.false., rc=rc)
949  if (esmf_logfounderror(rc, passthru)) return
950  ! export grid id
951  call esmf_configgetattribute(config, expgridid, &
952  label=trim(cname)//'_export_grid_id:', default=1, rc=rc)
953  if (esmf_logfounderror(rc, passthru)) return
954  ! realize all export flag
955  call esmf_configgetattribute(config, realizeallexport, &
956  label=trim(cname)//'_realize_all_export:', default=.false., rc=rc)
957  if (esmf_logfounderror(rc, passthru)) return
958  ! grid mask convention
959  call esmf_configgetattribute(config, maskvaluewater, &
960  label='mask_value_water:', default=default_mask_water, rc=rc)
961  if (esmf_logfounderror(rc, passthru)) return
962  call esmf_configgetattribute(config, maskvalueland, &
963  label='mask_value_land:', default=default_mask_land, rc=rc)
964  if (esmf_logfounderror(rc, passthru)) return
965  ! z-level file
966  call esmf_configgetattribute(config, zlfile, &
967  label=trim(cname)//'_zlevel_exp_file:', default='none', rc=rc)
968  if (esmf_logfounderror(rc, passthru)) return
969  endif
970  ! preamb = trim(wrkdir)//'/'
971  preamb = trim(preamb)//'/' !TODO: have separate paths for .inp, logs and data?
972  !
973  ! 1.e Set internal start/stop time from external start/stop time
974  !
975 
976  call esmf_clockget(extclock, starttime=ttmp, rc=rc)
977  if (esmf_logfounderror(rc, passthru)) return
978  call esmf_clockget(extclock, currtime=cttmp, rc=rc)
979  if (esmf_logfounderror(rc, passthru)) return
980  !
981  ! Adjust internal start time to currTime in case of delayed start
982  !
983  if ( cttmp.gt.ttmp ) ttmp=cttmp
984  call esmf_timeget(ttmp, yy=yy,mm=mm,dd=dd,h=h,m=m,s=s, rc=rc)
985  if (esmf_logfounderror(rc, passthru)) return
986  stime(1) = 10000*yy + 100*mm + dd
987  stime(2) = 10000*h + 100*m + s
988 
989  call esmf_clockget(extclock, stoptime=ttmp, rc=rc)
990  if (esmf_logfounderror(rc, passthru)) return
991  call esmf_timeget(ttmp, yy=yy,mm=mm,dd=dd,h=h,m=m,s=s, rc=rc)
992  if (esmf_logfounderror(rc, passthru)) return
993  etime(1) = 10000*yy + 100*mm + dd
994  etime(2) = 10000*h + 100*m + s
995  !
996  ! 1.f Identify available unit numbers
997  ! Each ESMF_UtilIOUnitGet is followed by an OPEN statement for that
998  ! unit so that subsequent ESMF_UtilIOUnitGet calls do not return the
999  ! the same unit. After getting all the available unit numbers, close
1000  ! the units since they will be opened within WMINIT.
1001  !
1002  call esmf_utiliounitget(idsi); open(unit=idsi, status='scratch');
1003  call esmf_utiliounitget(idso); open(unit=idso, status='scratch');
1004  call esmf_utiliounitget(idss); open(unit=idss, status='scratch');
1005  call esmf_utiliounitget(idst); open(unit=idst, status='scratch');
1006  call esmf_utiliounitget(idse); open(unit=idse, status='scratch');
1007  close(idsi); close(idso); close(idss); close(idst); close(idse);
1008  !
1009  ! 1.g Get merging option for regional coupling that domians does not
1010  ! overlap complately. This will blend the data coming from forcing with
1011  ! the data coming from coupling.
1012  !
1013  call nuopc_compattributeget(gcomp, name="merge_import", &
1014  value=attstr, ispresent=ispresent, isset=isset, rc=rc)
1015  if (esmf_logfounderror(rc, passthru)) return
1016  if (ispresent .and. isset) then
1017  if (trim(attstr) .eq. '.true.') then
1018  merge_import = .true.
1019  end if
1020  end if
1021  if (verbosity.gt.0) then
1022  write(logmsg,'(l)') merge_import
1023  call esmf_logwrite(trim(cname)//import = '// &
1024  trim(logmsg), ESMF_LOGMSG_INFO, rc=rc)
1025  if (ESMF_LogFoundError(rc, PASSTHRU)) return
1026  end if
1027  !
1028  ! -------------------------------------------------------------------- /
1029  ! 2. Initialization of all wave models / grids
1030  !
1031  ! 2.a Call into WMINIT
1032  !
1033 .not. if ( lsep_ss ) idss = stdo
1034 .not. if ( lsep_st ) idst = stdo
1035 .not. if ( lsep_se ) idse = stdo
1036 .eq. if ( trim(ifname)'ww3_multi.nml' ) then
1037  call wminitnml ( idsi, idso, idss, idst, idse, trim(ifname), &
1038  mpicomm, preamb=preamb )
1039  else
1040  call wminit ( idsi, idso, idss, idst, idse, trim(ifname), &
1041  mpicomm, preamb=preamb )
1042  endif
1043  !
1044  ! 2.b Check consistency between internal timestep and external
1045  ! timestep (coupling interval)
1046  !
1047  call ESMF_ClockGet(extClock, timeStep=etstep, rc=rc)
1048  if (ESMF_LogFoundError(rc, PASSTHRU)) return
1049  !
1050  ! 2.c Trap unsupported CPL input forcing settings
1051  !
1052 .lt. if ( any(inpmap0) ) then
1053 .gt. if ( nrgrd1 ) then
1054 .eq. if ( any(inpmap-999) ) then
1055  write (msg,'(a)') 'cpl input forcing defined on a '// &
1056  'native grid is not supported with multiple model grids'
1057 .eq. if ( improc nmpscr ) write (idse,'(a)') trim(msg)
1058  call ESMF_LogWrite(trim(msg), ESMF_LOGMSG_ERROR)
1059  rc = ESMF_FAILURE
1060  return
1061  endif
1062  endif
1063  allocate (cplmap(nrgrd,jfirst:8), stat=rc)
1064  if (ESMF_LogFoundAllocError(rc, PASSTHRU)) return
1065  jmod = minval(inpmap)
1066  cplmap = inpmap
1067 .lt. where ( inpmap0 ) cplmap = jmod
1068 .ne. if ( any(inpmapcplmap) ) then
1069  write (msg,'(a)') 'all cpl input forcing must be '// &
1070  'defined on the same grid'
1071 .eq. if ( improc nmpscr ) write (idse,'(a)') trim(msg)
1072  call ESMF_LogWrite(trim(msg), ESMF_LOGMSG_ERROR)
1073  rc = ESMF_FAILURE
1074  return
1075  endif
1076  deallocate (cplmap, stat=rc)
1077  if (ESMF_LogFoundDeallocError(rc, PASSTHRU)) return
1078  endif
1079  !
1080  ! -------------------------------------------------------------------- /
1081 import field list ! 3. Initialize
1082  !
1083  istep_import: do istep = 1, 2
1084 
1085 .eq. if ( istep2 ) then
1086  allocate ( impFieldName(numImpFields), &
1087  impFieldStdName(numImpFields), &
1088  impFieldInitRqrd(numImpFields), &
1089  impFieldActive(numImpFields), &
1090  impField(numImpFields), &
1091  stat=rc )
1092  if (ESMF_LogFoundAllocError(rc, PASSTHRU)) return
1093  allocate ( mbgFieldName(numImpFields), &
1094  mbgFieldStdName(numImpFields), &
1095  mbgFieldActive(numImpFields), &
1096  mbgField(numImpFields), &
1097  bmskField(numImpFields), &
1098  stat=rc )
1099  if (ESMF_LogFoundAllocError(rc, PASSTHRU)) return
1100  if (merge_import) then
1101  allocate (mmskCreated(numImpFields))
1102  allocate (mmskField(numImpFields))
1103  allocate (mdtField(numImpFields))
1104  mmskCreated(:) = .false.
1105  end if
1106  impFieldActive(:) = .false.
1107  endif
1108  i = 0
1109 
1110  i = i + 1
1111 .eq. if ( istep2 ) then
1112  j = 1
1113 .lt. impFieldActive(i) = any(inpmap(:,j)0)
1114  impFieldName(i) = 'seahgt'
1115  impFieldStdName(i) = 'sea_surface_height_above_sea_level'
1116  impFieldInitRqrd(i) = .true.
1117 .and. mbgFieldActive(i) = impFieldActive(i)includeObg
1118  endif
1119 
1120  i = i + 1
1121 .eq. if ( istep2 ) then
1122  j = 2
1123 .lt. impFieldActive(i) = any(inpmap(:,j)0)
1124  impFieldName(i) = 'uucurr'
1125  impFieldStdName(i) = 'surface_eastward_sea_water_velocity'
1126  impFieldInitRqrd(i) = .true.
1127 .and. mbgFieldActive(i) = impFieldActive(i)includeObg
1128  endif
1129 
1130  i = i + 1
1131 .eq. if ( istep2 ) then
1132  j = 2
1133 .lt. impFieldActive(i) = any(inpmap(:,j)0)
1134  impFieldName(i) = 'vvcurr'
1135  impFieldStdName(i) = 'surface_northward_sea_water_velocity'
1136  impFieldInitRqrd(i) = .true.
1137 .and. mbgFieldActive(i) = impFieldActive(i)includeObg
1138  endif
1139 
1140  i = i + 1
1141 .eq. if ( istep2 ) then
1142  j = 3
1143 .lt. impFieldActive(i) = any(inpmap(:,j)0)
1144  impFieldName(i) = 'uutrue'
1145  impFieldStdName(i) = 'eastward_wind_at_10m_height'
1146  impFieldInitRqrd(i) = .true.
1147 .and. mbgFieldActive(i) = impFieldActive(i)includeAbg
1148  endif
1149 
1150  i = i + 1
1151 .eq. if ( istep2 ) then
1152  j = 3
1153 .lt. impFieldActive(i) = any(inpmap(:,j)0)
1154  impFieldName(i) = 'vvtrue'
1155  impFieldStdName(i) = 'northward_wind_at_10m_height'
1156  impFieldInitRqrd(i) = .true.
1157 .and. mbgFieldActive(i) = impFieldActive(i)includeAbg
1158  endif
1159 
1160  i = i + 1
1161 .eq. if ( istep2 ) then
1162  j = 4
1163 .lt. impFieldActive(i) = any(inpmap(:,j)0)
1164  impFieldName(i) = 'seaice'
1165  impFieldStdName(i) = 'sea_ice_concentration'
1166  impFieldInitRqrd(i) = .true.
1167 .and. mbgFieldActive(i) = impFieldActive(i)includeIbg
1168  endif
1169 
1170  numImpFields = i
1171 import enddo istep_
1172 
1173 .not. noActiveImpFields = all(impFieldActive)
1174 
1175  do i = 1,numImpFields
1176  mbgFieldName(i) = 'mbg_'//trim(impFieldName(i))
1177  mbgFieldStdName(i) = 'mbg_'//trim(impFieldStdName(i))
1178  enddo
1179  !
1180  ! -------------------------------------------------------------------- /
1181  ! 4. Initialize export field list
1182  !
1183  istep_export: do istep = 1, 2
1184 
1185 .eq. if ( istep2 ) then
1186  allocate ( expFieldName(numExpFields), &
1187  expFieldStdName(numExpFields), &
1188  expFieldDim(numExpFields), &
1189  expFieldActive(numExpFields), &
1190  expField(numExpFields), &
1191  stat=rc )
1192  if (ESMF_LogFoundAllocError(rc, PASSTHRU)) return
1193  expFieldActive(:) = .false.
1194  endif
1195  i = 0
1196 
1197  i = i + 1
1198 .eq. if ( istep2 ) then
1199  expFieldName(i) = 'charno'
1200  expFieldStdName(i) = 'wave_induced_charnock_parameter'
1201  expFieldDim(i) = 2
1202  endif
1203 
1204  i = i + 1
1205 .eq. if ( istep2 ) then
1206  expFieldName(i) = 'z0rlen'
1207  expFieldStdName(i) = 'wave_z0_roughness_length'
1208  expFieldDim(i) = 2
1209  endif
1210 
1211  i = i + 1
1212 .eq. if ( istep2 ) then
1213  expFieldName(i) = 'uscurr'
1214  expFieldStdName(i) = 'eastward_stokes_drift_current'
1215  expFieldDim(i) = 3
1216  endif
1217 
1218  i = i + 1
1219 .eq. if ( istep2 ) then
1220  expFieldName(i) = 'vscurr'
1221  expFieldStdName(i) = 'northward_stokes_drift_current'
1222  expFieldDim(i) = 3
1223  endif
1224 
1225  i = i + 1
1226 .eq. if ( istep2 ) then
1227  expFieldName(i) = 'x1pstk'
1228  expFieldStdName(i) = 'eastward_partitioned_stokes_drift_1'
1229  expFieldDim(i) = 2
1230  endif
1231 
1232  i = i + 1
1233 .eq. if ( istep2 ) then
1234  expFieldName(i) = 'y1pstk'
1235  expFieldStdName(i) = 'northward_partitioned_stokes_drift_1'
1236  expFieldDim(i) = 2
1237  endif
1238 
1239  i = i + 1
1240 .eq. if ( istep2 ) then
1241  expFieldName(i) = 'x2pstk'
1242  expFieldStdName(i) = 'eastward_partitioned_stokes_drift_2'
1243  expFieldDim(i) = 2
1244  endif
1245 
1246  i = i + 1
1247 .eq. if ( istep2 ) then
1248  expFieldName(i) = 'y2pstk'
1249  expFieldStdName(i) = 'northward_partitioned_stokes_drift_2'
1250  expFieldDim(i) = 2
1251  endif
1252 
1253  i = i + 1
1254 .eq. if ( istep2 ) then
1255  expFieldName(i) = 'x3pstk'
1256  expFieldStdName(i) = 'eastward_partitioned_stokes_drift_3'
1257  expFieldDim(i) = 2
1258  endif
1259 
1260  i = i + 1
1261 .eq. if ( istep2 ) then
1262  expFieldName(i) = 'y3pstk'
1263  expFieldStdName(i) = 'northward_partitioned_stokes_drift_3'
1264  expFieldDim(i) = 2
1265  endif
1266 
1267  i = i + 1
1268 .eq. if ( istep2 ) then
1269  expFieldName(i) = 'wbcuru'
1270  expFieldStdName(i) = 'eastward_wave_bottom_current'
1271  expFieldDim(i) = 2
1272  endif
1273 
1274  i = i + 1
1275 .eq. if ( istep2 ) then
1276  expFieldName(i) = 'wbcurv'
1277  expFieldStdName(i) = 'northward_wave_bottom_current'
1278  expFieldDim(i) = 2
1279  endif
1280 
1281  i = i + 1
1282 .eq. if ( istep2 ) then
1283  expFieldName(i) = 'wbcurp'
1284  expFieldStdName(i) = 'wave_bottom_current_period'
1285  expFieldDim(i) = 2
1286  endif
1287 
1288  i = i + 1
1289 .eq. if ( istep2 ) then
1290  expFieldName(i) = 'wavsuu'
1291  expFieldStdName(i) = 'eastward_wave_radiation_stress'
1292  expFieldDim(i) = 2
1293  endif
1294 
1295  i = i + 1
1296 .eq. if ( istep2 ) then
1297  expFieldName(i) = 'wavsuv'
1298  expFieldStdName(i) = 'eastward_northward_wave_radiation_stress'
1299  expFieldDim(i) = 2
1300  endif
1301 
1302  i = i + 1
1303 .eq. if ( istep2 ) then
1304  expFieldName(i) = 'wavsvv'
1305  expFieldStdName(i) = 'northward_wave_radiation_stress'
1306  expFieldDim(i) = 2
1307  endif
1308 
1309  if (med_present) then
1310  i = i + 1
1311 .eq. if ( istep2 ) then
1312  expFieldName(i) = trim(flds_scalar_name)
1313  expFieldStdName(i) = trim(flds_scalar_name)
1314  expFieldDim(i) = 1
1315  endif
1316  endif
1317 
1318  numExpFields = i
1319  enddo istep_export
1320 
1321 .not. noActiveExpFields = all(expFieldActive)
1322  !
1323  ! -------------------------------------------------------------------- /
1324 import fields ! 5. Advertise
1325  !
1326 import fields ! 5.a Advertise active
1327  !
1328  n = 0
1329  do i = 1,numImpFields
1330 .not. if (impFieldActive(i)) cycle
1331  n = n + 1
1332  call NUOPC_Advertise(impState, &
1333  trim(impFieldStdName(i)), name=trim(impFieldName(i)), rc=rc)
1334  if (ESMF_LogFoundError(rc, PASSTHRU)) return
1335 .not. if (mbgFieldActive(i)) cycle
1336  n = n + 1
1337  call NUOPC_Advertise(impState, &
1338  trim(mbgFieldStdName(i)), name=trim(mbgFieldName(i)), rc=rc)
1339  if (ESMF_LogFoundError(rc, PASSTHRU)) return
1340  enddo
1341  !
1342 import fields ! 5.b Report advertised
1343  !
1344  write(msg,'(a,i0,a)') trim(cname)// &
1345  ': list of advertised import fields(',n,'):'
1346  call ESMF_LogWrite(trim(msg), ESMF_LOGMSG_INFO)
1347  write(msg,'(a,a5,a,a10,a3,a)') trim(cname)// &
1348  ': ','index',' ','name',' ','standardname'
1349  call ESMF_LogWrite(trim(msg), ESMF_LOGMSG_INFO)
1350  n = 0
1351  do i = 1,numImpFields
1352 .not. if (impFieldActive(i)) cycle
1353  n = n + 1
1354  write(msg,'(a,i5,a,a10,a3,a)') trim(cname)//': ',n, &
1355  ' ',trim(impFieldName(i)),' ',trim(impFieldStdName(i))
1356  call ESMF_LogWrite(trim(msg), ESMF_LOGMSG_INFO)
1357 .not. if (mbgFieldActive(i)) cycle
1358  n = n + 1
1359  write(msg,'(a,i5,a,a10,a3,a)') trim(cname)//': ',n, &
1360  ' ',trim(mbgFieldName(i)),' ',trim(mbgFieldStdName(i))
1361  call ESMF_LogWrite(trim(msg), ESMF_LOGMSG_INFO)
1362  enddo
1363  !
1364  ! -------------------------------------------------------------------- /
1365  ! 6. Advertise export fields
1366  !
1367  ! 6.a Advertise all export fields
1368  !
1369  do i = 1,numExpFields
1370  call NUOPC_Advertise(expState, &
1371  trim(expFieldStdName(i)), name=trim(expFieldName(i)), rc=rc)
1372  if (ESMF_LogFoundError(rc, PASSTHRU)) return
1373  enddo
1374  !
1375  ! 6.b Report advertised export fields
1376  !
1377  write(msg,'(a,i0,a)') trim(cname)// &
1378  ': list of advertised export fields(',numExpFields,'):'
1379  call ESMF_LogWrite(trim(msg), ESMF_LOGMSG_INFO)
1380  write(msg,'(a,a5,a,a10,a3,a)') trim(cname)// &
1381  ': ','index',' ','name',' ','standardname'
1382  call ESMF_LogWrite(trim(msg), ESMF_LOGMSG_INFO)
1383  do i = 1,numExpFields
1384  write(msg,'(a,i5,a,a10,a3,a)') trim(cname)//': ',i, &
1385  ' ',trim(expFieldName(i)),' ',trim(expFieldStdName(i))
1386  call ESMF_LogWrite(trim(msg), ESMF_LOGMSG_INFO)
1387  enddo
1388  !
1389  ! -------------------------------------------------------------------- /
1390  ! Post
1391  !
1392  rc = ESMF_SUCCESS
1393  call ESMF_VMWtime(wftime)
1394  wtime(iwt) = wtime(iwt) + wftime - wstime
1395  wtcnt(iwt) = wtcnt(iwt) + 1
1396 .gt. if (verbosity0) call ESMF_LogWrite(trim(cname)// &
1397  ': leaving initializep1', ESMF_LOGMSG_INFO)
1398  !
1399  ! -------------------------------------------------------------------- /
1400  ! Formats
1401  !
1402 900 format (/15x,' *** wavewatch iii multi-grid shell *** '/ &
1403  15x,'================================================='/)
1404  !/
1405  !/ End of InitializeP1 ----------------------------------------------- /
1406  !/
1407  end subroutine InitializeP1
1408  !/ ------------------------------------------------------------------- /
1409  !/
1410 #undef METHOD
1411 #define METHOD "InitializeP3"
1412  !>
1413  !> @brief Initialize wave model (phase 3).
1414  !>
1415 import and export states. !> @details Realize fields in
1416  !>
1417  !> @param gcomp Gridded component.
1418 Import state. !> @param impState
1419  !> @param expState Export state.
1420  !> @param extClock External clock.
1421  !> @param[out] rc Return code.
1422  !>
1423  !> @author T. J. Campbell
1424  !> @author A. J. van der Westhuysen
1425  !> @date 09-Aug-2017
1426  !>
1427  subroutine InitializeP3 ( gcomp, impState, expState, extClock, rc )
1428  !/
1429  !/ +-----------------------------------+
1430  !/ | WAVEWATCH III NOAA/NCEP |
1431  !/ | T. J. Campbell, NRL |
1432  !/ | A. J. van der Westhuysen |
1433  !/ | FORTRAN 90 |
1434  !/ | Last update : 09-Aug-2017 |
1435  !/ +-----------------------------------+
1436  !/
1437  !/ 20-Jan-2017 : Origination. ( version 6.02 )
1438  !/ 09-Aug-2017 : Update 3D export field setup ( version 6.03 )
1439  !/ 28-Feb-2018 : Modifications for unstruc meshes ( version 6.06 )
1440  !/
1441  ! 1. Purpose :
1442  !
1443  ! Initialize wave model (phase 3)
1444 import and export states. ! * Realize fields in
1445  !
1446  ! 2. Method :
1447  !
1448  ! 3. Parameters :
1449  !
1450  ! Parameter list
1451  ! ----------------------------------------------------------------
1452  ! gcomp Type I/O Gridded component
1453 Import state ! impState Type I/O
1454  ! expState Type I/O Export state
1455  ! extClock Type I External clock
1456  ! rc Int. O Return code
1457  ! ----------------------------------------------------------------
1458  !
1459  ! 4. Subroutines used :
1460  !
1461  ! Name Type Module Description
1462  ! ----------------------------------------------------------------
1463  ! WMINIT Subr. WMINITMD Wave model initialization
1464  ! WMINITNML Subr. WMINITMD Wave model initialization
1465  ! ----------------------------------------------------------------
1466  !
1467  ! 5. Called by :
1468  !
1469  ! 6. Error messages :
1470  !
1471  ! 7. Remarks :
1472  !
1473  ! 8. Structure :
1474  !
1475  ! 9. Switches :
1476  !
1477  ! 10. Source code :
1478  !
1479  !/ ------------------------------------------------------------------- /
1480  !/
1481  !/ ------------------------------------------------------------------- /
1482  !/ Parameter list
1483  !/
1484  implicit none
1485  type(ESMF_GridComp) :: gcomp
1486  type(ESMF_State) :: impState
1487  type(ESMF_State) :: expState
1488  type(ESMF_Clock) :: extClock
1489  integer,intent(out) :: rc
1490  !/
1491  !/ ------------------------------------------------------------------- /
1492  !/ Local parameters
1493  !/
1494  character(ESMF_MAXSTR) :: cname
1495  integer, parameter :: iwt=3
1496  real(8) :: wstime, wftime
1497  integer :: i1, i2, i3, i, n
1498  logical :: isConnected
1499  type(ESMF_DistGrid) :: distgrid
1500  type(ESMF_Grid) :: grid_scalar
1501  !
1502  ! -------------------------------------------------------------------- /
1503  ! Prep
1504  !
1505  rc = ESMF_SUCCESS
1506  call ESMF_VMWtime(wstime)
1507  call ESMF_GridCompGet(gcomp, name=cname, rc=rc)
1508  if (ESMF_LogFoundError(rc, PASSTHRU)) return
1509 .gt. if (verbosity0) call ESMF_LogWrite(trim(cname)// &
1510  ': entered initializep3', ESMF_LOGMSG_INFO)
1511  !
1512  ! -------------------------------------------------------------------- /
1513 import fields ! 1. Realize active
1514  !
1515 import fields ! 1.a Create ESMF grid for
1516  !
1517 .eq..or..eq. if ( (GTYPERLGTYPE)(GTYPECLGTYPE) ) then
1518  write(msg,'(a)') trim(cname)// &
1519  ': creating import grid for reg/curvilinear mode'
1520  call ESMF_LogWrite(trim(msg), ESMF_LOGMSG_INFO)
1521  call CreateImpGrid( gcomp, rc=rc )
1522  if (ESMF_LogFoundError(rc, PASSTHRU)) return
1523 .eq. elseif (GTYPEUNGTYPE) then
1524  write(msg,'(a)') trim(cname)// &
1525  ': creating import mesh for unstructured mode'
1526  call ESMF_LogWrite(trim(msg), ESMF_LOGMSG_INFO)
1527  call CreateImpMesh( gcomp, rc=rc )
1528  if (ESMF_LogFoundError(rc, PASSTHRU)) return
1529  endif
1530  !
1531 import fields and realize ! 1.b Create
1532  !
1533  n = 0
1534  do i = 1,numImpFields
1535 .not. if (impFieldActive(i)) cycle
1536  n = n + 1
1537 .eq..or..eq. if ( (GTYPERLGTYPE)(GTYPECLGTYPE) ) then
1538  impField(i) = ESMF_FieldCreate( impGrid, impArraySpec2D, &
1539  totalLWidth=impHaloLWidth, totalUWidth=impHaloUWidth, &
1540  staggerLoc=impStaggerLoc, indexFlag=impIndexFlag, &
1541  name=trim(impFieldName(i)), rc=rc )
1542  if (ESMF_LogFoundError(rc, PASSTHRU)) return
1543  call FieldFill( impField(i), zeroValue, rc=rc )
1544  if (ESMF_LogFoundError(rc, PASSTHRU)) return
1545 .eq. elseif (GTYPEUNGTYPE) then
1546  impField(i) = ESMF_FieldCreate( impMesh, &
1547  typekind=ESMF_TYPEKIND_RX, name=trim(impFieldName(i)), rc=rc)
1548  if (ESMF_LogFoundError(rc, PASSTHRU)) return
1549  call FieldFill( impField(i), zeroValue, rc=rc )
1550  if (ESMF_LogFoundError(rc, PASSTHRU)) return
1551  endif
1552  call NUOPC_Realize( impState, impField(i), rc=rc )
1553  if (ESMF_LogFoundError(rc, PASSTHRU)) return
1554 .eq..or..eq. if ( (GTYPERLGTYPE)(GTYPECLGTYPE) ) then
1555  if (merge_import) then
1556  mmskField(i) = ESMF_FieldCreate( impGrid, impArraySpec2D, &
1557  totalLWidth=impHaloLWidth, totalUWidth=impHaloUWidth, &
1558  staggerLoc=impStaggerLoc, indexFlag=impIndexFlag, &
1559  name='mmsk_'//trim(impFieldName(i)), rc=rc )
1560  if (ESMF_LogFoundError(rc, PASSTHRU)) return
1561  call FieldFill( mmskField(i), zeroValue, rc=rc )
1562  if (ESMF_LogFoundError(rc, PASSTHRU)) return
1563  mdtField(i) = ESMF_FieldCreate( impGrid, impArraySpec2D, &
1564  totalLWidth=impHaloLWidth, totalUWidth=impHaloUWidth, &
1565  staggerLoc=impStaggerLoc, indexFlag=impIndexFlag, &
1566  name='mdt_'//trim(impFieldName(i)), rc=rc )
1567  if (ESMF_LogFoundError(rc, PASSTHRU)) return
1568  call FieldFill( mdtField(i), zeroValue, rc=rc )
1569  if (ESMF_LogFoundError(rc, PASSTHRU)) return
1570  end if
1571 .not. if (mbgFieldActive(i)) cycle
1572  n = n + 1
1573  mbgField(i) = ESMF_FieldCreate( impGrid, impArraySpec2D, &
1574  totalLWidth=impHaloLWidth, totalUWidth=impHaloUWidth, &
1575  staggerLoc=impStaggerLoc, indexFlag=impIndexFlag, &
1576  name=trim(mbgFieldName(i)), rc=rc )
1577  if (ESMF_LogFoundError(rc, PASSTHRU)) return
1578  call FieldFill( mbgField(i), zeroValue, rc=rc )
1579  if (ESMF_LogFoundError(rc, PASSTHRU)) return
1580  call NUOPC_Realize( impState, mbgField(i), rc=rc )
1581  if (ESMF_LogFoundError(rc, PASSTHRU)) return
1582  bmskField(i) = ESMF_FieldCreate( impGrid, impArraySpec2D, &
1583  totalLWidth=impHaloLWidth, totalUWidth=impHaloUWidth, &
1584  staggerLoc=impStaggerLoc, indexFlag=impIndexFlag, &
1585  name='bmsk_'//trim(impFieldName(i)), rc=rc )
1586  if (ESMF_LogFoundError(rc, PASSTHRU)) return
1587  endif
1588  enddo
1589  !
1590 import fields ! 1.c Report realized
1591  !
1592  write(msg,'(a,i0,a)') trim(cname)// &
1593  ': list of realized import fields(',n,'):'
1594  call ESMF_LogWrite(trim(msg), ESMF_LOGMSG_INFO)
1595  write(msg,'(a,a5,a,a10,a3,a)') trim(cname)// &
1596  ': ','index',' ','name',' ','standardname'
1597  call ESMF_LogWrite(trim(msg), ESMF_LOGMSG_INFO)
1598  n = 0
1599  do i = 1,numImpFields
1600 .not. if (impFieldActive(i)) cycle
1601  n = n + 1
1602  write(msg,'(a,i5,a,a10,a3,a)') trim(cname)//': ',n, &
1603  ' ',trim(impFieldName(i)),' ',trim(impFieldStdName(i))
1604  call ESMF_LogWrite(trim(msg), ESMF_LOGMSG_INFO)
1605 .not. if (mbgFieldActive(i)) cycle
1606  n = n + 1
1607  write(msg,'(a,i5,a,a10,a3,a)') trim(cname)//': ',n, &
1608  ' ',trim(mbgFieldName(i)),' ',trim(mbgFieldStdName(i))
1609  call ESMF_LogWrite(trim(msg), ESMF_LOGMSG_INFO)
1610  enddo
1611  !
1612  ! -------------------------------------------------------------------- /
1613  ! 2. Realize active export fields
1614  !
1615  ! 2.a Set connected export fields as active and remove unconnected
1616  ! If realizeAllExport, then set all fields as active and realize.
1617  !
1618  do i = 1,numExpFields
1619  isConnected = NUOPC_IsConnected(expState, &
1620  expFieldName(i), rc=rc)
1621  if (ESMF_LogFoundError(rc, PASSTHRU)) return
1622 .or. expFieldActive(i) = isConnected realizeAllExport
1623  if (expFieldActive(i)) noActiveExpFields = .false.
1624 .not. if (expFieldActive(i)) then
1625  call ESMF_StateRemove(expState, (/expFieldName(i)/), rc=rc)
1626  if (ESMF_LogFoundError(rc, PASSTHRU)) return
1627  write(msg,fmt="(a,l)") trim(cname)//': '//trim(expFieldName(i)), expFieldActive(i)
1628  call ESMF_LogWrite(trim(msg), ESMF_LOGMSG_INFO)
1629  endif
1630  enddo
1631  !
1632  ! 2.b Create ESMF grid for export fields
1633  !
1634 .eq..or..eq. if ( (GTYPERLGTYPE)(GTYPECLGTYPE) ) then
1635  write(msg,'(a)') trim(cname)// &
1636  ': creating export grid for reg/curvilinear mode'
1637  call CreateExpGrid( gcomp, rc=rc )
1638  if (ESMF_LogFoundError(rc, PASSTHRU)) return
1639 .eq. elseif (GTYPEUNGTYPE) then
1640  write(msg,'(a)') trim(cname)// &
1641  ': creating export mesh for unstructured mode'
1642  call ESMF_LogWrite(trim(msg), ESMF_LOGMSG_INFO)
1643  call CreateExpMesh( gcomp, rc=rc )
1644  if (ESMF_LogFoundError(rc, PASSTHRU)) return
1645  endif
1646  !
1647  ! 2.c Create active export fields and realize
1648  !
1649  n = 0
1650  do i = 1,numExpFields
1651 .not. if (expFieldActive(i)) cycle
1652  n = n + 1
1653 .eq..or..eq. if ( (GTYPERLGTYPE)(GTYPECLGTYPE) ) then
1654  if (trim(expFieldName(i)) == trim(flds_scalar_name)) then
1655  distgrid = ESMF_DistGridCreate(minIndex=(/1/), maxIndex=(/1/), rc=rc)
1656  if (ESMF_LogFoundError(rc, PASSTHRU)) return
1657  grid_scalar = ESMF_GridCreate(distgrid, rc=rc)
1658  if (ESMF_LogFoundError(rc, PASSTHRU)) return
1659  expField(i) = ESMF_FieldCreate(grid_scalar, typekind=ESMF_TYPEKIND_R8, &
1660  name=trim(expFieldName(i)), ungriddedLBound=(/1/), &
1661  ungriddedUBound=(/flds_scalar_num/), gridToFieldMap=(/2/), rc=rc)
1662  if (ESMF_LogFoundError(rc, PASSTHRU)) return
1663  else
1664 .eq. if ( expFieldDim(i)3 ) then
1665  expField(i) = ESMF_FieldCreate( expGrid, expArraySpec3D, &
1666  totalLWidth=expHaloLWidth, totalUWidth=expHaloUWidth, &
1667  gridToFieldMap=(/2,3/), ungriddedLBound=(/1/), ungriddedUBound=(/nz/), &
1668  staggerLoc=expStaggerLoc, name=trim(expFieldName(i)), rc=rc )
1669  if (ESMF_LogFoundError(rc, PASSTHRU)) return
1670  else
1671  expField(i) = ESMF_FieldCreate( expGrid, expArraySpec2D, &
1672  totalLWidth=expHaloLWidth, totalUWidth=expHaloUWidth, &
1673  staggerLoc=expStaggerLoc, name=trim(expFieldName(i)), rc=rc )
1674  if (ESMF_LogFoundError(rc, PASSTHRU)) return
1675  endif
1676  call FieldFill( expField(i), zeroValue, rc=rc )
1677  if (ESMF_LogFoundError(rc, PASSTHRU)) return
1678  endif
1679 .eq. elseif (GTYPEUNGTYPE) then
1680  expField(i) = ESMF_FieldCreate( expMesh, &
1681  typekind=ESMF_TYPEKIND_RX, name=trim(expFieldName(i)), rc=rc)
1682  if (ESMF_LogFoundError(rc, PASSTHRU)) return
1683  call FieldFill( expField(i), zeroValue, rc=rc )
1684  if (ESMF_LogFoundError(rc, PASSTHRU)) return
1685  endif
1686  call NUOPC_Realize( expState, expField(i), rc=rc )
1687  if (ESMF_LogFoundError(rc, PASSTHRU)) return
1688  enddo
1689  !
1690  ! 2.d Report realized export fields
1691  !
1692  write(msg,'(a,i0,a)') trim(cname)// &
1693  ': list of realized export fields(',n,'):'
1694  call ESMF_LogWrite(trim(msg), ESMF_LOGMSG_INFO)
1695  write(msg,'(a,a5,a,a10,a3,a)') trim(cname)// &
1696  ': ','index',' ','name',' ','standardname'
1697  call ESMF_LogWrite(trim(msg), ESMF_LOGMSG_INFO)
1698  n = 0
1699  do i = 1,numExpFields
1700 .not. if (expFieldActive(i)) cycle
1701  n = n + 1
1702  write(msg,'(a,i5,a,a10,a3,a)') trim(cname)//': ',n, &
1703  ' ',trim(expFieldName(i)),' ',trim(expFieldStdName(i))
1704  call ESMF_LogWrite(trim(msg), ESMF_LOGMSG_INFO)
1705  enddo
1706  !
1707  ! 2.e Set W3OUTG flags needed for calculating export fields
1708  !
1709 #ifdef USE_W3OUTG_FOR_EXPORT
1710  call w3seto ( expGridID, mdse, mdst )
1711 
1712  i1 = FieldIndex( expFieldName, 'uscurr', rc )
1713  if (ESMF_LogFoundError(rc, PASSTHRU)) return
1714  i2 = FieldIndex( expFieldName, 'vscurr', rc )
1715  if (ESMF_LogFoundError(rc, PASSTHRU)) return
1716 .and. if ( expFieldActive(i1) &
1717  expFieldActive(i2) ) then
1718  flogr2(6,8) = .true. !Spectrum of surface Stokes drift
1719 .le. if ( us3df(1) 0 ) then
1720  msg = trim(cname)//': stokes drift export using w3outg'// &
1721  ' requires setting us3d=1 (ww3_grid.inp: outs namelist)'
1722  call ESMF_LogWrite(trim(msg), ESMF_LOGMSG_ERROR)
1723  rc = ESMF_FAILURE
1724  return
1725  endif
1726  endif
1727 
1728  i1 = FieldIndex( expFieldName, 'wbcuru', rc )
1729  if (ESMF_LogFoundError(rc, PASSTHRU)) return
1730  i2 = FieldIndex( expFieldName, 'wbcurv', rc )
1731  if (ESMF_LogFoundError(rc, PASSTHRU)) return
1732  i3 = FieldIndex( expFieldName, 'wbcurp', rc )
1733  if (ESMF_LogFoundError(rc, PASSTHRU)) return
1734 .and. if ( expFieldActive(i1) &
1735 .and. expFieldActive(i2) &
1736  expFieldActive(i3) ) then
1737  flogr2(7,1) = .true. !Near bottom rms amplitudes
1738  flogr2(7,2) = .true. !Near bottom rms velocities
1739  endif
1740 
1741  i1 = FieldIndex( expFieldName, 'wavsuu', rc )
1742  if (ESMF_LogFoundError(rc, PASSTHRU)) return
1743  i2 = FieldIndex( expFieldName, 'wavsuv', rc )
1744  if (ESMF_LogFoundError(rc, PASSTHRU)) return
1745  i3 = FieldIndex( expFieldName, 'wavsvv', rc )
1746  if (ESMF_LogFoundError(rc, PASSTHRU)) return
1747 .and. if ( expFieldActive(i1) &
1748 .and. expFieldActive(i2) &
1749  expFieldActive(i3) ) then
1750  flogr2(6,1) = .true. !Radiation stresses
1751  endif
1752 #endif
1753  !
1754  ! -------------------------------------------------------------------- /
1755  ! Post
1756  !
1757  rc = ESMF_SUCCESS
1758  call ESMF_VMWtime(wftime)
1759  wtime(iwt) = wtime(iwt) + wftime - wstime
1760  wtcnt(iwt) = wtcnt(iwt) + 1
1761 .gt. if (verbosity0) call ESMF_LogWrite(trim(cname)// &
1762  ': leaving initializep3', ESMF_LOGMSG_INFO)
1763  !/
1764  !/ End of InitializeP3 ----------------------------------------------- /
1765  !/
1766  end subroutine InitializeP3
1767  !/ ------------------------------------------------------------------- /
1768  !/
1769 #undef METHOD
1770 #define METHOD "Finalize"
1771  !>
1772  !> @brief Finalize wave model.
1773  !>
1774  !> @param gcomp Gridded component.
1775  !> @param[out] rc Return code.
1776  !>
1777  !> @author T. J. Campbell @date 09-Aug-2017
1778  !>
1779  subroutine Finalize ( gcomp, rc )
1780  !/
1781  !/ +-----------------------------------+
1782  !/ | WAVEWATCH III NOAA/NCEP |
1783  !/ | T. J. Campbell, NRL |
1784  !/ | FORTRAN 90 |
1785  !/ | Last update : 09-Aug-2017 |
1786  !/ +-----------------------------------+
1787  !/
1788  !/ 20-Jan-2017 : Origination. ( version 6.02 )
1789  !/ 09-Aug-2017 : Add clean up of local allocations ( version 6.03 )
1790  !/
1791  ! 1. Purpose :
1792  !
1793  ! Finalize wave model
1794  !
1795  ! 2. Method :
1796  !
1797  ! 3. Parameters :
1798  !
1799  ! Parameter list
1800  ! ----------------------------------------------------------------
1801  ! gcomp Type I/O Gridded component
1802  ! rc Int. O Return code
1803  ! ----------------------------------------------------------------
1804  !
1805  ! 4. Subroutines used :
1806  !
1807  ! Name Type Module Description
1808  ! ----------------------------------------------------------------
1809  ! WMFINL Subr. WMFINLMD Wave model finalization
1810  ! ----------------------------------------------------------------
1811  !
1812  ! 5. Called by :
1813  !
1814  ! 6. Error messages :
1815  !
1816  ! 7. Remarks :
1817  !
1818  ! 8. Structure :
1819  !
1820  ! 9. Switches :
1821  !
1822  ! 10. Source code :
1823  !
1824  !/ ------------------------------------------------------------------- /
1825  !/
1826  !/ ------------------------------------------------------------------- /
1827  !/ Parameter list
1828  !/
1829  implicit none
1830  type(ESMF_GridComp) :: gcomp
1831  integer,intent(out) :: rc
1832  !/
1833  !/ ------------------------------------------------------------------- /
1834  !/ Local parameters
1835  !/
1836  character(ESMF_MAXSTR) :: cname
1837  integer, parameter :: iwt=6
1838  real(8) :: wstime, wftime
1839  integer :: i
1840  !
1841  ! -------------------------------------------------------------------- /
1842  ! Prep
1843  !
1844  rc = ESMF_SUCCESS
1845  call ESMF_VMWtime(wstime)
1846  call ESMF_GridCompGet(gcomp, name=cname, rc=rc)
1847  if (ESMF_LogFoundError(rc, PASSTHRU)) return
1848 .gt. if (verbosity0) call ESMF_LogWrite(trim(cname)// &
1849  ': entered finalize', ESMF_LOGMSG_INFO)
1850  !
1851  ! -------------------------------------------------------------------- /
1852  ! 1. Finalize the wave model
1853  !
1854  call wmfinl
1855  !
1856  ! -------------------------------------------------------------------- /
1857  ! 2. Clean up ESMF data structures
1858  !
1859 Import field and grid stuff ! 2.a
1860  !
1861 .not. if ( noActiveImpFields ) then
1862 
1863  do i = 1,numImpFields
1864 .not. if (impFieldActive(i)) cycle
1865  call ESMF_FieldDestroy(impField(i), rc=rc)
1866  if (ESMF_LogFoundError(rc, PASSTHRU)) return
1867  if (merge_import) then
1868  call ESMF_FieldDestroy(mdtField(i), rc=rc)
1869  if (ESMF_LogFoundError(rc, PASSTHRU)) return
1870  call ESMF_FieldDestroy(mmskField(i), rc=rc)
1871  if (ESMF_LogFoundError(rc, PASSTHRU)) return
1872  end if
1873 .not. if (mbgFieldActive(i)) cycle
1874  call ESMF_FieldDestroy(mbgField(i), rc=rc)
1875  if (ESMF_LogFoundError(rc, PASSTHRU)) return
1876  call ESMF_FieldDestroy(bmskField(i), rc=rc)
1877  if (ESMF_LogFoundError(rc, PASSTHRU)) return
1878  enddo
1879 
1880 .eq..or..eq. if ( (GTYPERLGTYPE)(GTYPECLGTYPE) ) then
1881  call ESMF_FieldHaloRelease(impHaloRH, rc=rc)
1882  if (ESMF_LogFoundError(rc, PASSTHRU)) return
1883 
1884  call ESMF_GridDestroy(impGrid, rc=rc)
1885  if (ESMF_LogFoundError(rc, PASSTHRU)) return
1886 
1887 .eq. elseif (GTYPEUNGTYPE) then
1888  !AW call ESMF_GridDestroy(impMesh, rc=rc)
1889  !AW if (ESMF_LogFoundError(rc, PASSTHRU)) return
1890  endif
1891 
1892  endif
1893 
1894  deallocate (impFieldName, &
1895  impFieldStdName, &
1896  impFieldInitRqrd, &
1897  impFieldActive, &
1898  impField, &
1899  stat=rc)
1900  if (ESMF_LogFoundDeallocError(rc, PASSTHRU)) return
1901 
1902  deallocate (mbgFieldName, &
1903  mbgFieldStdName, &
1904  mbgFieldActive, &
1905  mbgField, &
1906  bmskField, &
1907  stat=rc)
1908  if (ESMF_LogFoundDeallocError(rc, PASSTHRU)) return
1909 
1910  if (merge_import) then
1911  deallocate(mmskCreated, &
1912  mmskField, &
1913  mdtField, &
1914  stat=rc)
1915  if (ESMF_LogFoundDeallocError(rc, PASSTHRU)) return
1916  end if
1917  !
1918  ! 2.b Export field and grid stuff
1919  !
1920 .not. if ( noActiveExpFields ) then
1921 
1922  do i = 1,numExpFields
1923 .not. if (expFieldActive(i)) cycle
1924  call ESMF_FieldDestroy(expField(i), rc=rc)
1925  if (ESMF_LogFoundError(rc, PASSTHRU)) return
1926  enddo
1927 
1928 .eq..or..eq. if ( (GTYPERLGTYPE)(GTYPECLGTYPE) ) then
1929  call ESMF_FieldHaloRelease(expHaloRH, rc=rc)
1930  if (ESMF_LogFoundError(rc, PASSTHRU)) return
1931 
1932  call ESMF_GridDestroy(expGrid, rc=rc)
1933  if (ESMF_LogFoundError(rc, PASSTHRU)) return
1934 
1935 .eq. elseif (GTYPEUNGTYPE) then
1936  !AW call ESMF_GridDestroy(expMesh, rc=rc)
1937  !AW if (ESMF_LogFoundError(rc, PASSTHRU)) return
1938  endif
1939 
1940  endif
1941 
1942  deallocate (expFieldName, &
1943  expFieldStdName, &
1944  expFieldDim, &
1945  expFieldActive, &
1946  expField, &
1947  stat=rc)
1948  if (ESMF_LogFoundDeallocError(rc, PASSTHRU)) return
1949  !
1950  ! 2.c Native field and grid stuff
1951  !
1952 .not. if ( noActiveExpFields ) then
1953 
1954  call ESMF_FieldRedistRelease(n2eRH, rc=rc)
1955  if (ESMF_LogFoundError(rc, PASSTHRU)) return
1956 
1957  call ESMF_GridDestroy(natGrid, rc=rc)
1958  if (ESMF_LogFoundError(rc, PASSTHRU)) return
1959 
1960  endif
1961  !
1962  ! -------------------------------------------------------------------- /
1963  ! 3. Clean up locally allocated data structures
1964  !
1965  if (allocated(zl)) then
1966  deallocate (zl, stat=rc)
1967  if (ESMF_LogFoundDeallocError(rc, PASSTHRU)) return
1968  endif
1969  !
1970  ! -------------------------------------------------------------------- /
1971  ! Post
1972  !
1973  call ESMF_VMWtime(wftime)
1974  wtime(iwt) = wtime(iwt) + wftime - wstime
1975  wtcnt(iwt) = wtcnt(iwt) + 1
1976  call PrintTimers(trim(cname), wtnam, wtcnt, wtime)
1977  rc = ESMF_SUCCESS
1978 .eq. if ( improc nmpscr ) write (*,999)
1979 .gt. if (verbosity0) call ESMF_LogWrite(trim(cname)// &
1980  ': leaving finalize', ESMF_LOGMSG_INFO)
1981  !
1982  ! -------------------------------------------------------------------- /
1983  ! Formats
1984  !
1985 999 format(//' end of program '/ &
1986  ' ========================================'/ &
1987  ' wavewatch iii multi-grid shell '/)
1988  !/
1989  !/ End of Finalize --------------------------------------------------- /
1990  !/
1991  end subroutine Finalize
1992  !/ ------------------------------------------------------------------- /
1993  !/
1994 #undef METHOD
1995 #define METHOD "DataInitialize"
1996  !>
1997  !> @brief Initialize wave model export data
1998  !>
1999  !> @param gcomp Gridded component.
2000  !> @param[out] rc Return code.
2001  !>
2002  !> @author T. J. Campbell @date 20-Jan-2017
2003  !>
2004  subroutine DataInitialize ( gcomp, rc )
2005  !/
2006  !/ +-----------------------------------+
2007  !/ | WAVEWATCH III NOAA/NCEP |
2008  !/ | T. J. Campbell, NRL |
2009  !/ | FORTRAN 90 |
2010  !/ | Last update : 20-Jan-2017 |
2011  !/ +-----------------------------------+
2012  !/
2013  !/ 20-Jan-2017 : Origination. ( version 6.02 )
2014  !/
2015  ! 1. Purpose :
2016  !
2017  ! Initialize wave model export data
2018  !
2019  ! 2. Method :
2020  !
2021  ! 3. Parameters :
2022  !
2023  ! Parameter list
2024  ! ----------------------------------------------------------------
2025  ! gcomp Type I/O Gridded component
2026  ! rc Int. O Return code
2027  ! ----------------------------------------------------------------
2028  !
2029  ! 4. Subroutines used :
2030  !
2031  ! Name Type Module Description
2032  ! ----------------------------------------------------------------
2033 Import subr. wmesmfmd wave model get import fields ! Get
2034  ! SetExport Subr. WMESMFMD Wave model set export fields
2035  ! ----------------------------------------------------------------
2036  !
2037  ! 5. Called by :
2038  !
2039  ! 6. Error messages :
2040  !
2041  ! 7. Remarks :
2042  !
2043  ! 8. Structure :
2044  !
2045  ! 9. Switches :
2046  !
2047  ! 10. Source code :
2048  !
2049  !/ ------------------------------------------------------------------- /
2050  !/
2051  !/ ------------------------------------------------------------------- /
2052  !/ Parameter list
2053  !/
2054  implicit none
2055  type(ESMF_GridComp) :: gcomp
2056  integer,intent(out) :: rc
2057  !/
2058  !/ ------------------------------------------------------------------- /
2059  !/ Local parameters
2060  !/
2061  character(ESMF_MAXSTR) :: cname
2062  integer, parameter :: iwt=4
2063  real(8) :: wstime, wftime
2064  type(ESMF_Clock) :: clock
2065  type(ESMF_Time) :: currTime
2066  logical :: fldUpdated, allUpdated
2067  integer :: i, imod
2068  logical :: local
2069  !
2070  ! -------------------------------------------------------------------- /
2071  ! Prep
2072  !
2073  rc = ESMF_SUCCESS
2074  call ESMF_VMWtime(wstime)
2075  call ESMF_GridCompGet(gcomp, name=cname, rc=rc)
2076  if (ESMF_LogFoundError(rc, PASSTHRU)) return
2077 .gt. if (verbosity0) call ESMF_LogWrite(trim(cname)// &
2078  ': entered datainitialize', ESMF_LOGMSG_INFO)
2079  !
2080  ! -------------------------------------------------------------------- /
2081 import fields show correct time stamp ! 1. Check that required
2082  !
2083  if (med_present) then
2084  allUpdated = .true.
2085  else
2086  call ESMF_GridCompGet(gcomp, clock=clock, rc=rc)
2087  if (ESMF_LogFoundError(rc, PASSTHRU)) return
2088  call ESMF_ClockGet(clock, currTime=currTime, rc=rc)
2089  if (ESMF_LogFoundError(rc, PASSTHRU)) return
2090 
2091  allUpdated = .true.
2092  do i = 1,numImpFields
2093 .not. if (impFieldActive(i)) cycle
2094  if (impFieldInitRqrd(i)) then
2095  fldUpdated = NUOPC_IsAtTime(impField(i), currTime, rc=rc)
2096  if (ESMF_LogFoundError(rc, PASSTHRU)) return
2097  if (fldUpdated) then
2098  write(msg,'(a,a10,a,a13)') trim(cname)//': ', &
2099  trim(impFieldName(i)),': inter-model data dependency: ', &
2100  'satisfied'
2101  else
2102  allUpdated = .false.
2103  write(msg,'(a,a10,a,a13)') trim(cname)//': ', &
2104  trim(impFieldName(i)),': inter-model data dependency: ', &
2105  'not satisfied'
2106  endif
2107  else
2108  write(msg,'(a,a10,a,a13)') trim(cname)//': ', &
2109  trim(impFieldName(i)),': inter-model data dependency: ', &
2110  'not required'
2111  endif
2112 .gt. if (verbosity0) call ESMF_LogWrite(trim(msg), ESMF_LOGMSG_INFO)
2113 .eq. if (improcnmpscr) write(*,'(a)') trim(msg)
2114  ! background
2115 .not. if (mbgFieldActive(i)) cycle
2116  if (impFieldInitRqrd(i)) then
2117  fldUpdated = NUOPC_IsAtTime(mbgField(i), currTime, rc=rc)
2118  if (ESMF_LogFoundError(rc, PASSTHRU)) return
2119  if (fldUpdated) then
2120  write(msg,'(a,a10,a,a13)') trim(cname)//': ', &
2121  trim(mbgFieldName(i)),': inter-model data dependency: ', &
2122  'satisfied'
2123  else
2124  allUpdated = .false.
2125  write(msg,'(a,a10,a,a13)') trim(cname)//': ', &
2126  trim(mbgFieldName(i)),': inter-model data dependency: ', &
2127  'not satisfied'
2128  endif
2129  else
2130  write(msg,'(a,a10,a,a13)') trim(cname)//': ', &
2131  trim(mbgFieldName(i)),': inter-model data dependency: ', &
2132  'not required'
2133  endif
2134 .gt. if (verbosity0) call ESMF_LogWrite(trim(msg), ESMF_LOGMSG_INFO)
2135 .eq. if (improcnmpscr) write(*,'(a)') trim(msg)
2136  enddo
2137  endif
2138  !
2139 import dependencies are satisfied, then return ! If not all
2140  !
2141 .not. if (allUpdated) goto 1
2142  !
2143  ! -------------------------------------------------------------------- /
2144 import dependencies are satisfied, so finish initialization ! 2. All
2145  !
2146 import dependencies are satisfied ! 2.a Report all
2147  !
2148  write(msg,'(a)') trim(cname)// &
2149  ': all inter-model data dependencies satisfied'
2150 .gt. if (verbosity0) call ESMF_LogWrite(trim(msg), ESMF_LOGMSG_INFO)
2151 .eq. if (improcnmpscr) write(*,'(a)') trim(msg)
2152  !
2153 import field ! 2.b Setup background blending mask for each
2154  !
2155  do i = 1,numImpFields
2156 .not. if (impFieldActive(i)) cycle
2157 .not. if (mbgFieldActive(i)) cycle
2158  call SetupImpBmsk(bmskField(i), impField(i), missingValue, rc)
2159  if (ESMF_LogFoundError(rc, PASSTHRU)) return
2160  enddo
2161  !
2162 import fields ! 2.c Get
2163  !
2164  call GetImport(gcomp, rc)
2165  if (ESMF_LogFoundError(rc, PASSTHRU)) return
2166  !
2167  ! 2.d Finish initialization (compute initial state), if not restart
2168  !
2169  do imod = 1,nrgrd
2170  call w3setg ( imod, mdse, mdst )
2171  call w3setw ( imod, mdse, mdst )
2172  call w3seta ( imod, mdse, mdst )
2173  call w3seti ( imod, mdse, mdst )
2174  call w3seto ( imod, mdse, mdst )
2175  call wmsetm ( imod, mdse, mdst )
2176 .gt..and..le. local = iaproc 0 iaproc naproc
2177 .and..and. if ( local flcold fliwnd ) call w3uini( va )
2178  enddo
2179  !
2180  ! 2.e Set export fields
2181  !
2182  call SetExport(gcomp, rc)
2183  if (ESMF_LogFoundError(rc, PASSTHRU)) return
2184  !
2185  ! 2.f Set Updated Field Attribute to "true", indicating to the
2186  ! generic code to set the timestamp for these fields
2187  !
2188  do i = 1,numExpFields
2189 .not. if (expFieldActive(i)) cycle
2190  call NUOPC_SetAttribute(expField(i), name="Updated", &
2191  value="true", rc=rc)
2192  if (ESMF_LogFoundError(rc, PASSTHRU)) return
2193  enddo
2194  !
2195  ! 2.g Set InitializeDataComplete Attribute to "true", indicating to the
2196  ! generic code that all inter-model data dependencies are satisfied
2197  !
2198  call NUOPC_CompAttributeSet(gcomp, name="InitializeDataComplete", &
2199  value="true", rc=rc)
2200  if (ESMF_LogFoundError(rc, PASSTHRU)) return
2201  !
2202  ! -------------------------------------------------------------------- /
2203  ! Post
2204  !
2205 1 rc = ESMF_SUCCESS
2206  call ESMF_VMWtime(wftime)
2207  wtime(iwt) = wtime(iwt) + wftime - wstime
2208  wtcnt(iwt) = wtcnt(iwt) + 1
2209 .gt. if (verbosity0) call ESMF_LogWrite(trim(cname)// &
2210  ': leaving datainitialize', ESMF_LOGMSG_INFO)
2211  !/
2212  !/ End of DataInitialize --------------------------------------------- /
2213  !/
2214  end subroutine DataInitialize
2215  !/ ------------------------------------------------------------------- /
2216  !/
2217 #undef METHOD
2218 #define METHOD "ModelAdvance"
2219  !>
2220  !> @brief Advance wave model in time.
2221  !>
2222  !> @param gcomp Gridded component.
2223  !> @param[out] rc Return code.
2224  !>
2225  !> @author T. J. Campbell @date 20-Jan-2017
2226  !>
2227  subroutine ModelAdvance ( gcomp, rc )
2228  !/
2229  !/ +-----------------------------------+
2230  !/ | WAVEWATCH III NOAA/NCEP |
2231  !/ | T. J. Campbell, NRL |
2232  !/ | FORTRAN 90 |
2233  !/ | Last update : 20-Jan-2017 |
2234  !/ +-----------------------------------+
2235  !/
2236  !/ 20-Jan-2017 : Origination. ( version 6.02 )
2237  !/
2238  ! 1. Purpose :
2239  !
2240  ! Advance wave model in time
2241  !
2242  ! 2. Method :
2243  !
2244  ! 3. Parameters :
2245  !
2246  ! Parameter list
2247  ! ----------------------------------------------------------------
2248  ! gcomp Type I/O Gridded component
2249  ! rc Int. O Return code
2250  ! ----------------------------------------------------------------
2251  !
2252  ! 4. Subroutines used :
2253  !
2254  ! Name Type Module Description
2255  ! ----------------------------------------------------------------
2256 Import subr. wmesmfmd wave model get import fields ! Get
2257  ! SetExport Subr. WMESMFMD Wave model set export fields
2258  ! WMWAVE Subr. WMWAVEMD Wave model run
2259  ! ----------------------------------------------------------------
2260  !
2261  ! 5. Called by :
2262  !
2263  ! 6. Error messages :
2264  !
2265  ! 7. Remarks :
2266  !
2267  ! 8. Structure :
2268  !
2269  ! 9. Switches :
2270  !
2271  ! 10. Source code :
2272  !
2273  !/ ------------------------------------------------------------------- /
2274  !/
2275  !/ ------------------------------------------------------------------- /
2276  !/ Parameter list
2277  !/
2278  implicit none
2279  type(ESMF_GridComp) :: gcomp
2280  integer,intent(out) :: rc
2281  !/
2282  !/ ------------------------------------------------------------------- /
2283  !/ Local parameters
2284  !/
2285  character(ESMF_MAXSTR) :: cname
2286  integer, parameter :: iwt=5
2287  real(8) :: wstime, wftime
2288  integer :: i, stat, imod, tcur(2)
2289  integer, allocatable :: tend(:,:)
2290  integer(ESMF_KIND_I4) :: yy,mm,dd,h,m,s
2291  type(ESMF_Clock) :: clock
2292  type(ESMF_Time) :: currTime, stopTime
2293  real :: delt
2294  logical :: lerr
2295 
2296  type(ESMF_Time) :: startTime
2297  type(ESMF_TimeInterval) :: timeStep
2298  character(len=256) :: msgString
2299 
2300  !
2301  ! -------------------------------------------------------------------- /
2302  ! Prep
2303  !
2304  rc = ESMF_SUCCESS
2305  call ESMF_VMWtime(wstime)
2306  call ESMF_GridCompGet(gcomp, name=cname, rc=rc)
2307  if (ESMF_LogFoundError(rc, PASSTHRU)) return
2308 .gt. if (verbosity0) call ESMF_LogWrite(trim(cname)// &
2309  ': entered modeladvance', ESMF_LOGMSG_INFO)
2310  if(profile_memory) call ESMF_VMLogMemInfo('entering ww3 '// &
2311  'model_advance: ')
2312 
2313  allocate (tend(2,nrgrd), stat=rc)
2314  if (ESMF_LogFoundAllocError(rc, PASSTHRU)) return
2315  !
2316  ! -------------------------------------------------------------------- /
2317  ! 1. Advance model to requested end time
2318  !
2319  ! 1.a Get component clock
2320  !
2321  call ESMF_GridCompGet(gcomp, clock=clock, rc=rc)
2322  if (ESMF_LogFoundError(rc, PASSTHRU)) return
2323  !
2324  ! 1.b Report
2325  !
2326 .eq. if ( improc nmpscr ) then
2327  write(*,'(///)')
2328  call ESMF_ClockPrint(clock, options="currTime", &
2329  preString="-->Advancing "//TRIM(cname)//" from: ")
2330  call ESMF_ClockPrint(clock, options="stopTime", &
2331  preString="-----------------> to: ")
2332  endif
2333 
2334  if (profile_memory) then
2335  call ESMF_ClockPrint(clock, options="currTime", &
2336  preString="------>Advancing WAV from: ", &
2337  unit=msgString, rc=rc)
2338  call ESMF_LogWrite(trim(msgString), ESMF_LOGMSG_INFO)
2339 
2340  call ESMF_ClockGet(clock, startTime=startTime, &
2341  currTime=currTime, &
2342  timeStep=timeStep, rc=rc)
2343 
2344  call ESMF_TimePrint(currTime + timeStep, &
2345  preString="--------------------------------> to: ", &
2346  unit=msgString, rc=rc)
2347  call ESMF_LogWrite(trim(msgString), ESMF_LOGMSG_INFO)
2348  endif
2349  !
2350  ! 1.c Check internal current time with component current time
2351  !
2352  call ESMF_ClockGet(clock, currTime=currTime, rc=rc)
2353  if (ESMF_LogFoundError(rc, PASSTHRU)) return
2354  call ESMF_TimeGet(currTime, yy=yy,mm=mm,dd=dd,h=h,m=m,s=s, rc=rc)
2355  if (ESMF_LogFoundError(rc, PASSTHRU)) return
2356  lerr=.false.
2357  do imod = 1,nrgrd
2358  tcur(1) = 10000*yy + 100*mm + dd
2359  tcur(2) = 10000*h + 100*m + s
2360  call w3setw ( imod, mdse, mdst )
2361  delt = dsec21 ( time, tcur )
2362 .gt. if ( abs(delt)0 ) then
2363  lerr=.true.
2364  write(msg,'(a,i2,a,2(a,i8,a,i8,a))') &
2365  'wave model grid ',imod,': ', &
2366  'internal time (',time(1),'.',time(2),') /= ', &
2367  'component time (',tcur(1),'.',tcur(2),')'
2368  call ESMF_LogWrite(trim(msg), ESMF_LOGMSG_ERROR)
2369  endif
2370  enddo
2371  if (lerr) then
2372  rc = ESMF_FAILURE
2373  return
2374  endif
2375  !
2376  ! 1.d Set end time of this advance
2377  !
2378  call ESMF_ClockGet(clock, stopTime=stopTime, rc=rc)
2379  if (ESMF_LogFoundError(rc, PASSTHRU)) return
2380  call ESMF_TimeGet(stopTime, yy=yy,mm=mm,dd=dd,h=h,m=m,s=s, rc=rc)
2381  if (ESMF_LogFoundError(rc, PASSTHRU)) return
2382  do imod = 1,nrgrd
2383  tend(1,imod) = 10000*yy + 100*mm + dd
2384  tend(2,imod) = 10000*h + 100*m + s
2385  enddo
2386  !
2387 import fields ! 1.e Get
2388  !
2389  call GetImport(gcomp, rc=rc)
2390  if (ESMF_LogFoundError(rc, PASSTHRU)) return
2391  !
2392  ! 1.f Advance model
2393  !
2394  if(profile_memory) call ESMF_VMLogMemInfo("Entering WW3 Run : ")
2395  call wmwave ( tend )
2396  if(profile_memory) call ESMF_VMLogMemInfo("Entering WW3 Run : ")
2397  !
2398  ! 1.g Set export fields
2399  !
2400  call SetExport(gcomp, rc=rc)
2401  if (ESMF_LogFoundError(rc, PASSTHRU)) return
2402  !
2403  ! -------------------------------------------------------------------- /
2404  ! Post
2405  !
2406  deallocate (tend, stat=rc)
2407  if (ESMF_LogFoundDeallocError(rc, PASSTHRU)) return
2408  rc = ESMF_SUCCESS
2409  call ESMF_VMWtime(wftime)
2410  wtime(iwt) = wtime(iwt) + wftime - wstime
2411  wtcnt(iwt) = wtcnt(iwt) + 1
2412 .gt. if (verbosity0) call ESMF_LogWrite(trim(cname)// &
2413  ': leaving modeladvance', ESMF_LOGMSG_INFO)
2414  if(profile_memory) call ESMF_VMLogMemInfo('leaving ww3 '// &
2415  'model_advance: ')
2416  !/
2417  !/ End of ModelAdvance ----------------------------------------------- /
2418  !/
2419  end subroutine ModelAdvance
2420  !/ ------------------------------------------------------------------- /
2421  !/
2422 #undef METHOD
2423 #define METHOD "GetImport"
2424  !>
2425 import fields and put in internal data structures. !> @brief Get
2426  !>
2427  !> @param gcomp Gridded component.
2428  !> @param[out] rc Return code.
2429  !>
2430  !> @author T. J. Campbell @date 20-Jan-2017
2431  !>
2432 Import ( gcomp, rc ) subroutine Get
2433  !/
2434  !/ +-----------------------------------+
2435  !/ | WAVEWATCH III NOAA/NCEP |
2436  !/ | T. J. Campbell, NRL |
2437  !/ | FORTRAN 90 |
2438  !/ | Last update : 20-Jan-2017 |
2439  !/ +-----------------------------------+
2440  !/
2441  !/ 20-Jan-2017 : Origination. ( version 6.02 )
2442  !/
2443  ! 1. Purpose :
2444  !
2445 import fields and put in internal data structures ! Get
2446  !
2447  ! 2. Method :
2448  !
2449  ! 3. Parameters :
2450  !
2451  ! Parameter list
2452  ! ----------------------------------------------------------------
2453  ! gcomp Type I/O Gridded component
2454  ! rc Int. O Return code
2455  ! ----------------------------------------------------------------
2456  !
2457  ! 4. Subroutines used :
2458  !
2459  ! Name Type Module Description
2460  ! ----------------------------------------------------------------
2461  ! NONE
2462  ! ----------------------------------------------------------------
2463  !
2464  ! 5. Called by :
2465  !
2466  ! 6. Error messages :
2467  !
2468  ! 7. Remarks :
2469  !
2470  ! 8. Structure :
2471  !
2472  ! 9. Switches :
2473  !
2474  ! 10. Source code :
2475  !
2476  !/ ------------------------------------------------------------------- /
2477  !/
2478  !/ ------------------------------------------------------------------- /
2479  !/ Parameter list
2480  !/
2481 #ifdef W3_MPI
2482  USE WMMDATMD, ONLY: IMPROC
2483 #endif
2484  implicit none
2485  type(ESMF_GridComp) :: gcomp
2486  integer,intent(out) :: rc
2487  !/
2488  !/ ------------------------------------------------------------------- /
2489  !/ Local parameters
2490  !/
2491  character(ESMF_MAXSTR) :: cname
2492  !AW ---TEST-TEST-TEST---------------------------
2493  character(500) :: msg
2494  integer :: k
2495  !AW ---TEST-TEST-TEST---------------------------
2496  integer, parameter :: iwt=7
2497  real(8) :: wstime, wftime
2498  integer :: i1, i2, i3, j, imod, jmod
2499  logical, save :: firstCall = .true.
2500  integer :: tcur(2), tend(2)
2501  integer(ESMF_KIND_I4) :: yy,mm,dd,h,m,s
2502  type(ESMF_Clock) :: clock
2503  type(ESMF_Time) :: currTime, stopTime
2504 #if defined(TEST_WMESMFMD) || defined(TEST_WMESMFMD_GETIMPORT)
2505  type(ESMF_State) :: dumpState
2506  integer, save :: timeSlice = 1
2507 #endif
2508  real(ESMF_KIND_RX), pointer :: rptr(:,:)
2509  integer :: iy, ix
2510  integer :: elb(2), eub(2)
2511  character(len=3) :: fieldName
2512  !
2513  ! -------------------------------------------------------------------- /
2514  ! Prep
2515  !
2516  rc = ESMF_SUCCESS
2517  if ( noActiveImpFields ) return
2518  call ESMF_VMWtime(wstime)
2519  call ESMF_GridCompGet(gcomp, name=cname, rc=rc)
2520  if (ESMF_LogFoundError(rc, PASSTHRU)) return
2521 .gt. if (verbosity0) call ESMF_LogWrite(trim(cname)// &
2522  ': entered getimport', ESMF_LOGMSG_INFO)
2523 #if defined(TEST_WMESMFMD) || defined(TEST_WMESMFMD_GETIMPORT)
2524  call NUOPC_ModelGet(gcomp, importState=dumpState, rc=rc)
2525  if (ESMF_LogFoundError(rc, PASSTHRU)) return
2526  call NUOPC_Write(dumpState, overwrite=.true., &
2527  fileNamePrefix="field_"//trim(cname)//"_import1_", &
2528  timeslice=timeSlice, relaxedFlag=.true., rc=rc)
2529  if (ESMF_LogFoundError(rc, PASSTHRU)) return
2530 #endif
2531  !
2532  ! -------------------------------------------------------------------- /
2533  ! Set time stamps using currTime and stopTime
2534  !
2535  call ESMF_GridCompGet(gcomp, clock=clock, rc=rc)
2536  if (ESMF_LogFoundError(rc, PASSTHRU)) return
2537  call ESMF_ClockGet(clock, currTime=currTime, rc=rc)
2538  if (ESMF_LogFoundError(rc, PASSTHRU)) return
2539  call ESMF_TimeGet(currTime, yy=yy,mm=mm,dd=dd,h=h,m=m,s=s, rc=rc)
2540  if (ESMF_LogFoundError(rc, PASSTHRU)) return
2541  tcur(1) = 10000*yy + 100*mm + dd
2542  tcur(2) = 10000*h + 100*m + s
2543  call ESMF_ClockGet(clock, stopTime=stopTime, rc=rc)
2544  if (ESMF_LogFoundError(rc, PASSTHRU)) return
2545  call ESMF_TimeGet(stopTime, yy=yy,mm=mm,dd=dd,h=h,m=m,s=s, rc=rc)
2546  if (ESMF_LogFoundError(rc, PASSTHRU)) return
2547  tend(1) = 10000*yy + 100*mm + dd
2548  tend(2) = 10000*h + 100*m + s
2549  !
2550  ! -------------------------------------------------------------------- /
2551  ! Water levels
2552  !
2553  j = 1
2554  i1 = FieldIndex( impFieldName, 'seahgt', rc )
2555  if (ESMF_LogFoundError(rc, PASSTHRU)) return
2556  i2 = i1
2557  if ( impFieldActive(i1) ) then
2558  call w3setg ( impGridID, mdse, mdst )
2559  call w3seti ( impGridID, mdse, mdst )
2560  if (firstCall) then
2561  tln = tcur
2562  else
2563  tln = tend
2564  endif
2565  tfn(:,j) = tln
2566  if ( mbgFieldActive(i1) ) then
2567  call BlendImpField( impField(i1), mbgField(i1), bmskField(i1), rc=rc )
2568  if (ESMF_LogFoundError(rc, PASSTHRU)) return
2569  endif
2570  call FieldGather( impField(i1), nx, ny, wlev, rc=rc )
2571  if (ESMF_LogFoundError(rc, PASSTHRU)) return
2572  do imod = 1,nrgrd
2573  call w3setg ( imod, mdse, mdst )
2574  call w3setw ( imod, mdse, mdst )
2575  call w3seti ( imod, mdse, mdst )
2576  call w3seto ( imod, mdse, mdst )
2577  call wmsetm ( imod, mdse, mdst )
2578 #ifdef W3_MPI
2579 .eq. if ( mpi_comm_grd mpi_comm_null ) cycle
2580 #endif
2581  jmod = inpmap(imod,j)
2582 .lt..and..ne. if ( jmod0 jmod-999 ) then
2583  call wmupd2( imod, j, jmod, rc )
2584  if (ESMF_LogFoundError(rc, PASSTHRU)) return
2585  endif
2586  enddo
2587  endif
2588  !
2589  ! -------------------------------------------------------------------- /
2590  ! Currents
2591  !
2592  j = 2
2593  i1 = FieldIndex( impFieldName, 'uucurr', rc )
2594  if (ESMF_LogFoundError(rc, PASSTHRU)) return
2595  i2 = FieldIndex( impFieldName, 'vvcurr', rc )
2596  if (ESMF_LogFoundError(rc, PASSTHRU)) return
2597  if ( impFieldActive(i1) ) then
2598  call w3setg ( impGridID, mdse, mdst )
2599  call w3seti ( impGridID, mdse, mdst )
2600  if (firstCall) then
2601  tcn = tcur
2602  else
2603  tc0 = tcn
2604  cx0 = cxn
2605  cy0 = cyn
2606  tcn = tend
2607  endif
2608  tfn(:,j) = tcn
2609  if ( mbgFieldActive(i1) ) then
2610  call BlendImpField( impField(i1), mbgField(i1), bmskField(i1), rc=rc )
2611  if (ESMF_LogFoundError(rc, PASSTHRU)) return
2612  call BlendImpField( impField(i2), mbgField(i2), bmskField(i2), rc=rc )
2613  if (ESMF_LogFoundError(rc, PASSTHRU)) return
2614  endif
2615  call FieldGather( impField(i1), nx, ny, cxn, rc=rc )
2616  if (ESMF_LogFoundError(rc, PASSTHRU)) return
2617  call FieldGather( impField(i2), nx, ny, cyn, rc=rc )
2618  if (ESMF_LogFoundError(rc, PASSTHRU)) return
2619  if (firstCall) then
2620  tc0 = tcn
2621  cx0 = cxn
2622  cy0 = cyn
2623  endif
2624  do imod = 1,nrgrd
2625  call w3setg ( imod, mdse, mdst )
2626  call w3setw ( imod, mdse, mdst )
2627  call w3seti ( imod, mdse, mdst )
2628  call wmsetm ( imod, mdse, mdst )
2629 #ifdef W3_MPI
2630 .eq. if ( mpi_comm_grd mpi_comm_null ) cycle
2631 #endif
2632  jmod = inpmap(imod,j)
2633 .lt..and..ne. if ( jmod0 jmod-999 ) then
2634  call wmupd2( imod, j, jmod, rc )
2635  if (ESMF_LogFoundError(rc, PASSTHRU)) return
2636  endif
2637  enddo
2638  endif
2639  !
2640  ! -------------------------------------------------------------------- /
2641  ! Winds
2642  !
2643  j = 3
2644  i1 = FieldIndex( impFieldName, 'uutrue', rc )
2645  if (ESMF_LogFoundError(rc, PASSTHRU)) return
2646  i2 = FieldIndex( impFieldName, 'vvtrue', rc )
2647  if (ESMF_LogFoundError(rc, PASSTHRU)) return
2648  if ( impFieldActive(i1) ) then
2649  call w3setg ( impGridID, mdse, mdst )
2650  call w3seti ( impGridID, mdse, mdst )
2651 
2652  if (firstCall) then
2653  twn = tcur
2654  else
2655  tw0 = twn
2656  wx0 = wxn
2657  wy0 = wyn
2658  twn = tend
2659  endif
2660  tfn(:,j) = twn
2661  if ( mbgFieldActive(i1) ) then
2662  call BlendImpField( impField(i1), mbgField(i1), bmskField(i1), rc=rc )
2663  if (ESMF_LogFoundError(rc, PASSTHRU)) return
2664  call BlendImpField( impField(i2), mbgField(i2), bmskField(i2), rc=rc )
2665  if (ESMF_LogFoundError(rc, PASSTHRU)) return
2666  endif
2667  if (merge_import) then
2668  ! read wave input
2669  fieldName = 'wnd'
2670  call ReadFromFile(fieldName, mdtField(i1), mdtField(i2), tcur, tend, rc=rc)
2671  if (ESMF_LogFoundError(rc, PASSTHRU)) return
2672  ! create merge mask
2673 .not. if ( firstCall) then
2674  call SetupImpMmsk(mmskField(i1), impField(i1), fillValue, mmskCreated(i1), rc=rc)
2675  if (ESMF_LogFoundError(rc, PASSTHRU)) return
2676  call SetupImpMmsk(mmskField(i2), impField(i2), fillValue, mmskCreated(i2), rc=rc)
2677  if (ESMF_LogFoundError(rc, PASSTHRU)) return
2678  end if
2679  ! blend data, mask is all zero initially (use all data)
2680  call BlendImpField( impField(i1), mdtField(i1), mmskField(i1), rc=rc )
2681  if (ESMF_LogFoundError(rc, PASSTHRU)) return
2682  call BlendImpField( impField(i2), mdtField(i2), mmskField(i2), rc=rc )
2683  if (ESMF_LogFoundError(rc, PASSTHRU)) return
2684  end if
2685  call FieldGather( impField(i1), nx, ny, wxn, rc=rc )
2686  if (ESMF_LogFoundError(rc, PASSTHRU)) return
2687  call FieldGather( impField(i2), nx, ny, wyn, rc=rc )
2688  if (ESMF_LogFoundError(rc, PASSTHRU)) return
2689  if (firstCall) then
2690  tw0 = twn
2691  wx0 = wxn
2692  wy0 = wyn
2693 #ifdef W3_WRST
2694  ! The WRST switch saves the values of wind in the
2695  ! restart file and then uses the wind for the first
2696  ! time step here. This is needed when coupling with
2697  ! an atm model that does not have 10m wind speeds at
2698  ! initialization. If there is no restart, wind is zero
2699  wxn = WXNwrst !replace with values from restart
2700  wyn = WYNwrst
2701  wx0 = WXNwrst
2702  wy0 = WYNwrst
2703  do imod = 1,nrgrd
2704  call w3setg ( imod, mdse, mdst )
2705  call w3setw ( imod, mdse, mdst )
2706  call w3seti ( imod, mdse, mdst )
2707  call wmsetm ( imod, mdse, mdst )
2708 #ifdef W3_MPI
2709 .eq. if ( mpi_comm_grd mpi_comm_null ) cycle
2710 #endif
2711  INPUTS(IMOD)%TW0(:) = INPUTS(impGridID)%TW0(:)
2712  INPUTS(IMOD)%TFN(:,3) = INPUTS(impGridID)%TFN(:,3)
2713  wxn = WXNwrst !replace with values from restart
2714  wyn = WYNwrst
2715  wx0 = WXNwrst
2716  wy0 = WYNwrst
2717  if (ESMF_LogFoundError(rc, PASSTHRU)) return
2718  enddo
2719 #endif
2720  endif
2721 
2722 #ifdef W3_WRST
2723 .le. if ( ((twn(1)-tw0(1))*1000000+((twn(2)-tw0(2)))) 0 ) then
2724  !If the time of the field is still initial time, replace
2725  !with restart field
2726  wxn = WXNwrst !replace with values from restart
2727  wyn = WYNwrst
2728  else !twn>tw0
2729 #endif
2730  do imod = 1,nrgrd
2731  call w3setg ( imod, mdse, mdst )
2732  call w3setw ( imod, mdse, mdst )
2733  call w3seti ( imod, mdse, mdst )
2734  call wmsetm ( imod, mdse, mdst )
2735 #ifdef W3_MPI
2736 .eq. if ( mpi_comm_grd mpi_comm_null ) cycle
2737 #endif
2738  jmod = inpmap(imod,j)
2739 .lt..and..ne. if ( jmod0 jmod-999 ) then
2740  call wmupd2( imod, j, jmod, rc )
2741  if (ESMF_LogFoundError(rc, PASSTHRU)) return
2742  endif
2743  enddo
2744 #ifdef W3_WRST
2745 .le. endif !if ( twn-tw0 0 )
2746 #endif
2747  endif
2748  !
2749  ! -------------------------------------------------------------------- /
2750  ! Sea ice concentration
2751  !
2752  j = 4
2753  i1 = FieldIndex( impFieldName, 'seaice', rc )
2754  if (ESMF_LogFoundError(rc, PASSTHRU)) return
2755  i2 = i1
2756  if ( impFieldActive(i1) ) then
2757  call w3setg ( impGridID, mdse, mdst )
2758  call w3seti ( impGridID, mdse, mdst )
2759  if (firstCall) then
2760  tin = tcur
2761  else
2762  tin = tend
2763  endif
2764  tfn(:,j) = tin
2765  if ( mbgFieldActive(i1) ) then
2766  call BlendImpField( impField(i1), mbgField(i1), bmskField(i1), rc=rc )
2767  if (ESMF_LogFoundError(rc, PASSTHRU)) return
2768  endif
2769  call FieldGather( impField(i1), nx, ny, icei, rc=rc )
2770  if (ESMF_LogFoundError(rc, PASSTHRU)) return
2771  do imod = 1,nrgrd
2772  call w3setg ( imod, mdse, mdst )
2773  call w3setw ( imod, mdse, mdst )
2774  call w3seti ( imod, mdse, mdst )
2775  call wmsetm ( imod, mdse, mdst )
2776 #ifdef W3_MPI
2777 .eq. if ( mpi_comm_grd mpi_comm_null ) cycle
2778 #endif
2779  jmod = inpmap(imod,j)
2780 .lt..and..ne. if ( jmod0 jmod-999 ) then
2781  call wmupd2( imod, j, jmod, rc )
2782  if (ESMF_LogFoundError(rc, PASSTHRU)) return
2783  endif
2784  enddo
2785  endif
2786  !
2787  ! -------------------------------------------------------------------- /
2788  ! Post
2789  !
2790 #if defined(TEST_WMESMFMD) || defined(TEST_WMESMFMD_GETIMPORT)
2791  call NUOPC_Write(dumpState, overwrite=.true., &
2792  fileNamePrefix="field_"//trim(cname)//"_import2_", &
2793  timeslice=timeSlice, relaxedFlag=.true., rc=rc)
2794  if (ESMF_LogFoundError(rc, PASSTHRU)) return
2795  timeSlice = timeSlice + 1
2796 #endif
2797  firstCall = .false.
2798  rc = ESMF_SUCCESS
2799  call ESMF_VMWtime(wftime)
2800  wtime(iwt) = wtime(iwt) + wftime - wstime
2801  wtcnt(iwt) = wtcnt(iwt) + 1
2802 .gt. if (verbosity0) call ESMF_LogWrite(trim(cname)// &
2803  ': leaving getimport', ESMF_LOGMSG_INFO)
2804  !/
2805 Import -------------------------------------------------- / !/ End of Get
2806  !/
2807 Import end subroutine Get
2808  !/ ------------------------------------------------------------------- /
2809  !/
2810 #undef METHOD
2811 #define METHOD "SetExport"
2812  !>
2813  !> @brief Set export fields from internal data structures.
2814  !>
2815  !> @param gcomp Gridded component
2816  !> @param[out] rc Return code
2817  !>
2818  !> @author T. J. Campbell @date 09-Aug-2017
2819  !>
2820  subroutine SetExport ( gcomp, rc )
2821  !/
2822  !/ +-----------------------------------+
2823  !/ | WAVEWATCH III NOAA/NCEP |
2824  !/ | T. J. Campbell, NRL |
2825  !/ | FORTRAN 90 |
2826  !/ | Last update : 09-Aug-2017 |
2827  !/ +-----------------------------------+
2828  !/
2829  !/ 20-Jan-2017 : Origination. ( version 6.02 )
2830  !/ 09-Aug-2017 : Add ocean forcing export fields ( version 6.03 )
2831  !/
2832  ! 1. Purpose :
2833  !
2834  ! Set export fields from internal data structures
2835  !
2836  ! 2. Method :
2837  !
2838  ! 3. Parameters :
2839  !
2840  ! Parameter list
2841  ! ----------------------------------------------------------------
2842  ! gcomp Type I/O Gridded component
2843  ! rc Int. O Return code
2844  ! ----------------------------------------------------------------
2845  !
2846  ! 4. Subroutines used :
2847  !
2848  ! Name Type Module Description
2849  ! ----------------------------------------------------------------
2850  ! NONE
2851  ! ----------------------------------------------------------------
2852  !
2853  ! 5. Called by :
2854  !
2855  ! 6. Error messages :
2856  !
2857  ! 7. Remarks :
2858  !
2859  ! 8. Structure :
2860  !
2861  ! 9. Switches :
2862  !
2863  ! 10. Source code :
2864  !
2865  !/ ------------------------------------------------------------------- /
2866  !/
2867  !/ ------------------------------------------------------------------- /
2868  !/ Parameter list
2869  !/
2870  implicit none
2871  type(ESMF_GridComp) :: gcomp
2872  integer,intent(out) :: rc
2873  !/
2874  !/ ------------------------------------------------------------------- /
2875  !/ Local parameters
2876  !/
2877  character(ESMF_MAXSTR) :: cname
2878  integer, parameter :: iwt=8
2879  real(8) :: wstime, wftime
2880  integer :: i1, i2, i3, i4, i5, i6
2881  logical :: flpart = .false., floutg = .false., floutg2 = .true.
2882 #if defined(TEST_WMESMFMD) || defined(TEST_WMESMFMD_SETEXPORT)
2883  type(ESMF_State) :: dumpState
2884  integer, save :: timeSlice = 1
2885 #endif
2886  real(ESMF_KIND_R8), pointer :: farrayptr(:,:)
2887  !
2888  ! -------------------------------------------------------------------- /
2889  ! Prep
2890  !
2891  rc = ESMF_SUCCESS
2892  if ( noActiveExpFields ) return
2893  call ESMF_VMWtime(wstime)
2894  call ESMF_GridCompGet(gcomp, name=cname, rc=rc)
2895  if (ESMF_LogFoundError(rc, PASSTHRU)) return
2896 .gt. if (verbosity0) call ESMF_LogWrite(trim(cname)// &
2897  ': entered setexport', ESMF_LOGMSG_INFO)
2898  !
2899  ! -------------------------------------------------------------------- /
2900  ! Setup
2901  !
2902  call w3setg ( expGridID, mdse, mdst )
2903  call w3setw ( expGridID, mdse, mdst )
2904  call w3seta ( expGridID, mdse, mdst )
2905  call w3seti ( expGridID, mdse, mdst )
2906  call w3seto ( expGridID, mdse, mdst )
2907  call wmsetm ( expGridID, mdse, mdst )
2908 #ifdef USE_W3OUTG_FOR_EXPORT
2909  if ( natGridIsLocal ) call w3outg( va, flpart, floutg, floutg2 )
2910 #endif
2911  !
2912  ! -------------------------------------------------------------------- /
2913  ! Charnock
2914  !
2915  i1 = FieldIndex( expFieldName, 'charno', rc )
2916  if (ESMF_LogFoundError(rc, PASSTHRU)) return
2917  if ( expFieldActive(i1) ) then
2918  call CalcCharnk( expField(i1), rc )
2919  if (ESMF_LogFoundError(rc, PASSTHRU)) return
2920  endif
2921  !
2922  ! -------------------------------------------------------------------- /
2923  ! Surface Roughness
2924  !
2925  i1 = FieldIndex( expFieldName, 'z0rlen', rc )
2926  if (ESMF_LogFoundError(rc, PASSTHRU)) return
2927  if ( expFieldActive(i1) ) then
2928  call CalcRoughl( expField(i1), rc )
2929  if (ESMF_LogFoundError(rc, PASSTHRU)) return
2930  endif
2931  !
2932  ! -------------------------------------------------------------------- /
2933  ! Stokes Drift 3D
2934  !
2935  i1 = FieldIndex( expFieldName, 'uscurr', rc )
2936  if (ESMF_LogFoundError(rc, PASSTHRU)) return
2937  i2 = FieldIndex( expFieldName, 'vscurr', rc )
2938  if (ESMF_LogFoundError(rc, PASSTHRU)) return
2939 .and. if ( expFieldActive(i1) &
2940  expFieldActive(i2) ) then
2941  call CalcStokes3D( va, expField(i1), expField(i2), rc )
2942  if (ESMF_LogFoundError(rc, PASSTHRU)) return
2943  endif
2944  !
2945  ! -------------------------------------------------------------------- /
2946  ! Partitioned Stokes Drift 3 2D fields
2947  !
2948  i1 = FieldIndex( expFieldName, 'x1pstk', rc )
2949  if (ESMF_LogFoundError(rc, PASSTHRU)) return
2950  i2 = FieldIndex( expFieldName, 'y1pstk', rc )
2951  if (ESMF_LogFoundError(rc, PASSTHRU)) return
2952  i3 = FieldIndex( expFieldName, 'x2pstk', rc )
2953  if (ESMF_LogFoundError(rc, PASSTHRU)) return
2954  i4 = FieldIndex( expFieldName, 'y2pstk', rc )
2955  if (ESMF_LogFoundError(rc, PASSTHRU)) return
2956  i5 = FieldIndex( expFieldName, 'x3pstk', rc )
2957  if (ESMF_LogFoundError(rc, PASSTHRU)) return
2958  i6 = FieldIndex( expFieldName, 'y3pstk', rc )
2959  if (ESMF_LogFoundError(rc, PASSTHRU)) return
2960 .and. if ( expFieldActive(i1) &
2961 .and. expFieldActive(i2) &
2962 .and. expFieldActive(i3) &
2963 .and. expFieldActive(i4) &
2964 .and. expFieldActive(i5) &
2965  expFieldActive(i6) ) then
2966  call CalcPStokes( va, expField(i1), expField(i2), expField(i3), &
2967  expField(i4), expField(i5), expField(i6), rc )
2968  if (ESMF_LogFoundError(rc, PASSTHRU)) return
2969  endif
2970  !
2971  ! -------------------------------------------------------------------- /
2972  ! Bottom Currents
2973  !
2974  i1 = FieldIndex( expFieldName, 'wbcuru', rc )
2975  if (ESMF_LogFoundError(rc, PASSTHRU)) return
2976  i2 = FieldIndex( expFieldName, 'wbcurv', rc )
2977  if (ESMF_LogFoundError(rc, PASSTHRU)) return
2978  i3 = FieldIndex( expFieldName, 'wbcurp', rc )
2979  if (ESMF_LogFoundError(rc, PASSTHRU)) return
2980 .and. if ( expFieldActive(i1) &
2981 .and. expFieldActive(i2) &
2982  expFieldActive(i3) ) then
2983  call CalcBotcur( va, expField(i1), expField(i2), expField(i3), rc )
2984  if (ESMF_LogFoundError(rc, PASSTHRU)) return
2985  endif
2986  !
2987  ! -------------------------------------------------------------------- /
2988  ! Radiation stresses 2D
2989  !
2990  i1 = FieldIndex( expFieldName, 'wavsuu', rc )
2991  if (ESMF_LogFoundError(rc, PASSTHRU)) return
2992  i2 = FieldIndex( expFieldName, 'wavsuv', rc )
2993  if (ESMF_LogFoundError(rc, PASSTHRU)) return
2994  i3 = FieldIndex( expFieldName, 'wavsvv', rc )
2995  if (ESMF_LogFoundError(rc, PASSTHRU)) return
2996 .and. if ( expFieldActive(i1) &
2997 .and. expFieldActive(i2) &
2998  expFieldActive(i3) ) then
2999  call CalcRadstr2D( va, expField(i1), expField(i2), expField(i3), rc )
3000  if (ESMF_LogFoundError(rc, PASSTHRU)) return
3001  endif
3002  !
3003  ! -------------------------------------------------------------------- /
3004  ! cpl_scalars - grid sizes
3005  !
3006  if (med_present) then
3007  i1 = FieldIndex( expFieldName, trim(flds_scalar_name), rc=rc )
3008  if (ESMF_LogFoundError(rc, PASSTHRU)) return
3009  if ( expFieldActive(i1) ) then
3010  call ESMF_FieldGet(expField(i1), farrayPtr=farrayptr, rc=rc)
3011  if (ESMF_LogFoundError(rc, PASSTHRU)) return
3012 .and. if (flds_scalar_index_nx > 0 flds_scalar_index_nx < flds_scalar_num) then
3013  farrayptr(flds_scalar_index_nx,1) = dble(nx)
3014  endif
3015 .and. if (flds_scalar_index_ny > 0 flds_scalar_index_ny < flds_scalar_num) then
3016  farrayptr(flds_scalar_index_ny,1) = dble(ny)
3017  endif
3018  endif
3019  endif
3020  !
3021  ! -------------------------------------------------------------------- /
3022  ! Post
3023  !
3024 #if defined(TEST_WMESMFMD) || defined(TEST_WMESMFMD_SETEXPORT)
3025  call NUOPC_ModelGet(gcomp, exportState=dumpState, rc=rc)
3026  if (ESMF_LogFoundError(rc, PASSTHRU)) return
3027  call NUOPC_Write(dumpState, overwrite=.true., &
3028  fileNamePrefix="field_"//trim(cname)//"_export_", &
3029  timeslice=timeSlice, relaxedFlag=.true., rc=rc)
3030  if (ESMF_LogFoundError(rc, PASSTHRU)) return
3031  timeSlice = timeSlice + 1
3032 #endif
3033  rc = ESMF_SUCCESS
3034  call ESMF_VMWtime(wftime)
3035  wtime(iwt) = wtime(iwt) + wftime - wstime
3036  wtcnt(iwt) = wtcnt(iwt) + 1
3037 .gt. if (verbosity0) call ESMF_LogWrite(trim(cname)// &
3038  ': leaving setexport', ESMF_LOGMSG_INFO)
3039  !/
3040  !/ End of SetExport -------------------------------------------------- /
3041  !/
3042  end subroutine SetExport
3043  !/ ------------------------------------------------------------------- /
3044  !/
3045 #undef METHOD
3046 #define METHOD "CreateImpGrid"
3047  !>
3048 import fields. !> @brief Create ESMF grid for
3049  !>
3050  !> @param gcomp Gridded component
3051  !> @param[out] rc Return code
3052  !>
3053  !> @author T. J. Campbell @date 20-Jan-2017
3054  !>
3055  subroutine CreateImpGrid ( gcomp, rc )
3056  !/
3057  !/ +-----------------------------------+
3058  !/ | WAVEWATCH III NOAA/NCEP |
3059  !/ | T. J. Campbell, NRL |
3060  !/ | FORTRAN 90 |
3061  !/ | Last update : 20-Jan-2017 |
3062  !/ +-----------------------------------+
3063  !/
3064  !/ 20-Jan-2017 : Origination. ( version 6.02 )
3065  !/
3066  ! 1. Purpose :
3067  !
3068 import fields ! Create ESMF grid for
3069  !
3070  ! 2. Method :
3071  !
3072  ! 3. Parameters :
3073  !
3074  ! Parameter list
3075  ! ----------------------------------------------------------------
3076  ! gcomp Type I/O Gridded component
3077  ! rc Int. O Return code
3078  ! ----------------------------------------------------------------
3079  !
3080  ! 4. Subroutines used :
3081  !
3082  ! Name Type Module Description
3083  ! ----------------------------------------------------------------
3084  ! NONE
3085  ! ----------------------------------------------------------------
3086  !
3087  ! 5. Called by :
3088  !
3089  ! 6. Error messages :
3090  !
3091  ! 7. Remarks :
3092  !
3093  ! 8. Structure :
3094  !
3095  ! 9. Switches :
3096  !
3097  ! 10. Source code :
3098  !
3099  !/ ------------------------------------------------------------------- /
3100  !/
3101  !/ ------------------------------------------------------------------- /
3102  !/ Parameter list
3103  !/
3104  implicit none
3105  type(ESMF_GridComp) :: gcomp
3106  integer,intent(out) :: rc
3107  !/
3108  !/ ------------------------------------------------------------------- /
3109  !/ Local parameters
3110  !/
3111  type(ESMF_VM) :: vm
3112  character(ESMF_MAXSTR) :: cname
3113  integer :: nproc, nxproc, nyproc
3114  integer, parameter :: lde = 0
3115  integer :: lpet, ldecnt
3116  integer :: ix, iy, isea, jsea, irec, ubx, uby
3117  integer :: elb(2), eub(2), elbc(2), eubc(2)
3118  integer :: tlb(2), tub(2)
3119  integer(ESMF_KIND_I4), pointer :: iptr(:,:)
3120  real(ESMF_KIND_RX), pointer :: rptrx(:,:), rptry(:,:)
3121  real(ESMF_KIND_RX), pointer :: rptr(:,:)
3122  real(ESMF_KIND_R8), allocatable :: xgrd_center(:)
3123  real(ESMF_KIND_R8), allocatable :: ygrd_center(:)
3124  real(ESMF_KIND_R8), allocatable :: xgrd_corner(:,:)
3125  real(ESMF_KIND_R8), allocatable :: ygrd_corner(:,:)
3126  logical, allocatable :: land_sea(:)
3127  integer, allocatable :: grid_dims(:)
3128  integer :: grid_size, grid_corners, grid_rank
3129  type(ESMF_Field) :: tmpField
3130  !
3131  ! -------------------------------------------------------------------- /
3132  ! Prep
3133  !
3134  rc = ESMF_SUCCESS
3135  if ( noActiveImpFields ) return
3136  call ESMF_GridCompGet(gcomp, name=cname, vm=vm, rc=rc)
3137  if (ESMF_LogFoundError(rc, PASSTHRU)) return
3138  call ESMF_VMGet(vm, localPet=lpet, rc=rc)
3139  if (ESMF_LogFoundError(rc, PASSTHRU)) return
3140 .gt. if (verbosity0) call ESMF_LogWrite(trim(cname)// &
3141  ': entered createimpgrid', ESMF_LOGMSG_INFO)
3142  !
3143  ! -------------------------------------------------------------------- /
3144  ! 1. Setup
3145  !
3146  ! 1.a Set grid pointers
3147  !
3148  impGridID = minval(inpmap)
3149 .eq. if ( impGridID-999 ) impGridID = 1
3150  call w3setg ( impGridID, mdse, mdst )
3151  call w3seti ( impGridID, mdse, mdst )
3152  call w3seto ( impGridID, mdse, mdst )
3153 .gt. if ( impGridID0 ) then
3154  call wmsetm ( impGridID, mdse, mdst )
3155  nproc = naproc
3156  else
3157  nproc = nmproc
3158  endif
3159  !
3160  ! 1.b Compute a 2D subdomain layout based on nproc
3161  !
3162  call CalcDecomp( nx, ny, nproc, impHaloWidth, .true., nxproc, nyproc, rc )
3163  if (ESMF_LogFoundError(rc, PASSTHRU)) return
3164  !
3165 import fields ! 1.c Set arraySpec, staggerLoc, and indexFlag for
3166  !
3167  call ESMF_ArraySpecSet( impArraySpec2D, rank=2, &
3168  typekind=ESMF_TYPEKIND_RX, rc=rc )
3169  if (ESMF_LogFoundError(rc, PASSTHRU)) return
3170  impStaggerLoc = ESMF_STAGGERLOC_CENTER
3171  impIndexFlag = ESMF_INDEX_GLOBAL
3172  !
3173  ! -------------------------------------------------------------------- /
3174 import with 2d subdomain layout ! 2. Create ESMF grid for
3175  ! Note that the ESMF grid layout is dim1=X, dim2=Y
3176  !
3177 import grid ! 2.a Create ESMF
3178  !
3179  select case (iclose)
3180  case (iclose_none)
3181  impGrid = ESMF_GridCreateNoPeriDim( &
3182  minIndex=(/ 1, 1/), &
3183  maxIndex=(/nx,ny/), &
3184  coordDep1=(/1,2/), &
3185  coordDep2=(/1,2/), &
3186  regDecomp=(/nxproc,nyproc/), &
3187  decompFlag=(/ESMF_DECOMP_BALANCED,ESMF_DECOMP_BALANCED/), &
3188  coordTypeKind=ESMF_TYPEKIND_RX, &
3189  coordSys=ESMF_COORDSYS_SPH_DEG, &
3190  indexFlag=impIndexFlag, &
3191  name=trim(cname)//"_import_grid", rc=rc )
3192  if (ESMF_LogFoundError(rc, PASSTHRU)) return
3193  case (iclose_smpl)
3194  impGrid = ESMF_GridCreate1PeriDim( &
3195  periodicDim=1, &
3196  poleDim=2, &
3197  poleKindFlag=(/ESMF_POLEKIND_NONE,ESMF_POLEKIND_NONE/), &
3198  minIndex=(/ 1, 1/), &
3199  maxIndex=(/nx,ny/), &
3200  coordDep1=(/1,2/), &
3201  coordDep2=(/1,2/), &
3202  regDecomp=(/nxproc,nyproc/), &
3203  decompFlag=(/ESMF_DECOMP_BALANCED,ESMF_DECOMP_BALANCED/), &
3204  coordTypeKind=ESMF_TYPEKIND_RX, &
3205  coordSys=ESMF_COORDSYS_SPH_DEG, &
3206  indexFlag=impIndexFlag, &
3207  name=trim(cname)//"_import_grid", rc=rc )
3208  if (ESMF_LogFoundError(rc, PASSTHRU)) return
3209  case default
3210  write(msg,'(a,i1,a)') 'index closure ',iclose, &
3211  ' not supported for import grid'
3212  call ESMF_LogWrite(trim(msg), ESMF_LOGMSG_ERROR)
3213  rc = ESMF_FAILURE
3214  return
3215  endselect
3216  !
3217 import grid ! 2.b Add coordinate arrays and land/sea mask to
3218  !
3219  call ESMF_GridAddCoord( impGrid, staggerLoc=impStaggerLoc, rc=rc )
3220  if (ESMF_LogFoundError(rc, PASSTHRU)) return
3221  call ESMF_GridAddItem( impGrid, ESMF_GRIDITEM_MASK, &
3222  staggerLoc=impStaggerLoc, rc=rc )
3223  if (ESMF_LogFoundError(rc, PASSTHRU)) return
3224  !
3225 import grid storage ! 2.c Set flag to indicate that this processor has local
3226  !
3227  call ESMF_GridGet( impGrid, localDECount=ldecnt, rc=rc )
3228  if (ESMF_LogFoundError(rc, PASSTHRU)) return
3229 .gt. impGridIsLocal = ldecnt0
3230  !
3231 import grid ! 2.d Get exclusive bounds (global index) for
3232  !
3233  if ( impGridIsLocal ) then
3234  call ESMF_GridGet( impGrid, impStaggerLoc, lde, &
3235  exclusiveLBound=elb, exclusiveUBound=eub, rc=rc )
3236  if (ESMF_LogFoundError(rc, PASSTHRU)) return
3237  endif
3238  !
3239 import fields ! 2.e Set halo widths for
3240  !
3241  if ( impGridIsLocal ) then
3242  impHaloLWidth = (/impHaloWidth,impHaloWidth/)
3243  impHaloUWidth = (/impHaloWidth,impHaloWidth/)
3244  select case (iclose)
3245  case (iclose_none)
3246 .eq. if ( elb(1)1 ) impHaloLWidth(1) = 0
3247 .eq. if ( elb(2)1 ) impHaloLWidth(2) = 0
3248 .eq. if ( eub(1)nx ) impHaloUWidth(1) = 0
3249 .eq. if ( eub(2)ny ) impHaloUWidth(2) = 0
3250  case (iclose_smpl)
3251 .eq. if ( elb(2)1 ) impHaloLWidth(2) = 0
3252 .eq. if ( eub(2)ny ) impHaloUWidth(2) = 0
3253  endselect
3254  else
3255  impHaloLWidth = (/0,0/)
3256  impHaloUWidth = (/0,0/)
3257  endif
3258  !
3259 import grid coordinates ! 2.f Set ESMF
3260  !
3261  if ( impGridIsLocal ) then
3262  call ESMF_GridGetCoord( impGrid, 1, localDE=lde, &
3263  staggerLoc=impStaggerLoc, farrayPtr=rptrx, rc=rc )
3264  if (ESMF_LogFoundError(rc, PASSTHRU)) return
3265  call ESMF_GridGetCoord( impGrid, 2, localDE=lde, &
3266  staggerLoc=impStaggerLoc, farrayPtr=rptry, rc=rc )
3267  if (ESMF_LogFoundError(rc, PASSTHRU)) return
3268  do iy = elb(2),eub(2)
3269  do ix = elb(1),eub(1)
3270  rptrx(ix,iy) = xgrd(iy,ix)
3271  rptry(ix,iy) = ygrd(iy,ix)
3272  enddo
3273  enddo
3274  nullify(rptrx)
3275  nullify(rptry)
3276  endif
3277  !
3278 import grid land/sea mask values. ! 2.g Set ESMF
3279  ! Land/sea mask is fixed in time and based on excluded points only.
3280  !
3281  if ( impGridIsLocal ) then
3282  call ESMF_GridGetItem( impGrid, ESMF_GRIDITEM_MASK, localDE=lde, &
3283  staggerLoc=impStaggerLoc, farrayPtr=iptr, rc=rc )
3284  if (ESMF_LogFoundError(rc, PASSTHRU)) return
3285  do iy = elb(2),eub(2)
3286  do ix = elb(1),eub(1)
3287 .ne. if ( mapsta(iy,ix)0 ) then
3288  iptr(ix,iy) = maskValueWater
3289  else
3290  iptr(ix,iy) = maskValueLand
3291  endif
3292  enddo
3293  enddo
3294  endif
3295  !
3296 import grid corner coordinates ! 2.h Set ESMF
3297  !
3298 #ifdef W3_SCRIP
3299  call ESMF_GridAddCoord( impGrid, &
3300  staggerLoc=ESMF_STAGGERLOC_CORNER, rc=rc )
3301  if (ESMF_LogFoundError(rc, PASSTHRU)) return
3302 
3303  ! Calculate grid coordinates with help of SCRIP module
3304  ! It does not return coordinates of top-most row and
3305  ! right-most column but ESMF expects it. So, top-most row
3306  ! and right-most column are theated specially in below
3307  call get_scrip_info_structured(impGridID, &
3308  xgrd_center, ygrd_center, xgrd_corner, ygrd_corner, &
3309  land_sea, grid_dims, grid_size, grid_corners, grid_rank)
3310 
3311  ! Add corner coordinates
3312  if ( impGridIsLocal ) then
3313  ! Retrieve pointers
3314  call ESMF_GridGetCoord( impGrid, 1, localDE=lde, &
3315  staggerLoc=ESMF_STAGGERLOC_CORNER, farrayPtr=rptrx, rc=rc )
3316  if (ESMF_LogFoundError(rc, PASSTHRU)) return
3317  call ESMF_GridGetCoord( impGrid, 2, localDE=lde, &
3318  staggerLoc=ESMF_STAGGERLOC_CORNER, farrayPtr=rptry, rc=rc )
3319  if (ESMF_LogFoundError(rc, PASSTHRU)) return
3320 
3321 import grid ! Get exclusive bounds (global index) for
3322  ! corner coordinates
3323  call ESMF_GridGet( impGrid, ESMF_STAGGERLOC_CORNER, lde, &
3324  exclusiveLBound=elbc, exclusiveUBound=eubc, rc=rc )
3325  if (ESMF_LogFoundError(rc, PASSTHRU)) return
3326 
3327  ! Adjust upper bounds for specific PEs
3328  ubx = 0
3329  uby = 0
3330  if (eubc(1) == grid_dims(1)+1) ubx = -1
3331  if (eubc(2) == grid_dims(2)+1) uby = -1
3332 
3333  ! Fill coordinates
3334  do iy = elbc(2),eubc(2)+uby
3335  do ix = elbc(1),eubc(1)+ubx
3336  irec = (iy-1)*grid_dims(1)+ix
3337  rptrx(ix,iy) = real(xgrd_corner(1,irec), kind=ESMF_KIND_RX)
3338  rptry(ix,iy) = real(ygrd_corner(1,irec), kind=ESMF_KIND_RX)
3339  enddo
3340  enddo
3341 
3342  ! Fill data on top-most row
3343  if (eubc(2) == grid_dims(2)+1) then
3344  do ix = elbc(1),eubc(1)+ubx
3345  rptrx(ix,grid_dims(2)+1) = rptrx(ix,grid_dims(2))+ &
3346  (rptrx(ix,grid_dims(2))-rptrx(ix,grid_dims(2)-1))
3347  rptry(ix,grid_dims(2)+1) = rptry(ix,grid_dims(2))+ &
3348  (rptry(ix,grid_dims(2))-rptry(ix,grid_dims(2)-1))
3349  end do
3350  end if
3351 
3352  ! Fill data on right-most column
3353  if (eubc(1) == grid_dims(1)+1) then
3354  do iy = elbc(2),eubc(2)+uby
3355  rptrx(grid_dims(1)+1,iy) = rptrx(grid_dims(1),iy)+ &
3356  (rptrx(grid_dims(1),iy)-rptrx(grid_dims(1)-1,iy))
3357  rptry(grid_dims(1)+1,iy) = rptry(grid_dims(1),iy)+ &
3358  (rptry(grid_dims(1),iy)-rptry(grid_dims(1)-1,iy))
3359  end do
3360  end if
3361 
3362  ! Fill data on top-right corner, single point
3363 .and. if (eubc(1) == grid_dims(1)+1 eubc(2) == grid_dims(2)+1) then
3364  rptrx(grid_dims(1)+1,grid_dims(2)+1) = &
3365  rptrx(grid_dims(1)+1,grid_dims(2))
3366  rptry(grid_dims(1)+1,grid_dims(2)+1) = &
3367  rptry(grid_dims(1),grid_dims(2)+1)
3368  end if
3369  endif
3370 #endif
3371  !
3372  ! -------------------------------------------------------------------- /
3373 import field mask and routehandle halo update ! 3. Create
3374  !
3375 import grid land/sea mask. ! 3.a Create field for
3376  !
3377  impMask = ESMF_FieldCreate( impGrid, impArraySpec2D, &
3378  totalLWidth=impHaloLWidth, totalUWidth=impHaloUWidth, &
3379  staggerLoc=impStaggerLoc, indexFlag=impIndexFlag, &
3380  name='mask', rc=rc )
3381  if (ESMF_LogFoundError(rc, PASSTHRU)) return
3382  !
3383 import field halo routehandle ! 3.b Store
3384  !
3385  call ESMF_FieldHaloStore( impMask, routeHandle=impHaloRH, rc=rc )
3386  if (ESMF_LogFoundError(rc, PASSTHRU)) return
3387  !
3388 import field land/sea mask values and update halos ! 3.c Set
3389  !
3390  if ( impGridIsLocal ) then
3391  call ESMF_FieldGet( impMask, localDE=lde, farrayPtr=rptr, &
3392  totalLBound=tlb, totalUBound=tub, rc=rc )
3393  if (ESMF_LogFoundError(rc, PASSTHRU)) return
3394  do iy = elb(2),eub(2)
3395  do ix = elb(1),eub(1)
3396  rptr(ix,iy) = iptr(ix,iy)
3397  enddo
3398  enddo
3399  endif
3400 
3401  call ESMF_FieldHalo( impMask, impHaloRH, rc=rc )
3402  if (ESMF_LogFoundError(rc, PASSTHRU)) return
3403  !
3404  ! -------------------------------------------------------------------- /
3405  ! Post
3406  !
3407 #if defined(TEST_WMESMFMD) || defined(TEST_WMESMFMD_CREATEIMPGRID)
3408  write(msg,'(a,i6)') ' impgridid: ',impGridID
3409  call ESMF_LogWrite(trim(cname)//': createimpgrid: '//trim(msg), ESMF_LOGMSG_INFO)
3410  write(msg,'(a,l6)') 'impgridislocal: ',impGridIsLocal
3411  call ESMF_LogWrite(trim(cname)//': createimpgrid: '//trim(msg), ESMF_LOGMSG_INFO)
3412  write(msg,'(a,2i6)') ' nx, ny: ',nx,ny
3413  call ESMF_LogWrite(trim(cname)//': createimpgrid: '//trim(msg), ESMF_LOGMSG_INFO)
3414  write(msg,'(a,2i6)') 'naproc, nmproc: ',naproc,nmproc
3415  call ESMF_LogWrite(trim(cname)//': createimpgrid: '//trim(msg), ESMF_LOGMSG_INFO)
3416  write(msg,'(a,i6)') ' nproc: ',nproc
3417  call ESMF_LogWrite(trim(cname)//': createimpgrid: '//trim(msg), ESMF_LOGMSG_INFO)
3418  write(msg,'(a,2i6)') 'nxproc, nyproc: ',nxproc,nyproc
3419  call ESMF_LogWrite(trim(cname)//': createimpgrid: '//trim(msg), ESMF_LOGMSG_INFO)
3420  write(msg,'(a,2i6)') ' elb: ',elb(:)
3421  call ESMF_LogWrite(trim(cname)//': createimpgrid: '//trim(msg), ESMF_LOGMSG_INFO)
3422  write(msg,'(a,2i6)') ' eub: ',eub(:)
3423  call ESMF_LogWrite(trim(cname)//': createimpgrid: '//trim(msg), ESMF_LOGMSG_INFO)
3424  write(msg,'(a,2i6)') ' tlb: ',tlb(:)
3425  call ESMF_LogWrite(trim(cname)//': createimpgrid: '//trim(msg), ESMF_LOGMSG_INFO)
3426  write(msg,'(a,2i6)') ' tub: ',tub(:)
3427  call ESMF_LogWrite(trim(cname)//': createimpgrid: '//trim(msg), ESMF_LOGMSG_INFO)
3428  write(msg,'(a,2i6)') ' imphalolwidth: ',impHaloLWidth(:)
3429  call ESMF_LogWrite(trim(cname)//': createimpgrid: '//trim(msg), ESMF_LOGMSG_INFO)
3430  write(msg,'(a,2i6)') ' imphalouwidth: ',impHaloUWidth(:)
3431  call ESMF_LogWrite(trim(cname)//': createimpgrid: '//trim(msg), ESMF_LOGMSG_INFO)
3432  call ESMF_FieldWrite( impMask, &
3433  "wmesmfmd_createimpgrid_import_mask.nc", overwrite=.true., rc=rc )
3434  if (ESMF_LogFoundError(rc, PASSTHRU)) return
3435  tmpField = ESMF_FieldCreate( impGrid, impArraySpec2D, &
3436  totalLWidth=impHaloLWidth, totalUWidth=impHaloUWidth, &
3437  staggerLoc=impStaggerLoc, indexFlag=impIndexFlag, &
3438  name='temp', rc=rc )
3439  if (ESMF_LogFoundError(rc, PASSTHRU)) return
3440  if ( impGridIsLocal ) then
3441  call ESMF_FieldGet( tmpField, localDE=lde, farrayPtr=rptr, rc=rc )
3442  if (ESMF_LogFoundError(rc, PASSTHRU)) return
3443  endif
3444  if ( impGridIsLocal ) then
3445  do iy = elb(2),eub(2)
3446  do ix = elb(1),eub(1)
3447  rptr(ix,iy) = xgrd(iy,ix)
3448  enddo
3449  enddo
3450  endif
3451  call ESMF_FieldWrite( tmpField, &
3452  "wmesmfmd_createimpgrid_import_xgrd.nc", overwrite=.true., rc=rc )
3453  if (ESMF_LogFoundError(rc, PASSTHRU)) return
3454  if ( impGridIsLocal ) then
3455  do iy = elb(2),eub(2)
3456  do ix = elb(1),eub(1)
3457  rptr(ix,iy) = ygrd(iy,ix)
3458  enddo
3459  enddo
3460  endif
3461  call ESMF_FieldWrite( tmpField, &
3462  "wmesmfmd_createimpgrid_import_ygrd.nc", overwrite=.true., rc=rc )
3463  if (ESMF_LogFoundError(rc, PASSTHRU)) return
3464  if ( impGridIsLocal ) then
3465  do iy = elb(2),eub(2)
3466  do ix = elb(1),eub(1)
3467  rptr(ix,iy) = hpfac(iy,ix)
3468  enddo
3469  enddo
3470  endif
3471  call ESMF_FieldWrite( tmpField, &
3472  "wmesmfmd_createimpgrid_import_hpfac.nc", overwrite=.true., rc=rc )
3473  if (ESMF_LogFoundError(rc, PASSTHRU)) return
3474  if ( impGridIsLocal ) then
3475  do iy = elb(2),eub(2)
3476  do ix = elb(1),eub(1)
3477  rptr(ix,iy) = hqfac(iy,ix)
3478  enddo
3479  enddo
3480  endif
3481  call ESMF_FieldWrite( tmpField, &
3482  "wmesmfmd_createimpgrid_import_hqfac.nc", overwrite=.true., rc=rc )
3483  if (ESMF_LogFoundError(rc, PASSTHRU)) return
3484  if ( impGridIsLocal ) then
3485  do iy = elb(2),eub(2)
3486  do ix = elb(1),eub(1)
3487  rptr(ix,iy) = lpet
3488  enddo
3489  enddo
3490  endif
3491  call ESMF_FieldWrite( tmpField, &
3492  "wmesmfmd_createimpgrid_import_dcomp.nc", overwrite=.true., rc=rc )
3493  if (ESMF_LogFoundError(rc, PASSTHRU)) return
3494  call ESMF_FieldDestroy( tmpField, rc=rc )
3495  if (ESMF_LogFoundError(rc, PASSTHRU)) return
3496 #endif
3497  !
3498  rc = ESMF_SUCCESS
3499 .gt. if (verbosity0) call ESMF_LogWrite(trim(cname)// &
3500  ': leaving createimpgrid', ESMF_LOGMSG_INFO)
3501  !/
3502  !/ End of CreateImpGrid ---------------------------------------------- /
3503  !/
3504  end subroutine CreateImpGrid
3505  !/ ------------------------------------------------------------------- /
3506  !/
3507 #undef METHOD
3508 #define METHOD "CreateExpGrid"
3509  !>
3510  !> @brief Create ESMF grid for export fields
3511  !>
3512  !> @param gcomp Gridded component
3513  !> @param[out] rc Return code
3514  !>
3515  !> @author T. J. Campbell @date 20-Jan-2017
3516  !>
3517  subroutine CreateExpGrid ( gcomp, rc )
3518  !/
3519  !/ +-----------------------------------+
3520  !/ | WAVEWATCH III NOAA/NCEP |
3521  !/ | T. J. Campbell, NRL |
3522  !/ | FORTRAN 90 |
3523  !/ | Last update : 20-Jan-2017 |
3524  !/ +-----------------------------------+
3525  !/
3526  !/ 20-Jan-2017 : Origination. ( version 6.02 )
3527  !/
3528  ! 1. Purpose :
3529  !
3530  !
3531  !
3532  ! 2. Method :
3533  !
3534  ! 3. Parameters :
3535  !
3536  ! Parameter list
3537  ! ----------------------------------------------------------------
3538  ! gcomp Type I/O Gridded component
3539  ! rc Int. O Return code
3540  ! ----------------------------------------------------------------
3541  !
3542  ! 4. Subroutines used :
3543  !
3544  ! Name Type Module Description
3545  ! ----------------------------------------------------------------
3546  ! NONE
3547  ! ----------------------------------------------------------------
3548  !
3549  ! 5. Called by :
3550  !
3551  ! 6. Error messages :
3552  !
3553  ! 7. Remarks :
3554  !
3555  ! 8. Structure :
3556  !
3557  ! 9. Switches :
3558  !
3559  ! !/SHRD Switch for shared / distributed memory architecture.
3560  ! !/DIST Id.
3561  !
3562  ! 10. Source code :
3563  !
3564  !/ ------------------------------------------------------------------- /
3565  !/
3566  !/ ------------------------------------------------------------------- /
3567  !/ Parameter list
3568  !/
3569  implicit none
3570  type(ESMF_GridComp) :: gcomp
3571  integer,intent(out) :: rc
3572  !/
3573  !/ ------------------------------------------------------------------- /
3574  !/ Local parameters
3575  !/
3576  character(ESMF_MAXSTR) :: cname
3577  integer :: nproc, nxproc, nyproc
3578  integer, parameter :: lde = 0
3579  integer :: ldecnt
3580  integer :: ix, iy, isea, jsea, irec, k, ubx, uby
3581  integer :: elb(2), eub(2), elbc(2), eubc(2)
3582  integer :: tlb(2), tub(2)
3583  integer(ESMF_KIND_I4), pointer :: iptr(:,:)
3584  real(ESMF_KIND_RX), pointer :: rptrx(:,:), rptry(:,:)
3585  real(ESMF_KIND_RX), pointer :: rptr(:,:)
3586  real(ESMF_KIND_R8), allocatable :: xgrd_center(:)
3587  real(ESMF_KIND_R8), allocatable :: ygrd_center(:)
3588  real(ESMF_KIND_R8), allocatable :: xgrd_corner(:,:)
3589  real(ESMF_KIND_R8), allocatable :: ygrd_corner(:,:)
3590  logical, allocatable :: land_sea(:)
3591  integer, allocatable :: grid_dims(:)
3592  integer :: grid_size, grid_corners, grid_rank
3593  integer :: arbIndexCount
3594  integer, allocatable :: arbIndexList(:,:)
3595  type(ESMF_Field) :: nField, eField
3596  type(ESMF_Field) :: tmpField
3597  !
3598  ! -------------------------------------------------------------------- /
3599  ! Prep
3600  !
3601  rc = ESMF_SUCCESS
3602  if ( noActiveExpFields ) return
3603  call ESMF_GridCompGet(gcomp, name=cname, rc=rc)
3604  if (ESMF_LogFoundError(rc, PASSTHRU)) return
3605 .gt. if (verbosity0) call ESMF_LogWrite(trim(cname)// &
3606  ': entered createexpgrid', ESMF_LOGMSG_INFO)
3607  !
3608  ! -------------------------------------------------------------------- /
3609  ! 1. Setup
3610  !
3611  ! 1.a Set grid pointers
3612  !
3613  !TODO: only export from one grid
3614  !expGridID set from config input (default = 1)
3615  call w3setg ( expGridID, mdse, mdst )
3616  call w3setw ( expGridID, mdse, mdst )
3617  call w3seta ( expGridID, mdse, mdst )
3618  call w3seti ( expGridID, mdse, mdst )
3619  call w3seto ( expGridID, mdse, mdst )
3620  call wmsetm ( expGridID, mdse, mdst )
3621  natGridID = expGridID
3622  nproc = naproc
3623  !
3624  ! 1.b Compute a 2D subdomain layout based on nproc
3625  !
3626  call CalcDecomp( nx, ny, nproc, expHaloWidth, .true., nxproc, nyproc, rc )
3627  if (ESMF_LogFoundError(rc, PASSTHRU)) return
3628  !
3629  ! 1.c Set arraySpec, staggerLoc, and indexFlag for export fields
3630  !
3631  call ESMF_ArraySpecSet( expArraySpec2D, rank=2, &
3632  typekind=ESMF_TYPEKIND_RX, rc=rc )
3633  if (ESMF_LogFoundError(rc, PASSTHRU)) return
3634  call ESMF_ArraySpecSet( expArraySpec3D, rank=3, &
3635  typekind=ESMF_TYPEKIND_RX, rc=rc )
3636  if (ESMF_LogFoundError(rc, PASSTHRU)) return
3637  expStaggerLoc = ESMF_STAGGERLOC_CENTER
3638  expIndexFlag = ESMF_INDEX_GLOBAL
3639  !
3640  ! 1.d Set arraySpec, staggerLoc, and indexFlag for native fields
3641  !
3642  call ESMF_ArraySpecSet( natArraySpec2D, rank=1, &
3643  typekind=ESMF_TYPEKIND_RX, rc=rc )
3644  if (ESMF_LogFoundError(rc, PASSTHRU)) return
3645  call ESMF_ArraySpecSet( natArraySpec3D, rank=2, &
3646  typekind=ESMF_TYPEKIND_RX, rc=rc )
3647  if (ESMF_LogFoundError(rc, PASSTHRU)) return
3648  natStaggerLoc = ESMF_STAGGERLOC_CENTER
3649  natIndexFlag = ESMF_INDEX_DELOCAL
3650  !
3651  ! 1.e Get z-levels for 3D export fields
3652  !
3653  call GetZlevels( rc )
3654  if (ESMF_LogFoundError(rc, PASSTHRU)) return
3655  write(msg,'(a)') 'input z-level file: '//trim(zlfile)
3656  call ESMF_LogWrite(trim(cname)//': '//trim(msg), ESMF_LOGMSG_INFO)
3657  write(msg,'(a)') 'table of z-levels'
3658  call ESMF_LogWrite(trim(cname)//': '//trim(msg), ESMF_LOGMSG_INFO)
3659  write(msg,'(a)') ' index z'
3660  call ESMF_LogWrite(trim(cname)//': '//trim(msg), ESMF_LOGMSG_INFO)
3661  do k=1,nz
3662  write(msg,'(i8,1f10.2)') k, zl(k)
3663  call ESMF_LogWrite(trim(cname)//': '//trim(msg), ESMF_LOGMSG_INFO)
3664  enddo
3665  !
3666  ! -------------------------------------------------------------------- /
3667  ! 2. Create ESMF grid for export with 2D subdomain layout
3668  ! Note that the ESMF grid layout is dim1=X, dim2=Y
3669  !
3670  ! 2.a Create ESMF export grid
3671  !
3672  select case (iclose)
3673  case (iclose_none)
3674  expGrid = ESMF_GridCreateNoPeriDim( &
3675  minIndex=(/ 1, 1/), &
3676  maxIndex=(/nx,ny/), &
3677  coordDep1=(/1,2/), &
3678  coordDep2=(/1,2/), &
3679  regDecomp=(/nxproc,nyproc/), &
3680  decompFlag=(/ESMF_DECOMP_BALANCED,ESMF_DECOMP_BALANCED/), &
3681  coordTypeKind=ESMF_TYPEKIND_RX, &
3682  coordSys=ESMF_COORDSYS_SPH_DEG, &
3683  indexFlag=expIndexFlag, &
3684  name=trim(cname)//"_export_grid", rc=rc )
3685  if (ESMF_LogFoundError(rc, PASSTHRU)) return
3686  case (iclose_smpl)
3687  expGrid = ESMF_GridCreate1PeriDim( &
3688  periodicDim=1, &
3689  poleDim=2, &
3690  poleKindFlag=(/ESMF_POLEKIND_NONE,ESMF_POLEKIND_NONE/), &
3691  minIndex=(/ 1, 1/), &
3692  maxIndex=(/nx,ny/), &
3693  coordDep1=(/1,2/), &
3694  coordDep2=(/1,2/), &
3695  regDecomp=(/nxproc,nyproc/), &
3696  decompFlag=(/ESMF_DECOMP_BALANCED,ESMF_DECOMP_BALANCED/), &
3697  coordTypeKind=ESMF_TYPEKIND_RX, &
3698  coordSys=ESMF_COORDSYS_SPH_DEG, &
3699  indexFlag=expIndexFlag, &
3700  name=trim(cname)//"_export_grid", rc=rc )
3701  if (ESMF_LogFoundError(rc, PASSTHRU)) return
3702  case default
3703  write(msg,'(a,i1,a)') 'index closure ',iclose, &
3704  ' not supported for export grid'
3705  call ESMF_LogWrite(trim(msg), ESMF_LOGMSG_ERROR)
3706  rc = ESMF_FAILURE
3707  return
3708  endselect
3709  !
3710  ! 2.b Add coordinate arrays and land/sea mask to export grid
3711  !
3712  call ESMF_GridAddCoord( expGrid, staggerLoc=expStaggerLoc, rc=rc )
3713  if (ESMF_LogFoundError(rc, PASSTHRU)) return
3714  call ESMF_GridAddItem( expGrid, ESMF_GRIDITEM_MASK, &
3715  staggerLoc=expStaggerLoc, rc=rc )
3716  if (ESMF_LogFoundError(rc, PASSTHRU)) return
3717  !
3718  ! 2.c Set flag to indicate that this processor has local export grid storage
3719  !
3720  call ESMF_GridGet( expGrid, localDECount=ldecnt, rc=rc )
3721  if (ESMF_LogFoundError(rc, PASSTHRU)) return
3722 .gt. expGridIsLocal = ldecnt0
3723  !
3724  ! 2.d Get exclusive bounds (global index) for export grid
3725  !
3726  if ( expGridIsLocal ) then
3727  call ESMF_GridGet( expGrid, expStaggerLoc, lde, &
3728  exclusiveLBound=elb, exclusiveUBound=eub, rc=rc )
3729  if (ESMF_LogFoundError(rc, PASSTHRU)) return
3730  endif
3731  !
3732  ! 2.e Set halo widths for export fields
3733  !
3734  if ( expGridIsLocal ) then
3735  expHaloLWidth = (/expHaloWidth,expHaloWidth/)
3736  expHaloUWidth = (/expHaloWidth,expHaloWidth/)
3737  select case (iclose)
3738  case (iclose_none)
3739 .eq. if ( elb(1)1 ) expHaloLWidth(1) = 0
3740 .eq. if ( elb(2)1 ) expHaloLWidth(2) = 0
3741 .eq. if ( eub(1)nx ) expHaloUWidth(1) = 0
3742 .eq. if ( eub(2)ny ) expHaloUWidth(2) = 0
3743  case (iclose_smpl)
3744 .eq. if ( elb(2)1 ) expHaloLWidth(2) = 0
3745 .eq. if ( eub(2)ny ) expHaloUWidth(2) = 0
3746  endselect
3747  else
3748  expHaloLWidth = (/0,0/)
3749  expHaloUWidth = (/0,0/)
3750  endif
3751  !
3752  ! 2.f Set ESMF export grid coordinate
3753  !
3754  if ( expGridIsLocal ) then
3755  call ESMF_GridGetCoord( expGrid, 1, localDE=lde, &
3756  staggerLoc=expStaggerLoc, farrayPtr=rptrx, rc=rc )
3757  if (ESMF_LogFoundError(rc, PASSTHRU)) return
3758  call ESMF_GridGetCoord( expGrid, 2, localDE=lde, &
3759  staggerLoc=expStaggerLoc, farrayPtr=rptry, rc=rc )
3760  if (ESMF_LogFoundError(rc, PASSTHRU)) return
3761  do iy = elb(2),eub(2)
3762  do ix = elb(1),eub(1)
3763  rptrx(ix,iy) = xgrd(iy,ix)
3764  rptry(ix,iy) = ygrd(iy,ix)
3765  enddo
3766  enddo
3767  endif
3768  !
3769  ! 2.g Set ESMF export grid land/sea mask values.
3770  ! Land/sea mask is fixed in time and based on excluded points only.
3771  !
3772  if ( expGridIsLocal ) then
3773  call ESMF_GridGetItem( expGrid, ESMF_GRIDITEM_MASK, localDE=lde, &
3774  staggerLoc=expStaggerLoc, farrayPtr=iptr, rc=rc )
3775  if (ESMF_LogFoundError(rc, PASSTHRU)) return
3776  do iy = elb(2),eub(2)
3777  do ix = elb(1),eub(1)
3778 .ne. if ( mapsta(iy,ix)0 ) then
3779  iptr(ix,iy) = maskValueWater
3780  else
3781  iptr(ix,iy) = maskValueLand
3782  endif
3783  enddo
3784  enddo
3785  endif
3786  !
3787  ! 2.h Set ESMF export grid corner coordinates
3788  !
3789 #ifdef W3_SCRIP
3790  call ESMF_GridAddCoord( expGrid, &
3791  staggerLoc=ESMF_STAGGERLOC_CORNER, rc=rc )
3792  if (ESMF_LogFoundError(rc, PASSTHRU)) return
3793 
3794  ! Calculate grid coordinates with help of SCRIP module
3795  ! It does not return coordinates of top-most row and
3796  ! right-most column but ESMF expects it. So, top-most row
3797  ! and right-most column are theated specially in below
3798  call get_scrip_info_structured(expGridID, &
3799  xgrd_center, ygrd_center, xgrd_corner, ygrd_corner, &
3800  land_sea, grid_dims, grid_size, grid_corners, grid_rank)
3801 
3802  ! Add corner coordinates
3803  if ( impGridIsLocal ) then
3804  ! Retrieve pointers
3805  call ESMF_GridGetCoord( expGrid, 1, localDE=lde, &
3806  staggerLoc=ESMF_STAGGERLOC_CORNER, farrayPtr=rptrx, rc=rc )
3807  if (ESMF_LogFoundError(rc, PASSTHRU)) return
3808  call ESMF_GridGetCoord( expGrid, 2, localDE=lde, &
3809  staggerLoc=ESMF_STAGGERLOC_CORNER, farrayPtr=rptry, rc=rc )
3810  if (ESMF_LogFoundError(rc, PASSTHRU)) return
3811 
3812  ! Get exclusive bounds (global index) for export grid
3813  ! corner coordinates
3814  call ESMF_GridGet( impGrid, ESMF_STAGGERLOC_CORNER, lde, &
3815  exclusiveLBound=elbc, exclusiveUBound=eubc, rc=rc )
3816  if (ESMF_LogFoundError(rc, PASSTHRU)) return
3817 
3818  ! Adjust upper bounds for specific PEs
3819  ubx = 0
3820  uby = 0
3821  if (eubc(1) == grid_dims(1)+1) ubx = -1
3822  if (eubc(2) == grid_dims(2)+1) uby = -1
3823 
3824  ! Fill coordinates
3825  do iy = elbc(2),eubc(2)+uby
3826  do ix = elbc(1),eubc(1)+ubx
3827  irec = (iy-1)*grid_dims(1)+ix
3828  rptrx(ix,iy) = real(xgrd_corner(1,irec), kind=ESMF_KIND_RX)
3829  rptry(ix,iy) = real(ygrd_corner(1,irec), kind=ESMF_KIND_RX)
3830  enddo
3831  enddo
3832 
3833  ! Fill data on top-most row
3834  if (eubc(2) == grid_dims(2)+1) then
3835  do ix = elbc(1),eubc(1)+ubx
3836  rptrx(ix,grid_dims(2)+1) = rptrx(ix,grid_dims(2))+ &
3837  (rptrx(ix,grid_dims(2))-rptrx(ix,grid_dims(2)-1))
3838  rptry(ix,grid_dims(2)+1) = rptry(ix,grid_dims(2))+ &
3839  (rptry(ix,grid_dims(2))-rptry(ix,grid_dims(2)-1))
3840  end do
3841  end if
3842 
3843  ! Fill data on right-most column
3844  if (eubc(1) == grid_dims(1)+1) then
3845  do iy = elbc(2),eubc(2)+uby
3846  rptrx(grid_dims(1)+1,iy) = rptrx(grid_dims(1),iy)+ &
3847  (rptrx(grid_dims(1),iy)-rptrx(grid_dims(1)-1,iy))
3848  rptry(grid_dims(1)+1,iy) = rptry(grid_dims(1),iy)+ &
3849  (rptry(grid_dims(1),iy)-rptry(grid_dims(1)-1,iy))
3850  end do
3851  end if
3852 
3853  ! Fill data on top-right corner, single point
3854 .and. if (eubc(1) == grid_dims(1)+1 eubc(2) == grid_dims(2)+1) then
3855  rptrx(grid_dims(1)+1,grid_dims(2)+1) = &
3856  rptrx(grid_dims(1)+1,grid_dims(2))
3857  rptry(grid_dims(1)+1,grid_dims(2)+1) = &
3858  rptry(grid_dims(1),grid_dims(2)+1)
3859  end if
3860  end if
3861 #endif
3862  !
3863  ! -------------------------------------------------------------------- /
3864  ! 3. Create export field mask and routeHandle halo update
3865  !
3866  ! 3.a Create field for export grid land/sea mask.
3867  !
3868  expMask = ESMF_FieldCreate( expGrid, expArraySpec2D, &
3869  totalLWidth=expHaloLWidth, totalUWidth=expHaloUWidth, &
3870  staggerLoc=expStaggerLoc, indexFlag=expIndexFlag, &
3871  name='mask', rc=rc )
3872  if (ESMF_LogFoundError(rc, PASSTHRU)) return
3873  !
3874  ! 3.b Store export field halo routeHandle
3875  !
3876  call ESMF_FieldHaloStore( expMask, routeHandle=expHaloRH, rc=rc )
3877  if (ESMF_LogFoundError(rc, PASSTHRU)) return
3878  !
3879  ! 3.c Set export field land/sea mask values and update halos
3880  !
3881  if ( expGridIsLocal ) then
3882  call ESMF_FieldGet( expMask, localDE=lde, farrayPtr=rptr, &
3883  totalLBound=tlb, totalUBound=tub, rc=rc )
3884  if (ESMF_LogFoundError(rc, PASSTHRU)) return
3885  do iy = elb(2),eub(2)
3886  do ix = elb(1),eub(1)
3887  rptr(ix,iy) = iptr(ix,iy)
3888  enddo
3889  enddo
3890  endif
3891 
3892  call ESMF_FieldHalo( expMask, expHaloRH, rc=rc )
3893  if (ESMF_LogFoundError(rc, PASSTHRU)) return
3894  !
3895  ! -------------------------------------------------------------------- /
3896  ! 4. Create ESMF grid with arbitrary domain decomposition to match
3897  ! the native domain decomposition of the non-excluded points
3898  ! Note that the native grid layout is dim1=X, dim2=Y
3899  ! Note that coordinates and mask are not needed since this
3900  ! grid is only used to define fields for a redist operation
3901  !
3902  ! 4.a Set flag to indicate that this processor has local native grid storage
3903  !
3904 .gt..and..le. natGridIsLocal = iaproc 0 iaproc naproc
3905  !
3906  ! 4.b Setup arbitrary sequence index list
3907  !
3908  do ipass = 1,2
3909 .eq. if (ipass2) then
3910  allocate (arbIndexList(arbIndexCount,2), stat=rc)
3911  if (ESMF_LogFoundAllocError(rc, PASSTHRU)) return
3912  endif
3913  arbIndexCount = 0
3914  ! list local native grid non-excluded points
3915  if ( natGridIsLocal ) then
3916  do jsea = 1,nseal
3917 #ifdef W3_DIST
3918  isea = iaproc + (jsea-1)*naproc
3919 #endif
3920 #ifdef W3_SHRD
3921  isea = jsea
3922 #endif
3923  arbIndexCount = arbIndexCount+1
3924 .eq. if (ipass2) then
3925  ix = mapsf(isea,1)
3926  iy = mapsf(isea,2)
3927  ! native grid layout: dim1=X, dim2=Y
3928  arbIndexList(arbIndexCount,1) = ix
3929  arbIndexList(arbIndexCount,2) = iy
3930  endif
3931  enddo
3932  endif
3933  ! list local export grid excluded points
3934  if ( expGridIsLocal ) then
3935  do iy = elb(2),eub(2)
3936  do ix = elb(1),eub(1)
3937 .ne. if ( mapsta(iy,ix)0 ) cycle ! skip non-excluded point
3938  arbIndexCount = arbIndexCount+1
3939 .eq. if (ipass2) then
3940  ! native grid layout: dim1=X, dim2=Y
3941  arbIndexList(arbIndexCount,1) = ix
3942  arbIndexList(arbIndexCount,2) = iy
3943  endif
3944  enddo
3945  enddo
3946  endif
3947  enddo !ipass
3948  !
3949  ! 4.c Create ESMF native grid
3950  !
3951  select case (iclose)
3952  case (iclose_none)
3953  natGrid = ESMF_GridCreateNoPeriDim( &
3954  minIndex=(/ 1, 1/), &
3955  maxIndex=(/nx,ny/), &
3956  coordDep1=(/ESMF_DIM_ARB,ESMF_DIM_ARB/), &
3957  coordDep2=(/ESMF_DIM_ARB,ESMF_DIM_ARB/), &
3958  arbIndexCount=arbIndexCount, &
3959  arbIndexList=arbIndexList, &
3960  coordTypeKind=ESMF_TYPEKIND_RX, &
3961  coordSys=ESMF_COORDSYS_SPH_DEG, &
3962  name=trim(cname)//"_native_grid", rc=rc )
3963  if (ESMF_LogFoundError(rc, PASSTHRU)) return
3964  case (iclose_smpl)
3965  natGrid = ESMF_GridCreate1PeriDim( &
3966  periodicDim=1, &
3967  poleDim=2, &
3968  poleKindFlag=(/ESMF_POLEKIND_NONE,ESMF_POLEKIND_NONE/), &
3969  minIndex=(/ 1, 1/), &
3970  maxIndex=(/nx,ny/), &
3971  coordDep1=(/ESMF_DIM_ARB,ESMF_DIM_ARB/), &
3972  coordDep2=(/ESMF_DIM_ARB,ESMF_DIM_ARB/), &
3973  arbIndexCount=arbIndexCount, &
3974  arbIndexList=arbIndexList, &
3975  coordTypeKind=ESMF_TYPEKIND_RX, &
3976  coordSys=ESMF_COORDSYS_SPH_DEG, &
3977  name=trim(cname)//"_native_grid", rc=rc )
3978  if (ESMF_LogFoundError(rc, PASSTHRU)) return
3979  case default
3980  write(msg,'(a,i1,a)') 'index closure ',iclose, &
3981  ' not supported for native grid'
3982  call ESMF_LogWrite(trim(msg), ESMF_LOGMSG_ERROR)
3983  rc = ESMF_FAILURE
3984  return
3985  endselect
3986  !
3987  ! 4.d Deallocate arbitrary sequence index list
3988  !
3989  deallocate (arbIndexList, stat=rc)
3990  if (ESMF_LogFoundDeallocError(rc, PASSTHRU)) return
3991  !
3992  ! -------------------------------------------------------------------- /
3993  ! 5. Create route handle for redist between native grid domain
3994  ! decomposition and the export grid domain decomposition
3995  !
3996  ! 5.a Create temporary fields
3997  !
3998  nField = ESMF_FieldCreate( natGrid, natArraySpec2D, &
3999  staggerLoc=natStaggerLoc, rc=rc )
4000  if (ESMF_LogFoundError(rc, PASSTHRU)) return
4001  eField = ESMF_FieldCreate( expGrid, expArraySpec2D, &
4002  totalLWidth=expHaloLWidth, totalUWidth=expHaloUWidth, &
4003  staggerLoc=expStaggerLoc, indexFlag=expIndexFlag, rc=rc )
4004  if (ESMF_LogFoundError(rc, PASSTHRU)) return
4005  !
4006  ! 5.b Store route handle
4007  !
4008  call ESMF_FieldRedistStore( nField, eField, n2eRH, rc=rc )
4009  if (ESMF_LogFoundError(rc, PASSTHRU)) return
4010  !
4011  ! 5.c Clean up
4012  !
4013  call ESMF_FieldDestroy( nField, rc=rc )
4014  if (ESMF_LogFoundError(rc, PASSTHRU)) return
4015  call ESMF_FieldDestroy( eField, rc=rc )
4016  if (ESMF_LogFoundError(rc, PASSTHRU)) return
4017  !
4018  ! -------------------------------------------------------------------- /
4019  ! Post
4020  !
4021 #if defined(TEST_WMESMFMD) || defined(TEST_WMESMFMD_CREATEEXPGRID)
4022  write(msg,'(a,i6)') ' expgridid: ',expGridID
4023  call ESMF_LogWrite(trim(cname)//': createexpgrid: '//trim(msg), ESMF_LOGMSG_INFO)
4024  write(msg,'(a,l6)') 'expgridislocal: ',expGridIsLocal
4025  call ESMF_LogWrite(trim(cname)//': createexpgrid: '//trim(msg), ESMF_LOGMSG_INFO)
4026  write(msg,'(a,2i6)') ' nx, ny: ',nx,ny
4027  call ESMF_LogWrite(trim(cname)//': createexpgrid: '//trim(msg), ESMF_LOGMSG_INFO)
4028  write(msg,'(a,2i6)') 'naproc, nmproc: ',naproc,nmproc
4029  call ESMF_LogWrite(trim(cname)//': createexpgrid: '//trim(msg), ESMF_LOGMSG_INFO)
4030  write(msg,'(a,i6)') ' nproc: ',nproc
4031  call ESMF_LogWrite(trim(cname)//': createexpgrid: '//trim(msg), ESMF_LOGMSG_INFO)
4032  write(msg,'(a,2i6)') 'nxproc, nyproc: ',nxproc,nyproc
4033  call ESMF_LogWrite(trim(cname)//': createexpgrid: '//trim(msg), ESMF_LOGMSG_INFO)
4034  write(msg,'(a,2i6)') ' elb: ',elb(:)
4035  call ESMF_LogWrite(trim(cname)//': createexpgrid: '//trim(msg), ESMF_LOGMSG_INFO)
4036  write(msg,'(a,2i6)') ' eub: ',eub(:)
4037  call ESMF_LogWrite(trim(cname)//': createexpgrid: '//trim(msg), ESMF_LOGMSG_INFO)
4038  write(msg,'(a,2i6)') ' tlb: ',tlb(:)
4039  call ESMF_LogWrite(trim(cname)//': createexpgrid: '//trim(msg), ESMF_LOGMSG_INFO)
4040  write(msg,'(a,2i6)') ' tub: ',tub(:)
4041  call ESMF_LogWrite(trim(cname)//': createexpgrid: '//trim(msg), ESMF_LOGMSG_INFO)
4042  write(msg,'(a,2i6)') ' exphalolwidth: ',expHaloLWidth(:)
4043  call ESMF_LogWrite(trim(cname)//': createexpgrid: '//trim(msg), ESMF_LOGMSG_INFO)
4044  write(msg,'(a,2i6)') ' exphalouwidth: ',expHaloUWidth(:)
4045  call ESMF_LogWrite(trim(cname)//': createexpgrid: '//trim(msg), ESMF_LOGMSG_INFO)
4046  call ESMF_FieldWrite( expMask, &
4047  "wmesmfmd_createexpgrid_export_mask.nc", overwrite=.true., rc=rc )
4048  if (ESMF_LogFoundError(rc, PASSTHRU)) return
4049  tmpField = ESMF_FieldCreate( expGrid, expArraySpec2D, &
4050  totalLWidth=expHaloLWidth, totalUWidth=expHaloUWidth, &
4051  staggerLoc=expStaggerLoc, indexFlag=expIndexFlag, &
4052  name='temp', rc=rc )
4053  if (ESMF_LogFoundError(rc, PASSTHRU)) return
4054  if ( expGridIsLocal ) then
4055  call ESMF_FieldGet( tmpField, localDE=lde, farrayPtr=rptr, rc=rc )
4056  if (ESMF_LogFoundError(rc, PASSTHRU)) return
4057  endif
4058  if ( expGridIsLocal ) then
4059  do iy = elb(2),eub(2)
4060  do ix = elb(1),eub(1)
4061  rptr(ix,iy) = xgrd(iy,ix)
4062  enddo
4063  enddo
4064  endif
4065  call ESMF_FieldWrite( tmpField, &
4066  "wmesmfmd_createexpgrid_export_xgrd.nc", overwrite=.true., rc=rc )
4067  if (ESMF_LogFoundError(rc, PASSTHRU)) return
4068  if ( expGridIsLocal ) then
4069  do iy = elb(2),eub(2)
4070  do ix = elb(1),eub(1)
4071  rptr(ix,iy) = ygrd(iy,ix)
4072  enddo
4073  enddo
4074  endif
4075  call ESMF_FieldWrite( tmpField, &
4076  "wmesmfmd_createexpgrid_export_ygrd.nc", overwrite=.true., rc=rc )
4077  if (ESMF_LogFoundError(rc, PASSTHRU)) return
4078  if ( expGridIsLocal ) then
4079  do iy = elb(2),eub(2)
4080  do ix = elb(1),eub(1)
4081  rptr(ix,iy) = hpfac(iy,ix)
4082  enddo
4083  enddo
4084  endif
4085  call ESMF_FieldWrite( tmpField, &
4086  "wmesmfmd_createexpgrid_export_hpfac.nc", overwrite=.true., rc=rc )
4087  if (ESMF_LogFoundError(rc, PASSTHRU)) return
4088  if ( expGridIsLocal ) then
4089  do iy = elb(2),eub(2)
4090  do ix = elb(1),eub(1)
4091  rptr(ix,iy) = hqfac(iy,ix)
4092  enddo
4093  enddo
4094  endif
4095  call ESMF_FieldWrite( tmpField, &
4096  "wmesmfmd_createexpgrid_export_hqfac.nc", overwrite=.true., rc=rc )
4097  if (ESMF_LogFoundError(rc, PASSTHRU)) return
4098  if ( expGridIsLocal ) then
4099  do iy = elb(2),eub(2)
4100  do ix = elb(1),eub(1)
4101  rptr(ix,iy) = lpet
4102  enddo
4103  enddo
4104  endif
4105  call ESMF_FieldWrite( tmpField, &
4106  "wmesmfmd_createexpgrid_export_dcomp.nc", overwrite=.true., rc=rc )
4107  if (ESMF_LogFoundError(rc, PASSTHRU)) return
4108  call ESMF_FieldDestroy( tmpField, rc=rc )
4109  if (ESMF_LogFoundError(rc, PASSTHRU)) return
4110 #endif
4111  !
4112  rc = ESMF_SUCCESS
4113 .gt. if (verbosity0) call ESMF_LogWrite(trim(cname)// &
4114  ': leaving createexpgrid', ESMF_LOGMSG_INFO)
4115  !/
4116  !/ End of CreateExpGrid ---------------------------------------------- /
4117  !/
4118  end subroutine CreateExpGrid
4119  !/ ------------------------------------------------------------------- /
4120  !/
4121 #undef METHOD
4122 #define METHOD "CreateImpMesh"
4123  !>
4124 import fields. !> @brief Create ESMF mesh (unstructured) for
4125  !>
4126 import using the unstructured mesh !> @details Create an ESMF Mesh for
4127 import mesh is not !> description in W3GDATMD. At present, this
4128  !> domain decomposed, but instead is defined on PET 0 only. (In
4129  !> future, when the unstructured mesh will run on domain decomposition,
4130  !> we will use that decomposition.)
4131  !>
4132  !> @param gcomp Gridded component
4133  !> @param[out] rc Return code
4134  !>
4135  !> @author A. J. van der Westhuysen @date 28-Feb-2018
4136  !>
4137  subroutine CreateImpMesh ( gcomp, rc )
4138  !/
4139  !/ +-----------------------------------+
4140  !/ | WAVEWATCH III NOAA/NCEP |
4141  !/ | A. J. van der Westhuysen |
4142  !/ | FORTRAN 90 |
4143  !/ | Last update : 28-FEB_2018 |
4144  !/ +-----------------------------------+
4145  !/
4146  !/ 28-Feb-2018 : Origination. ( version 6.06 )
4147  !/
4148  ! 1. Purpose :
4149  !
4150 import fields ! Create ESMF mesh (unstructured) for
4151  !
4152  ! 2. Method :
4153  !
4154 import using the unstructured mesh description ! Create an ESMF Mesh for
4155 import mesh is not domain decomposed, ! in W3GDATMD. At present, this
4156  ! but instead is defined on PET 0 only. (In future, when the unstructured
4157  ! mesh will run on domain decomposition, we will use that decomposition.)
4158  !
4159  ! 3. Parameters :
4160  !
4161  ! Parameter list
4162  ! ----------------------------------------------------------------
4163  ! gcomp Type I/O Gridded component
4164  ! rc Int. O Return code
4165  ! ----------------------------------------------------------------
4166  !
4167  ! 4. Subroutines used :
4168  !
4169  ! Name Type Module Description
4170  ! ----------------------------------------------------------------
4171  ! NONE
4172  ! ----------------------------------------------------------------
4173  !
4174  ! 5. Called by :
4175  !
4176  ! 6. Error messages :
4177  !
4178  ! 7. Remarks :
4179  !
4180  ! 8. Structure :
4181  !
4182  ! 9. Switches :
4183  !
4184  ! 10. Source code :
4185  !
4186  !/ ------------------------------------------------------------------- /
4187  !/
4188 #ifdef W3_PDLIB
4189  use yowNodepool, only: npa, iplg, nodes_global
4190  use yowElementpool, only: ne, ielg, INE
4191 #endif
4192  !/
4193  !/ ------------------------------------------------------------------- /
4194  !/ Parameter list
4195  !/
4196  implicit none
4197  type(ESMF_GridComp) :: gcomp
4198  integer,intent(out) :: rc
4199  !/
4200  !/ ------------------------------------------------------------------- /
4201  !/ Local parameters
4202  !/
4203  character(ESMF_MAXSTR) :: cname
4204  character(128) :: msg
4205  integer :: nproc, nxproc, nyproc, n, nfac, irp
4206  real :: gr, rp, pr, diff
4207  integer, parameter :: lde = 0
4208  integer :: ldecnt
4209  integer :: i, j, pos, ix, iy
4210  integer(ESMF_KIND_I4), pointer :: iptr(:,:)
4211  real(ESMF_KIND_RX), pointer :: rptrx(:,:), rptry(:,:)
4212  real(ESMF_KIND_RX), pointer :: rptr(:,:)
4213  type(ESMF_Field) :: tmpField
4214  integer(ESMF_KIND_I4), allocatable :: nodeIds(:)
4215  real(ESMF_KIND_R8), allocatable :: nodeCoords(:)
4216  integer(ESMF_KIND_I4), allocatable :: nodeOwners(:)
4217  integer(ESMF_KIND_I4), allocatable :: elemIds(:)
4218  integer(ESMF_KIND_I4), allocatable :: elemTypes(:)
4219  integer(ESMF_KIND_I4), allocatable :: elemConn(:)
4220  !
4221  ! -------------------------------------------------------------------- /
4222  ! Prep
4223  !
4224  rc = ESMF_SUCCESS
4225  if ( noActiveImpFields ) return
4226  call ESMF_GridCompGet(gcomp, name=cname, rc=rc)
4227  if (ESMF_LogFoundError(rc, PASSTHRU)) return
4228 .gt. if (verbosity0) call ESMF_LogWrite(trim(cname)// &
4229  ': entered createimpmesh', ESMF_LOGMSG_INFO)
4230  !
4231  ! -------------------------------------------------------------------- /
4232  ! 1. Setup
4233  !
4234  ! 1.a Set grid pointers
4235  !
4236  impGridID = minval(inpmap)
4237 .eq. if ( impGridID-999 ) impGridID = 1
4238  call w3setg ( impGridID, mdse, mdst )
4239  call w3seti ( impGridID, mdse, mdst )
4240  call w3seto ( impGridID, mdse, mdst )
4241 .gt. if ( impGridID0 ) then
4242  call wmsetm ( impGridID, mdse, mdst )
4243  nproc = naproc
4244  else
4245  nproc = nmproc
4246  endif
4247  !
4248 import fields ! 1.b Set arraySpec, staggerLoc, and indexFlag for
4249  !
4250  ! call ESMF_ArraySpecSet( impArraySpec2D, rank=2, &
4251  ! typekind=ESMF_TYPEKIND_RX, rc=rc )
4252  ! if (ESMF_LogFoundError(rc, PASSTHRU)) return
4253  ! impStaggerLoc = ESMF_STAGGERLOC_CENTER
4254  ! impIndexFlag = ESMF_INDEX_GLOBAL
4255  !
4256  ! -------------------------------------------------------------------- /
4257  ! 2. Create ESMF mesh for import, currently without domain decomposition
4258  ! Note that the ESMF grid layout is dim1=X, dim2=Y
4259  !
4260 import mesh ! 2.a Create ESMF
4261  !
4262  ! Allocate and fill the node id array.
4263 #ifdef W3_PDLIB
4264 .EQV. if ( LPDLIB .FALSE. ) then
4265 #endif
4266  allocate(nodeIds(NX))
4267  do i = 1,NX
4268  nodeIds(i)=i
4269  enddo
4270 #ifdef W3_PDLIB
4271  else
4272  ! -------------------------------------------------------------------
4273  ! ESMF Definition: The global id's of the nodes resident on this processor ! ESMF Definition: The global id'
4274  ! -------------------------------------------------------------------
4275  ! Allocate global node ids, including ghost nodes (npa=np+ng)
4276  allocate(nodeIds(npa))
4277  do i = 1,npa
4278  nodeIds(i)=iplg(i)
4279  enddo
4280  endif
4281  !
4282  ! call ESMF_LogWrite(trim(cname)//': in createimpmesh, nodeids=', &
4283  ! ESMF_LOGMSG_INFO)
4284  ! do i = 1,npa
4285  ! write(msg,*) trim(cname)//': nodeids(i)',i, &
4286  ! ' ',nodeIds(i)
4287  ! call ESMF_LogWrite(trim(msg), ESMF_LOGMSG_INFO)
4288  ! enddo
4289 #endif
4290 
4291  ! call ESMF_LogWrite(trim(cname)//': in createimpmesh, nodeids=', &
4292  ! ESMF_LOGMSG_INFO)
4293  ! do i = 1,NX
4294  ! write(msg,*) trim(cname)//': ',i, &
4295  ! ' ',nodeIds(i)
4296  ! call ESMF_LogWrite(trim(msg), ESMF_LOGMSG_INFO)
4297  ! enddo
4298 
4299  ! Allocate and fill node coordinate array.
4300  ! Since this is a 2D Mesh the size is 2x the
4301  ! number of nodes.
4302 #ifdef W3_PDLIB
4303 .EQV. if ( LPDLIB .FALSE. ) then
4304 #endif
4305  allocate(nodeCoords(2*NX))
4306  do i = 1,NX
4307  do j = 1,2
4308  pos=2*(i-1)+j
4309  if (j == 1) then
4310  nodeCoords(pos) = xgrd(1,i)
4311  else
4312  nodeCoords(pos) = ygrd(1,i)
4313  endif
4314  enddo
4315  enddo
4316 #ifdef W3_PDLIB
4317  else
4318  ! -------------------------------------------------------------------
4319  ! ESMF Definition: Physical coordinates of the nodes
4320  ! -------------------------------------------------------------------
4321  allocate(nodeCoords(2*npa))
4322  do i = 1,npa
4323  do j = 1,2
4324  pos=2*(i-1)+j
4325  if ( j == 1) then
4326  nodeCoords(pos) = xgrd(1,iplg(i))
4327  else
4328  nodeCoords(pos) = ygrd(1,iplg(i))
4329  endif
4330  enddo
4331  enddo
4332  endif
4333  !
4334  ! call ESMF_LogWrite(trim(cname)//': in createimpmesh, nodecoords=', &
4335  ! ESMF_LOGMSG_INFO)
4336  ! do i = 1,(2*npa)
4337  ! write(msg,*) trim(cname)//': nodecoords(i)',i, &
4338  ! ' ',nodeCoords(i)
4339  ! call ESMF_LogWrite(trim(msg), ESMF_LOGMSG_INFO)
4340  ! enddo
4341 #endif
4342 
4343  ! call ESMF_LogWrite(trim(cname)//': in createimpmesh, nodecoords=', &
4344  ! ESMF_LOGMSG_INFO)
4345  ! do i = 1,(2*NX)
4346  ! write(msg,*) trim(cname)//': ',i, &
4347  ! ' ',nodeCoords(i)
4348  ! call ESMF_LogWrite(trim(msg), ESMF_LOGMSG_INFO)
4349  ! enddo
4350 
4351  ! Allocate and fill the node owner array.
4352  ! Since this mesh is all on PET 0, it’s just set to all 0.
4353 #ifdef W3_PDLIB
4354 .EQV. if ( LPDLIB .FALSE. ) then
4355 #endif
4356  allocate(nodeOwners(NX))
4357  nodeOwners=0 ! everything on PET 0
4358 #ifdef W3_PDLIB
4359  else
4360  ! -------------------------------------------------------------------
4361  ! ESMF Definition: Processor that owns the node
4362  ! -------------------------------------------------------------------
4363  allocate(nodeOwners(npa))
4364  nodeOwners=nodes_global(iplg(1:npa))%domainID-1
4365  endif
4366  !
4367  ! call ESMF_LogWrite(trim(cname)//': in createimpmesh, nodeowners=', &
4368  ! ESMF_LOGMSG_INFO)
4369  ! do i = 1,npa
4370  ! write(msg,*) trim(cname)//': nodeowners(i)',i, &
4371  ! ' ',nodeOwners(i)
4372  ! call ESMF_LogWrite(trim(msg), ESMF_LOGMSG_INFO)
4373  ! enddo
4374 #endif
4375 
4376  ! call ESMF_LogWrite(trim(cname)//': in createimpmesh, nodeowners=', &
4377  ! ESMF_LOGMSG_INFO)
4378  ! do i = 1,NX
4379  ! write(msg,*) trim(cname)//': ',i, &
4380  ! ' ',nodeOwners(i)
4381  ! call ESMF_LogWrite(trim(msg), ESMF_LOGMSG_INFO)
4382  ! enddo
4383 
4384  ! Allocate and fill the element id array.
4385 #ifdef W3_PDLIB
4386 .EQV. if ( LPDLIB .FALSE. ) then
4387 #endif
4388  allocate(elemIds(NTRI))
4389  do i = 1,NTRI
4390  elemIds(i)=i
4391  enddo
4392 #ifdef W3_PDLIB
4393  else
4394  ! -------------------------------------------------------------------
4395  ! ESMF Definition: The global id's of the elements resident on this processor
4396  ! -------------------------------------------------------------------
4397  allocate(elemids(ne))
4398  do i = 1,ne
4399  elemids(i)=ielg(i)
4400  enddo
4401  endif
4402  !
4403  ! call ESMF_LogWrite(trim(cname)//': In CreateImpMesh, elemIds=', &
4404  ! ESMF_LOGMSG_INFO)
4405  ! do i = 1,ne
4406  ! write(msg,*) trim(cname)//': elemIds(i)',i, &
4407  ! ' ',elemIds(i)
4408  ! call ESMF_LogWrite(trim(msg), ESMF_LOGMSG_INFO)
4409  ! enddo
4410 #endif
4411 
4412  ! call ESMF_LogWrite(trim(cname)//': In CreateImpMesh, elemIds=', &
4413  ! ESMF_LOGMSG_INFO)
4414  ! do i = 1,NTRI
4415  ! write(msg,*) trim(cname)//': ',i, &
4416  ! ' ',elemIds(i)
4417  ! call ESMF_LogWrite(trim(msg), ESMF_LOGMSG_INFO)
4418  ! enddo
4419 
4420  ! Allocate and fill the element topology type array.
4421 #ifdef W3_PDLIB
4422  if ( lpdlib .EQV. .false. ) then
4423 #endif
4424  allocate(elemtypes(ntri))
4425  do i = 1,ntri
4426  elemtypes(i)=esmf_meshelemtype_tri
4427  enddo
4428 #ifdef W3_PDLIB
4429  else
4430  ! -------------------------------------------------------------------
4431  ! ESMF Definition: Topology of the given element (one of ESMF_MeshElement)
4432  ! -------------------------------------------------------------------
4433  allocate(elemtypes(ne))
4434  do i = 1,ne
4435  elemtypes(i)=esmf_meshelemtype_tri
4436  enddo
4437  endif
4438  !
4439  ! call ESMF_LogWrite(trim(cname)//': In CreateImpM, elemTypes=', &
4440  ! ESMF_LOGMSG_INFO)
4441  ! do i = 1,ne
4442  ! write(msg,*) trim(cname)//': elemTypes(i)',i, &
4443  ! ' ',elemTypes(i)
4444  ! call ESMF_LogWrite(trim(msg), ESMF_LOGMSG_INFO)
4445  ! enddo
4446 #endif
4447 
4448  ! call ESMF_LogWrite(trim(cname)//': In CreateImpM, elemTypes=', &
4449  ! ESMF_LOGMSG_INFO)
4450  ! do i = 1,NTRI
4451  ! write(msg,*) trim(cname)//': ',i, &
4452  ! ' ',elemTypes(i)
4453  ! call ESMF_LogWrite(trim(msg), ESMF_LOGMSG_INFO)
4454  ! enddo
4455 
4456  ! Allocate and fill the element connection type array.
4457 #ifdef W3_PDLIB
4458  if ( lpdlib .EQV. .false. ) then
4459 #endif
4460  allocate(elemconn(3*ntri))
4461  do i = 1,ntri
4462  do j = 1,3
4463  pos=3*(i-1)+j
4464  elemconn(pos)=trigp(j,i)
4465  enddo
4466  enddo
4467 #ifdef W3_PDLIB
4468  else
4469  ! -------------------------------------------------------------------
4470  ! ESMF Definition: Connectivity table. The number of entries should
4471  ! be equal to the number of nodes in the given topology. The indices
4472  ! should be the local index (1 based) into the array of nodes that
4473  ! was declared with MeshAddNodes.
4474  ! -------------------------------------------------------------------
4475  ! > INE is local element array. it stores the local node IDs
4476  ! > first index from 1 to 3.
4477  ! > second index from 1 to ne.
4478  allocate(elemconn(3*ne))
4479  do i = 1,ne
4480  do j = 1,3
4481  pos=3*(i-1)+j
4482  elemconn(pos)=ine(j,i)
4483  enddo
4484  enddo
4485  endif
4486  !
4487  ! call ESMF_LogWrite(trim(cname)//': In CreateImpMesh, elemConn=', &
4488  ! ESMF_LOGMSG_INFO)
4489  ! do i = 1,(3*ne)
4490  ! write(msg,*) trim(cname)//': elemConn(i)',i, &
4491  ! ' ',elemConn(i)
4492  ! call ESMF_LogWrite(trim(msg), ESMF_LOGMSG_INFO)
4493  ! enddo
4494 #endif
4495 
4496  ! call ESMF_LogWrite(trim(cname)//': In CreateImpMesh, elemConn=', &
4497  ! ESMF_LOGMSG_INFO)
4498  ! do i = 1,(3*NTRI)
4499  ! write(msg,*) trim(cname)//': ',i, &
4500  ! ' ',elemConn(i)
4501  ! call ESMF_LogWrite(trim(msg), ESMF_LOGMSG_INFO)
4502  ! enddo
4503 
4504  impmesh = esmf_meshcreate( parametricdim=2,spatialdim=2, &
4505  nodeids=nodeids, nodecoords=nodecoords, &
4506  nodeowners=nodeowners, elementids=elemids,&
4507  elementtypes=elemtypes, elementconn=elemconn, &
4508  rc=rc )
4509  if (esmf_logfounderror(rc, passthru)) return
4510 
4511  deallocate(nodeids)
4512  deallocate(nodecoords)
4513  deallocate(nodeowners)
4514  deallocate(elemids)
4515  deallocate(elemtypes)
4516  deallocate(elemconn)
4517 
4518  call esmf_logwrite(trim(cname)//': In CreateImpMesh, created impMesh', &
4519  esmf_logmsg_info)
4520  !
4521  rc = esmf_success
4522  if (verbosity.gt.0) call esmf_logwrite(trim(cname)// &
4523  ': leaving CreateImpMesh', esmf_logmsg_info)
4524  !/
4525  !/ End of CreateImpMesh ---------------------------------------------- /
4526  !/
4527  end subroutine createimpmesh
4528  !/ ------------------------------------------------------------------- /
4529  !/
4530 #undef METHOD
4531 #define METHOD "CreateExpMesh"
4532 
4553  subroutine createexpmesh ( gcomp, rc )
4554  !/
4555  !/ +-----------------------------------+
4556  !/ | WAVEWATCH III NOAA/NCEP |
4557  !/ | A. J. van der Westhuysen |
4558  !/ | FORTRAN 90 |
4559  !/ | Last update : 28-FEB-2018 |
4560  !/ +-----------------------------------+
4561  !/
4562  !/ 28-Feb-2018 : Origination. ( version 6.06 )
4563  !/
4564  ! 1. Purpose :
4565  !
4566  ! Create ESMF mesh (unstructured) for export fields
4567  !
4568  ! 2. Method :
4569  !
4570  ! Create an ESMF Mesh for export using the unstructured mesh description
4571  ! in W3GDATMD. At present, this export mesh is not domain decomposed,
4572  ! but instead is defined on PET 0 only. (In future, when the unstructured
4573  ! mesh will run on domain decomposition, we will use that decomposition.)
4574  !
4575  ! Since the internal parallel data is currently stored accross grid points
4576  ! in a "card deck" fashion, we will define an intermediate native grid, as
4577  ! is done for regular/curvilinear grids, and perform an ESMF regrid to the
4578  ! export mesh. This code segment is taken from T. J. Campbell, and
4579  ! modified to 1D, because the internal data structure for unstructred
4580  ! meshes is an array with dimensions [NX,NY=1].
4581  !
4582  ! 3. Parameters :
4583  !
4584  ! Parameter list
4585  ! ----------------------------------------------------------------
4586  ! gcomp Type I/O Gridded component
4587  ! rc Int. O Return code
4588  ! ----------------------------------------------------------------
4589  !
4590  ! 4. Subroutines used :
4591  !
4592  ! Name Type Module Description
4593  ! ----------------------------------------------------------------
4594  ! NONE
4595  ! ----------------------------------------------------------------
4596  !
4597  ! 5. Called by :
4598  !
4599  ! 6. Error messages :
4600  !
4601  ! 7. Remarks :
4602  !
4603  ! 8. Structure :
4604  !
4605  ! 9. Switches :
4606  !
4607  ! !/SHRD Switch for shared / distributed memory architecture.
4608  ! !/DIST Id.
4609  !
4610  ! 10. Source code :
4611  !
4612  !/ ------------------------------------------------------------------- /
4613  !/
4614 #ifdef W3_PDLIB
4615  use yownodepool, only: npa, iplg, nodes_global
4616  use yowelementpool, only: ne, ielg, ine
4617 #endif
4618  !/
4619  !/ ------------------------------------------------------------------- /
4620  !/ Parameter list
4621  !/
4622  implicit none
4623  type(esmf_gridcomp) :: gcomp
4624  integer,intent(out) :: rc
4625  !/
4626  !/ ------------------------------------------------------------------- /
4627  !/ Local parameters
4628  !/
4629  character(ESMF_MAXSTR) :: cname
4630  character(128) :: msg
4631  integer :: nproc, nxproc, nyproc, n, nfac, irp
4632  real :: gr, rp, pr, diff
4633  integer, parameter :: lde = 0
4634  integer :: ldecnt
4635  integer :: i, j, pos, ix, iy, isea, jsea, iproc
4636  integer :: elb(2), eub(2)
4637  integer(ESMF_KIND_I4), pointer :: iptr(:,:)
4638  real(ESMF_KIND_RX), pointer :: rptrx(:,:), rptry(:,:)
4639  real(ESMF_KIND_RX), pointer :: rptr(:,:)
4640  integer :: arbIndexCount
4641  integer, allocatable :: arbIndexList(:,:)
4642  type(esmf_field) :: nField, eField
4643  type(esmf_field) :: tmpField
4644  integer(ESMF_KIND_I4), allocatable :: nodeIds(:)
4645  real(ESMF_KIND_R8), allocatable :: nodeCoords(:)
4646  integer(ESMF_KIND_I4), allocatable :: nodeOwners(:)
4647  integer(ESMF_KIND_I4), allocatable :: elemIds(:)
4648  integer(ESMF_KIND_I4), allocatable :: elemTypes(:)
4649  integer(ESMF_KIND_I4), allocatable :: elemConn(:)
4650  !
4651  ! -------------------------------------------------------------------- /
4652  ! Prep
4653  !
4654  rc = esmf_success
4655  if ( noactiveexpfields ) return
4656  call esmf_gridcompget(gcomp, name=cname, rc=rc)
4657  if (esmf_logfounderror(rc, passthru)) return
4658  if (verbosity.gt.0) call esmf_logwrite(trim(cname)// &
4659  ': entered CreateExpMesh', esmf_logmsg_info)
4660  !
4661  ! -------------------------------------------------------------------- /
4662  ! Set flag to indicate that this processor has local native grid storage
4663  !
4664  natgridislocal = iaproc .gt. 0 .and. iaproc .le. naproc
4665 
4666  ! 1. Setup
4667  !
4668  ! 1.a Set grid pointers
4669  !
4670  expgridid = 1 !TODO: only export from grid 1
4671  call w3setg ( expgridid, mdse, mdst )
4672  call w3setw ( expgridid, mdse, mdst )
4673  call w3seta ( expgridid, mdse, mdst )
4674  call w3seti ( expgridid, mdse, mdst )
4675  call w3seto ( expgridid, mdse, mdst )
4676  call wmsetm ( expgridid, mdse, mdst )
4677  natgridid = expgridid
4678  nproc = naproc
4679  !
4680  ! 1.b Set arraySpec, staggerLoc, and indexFlag for native fields.
4681  ! NOTE: For unstructured meshes the native grid is a 1D array (NY=1)
4682  !
4683  call esmf_arrayspecset( natarrayspec1d, rank=1, &
4684  typekind=esmf_typekind_rx, rc=rc )
4685  if (esmf_logfounderror(rc, passthru)) return
4686  natstaggerloc = esmf_staggerloc_center
4687  natindexflag = esmf_index_delocal
4688  !
4689  ! -------------------------------------------------------------------- /
4690  ! 2. Create ESMF mesh for export
4691  !
4692  ! 2.a Create ESMF export mesh
4693  !
4694  ! Allocate and fill the node id array.
4695 #ifdef W3_PDLIB
4696  if ( lpdlib .EQV. .false. ) then
4697 #endif
4698  allocate(nodeids(nx))
4699  do i = 1,nx
4700  nodeids(i)=i
4701  enddo
4702 #ifdef W3_PDLIB
4703  else
4704  ! -------------------------------------------------------------------
4705  ! ESMF Definition: The global id's of the nodes resident on this processor
4706  ! -------------------------------------------------------------------
4707  ! Allocate global node ids, including ghost nodes (npa=np+ng)
4708  allocate(nodeids(npa))
4709  do i = 1,npa
4710  nodeids(i)=iplg(i)
4711  enddo
4712  endif
4713  !
4714  ! call ESMF_LogWrite(trim(cname)//': In CreateExpMesh, nodeIds=', &
4715  ! ESMF_LOGMSG_INFO)
4716  ! do i = 1,npa
4717  ! write(msg,*) trim(cname)//': nodeIds(i)',i, &
4718  ! ' ',nodeIds(i)
4719  ! call ESMF_LogWrite(trim(msg), ESMF_LOGMSG_INFO)
4720  ! enddo
4721 #endif
4722 
4723  ! call ESMF_LogWrite(trim(cname)//': In CreateExpMesh, nodeIds=', &
4724  ! ESMF_LOGMSG_INFO)
4725  ! do i = 1,NX
4726  ! write(msg,*) trim(cname)//': ',i, &
4727  ! ' ',nodeIds(i)
4728  ! call ESMF_LogWrite(trim(msg), ESMF_LOGMSG_INFO)
4729  ! enddo
4730 
4731  ! Allocate and fill node coordinate array.
4732  ! Since this is a 2D Mesh the size is 2x the
4733  ! number of nodes.
4734 #ifdef W3_PDLIB
4735  if ( lpdlib .EQV. .false. ) then
4736 #endif
4737  allocate(nodecoords(2*nx))
4738  do i = 1,nx
4739  do j = 1,2
4740  pos=2*(i-1)+j
4741  if (j == 1) then
4742  nodecoords(pos) = xgrd(1,i)
4743  else
4744  nodecoords(pos) = ygrd(1,i)
4745  endif
4746  enddo
4747  enddo
4748 #ifdef W3_PDLIB
4749  else
4750  ! -------------------------------------------------------------------
4751  ! ESMF Definition: Physical coordinates of the nodes
4752  ! -------------------------------------------------------------------
4753  allocate(nodecoords(2*npa))
4754  do i = 1,npa
4755  do j = 1,2
4756  pos=2*(i-1)+j
4757  if ( j == 1) then
4758  nodecoords(pos) = xgrd(1,iplg(i))
4759  else
4760  nodecoords(pos) = ygrd(1,iplg(i))
4761  endif
4762  enddo
4763  enddo
4764  endif
4765  !
4766  ! call ESMF_LogWrite(trim(cname)//': In CreateExpMesh, nodeCoords=', &
4767  ! ESMF_LOGMSG_INFO)
4768  ! do i = 1,(2*npa)
4769  ! write(msg,*) trim(cname)//': nodeCoords(i)',i, &
4770  ! ' ',nodeCoords(i)
4771  ! call ESMF_LogWrite(trim(msg), ESMF_LOGMSG_INFO)
4772  ! enddo
4773 #endif
4774 
4775  ! call ESMF_LogWrite(trim(cname)//': In CreateExpMesh, nodeCoords=', &
4776  ! ESMF_LOGMSG_INFO)
4777  ! do i = 1,(2*NX)
4778  ! write(msg,*) trim(cname)//': ',i, &
4779  ! ' ',nodeCoords(i)
4780  ! call ESMF_LogWrite(trim(msg), ESMF_LOGMSG_INFO)
4781  ! enddo
4782 
4783  ! Allocate and fill the node owner array.
4784 #ifdef W3_PDLIB
4785  if ( lpdlib .EQV. .false. ) then
4786 #endif
4787  allocate(nodeowners(nx))
4788  nodeowners=0 ! TODO: For now, export everything via PET 0
4789 #ifdef W3_PDLIB
4790  else
4791  ! -------------------------------------------------------------------
4792  ! ESMF Definition: Processor that owns the node
4793  ! -------------------------------------------------------------------
4794  allocate(nodeowners(npa))
4795  nodeowners=nodes_global(iplg(1:npa))%domainID-1
4796  endif
4797  !
4798  ! call ESMF_LogWrite(trim(cname)//': In CreateExpMesh, nodeOwners=', &
4799  ! ESMF_LOGMSG_INFO)
4800  ! do i = 1,npa
4801  ! write(msg,*) trim(cname)//': nodeOwners(i)',i, &
4802  ! ' ',nodeOwners(i)
4803  ! call ESMF_LogWrite(trim(msg), ESMF_LOGMSG_INFO)
4804  ! enddo
4805 #endif
4806 
4807  ! call ESMF_LogWrite(trim(cname)//': In CreateExpMesh, nodeOwners=', &
4808  ! ESMF_LOGMSG_INFO)
4809  ! do i = 1,NX
4810  ! write(msg,*) trim(cname)//': ',i, &
4811  ! ' ',nodeOwners(i)
4812  ! call ESMF_LogWrite(trim(msg), ESMF_LOGMSG_INFO)
4813  ! enddo
4814 
4815  ! Allocate and fill the element id array.
4816 #ifdef W3_PDLIB
4817  if ( lpdlib .EQV. .false. ) then
4818 #endif
4819  allocate(elemids(ntri))
4820  do i = 1,ntri
4821  elemids(i)=i
4822  enddo
4823 #ifdef W3_PDLIB
4824  else
4825  ! -------------------------------------------------------------------
4826  ! ESMF Definition: The global id's of the elements resident on this processor
4827  ! -------------------------------------------------------------------
4828  allocate(elemids(ne))
4829  do i = 1,ne
4830  elemids(i)=ielg(i)
4831  enddo
4832  endif
4833  !
4834  ! call ESMF_LogWrite(trim(cname)//': In CreateExpMesh, elemIds=', &
4835  ! ESMF_LOGMSG_INFO)
4836  ! do i = 1,ne
4837  ! write(msg,*) trim(cname)//': elemIds(i)',i, &
4838  ! ' ',elemIds(i)
4839  ! call ESMF_LogWrite(trim(msg), ESMF_LOGMSG_INFO)
4840  ! enddo
4841 #endif
4842 
4843  ! call ESMF_LogWrite(trim(cname)//': In CreateExpMesh, elemIds=', &
4844  ! ESMF_LOGMSG_INFO)
4845  ! do i = 1,NTRI
4846  ! write(msg,*) trim(cname)//': ',i, &
4847  ! ' ',elemIds(i)
4848  ! call ESMF_LogWrite(trim(msg), ESMF_LOGMSG_INFO)
4849  ! enddo
4850 
4851  ! Allocate and fill the element topology type array.
4852 #ifdef W3_PDLIB
4853  if ( lpdlib .EQV. .false. ) then
4854 #endif
4855  allocate(elemtypes(ntri))
4856  do i = 1,ntri
4857  elemtypes(i)=esmf_meshelemtype_tri
4858  enddo
4859 #ifdef W3_PDLIB
4860  else
4861  ! -------------------------------------------------------------------
4862  ! ESMF Definition: Topology of the given element (one of ESMF_MeshElement)
4863  ! -------------------------------------------------------------------
4864  allocate(elemtypes(ne))
4865  do i = 1,ne
4866  elemtypes(i)=esmf_meshelemtype_tri
4867  enddo
4868  endif
4869  !
4870  ! call ESMF_LogWrite(trim(cname)//': In CreateExpMesh, elemTypes=', &
4871  ! ESMF_LOGMSG_INFO)
4872  ! do i = 1,ne
4873  ! write(msg,*) trim(cname)//': elemTypes(i)',i, &
4874  ! ' ',elemTypes(i)
4875  ! call ESMF_LogWrite(trim(msg), ESMF_LOGMSG_INFO)
4876  ! enddo
4877 #endif
4878 
4879  ! call ESMF_LogWrite(trim(cname)//': In CreateExpMesh, elemTypes=', &
4880  ! ESMF_LOGMSG_INFO)
4881  ! do i = 1,NTRI
4882  ! write(msg,*) trim(cname)//': ',i, &
4883  ! ' ',elemTypes(i)
4884  ! call ESMF_LogWrite(trim(msg), ESMF_LOGMSG_INFO)
4885  ! enddo
4886 
4887  ! Allocate and fill the element connection type array.
4888 #ifdef W3_PDLIB
4889  if ( lpdlib .EQV. .false. ) then
4890 #endif
4891  allocate(elemconn(3*ntri))
4892  do i = 1,ntri
4893  do j = 1,3
4894  pos=3*(i-1)+j
4895  elemconn(pos)=trigp(j,i)
4896  enddo
4897  enddo
4898 #ifdef W3_PDLIB
4899  else
4900  ! -------------------------------------------------------------------
4901  ! ESMF Definition: Connectivity table. The number of entries should
4902  ! be equal to the number of nodes in the given topology. The indices
4903  ! should be the local index (1 based) into the array of nodes that
4904  ! was declared with MeshAddNodes.
4905  ! -------------------------------------------------------------------
4906  ! > INE is local element array. it stores the local node IDs
4907  ! > first index from 1 to 3.
4908  ! > second index from 1 to ne.
4909  allocate(elemconn(3*ne))
4910  do i = 1,ne
4911  do j = 1,3
4912  pos=3*(i-1)+j
4913  elemconn(pos)=ine(j,i)
4914  enddo
4915  enddo
4916  endif
4917  !
4918  ! call ESMF_LogWrite(trim(cname)//': In CreateExpMesh, elemConn=', &
4919  ! ESMF_LOGMSG_INFO)
4920  ! do i = 1,(3*ne)
4921  ! write(msg,*) trim(cname)//': elemConn(i)',i, &
4922  ! ' ',elemConn(i)
4923  ! call ESMF_LogWrite(trim(msg), ESMF_LOGMSG_INFO)
4924  ! enddo
4925 #endif
4926 
4927  ! call ESMF_LogWrite(trim(cname)//': In CreateExpMesh, elemConn=', &
4928  ! ESMF_LOGMSG_INFO)
4929  ! do i = 1,(3*NTRI)
4930  ! write(msg,*) trim(cname)//': ',i, &
4931  ! ' ',elemConn(i)
4932  ! call ESMF_LogWrite(trim(msg), ESMF_LOGMSG_INFO)
4933  ! enddo
4934 
4935  expmesh = esmf_meshcreate( parametricdim=2,spatialdim=2, &
4936  nodeids=nodeids, nodecoords=nodecoords, &
4937  nodeowners=nodeowners, elementids=elemids,&
4938  elementtypes=elemtypes, elementconn=elemconn, &
4939  rc=rc )
4940  if (esmf_logfounderror(rc, passthru)) return
4941 
4942  deallocate(nodeids)
4943  deallocate(nodecoords)
4944  deallocate(nodeowners)
4945  deallocate(elemids)
4946  deallocate(elemtypes)
4947  deallocate(elemconn)
4948  !
4949  ! Set flag to indicate that this processor has local export grid storage
4950  !
4951  !AW if (lpet == 0) then
4952  !AW call ESMF_GridGet( expMesh, localDECount=ldecnt, rc=rc )
4953  !AW if (ESMF_LogFoundError(rc, PASSTHRU)) return
4954  !AW expGridIsLocal = ldecnt.gt.0
4955  !AW endif
4956 
4957  !
4958  ! -------------------------------------------------------------------- /
4959  ! 3. Create ESMF grid with arbitrary domain decomposition to match
4960  ! the native domain decomposition of the non-excluded points
4961  ! Note that the native grid layout is dim1=Y, dim2=X
4962  ! Note that coordinates and mask are not needed since this
4963  ! grid is only used to define fields for a redist operation
4964  !
4965  ! 3.a Set flag to indicate that this processor has local native grid storage
4966  !
4967  natgridislocal = iaproc .gt. 0 .and. iaproc .le. naproc
4968 
4969 #ifdef W3_PDLIB
4970  if ( lpdlib .EQV. .false. ) then
4971 #endif
4972  !
4973  ! 3.b Setup arbitrary sequence index list
4974  !
4975  do ipass = 1,2
4976  if (ipass.eq.2) then
4977  allocate (arbindexlist(arbindexcount,2), stat=rc)
4978  if (esmf_logfoundallocerror(rc, passthru)) return
4979  endif
4980  arbindexcount = 0
4981  ! list local native grid non-excluded points
4982  if ( natgridislocal ) then
4983  do jsea = 1,nseal
4984 #ifdef W3_DIST
4985  isea = iaproc + (jsea-1)*naproc
4986 #endif
4987 #ifdef W3_SHRD
4988  isea = jsea
4989 #endif
4990  arbindexcount = arbindexcount+1
4991  if (ipass.eq.2) then
4992  ix = mapsf(isea,1)
4993  iy = mapsf(isea,2)
4994  ! native grid layout: dim1=Y, dim2=X
4995  arbindexlist(arbindexcount,1) = iy
4996  arbindexlist(arbindexcount,2) = ix
4997  endif
4998  enddo
4999  endif
5000  enddo !ipass
5001  !
5002  ! 3.c Create ESMF native grid
5003  !
5004  natgrid = esmf_gridcreatenoperidim( &
5005  minindex=(/ 1, 1/), &
5006  maxindex=(/ny,nx/), &
5007  coorddep1=(/esmf_dim_arb,esmf_dim_arb/), &
5008  coorddep2=(/esmf_dim_arb,esmf_dim_arb/), &
5009  arbindexcount=arbindexcount, &
5010  arbindexlist=arbindexlist, &
5011  coordtypekind=esmf_typekind_rx, &
5012  coordsys=esmf_coordsys_sph_deg, &
5013  name=trim(cname)//"_native_grid", rc=rc )
5014  if (esmf_logfounderror(rc, passthru)) return
5015  !
5016  ! 3.d Deallocate arbitrary sequence index list
5017  !
5018  deallocate (arbindexlist, stat=rc)
5019  if (esmf_logfounddeallocerror(rc, passthru)) return
5020  !
5021  ! -------------------------------------------------------------------- /
5022  ! 4. Create route handle for redist between native grid domain
5023  ! decomposition and the export grid domain decomposition
5024  !
5025  ! 4.a Create temporary fields
5026  !
5027  nfield = esmf_fieldcreate( natgrid, natarrayspec1d, &
5028  staggerloc=natstaggerloc, rc=rc )
5029  if (esmf_logfounderror(rc, passthru)) return
5030  efield = esmf_fieldcreate(expmesh, typekind=esmf_typekind_rx, rc=rc)
5031  if (esmf_logfounderror(rc, passthru)) return
5032  !
5033  ! 4.b Store route handle
5034  !
5035  call esmf_fieldrediststore( nfield, efield, n2erh, rc=rc )
5036  if (esmf_logfounderror(rc, passthru)) return
5037  !
5038  ! 4.c Clean up
5039  !
5040  call esmf_fielddestroy( nfield, rc=rc )
5041  if (esmf_logfounderror(rc, passthru)) return
5042  call esmf_fielddestroy( efield, rc=rc )
5043  if (esmf_logfounderror(rc, passthru)) return
5044 
5045 #ifdef W3_PDLIB
5046  endif
5047 #endif
5048 
5049  call esmf_logwrite(trim(cname)//': In CreateExpMesh, created expMesh', &
5050  esmf_logmsg_info)
5051 
5052  rc = esmf_success
5053  if (verbosity.gt.0) call esmf_logwrite(trim(cname)// &
5054  ': leaving CreateExpMesh', esmf_logmsg_info)
5055  !/
5056  !/ End of CreateExpMesh ---------------------------------------------- /
5057  !/
5058  end subroutine createexpmesh
5059  !/ ------------------------------------------------------------------- /
5060  !/
5061 #undef METHOD
5062 #define METHOD "SetupImpBmsk"
5063 
5073  subroutine setupimpbmsk( bmskField, impField, missingVal, rc )
5074  !/
5075  !/ +-----------------------------------+
5076  !/ | WAVEWATCH III NOAA/NCEP |
5077  !/ | T. J. Campbell, NRL |
5078  !/ | FORTRAN 90 |
5079  !/ | Last update : 09-Aug-2017 |
5080  !/ +-----------------------------------+
5081  !/
5082  !/ 09-Aug-2017 : Origination. ( version 6.03 )
5083  !/
5084  ! 1. Purpose :
5085  !
5086  ! Setup background blending mask field for an import field
5087  !
5088  ! 2. Method :
5089  !
5090  ! 3. Parameters :
5091  !
5092  ! Parameter list
5093  ! ----------------------------------------------------------------
5094  ! bmskField Type I/O blending mask field
5095  ! impField Type I import field
5096  ! missingVal Real I missing value
5097  ! rc Int O Return code
5098  ! ----------------------------------------------------------------
5099  !
5100  ! 4. Subroutines used :
5101  !
5102  ! Name Type Module Description
5103  ! ----------------------------------------------------------------
5104  ! NONE
5105  ! ----------------------------------------------------------------
5106  !
5107  ! 5. Called by :
5108  !
5109  ! 6. Error messages :
5110  !
5111  ! 7. Remarks :
5112  !
5113  ! 8. Structure :
5114  !
5115  ! 9. Switches :
5116  !
5117  ! 10. Source code :
5118  !
5119  !/ ------------------------------------------------------------------- /
5120  !/
5121  !/ ------------------------------------------------------------------- /
5122  !/ Parameter list
5123  !/
5124  implicit none
5125  type(esmf_field) :: bmskField
5126  type(esmf_field) :: impField
5127  real(ESMF_KIND_RX) :: missingVal
5128  integer, optional :: rc
5129  !/
5130  !/ ------------------------------------------------------------------- /
5131  !/ Local parameters
5132  !/
5133  real(ESMF_KIND_RX), parameter :: zero = 0.0
5134  real(ESMF_KIND_RX), parameter :: half = 0.5
5135  real(ESMF_KIND_RX), parameter :: one = 1.0
5136  integer, parameter :: nsig = imphalowidth-1
5137  integer, parameter :: niter = 10
5138  integer, parameter :: iter0 = 1-niter
5139  integer, parameter :: lde = 0
5140  integer :: iter, i, j, ii, jj, k, l
5141  integer :: elb(2), eub(2)
5142  integer :: tlb(2), tub(2)
5143  real(ESMF_KIND_RX), pointer :: mptr(:,:), dptr(:,:)
5144  type(esmf_field) :: cmskField
5145  real(ESMF_KIND_RX), pointer :: bmsk(:,:), cmsk(:,:)
5146  real(ESMF_KIND_RX) :: bsum, wsum
5147  real(ESMF_KIND_RX) :: wflt(-nsig:nsig,-nsig:nsig)
5148  character(ESMF_MAXSTR) :: fnm
5149 #if defined(TEST_WMESMFMD) || defined(TEST_WMESMFMD_SETUPIMPBMSK)
5150  integer :: timeSlice
5151 #endif
5152  !
5153  ! -------------------------------------------------------------------- /
5154  ! Initialize filter
5155  !
5156  if (present(rc)) rc = esmf_success
5157 
5158  do l = -nsig,nsig
5159  do k = -nsig,nsig
5160  wflt(k,l) = exp( -half*( real(k,esmf_kind_rx)**2 &
5161  + real(l,esmf_kind_rx)**2 ) )
5162  enddo
5163  enddo
5164  !
5165  ! -------------------------------------------------------------------- /
5166  ! Set up fields and pointers
5167  !
5168  call esmf_fieldget( impfield, name=fnm, rc=rc )
5169  if (esmf_logfounderror(rc, passthru)) return
5170 
5171  cmskfield = esmf_fieldcreate( impgrid, imparrayspec2d, &
5172  totallwidth=imphalolwidth, totaluwidth=imphalouwidth, &
5173  staggerloc=impstaggerloc, indexflag=impindexflag, rc=rc )
5174  if (esmf_logfounderror(rc, passthru)) return
5175 
5176  if ( impgridislocal ) then
5177  call esmf_fieldget( impmask, localde=lde, farrayptr=mptr, &
5178  exclusivelbound=elb, exclusiveubound=eub, &
5179  totallbound=tlb, totalubound=tub, rc=rc )
5180  if (esmf_logfounderror(rc, passthru)) return
5181  call esmf_fieldget( impfield, localde=lde, farrayptr=dptr, rc=rc )
5182  if (esmf_logfounderror(rc, passthru)) return
5183  call esmf_fieldget( bmskfield, localde=lde, farrayptr=bmsk, rc=rc )
5184  if (esmf_logfounderror(rc, passthru)) return
5185  call esmf_fieldget( cmskfield, localde=lde, farrayptr=cmsk, rc=rc )
5186  if (esmf_logfounderror(rc, passthru)) return
5187  endif
5188  !
5189  ! -------------------------------------------------------------------- /
5190  ! Create blending mask
5191  !
5192  if ( impgridislocal ) then
5193  do j = elb(2),eub(2)
5194  do i = elb(1),eub(1)
5195  if ( nint(dptr(i,j)).eq.nint(missingval) ) then
5196  bmsk(i,j) = zero
5197  else
5198  bmsk(i,j) = one
5199  endif
5200  cmsk(i,j) = bmsk(i,j)
5201  enddo
5202  enddo
5203  endif
5204 #if defined(TEST_WMESMFMD) || defined(TEST_WMESMFMD_SETUPIMPBMSK)
5205  timeslice = 1
5206  call esmf_fieldwrite( bmskfield, &
5207  "wmesmfmd_setupimpbmsk_"//trim(fnm)//".nc", &
5208  overwrite=.true., timeslice=timeslice, rc=rc )
5209  if (esmf_logfounderror(rc, passthru)) return
5210 #endif
5211 
5212  iter_loop: do iter = iter0,niter
5213 
5214  call esmf_fieldhalo( bmskfield, imphalorh, rc=rc )
5215  if (esmf_logfounderror(rc, passthru)) return
5216 
5217  if ( impgridislocal ) then
5218 
5219  j_loop: do j = elb(2),eub(2)
5220  i_loop: do i = elb(1),eub(1)
5221  if ( nint(mptr(i,j)).eq.maskvalueland ) cycle i_loop
5222  if ( nint(dptr(i,j)).eq.nint(missingval) ) cycle i_loop
5223 
5224  if (iter.le.0) then
5225 
5226  ! initialize blending zone to zero
5227  l_loop0: do l = -1,1
5228  jj = j + l
5229  if ( jj.lt.tlb(2).or.jj.gt.tub(2) ) cycle l_loop0
5230  k_loop0: do k = -1,1
5231  ii = i + k
5232  if ( ii.lt.tlb(1).or.ii.gt.tub(1) ) cycle k_loop0
5233  if ( nint(mptr(ii,jj)).eq.maskvalueland ) cycle k_loop0
5234  if ( bmsk(ii,jj).eq.zero ) cmsk(i,j) = zero
5235  enddo k_loop0
5236  enddo l_loop0
5237 
5238  else
5239 
5240  ! iterate filter over blending zone
5241  bsum = zero
5242  wsum = zero
5243  l_loop: do l = -nsig,nsig
5244  jj = j + l
5245  if ( jj.lt.tlb(2).or.jj.gt.tub(2) ) cycle l_loop
5246  k_loop: do k = -nsig,nsig
5247  ii = i + k
5248  if ( ii.lt.tlb(1).or.ii.gt.tub(1) ) cycle k_loop
5249  if ( nint(mptr(ii,jj)).eq.maskvalueland ) cycle k_loop
5250  bsum = bsum + wflt(k,l)*bmsk(ii,jj)
5251  wsum = wsum + wflt(k,l)
5252  enddo k_loop
5253  enddo l_loop
5254  if ( wsum.gt.zero ) cmsk(i,j) = bsum/wsum
5255 
5256  endif
5257 
5258  enddo i_loop
5259  enddo j_loop
5260 
5261  do j = elb(2),eub(2)
5262  do i = elb(1),eub(1)
5263  if ( nint(mptr(i,j)).eq.maskvalueland ) cycle
5264  bmsk(i,j) = cmsk(i,j)
5265  enddo
5266  enddo
5267 
5268  endif
5269 #if defined(TEST_WMESMFMD) || defined(TEST_WMESMFMD_SETUPIMPBMSK)
5270  timeslice = timeslice + 1
5271  call esmf_fieldwrite( bmskfield, &
5272  "wmesmfmd_setupimpbmsk_"//trim(fnm)//".nc", &
5273  overwrite=.true., timeslice=timeslice, rc=rc )
5274  if (esmf_logfounderror(rc, passthru)) return
5275 #endif
5276 
5277  enddo iter_loop
5278  !
5279  ! -------------------------------------------------------------------- /
5280  ! Clean up
5281  !
5282  call esmf_fielddestroy( cmskfield, rc=rc )
5283  if (esmf_logfounderror(rc, passthru)) return
5284  !/
5285  !/ End of SetupImpBmsk ----------------------------------------------- /
5286  !/
5287  end subroutine setupimpbmsk
5288  !/ ------------------------------------------------------------------- /
5289  !/
5290 #undef METHOD
5291 #define METHOD "BlendImpField"
5292 
5302  subroutine blendimpfield( impField, mbgField, bmskField, rc )
5303  !/
5304  !/ +-----------------------------------+
5305  !/ | WAVEWATCH III NOAA/NCEP |
5306  !/ | T. J. Campbell, NRL |
5307  !/ | FORTRAN 90 |
5308  !/ | Last update : 09-Aug-2017 |
5309  !/ +-----------------------------------+
5310  !/
5311  !/ 09-Aug-2017 : Origination. ( version 6.03 )
5312  !/
5313  ! 1. Purpose :
5314  !
5315  ! Blend import field with background field
5316  !
5317  ! 2. Method :
5318  !
5319  ! 3. Parameters :
5320  !
5321  ! Parameter list
5322  ! ----------------------------------------------------------------
5323  ! impField Type I/O import field
5324  ! mbgField Type I import background field
5325  ! bmskField Type I blending mask field
5326  ! rc Int I/O Return code
5327  ! ----------------------------------------------------------------
5328  !
5329  ! 4. Subroutines used :
5330  !
5331  ! Name Type Module Description
5332  ! ----------------------------------------------------------------
5333  ! NONE
5334  ! ----------------------------------------------------------------
5335  !
5336  ! 5. Called by :
5337  !
5338  ! 6. Error messages :
5339  !
5340  ! 7. Remarks :
5341  !
5342  ! 8. Structure :
5343  !
5344  ! 9. Switches :
5345  !
5346  ! 10. Source code :
5347  !
5348  !/ ------------------------------------------------------------------- /
5349  !/
5350  !/ ------------------------------------------------------------------- /
5351  !/ Parameter list
5352  !/
5353  implicit none
5354  type(esmf_field), intent(inout) :: impField
5355  type(esmf_field), intent(in) :: mbgField
5356  type(esmf_field), intent(in) :: bmskField
5357  integer, optional, intent(inout) :: rc
5358  !/
5359  !/ ------------------------------------------------------------------- /
5360  !/ Local parameters
5361  !/
5362  real(ESMF_KIND_RX), parameter :: one = 1.0
5363  integer, parameter :: lde = 0
5364  integer :: i, j
5365  integer :: elb(2), eub(2)
5366  real(ESMF_KIND_RX), pointer :: mptr(:,:), dptr(:,:), sptr(:,:)
5367  real(ESMF_KIND_RX), pointer :: bmsk(:,:)
5368  !
5369  ! -------------------------------------------------------------------- /
5370  ! Get array pointers and bounds
5371  !
5372  if (present(rc)) rc = esmf_success
5373 
5374  if ( impgridislocal ) then
5375  call esmf_fieldget( impmask, localde=lde, farrayptr=mptr, &
5376  exclusivelbound=elb, exclusiveubound=eub, rc=rc )
5377  if (esmf_logfounderror(rc, passthru)) return
5378  call esmf_fieldget( impfield, localde=lde, farrayptr=dptr, rc=rc )
5379  if (esmf_logfounderror(rc, passthru)) return
5380  call esmf_fieldget( mbgfield, localde=lde, farrayptr=sptr, rc=rc )
5381  if (esmf_logfounderror(rc, passthru)) return
5382  call esmf_fieldget( bmskfield, localde=lde, farrayptr=bmsk, rc=rc )
5383  if (esmf_logfounderror(rc, passthru)) return
5384  endif
5385  !
5386  ! -------------------------------------------------------------------- /
5387  ! Blend Fields
5388  !
5389  if ( impgridislocal ) then
5390  do j = elb(2),eub(2)
5391  do i = elb(1),eub(1)
5392  if ( nint(mptr(i,j)).eq.maskvalueland ) cycle
5393  dptr(i,j) = bmsk(i,j)*dptr(i,j) + (one-bmsk(i,j))*sptr(i,j)
5394  enddo
5395  enddo
5396  endif
5397  !/
5398  !/ End of BlendImpField ---------------------------------------------- /
5399  !/
5400  end subroutine blendimpfield
5401  !/ ------------------------------------------------------------------- /
5402  !/
5403 #undef METHOD
5404 #define METHOD "SetupImpMmsk"
5405 
5417  subroutine setupimpmmsk( mmskField, impField, fillVal, mskCreated, rc )
5418  !/
5419  !/ +-----------------------------------+
5420  !/ | WAVEWATCH III NOAA/NCEP |
5421  !/ | U. Turuncoglu |
5422  !/ | FORTRAN 90 |
5423  !/ | Last update : 18-May-2021 |
5424  !/ +-----------------------------------+
5425  !/
5426  !/ 18-May-2021 : Origination. ( version 7.13 )
5427  !/
5428  ! 1. Purpose :
5429  !
5430  ! Setup merging mask field for an import field for the cases that
5431  ! model domains does not overlap completely
5432  !
5433  ! 2. Method :
5434  !
5435  ! 3. Parameters :
5436  !
5437  ! Parameter list
5438  ! ----------------------------------------------------------------
5439  ! mmskField Type I/O merging mask field
5440  ! impField Type I import field
5441  ! fillVal Real I fill value
5442  ! mskCreated Log. I/O mask is created or not
5443  ! rc Int O Return code
5444  ! ----------------------------------------------------------------
5445  !
5446  ! 4. Subroutines used :
5447  !
5448  ! Name Type Module Description
5449  ! ----------------------------------------------------------------
5450  ! NONE
5451  ! ----------------------------------------------------------------
5452  !
5453  ! 5. Called by :
5454  !
5455  ! 6. Error messages :
5456  !
5457  ! 7. Remarks :
5458  !
5459  ! 8. Structure :
5460  !
5461  ! 9. Switches :
5462  !
5463  ! 10. Source code :
5464  !
5465  !/ ------------------------------------------------------------------- /
5466  !/
5467  !/ ------------------------------------------------------------------- /
5468  !/ Parameter list
5469  !/
5470  implicit none
5471  type(esmf_field) :: mmskField
5472  type(esmf_field) :: impField
5473  real(ESMF_KIND_RX) :: fillVal
5474  logical :: mskCreated
5475  integer, optional :: rc
5476  !/
5477  !/ ------------------------------------------------------------------- /
5478  !/ Local parameters
5479  !/
5480  integer, parameter :: lde = 0
5481  integer :: i, j
5482  integer :: elb(2), eub(2)
5483  integer :: tlb(2), tub(2)
5484  real(ESMF_KIND_RX), pointer :: mptr(:,:), dptr(:,:)
5485  real(ESMF_KIND_RX), pointer :: mmsk(:,:)
5486  character(ESMF_MAXSTR) :: fnm
5487 #if defined(TEST_WMESMFMD) || defined(TEST_WMESMFMD_SETUPIMPMMSK)
5488  integer, save :: timeSlice = 1
5489 #endif
5490  !
5491  ! -------------------------------------------------------------------- /
5492  ! Check mask is created or not
5493  !
5494  if ( mskcreated ) return
5495  !
5496  ! -------------------------------------------------------------------- /
5497  ! Set up fields and pointers
5498  !
5499 
5500  call esmf_fieldget( impfield, name=fnm, rc=rc )
5501  if (esmf_logfounderror(rc, passthru)) return
5502 
5503  if ( impgridislocal ) then
5504  call esmf_fieldget( impmask, localde=lde, farrayptr=mptr, &
5505  exclusivelbound=elb, exclusiveubound=eub, &
5506  totallbound=tlb, totalubound=tub, rc=rc )
5507  if (esmf_logfounderror(rc, passthru)) return
5508  call esmf_fieldget( impfield, localde=lde, farrayptr=dptr, rc=rc )
5509  if (esmf_logfounderror(rc, passthru)) return
5510  call esmf_fieldget( mmskfield, localde=lde, farrayptr=mmsk, rc=rc )
5511  if (esmf_logfounderror(rc, passthru)) return
5512  endif
5513  !
5514  ! -------------------------------------------------------------------- /
5515  ! Create merging mask
5516  !
5517  if ( impgridislocal ) then
5518  do j = elb(2),eub(2)
5519  do i = elb(1),eub(1)
5520  mmsk(i,j) = 0.0
5521  if (dptr(i,j).lt.fillval) then
5522  mmsk(i,j) = 1.0
5523  end if
5524  enddo
5525  enddo
5526  endif
5527  !
5528  ! -------------------------------------------------------------------- /
5529  ! Set mask created flag
5530  !
5531  mskcreated = .true.
5532 #if defined(TEST_WMESMFMD) || defined(TEST_WMESMFMD_SETUPIMPMMSK)
5533  call esmf_fieldwrite( mmskfield, &
5534  "wmesmfmd_setupimpmmsk_"//trim(fnm)//".nc", &
5535  overwrite=.true., timeslice=timeslice, rc=rc )
5536  if (esmf_logfounderror(rc, passthru)) return
5537  timeslice = timeslice+1
5538 #endif
5539  !/
5540  !/ End of SetupImpMmsk ----------------------------------------------- /
5541  !/
5542  end subroutine setupimpmmsk
5543  !/ ------------------------------------------------------------------- /
5544  !/
5545 #undef METHOD
5546 #define METHOD "FieldFill"
5547 
5556  subroutine fieldfill(field, fillVal, rc)
5557  !/
5558  !/ +-----------------------------------+
5559  !/ | WAVEWATCH III NOAA/NCEP |
5560  !/ | T. J. Campbell, NRL |
5561  !/ | FORTRAN 90 |
5562  !/ | Last update : 09-Aug-2017 |
5563  !/ +-----------------------------------+
5564  !/
5565  !/ 20-Jan-2017 : Origination. ( version 6.02 )
5566  !/ 09-Aug-2017 : Remove mask parameter. ( version 6.03 )
5567  !/
5568  ! 1. Purpose :
5569  !
5570  ! Fill ESMF Field
5571  !
5572  ! 2. Method :
5573  !
5574  ! 3. Parameters :
5575  !
5576  ! Parameter list
5577  ! ----------------------------------------------------------------
5578  ! field Type I/O ESMF field
5579  ! fillVal Real I fill value
5580  ! rc Int O Return code
5581  ! ----------------------------------------------------------------
5582  !
5583  ! 4. Subroutines used :
5584  !
5585  ! Name Type Module Description
5586  ! ----------------------------------------------------------------
5587  ! NONE
5588  ! ----------------------------------------------------------------
5589  !
5590  ! 5. Called by :
5591  !
5592  ! 6. Error messages :
5593  !
5594  ! 7. Remarks :
5595  !
5596  ! 8. Structure :
5597  !
5598  ! 9. Switches :
5599  !
5600  ! 10. Source code :
5601  !
5602  !/ ------------------------------------------------------------------- /
5603  !/
5604  !/ ------------------------------------------------------------------- /
5605  !/ Parameter list
5606  !/
5607  implicit none
5608  type(esmf_field) :: field
5609  real(ESMF_KIND_RX) :: fillVal
5610  integer, optional :: rc
5611  !/
5612  !/ ------------------------------------------------------------------- /
5613  !/ Local parameters
5614  !/
5615  integer :: ldecnt, lde, i, j, k
5616  integer :: rank
5617  integer :: lb1(1), ub1(1)
5618  integer :: lb2(2), ub2(2)
5619  integer :: lb3(3), ub3(3)
5620  real(ESMF_KIND_RX), pointer :: dptr1(:)
5621  real(ESMF_KIND_RX), pointer :: dptr2(:,:)
5622  real(ESMF_KIND_RX), pointer :: dptr3(:,:,:)
5623  integer, parameter :: iwt=10
5624  real(8) :: wstime, wftime
5625  !
5626  ! -------------------------------------------------------------------- /
5627  ! Fill Field
5628  !
5629  if (present(rc)) rc = esmf_success
5630 
5631  call esmf_vmwtime(wstime)
5632 
5633  call esmf_fieldget(field, localdecount=ldecnt, rank=rank, rc=rc)
5634  if (esmf_logfounderror(rc, passthru)) return ! bail out
5635  if (rank.ne.1.and.rank.ne.2.and.rank.ne.3) then
5636  call esmf_logseterror(esmf_failure, rctoreturn=rc, &
5637  msg='FieldFill: rank must be 1, 2 or 3')
5638  return ! bail out
5639  endif
5640 
5641  do lde=0,ldecnt-1
5642 
5643  if (rank.eq.1) then
5644  call esmf_fieldget(field, localde=lde, farrayptr=dptr1, &
5645  exclusivelbound=lb1, exclusiveubound=ub1, rc=rc)
5646  if (esmf_logfounderror(rc, passthru)) return ! bail out
5647  elseif (rank.eq.2) then
5648  call esmf_fieldget(field, localde=lde, farrayptr=dptr2, &
5649  exclusivelbound=lb2, exclusiveubound=ub2, rc=rc)
5650  if (esmf_logfounderror(rc, passthru)) return ! bail out
5651  else
5652  call esmf_fieldget(field, localde=lde, farrayptr=dptr3, &
5653  exclusivelbound=lb3, exclusiveubound=ub3, rc=rc)
5654  if (esmf_logfounderror(rc, passthru)) return ! bail out
5655  endif
5656 
5657  if (rank.eq.1) then
5658  dptr1(lb1(1):ub1(1)) = fillval
5659  elseif (rank.eq.2) then
5660  dptr2(lb2(1):ub2(1),lb2(2):ub2(2)) = fillval
5661  else
5662  dptr3(lb3(1):ub3(1),lb3(2):ub3(2),lb3(3):ub3(3)) = fillval
5663  endif
5664 
5665  enddo
5666 
5667  call esmf_vmwtime(wftime)
5668  wtime(iwt) = wtime(iwt) + wftime - wstime
5669  wtcnt(iwt) = wtcnt(iwt) + 1
5670  !/
5671  !/ End of FieldFill ------------------------------------------------- /
5672  !/
5673  end subroutine fieldfill
5674  !/ ------------------------------------------------------------------- /
5675  !/
5676 #undef METHOD
5677 #define METHOD "FieldGather"
5678 
5691  subroutine fieldgather(field, n1, n2, fout, rc)
5692  !/
5693  !/ +-----------------------------------+
5694  !/ | WAVEWATCH III NOAA/NCEP |
5695  !/ | T. J. Campbell, NRL |
5696  !/ | A. J. van der Westhuysen |
5697  !/ | FORTRAN 90 |
5698  !/ | Last update : 20-Jan-2017 |
5699  !/ +-----------------------------------+
5700  !/
5701  !/ 20-Jan-2017 : Origination. ( version 6.02 )
5702  !/ 27-Feb-2018 : Modification for use with UNGTYPE ( version 6.06 )
5703  !/
5704  ! 1. Purpose :
5705  !
5706  ! All gather of ESMF field
5707  !
5708  ! 2. Method :
5709  !
5710  ! 3. Parameters :
5711  !
5712  ! Parameter list
5713  ! ----------------------------------------------------------------
5714  ! field Type I/O ESMF field
5715  ! n1,n2 Int I Dimensions of output array
5716  ! fout R.A. O global output array
5717  ! rc Int O Return code
5718  ! ----------------------------------------------------------------
5719  !
5720  ! 4. Subroutines used :
5721  !
5722  ! Name Type Module Description
5723  ! ----------------------------------------------------------------
5724  ! NONE
5725  ! ----------------------------------------------------------------
5726  !
5727  ! 5. Called by :
5728  !
5729  ! 6. Error messages :
5730  !
5731  ! 7. Remarks :
5732  !
5733  ! 8. Structure :
5734  !
5735  ! 9. Switches :
5736  !
5737  ! 10. Source code :
5738  !
5739  !/ ------------------------------------------------------------------- /
5740  !/
5741 #ifdef W3_PDLIB
5742  use yownodepool, only: np, iplg
5743  use yowrankmodule, only: rank
5744 #endif
5745  !/
5746  implicit none
5747  !/ ------------------------------------------------------------------- /
5748  !/ Parameter list
5749  !/
5750  type(esmf_field) :: field
5751  integer :: n1, n2
5752  real :: fout(n1,n2)
5753  integer, optional :: rc
5754  !/
5755  !/ ------------------------------------------------------------------- /
5756  !/ Local parameters
5757  !/
5758  character(ESMF_MAXSTR) :: cname
5759  character(500) :: msg
5760  integer :: i, j, k, ir, ip, count
5761  real(ESMF_KIND_RX) :: floc(n1,n2)
5762  real(ESMF_KIND_RX) :: floc1d(n1), floc1dary(n1*n2)
5763 #ifdef W3_PDLIB
5764  real(ESMF_KIND_R8), pointer :: fldptr(:)
5765 #endif
5766  integer, parameter :: iwt=9
5767  real(8) :: wstime, wftime
5768  !
5769  ! -------------------------------------------------------------------- /
5770  ! Gather Field
5771  !
5772  if (present(rc)) rc = esmf_success
5773 
5774  call esmf_vmwtime(wstime)
5775 
5776  if ( (gtype.eq.rlgtype).or.(gtype.eq.clgtype) ) then
5777  count = n1 * n2
5778  floc = 0.
5779  floc1dary = 0.
5780  call esmf_fieldgather( field, floc, rootpet=0, vm=vm, rc=rc )
5781  if (esmf_logfounderror(rc, passthru)) return
5782  do j=1,n2
5783  do i=1,n1
5784  floc1dary(i+(j-1)*n1) = floc(i,j)
5785  enddo
5786  enddo
5787  call esmf_vmbroadcast( vm, bcstdata=floc1dary, count=count, rootpet=0, rc=rc)
5788  if (esmf_logfounderror(rc, passthru)) return
5789  do j=1,n2
5790  do i=1,n1
5791  fout(i,j) = floc1dary(i+(j-1)*n1)
5792  enddo
5793  enddo
5794  elseif (gtype.eq.ungtype) then
5795  count = n1
5796  floc1d = 0.
5797  call esmf_fieldgather( field, floc1d, rootpet=0, vm=vm, rc=rc )
5798  if (esmf_logfounderror(rc, passthru)) return
5799  call esmf_vmbroadcast( vm, bcstdata=floc1d, count=count, rootpet=0, rc=rc)
5800  if (esmf_logfounderror(rc, passthru)) return
5801 #ifdef W3_PDLIB
5802  if ( lpdlib .EQV. .false. ) then
5803 #endif
5804  do k = 1, n1
5805  fout(k,1) = floc1d(k)
5806  enddo
5807 #ifdef W3_PDLIB
5808  else
5809  count = 0
5810  do ir = 1, npet
5811  do ip = 1, rank(ir)%np
5812  count = count+1
5813  fout(rank(ir)%iplg(ip),1) = floc1d(count)
5814  ! write(msg,*) trim(cname)//': count,ir,ip =',count, &
5815  ! ir,ip
5816  ! call ESMF_LogWrite(trim(msg), ESMF_LOGMSG_INFO)
5817  enddo
5818  enddo
5819  endif
5820 #endif
5821 
5822 #ifdef W3_PDLIB
5823  ! call ESMF_LogWrite(trim(cname)//': In FieldGather, fout(k,1)=', &
5824  ! ESMF_LOGMSG_INFO)
5825  ! do k = 1, n1
5826  ! write(msg,*) trim(cname)//': fout(k,1) =',k, &
5827  ! ' ',fout(k,1)
5828  ! call ESMF_LogWrite(trim(msg), ESMF_LOGMSG_INFO)
5829  ! enddo
5830 #endif
5831 
5832  endif
5833 
5834  call esmf_vmwtime(wftime)
5835  wtime(iwt) = wtime(iwt) + wftime - wstime
5836  wtcnt(iwt) = wtcnt(iwt) + 1
5837 
5838  !/
5839  !/ End of FieldGather ------------------------------------------------ /
5840  !/
5841  end subroutine fieldgather
5842  !/ ------------------------------------------------------------------- /
5843  !/
5844 #undef METHOD
5845 #define METHOD "FieldIndex"
5846 
5856  function fieldindex ( fnameList, fname, rc ) result (indx)
5857  !/
5858  !/ +-----------------------------------+
5859  !/ | WAVEWATCH III NOAA/NCEP |
5860  !/ | T. J. Campbell, NRL |
5861  !/ | FORTRAN 90 |
5862  !/ | Last update : 20-Jan-2017 |
5863  !/ +-----------------------------------+
5864  !/
5865  !/ 20-Jan-2017 : Origination. ( version 6.02 )
5866  !/
5867  ! 1. Purpose :
5868  !
5869  ! Return index associated with field name
5870  !
5871  ! 2. Method :
5872  !
5873  ! 3. Parameters :
5874  !
5875  ! Parameter list
5876  ! ----------------------------------------------------------------
5877  ! fnameList StrA I Array of field names
5878  ! fname Str I Field name
5879  ! rc Int. O Return code
5880  ! indx Int I Returned index of fname
5881  ! ----------------------------------------------------------------
5882  !
5883  ! 4. Subroutines used :
5884  !
5885  ! Name Type Module Description
5886  ! ----------------------------------------------------------------
5887  ! NONE
5888  ! ----------------------------------------------------------------
5889  !
5890  ! 5. Called by :
5891  !
5892  ! 6. Error messages :
5893  !
5894  ! 7. Remarks :
5895  !
5896  ! 8. Structure :
5897  !
5898  ! 9. Switches :
5899  !
5900  ! 10. Source code :
5901  !
5902  !/ ------------------------------------------------------------------- /
5903  !/
5904  !/ ------------------------------------------------------------------- /
5905  !/ Parameter list
5906  !/
5907  implicit none
5908  character (len=*) :: fnamelist(:)
5909  character (len=*) :: fname
5910  integer :: rc
5911  integer :: indx
5912  !/
5913  !/ ------------------------------------------------------------------- /
5914  !/ Local parameters
5915  !/
5916  integer :: i, check
5917  !
5918  ! -------------------------------------------------------------------- /
5919  ! Find name in fnameList that matches fname
5920  !
5921  check = lbound(fnamelist,1) - 1
5922  indx = check
5923  do i = lbound(fnamelist,1),ubound(fnamelist,1)
5924  if ( trim(fnamelist(i)).eq.trim(fname) ) then
5925  indx = i
5926  exit
5927  endif
5928  enddo
5929  if ( indx.eq.check ) then
5930  call esmf_logseterror(esmf_failure, rctoreturn=rc, &
5931  msg='FieldIndex: input name ('//fname//') not in list')
5932  endif
5933  !/
5934  !/ End of FieldIndex ------------------------------------------------- /
5935  !/
5936  end function fieldindex
5937  !/ ------------------------------------------------------------------- /
5938  !/
5939 #undef METHOD
5940 #define METHOD "PrintTimers"
5941 
5951  subroutine printtimers ( cname, wtnam, wtcnt, wtime )
5952  !/
5953  !/ +-----------------------------------+
5954  !/ | WAVEWATCH III NOAA/NCEP |
5955  !/ | T. J. Campbell, NRL |
5956  !/ | FORTRAN 90 |
5957  !/ | Last update : 20-Jan-2017 |
5958  !/ +-----------------------------------+
5959  !/
5960  !/ 20-Jan-2017 : Origination. ( version 6.02 )
5961  !/
5962  ! 1. Purpose :
5963  !
5964  ! Print wallclock timers to ESMF log file
5965  !
5966  ! 2. Method :
5967  !
5968  ! 3. Parameters :
5969  !
5970  ! Parameter list
5971  ! ----------------------------------------------------------------
5972  ! cname Str I Name of component
5973  ! wtnam Str I Timer names
5974  ! wtcnt Int I Timer counts
5975  ! wtime R8 I Timers
5976  ! ----------------------------------------------------------------
5977  !
5978  ! 4. Subroutines used :
5979  !
5980  ! Name Type Module Description
5981  ! ----------------------------------------------------------------
5982  ! NONE
5983  ! ----------------------------------------------------------------
5984  !
5985  ! 5. Called by :
5986  !
5987  ! 6. Error messages :
5988  !
5989  ! 7. Remarks :
5990  !
5991  ! 8. Structure :
5992  !
5993  ! 9. Switches :
5994  !
5995  ! 10. Source code :
5996  !
5997  !/ ------------------------------------------------------------------- /
5998  !/
5999  !/ ------------------------------------------------------------------- /
6000  !/ Parameter list
6001  !/
6002  implicit none
6003  character(*) :: cname
6004  character(*) :: wtnam(:)
6005  integer :: wtcnt(:)
6006  real(8) :: wtime(:)
6007  !/
6008  !/ ------------------------------------------------------------------- /
6009  !/ Local parameters
6010  !/
6011  character(128) :: msg
6012  integer :: k
6013  !
6014  ! -------------------------------------------------------------------- /
6015  ! Print timers to ESMF log file
6016  !
6017  write(msg,1) trim(cname),"timer","count","time"
6018  call esmf_logwrite(trim(msg), esmf_logmsg_info)
6019  do k=lbound(wtcnt,1),ubound(wtcnt,1)
6020  write(msg,2) trim(cname),trim(wtnam(k)),wtcnt(k),wtime(k)
6021  call esmf_logwrite(trim(msg), esmf_logmsg_info)
6022  enddo
6023  !
6024  ! -------------------------------------------------------------------- /
6025  ! Formats
6026  !
6027 1 format(a,': wtime: ',a20,a10,a14)
6028 2 format(a,': wtime: ',a20,i10,e14.6)
6029  !/
6030  !/ End of PrintTimers ------------------------------------------------ /
6031  !/
6032  end subroutine printtimers
6033  !/ ------------------------------------------------------------------- /
6034  !/
6035 #undef METHOD
6036 #define METHOD "CalcDecomp"
6037 
6051  subroutine calcdecomp ( nx, ny, nproc, npmin, adjust, nxproc, nyproc, rc )
6052  !/
6053  !/ +-----------------------------------+
6054  !/ | WAVEWATCH III NOAA/NCEP |
6055  !/ | T. J. Campbell, NRL |
6056  !/ | FORTRAN 90 |
6057  !/ | Last update : 09-Aug-2017 |
6058  !/ +-----------------------------------+
6059  !/
6060  !/ 09-Aug-2017 : Origination. ( version 6.03 )
6061  !/
6062  ! 1. Purpose :
6063  !
6064  ! Calculate a 2D processor layout
6065  !
6066  ! 2. Method :
6067  !
6068  ! 3. Parameters :
6069  !
6070  ! Parameter list
6071  ! ----------------------------------------------------------------
6072  ! nx,ny Int I Grid dimensions
6073  ! nproc Int I Total processor count
6074  ! npmin Int I Min number of grid points per tile per direction
6075  ! adjust Log I Enable/disable adjusting proc count downward
6076  ! nxproc Int O Processor count in x-direction
6077  ! nyproc Int O Processor count in y-direction
6078  ! rc Int O Return code
6079  ! ----------------------------------------------------------------
6080  !
6081  ! 4. Subroutines used :
6082  !
6083  ! Name Type Module Description
6084  ! ----------------------------------------------------------------
6085  ! NONE
6086  ! ----------------------------------------------------------------
6087  !
6088  ! 5. Called by :
6089  !
6090  ! 6. Error messages :
6091  !
6092  ! 7. Remarks :
6093  !
6094  ! 8. Structure :
6095  !
6096  ! 9. Switches :
6097  !
6098  ! 10. Source code :
6099  !
6100  !/ ------------------------------------------------------------------- /
6101  !/
6102  !/ ------------------------------------------------------------------- /
6103  !/ Parameter list
6104  !/
6105  implicit none
6106  integer, intent(in) :: nx, ny
6107  integer, intent(in) :: nproc
6108  integer, intent(in) :: npmin
6109  logical, intent(in) :: adjust
6110  integer, intent(out) :: nxproc
6111  integer, intent(out) :: nyproc
6112  integer, intent(inout) :: rc
6113  !/
6114  !/ ------------------------------------------------------------------- /
6115  !/ Local parameters
6116  !/
6117  integer, parameter :: k = 4
6118  integer :: mproc, n, nfac, irp
6119  real(k) :: gr, rp, pr, diff, npx, npy
6120  character(256) :: msg
6121  !
6122  ! -------------------------------------------------------------------- /
6123  !
6124  rc = esmf_success
6125 
6126  if ( nx.gt.ny ) then
6127  gr = real(nx,k)/real(ny,k)
6128  else
6129  gr = real(ny,k)/real(nx,k)
6130  endif
6131 
6132  mproc = nproc
6133  mproc_loop: do
6134 
6135  irp = int(sqrt(real(mproc,k)))
6136  diff = huge(gr)
6137  nfac = mproc
6138  do n = irp,mproc
6139  if ( mod(mproc,n).ne.0 ) cycle
6140  pr = real(n**2,k)/real(mproc,k)
6141  if ( abs(gr-pr) < diff ) then
6142  diff = abs(gr-pr)
6143  nfac = n
6144  endif
6145  enddo
6146  if ( nx.gt.ny ) then
6147  nxproc = nfac
6148  nyproc = mproc/nfac
6149  else
6150  nxproc = mproc/nfac
6151  nyproc = nfac
6152  endif
6153 
6154  npx = nx/real(nxproc,k)
6155  npy = ny/real(nyproc,k)
6156  if (.not.adjust) exit mproc_loop
6157 
6158  if ( npx.ge.npmin .and. npy.ge.npmin ) then
6159  exit mproc_loop
6160  else
6161  if ( mproc.gt.1 ) then
6162  mproc = mproc - 1
6163  else
6164  exit mproc_loop
6165  endif
6166  endif
6167 
6168  enddo mproc_loop
6169 
6170  if ( npx.lt.npmin .or. npy.lt.npmin ) then
6171  write(msg,'(a,7i6)') 'proc count is too large for grid size:', &
6172  nx,ny,npmin,nproc,mproc,nxproc,nyproc
6173  call esmf_logwrite(trim(msg), esmf_logmsg_error)
6174  rc = esmf_failure
6175  endif
6176  !/
6177  !/ End of CalcDecomp ------------------------------------------------- /
6178  !/
6179  end subroutine calcdecomp
6180  !/ ------------------------------------------------------------------- /
6181  !/
6182 #undef METHOD
6183 #define METHOD "GetEnvValue"
6184 
6193  subroutine getenvvalue ( cenv, cval, rc )
6194  !/
6195  !/ +-----------------------------------+
6196  !/ | WAVEWATCH III NOAA/NCEP |
6197  !/ | T. J. Campbell, NRL |
6198  !/ | FORTRAN 90 |
6199  !/ | Last update : 09-Aug-2017 |
6200  !/ +-----------------------------------+
6201  !/
6202  !/ 09-Aug-2017 : Origination. ( version 6.03 )
6203  !/
6204  ! 1. Purpose :
6205  !
6206  ! Get value of environment variable
6207  !
6208  ! 2. Method :
6209  !
6210  ! 3. Parameters :
6211  !
6212  ! Parameter list
6213  ! ----------------------------------------------------------------
6214  ! cenv Str I Name of environment variable
6215  ! cval Str O Value of environment variable
6216  ! rc Int O Return code
6217  ! ----------------------------------------------------------------
6218  !
6219  ! 4. Subroutines used :
6220  !
6221  ! Name Type Module Description
6222  ! ----------------------------------------------------------------
6223  ! NONE
6224  ! ----------------------------------------------------------------
6225  !
6226  ! 5. Called by :
6227  !
6228  ! 6. Error messages :
6229  !
6230  ! 7. Remarks :
6231  !
6232  ! 8. Structure :
6233  !
6234  ! 9. Switches :
6235  !
6236  ! 10. Source code :
6237  !
6238  !/ ------------------------------------------------------------------- /
6239  !/
6240  !/ ------------------------------------------------------------------- /
6241  !/ Parameter list
6242  !/
6243  implicit none
6244  character(*) :: cenv
6245  character(*) :: cval
6246  integer :: rc
6247  !/
6248  !/ ------------------------------------------------------------------- /
6249  !/ Local parameters
6250  !/
6251  character(256) :: msg
6252  integer :: length, istat
6253  !
6254  ! -------------------------------------------------------------------- /
6255  !
6256  rc = esmf_success
6257  call get_environment_variable( name=trim(cenv), value=cval, &
6258  length=length, trim_name=.false., status=istat )
6259  if (istat.lt.0) then
6260  ! The VALUE argument is present and has a length less than
6261  ! the significant length of the environment variable value.
6262  write(msg,'(a,i3,a)') "Length of input variable", &
6263  " is less than length of environment variable " &
6264  //trim(cenv)//" value (",length,")."
6265  call esmf_logwrite(trim(msg), esmf_logmsg_error)
6266  rc = istat
6267  elseif (istat.gt.0) then
6268  ! 1: The specified environment variable NAME does not exist.
6269  ! 2: The processor does not support environment variables.
6271  cval=" "
6272  endif
6273  if (length.eq.0) cval=" "
6274  !/
6275  !/ End of GetEnvValue ------------------------------------------------ /
6276  !/
6277  end subroutine getenvvalue
6278  !/ ------------------------------------------------------------------- /
6279  !/
6280 #undef METHOD
6281 #define METHOD "GetZlevels"
6282 
6289  subroutine getzlevels ( rc )
6290  !/
6291  !/ +-----------------------------------+
6292  !/ | WAVEWATCH III NOAA/NCEP |
6293  !/ | T. J. Campbell, NRL |
6294  !/ | FORTRAN 90 |
6295  !/ | Last update : 09-Aug-2017 |
6296  !/ +-----------------------------------+
6297  !/
6298  !/ 09-Aug-2017 : Origination. ( version 6.03 )
6299  !/
6300  ! 1. Purpose :
6301  !
6302  ! Get array of z-levels from zlfile for SDC
6303  !
6304  ! 2. Method :
6305  !
6306  ! 3. Parameters :
6307  !
6308  ! Parameter list
6309  ! ----------------------------------------------------------------
6310  ! rc Int O Return code
6311  ! ----------------------------------------------------------------
6312  !
6313  ! 4. Subroutines used :
6314  !
6315  ! Name Type Module Description
6316  ! ----------------------------------------------------------------
6317  ! NONE
6318  ! ----------------------------------------------------------------
6319  !
6320  ! 5. Called by :
6321  !
6322  ! 6. Error messages :
6323  !
6324  ! 7. Remarks :
6325  !
6326  ! 8. Structure :
6327  !
6328  ! 9. Switches :
6329  !
6330  ! 10. Source code :
6331  !
6332  !/ ------------------------------------------------------------------- /
6333  !/
6334  !/ ------------------------------------------------------------------- /
6335  !/ Parameter list
6336  !/
6337  implicit none
6338  integer :: rc
6339  !/
6340  !/ ------------------------------------------------------------------- /
6341  !/ Local parameters
6342  !/
6343  character(256) :: msg
6344  integer :: k, iunit, ierr
6345  !
6346  ! -------------------------------------------------------------------- /
6347  !
6348  rc = esmf_success
6349 
6350  if (len_trim(zlfile).eq.0 .or. trim(zlfile) .eq. 'none') then
6351 
6352  nz = 1
6353  allocate(zl(nz), stat=rc)
6354  if (esmf_logfoundallocerror(rc, passthru)) return
6355  zl(1) = 0
6356 
6357  else
6358 
6359  call esmf_utiliounitget(iunit, rc=rc)
6360  if (esmf_logfounderror(rc, passthru)) return
6361  open(unit=iunit, file=trim(zlfile), form='formatted', &
6362  status='old', access='sequential', iostat=ierr)
6363  if (ierr.ne.0) then
6364  msg = "failed opening "//trim(zlfile)
6365  call esmf_logwrite(trim(msg), esmf_logmsg_error)
6366  rc = esmf_failure
6367  return
6368  endif
6369  read(iunit, fmt=*, iostat=ierr) nz
6370  if (ierr.ne.0) then
6371  msg = "read nz failed: "//trim(zlfile)
6372  call esmf_logwrite(trim(msg), esmf_logmsg_error)
6373  rc = esmf_failure
6374  return
6375  endif
6376  allocate(zl(nz), stat=rc)
6377  if (esmf_logfoundallocerror(rc, passthru)) return
6378  do k=1,nz
6379  read(iunit, fmt=*, iostat=ierr) zl(k)
6380  if (ierr.ne.0) then
6381  msg = "read zl failed: "//trim(zlfile)
6382  call esmf_logwrite(trim(msg), esmf_logmsg_error)
6383  rc = esmf_failure
6384  return
6385  endif
6386  enddo
6387  close(iunit)
6388 
6389  endif
6390  !/
6391  !/ End of GetZlevels ------------------------------------------------- /
6392  !/
6393  end subroutine getzlevels
6394  !/ ------------------------------------------------------------------- /
6395  !/
6396 #undef METHOD
6397 #define METHOD "CalcCharnk"
6398 
6406  subroutine calccharnk ( chkField, rc )
6407  !/
6408  !/ +-----------------------------------+
6409  !/ | WAVEWATCH III NOAA/NCEP |
6410  !/ | T. J. Campbell, NRL |
6411  !/ | FORTRAN 90 |
6412  !/ | Last update : 09-Aug-2017 |
6413  !/ +-----------------------------------+
6414  !/
6415  !/ 09-Aug-2017 : Origination. ( version 6.03 )
6416  !/
6417  ! 1. Purpose :
6418  !
6419  ! Calculate Charnock for export
6420  !
6421  ! 2. Method :
6422  !
6423  ! 3. Parameters :
6424  !
6425  ! Parameter list
6426  ! ----------------------------------------------------------------
6427  ! chkField Type I/O 2D Charnock export field
6428  ! rc Int O Return code
6429  ! ----------------------------------------------------------------
6430  !
6431  ! 4. Subroutines used :
6432  !
6433  ! Name Type Module Description
6434  ! ----------------------------------------------------------------
6435  ! NONE
6436  ! ----------------------------------------------------------------
6437  !
6438  ! 5. Called by :
6439  !
6440  ! 6. Error messages :
6441  !
6442  ! 7. Remarks :
6443  !
6444  ! 8. Structure :
6445  !
6446  ! 9. Switches :
6447  !
6448  ! 10. Source code :
6449  !
6450  !/ ------------------------------------------------------------------- /
6451  !/
6452  !/ ------------------------------------------------------------------- /
6453  !/ Parameter list
6454  !/
6455  implicit none
6456  type(esmf_field) :: chkfield
6457  integer :: rc
6458  !/
6459  !/ ------------------------------------------------------------------- /
6460  !/ Local parameters
6461  !/
6462  real , parameter :: zero = 0.0
6463  logical, save :: firstcall = .true.
6464  integer :: isea, jsea
6465  real :: emean, fmean, fmean1, wnmean, amax, ustar, ustdr, &
6466  tauwx, tauwy, cd, z0, fmeanws, dlwmean
6467  logical :: llws(nspec)
6468  type(esmf_field) :: chknfield
6469  real(esmf_kind_rx), pointer :: chkn(:)
6470  integer, save :: timeslice = 1
6471  !
6472  ! -------------------------------------------------------------------- /
6473  !
6474  rc = esmf_success
6475 
6476  chknfield = esmf_fieldcreate( natgrid, natarrayspec2d, &
6477  staggerloc=natstaggerloc, rc=rc )
6478  if (esmf_logfounderror(rc, passthru)) return
6479 
6480  call fieldfill( chknfield, zerovalue, rc=rc )
6481  if (esmf_logfounderror(rc, passthru)) return
6482 
6483  if ( natgridislocal ) then
6484 
6485  call esmf_fieldget( chknfield, farrayptr=chkn, rc=rc )
6486  if (esmf_logfounderror(rc, passthru)) return
6487 
6488  jsea_loop: do jsea = 1,nseal
6489 #ifdef W3_DIST
6490  isea = iaproc + (jsea-1)*naproc
6491 #endif
6492 #ifdef W3_SHRD
6493  isea = jsea
6494 #endif
6495  if ( firstcall ) then
6496  charn(jsea) = zero
6497 #ifdef W3_ST3
6498  llws(:) = .true.
6499  ustar = zero
6500  ustdr = zero
6501  tauwx = zero
6502  tauwy = zero
6503  call w3spr3( va(:,jsea), cg(1:nk,isea), wn(1:nk,isea), &
6504  emean, fmean, fmean1, wnmean, amax, &
6505  u10(isea), u10d(isea), ustar, ustdr, tauwx, &
6506  tauwy, cd, z0, charn(jsea), llws, fmeanws )
6507 #endif
6508 #ifdef W3_ST4
6509  llws(:) = .true.
6510  ustar = zero
6511  ustdr = zero
6512  tauwx = zero
6513  tauwy = zero
6514  call w3spr4( va(:,jsea), cg(1:nk,isea), wn(1:nk,isea), &
6515  emean, fmean, fmean1, wnmean, amax, &
6516  u10(isea), u10d(isea), ustar, ustdr, tauwx, &
6517  tauwy, cd, z0, charn(jsea), llws, fmeanws, &
6518  dlwmean )
6519 #endif
6520  endif !firstCall
6521  chkn(jsea) = charn(jsea)
6522  enddo jsea_loop
6523 
6524  endif !natGridIsLocal
6525 
6526  call esmf_fieldredist( chknfield, chkfield, n2erh, rc=rc )
6527  if (esmf_logfounderror(rc, passthru)) return
6528 
6529  call esmf_fielddestroy( chknfield, rc=rc )
6530  if (esmf_logfounderror(rc, passthru)) return
6531 
6532  firstcall = .false.
6533 
6534 #ifdef TEST_WMESMFMD_CHARNK
6535  call esmf_fieldwrite( chkfield, "wmesmfmd_charnk_chk.nc", &
6536  overwrite=.true., timeslice=timeslice, rc=rc )
6537  if (esmf_logfounderror(rc, passthru)) return
6538  timeslice = timeslice + 1
6539 #endif
6540  !/
6541  !/ End of CalcCharnk ------------------------------------------------- /
6542  !/
6543  end subroutine calccharnk
6544  !/ ------------------------------------------------------------------- /
6545  !/
6546 #undef METHOD
6547 #define METHOD "CalcRoughl"
6548 
6556  subroutine calcroughl ( wrlField, rc )
6557  !/
6558  !/ +-----------------------------------+
6559  !/ | WAVEWATCH III NOAA/NCEP |
6560  !/ | T. J. Campbell, NRL |
6561  !/ | FORTRAN 90 |
6562  !/ | Last update : 09-Aug-2017 |
6563  !/ +-----------------------------------+
6564  !/
6565  !/ 09-Aug-2017 : Origination. ( version 6.03 )
6566  !/
6567  ! 1. Purpose :
6568  !
6569  ! Calculate 2D wave roughness length for export
6570  !
6571  ! 2. Method :
6572  !
6573  ! 3. Parameters :
6574  !
6575  ! Parameter list
6576  ! ----------------------------------------------------------------
6577  ! wrlField Type I/O 2D roughness length export field
6578  ! rc Int O Return code
6579  ! ----------------------------------------------------------------
6580  !
6581  ! 4. Subroutines used :
6582  !
6583  ! Name Type Module Description
6584  ! ----------------------------------------------------------------
6585  ! NONE
6586  ! ----------------------------------------------------------------
6587  !
6588  ! 5. Called by :
6589  !
6590  ! 6. Error messages :
6591  !
6592  ! 7. Remarks :
6593  !
6594  ! 8. Structure :
6595  !
6596  ! 9. Switches :
6597  !
6598  ! 10. Source code :
6599  !
6600  !/ ------------------------------------------------------------------- /
6601  !/
6602  !/ ------------------------------------------------------------------- /
6603  !/ Parameter list
6604  !/
6605  implicit none
6606  type(esmf_field) :: wrlfield
6607  integer :: rc
6608  !/
6609  !/ ------------------------------------------------------------------- /
6610  !/ Local parameters
6611  !/
6612  real , parameter :: zero = 0.0
6613  logical, save :: firstcall = .true.
6614  integer :: isea, jsea, ix, iy
6615  real :: emean, fmean, fmean1, wnmean, amax, ustar, ustdr, &
6616  tauwx, tauwy, cd, z0, fmeanws, dlwmean
6617  logical :: llws(nspec)
6618  type(esmf_field) :: wrlnfield
6619  real(esmf_kind_rx), pointer :: wrln(:)
6620  integer, save :: timeslice = 1
6621  !
6622  ! -------------------------------------------------------------------- /
6623  !
6624  rc = esmf_success
6625 
6626  wrlnfield = esmf_fieldcreate( natgrid, natarrayspec2d, &
6627  staggerloc=natstaggerloc, rc=rc )
6628  if (esmf_logfounderror(rc, passthru)) return
6629 
6630  call fieldfill( wrlnfield, zerovalue, rc=rc )
6631  if (esmf_logfounderror(rc, passthru)) return
6632 
6633  if ( natgridislocal ) then
6634 
6635  call esmf_fieldget( wrlnfield, farrayptr=wrln, rc=rc )
6636  if (esmf_logfounderror(rc, passthru)) return
6637 
6638  jsea_loop: do jsea = 1,nseal
6639 #ifdef W3_DIST
6640  isea = iaproc + (jsea-1)*naproc
6641 #endif
6642 #ifdef W3_SHRD
6643  isea = jsea
6644 #endif
6645  ix = mapsf(isea,1)
6646  iy = mapsf(isea,2)
6647  IF ( mapsta(iy,ix) .EQ. 1 ) THEN
6648  if ( firstcall ) then
6649  charn(jsea) = zero
6650 #ifdef W3_ST3
6651  llws(:) = .true.
6652  ustar = zero
6653  ustdr = zero
6654  tauwx = zero
6655  tauwy = zero
6656  call w3spr3( va(:,jsea), cg(1:nk,isea), wn(1:nk,isea), &
6657  emean, fmean, fmean1, wnmean, amax, &
6658  u10(isea), u10d(isea), ustar, ustdr, tauwx, &
6659  tauwy, cd, z0, charn(jsea), llws, fmeanws )
6660 #endif
6661 #ifdef W3_ST4
6662  llws(:) = .true.
6663  ustar = zero
6664  ustdr = zero
6665  tauwx = zero
6666  tauwy = zero
6667  call w3spr4( va(:,jsea), cg(1:nk,isea), wn(1:nk,isea), &
6668  emean, fmean, fmean1, wnmean, amax, &
6669  u10(isea), u10d(isea), ustar, ustdr, tauwx, &
6670  tauwy, cd, z0, charn(jsea), llws, fmeanws, &
6671  dlwmean )
6672 #endif
6673  endif !firstCall
6674  wrln(jsea) = charn(jsea)*ust(isea)**2/grav
6675  endif
6676  enddo jsea_loop
6677 
6678  endif !natGridIsLocal
6679 
6680  call esmf_fieldredist( wrlnfield, wrlfield, n2erh, rc=rc )
6681  if (esmf_logfounderror(rc, passthru)) return
6682 
6683  call esmf_fielddestroy( wrlnfield, rc=rc )
6684  if (esmf_logfounderror(rc, passthru)) return
6685 
6686  firstcall = .false.
6687 
6688 #ifdef TEST_WMESMFMD_ROUGHL
6689  call esmf_fieldwrite( wrlfield, "wmesmfmd_roughl_wrl.nc", &
6690  overwrite=.true., timeslice=timeslice, rc=rc )
6691  if (esmf_logfounderror(rc, passthru)) return
6692  timeslice = timeslice + 1
6693 #endif
6694  !/
6695  !/ End of CalcRoughl ------------------------------------------------- /
6696  !/
6697  end subroutine calcroughl
6698  !/ ------------------------------------------------------------------- /
6699  !/
6700 #undef METHOD
6701 #define METHOD "CalcBotcur"
6702 
6715  subroutine calcbotcur ( a, wbxField, wbyField, wbpField, rc )
6716  !/
6717  !/ +-----------------------------------+
6718  !/ | WAVEWATCH III NOAA/NCEP |
6719  !/ | T. J. Campbell, NRL |
6720  !/ | FORTRAN 90 |
6721  !/ | Last update : 09-Aug-2017 |
6722  !/ +-----------------------------------+
6723  !/
6724  !/ 09-Aug-2017 : Origination. ( version 6.03 )
6725  !/
6726  ! 1. Purpose :
6727  !
6728  ! Calculate wave-bottom currents for export
6729  !
6730  ! 2. Method :
6731  !
6732  ! > Madsen, O. S. (1994), ICCE
6733  !
6734  ! //
6735  ! U_bot = sqrt( 2*|| S_ub dsig dtheta )
6736  ! (magnitude) //
6737  !
6738  ! //
6739  ! || S_ub*sin(theta) dsig dtheta
6740  ! //
6741  ! phi_b = arctan( ---------------------------------- )
6742  ! (direction) //
6743  ! || S_ub*cos(theta) dsig dtheta
6744  ! //
6745  !
6746  ! //
6747  ! || S_ub dsig dtheta
6748  ! //
6749  ! U_bp = 2*pi * ----------------------------
6750  ! (period) //
6751  ! || sig*S_ub dsig dtheta
6752  ! //
6753  !
6754  ! Where:
6755  ! S_ub(theta,k) = near-bottom orbital velocity spectrum
6756  ! = ( sig^2 / sinh^2(kD) ) * E(theta,k) / Cg
6757  ! = ( sig^3 / sinh^2(kD) ) * Ac(theta,k) / Cg
6758  ! Ac(theta,k) = wave action density
6759  ! D = depth
6760  !
6761  ! 3. Parameters :
6762  !
6763  ! Parameter list
6764  ! ----------------------------------------------------------------
6765  ! a Real I Input spectra (in par list to change shape)
6766  ! wbxField Type I/O WBC 2D eastward-component export field
6767  ! wbyField Type I/O WBC 2D northward-component export field
6768  ! wbpField Type I/O WBC 2D period export field
6769  ! rc Int O Return code
6770  ! ----------------------------------------------------------------
6771  !
6772  ! 4. Subroutines used :
6773  !
6774  ! Name Type Module Description
6775  ! ----------------------------------------------------------------
6776  ! NONE
6777  ! ----------------------------------------------------------------
6778  !
6779  ! 5. Called by :
6780  !
6781  ! 6. Error messages :
6782  !
6783  ! 7. Remarks :
6784  !
6785  ! 8. Structure :
6786  !
6787  ! 9. Switches :
6788  !
6789  ! 10. Source code :
6790  !
6791  !/ ------------------------------------------------------------------- /
6792  !/
6793  !/ ------------------------------------------------------------------- /
6794  !/ Parameter list
6795  !/
6796  implicit none
6797  real :: a(nth,nk,0:nseal)
6798  type(esmf_field) :: wbxfield
6799  type(esmf_field) :: wbyfield
6800  type(esmf_field) :: wbpfield
6801  integer :: rc
6802  !/
6803  !/ ------------------------------------------------------------------- /
6804  !/ Local parameters
6805  !/
6806  real(8), parameter :: zero = 0.0
6807  real(8), parameter :: half = 0.5
6808  real(8), parameter :: one = 1.0
6809  real(8), parameter :: two = 2.0
6810  ! kdmin = 1e-7: sinh(kdmin)**2 ~ 1e-14
6811  real(8), parameter :: kdmin = 1e-7
6812  ! kdmax = 18.0: 1/sinh(kdmax)**2 ~ 1e-14
6813  real(8), parameter :: kdmax = 18.0
6814  integer :: isea, jsea, ik, ith
6815  real(8) :: depth
6816  real(8) :: kd, fack, fkd, aka, akx, aky, abr, ubr, ubx, uby, dir
6817  real(8), allocatable :: sig2(:)
6818  type(esmf_field) :: wbxnfield, wbynfield, wbpnfield
6819  real(esmf_kind_rx), pointer :: wbxn(:), wbyn(:), wbpn(:)
6820  integer, save :: timeslice = 1
6821  !
6822  ! -------------------------------------------------------------------- /
6823  !
6824  rc = esmf_success
6825 
6826  wbxnfield = esmf_fieldcreate( natgrid, natarrayspec2d, &
6827  staggerloc=natstaggerloc, rc=rc )
6828  if (esmf_logfounderror(rc, passthru)) return
6829  wbynfield = esmf_fieldcreate( natgrid, natarrayspec2d, &
6830  staggerloc=natstaggerloc, rc=rc )
6831  if (esmf_logfounderror(rc, passthru)) return
6832  wbpnfield = esmf_fieldcreate( natgrid, natarrayspec2d, &
6833  staggerloc=natstaggerloc, rc=rc )
6834  if (esmf_logfounderror(rc, passthru)) return
6835 
6836  call fieldfill( wbxnfield, zerovalue, rc=rc )
6837  if (esmf_logfounderror(rc, passthru)) return
6838  call fieldfill( wbynfield, zerovalue, rc=rc )
6839  if (esmf_logfounderror(rc, passthru)) return
6840  call fieldfill( wbpnfield, zerovalue, rc=rc )
6841  if (esmf_logfounderror(rc, passthru)) return
6842 
6843  if ( natgridislocal ) then
6844 
6845  call esmf_fieldget( wbxnfield, farrayptr=wbxn, rc=rc )
6846  if (esmf_logfounderror(rc, passthru)) return
6847  call esmf_fieldget( wbynfield, farrayptr=wbyn, rc=rc )
6848  if (esmf_logfounderror(rc, passthru)) return
6849  call esmf_fieldget( wbpnfield, farrayptr=wbpn, rc=rc )
6850  if (esmf_logfounderror(rc, passthru)) return
6851 
6852  allocate( sig2(1:nk) )
6853  sig2(1:nk) = sig(1:nk)**2
6854 
6855  jsea_loop: do jsea = 1,nseal
6856 #ifdef W3_DIST
6857  isea = iaproc + (jsea-1)*naproc
6858 #endif
6859 #ifdef W3_SHRD
6860  isea = jsea
6861 #endif
6862  if ( dw(isea).le.zero ) cycle jsea_loop
6863  depth = max(dmin,dw(isea))
6864 #ifdef USE_W3OUTG_FOR_EXPORT
6865  if ( aba(jsea).le.zero ) cycle jsea_loop
6866  if ( uba(jsea).le.zero ) cycle jsea_loop
6867  wbxn(jsea) = uba(jsea)*cos(ubd(jsea))
6868  wbyn(jsea) = uba(jsea)*sin(ubd(jsea))
6869  wbpn(jsea) = tpi*aba(jsea)/uba(jsea)
6870 #else
6871  abr = zero
6872  ubr = zero
6873  ubx = zero
6874  uby = zero
6875  ik_loop: do ik = 1,nk
6876  aka = zero
6877  akx = zero
6878  aky = zero
6879  ith_loop: do ith = 1,nth
6880  aka = aka + a(ith,ik,jsea)
6881  akx = akx + a(ith,ik,jsea)*ecos(ith)
6882  aky = aky + a(ith,ik,jsea)*esin(ith)
6883  enddo ith_loop
6884  fack = dden(ik)/cg(ik,isea)
6885  kd = max(kdmin,min(kdmax,wn(ik,isea)*depth))
6886  fkd = fack/sinh(kd)**2
6887  abr = abr + aka*fkd
6888  ubr = ubr + aka*sig2(ik)*fkd
6889  ubx = ubx + akx*sig2(ik)*fkd
6890  uby = uby + aky*sig2(ik)*fkd
6891  enddo ik_loop
6892  if ( abr.le.zero .or. ubr.le.zero ) cycle jsea_loop
6893  abr = sqrt(two*abr)
6894  ubr = sqrt(two*ubr)
6895  dir = atan2(uby,ubx)
6896  wbxn(jsea) = ubr*cos(dir)
6897  wbyn(jsea) = ubr*sin(dir)
6898  wbpn(jsea) = tpi*abr/ubr
6899 #endif
6900  enddo jsea_loop
6901 
6902  deallocate( sig2 )
6903 
6904  endif !natGridIsLocal
6905 
6906  call esmf_fieldredist( wbxnfield, wbxfield, n2erh, rc=rc )
6907  if (esmf_logfounderror(rc, passthru)) return
6908  call esmf_fieldredist( wbynfield, wbyfield, n2erh, rc=rc )
6909  if (esmf_logfounderror(rc, passthru)) return
6910  call esmf_fieldredist( wbpnfield, wbpfield, n2erh, rc=rc )
6911  if (esmf_logfounderror(rc, passthru)) return
6912 
6913  call esmf_fielddestroy( wbxnfield, rc=rc )
6914  if (esmf_logfounderror(rc, passthru)) return
6915  call esmf_fielddestroy( wbynfield, rc=rc )
6916  if (esmf_logfounderror(rc, passthru)) return
6917  call esmf_fielddestroy( wbpnfield, rc=rc )
6918  if (esmf_logfounderror(rc, passthru)) return
6919 
6920 #ifdef TEST_WMESMFMD_BOTCUR
6921  call esmf_fieldwrite( wbxfield, "wmesmfmd_botcur_wbx.nc", &
6922  overwrite=.true., timeslice=timeslice, rc=rc )
6923  if (esmf_logfounderror(rc, passthru)) return
6924  call esmf_fieldwrite( wbyfield, "wmesmfmd_botcur_wby.nc", &
6925  overwrite=.true., timeslice=timeslice, rc=rc )
6926  if (esmf_logfounderror(rc, passthru)) return
6927  call esmf_fieldwrite( wbpfield, "wmesmfmd_botcur_wbp.nc", &
6928  overwrite=.true., timeslice=timeslice, rc=rc )
6929  if (esmf_logfounderror(rc, passthru)) return
6930  timeslice = timeslice + 1
6931 #endif
6932  !/
6933  !/ End of CalcBotcur ------------------------------------------------- /
6934  !/
6935  end subroutine calcbotcur
6936  !/ ------------------------------------------------------------------- /
6937  !/
6938 #undef METHOD
6939 #define METHOD "CalcRadstr2D"
6940 
6952  subroutine calcradstr2d ( a, sxxField, sxyField, syyField, rc )
6953  !/
6954  !/ +-----------------------------------+
6955  !/ | WAVEWATCH III NOAA/NCEP |
6956  !/ | T. J. Campbell, NRL |
6957  !/ | A. J. van der Westhuysen |
6958  !/ | FORTRAN 90 |
6959  !/ | Last update : 09-Aug-2017 |
6960  !/ +-----------------------------------+
6961  !/
6962  !/ 09-Aug-2017 : Origination. ( version 6.03 )
6963  !/ 27-Feb-2018 : Modification for use with UNGTYPE ( version 6.06 )
6964  !/
6965  ! 1. Purpose :
6966  !
6967  ! Calculate 2D radiation stresses for export
6968  !
6969  ! 2. Method :
6970  !
6971  ! Radiation stresses are defined as:
6972  !
6973  ! //
6974  ! Sxx = rho grav || (N*cos^2(theta) + N - 1/2) * sig*Ac(theta,k)/Cg dsig dtheta
6975  ! //
6976  ! //
6977  ! Sxy = rho grav || N*sin(theta)*cos(theta) * sig*Ac(theta,k)/Cg dsig dtheta
6978  ! //
6979  ! //
6980  ! Syy = rho grav || (N*sin^2(theta) + N - 1/2) * sig*Ac(theta,k)/Cg dsig dtheta
6981  ! //
6982  !
6983  ! Where:
6984  ! rho = density of sea water
6985  ! grav = acceleration due to gravity
6986  ! Ac(theta,k) = wave action density
6987  ! N = Cg/C = ratio of group velocity and phase velocity
6988  !
6989  ! 3. Parameters :
6990  !
6991  ! Parameter list
6992  ! ----------------------------------------------------------------
6993  ! a Real I Input spectra (in par list to change shape)
6994  ! sxxField Type I/O RS 2D eastward-component export field
6995  ! sxyField Type I/O RS 2D eastward-northward-component export field
6996  ! syyField Type I/O RS 2D northward-component export field
6997  ! rc Int O Return code
6998  ! ----------------------------------------------------------------
6999  !
7000  ! 4. Subroutines used :
7001  !
7002  ! Name Type Module Description
7003  ! ----------------------------------------------------------------
7004  ! NONE
7005  ! ----------------------------------------------------------------
7006  !
7007  ! 5. Called by :
7008  !
7009  ! 6. Error messages :
7010  !
7011  ! 7. Remarks :
7012  !
7013  ! 8. Structure :
7014  !
7015  ! 9. Switches :
7016  !
7017  ! 10. Source code :
7018  !
7019  !/ ------------------------------------------------------------------- /
7020  !/
7021 #ifdef W3_PDLIB
7022  use yownodepool, only: np, iplg
7023 #endif
7024  !/
7025  !/ ------------------------------------------------------------------- /
7026  !/ Parameter list
7027  !/
7028  implicit none
7029  real :: a(nth,nk,0:nseal)
7030  type(esmf_field) :: sxxfield
7031  type(esmf_field) :: sxyfield
7032  type(esmf_field) :: syyfield
7033  integer :: rc
7034  !/
7035  !/ ------------------------------------------------------------------- /
7036  !/ Local parameters
7037  !/
7038  character(ESMF_MAXSTR) :: cname
7039  character(128) :: msg
7040  real(8), parameter :: zero = 0.0
7041  real(8), parameter :: half = 0.5
7042  real(8), parameter :: one = 1.0
7043  real(8), parameter :: two = 2.0
7044  integer :: isea, jsea, ik, ith
7045  real(8) :: sxxs, sxys, syys
7046  real(8) :: akxx, akxy, akyy, cgoc, facd, fack, facs
7047  type(esmf_field) :: sxxnfield, sxynfield, syynfield
7048  real(esmf_kind_rx), pointer :: sxxn(:), sxyn(:), syyn(:)
7049  integer, save :: timeslice = 1
7050  !
7051  ! -------------------------------------------------------------------- /
7052  !
7053  rc = esmf_success
7054 
7055  ! For regular and curvilinear grids the native grid has a 2D
7056  ! layout, whereas for unstructured meshes it is a 1D array
7057  if ( (gtype.eq.rlgtype).or.(gtype.eq.clgtype) ) then
7058  sxxnfield = esmf_fieldcreate( natgrid, natarrayspec2d, &
7059  staggerloc=natstaggerloc, rc=rc )
7060  if (esmf_logfounderror(rc, passthru)) return
7061  sxynfield = esmf_fieldcreate( natgrid, natarrayspec2d, &
7062  staggerloc=natstaggerloc, rc=rc )
7063  if (esmf_logfounderror(rc, passthru)) return
7064  syynfield = esmf_fieldcreate( natgrid, natarrayspec2d, &
7065  staggerloc=natstaggerloc, rc=rc )
7066  if (esmf_logfounderror(rc, passthru)) return
7067  elseif (gtype.eq.ungtype) then
7068 #ifdef W3_PDLIB
7069  if ( lpdlib .EQV. .false. ) then
7070 #endif
7071  sxxnfield = esmf_fieldcreate( natgrid, natarrayspec1d, &
7072  staggerloc=natstaggerloc, rc=rc )
7073  if (esmf_logfounderror(rc, passthru)) return
7074  sxynfield = esmf_fieldcreate( natgrid, natarrayspec1d, &
7075  staggerloc=natstaggerloc, rc=rc )
7076  if (esmf_logfounderror(rc, passthru)) return
7077  syynfield = esmf_fieldcreate( natgrid, natarrayspec1d, &
7078  staggerloc=natstaggerloc, rc=rc )
7079  if (esmf_logfounderror(rc, passthru)) return
7080 #ifdef W3_PDLIB
7081  endif
7082 #endif
7083  endif
7084 
7085 #ifdef W3_PDLIB
7086  if ( lpdlib .EQV. .false. ) then
7087 #endif
7088  call fieldfill( sxxnfield, zerovalue, rc=rc )
7089  if (esmf_logfounderror(rc, passthru)) return
7090  call fieldfill( sxynfield, zerovalue, rc=rc )
7091  if (esmf_logfounderror(rc, passthru)) return
7092  call fieldfill( syynfield, zerovalue, rc=rc )
7093  if (esmf_logfounderror(rc, passthru)) return
7094 #ifdef W3_PDLIB
7095  endif
7096 #endif
7097 
7098  if ( natgridislocal ) then
7099 
7100 #ifdef W3_PDLIB
7101  if ( lpdlib .EQV. .false. ) then
7102  ! Use auxiliary native grid/mesh to populate and redistribute data
7103 #endif
7104  call esmf_fieldget( sxxnfield, farrayptr=sxxn, rc=rc )
7105  if (esmf_logfounderror(rc, passthru)) return
7106  call esmf_fieldget( sxynfield, farrayptr=sxyn, rc=rc )
7107  if (esmf_logfounderror(rc, passthru)) return
7108  call esmf_fieldget( syynfield, farrayptr=syyn, rc=rc )
7109  if (esmf_logfounderror(rc, passthru)) return
7110 #ifdef W3_PDLIB
7111  else
7112  ! Use single domain-decomposed native mesh to populate and communicate data
7113  call esmf_fieldget( sxxfield, farrayptr=sxxn, rc=rc )
7114  if (esmf_logfounderror(rc, passthru)) return
7115  call esmf_fieldget( sxyfield, farrayptr=sxyn, rc=rc )
7116  if (esmf_logfounderror(rc, passthru)) return
7117  call esmf_fieldget( syyfield, farrayptr=syyn, rc=rc )
7118  if (esmf_logfounderror(rc, passthru)) return
7119  endif
7120 #endif
7121 
7122  facd = dwat*grav
7123 #ifdef W3_PDLIB
7124  if ( lpdlib .EQV. .false. ) then
7125 #endif
7126  jsea_loop: do jsea = 1,nseal
7127 #ifdef W3_DIST
7128  isea = iaproc + (jsea-1)*naproc
7129 #endif
7130 #ifdef W3_SHRD
7131  isea = jsea
7132 #endif
7133  if ( dw(isea).le.zero ) cycle jsea_loop
7134 #ifdef USE_W3OUTG_FOR_EXPORT
7135  sxxn(jsea) = sxx(jsea)
7136  sxyn(jsea) = sxy(jsea)
7137  syyn(jsea) = syy(jsea)
7138 #else
7139  sxxs = zero
7140  sxys = zero
7141  syys = zero
7142  ik_loop: do ik = 1,nk
7143  akxx = zero
7144  akxy = zero
7145  akyy = zero
7146  cgoc = cg(ik,isea)*wn(ik,isea)/sig(ik)
7147  cgoc = min(one,max(half,cgoc))
7148  ith_loop: do ith = 1,nth
7149  akxx = akxx + (cgoc*(ec2(ith)+one)-half)*a(ith,ik,jsea)
7150  akxy = akxy + cgoc*esc(ith)*a(ith,ik,jsea)
7151  akyy = akyy + (cgoc*(es2(ith)+one)-half)*a(ith,ik,jsea)
7152  enddo ith_loop
7153  fack = dden(ik)/cg(ik,isea)
7154  sxxs = sxxs + akxx*fack
7155  sxys = sxys + akxy*fack
7156  syys = syys + akyy*fack
7157  enddo ik_loop
7158  facs = (one+fte/cg(nk,isea))*facd
7159  sxxn(jsea) = sxxs*facs
7160  sxyn(jsea) = sxys*facs
7161  syyn(jsea) = syys*facs
7162 #endif
7163  enddo jsea_loop
7164 #ifdef W3_PDLIB
7165  else
7166  jsea_loop2: do jsea = 1,np
7167  isea = iplg(jsea)
7168  ! if ( dw(isea).le.zero ) cycle jsea_loop
7169  sxxn(jsea) = sxx(jsea)
7170  sxyn(jsea) = sxy(jsea)
7171  syyn(jsea) = syy(jsea)
7172  ! write(msg,*) trim(cname)//' sxxn', sxxn(jsea)
7173  ! call ESMF_LogWrite(trim(msg), ESMF_LOGMSG_INFO)
7174  enddo jsea_loop2
7175  endif
7176 #endif
7177 
7178  endif !natGridIsLocal
7179 
7180 #ifdef W3_PDLIB
7181  if ( lpdlib .EQV. .false. ) then
7182 #endif
7183  call esmf_fieldredist( sxxnfield, sxxfield, n2erh, rc=rc )
7184  if (esmf_logfounderror(rc, passthru)) return
7185  call esmf_fieldredist( sxynfield, sxyfield, n2erh, rc=rc )
7186  if (esmf_logfounderror(rc, passthru)) return
7187  call esmf_fieldredist( syynfield, syyfield, n2erh, rc=rc )
7188  if (esmf_logfounderror(rc, passthru)) return
7189 
7190  call esmf_fielddestroy( sxxnfield, rc=rc )
7191  if (esmf_logfounderror(rc, passthru)) return
7192  call esmf_fielddestroy( sxynfield, rc=rc )
7193  if (esmf_logfounderror(rc, passthru)) return
7194  call esmf_fielddestroy( syynfield, rc=rc )
7195  if (esmf_logfounderror(rc, passthru)) return
7196 #ifdef W3_PDLIB
7197  endif
7198 #endif
7199 
7200 #ifdef TEST_WMESMFMD_RADSTR2D
7201  call esmf_fieldwrite( sxxfield, "wmesmfmd_radstr2d_sxx.nc", &
7202  overwrite=.true., timeslice=timeslice, rc=rc )
7203  if (esmf_logfounderror(rc, passthru)) return
7204  call esmf_fieldwrite( sxyfield, "wmesmfmd_radstr2d_sxy.nc", &
7205  overwrite=.true., timeslice=timeslice, rc=rc )
7206  if (esmf_logfounderror(rc, passthru)) return
7207  call esmf_fieldwrite( syyfield, "wmesmfmd_radstr2d_syy.nc", &
7208  overwrite=.true., timeslice=timeslice, rc=rc )
7209  if (esmf_logfounderror(rc, passthru)) return
7210  timeslice = timeslice + 1
7211 #endif
7212  !/
7213  !/ End of CalcRadstr2D ----------------------------------------------- /
7214  !/
7215  end subroutine calcradstr2d
7216  !/ ------------------------------------------------------------------- /
7217  !/
7218 #undef METHOD
7219 #define METHOD "CalcStokes3D"
7220 
7231  subroutine calcstokes3d ( a, usxField, usyField, rc )
7232  !/
7233  !/ +-----------------------------------+
7234  !/ | WAVEWATCH III NOAA/NCEP |
7235  !/ | T. J. Campbell, NRL |
7236  !/ | FORTRAN 90 |
7237  !/ | Last update : 09-Aug-2017 |
7238  !/ +-----------------------------------+
7239  !/
7240  !/ 09-Aug-2017 : Origination. ( version 6.03 )
7241  !/
7242  ! 1. Purpose :
7243  !
7244  ! Calculate 3D Stokes drift current for export
7245  !
7246  ! 2. Method :
7247  !
7248  ! Kenyon, K. E. (1969), J. Geophys. R., Vol 74, No 28, p 6991
7249  !
7250  ! U_vec(z)
7251  ! //
7252  ! = 2 g || ( F(f,theta) k_vec/C cosh(2k(D+z))/sinh(2kD) ) dsig dtheta
7253  ! //
7254  !
7255  ! //
7256  ! = || (Ac(k,theta) sig^2 k_vec/Cg cosh(2k(D+z))/sinh^2(kD) ) dsig dtheta
7257  ! //
7258  !
7259  ! Where:
7260  ! Ac(k,theta) = wave action density
7261  ! k_vec = k*[cos(theta),sin(theta)]
7262  ! D = depth
7263  ! z = height (0 = mean sea level)
7264  !
7265  ! In deep water (kD large): cosh(2k(D+z))/sinh^2(kD) --> 2*exp(2kz)
7266  !
7267  ! 3. Parameters :
7268  !
7269  ! Parameter list
7270  ! ----------------------------------------------------------------
7271  ! a Real I Input spectra (in par list to change shape)
7272  ! usxField Type I/O 3D SDC eastward-component export field
7273  ! usyField Type I/O 3D SDC northward-component export field
7274  ! rc Int O Return code
7275  ! ----------------------------------------------------------------
7276  !
7277  ! 4. Subroutines used :
7278  !
7279  ! Name Type Module Description
7280  ! ----------------------------------------------------------------
7281  ! NONE
7282  ! ----------------------------------------------------------------
7283  !
7284  ! 5. Called by :
7285  !
7286  ! 6. Error messages :
7287  !
7288  ! 7. Remarks :
7289  !
7290  ! 8. Structure :
7291  !
7292  ! 9. Switches :
7293  !
7294  ! 10. Source code :
7295  !
7296  !/ ------------------------------------------------------------------- /
7297  !/
7298  !/ ------------------------------------------------------------------- /
7299  !/ Parameter list
7300  !/
7301  implicit none
7302  real :: a(nth,nk,0:nseal)
7303  type(esmf_field) :: usxField
7304  type(esmf_field) :: usyField
7305  integer :: rc
7306  !/
7307  !/ ------------------------------------------------------------------- /
7308  !/ Local parameters
7309  !/
7310  real(8), parameter :: zero = 0.0
7311  real(8), parameter :: half = 0.5
7312  real(8), parameter :: one = 1.0
7313  real(8), parameter :: two = 2.0
7314  ! kdmin = 1e-7: sinh(kdmin)**2 ~ 1e-14
7315  real(8), parameter :: kdmin = 1e-7
7316  ! kdmax = 18.0: cosh(2*(kdmax+kz))/sinh(kdmax)**2 - 2*exp(2*kz) < 1e-14
7317  real(8), parameter :: kdmax = 18.0
7318  ! kdmin & kdmax settings used in w3iogomd
7319  real(8), parameter :: kdmin_us3d = 1e-3
7320  real(8), parameter :: kdmax_us3d = 6.0
7321  integer :: isea, jsea, ik, ith, iz
7322  real(8) :: depth
7323  real(8) :: akx, aky, kd, kz, fac1, fac2, fac3
7324  real(8) :: uzx(nz), uzy(nz)
7325  real(8), allocatable :: fack(:)
7326  type(esmf_field) :: usxnField, usynField
7327  real(ESMF_KIND_RX), pointer :: usxn(:,:), usyn(:,:)
7328  integer, save :: timeSlice = 1
7329  ! Need this workaround to deal with ESMF_FieldCreate not setting up the
7330  ! Fortran arrays with the ungridded dimension as the first array dimension
7331 #define ESMF_ARBSEQ_WORKAROUND
7332 #ifdef ESMF_ARBSEQ_WORKAROUND
7333  type(esmf_distgrid) :: natDistGrid
7334  type(esmf_array) :: usxnArray, usynArray
7335 #endif
7336  !
7337  ! -------------------------------------------------------------------- /
7338  !
7339  rc = esmf_success
7340 
7341 #ifdef ESMF_ARBSEQ_WORKAROUND
7342  call esmf_gridget( natgrid, distgrid=natdistgrid, rc=rc )
7343  if (esmf_logfounderror(rc, passthru)) return
7344  usxnarray = esmf_arraycreate( natdistgrid, esmf_typekind_rx, &
7345  distgridtoarraymap=(/2/), undistlbound=(/1/), undistubound=(/nz/), rc=rc )
7346  if (esmf_logfounderror(rc, passthru)) return
7347  usxnfield = esmf_fieldcreate( natgrid, usxnarray, &
7348  gridtofieldmap=(/2,3/), ungriddedlbound=(/1/), ungriddedubound=(/nz/), &
7349  staggerloc=natstaggerloc, rc=rc )
7350  if (esmf_logfounderror(rc, passthru)) return
7351  usynarray = esmf_arraycreate( natdistgrid, esmf_typekind_rx, &
7352  distgridtoarraymap=(/2/), undistlbound=(/1/), undistubound=(/nz/), rc=rc )
7353  if (esmf_logfounderror(rc, passthru)) return
7354  usynfield = esmf_fieldcreate( natgrid, usynarray, &
7355  gridtofieldmap=(/2,3/), ungriddedlbound=(/1/), ungriddedubound=(/nz/), &
7356  staggerloc=natstaggerloc, rc=rc )
7357  if (esmf_logfounderror(rc, passthru)) return
7358 #else
7359  usxnfield = esmf_fieldcreate( natgrid, natarrayspec3d, &
7360  gridtofieldmap=(/2,3/), ungriddedlbound=(/1/), ungriddedubound=(/nz/), &
7361  staggerloc=natstaggerloc, rc=rc )
7362  if (esmf_logfounderror(rc, passthru)) return
7363  usynfield = esmf_fieldcreate( natgrid, natarrayspec3d, &
7364  gridtofieldmap=(/2,3/), ungriddedlbound=(/1/), ungriddedubound=(/nz/), &
7365  staggerloc=natstaggerloc, rc=rc )
7366  if (esmf_logfounderror(rc, passthru)) return
7367 #endif
7368 
7369  call fieldfill( usxnfield, zerovalue, rc=rc )
7370  if (esmf_logfounderror(rc, passthru)) return
7371  call fieldfill( usynfield, zerovalue, rc=rc )
7372  if (esmf_logfounderror(rc, passthru)) return
7373 
7374  if ( natgridislocal ) then
7375 
7376  call esmf_fieldget( usxnfield, farrayptr=usxn, rc=rc )
7377  if (esmf_logfounderror(rc, passthru)) return
7378  call esmf_fieldget( usynfield, farrayptr=usyn, rc=rc )
7379  if (esmf_logfounderror(rc, passthru)) return
7380 
7381  allocate( fack(1:nk) )
7382  fack(1:nk) = dden(1:nk) * sig(1:nk)
7383 
7384  jsea_loop: do jsea = 1,nseal
7385 #ifdef W3_DIST
7386  isea = iaproc + (jsea-1)*naproc
7387 #endif
7388 #ifdef W3_SHRD
7389  isea = jsea
7390 #endif
7391  if ( dw(isea).le.zero ) cycle jsea_loop
7392  depth = max(dmin,dw(isea))
7393  uzx(:) = zero
7394  uzy(:) = zero
7395 #ifdef USE_W3OUTG_FOR_EXPORT
7396  ik_loop: do ik = us3df(2),us3df(3)
7397  fac1 = tpiinv*dsii(ik)
7398  kd = max(kdmin_us3d,wn(ik,isea)*dw(isea))
7399  iz_loop: do iz = 1,nz
7400  if ( dw(isea)+zl(iz).le.zero ) cycle iz_loop
7401  kz = wn(ik,isea)*zl(iz)
7402  if ( kd .lt. kdmax_us3d ) then
7403  fac2 = fac1*cosh(two*max(zero,kd+kz))/cosh(two*kd)
7404  else
7405  fac2 = fac1*exp(two*kz)
7406  endif
7407  uzx(iz) = uzx(iz) + us3d(jsea,ik )*fac2
7408  uzy(iz) = uzy(iz) + us3d(jsea,nk+ik)*fac2
7409  enddo iz_loop
7410  enddo ik_loop
7411 #else
7412  ik_loop: do ik = 1,nk
7413  akx = zero
7414  aky = zero
7415  ith_loop: do ith = 1,nth
7416  akx = akx + a(ith,ik,jsea)*ecos(ith)
7417  aky = aky + a(ith,ik,jsea)*esin(ith)
7418  enddo ith_loop
7419  fac1 = fack(ik)*wn(ik,isea)/cg(ik,isea)
7420  kd = max(kdmin,wn(ik,isea)*depth)
7421  if ( kd .lt. kdmax ) then
7422  fac2 = fac1/sinh(kd)**2
7423  else
7424  fac2 = fac1*two
7425  endif
7426  akx = akx*fac2
7427  aky = aky*fac2
7428  iz_loop: do iz = 1,nz
7429  if ( depth+zl(iz).le.zero ) cycle iz_loop
7430  kz = wn(ik,isea)*zl(iz)
7431  if ( kd .lt. kdmax ) then
7432  fac3 = cosh(two*max(zero,kd+kz))
7433  else
7434  fac3 = exp(two*kz)
7435  endif
7436  uzx(iz) = uzx(iz) + akx*fac3
7437  uzy(iz) = uzy(iz) + aky*fac3
7438  enddo iz_loop
7439  enddo ik_loop
7440 #endif
7441  usxn(:,jsea) = uzx(:)
7442  usyn(:,jsea) = uzy(:)
7443  enddo jsea_loop
7444 
7445  deallocate( fack )
7446 
7447  endif !natGridIsLocal
7448 
7449  call esmf_fieldredist( usxnfield, usxfield, n2erh, rc=rc )
7450  if (esmf_logfounderror(rc, passthru)) return
7451  call esmf_fieldredist( usynfield, usyfield, n2erh, rc=rc )
7452  if (esmf_logfounderror(rc, passthru)) return
7453 
7454 #ifdef ESMF_ARBSEQ_WORKAROUND
7455  call esmf_arraydestroy( usxnarray, rc=rc )
7456  if (esmf_logfounderror(rc, passthru)) return
7457  call esmf_arraydestroy( usynarray, rc=rc )
7458  if (esmf_logfounderror(rc, passthru)) return
7459 #endif
7460  call esmf_fielddestroy( usxnfield, rc=rc )
7461  if (esmf_logfounderror(rc, passthru)) return
7462  call esmf_fielddestroy( usynfield, rc=rc )
7463  if (esmf_logfounderror(rc, passthru)) return
7464 
7465 #ifdef TEST_WMESMFMD_STOKES3D
7466  call esmf_fieldwrite( usxfield, "wmesmfmd_stokes3d_usx.nc", &
7467  overwrite=.true., timeslice=timeslice, rc=rc )
7468  if (esmf_logfounderror(rc, passthru)) return
7469  call esmf_fieldwrite( usyfield, "wmesmfmd_stokes3d_usy.nc", &
7470  overwrite=.true., timeslice=timeslice, rc=rc )
7471  if (esmf_logfounderror(rc, passthru)) return
7472  timeslice = timeslice + 1
7473 #endif
7474  !/
7475  !/ End of CalcStokes3D ----------------------------------------------- /
7476  !/
7477  end subroutine calcstokes3d
7478  !/ ------------------------------------------------------------------- /
7479  !/
7480 #undef METHOD
7481 #define METHOD "CalcPStokes"
7482 
7496  subroutine calcpstokes ( a, p1xField, p1yField, p2xField, &
7497  p2yField, p3xField, p3yField, rc )
7498  !/
7499  !/ +-----------------------------------+
7500  !/ | WAVEWATCH III NOAA/NCEP |
7501  !/ | J. Meixner |
7502  !/ | FORTRAN 90 |
7503  !/ | Last update : 29-Oct-2019 |
7504  !/ +-----------------------------------+
7505  !/
7506  !/ DD-MMM-YYYY : Origination. ( version 7.13 )
7507  !/
7508  ! 1. Purpose :
7509  !
7510  ! Calculate partitioned Stokes drift for export
7511  !
7512  ! 2. Method :
7513  !
7514  ! 3. Parameters :
7515  !
7516  ! Parameter list
7517  ! ----------------------------------------------------------------
7518  ! a Real I Input spectra (in par list to change shape)
7519  ! p1Field Type I/O
7520  ! p2Field Type I/O
7521  ! p3Field Type I/O
7522  ! rc Int O Return code
7523  ! ----------------------------------------------------------------
7524  !
7525  ! 4. Subroutines used :
7526  !
7527  ! Name Type Module Description
7528  ! ----------------------------------------------------------------
7529  ! NONE
7530  ! ----------------------------------------------------------------
7531  !
7532  ! 5. Called by :
7533  !
7534  ! 6. Error messages :
7535  !
7536  ! 7. Remarks :
7537  !
7538  ! 8. Structure :
7539  !
7540  ! 9. Switches :
7541  !
7542  ! 10. Source code :
7543  !
7544  !/ ------------------------------------------------------------------- /
7545  !/
7546  USE w3adatmd, ONLY: ussp
7547  USE w3iogomd, ONLY: calc_u3stokes
7548  IMPLICIT NONE
7549  !/ ------------------------------------------------------------------- /
7550  !/ Parameter list
7551  !/
7552  real :: a(nth,nk,0:nseal)
7553  type(esmf_field) :: p1xField,p2xField,p3xField
7554  type(esmf_field) :: p1yField,p2yField,p3yField
7555  integer :: rc
7556  !/
7557  !/ ------------------------------------------------------------------- /
7558  !/ Local parameters
7559  !/
7560  !real(8) :: sxxs, sxys, syys
7561  type(esmf_field) :: p1xnField, p2xnField, p3xnField
7562  type(esmf_field) :: p1ynField, p2ynField, p3ynField
7563  real(ESMF_KIND_RX), pointer :: p1xn(:), p2xn(:), p3xn(:)
7564  real(ESMF_KIND_RX), pointer :: p1yn(:), p2yn(:), p3yn(:)
7565  integer, save :: timeSlice = 1
7566  integer :: isea,jsea
7567  !
7568  ! -------------------------------------------------------------------- /
7569  !
7570  rc = esmf_success
7571 
7572 
7573  p1xnfield = esmf_fieldcreate( natgrid, natarrayspec2d, &
7574  staggerloc=natstaggerloc, rc=rc )
7575  if (esmf_logfounderror(rc, passthru)) return
7576  p1ynfield = esmf_fieldcreate( natgrid, natarrayspec2d, &
7577  staggerloc=natstaggerloc, rc=rc )
7578  if (esmf_logfounderror(rc, passthru)) return
7579  p2xnfield = esmf_fieldcreate( natgrid, natarrayspec2d, &
7580  staggerloc=natstaggerloc, rc=rc )
7581  if (esmf_logfounderror(rc, passthru)) return
7582  p2ynfield = esmf_fieldcreate( natgrid, natarrayspec2d, &
7583  staggerloc=natstaggerloc, rc=rc )
7584  if (esmf_logfounderror(rc, passthru)) return
7585  p3xnfield = esmf_fieldcreate( natgrid, natarrayspec2d, &
7586  staggerloc=natstaggerloc, rc=rc )
7587  if (esmf_logfounderror(rc, passthru)) return
7588  p3ynfield = esmf_fieldcreate( natgrid, natarrayspec2d, &
7589  staggerloc=natstaggerloc, rc=rc )
7590  if (esmf_logfounderror(rc, passthru)) return
7591 
7592  call fieldfill( p1xnfield, zerovalue, rc=rc )
7593  if (esmf_logfounderror(rc, passthru)) return
7594  call fieldfill( p1ynfield, zerovalue, rc=rc )
7595  if (esmf_logfounderror(rc, passthru)) return
7596  call fieldfill( p2xnfield, zerovalue, rc=rc )
7597  if (esmf_logfounderror(rc, passthru)) return
7598  call fieldfill( p2ynfield, zerovalue, rc=rc )
7599  if (esmf_logfounderror(rc, passthru)) return
7600  call fieldfill( p3xnfield, zerovalue, rc=rc )
7601  if (esmf_logfounderror(rc, passthru)) return
7602  call fieldfill( p3ynfield, zerovalue, rc=rc )
7603  if (esmf_logfounderror(rc, passthru)) return
7604 
7605  if ( natgridislocal ) then
7606 
7607  call esmf_fieldget( p1xnfield, farrayptr=p1xn, rc=rc )
7608  if (esmf_logfounderror(rc, passthru)) return
7609  call esmf_fieldget( p1ynfield, farrayptr=p1yn, rc=rc )
7610  if (esmf_logfounderror(rc, passthru)) return
7611  call esmf_fieldget( p2xnfield, farrayptr=p2xn, rc=rc )
7612  if (esmf_logfounderror(rc, passthru)) return
7613  call esmf_fieldget( p2ynfield, farrayptr=p2yn, rc=rc )
7614  if (esmf_logfounderror(rc, passthru)) return
7615  call esmf_fieldget( p3xnfield, farrayptr=p3xn, rc=rc )
7616  if (esmf_logfounderror(rc, passthru)) return
7617  call esmf_fieldget( p3ynfield, farrayptr=p3yn, rc=rc )
7618  if (esmf_logfounderror(rc, passthru)) return
7619 
7620  call calc_u3stokes ( a , 2 )
7621 
7622  jsea_loop: do jsea = 1,nseal
7623 #ifdef W3_DIST
7624  isea = iaproc + (jsea-1)*naproc
7625 #endif
7626 #ifdef W3_SHRD
7627  isea = jsea
7628 #endif
7629 
7630  p1xn(jsea)=ussp(jsea,1)
7631  p1yn(jsea)=ussp(jsea,nk+1)
7632  p2xn(jsea)=ussp(jsea,2)
7633  p2yn(jsea)=ussp(jsea,nk+2)
7634  p3xn(jsea)=ussp(jsea,3)
7635  p3yn(jsea)=ussp(jsea,nk+3)
7636  enddo jsea_loop
7637 
7638  endif !natGridIsLocal
7639 
7640  call esmf_fieldredist( p1xnfield, p1xfield, n2erh, rc=rc )
7641  if (esmf_logfounderror(rc, passthru)) return
7642  call esmf_fieldredist( p1ynfield, p1yfield, n2erh, rc=rc )
7643  if (esmf_logfounderror(rc, passthru)) return
7644  call esmf_fieldredist( p2xnfield, p2xfield, n2erh, rc=rc )
7645  if (esmf_logfounderror(rc, passthru)) return
7646  call esmf_fieldredist( p2ynfield, p2yfield, n2erh, rc=rc )
7647  if (esmf_logfounderror(rc, passthru)) return
7648  call esmf_fieldredist( p3xnfield, p3xfield, n2erh, rc=rc )
7649  if (esmf_logfounderror(rc, passthru)) return
7650  call esmf_fieldredist( p3ynfield, p3yfield, n2erh, rc=rc )
7651  if (esmf_logfounderror(rc, passthru)) return
7652 
7653  call esmf_fielddestroy( p1xnfield, rc=rc )
7654  if (esmf_logfounderror(rc, passthru)) return
7655  call esmf_fielddestroy( p2xnfield, rc=rc )
7656  if (esmf_logfounderror(rc, passthru)) return
7657  call esmf_fielddestroy( p3xnfield, rc=rc )
7658  if (esmf_logfounderror(rc, passthru)) return
7659  call esmf_fielddestroy( p1ynfield, rc=rc )
7660  if (esmf_logfounderror(rc, passthru)) return
7661  call esmf_fielddestroy( p2ynfield, rc=rc )
7662  if (esmf_logfounderror(rc, passthru)) return
7663  call esmf_fielddestroy( p3ynfield, rc=rc )
7664  if (esmf_logfounderror(rc, passthru)) return
7665 
7666 #ifdef TEST_WMESMFMD_PSTOKES
7667  call esmf_fieldwrite( p1xfield, "wmesmfmd_pstokes_1x.nc", &
7668  overwrite=.true., timeslice=timeslice, rc=rc )
7669  if (esmf_logfounderror(rc, passthru)) return
7670  call esmf_fieldwrite( p1yfield, "wmesmfmd_pstokes_1y.nc", &
7671  overwrite=.true., timeslice=timeslice, rc=rc )
7672  if (esmf_logfounderror(rc, passthru)) return
7673  call esmf_fieldwrite( p2xfield, "wmesmfmd_pstokes_2x.nc", &
7674  overwrite=.true., timeslice=timeslice, rc=rc )
7675  if (esmf_logfounderror(rc, passthru)) return
7676  call esmf_fieldwrite( p2yfield, "wmesmfmd_pstokes_2y.nc", &
7677  overwrite=.true., timeslice=timeslice, rc=rc )
7678  if (esmf_logfounderror(rc, passthru)) return
7679  call esmf_fieldwrite( p3xfield, "wmesmfmd_pstokes_3x.nc", &
7680  overwrite=.true., timeslice=timeslice, rc=rc )
7681  if (esmf_logfounderror(rc, passthru)) return
7682  call esmf_fieldwrite( p3yfield, "wmesmfmd_pstokes_3y.nc", &
7683  overwrite=.true., timeslice=timeslice, rc=rc )
7684  if (esmf_logfounderror(rc, passthru)) return
7685  timeslice = timeslice + 1
7686 #endif
7687  !/
7688  !/ End of CalcPStokes ----------------------------------------------- /
7689  !/
7690  end subroutine calcpstokes
7691  !/ ------------------------------------------------------------------- /
7692  !/
7693 #undef METHOD
7694 #define METHOD "ReadFromFile"
7695 
7708  subroutine readfromfile (idfld, fldwx, fldwy, time0, timen, rc)
7709  !/
7710  !/ +-----------------------------------+
7711  !/ | WAVEWATCH III NOAA/NCEP |
7712  !/ | U. Turuncoglu |
7713  !/ | FORTRAN 90 |
7714  !/ | Last update : 18-May-2021 |
7715  !/ +-----------------------------------+
7716  !/
7717  !/ 18-May-2021 : Origination. ( version 7.13 )
7718  !/
7719  ! 1. Purpose :
7720  !
7721  ! Read input file to fill unmapped point for regional applications
7722  !
7723  ! 2. Method :
7724  !
7725  ! 3. Parameters :
7726  !
7727  ! Parameter list
7728  ! ----------------------------------------------------------------
7729  ! idfld Str I/O Field name
7730  ! fldwx Type I/O 2D eastward-component of field
7731  ! fldwy Type I/O 2D northward-component of field
7732  ! time0 Int I Time stamp for current time
7733  ! timen Int I Time stamp for end time
7734  ! rc Int I/O Return code
7735  ! ----------------------------------------------------------------
7736  !
7737  ! 4. Subroutines used :
7738  !
7739  ! Name Type Module Description
7740  ! ----------------------------------------------------------------
7741  ! NONE
7742  ! ----------------------------------------------------------------
7743  !
7744  ! 5. Called by :
7745  !
7746  ! 6. Error messages :
7747  !
7748  ! 7. Remarks :
7749  !
7750  ! 8. Structure :
7751  !
7752  ! 9. Switches :
7753  !
7754  ! 10. Source code :
7755  !
7756  !/ ------------------------------------------------------------------- /
7757  !/
7758  USE w3fldsmd, ONLY: w3fldo, w3fldg
7759  USE wmunitmd, ONLY: wmuget, wmuset
7760  IMPLICIT NONE
7761  !/ ------------------------------------------------------------------- /
7762  !/ Parameter list
7763  !/
7764  character(len=3), intent(inout) :: idfld
7765  type(esmf_field), intent(inout) :: fldwx
7766  type(esmf_field), intent(inout) :: fldwy
7767  integer, intent(in) :: time0(2)
7768  integer, intent(in) :: timen(2)
7769  integer, intent(inout), optional :: rc
7770  !/
7771  !/ ------------------------------------------------------------------- /
7772  !/ Local parameters
7773  !/
7774  integer :: ierr, tw0l(2), twnl(2), lb(2), ub(2)
7775  real :: wx0l(nx,ny), wy0l(nx,ny)
7776  real :: wxnl(nx,ny), wynl(nx,ny)
7777  real :: dt0l(nx,ny), dtnl(nx,ny)
7778  real(ESMF_KIND_RX), pointer :: dptr(:,:)
7779  integer :: mdse = 6
7780  integer :: mdst = 10
7781  integer, save :: mdsf
7782  character(256) :: logmsg
7783  logical :: flagsc = .false.
7784  integer, parameter :: lde = 0
7785  logical, save :: firstCall = .true.
7786  character(len=13) :: tsstr
7787  character(len=3) :: tsfld
7788  integer :: nxt, nyt, gtypet, filler(3), tideflag
7789 #if defined(TEST_WMESMFMD) || defined(TEST_WMESMFMD_READFROMFILE)
7790  integer, save :: timeSlice = 1
7791 #endif
7792  !
7793  ! -------------------------------------------------------------------- /
7794  !
7795  rc = esmf_success
7796 
7797  if (firstcall) then
7798  ! assign unit number for input file
7799  call wmuget(mdse, mdst, mdsf, 'INP')
7800  call wmuset(mdse, mdst, mdsf, .true., desc='Input data file')
7801 
7802  ! open file
7803  call w3fldo('READ', idfld, mdsf, mdst, mdse, nx, ny, gtype, ierr)
7804  if (ierr.ne.0) then
7805  write(logmsg,*) "Error in opening "//idfld//", iostat = ", ierr
7806  call esmf_logwrite(trim(logmsg), esmf_logmsg_error)
7807  rc = esmf_failure
7808  return
7809  endif
7810 
7811  firstcall = .false.
7812  end if
7813 
7814  ! init variables
7815  wx0l = 0.0
7816  wy0l = 0.0
7817  dt0l = 0.0
7818  wxnl = 0.0
7819  wynl = 0.0
7820  dtnl = 0.0
7821 
7822  ! need to rewind to the begining of the file to access
7823  ! data of requested date correctly
7824  rewind(mdsf)
7825 
7826  ! read header information
7827  ! this was inside of w3fldo call but since we are opening file
7828  ! once and rewinding, the header need to be read
7829  read(mdsf, iostat=ierr) tsstr, tsfld, nxt, nyt, &
7830  gtypet, filler(1:2), tideflag
7831 
7832  ! read input
7833  call w3fldg('READ', idfld, mdsf, mdst, mdse, nx, ny, &
7834  nx, ny, time0, timen, tw0l, wx0l, wy0l, dt0l, twnl, &
7835  wxnl, wynl, dtnl, ierr, flagsc)
7836 
7837  ! fill fields with data belong to current time
7838  if ( impgridislocal ) then
7839  call esmf_fieldget(fldwx, localde=lde, farrayptr=dptr, &
7840  exclusivelbound=lb, exclusiveubound=ub, rc=rc)
7841  if (esmf_logfounderror(rc, passthru)) return
7842  dptr(lb(1):ub(1),lb(2):ub(2)) = wx0l(lb(1):ub(1),lb(2):ub(2))
7843  if (associated(dptr)) nullify(dptr)
7844  call esmf_fieldget(fldwy, localde=lde, farrayptr=dptr, &
7845  exclusivelbound=lb, exclusiveubound=ub, rc=rc)
7846  if (esmf_logfounderror(rc, passthru)) return
7847  dptr(lb(1):ub(1),lb(2):ub(2)) = wy0l(lb(1):ub(1),lb(2):ub(2))
7848  if (associated(dptr)) nullify(dptr)
7849  end if
7850 
7851 #if defined(TEST_WMESMFMD) || defined(TEST_WMESMFMD_READFROMFILE)
7852  write(logmsg,*) 'time0 = ', time0(1), time0(2)
7853  call esmf_logwrite(trim(logmsg), esmf_logmsg_info, rc=rc)
7854  if (esmf_logfounderror(rc, passthru)) return
7855  write(logmsg,*) 'timen = ', timen(1), timen(2)
7856  call esmf_logwrite(trim(logmsg), esmf_logmsg_info, rc=rc)
7857  if (esmf_logfounderror(rc, passthru)) return
7858  write(logmsg,*) 'tw0 = ', tw0l(1), tw0l(2)
7859  call esmf_logwrite(trim(logmsg), esmf_logmsg_info, rc=rc)
7860  if (esmf_logfounderror(rc, passthru)) return
7861  write(logmsg,*) 'twn = ', twnl(1), twnl(2)
7862  call esmf_logwrite(trim(logmsg), esmf_logmsg_info, rc=rc)
7863  if (esmf_logfounderror(rc, passthru)) return
7864  write(logmsg,*) 'wx0 min, max = ', minval(wx0l), maxval(wx0l)
7865  call esmf_logwrite(trim(logmsg), esmf_logmsg_info, rc=rc)
7866  if (esmf_logfounderror(rc, passthru)) return
7867  write(logmsg,*) 'wy0 min, max = ', minval(wy0l), maxval(wy0l)
7868  call esmf_logwrite(trim(logmsg), esmf_logmsg_info, rc=rc)
7869  if (esmf_logfounderror(rc, passthru)) return
7870  write(logmsg,*) 'wxn min, max = ', minval(wxnl), maxval(wxnl)
7871  call esmf_logwrite(trim(logmsg), esmf_logmsg_info, rc=rc)
7872  if (esmf_logfounderror(rc, passthru)) return
7873  write(logmsg,*) 'wyn min, max = ', minval(wynl), maxval(wynl)
7874  call esmf_logwrite(trim(logmsg), esmf_logmsg_info, rc=rc)
7875  if (esmf_logfounderror(rc, passthru)) return
7876  call esmf_fieldwrite( fldwx, &
7877  "wmesmfmd_read_wx0.nc", &
7878  overwrite=.true., timeslice=timeslice, rc=rc )
7879  if (esmf_logfounderror(rc, passthru)) return
7880  call esmf_fieldwrite( fldwy, &
7881  "wmesmfmd_read_wy0.nc", &
7882  overwrite=.true., timeslice=timeslice, rc=rc )
7883  if (esmf_logfounderror(rc, passthru)) return
7884  timeslice = timeslice + 1
7885 #endif
7886  !/
7887  !/ End of ReadFromFile ------------------------------------------- /
7888  !/
7889  end subroutine readfromfile
7890  !/ ------------------------------------------------------------------- /
7891  !/
7892  !/ End of module WMESMFMD -------------------------------------------- /
7893  !/
7894 end module wmesmfmd
w3gdatmd::nk
integer, pointer nk
Definition: w3gdatmd.F90:1230
w3gdatmd::esc
real, dimension(:), pointer esc
Definition: w3gdatmd.F90:1234
w3gdatmd::trigp
integer, dimension(:,:), pointer trigp
Definition: w3gdatmd.F90:1111
w3gdatmd::nseal
integer, pointer nseal
Definition: w3gdatmd.F90:1097
include
cmake src_list cmake include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/check_switches.cmake) check_switches("$
Definition: CMakeLists.txt:15
wmmdatmd::mdse
integer mdse
MDSE.
Definition: wmmdatmd.F90:316
yowelementpool::ielg
integer, dimension(:), allocatable, target, public ielg
global element array.
Definition: yowelementpool.F90:65
wmfinlmd
Finalization of the multi-grid wave model.
Definition: wmfinlmd.F90:14
w3idatmd::input
Definition: w3idatmd.F90:171
wminitmd
Initialization of the multi-grid wave model.
Definition: wminitmd.F90:18
w3adatmd::charn
real, dimension(:), pointer charn
Definition: w3adatmd.F90:603
w3gdatmd::ygrd
double precision, dimension(:,:), pointer ygrd
Definition: w3gdatmd.F90:1205
yowelementpool
Definition: yowelementpool.F90:38
wmupdtmd
Update model input at the driver level of the multi-grid version of WAVEWATCH III.
Definition: wmupdtmd.F90:14
w3adatmd
Define data structures to set up wave model auxiliary data for several models simultaneously.
Definition: w3adatmd.F90:26
w3gdatmd::nspec
integer, pointer nspec
Definition: w3gdatmd.F90:1230
wmwavemd::wmwave
subroutine wmwave(TEND)
Run multi-grid version of WAVEWATCH III.
Definition: wmwavemd.F90:91
wmmdatmd::stime
integer, dimension(2) stime
STIME.
Definition: wmmdatmd.F90:328
yowrankmodule::rank
type(t_rank), dimension(:), allocatable, public rank
Provides access to some information of all threads e.g.
Definition: yowrankModule.F90:68
w3gdatmd::ungtype
integer, parameter ungtype
Definition: w3gdatmd.F90:626
wmupdtmd::wmupd2
subroutine wmupd2(IMOD, J, JMOD, IERR)
Update selected input using input grids.
Definition: wmupdtmd.F90:870
w3gdatmd::dmin
real, pointer dmin
Definition: w3gdatmd.F90:1183
w3gdatmd::ntri
integer, pointer ntri
Definition: w3gdatmd.F90:1109
w3wdatmd
Define data structures to set up wave model dynamic data for several models simultaneously.
Definition: w3wdatmd.F90:18
wmmdatmd::nmpscr
integer nmpscr
NMPSCR.
Definition: wmmdatmd.F90:324
w3updtmd::w3uini
subroutine w3uini(A)
Initialize the wave field with fetch-limited spectra before the actual calculation start.
Definition: w3updtmd.F90:1050
w3adatmd::us3d
real, dimension(:,:), pointer us3d
Definition: w3adatmd.F90:612
w3adatmd::cg
real, dimension(:,:), pointer cg
Definition: w3adatmd.F90:575
w3gdatmd::rlgtype
integer, parameter rlgtype
Definition: w3gdatmd.F90:624
w3gdatmd::grid
Definition: w3gdatmd.F90:643
w3adatmd::dw
real, dimension(:), pointer dw
Definition: w3adatmd.F90:584
wminitmd::wminit
subroutine wminit(IDSI, IDSO, IDSS, IDST, IDSE, IFNAME, MPI_COMM, PREAMB)
Initialize multi-grid version of WAVEWATCH III.
Definition: wminitmd.F90:131
w3adatmd::u10d
real, dimension(:), pointer u10d
Definition: w3adatmd.F90:584
w3gdatmd::sig
real, dimension(:), pointer sig
Definition: w3gdatmd.F90:1234
w3gdatmd::xgrd
double precision, dimension(:,:), pointer xgrd
Definition: w3gdatmd.F90:1205
wmfinlmd::wmfinl
subroutine wmfinl
Initialize multi-grid version of WAVEWATCH III.
Definition: wmfinlmd.F90:75
wminitmd::wminitnml
subroutine wminitnml(IDSI, IDSO, IDSS, IDST, IDSE, IFNAME, MPI_COMM, PREAMB)
Initialize multi-grid version of WAVEWATCH III.
Definition: wminitmd.F90:3502
w3adatmd::ipass
integer, pointer ipass
Definition: w3adatmd.F90:686
w3odatmd::iaproc
integer, pointer iaproc
Definition: w3odatmd.F90:457
wmesmfmd::fieldindex
integer function fieldindex(fnameList, fname, rc)
Return index associated with field name.
Definition: wmesmfmd.F90:5857
w3updtmd
Bundles all input updating routines for WAVEWATCH III.
Definition: w3updtmd.F90:22
w3wdatmd::time
integer, dimension(:), pointer time
Definition: w3wdatmd.F90:172
wmwavemd
Running the multi-grid version of WAVEWATCH III up to a given ending time for each grid.
Definition: wmwavemd.F90:14
wmesmfmd::setupimpbmsk
subroutine setupimpbmsk(bmskField, impField, missingVal, rc)
Setup background blending mask field for an import field.
Definition: wmesmfmd.F90:5074
w3gdatmd::ecos
real, dimension(:), pointer ecos
Definition: w3gdatmd.F90:1234
w3gdatmd::grids
type(grid), dimension(:), allocatable, target grids
Definition: w3gdatmd.F90:1088
constants::is_esmf_component
logical is_esmf_component
IS_ESMF_COMPONENT Flag for model invoked via ESMF.
Definition: constants.F90:109
w3gdatmd::ny
integer, pointer ny
Definition: w3gdatmd.F90:1097
yownodepool::iplg
integer, dimension(:), allocatable, public iplg
Node local to global mapping.
Definition: yownodepool.F90:116
w3adatmd::uba
real, dimension(:), pointer uba
Definition: w3adatmd.F90:614
yownodepool::npa
integer, public npa
number of ghost + resident nodes this partition holds
Definition: yownodepool.F90:99
wmunitmd::wmuset
subroutine wmuset(NDSE, NDST, NDS, FLAG, TYPE, NAME, DESC)
Directly set information for a unit number in the data structure.
Definition: wmunitmd.F90:497
wmunitmd::wmuget
subroutine wmuget(NDSE, NDST, NDS, TYPE, NR)
Find a free unit number for a given file type.
Definition: wmunitmd.F90:667
w3wdatmd::va
real, dimension(:,:), pointer va
Definition: w3wdatmd.F90:183
wmmdatmd::improc
integer improc
IMPROC.
Definition: wmmdatmd.F90:322
w3gdatmd::w3setg
subroutine w3setg(IMOD, NDSE, NDST)
Definition: w3gdatmd.F90:2152
yowelementpool::ne
integer, public ne
number of local elements
Definition: yowelementpool.F90:48
wmmdatmd::nmproc
integer nmproc
NMPROC.
Definition: wmmdatmd.F90:321
w3gdatmd::es2
real, dimension(:), pointer es2
Definition: w3gdatmd.F90:1234
w3adatmd::w3seta
subroutine w3seta(IMOD, NDSE, NDST)
Select one of the WAVEWATCH III grids / models.
Definition: w3adatmd.F90:2645
w3gdatmd::esin
real, dimension(:), pointer esin
Definition: w3gdatmd.F90:1234
yownodepool
Has data that belong to nodes.
Definition: yownodepool.F90:39
constants::lpdlib
logical lpdlib
LPDLIB Logical for using the PDLIB library.
Definition: constants.F90:101
w3gdatmd::clgtype
integer, parameter clgtype
Definition: w3gdatmd.F90:625
w3gdatmd::dsii
real, dimension(:), pointer dsii
Definition: w3gdatmd.F90:1234
wmesmfmd::createexpmesh
subroutine createexpmesh(gcomp, rc)
Create ESMF mesh (unstructured) for export fields.
Definition: wmesmfmd.F90:4554
yowrankmodule
Provides access to some information of all threads e.g.
Definition: yowrankModule.F90:44
w3wdatmd::w3setw
subroutine w3setw(IMOD, NDSE, NDST)
Select one of the WAVEWATCH III grids / models.
Definition: w3wdatmd.F90:660
constants::tpiinv
real, parameter tpiinv
TPIINV Inverse of 2*Pi.
Definition: constants.F90:74
w3odatmd::w3seto
subroutine w3seto(IMOD, NDSERR, NDSTST)
Definition: w3odatmd.F90:1523
w3adatmd::sxy
real, dimension(:), pointer sxy
Definition: w3adatmd.F90:607
w3gdatmd::nth
integer, pointer nth
Definition: w3gdatmd.F90:1230
w3odatmd
Definition: w3odatmd.F90:3
constants::dwat
real, parameter dwat
DWAT Density of water (kg/m3).
Definition: constants.F90:62
w3gdatmd::mapsf
integer, dimension(:,:), pointer mapsf
Definition: w3gdatmd.F90:1163
w3odatmd::naproc
integer, pointer naproc
Definition: w3odatmd.F90:457
w3gdatmd::us3df
integer, dimension(:), pointer us3df
Definition: w3gdatmd.F90:1098
yownodepool::np
integer, public np
number of nodes, local
Definition: yownodepool.F90:93
w3adatmd::wnmean
real, dimension(:), pointer wnmean
Definition: w3adatmd.F90:587
w3idatmd::w3seti
subroutine w3seti(IMOD, NDSE, NDST)
Select one of the WAVEWATCH III grids / models.
Definition: w3idatmd.F90:819
file
file(STRINGS ${CMAKE_BINARY_DIR}/switch switch_strings) separate_arguments(switches UNIX_COMMAND $
Definition: CMakeLists.txt:3
wmmdatmd::mdst
integer mdst
MDST.
Definition: wmmdatmd.F90:315
w3gdatmd::sig2
real, dimension(:), pointer sig2
Definition: w3gdatmd.F90:1234
w3adatmd::wn
real, dimension(:,:), pointer wn
Definition: w3adatmd.F90:575
w3adatmd::u10
real, dimension(:), pointer u10
Definition: w3adatmd.F90:584
w3iogomd::calc_u3stokes
subroutine calc_u3stokes(A, USS_SWITCH)
Output Stokes drift related parameters.
Definition: w3iogomd.F90:4156
constants::tpi
real, parameter tpi
TPI 2*Pi.
Definition: constants.F90:72
w3iogomd
Gridded output of mean wave parameters.
Definition: w3iogomd.F90:15
yowelementpool::ine
integer, dimension(:,:), allocatable, target, public ine
number of elements of the augmented domain
Definition: yowelementpool.F90:56
wmmdatmd::wmsetm
subroutine wmsetm(IMOD, NDSE, NDST)
Select one of the WAVEWATCH III grids / models.
Definition: wmmdatmd.F90:1169
w3gdatmd::gtype
integer, pointer gtype
Definition: w3gdatmd.F90:1094
w3idatmd
Define data structures to set up wave model input data for several models simultaneously.
Definition: w3idatmd.F90:16
wmesmfmd::setservices
subroutine, public setservices(gcomp, rc)
Wave model ESMF set services.
Definition: wmesmfmd.F90:352
w3gdatmd::fte
real, pointer fte
Definition: w3gdatmd.F90:1232
wmesmfmd::calcstokes3d
subroutine calcstokes3d(a, usxField, usyField, rc)
Calculate 3D Stokes drift current for export.
Definition: wmesmfmd.F90:7232
yownodepool::nodes_global
type(t_node), dimension(:), allocatable, target, public nodes_global
all nodes with their data.
Definition: yownodepool.F90:103
wmesmfmd
National Unified Prediction Capability (NUOPC) based Earth System Modeling Framework (ESMF) interface...
Definition: wmesmfmd.F90:72
wmscrpmd
Routines to determine and process grid dependencies in the multi-grid wave model.
Definition: wmscrpmd.F90:23
w3src3md::w3spr3
subroutine w3spr3(A, CG, WN, EMEAN, FMEAN, FMEANS, WNMEAN, AMAX, U, UDIR, USTAR, USDIR, TAUWX, TAUWY, CD, Z0, CHARN, LLWS, FMEANWS)
Calculate mean wave parameters for the use in the source term routines.
Definition: w3src3md.F90:137
w3wdatmd::ust
real, dimension(:), pointer ust
Definition: w3wdatmd.F90:183
wmscrpmd::get_scrip_info_structured
subroutine get_scrip_info_structured(ID_GRD, GRID_CENTER_LON, GRID_CENTER_LAT, GRID_CORNER_LON, GRID_CORNER_LAT, GRID_MASK, GRID_DIMS, GRID_SIZE, GRID_CORNERS, GRID_RANK)
Compute grid arrays needed for scrip for a specific structured grid.
Definition: wmscrpmd.F90:974
constants
Define some much-used constants for global use (all defined as PARAMETER).
Definition: constants.F90:20
w3gdatmd::dden
real, dimension(:), pointer dden
Definition: w3gdatmd.F90:1234
w3gdatmd
Definition: w3gdatmd.F90:16
wmmdatmd
Define data structures to set up wave model dynamic data for several models simultaneously.
Definition: wmmdatmd.F90:16
w3fldsmd::w3fldg
subroutine w3fldg(INXOUT, IDFLD, NDS, NDST, NDSE, MX, MY, NX, NY, T0, TN, TF0, FX0, FY0, FA0, TFN, FXN, FYN, FAN, IERR, FLAGSC ifdef W3_OASIS
Definition: w3fldsmd.F90:958
w3src3md
The 'WAM4+' source terms based on P.A.E.M.
Definition: w3src3md.F90:30
w3src4md
The 'SHOM/Ifremer' source terms based on P.A.E.M.
Definition: w3src4md.F90:28
w3fldsmd::w3fldo
subroutine w3fldo(INXOUT, IDFLD, NDS, NDST, NDSE, NX, NY, GTYPE, IERR, FEXT, FPRE, FHDR, TIDEFLAGIN)
Definition: w3fldsmd.F90:90
wmesmfmd::setexport
subroutine setexport(gcomp, rc)
Set export fields from internal data structures.
Definition: wmesmfmd.F90:2821
w3iogomd::w3outg
subroutine w3outg(A, FLPART, FLOUTG, FLOUTG2)
Fill necessary arrays with gridded data for output.
Definition: w3iogomd.F90:1198
w3gdatmd::nx
integer, pointer nx
Definition: w3gdatmd.F90:1097
wmesmfmd::readfromfile
subroutine readfromfile(idfld, fldwx, fldwy, time0, timen, rc)
Read input file to fill unmapped point for regional applications.
Definition: wmesmfmd.F90:7709
w3timemd
Definition: w3timemd.F90:3
w3src4md::w3spr4
subroutine w3spr4(A, CG, WN, EMEAN, FMEAN, FMEAN1, WNMEAN, AMAX, U, UDIR, ifdef W3_FLX5
Calculate mean wave parameters for the use in the source term routines.
Definition: w3src4md.F90:145
w3adatmd::ussp
real, dimension(:,:), pointer ussp
Definition: w3adatmd.F90:612
check
subroutine check(status)
N/A.
Definition: ww3_systrk.F90:1299
w3gdatmd::ec2
real, dimension(:), pointer ec2
Definition: w3gdatmd.F90:1234
wmunitmd
Dynamic assignement of unit numbers for the multi-grid wave model.
Definition: wmunitmd.F90:18
w3gdatmd::mapsta
integer, dimension(:,:), pointer mapsta
Definition: w3gdatmd.F90:1163
constants::grav
real, parameter grav
GRAV Acc.
Definition: constants.F90:61
w3adatmd::aba
real, dimension(:), pointer aba
Definition: w3adatmd.F90:614
w3adatmd::syy
real, dimension(:), pointer syy
Definition: w3adatmd.F90:607
wmmdatmd::etime
integer, dimension(2) etime
ETIME.
Definition: wmmdatmd.F90:329
w3adatmd::ubd
real, dimension(:), pointer ubd
Definition: w3adatmd.F90:614
w3adatmd::sxx
real, dimension(:), pointer sxx
Definition: w3adatmd.F90:607
w3fldsmd
Definition: w3fldsmd.F90:3