15 #define FILENAME "wmesmfmd.ftn"
16 #define CONTEXT line=__LINE__,file=FILENAME,method=METHOD
17 #define PASSTHRU msg=ESMF_LOGERR_PASSTHRU,CONTEXT
23 #define ESMF_KIND_RX ESMF_KIND_R8
24 #define ESMF_TYPEKIND_RX ESMF_TYPEKIND_R8
26 #define ESMF_KIND_RX ESMF_KIND_R4
27 #define ESMF_TYPEKIND_RX ESMF_TYPEKIND_R4
33 #define USE_W3OUTG_FOR_EXPORT___disabled
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
222 INTEGER,
PARAMETER :: DEFAULT_MASK_WATER = 0
223 INTEGER,
PARAMETER :: DEFAULT_MASK_LAND = 1
226 integer,
parameter :: stdo = 6
231 logical :: realizeAllExport = .false.
232 integer :: maskValueWater = default_mask_water
233 integer :: maskValueLand = default_mask_land
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
243 integer,
parameter :: numwt=10
244 character(32) :: wtnam(numwt)
245 integer :: wtcnt(numwt)
246 real(8) :: wtime(numwt)
249 type(ESMF_ArraySpec) :: impArraySpec2D
250 type(ESMF_StaggerLoc) :: impStaggerLoc
251 type(ESMF_Index_Flag) :: impIndexFlag
252 type(ESMF_Grid) :: impGrid
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(:)
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(:)
276 type(ESMF_Mesh) :: impMesh
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(:)
302 type(ESMF_Mesh) :: expMesh
304 logical :: expMeshIsLocal
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
314 logical :: natGridIsLocal
315 type(ESMF_RouteHandle):: n2eRH
318 logical :: med_present = .false.
319 character(256) :: flds_scalar_name =
''
320 integer :: flds_scalar_num = 0
324 integer :: flds_scalar_index_nx = 0
325 integer :: flds_scalar_index_ny = 0
327 logical :: profile_memory = .false.
330 logical :: merge_import = .false.
331 logical,
allocatable :: mmskCreated(:)
332 type(ESMF_Field),
allocatable :: mmskField(:)
333 type(ESMF_Field),
allocatable :: mdtField(:)
342 #define METHOD "SetServices"
406 type(esmf_gridcomp) :: gcomp
407 integer,
intent(out) :: rc
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'
437 call nuopc_compderive(gcomp, parent_setservices, rc=rc)
438 if (esmf_logfounderror(rc, passthru))
return
445 call esmf_gridcompsetentrypoint(gcomp, esmf_method_initialize, &
446 userroutine=initializep0, phase=0, rc=rc)
447 if (esmf_logfounderror(rc, passthru))
return
455 call nuopc_compsetentrypoint(gcomp, esmf_method_initialize, &
456 phaselabellist=(/
"IPDv03p1"/), userroutine=initializep1, rc=rc)
457 if (esmf_logfounderror(rc, passthru))
return
460 call nuopc_compsetentrypoint(gcomp, esmf_method_initialize, &
461 phaselabellist=(/
"IPDv03p3"/), userroutine=initializep3, rc=rc)
462 if (esmf_logfounderror(rc, passthru))
return
474 call nuopc_compspecialize(gcomp, speclabel=label_datainitialize, &
475 specroutine=datainitialize, rc=rc)
476 if (esmf_logfounderror(rc, passthru))
return
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
488 call nuopc_compspecialize(gcomp, speclabel=label_advance, &
489 specroutine=modeladvance, rc=rc)
490 if (esmf_logfounderror(rc, passthru))
return
494 call nuopc_compspecialize(gcomp, speclabel=label_finalize, &
495 specroutine=finalize, rc=rc)
496 if (esmf_logfounderror(rc, passthru))
return
509 #define METHOD "InitializeP0"
523 subroutine initializep0 ( gcomp, impState, expState, extClock, rc )
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
586 character(ESMF_MAXSTR) :: cname
587 character(ESMF_MAXSTR) :: valuestring
588 integer,
parameter :: iwt=1
589 real(8) :: wstime, wftime
590 logical :: ispresent, isset
596 call esmf_vmwtime(wstime)
597 call esmf_gridcompget(gcomp, name=cname, rc=rc)
598 if (esmf_logfounderror(rc, passthru))
return
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
611 if (verbosity.gt.0)
call esmf_logwrite(trim(cname)// &
612 ': entered InitializeP0', esmf_logmsg_info)
618 call nuopc_compfilterphasemap(gcomp, esmf_method_initialize, &
619 acceptstringlist=(/
"IPDv03p"/), rc=rc)
620 if (esmf_logfounderror(rc, passthru))
return
625 call nuopc_compattributeget(gcomp, name=
"mediator_present", &
626 value=valuestring, ispresent=ispresent, isset=isset, rc=rc)
627 if (esmf_logfounderror(rc, passthru))
return
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
639 call nuopc_compattributeget(gcomp, name=
"ProfileMemory", &
640 value=valuestring, ispresent=ispresent, isset=isset, rc=rc)
641 if (esmf_logfounderror(rc, passthru))
return
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
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)
663 end subroutine initializep0
667 #define METHOD "InitializeP1"
681 subroutine initializep1 ( gcomp, impState, expState, extClock, rc )
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
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
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)
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
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
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
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
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
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
880 zerovalue = real(0,esmf_kind_rx)
881 missingvalue = real(0,esmf_kind_rx)
882 fillvalue = real(9.99e20,esmf_kind_rx)
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
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
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
933 call esmf_configgetattribute(config, wrkdir, &
934 label=trim(cname)//
'_work_dir:', default=
'.', rc=rc)
935 if (esmf_logfounderror(rc, passthru))
return
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
951 call esmf_configgetattribute(config, expgridid, &
952 label=trim(cname)//
'_export_grid_id:', default=1, rc=rc)
953 if (esmf_logfounderror(rc, passthru))
return
955 call esmf_configgetattribute(config, realizeallexport, &
956 label=trim(cname)//
'_realize_all_export:', default=.false., rc=rc)
957 if (esmf_logfounderror(rc, passthru))
return
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
966 call esmf_configgetattribute(config, zlfile, &
967 label=trim(cname)//
'_zlevel_exp_file:', default=
'none', rc=rc)
968 if (esmf_logfounderror(rc, passthru))
return
971 preamb = trim(preamb)//
'/'
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
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
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
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);
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.
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
1028 ! -------------------------------------------------------------------- /
1029 ! 2. Initialization of all wave models / grids
1031 ! 2.a Call into WMINIT
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 )
1040 call wminit ( idsi, idso, idss, idst, idse, trim(ifname), &
1041 mpicomm, preamb=preamb )
1044 ! 2.b Check consistency between internal timestep and external
1045 ! timestep (coupling interval)
1047 call ESMF_ClockGet(extClock, timeStep=etstep, rc=rc)
1048 if (ESMF_LogFoundError(rc, PASSTHRU)) return
1050 ! 2.c Trap unsupported CPL input forcing settings
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)
1063 allocate (cplmap(nrgrd,jfirst:8), stat=rc)
1064 if (ESMF_LogFoundAllocError(rc, PASSTHRU)) return
1065 jmod = minval(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)
1076 deallocate (cplmap, stat=rc)
1077 if (ESMF_LogFoundDeallocError(rc, PASSTHRU)) return
1080 ! -------------------------------------------------------------------- /
1081 import field list
! 3. Initialize
1083 istep_import: do istep = 1, 2
1085 .eq.
if ( istep2 ) then
1086 allocate ( impFieldName(numImpFields), &
1087 impFieldStdName(numImpFields), &
1088 impFieldInitRqrd(numImpFields), &
1089 impFieldActive(numImpFields), &
1090 impField(numImpFields), &
1092 if (ESMF_LogFoundAllocError(rc, PASSTHRU)) return
1093 allocate ( mbgFieldName(numImpFields), &
1094 mbgFieldStdName(numImpFields), &
1095 mbgFieldActive(numImpFields), &
1096 mbgField(numImpFields), &
1097 bmskField(numImpFields), &
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.
1106 impFieldActive(:) = .false.
1111 .eq.
if ( istep2 ) then
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
1121 .eq.
if ( istep2 ) then
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
1131 .eq.
if ( istep2 ) then
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
1141 .eq.
if ( istep2 ) then
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
1151 .eq.
if ( istep2 ) then
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
1161 .eq.
if ( istep2 ) then
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
1173 .not.
noActiveImpFields = all(impFieldActive)
1175 do i = 1,numImpFields
1176 mbgFieldName(i) = 'mbg_
'//trim(impFieldName(i))
1177 mbgFieldStdName(i) = 'mbg_
'//trim(impFieldStdName(i))
1180 ! -------------------------------------------------------------------- /
1181 ! 4. Initialize export field list
1183 istep_export: do istep = 1, 2
1185 .eq.
if ( istep2 ) then
1186 allocate ( expFieldName(numExpFields), &
1187 expFieldStdName(numExpFields), &
1188 expFieldDim(numExpFields), &
1189 expFieldActive(numExpFields), &
1190 expField(numExpFields), &
1192 if (ESMF_LogFoundAllocError(rc, PASSTHRU)) return
1193 expFieldActive(:) = .false.
1198 .eq.
if ( istep2 ) then
1199 expFieldName(i) = 'charno
'
1200 expFieldStdName(i) = 'wave_induced_charnock_parameter
'
1205 .eq.
if ( istep2 ) then
1206 expFieldName(i) = 'z0rlen
'
1207 expFieldStdName(i) = 'wave_z0_roughness_length
'
1212 .eq.
if ( istep2 ) then
1213 expFieldName(i) = 'uscurr
'
1214 expFieldStdName(i) = 'eastward_stokes_drift_current
'
1219 .eq.
if ( istep2 ) then
1220 expFieldName(i) = 'vscurr
'
1221 expFieldStdName(i) = 'northward_stokes_drift_current
'
1226 .eq.
if ( istep2 ) then
1227 expFieldName(i) = 'x1pstk
'
1228 expFieldStdName(i) = 'eastward_partitioned_stokes_drift_1
'
1233 .eq.
if ( istep2 ) then
1234 expFieldName(i) = 'y1pstk
'
1235 expFieldStdName(i) = 'northward_partitioned_stokes_drift_1
'
1240 .eq.
if ( istep2 ) then
1241 expFieldName(i) = 'x2pstk
'
1242 expFieldStdName(i) = 'eastward_partitioned_stokes_drift_2
'
1247 .eq.
if ( istep2 ) then
1248 expFieldName(i) = 'y2pstk
'
1249 expFieldStdName(i) = 'northward_partitioned_stokes_drift_2
'
1254 .eq.
if ( istep2 ) then
1255 expFieldName(i) = 'x3pstk
'
1256 expFieldStdName(i) = 'eastward_partitioned_stokes_drift_3
'
1261 .eq.
if ( istep2 ) then
1262 expFieldName(i) = 'y3pstk
'
1263 expFieldStdName(i) = 'northward_partitioned_stokes_drift_3
'
1268 .eq.
if ( istep2 ) then
1269 expFieldName(i) = 'wbcuru
'
1270 expFieldStdName(i) = 'eastward_wave_bottom_current
'
1275 .eq.
if ( istep2 ) then
1276 expFieldName(i) = 'wbcurv
'
1277 expFieldStdName(i) = 'northward_wave_bottom_current
'
1282 .eq.
if ( istep2 ) then
1283 expFieldName(i) = 'wbcurp
'
1284 expFieldStdName(i) = 'wave_bottom_current_period
'
1289 .eq.
if ( istep2 ) then
1290 expFieldName(i) = 'wavsuu
'
1291 expFieldStdName(i) = 'eastward_wave_radiation_stress
'
1296 .eq.
if ( istep2 ) then
1297 expFieldName(i) = 'wavsuv
'
1298 expFieldStdName(i) = 'eastward_northward_wave_radiation_stress
'
1303 .eq.
if ( istep2 ) then
1304 expFieldName(i) = 'wavsvv
'
1305 expFieldStdName(i) = 'northward_wave_radiation_stress
'
1309 if (med_present) then
1311 .eq.
if ( istep2 ) then
1312 expFieldName(i) = trim(flds_scalar_name)
1313 expFieldStdName(i) = trim(flds_scalar_name)
1321 .not.
noActiveExpFields = all(expFieldActive)
1323 ! -------------------------------------------------------------------- /
1324 import fields
! 5. Advertise
1326 import fields
! 5.a Advertise active
1329 do i = 1,numImpFields
1330 .not.
if (impFieldActive(i)) cycle
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
1337 call NUOPC_Advertise(impState, &
1338 trim(mbgFieldStdName(i)), name=trim(mbgFieldName(i)), rc=rc)
1339 if (ESMF_LogFoundError(rc, PASSTHRU)) return
1342 import fields
! 5.b Report advertised
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)
1351 do i = 1,numImpFields
1352 .not.
if (impFieldActive(i)) cycle
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
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)
1364 ! -------------------------------------------------------------------- /
1365 ! 6. Advertise export fields
1367 ! 6.a Advertise all export fields
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
1375 ! 6.b Report advertised export fields
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)
1389 ! -------------------------------------------------------------------- /
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)
1399 ! -------------------------------------------------------------------- /
1402 900 format (/15x,' *** wavewatch iii multi-
grid shell ***
'/ &
1403 15x,'=================================================
'/)
1405 !/ End of InitializeP1 ----------------------------------------------- /
1407 end subroutine InitializeP1
1408 !/ ------------------------------------------------------------------- /
1411 #define METHOD "InitializeP3"
1413 !> @brief Initialize wave model (phase 3).
1415 import and export states.
!> @details Realize fields in
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.
1423 !> @author T. J. Campbell
1424 !> @author A. J. van der Westhuysen
1425 !> @date 09-Aug-2017
1427 subroutine InitializeP3 ( gcomp, impState, expState, extClock, rc )
1429 !/ +-----------------------------------+
1430 !/ | WAVEWATCH III NOAA/NCEP |
1431 !/ | T. J. Campbell, NRL |
1432 !/ | A. J. van der Westhuysen |
1434 !/ | Last update : 09-Aug-2017 |
1435 !/ +-----------------------------------+
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 )
1443 ! Initialize wave model (phase 3)
1444 import and export states.
! * Realize fields in
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 ! ----------------------------------------------------------------
1459 ! 4. Subroutines used :
1461 ! Name Type Module Description
1462 ! ----------------------------------------------------------------
1463 ! WMINIT Subr. WMINITMD Wave model initialization
1464 ! WMINITNML Subr. WMINITMD Wave model initialization
1465 ! ----------------------------------------------------------------
1469 ! 6. Error messages :
1479 !/ ------------------------------------------------------------------- /
1481 !/ ------------------------------------------------------------------- /
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
1491 !/ ------------------------------------------------------------------- /
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
1502 ! -------------------------------------------------------------------- /
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)
1512 ! -------------------------------------------------------------------- /
1513 import fields
! 1. Realize active
1515 import fields
! 1.a Create ESMF grid for
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
1531 import fields and realize
! 1.b Create
1534 do i = 1,numImpFields
1535 .not.
if (impFieldActive(i)) cycle
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
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
1571 .not.
if (mbgFieldActive(i)) cycle
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
1590 import fields
! 1.c Report realized
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)
1599 do i = 1,numImpFields
1600 .not.
if (impFieldActive(i)) cycle
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
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)
1612 ! -------------------------------------------------------------------- /
1613 ! 2. Realize active export fields
1615 ! 2.a Set connected export fields as active and remove unconnected
1616 ! If realizeAllExport, then set all fields as active and realize.
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)
1632 ! 2.b Create ESMF grid for export fields
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
1647 ! 2.c Create active export fields and realize
1650 do i = 1,numExpFields
1651 .not.
if (expFieldActive(i)) cycle
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
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
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
1676 call FieldFill( expField(i), zeroValue, rc=rc )
1677 if (ESMF_LogFoundError(rc, PASSTHRU)) return
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
1686 call NUOPC_Realize( expState, expField(i), rc=rc )
1687 if (ESMF_LogFoundError(rc, PASSTHRU)) return
1690 ! 2.d Report realized export fields
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)
1699 do i = 1,numExpFields
1700 .not.
if (expFieldActive(i)) cycle
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)
1707 ! 2.e Set W3OUTG flags needed for calculating export fields
1709 #ifdef USE_W3OUTG_FOR_EXPORT
1710 call w3seto ( expGridID, mdse, mdst )
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)
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
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
1754 ! -------------------------------------------------------------------- /
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)
1764 !/ End of InitializeP3 ----------------------------------------------- /
1766 end subroutine InitializeP3
1767 !/ ------------------------------------------------------------------- /
1770 #define METHOD "Finalize"
1772 !> @brief Finalize wave model.
1774 !> @param gcomp Gridded component.
1775 !> @param[out] rc Return code.
1777 !> @author T. J. Campbell @date 09-Aug-2017
1779 subroutine Finalize ( gcomp, rc )
1781 !/ +-----------------------------------+
1782 !/ | WAVEWATCH III NOAA/NCEP |
1783 !/ | T. J. Campbell, NRL |
1785 !/ | Last update : 09-Aug-2017 |
1786 !/ +-----------------------------------+
1788 !/ 20-Jan-2017 : Origination. ( version 6.02 )
1789 !/ 09-Aug-2017 : Add clean up of local allocations ( version 6.03 )
1793 ! Finalize wave model
1800 ! ----------------------------------------------------------------
1801 ! gcomp Type I/O Gridded component
1802 ! rc Int. O Return code
1803 ! ----------------------------------------------------------------
1805 ! 4. Subroutines used :
1807 ! Name Type Module Description
1808 ! ----------------------------------------------------------------
1809 ! WMFINL Subr. WMFINLMD Wave model finalization
1810 ! ----------------------------------------------------------------
1814 ! 6. Error messages :
1824 !/ ------------------------------------------------------------------- /
1826 !/ ------------------------------------------------------------------- /
1830 type(ESMF_GridComp) :: gcomp
1831 integer,intent(out) :: rc
1833 !/ ------------------------------------------------------------------- /
1836 character(ESMF_MAXSTR) :: cname
1837 integer, parameter :: iwt=6
1838 real(8) :: wstime, wftime
1841 ! -------------------------------------------------------------------- /
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)
1851 ! -------------------------------------------------------------------- /
1852 ! 1. Finalize the wave model
1856 ! -------------------------------------------------------------------- /
1857 ! 2. Clean up ESMF data structures
1859 Import field and
grid stuff
! 2.a
1861 .not.
if ( noActiveImpFields ) then
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
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
1880 .eq..or..eq.
if ( (GTYPERLGTYPE)(GTYPECLGTYPE) ) then
1881 call ESMF_FieldHaloRelease(impHaloRH, rc=rc)
1882 if (ESMF_LogFoundError(rc, PASSTHRU)) return
1884 call ESMF_GridDestroy(impGrid, rc=rc)
1885 if (ESMF_LogFoundError(rc, PASSTHRU)) return
1887 .eq.
elseif (GTYPEUNGTYPE) then
1888 !AW call ESMF_GridDestroy(impMesh, rc=rc)
1889 !AW if (ESMF_LogFoundError(rc, PASSTHRU)) return
1894 deallocate (impFieldName, &
1900 if (ESMF_LogFoundDeallocError(rc, PASSTHRU)) return
1902 deallocate (mbgFieldName, &
1908 if (ESMF_LogFoundDeallocError(rc, PASSTHRU)) return
1910 if (merge_import) then
1911 deallocate(mmskCreated, &
1915 if (ESMF_LogFoundDeallocError(rc, PASSTHRU)) return
1918 ! 2.b Export field and grid stuff
1920 .not.
if ( noActiveExpFields ) then
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
1928 .eq..or..eq.
if ( (GTYPERLGTYPE)(GTYPECLGTYPE) ) then
1929 call ESMF_FieldHaloRelease(expHaloRH, rc=rc)
1930 if (ESMF_LogFoundError(rc, PASSTHRU)) return
1932 call ESMF_GridDestroy(expGrid, rc=rc)
1933 if (ESMF_LogFoundError(rc, PASSTHRU)) return
1935 .eq.
elseif (GTYPEUNGTYPE) then
1936 !AW call ESMF_GridDestroy(expMesh, rc=rc)
1937 !AW if (ESMF_LogFoundError(rc, PASSTHRU)) return
1942 deallocate (expFieldName, &
1948 if (ESMF_LogFoundDeallocError(rc, PASSTHRU)) return
1950 ! 2.c Native field and grid stuff
1952 .not.
if ( noActiveExpFields ) then
1954 call ESMF_FieldRedistRelease(n2eRH, rc=rc)
1955 if (ESMF_LogFoundError(rc, PASSTHRU)) return
1957 call ESMF_GridDestroy(natGrid, rc=rc)
1958 if (ESMF_LogFoundError(rc, PASSTHRU)) return
1962 ! -------------------------------------------------------------------- /
1963 ! 3. Clean up locally allocated data structures
1965 if (allocated(zl)) then
1966 deallocate (zl, stat=rc)
1967 if (ESMF_LogFoundDeallocError(rc, PASSTHRU)) return
1970 ! -------------------------------------------------------------------- /
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)
1978 .eq.
if ( improc nmpscr ) write (*,999)
1979 .gt.
if (verbosity0) call ESMF_LogWrite(trim(cname)// &
1980 ': leaving finalize
', ESMF_LOGMSG_INFO)
1982 ! -------------------------------------------------------------------- /
1985 999 format(//' end of program
'/ &
1986 ' ========================================
'/ &
1987 ' wavewatch iii multi-
grid shell
'/)
1989 !/ End of Finalize --------------------------------------------------- /
1991 end subroutine Finalize
1992 !/ ------------------------------------------------------------------- /
1995 #define METHOD "DataInitialize"
1997 !> @brief Initialize wave model export data
1999 !> @param gcomp Gridded component.
2000 !> @param[out] rc Return code.
2002 !> @author T. J. Campbell @date 20-Jan-2017
2004 subroutine DataInitialize ( gcomp, rc )
2006 !/ +-----------------------------------+
2007 !/ | WAVEWATCH III NOAA/NCEP |
2008 !/ | T. J. Campbell, NRL |
2010 !/ | Last update : 20-Jan-2017 |
2011 !/ +-----------------------------------+
2013 !/ 20-Jan-2017 : Origination. ( version 6.02 )
2017 ! Initialize wave model export data
2024 ! ----------------------------------------------------------------
2025 ! gcomp Type I/O Gridded component
2026 ! rc Int. O Return code
2027 ! ----------------------------------------------------------------
2029 ! 4. Subroutines used :
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 ! ----------------------------------------------------------------
2039 ! 6. Error messages :
2049 !/ ------------------------------------------------------------------- /
2051 !/ ------------------------------------------------------------------- /
2055 type(ESMF_GridComp) :: gcomp
2056 integer,intent(out) :: rc
2058 !/ ------------------------------------------------------------------- /
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
2070 ! -------------------------------------------------------------------- /
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)
2080 ! -------------------------------------------------------------------- /
2081 import fields show correct
time stamp
! 1. Check that required
2083 if (med_present) then
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
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:
', &
2102 allUpdated = .false.
2103 write(msg,'(a,a10,a,a13)
') trim(cname)//':
', &
2104 trim(impFieldName(i)),': inter-model data dependency:
', &
2108 write(msg,'(a,a10,a,a13)
') trim(cname)//':
', &
2109 trim(impFieldName(i)),': inter-model data dependency:
', &
2112 .gt.
if (verbosity0) call ESMF_LogWrite(trim(msg), ESMF_LOGMSG_INFO)
2113 .eq.
if (improcnmpscr) write(*,'(a)
') trim(msg)
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:
', &
2124 allUpdated = .false.
2125 write(msg,'(a,a10,a,a13)
') trim(cname)//':
', &
2126 trim(mbgFieldName(i)),': inter-model data dependency:
', &
2130 write(msg,'(a,a10,a,a13)
') trim(cname)//':
', &
2131 trim(mbgFieldName(i)),': inter-model data dependency:
', &
2134 .gt.
if (verbosity0) call ESMF_LogWrite(trim(msg), ESMF_LOGMSG_INFO)
2135 .eq.
if (improcnmpscr) write(*,'(a)
') trim(msg)
2139 import dependencies are satisfied, then return
! If not all
2141 .not.
if (allUpdated) goto 1
2143 ! -------------------------------------------------------------------- /
2144 import dependencies are satisfied, so finish initialization
! 2. All
2146 import dependencies are satisfied
! 2.a Report all
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)
2153 import field
! 2.b Setup background blending mask for each
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
2162 import fields
! 2.c Get
2164 call GetImport(gcomp, rc)
2165 if (ESMF_LogFoundError(rc, PASSTHRU)) return
2167 ! 2.d Finish initialization (compute initial state), if not restart
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 )
2180 ! 2.e Set export fields
2182 call SetExport(gcomp, rc)
2183 if (ESMF_LogFoundError(rc, PASSTHRU)) return
2185 ! 2.f Set Updated Field Attribute to "true", indicating to the
2186 ! generic code to set the timestamp for these fields
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
2195 ! 2.g Set InitializeDataComplete Attribute to "true", indicating to the
2196 ! generic code that all inter-model data dependencies are satisfied
2198 call NUOPC_CompAttributeSet(gcomp, name="InitializeDataComplete", &
2199 value="true", rc=rc)
2200 if (ESMF_LogFoundError(rc, PASSTHRU)) return
2202 ! -------------------------------------------------------------------- /
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)
2212 !/ End of DataInitialize --------------------------------------------- /
2214 end subroutine DataInitialize
2215 !/ ------------------------------------------------------------------- /
2218 #define METHOD "ModelAdvance"
2220 !> @brief Advance wave model in time.
2222 !> @param gcomp Gridded component.
2223 !> @param[out] rc Return code.
2225 !> @author T. J. Campbell @date 20-Jan-2017
2227 subroutine ModelAdvance ( gcomp, rc )
2229 !/ +-----------------------------------+
2230 !/ | WAVEWATCH III NOAA/NCEP |
2231 !/ | T. J. Campbell, NRL |
2233 !/ | Last update : 20-Jan-2017 |
2234 !/ +-----------------------------------+
2236 !/ 20-Jan-2017 : Origination. ( version 6.02 )
2240 ! Advance wave model in time
2247 ! ----------------------------------------------------------------
2248 ! gcomp Type I/O Gridded component
2249 ! rc Int. O Return code
2250 ! ----------------------------------------------------------------
2252 ! 4. Subroutines used :
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 ! ----------------------------------------------------------------
2263 ! 6. Error messages :
2273 !/ ------------------------------------------------------------------- /
2275 !/ ------------------------------------------------------------------- /
2279 type(ESMF_GridComp) :: gcomp
2280 integer,intent(out) :: rc
2282 !/ ------------------------------------------------------------------- /
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
2296 type(ESMF_Time) :: startTime
2297 type(ESMF_TimeInterval) :: timeStep
2298 character(len=256) :: msgString
2301 ! -------------------------------------------------------------------- /
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
'// &
2313 allocate (tend(2,nrgrd), stat=rc)
2314 if (ESMF_LogFoundAllocError(rc, PASSTHRU)) return
2316 ! -------------------------------------------------------------------- /
2317 ! 1. Advance model to requested end time
2319 ! 1.a Get component clock
2321 call ESMF_GridCompGet(gcomp, clock=clock, rc=rc)
2322 if (ESMF_LogFoundError(rc, PASSTHRU)) return
2326 .eq.
if ( improc nmpscr ) then
2328 call ESMF_ClockPrint(clock, options="currTime", &
2329 preString="-->Advancing "//TRIM(cname)//" from: ")
2330 call ESMF_ClockPrint(clock, options="stopTime", &
2331 preString="-----------------> to: ")
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)
2340 call ESMF_ClockGet(clock, startTime=startTime, &
2341 currTime=currTime, &
2342 timeStep=timeStep, rc=rc)
2344 call ESMF_TimePrint(currTime + timeStep, &
2345 preString="--------------------------------> to: ", &
2346 unit=msgString, rc=rc)
2347 call ESMF_LogWrite(trim(msgString), ESMF_LOGMSG_INFO)
2350 ! 1.c Check internal current time with component current time
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
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
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)
2376 ! 1.d Set end time of this advance
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
2383 tend(1,imod) = 10000*yy + 100*mm + dd
2384 tend(2,imod) = 10000*h + 100*m + s
2387 import fields
! 1.e Get
2389 call GetImport(gcomp, rc=rc)
2390 if (ESMF_LogFoundError(rc, PASSTHRU)) return
2394 if(profile_memory) call ESMF_VMLogMemInfo("Entering WW3 Run : ")
2395 call wmwave ( tend )
2396 if(profile_memory) call ESMF_VMLogMemInfo("Entering WW3 Run : ")
2398 ! 1.g Set export fields
2400 call SetExport(gcomp, rc=rc)
2401 if (ESMF_LogFoundError(rc, PASSTHRU)) return
2403 ! -------------------------------------------------------------------- /
2406 deallocate (tend, stat=rc)
2407 if (ESMF_LogFoundDeallocError(rc, PASSTHRU)) return
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
'// &
2417 !/ End of ModelAdvance ----------------------------------------------- /
2419 end subroutine ModelAdvance
2420 !/ ------------------------------------------------------------------- /
2423 #define METHOD "GetImport"
2425 import fields and put in internal data structures.
!> @brief Get
2427 !> @param gcomp Gridded component.
2428 !> @param[out] rc Return code.
2430 !> @author T. J. Campbell @date 20-Jan-2017
2432 Import ( gcomp, rc )
subroutine Get
2434 !/ +-----------------------------------+
2435 !/ | WAVEWATCH III NOAA/NCEP |
2436 !/ | T. J. Campbell, NRL |
2438 !/ | Last update : 20-Jan-2017 |
2439 !/ +-----------------------------------+
2441 !/ 20-Jan-2017 : Origination. ( version 6.02 )
2445 import fields and put in internal data structures
! Get
2452 ! ----------------------------------------------------------------
2453 ! gcomp Type I/O Gridded component
2454 ! rc Int. O Return code
2455 ! ----------------------------------------------------------------
2457 ! 4. Subroutines used :
2459 ! Name Type Module Description
2460 ! ----------------------------------------------------------------
2462 ! ----------------------------------------------------------------
2466 ! 6. Error messages :
2476 !/ ------------------------------------------------------------------- /
2478 !/ ------------------------------------------------------------------- /
2482 USE WMMDATMD, ONLY: IMPROC
2485 type(ESMF_GridComp) :: gcomp
2486 integer,intent(out) :: rc
2488 !/ ------------------------------------------------------------------- /
2491 character(ESMF_MAXSTR) :: cname
2492 !AW ---TEST-TEST-TEST---------------------------
2493 character(500) :: msg
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
2508 real(ESMF_KIND_RX), pointer :: rptr(:,:)
2510 integer :: elb(2), eub(2)
2511 character(len=3) :: fieldName
2513 ! -------------------------------------------------------------------- /
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
2532 ! -------------------------------------------------------------------- /
2533 ! Set time stamps using currTime and stopTime
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
2550 ! -------------------------------------------------------------------- /
2554 i1 = FieldIndex( impFieldName, 'seahgt
', rc )
2555 if (ESMF_LogFoundError(rc, PASSTHRU)) return
2557 if ( impFieldActive(i1) ) then
2558 call w3setg ( impGridID, mdse, mdst )
2559 call w3seti ( impGridID, mdse, mdst )
2566 if ( mbgFieldActive(i1) ) then
2567 call BlendImpField( impField(i1), mbgField(i1), bmskField(i1), rc=rc )
2568 if (ESMF_LogFoundError(rc, PASSTHRU)) return
2570 call FieldGather( impField(i1), nx, ny, wlev, rc=rc )
2571 if (ESMF_LogFoundError(rc, PASSTHRU)) return
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 )
2579 .eq.
if ( mpi_comm_grd mpi_comm_null ) cycle
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
2589 ! -------------------------------------------------------------------- /
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 )
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
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
2625 call w3setg ( imod, mdse, mdst )
2626 call w3setw ( imod, mdse, mdst )
2627 call w3seti ( imod, mdse, mdst )
2628 call wmsetm ( imod, mdse, mdst )
2630 .eq.
if ( mpi_comm_grd mpi_comm_null ) cycle
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
2640 ! -------------------------------------------------------------------- /
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 )
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
2667 if (merge_import) then
2670 call ReadFromFile(fieldName, mdtField(i1), mdtField(i2), tcur, tend, rc=rc)
2671 if (ESMF_LogFoundError(rc, PASSTHRU)) return
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
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
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
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
2704 call w3setg ( imod, mdse, mdst )
2705 call w3setw ( imod, mdse, mdst )
2706 call w3seti ( imod, mdse, mdst )
2707 call wmsetm ( imod, mdse, mdst )
2709 .eq.
if ( mpi_comm_grd mpi_comm_null ) cycle
2711 INPUTS(IMOD)%TW0(:) = INPUTS(impGridID)%TW0(:)
2712 INPUTS(IMOD)%TFN(:,3) = INPUTS(impGridID)%TFN(:,3)
2713 wxn = WXNwrst !replace with values from restart
2717 if (ESMF_LogFoundError(rc, PASSTHRU)) return
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
2726 wxn = WXNwrst !replace with values from restart
2731 call w3setg ( imod, mdse, mdst )
2732 call w3setw ( imod, mdse, mdst )
2733 call w3seti ( imod, mdse, mdst )
2734 call wmsetm ( imod, mdse, mdst )
2736 .eq.
if ( mpi_comm_grd mpi_comm_null ) cycle
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
2745 .le.
endif !if ( twn-tw0 0 )
2749 ! -------------------------------------------------------------------- /
2750 ! Sea ice concentration
2753 i1 = FieldIndex( impFieldName, 'seaice
', rc )
2754 if (ESMF_LogFoundError(rc, PASSTHRU)) return
2756 if ( impFieldActive(i1) ) then
2757 call w3setg ( impGridID, mdse, mdst )
2758 call w3seti ( impGridID, mdse, mdst )
2765 if ( mbgFieldActive(i1) ) then
2766 call BlendImpField( impField(i1), mbgField(i1), bmskField(i1), rc=rc )
2767 if (ESMF_LogFoundError(rc, PASSTHRU)) return
2769 call FieldGather( impField(i1), nx, ny, icei, rc=rc )
2770 if (ESMF_LogFoundError(rc, PASSTHRU)) return
2772 call w3setg ( imod, mdse, mdst )
2773 call w3setw ( imod, mdse, mdst )
2774 call w3seti ( imod, mdse, mdst )
2775 call wmsetm ( imod, mdse, mdst )
2777 .eq.
if ( mpi_comm_grd mpi_comm_null ) cycle
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
2787 ! -------------------------------------------------------------------- /
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
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)
2805 Import -------------------------------------------------- /
!/ End of Get
2807 Import end subroutine Get
2808 !/ ------------------------------------------------------------------- /
2811 #define METHOD "SetExport"
2813 !> @brief Set export fields from internal data structures.
2815 !> @param gcomp Gridded component
2816 !> @param[out] rc Return code
2818 !> @author T. J. Campbell @date 09-Aug-2017
2820 subroutine SetExport ( gcomp, rc )
2822 !/ +-----------------------------------+
2823 !/ | WAVEWATCH III NOAA/NCEP |
2824 !/ | T. J. Campbell, NRL |
2826 !/ | Last update : 09-Aug-2017 |
2827 !/ +-----------------------------------+
2829 !/ 20-Jan-2017 : Origination. ( version 6.02 )
2830 !/ 09-Aug-2017 : Add ocean forcing export fields ( version 6.03 )
2834 ! Set export fields from internal data structures
2841 ! ----------------------------------------------------------------
2842 ! gcomp Type I/O Gridded component
2843 ! rc Int. O Return code
2844 ! ----------------------------------------------------------------
2846 ! 4. Subroutines used :
2848 ! Name Type Module Description
2849 ! ----------------------------------------------------------------
2851 ! ----------------------------------------------------------------
2855 ! 6. Error messages :
2865 !/ ------------------------------------------------------------------- /
2867 !/ ------------------------------------------------------------------- /
2871 type(ESMF_GridComp) :: gcomp
2872 integer,intent(out) :: rc
2874 !/ ------------------------------------------------------------------- /
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
2886 real(ESMF_KIND_R8), pointer :: farrayptr(:,:)
2888 ! -------------------------------------------------------------------- /
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)
2899 ! -------------------------------------------------------------------- /
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 )
2912 ! -------------------------------------------------------------------- /
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
2922 ! -------------------------------------------------------------------- /
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
2932 ! -------------------------------------------------------------------- /
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
2945 ! -------------------------------------------------------------------- /
2946 ! Partitioned Stokes Drift 3 2D fields
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
2971 ! -------------------------------------------------------------------- /
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
2987 ! -------------------------------------------------------------------- /
2988 ! Radiation stresses 2D
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
3003 ! -------------------------------------------------------------------- /
3004 ! cpl_scalars - grid sizes
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)
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)
3021 ! -------------------------------------------------------------------- /
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
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)
3040 !/ End of SetExport -------------------------------------------------- /
3042 end subroutine SetExport
3043 !/ ------------------------------------------------------------------- /
3046 #define METHOD "CreateImpGrid"
3048 import fields.
!> @brief Create ESMF grid for
3050 !> @param gcomp Gridded component
3051 !> @param[out] rc Return code
3053 !> @author T. J. Campbell @date 20-Jan-2017
3055 subroutine CreateImpGrid ( gcomp, rc )
3057 !/ +-----------------------------------+
3058 !/ | WAVEWATCH III NOAA/NCEP |
3059 !/ | T. J. Campbell, NRL |
3061 !/ | Last update : 20-Jan-2017 |
3062 !/ +-----------------------------------+
3064 !/ 20-Jan-2017 : Origination. ( version 6.02 )
3068 import fields
! Create ESMF grid for
3075 ! ----------------------------------------------------------------
3076 ! gcomp Type I/O Gridded component
3077 ! rc Int. O Return code
3078 ! ----------------------------------------------------------------
3080 ! 4. Subroutines used :
3082 ! Name Type Module Description
3083 ! ----------------------------------------------------------------
3085 ! ----------------------------------------------------------------
3089 ! 6. Error messages :
3099 !/ ------------------------------------------------------------------- /
3101 !/ ------------------------------------------------------------------- /
3105 type(ESMF_GridComp) :: gcomp
3106 integer,intent(out) :: rc
3108 !/ ------------------------------------------------------------------- /
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
3131 ! -------------------------------------------------------------------- /
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)
3143 ! -------------------------------------------------------------------- /
3146 ! 1.a Set grid pointers
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 )
3160 ! 1.b Compute a 2D subdomain layout based on nproc
3162 call CalcDecomp( nx, ny, nproc, impHaloWidth, .true., nxproc, nyproc, rc )
3163 if (ESMF_LogFoundError(rc, PASSTHRU)) return
3165 import fields
! 1.c Set arraySpec, staggerLoc, and indexFlag for
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
3173 ! -------------------------------------------------------------------- /
3174 import with 2d subdomain layout
! 2. Create ESMF grid for
3175 ! Note that the ESMF grid layout is dim1=X, dim2=Y
3177 import grid ! 2.a Create ESMF
3179 select case (iclose)
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
3194 impGrid = ESMF_GridCreate1PeriDim( &
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
3210 write(msg,'(a,i1,a)
') 'index closure
',iclose, &
3211 ' not supported for
import grid'
3212 call ESMF_LogWrite(trim(msg), ESMF_LOGMSG_ERROR)
3217 import grid ! 2.b Add coordinate arrays and land/sea mask to
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
3225 import grid storage
! 2.c Set flag to indicate that this processor has local
3227 call ESMF_GridGet( impGrid, localDECount=ldecnt, rc=rc )
3228 if (ESMF_LogFoundError(rc, PASSTHRU)) return
3229 .gt.
impGridIsLocal = ldecnt0
3231 import grid ! 2.d Get exclusive bounds (global index) for
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
3239 import fields
! 2.e Set halo widths for
3241 if ( impGridIsLocal ) then
3242 impHaloLWidth = (/impHaloWidth,impHaloWidth/)
3243 impHaloUWidth = (/impHaloWidth,impHaloWidth/)
3244 select case (iclose)
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
3251 .eq.
if ( elb(2)1 ) impHaloLWidth(2) = 0
3252 .eq.
if ( eub(2)ny ) impHaloUWidth(2) = 0
3255 impHaloLWidth = (/0,0/)
3256 impHaloUWidth = (/0,0/)
3259 import grid coordinates
! 2.f Set ESMF
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)
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.
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
3290 iptr(ix,iy) = maskValueLand
3296 import grid corner coordinates
! 2.h Set ESMF
3299 call ESMF_GridAddCoord( impGrid, &
3300 staggerLoc=ESMF_STAGGERLOC_CORNER, rc=rc )
3301 if (ESMF_LogFoundError(rc, PASSTHRU)) return
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)
3311 ! Add corner coordinates
3312 if ( impGridIsLocal ) then
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
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
3327 ! Adjust upper bounds for specific PEs
3330 if (eubc(1) == grid_dims(1)+1) ubx = -1
3331 if (eubc(2) == grid_dims(2)+1) uby = -1
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)
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))
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))
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)
3372 ! -------------------------------------------------------------------- /
3373 import field mask and routehandle halo update
! 3. Create
3375 import grid land/sea mask.
! 3.a Create field for
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
3383 import field halo routehandle
! 3.b Store
3385 call ESMF_FieldHaloStore( impMask, routeHandle=impHaloRH, rc=rc )
3386 if (ESMF_LogFoundError(rc, PASSTHRU)) return
3388 import field land/sea mask values and update halos
! 3.c Set
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)
3401 call ESMF_FieldHalo( impMask, impHaloRH, rc=rc )
3402 if (ESMF_LogFoundError(rc, PASSTHRU)) return
3404 ! -------------------------------------------------------------------- /
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)
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
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)
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)
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)
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)
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)
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
3499 .gt.
if (verbosity0) call ESMF_LogWrite(trim(cname)// &
3500 ': leaving createimpgrid
', ESMF_LOGMSG_INFO)
3502 !/ End of CreateImpGrid ---------------------------------------------- /
3504 end subroutine CreateImpGrid
3505 !/ ------------------------------------------------------------------- /
3508 #define METHOD "CreateExpGrid"
3510 !> @brief Create ESMF grid for export fields
3512 !> @param gcomp Gridded component
3513 !> @param[out] rc Return code
3515 !> @author T. J. Campbell @date 20-Jan-2017
3517 subroutine CreateExpGrid ( gcomp, rc )
3519 !/ +-----------------------------------+
3520 !/ | WAVEWATCH III NOAA/NCEP |
3521 !/ | T. J. Campbell, NRL |
3523 !/ | Last update : 20-Jan-2017 |
3524 !/ +-----------------------------------+
3526 !/ 20-Jan-2017 : Origination. ( version 6.02 )
3537 ! ----------------------------------------------------------------
3538 ! gcomp Type I/O Gridded component
3539 ! rc Int. O Return code
3540 ! ----------------------------------------------------------------
3542 ! 4. Subroutines used :
3544 ! Name Type Module Description
3545 ! ----------------------------------------------------------------
3547 ! ----------------------------------------------------------------
3551 ! 6. Error messages :
3559 ! !/SHRD Switch for shared / distributed memory architecture.
3564 !/ ------------------------------------------------------------------- /
3566 !/ ------------------------------------------------------------------- /
3570 type(ESMF_GridComp) :: gcomp
3571 integer,intent(out) :: rc
3573 !/ ------------------------------------------------------------------- /
3576 character(ESMF_MAXSTR) :: cname
3577 integer :: nproc, nxproc, nyproc
3578 integer, parameter :: lde = 0
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
3598 ! -------------------------------------------------------------------- /
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)
3608 ! -------------------------------------------------------------------- /
3611 ! 1.a Set grid pointers
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
3624 ! 1.b Compute a 2D subdomain layout based on nproc
3626 call CalcDecomp( nx, ny, nproc, expHaloWidth, .true., nxproc, nyproc, rc )
3627 if (ESMF_LogFoundError(rc, PASSTHRU)) return
3629 ! 1.c Set arraySpec, staggerLoc, and indexFlag for export fields
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
3640 ! 1.d Set arraySpec, staggerLoc, and indexFlag for native fields
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
3651 ! 1.e Get z-levels for 3D export fields
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)
3662 write(msg,'(i8,1f10.2)
') k, zl(k)
3663 call ESMF_LogWrite(trim(cname)//':
'//trim(msg), ESMF_LOGMSG_INFO)
3666 ! -------------------------------------------------------------------- /
3667 ! 2. Create ESMF grid for export with 2D subdomain layout
3668 ! Note that the ESMF grid layout is dim1=X, dim2=Y
3670 ! 2.a Create ESMF export grid
3672 select case (iclose)
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
3687 expGrid = ESMF_GridCreate1PeriDim( &
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
3703 write(msg,'(a,i1,a)
') 'index closure
',iclose, &
3704 ' not supported for export
grid'
3705 call ESMF_LogWrite(trim(msg), ESMF_LOGMSG_ERROR)
3710 ! 2.b Add coordinate arrays and land/sea mask to export grid
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
3718 ! 2.c Set flag to indicate that this processor has local export grid storage
3720 call ESMF_GridGet( expGrid, localDECount=ldecnt, rc=rc )
3721 if (ESMF_LogFoundError(rc, PASSTHRU)) return
3722 .gt.
expGridIsLocal = ldecnt0
3724 ! 2.d Get exclusive bounds (global index) for export grid
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
3732 ! 2.e Set halo widths for export fields
3734 if ( expGridIsLocal ) then
3735 expHaloLWidth = (/expHaloWidth,expHaloWidth/)
3736 expHaloUWidth = (/expHaloWidth,expHaloWidth/)
3737 select case (iclose)
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
3744 .eq.
if ( elb(2)1 ) expHaloLWidth(2) = 0
3745 .eq.
if ( eub(2)ny ) expHaloUWidth(2) = 0
3748 expHaloLWidth = (/0,0/)
3749 expHaloUWidth = (/0,0/)
3752 ! 2.f Set ESMF export grid coordinate
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)
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.
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
3781 iptr(ix,iy) = maskValueLand
3787 ! 2.h Set ESMF export grid corner coordinates
3790 call ESMF_GridAddCoord( expGrid, &
3791 staggerLoc=ESMF_STAGGERLOC_CORNER, rc=rc )
3792 if (ESMF_LogFoundError(rc, PASSTHRU)) return
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)
3802 ! Add corner coordinates
3803 if ( impGridIsLocal ) then
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
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
3818 ! Adjust upper bounds for specific PEs
3821 if (eubc(1) == grid_dims(1)+1) ubx = -1
3822 if (eubc(2) == grid_dims(2)+1) uby = -1
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)
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))
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))
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)
3863 ! -------------------------------------------------------------------- /
3864 ! 3. Create export field mask and routeHandle halo update
3866 ! 3.a Create field for export grid land/sea mask.
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
3874 ! 3.b Store export field halo routeHandle
3876 call ESMF_FieldHaloStore( expMask, routeHandle=expHaloRH, rc=rc )
3877 if (ESMF_LogFoundError(rc, PASSTHRU)) return
3879 ! 3.c Set export field land/sea mask values and update halos
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)
3892 call ESMF_FieldHalo( expMask, expHaloRH, rc=rc )
3893 if (ESMF_LogFoundError(rc, PASSTHRU)) return
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
3902 ! 4.a Set flag to indicate that this processor has local native grid storage
3904 .gt..and..le.
natGridIsLocal = iaproc 0 iaproc naproc
3906 ! 4.b Setup arbitrary sequence index list
3909 .eq.
if (ipass2) then
3910 allocate (arbIndexList(arbIndexCount,2), stat=rc)
3911 if (ESMF_LogFoundAllocError(rc, PASSTHRU)) return
3914 ! list local native grid non-excluded points
3915 if ( natGridIsLocal ) then
3918 isea = iaproc + (jsea-1)*naproc
3923 arbIndexCount = arbIndexCount+1
3924 .eq.
if (ipass2) then
3927 ! native grid layout: dim1=X, dim2=Y
3928 arbIndexList(arbIndexCount,1) = ix
3929 arbIndexList(arbIndexCount,2) = iy
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
3949 ! 4.c Create ESMF native grid
3951 select case (iclose)
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
3965 natGrid = ESMF_GridCreate1PeriDim( &
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
3980 write(msg,'(a,i1,a)
') 'index closure
',iclose, &
3981 ' not supported for native
grid'
3982 call ESMF_LogWrite(trim(msg), ESMF_LOGMSG_ERROR)
3987 ! 4.d Deallocate arbitrary sequence index list
3989 deallocate (arbIndexList, stat=rc)
3990 if (ESMF_LogFoundDeallocError(rc, PASSTHRU)) return
3992 ! -------------------------------------------------------------------- /
3993 ! 5. Create route handle for redist between native grid domain
3994 ! decomposition and the export grid domain decomposition
3996 ! 5.a Create temporary fields
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
4006 ! 5.b Store route handle
4008 call ESMF_FieldRedistStore( nField, eField, n2eRH, rc=rc )
4009 if (ESMF_LogFoundError(rc, PASSTHRU)) return
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
4018 ! -------------------------------------------------------------------- /
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)
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
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)
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)
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)
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)
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)
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
4113 .gt.
if (verbosity0) call ESMF_LogWrite(trim(cname)// &
4114 ': leaving createexpgrid
', ESMF_LOGMSG_INFO)
4116 !/ End of CreateExpGrid ---------------------------------------------- /
4118 end subroutine CreateExpGrid
4119 !/ ------------------------------------------------------------------- /
4122 #define METHOD "CreateImpMesh"
4124 import fields.
!> @brief Create ESMF mesh (unstructured) for
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.)
4132 !> @param gcomp Gridded component
4133 !> @param[out] rc Return code
4135 !> @author A. J. van der Westhuysen @date 28-Feb-2018
4137 subroutine CreateImpMesh ( gcomp, rc )
4139 !/ +-----------------------------------+
4140 !/ | WAVEWATCH III NOAA/NCEP |
4141 !/ | A. J. van der Westhuysen |
4143 !/ | Last update : 28-FEB_2018 |
4144 !/ +-----------------------------------+
4146 !/ 28-Feb-2018 : Origination. ( version 6.06 )
4150 import fields
! Create ESMF mesh (unstructured) for
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.)
4162 ! ----------------------------------------------------------------
4163 ! gcomp Type I/O Gridded component
4164 ! rc Int. O Return code
4165 ! ----------------------------------------------------------------
4167 ! 4. Subroutines used :
4169 ! Name Type Module Description
4170 ! ----------------------------------------------------------------
4172 ! ----------------------------------------------------------------
4176 ! 6. Error messages :
4186 !/ ------------------------------------------------------------------- /
4189 use yowNodepool, only: npa, iplg, nodes_global
4190 use yowElementpool, only: ne, ielg, INE
4193 !/ ------------------------------------------------------------------- /
4197 type(ESMF_GridComp) :: gcomp
4198 integer,intent(out) :: rc
4200 !/ ------------------------------------------------------------------- /
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
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(:)
4221 ! -------------------------------------------------------------------- /
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)
4231 ! -------------------------------------------------------------------- /
4234 ! 1.a Set grid pointers
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 )
4248 import fields
! 1.b Set arraySpec, staggerLoc, and indexFlag for
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
4256 ! -------------------------------------------------------------------- /
4257 ! 2. Create ESMF mesh for import, currently without domain decomposition
4258 ! Note that the ESMF grid layout is dim1=X, dim2=Y
4260 import mesh
! 2.a Create ESMF
4262 ! Allocate and fill the node id array.
4264 .EQV.
if ( LPDLIB .FALSE. ) then
4266 allocate(nodeIds(NX))
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))
4282 ! call ESMF_LogWrite(trim(cname)//': in createimpmesh, nodeids=
', &
4285 ! write(msg,*) trim(cname)//': nodeids(i)
',i, &
4287 ! call ESMF_LogWrite(trim(msg), ESMF_LOGMSG_INFO)
4291 ! call ESMF_LogWrite(trim(cname)//': in createimpmesh, nodeids=
', &
4294 ! write(msg,*) trim(cname)//':
',i, &
4296 ! call ESMF_LogWrite(trim(msg), ESMF_LOGMSG_INFO)
4299 ! Allocate and fill node coordinate array.
4300 ! Since this is a 2D Mesh the size is 2x the
4303 .EQV.
if ( LPDLIB .FALSE. ) then
4305 allocate(nodeCoords(2*NX))
4310 nodeCoords(pos) = xgrd(1,i)
4312 nodeCoords(pos) = ygrd(1,i)
4318 ! -------------------------------------------------------------------
4319 ! ESMF Definition: Physical coordinates of the nodes
4320 ! -------------------------------------------------------------------
4321 allocate(nodeCoords(2*npa))
4326 nodeCoords(pos) = xgrd(1,iplg(i))
4328 nodeCoords(pos) = ygrd(1,iplg(i))
4334 ! call ESMF_LogWrite(trim(cname)//': in createimpmesh, nodecoords=
', &
4337 ! write(msg,*) trim(cname)//': nodecoords(i)
',i, &
4339 ! call ESMF_LogWrite(trim(msg), ESMF_LOGMSG_INFO)
4343 ! call ESMF_LogWrite(trim(cname)//': in createimpmesh, nodecoords=
', &
4346 ! write(msg,*) trim(cname)//':
',i, &
4348 ! call ESMF_LogWrite(trim(msg), ESMF_LOGMSG_INFO)
4351 ! Allocate and fill the node owner array.
4352 ! Since this mesh is all on PET 0, it’s just set to all 0.
4354 .EQV.
if ( LPDLIB .FALSE. ) then
4356 allocate(nodeOwners(NX))
4357 nodeOwners=0 ! everything on PET 0
4360 ! -------------------------------------------------------------------
4361 ! ESMF Definition: Processor that owns the node
4362 ! -------------------------------------------------------------------
4363 allocate(nodeOwners(npa))
4364 nodeOwners=nodes_global(iplg(1:npa))%domainID-1
4367 ! call ESMF_LogWrite(trim(cname)//': in createimpmesh, nodeowners=
', &
4370 ! write(msg,*) trim(cname)//': nodeowners(i)
',i, &
4372 ! call ESMF_LogWrite(trim(msg), ESMF_LOGMSG_INFO)
4376 ! call ESMF_LogWrite(trim(cname)//': in createimpmesh, nodeowners=
', &
4379 ! write(msg,*) trim(cname)//':
',i, &
4381 ! call ESMF_LogWrite(trim(msg), ESMF_LOGMSG_INFO)
4384 ! Allocate and fill the element id array.
4386 .EQV.
if ( LPDLIB .FALSE. ) then
4388 allocate(elemIds(NTRI))
4394 ! -------------------------------------------------------------------
4395 ! ESMF Definition: The global id's of the elements resident on this processor
4397 allocate(elemids(ne))
4422 if (
lpdlib .EQV. .false. )
then
4424 allocate(elemtypes(
ntri))
4426 elemtypes(i)=esmf_meshelemtype_tri
4433 allocate(elemtypes(ne))
4435 elemtypes(i)=esmf_meshelemtype_tri
4458 if (
lpdlib .EQV. .false. )
then
4460 allocate(elemconn(3*
ntri))
4464 elemconn(pos)=
trigp(j,i)
4478 allocate(elemconn(3*ne))
4482 elemconn(pos)=ine(j,i)
4504 impmesh = esmf_meshcreate( parametricdim=2,spatialdim=2, &
4505 nodeids=nodeids, nodecoords=nodecoords, &
4506 nodeowners=nodeowners, elementids=elemids,&
4507 elementtypes=elemtypes, elementconn=elemconn, &
4509 if (esmf_logfounderror(rc, passthru))
return
4512 deallocate(nodecoords)
4513 deallocate(nodeowners)
4515 deallocate(elemtypes)
4516 deallocate(elemconn)
4518 call esmf_logwrite(trim(cname)//
': In CreateImpMesh, created impMesh', &
4522 if (verbosity.gt.0)
call esmf_logwrite(trim(cname)// &
4523 ': leaving CreateImpMesh', esmf_logmsg_info)
4527 end subroutine createimpmesh
4531 #define METHOD "CreateExpMesh"
4623 type(esmf_gridcomp) :: gcomp
4624 integer,
intent(out) :: rc
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
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(:)
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)
4677 natgridid = expgridid
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
4696 if (
lpdlib .EQV. .false. )
then
4698 allocate(nodeids(
nx))
4708 allocate(nodeids(
npa))
4735 if (
lpdlib .EQV. .false. )
then
4737 allocate(nodecoords(2*
nx))
4742 nodecoords(pos) =
xgrd(1,i)
4744 nodecoords(pos) =
ygrd(1,i)
4753 allocate(nodecoords(2*
npa))
4785 if (
lpdlib .EQV. .false. )
then
4787 allocate(nodeowners(
nx))
4794 allocate(nodeowners(
npa))
4817 if (
lpdlib .EQV. .false. )
then
4819 allocate(elemids(
ntri))
4828 allocate(elemids(
ne))
4853 if (
lpdlib .EQV. .false. )
then
4855 allocate(elemtypes(
ntri))
4857 elemtypes(i)=esmf_meshelemtype_tri
4864 allocate(elemtypes(
ne))
4866 elemtypes(i)=esmf_meshelemtype_tri
4889 if (
lpdlib .EQV. .false. )
then
4891 allocate(elemconn(3*
ntri))
4895 elemconn(pos)=
trigp(j,i)
4909 allocate(elemconn(3*
ne))
4913 elemconn(pos)=
ine(j,i)
4935 expmesh = esmf_meshcreate( parametricdim=2,spatialdim=2, &
4936 nodeids=nodeids, nodecoords=nodecoords, &
4937 nodeowners=nodeowners, elementids=elemids,&
4938 elementtypes=elemtypes, elementconn=elemconn, &
4940 if (esmf_logfounderror(rc, passthru))
return
4943 deallocate(nodecoords)
4944 deallocate(nodeowners)
4946 deallocate(elemtypes)
4947 deallocate(elemconn)
4970 if (
lpdlib .EQV. .false. )
then
4976 if (
ipass.eq.2)
then
4977 allocate (arbindexlist(arbindexcount,2), stat=rc)
4978 if (esmf_logfoundallocerror(rc, passthru))
return
4982 if ( natgridislocal )
then
4990 arbindexcount = arbindexcount+1
4991 if (
ipass.eq.2)
then
4995 arbindexlist(arbindexcount,1) = iy
4996 arbindexlist(arbindexcount,2) = ix
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
5018 deallocate (arbindexlist, stat=rc)
5019 if (esmf_logfounddeallocerror(rc, passthru))
return
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
5035 call esmf_fieldrediststore( nfield, efield, n2erh, rc=rc )
5036 if (esmf_logfounderror(rc, passthru))
return
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
5049 call esmf_logwrite(trim(cname)//
': In CreateExpMesh, created expMesh', &
5053 if (verbosity.gt.0)
call esmf_logwrite(trim(cname)// &
5054 ': leaving CreateExpMesh', esmf_logmsg_info)
5062 #define METHOD "SetupImpBmsk"
5073 subroutine setupimpbmsk( bmskField, impField, missingVal, rc )
5125 type(esmf_field) :: bmskField
5126 type(esmf_field) :: impField
5127 real(ESMF_KIND_RX) :: missingVal
5128 integer,
optional :: rc
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
5156 if (
present(rc)) rc = esmf_success
5160 wflt(k,l) = exp( -half*( real(k,esmf_kind_rx)**2 &
5161 + real(l,esmf_kind_rx)**2 ) )
5168 call esmf_fieldget( impfield, name=fnm, rc=rc )
5169 if (esmf_logfounderror(rc, passthru))
return
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
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
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
5200 cmsk(i,j) = bmsk(i,j)
5204 #if defined(TEST_WMESMFMD) || defined(TEST_WMESMFMD_SETUPIMPBMSK)
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
5212 iter_loop:
do iter = iter0,niter
5214 call esmf_fieldhalo( bmskfield, imphalorh, rc=rc )
5215 if (esmf_logfounderror(rc, passthru))
return
5217 if ( impgridislocal )
then
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
5227 l_loop0:
do l = -1,1
5229 if ( jj.lt.tlb(2).or.jj.gt.tub(2) ) cycle l_loop0
5230 k_loop0:
do k = -1,1
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
5243 l_loop:
do l = -nsig,nsig
5245 if ( jj.lt.tlb(2).or.jj.gt.tub(2) ) cycle l_loop
5246 k_loop:
do k = -nsig,nsig
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)
5254 if ( wsum.gt.zero ) cmsk(i,j) = bsum/wsum
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)
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
5282 call esmf_fielddestroy( cmskfield, rc=rc )
5283 if (esmf_logfounderror(rc, passthru))
return
5291 #define METHOD "BlendImpField"
5302 subroutine blendimpfield( impField, mbgField, bmskField, rc )
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
5362 real(ESMF_KIND_RX),
parameter :: one = 1.0
5363 integer,
parameter :: lde = 0
5365 integer :: elb(2), eub(2)
5366 real(ESMF_KIND_RX),
pointer :: mptr(:,:), dptr(:,:), sptr(:,:)
5367 real(ESMF_KIND_RX),
pointer :: bmsk(:,:)
5372 if (
present(rc)) rc = esmf_success
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
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)
5400 end subroutine blendimpfield
5404 #define METHOD "SetupImpMmsk"
5417 subroutine setupimpmmsk( mmskField, impField, fillVal, mskCreated, rc )
5471 type(esmf_field) :: mmskField
5472 type(esmf_field) :: impField
5473 real(ESMF_KIND_RX) :: fillVal
5474 logical :: mskCreated
5475 integer,
optional :: rc
5480 integer,
parameter :: lde = 0
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
5494 if ( mskcreated )
return
5500 call esmf_fieldget( impfield, name=fnm, rc=rc )
5501 if (esmf_logfounderror(rc, passthru))
return
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
5517 if ( impgridislocal )
then
5518 do j = elb(2),eub(2)
5519 do i = elb(1),eub(1)
5521 if (dptr(i,j).lt.fillval)
then
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
5542 end subroutine setupimpmmsk
5546 #define METHOD "FieldFill"
5556 subroutine fieldfill(field, fillVal, rc)
5608 type(esmf_field) :: field
5609 real(ESMF_KIND_RX) :: fillVal
5610 integer,
optional :: rc
5615 integer :: ldecnt, lde, i, j, k
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
5629 if (
present(rc)) rc = esmf_success
5631 call esmf_vmwtime(wstime)
5633 call esmf_fieldget(field, localdecount=ldecnt, rank=rank, rc=rc)
5634 if (esmf_logfounderror(rc, passthru))
return
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')
5644 call esmf_fieldget(field, localde=lde, farrayptr=dptr1, &
5645 exclusivelbound=lb1, exclusiveubound=ub1, rc=rc)
5646 if (esmf_logfounderror(rc, passthru))
return
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
5652 call esmf_fieldget(field, localde=lde, farrayptr=dptr3, &
5653 exclusivelbound=lb3, exclusiveubound=ub3, rc=rc)
5654 if (esmf_logfounderror(rc, passthru))
return
5658 dptr1(lb1(1):ub1(1)) = fillval
5659 elseif (rank.eq.2)
then
5660 dptr2(lb2(1):ub2(1),lb2(2):ub2(2)) = fillval
5662 dptr3(lb3(1):ub3(1),lb3(2):ub3(2),lb3(3):ub3(3)) = fillval
5667 call esmf_vmwtime(wftime)
5668 wtime(iwt) = wtime(iwt) + wftime - wstime
5669 wtcnt(iwt) = wtcnt(iwt) + 1
5673 end subroutine fieldfill
5677 #define METHOD "FieldGather"
5691 subroutine fieldgather(field, n1, n2, fout, rc)
5750 type(esmf_field) :: field
5753 integer,
optional :: rc
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)
5764 real(ESMF_KIND_R8),
pointer :: fldptr(:)
5766 integer,
parameter :: iwt=9
5767 real(8) :: wstime, wftime
5772 if (
present(rc)) rc = esmf_success
5774 call esmf_vmwtime(wstime)
5780 call esmf_fieldgather( field, floc, rootpet=0, vm=vm, rc=rc )
5781 if (esmf_logfounderror(rc, passthru))
return
5784 floc1dary(i+(j-1)*n1) = floc(i,j)
5787 call esmf_vmbroadcast( vm, bcstdata=floc1dary, count=count, rootpet=0, rc=rc)
5788 if (esmf_logfounderror(rc, passthru))
return
5791 fout(i,j) = floc1dary(i+(j-1)*n1)
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
5802 if (
lpdlib .EQV. .false. )
then
5805 fout(k,1) = floc1d(k)
5811 do ip = 1,
rank(ir)%np
5813 fout(
rank(ir)%iplg(ip),1) = floc1d(count)
5834 call esmf_vmwtime(wftime)
5835 wtime(iwt) = wtime(iwt) + wftime - wstime
5836 wtcnt(iwt) = wtcnt(iwt) + 1
5841 end subroutine fieldgather
5845 #define METHOD "FieldIndex"
5856 function fieldindex ( fnameList, fname, rc )
result (indx)
5908 character (len=*) :: fnamelist(:)
5909 character (len=*) :: fname
5921 check = lbound(fnamelist,1) - 1
5923 do i = lbound(fnamelist,1),ubound(fnamelist,1)
5924 if ( trim(fnamelist(i)).eq.trim(fname) )
then
5929 if ( indx.eq.
check )
then
5930 call esmf_logseterror(esmf_failure, rctoreturn=rc, &
5931 msg=
'FieldIndex: input name ('//fname//
') not in list')
5940 #define METHOD "PrintTimers"
5951 subroutine printtimers ( cname, wtnam, wtcnt, wtime )
6003 character(*) :: cname
6004 character(*) :: wtnam(:)
6011 character(128) :: msg
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)
6027 1
format(a,
': wtime: ',a20,a10,a14)
6028 2
format(a,
': wtime: ',a20,i10,e14.6)
6032 end subroutine printtimers
6036 #define METHOD "CalcDecomp"
6051 subroutine calcdecomp ( nx, ny, nproc, npmin, adjust, nxproc, nyproc, rc )
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
6117 integer,
parameter :: k = 4
6118 integer :: mproc, n, nfac, irp
6119 real(k) :: gr, rp, pr, diff, npx, npy
6120 character(256) :: msg
6126 if (
nx.gt.
ny )
then
6127 gr = real(
nx,k)/real(
ny,k)
6129 gr = real(
ny,k)/real(
nx,k)
6135 irp = int(sqrt(real(mproc,k)))
6139 if ( mod(mproc,n).ne.0 ) cycle
6140 pr = real(n**2,k)/real(mproc,k)
6141 if ( abs(gr-pr) < diff )
then
6146 if (
nx.gt.
ny )
then
6154 npx =
nx/real(nxproc,k)
6155 npy =
ny/real(nyproc,k)
6156 if (.not.adjust)
exit mproc_loop
6158 if ( npx.ge.npmin .and. npy.ge.npmin )
then
6161 if ( mproc.gt.1 )
then
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)
6179 end subroutine calcdecomp
6183 #define METHOD "GetEnvValue"
6193 subroutine getenvvalue ( cenv, cval, rc )
6244 character(*) :: cenv
6245 character(*) :: cval
6251 character(256) :: msg
6252 integer :: length, istat
6257 call get_environment_variable( name=trim(cenv),
value=cval, &
6258 length=length, trim_name=.false., status=istat )
6259 if (istat.lt.0)
then
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)
6267 elseif (istat.gt.0)
then
6273 if (length.eq.0) cval=
" "
6277 end subroutine getenvvalue
6281 #define METHOD "GetZlevels"
6289 subroutine getzlevels ( rc )
6343 character(256) :: msg
6344 integer :: k, iunit, ierr
6350 if (len_trim(zlfile).eq.0 .or. trim(zlfile) .eq.
'none')
then
6353 allocate(zl(nz), stat=rc)
6354 if (esmf_logfoundallocerror(rc, passthru))
return
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)
6364 msg =
"failed opening "//trim(zlfile)
6365 call esmf_logwrite(trim(msg), esmf_logmsg_error)
6369 read(iunit, fmt=*, iostat=ierr) nz
6371 msg =
"read nz failed: "//trim(zlfile)
6372 call esmf_logwrite(trim(msg), esmf_logmsg_error)
6376 allocate(zl(nz), stat=rc)
6377 if (esmf_logfoundallocerror(rc, passthru))
return
6379 read(iunit, fmt=*, iostat=ierr) zl(k)
6381 msg =
"read zl failed: "//trim(zlfile)
6382 call esmf_logwrite(trim(msg), esmf_logmsg_error)
6393 end subroutine getzlevels
6397 #define METHOD "CalcCharnk"
6406 subroutine calccharnk ( chkField, rc )
6456 type(esmf_field) :: chkfield
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
6476 chknfield = esmf_fieldcreate( natgrid, natarrayspec2d, &
6477 staggerloc=natstaggerloc, rc=rc )
6478 if (esmf_logfounderror(rc, passthru))
return
6480 call fieldfill( chknfield, zerovalue, rc=rc )
6481 if (esmf_logfounderror(rc, passthru))
return
6483 if ( natgridislocal )
then
6485 call esmf_fieldget( chknfield, farrayptr=chkn, rc=rc )
6486 if (esmf_logfounderror(rc, passthru))
return
6488 jsea_loop:
do jsea = 1,
nseal
6495 if ( firstcall )
then
6504 emean, fmean, fmean1,
wnmean, amax, &
6505 u10(isea),
u10d(isea), ustar, ustdr, tauwx, &
6506 tauwy, cd, z0,
charn(jsea), llws, fmeanws )
6515 emean, fmean, fmean1,
wnmean, amax, &
6516 u10(isea),
u10d(isea), ustar, ustdr, tauwx, &
6517 tauwy, cd, z0,
charn(jsea), llws, fmeanws, &
6521 chkn(jsea) =
charn(jsea)
6526 call esmf_fieldredist( chknfield, chkfield, n2erh, rc=rc )
6527 if (esmf_logfounderror(rc, passthru))
return
6529 call esmf_fielddestroy( chknfield, rc=rc )
6530 if (esmf_logfounderror(rc, passthru))
return
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
6543 end subroutine calccharnk
6547 #define METHOD "CalcRoughl"
6556 subroutine calcroughl ( wrlField, rc )
6606 type(esmf_field) :: wrlfield
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
6626 wrlnfield = esmf_fieldcreate( natgrid, natarrayspec2d, &
6627 staggerloc=natstaggerloc, rc=rc )
6628 if (esmf_logfounderror(rc, passthru))
return
6630 call fieldfill( wrlnfield, zerovalue, rc=rc )
6631 if (esmf_logfounderror(rc, passthru))
return
6633 if ( natgridislocal )
then
6635 call esmf_fieldget( wrlnfield, farrayptr=wrln, rc=rc )
6636 if (esmf_logfounderror(rc, passthru))
return
6638 jsea_loop:
do jsea = 1,
nseal
6647 IF (
mapsta(iy,ix) .EQ. 1 )
THEN
6648 if ( firstcall )
then
6657 emean, fmean, fmean1,
wnmean, amax, &
6658 u10(isea),
u10d(isea), ustar, ustdr, tauwx, &
6659 tauwy, cd, z0,
charn(jsea), llws, fmeanws )
6668 emean, fmean, fmean1,
wnmean, amax, &
6669 u10(isea),
u10d(isea), ustar, ustdr, tauwx, &
6670 tauwy, cd, z0,
charn(jsea), llws, fmeanws, &
6680 call esmf_fieldredist( wrlnfield, wrlfield, n2erh, rc=rc )
6681 if (esmf_logfounderror(rc, passthru))
return
6683 call esmf_fielddestroy( wrlnfield, rc=rc )
6684 if (esmf_logfounderror(rc, passthru))
return
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
6697 end subroutine calcroughl
6701 #define METHOD "CalcBotcur"
6715 subroutine calcbotcur ( a, wbxField, wbyField, wbpField, rc )
6798 type(esmf_field) :: wbxfield
6799 type(esmf_field) :: wbyfield
6800 type(esmf_field) :: wbpfield
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
6811 real(8),
parameter :: kdmin = 1e-7
6813 real(8),
parameter :: kdmax = 18.0
6814 integer :: isea, jsea, ik, ith
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
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
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
6843 if ( natgridislocal )
then
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
6855 jsea_loop:
do jsea = 1,
nseal
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))
6875 ik_loop:
do ik = 1,
nk
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)
6884 fack =
dden(ik)/
cg(ik,isea)
6885 kd = max(kdmin,min(kdmax,
wn(ik,isea)*depth))
6886 fkd = fack/sinh(kd)**2
6888 ubr = ubr + aka*
sig2(ik)*fkd
6889 ubx = ubx + akx*
sig2(ik)*fkd
6890 uby = uby + aky*
sig2(ik)*fkd
6892 if ( abr.le.zero .or. ubr.le.zero ) cycle jsea_loop
6895 dir = atan2(uby,ubx)
6896 wbxn(jsea) = ubr*cos(dir)
6897 wbyn(jsea) = ubr*sin(dir)
6898 wbpn(jsea) =
tpi*abr/ubr
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
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
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
6935 end subroutine calcbotcur
6939 #define METHOD "CalcRadstr2D"
6952 subroutine calcradstr2d ( a, sxxField, sxyField, syyField, rc )
7030 type(esmf_field) :: sxxfield
7031 type(esmf_field) :: sxyfield
7032 type(esmf_field) :: syyfield
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
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
7069 if (
lpdlib .EQV. .false. )
then
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
7086 if (
lpdlib .EQV. .false. )
then
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
7098 if ( natgridislocal )
then
7101 if (
lpdlib .EQV. .false. )
then
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
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
7124 if (
lpdlib .EQV. .false. )
then
7126 jsea_loop:
do jsea = 1,
nseal
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)
7142 ik_loop:
do ik = 1,
nk
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)
7153 fack =
dden(ik)/
cg(ik,isea)
7154 sxxs = sxxs + akxx*fack
7155 sxys = sxys + akxy*fack
7156 syys = syys + akyy*fack
7158 facs = (one+
fte/
cg(
nk,isea))*facd
7159 sxxn(jsea) = sxxs*facs
7160 sxyn(jsea) = sxys*facs
7161 syyn(jsea) = syys*facs
7166 jsea_loop2:
do jsea = 1,
np
7169 sxxn(jsea) =
sxx(jsea)
7170 sxyn(jsea) =
sxy(jsea)
7171 syyn(jsea) =
syy(jsea)
7181 if (
lpdlib .EQV. .false. )
then
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
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
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
7215 end subroutine calcradstr2d
7219 #define METHOD "CalcStokes3D"
7302 real :: a(nth,nk,0:nseal)
7303 type(esmf_field) :: usxField
7304 type(esmf_field) :: usyField
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
7315 real(8),
parameter :: kdmin = 1e-7
7317 real(8),
parameter :: kdmax = 18.0
7319 real(8),
parameter :: kdmin_us3d = 1e-3
7320 real(8),
parameter :: kdmax_us3d = 6.0
7321 integer :: isea, jsea, ik, ith, iz
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
7331 #define ESMF_ARBSEQ_WORKAROUND
7332 #ifdef ESMF_ARBSEQ_WORKAROUND
7333 type(esmf_distgrid) :: natDistGrid
7334 type(esmf_array) :: usxnArray, usynArray
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
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
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
7374 if ( natgridislocal )
then
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
7381 allocate( fack(1:nk) )
7382 fack(1:nk) =
dden(1:nk) *
sig(1:nk)
7384 jsea_loop:
do jsea = 1,nseal
7391 if (
dw(isea).le.zero ) cycle jsea_loop
7392 depth = max(
dmin,
dw(isea))
7395 #ifdef USE_W3OUTG_FOR_EXPORT
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)
7405 fac2 = fac1*exp(two*kz)
7407 uzx(iz) = uzx(iz) +
us3d(jsea,ik )*fac2
7408 uzy(iz) = uzy(iz) +
us3d(jsea,nk+ik)*fac2
7412 ik_loop:
do ik = 1,nk
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)
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
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))
7436 uzx(iz) = uzx(iz) + akx*fac3
7437 uzy(iz) = uzy(iz) + aky*fac3
7441 usxn(:,jsea) = uzx(:)
7442 usyn(:,jsea) = uzy(:)
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
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
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
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
7481 #define METHOD "CalcPStokes"
7496 subroutine calcpstokes ( a, p1xField, p1yField, p2xField, &
7497 p2yField, p3xField, p3yField, rc )
7552 real :: a(nth,nk,0:nseal)
7553 type(esmf_field) :: p1xField,p2xField,p3xField
7554 type(esmf_field) :: p1yField,p2yField,p3yField
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
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
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
7605 if ( natgridislocal )
then
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
7622 jsea_loop:
do jsea = 1,nseal
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)
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
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
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
7690 end subroutine calcpstokes
7694 #define METHOD "ReadFromFile"
7708 subroutine readfromfile (idfld, fldwx, fldwy, time0, timen, rc)
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
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(:,:)
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
7799 call wmuget(mdse, mdst, mdsf,
'INP')
7800 call wmuset(mdse, mdst, mdsf, .true., desc=
'Input data file')
7803 call w3fldo(
'READ', idfld, mdsf, mdst, mdse, nx, ny,
gtype, ierr)
7805 write(logmsg,*)
"Error in opening "//idfld//
", iostat = ", ierr
7806 call esmf_logwrite(trim(logmsg), esmf_logmsg_error)
7829 read(mdsf, iostat=ierr) tsstr, tsfld, nxt, nyt, &
7830 gtypet, filler(1:2), tideflag
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)
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)
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