From a0bd4a6af8aa7ddea2f5991be16e048662e5c2a1 Mon Sep 17 00:00:00 2001 From: pjpegion Date: Wed, 2 Dec 2020 15:36:03 +0000 Subject: [PATCH 01/13] add ocean stochastic random patterns --- CMakeLists.txt | 1 - compns_stochy.F90 | 156 ++++++++++++++- dezouv_stochy.f | 1 - dozeuv_stochy.f | 1 - epslon_stochy.f | 1 - four_to_grid_stochy.F | 225 +--------------------- get_lats_node_a_stochy.f | 1 - get_ls_node_stochy.f | 6 +- get_stochy_pattern.F90 | 350 +++++++++++++++++----------------- getcon_lag_stochy.f | 9 +- getcon_spectral.F90 | 27 +-- gozrineo_stochy.f | 5 +- initialize_spectral_mod.F90 | 43 ++--- lndp_apply_perts.F90 | 8 +- makefile | 1 - pln2eo_stochy.f | 6 +- setlats_a_stochy.f | 3 +- setlats_lag_stochy.f | 27 +-- spectral_layout.F90 | 86 ++++----- stochastic_physics.F90 | 174 ++++++++++++++--- stochy_data_mod.F90 | 144 +++++++++++++- stochy_internal_state_mod.F90 | 73 +++---- stochy_namelist_def.F90 | 10 +- stochy_resol_def.f | 46 ----- sumfln_stochy.f | 57 ++---- 25 files changed, 763 insertions(+), 698 deletions(-) delete mode 100644 stochy_resol_def.f diff --git a/CMakeLists.txt b/CMakeLists.txt index 3d94ec2..66b18a6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,7 +22,6 @@ add_library( ./plumes.f90 ./stochy_gg_def.f - ./stochy_resol_def.f ./stochy_layout_lag.f ./four_to_grid_stochy.F ./glats_stochy.f diff --git a/compns_stochy.F90 b/compns_stochy.F90 index b61e894..d078050 100644 --- a/compns_stochy.F90 +++ b/compns_stochy.F90 @@ -60,7 +60,9 @@ subroutine compns_stochy (me,sz_nml,input_nml_file,fn_nml,nlunit,deltim,iret) shum_lscale,fhstoch,stochini,skeb_varspect_opt,sppt_sfclimit, & skeb,skeb_tau,skeb_vdof,skeb_lscale,iseed_skeb,skeb_vfilt,skeb_diss_smooth, & skeb_sigtop1,skeb_sigtop2,skebnorm,sppt_sigtop1,sppt_sigtop2,& - shum_sigefold,spptint,shumint,skebint,skeb_npass,use_zmtnblck,new_lscale + shum_sigefold,spptint,shumint,skebint,skeb_npass,use_zmtnblck,new_lscale, & + epbl,epbl_lscale,epbl_tau,iseed_epbl, & + ocnsppt,ocnsppt_lscale,ocnsppt_tau,iseed_ocnsppt namelist /nam_sfcperts/lndp_type,lndp_var_list, lndp_prt_list, iseed_lndp, & lndp_tau,lndp_lscale @@ -326,4 +328,156 @@ subroutine compns_stochy (me,sz_nml,input_nml_file,fn_nml,nlunit,deltim,iret) return end subroutine compns_stochy + subroutine compns_stochy_ocn (deltim,iret) +!$$$ Subprogram Documentation Block +! +! Subprogram: compns Check and compute namelist frequencies +! Prgmmr: Iredell Org: NP23 Date: 1999-01-26 +! +! Abstract: This subprogram checks global spectral model namelist +! frequencies in hour units for validity. If they are valid, +! then the frequencies are computed in timestep units. +! The following rules are applied: +! 1. the timestep must be positive; +! +! Program History Log: +! 2016-10-11 Phil Pegion make the stochastic physics stand alone +! +! Usage: call compns_stochy (me,deltim,nlunit, stochy_namelist,iret) +! Input Arguments: +! deltim - real timestep in seconds +! Output Arguments: +! iret - integer return code (0 if successful or +! between 1 and 8 for which rule above was broken) +! stochy_namelist +! +! Attributes: +! Language: Fortran 90 +! +!$$$ + + + use stochy_namelist_def + use mpp_mod ,only: mpp_pe,mpp_root_pe + + implicit none + + + real, intent(in) :: deltim + integer, intent(out) :: iret + real tol,l_min + real :: rerth,circ + integer k,ios,nlunit + integer,parameter :: four=4 + +! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +! + namelist /nam_stochy/ntrunc,lon_s,lat_s,sppt,sppt_tau,sppt_lscale,sppt_logit, & + iseed_shum,iseed_sppt,shum,shum_tau, & + shum_lscale,fhstoch,stochini,skeb_varspect_opt,sppt_sfclimit, & + skeb,skeb_tau,skeb_vdof,skeb_lscale,iseed_skeb,skeb_vfilt,skeb_diss_smooth, & + skeb_sigtop1,skeb_sigtop2,skebnorm,sppt_sigtop1,sppt_sigtop2,& + shum_sigefold,spptint,shumint,skebint,skeb_npass,use_zmtnblck,new_lscale, & + epbl,epbl_lscale,epbl_tau,iseed_epbl, & + ocnsppt,ocnsppt_lscale,ocnsppt_tau,iseed_ocnsppt + + namelist /nam_sfcperts/lndp_type,lndp_var_list, lndp_prt_list, iseed_lndp, & + lndp_tau,lndp_lscale + + + rerth =6.3712e+6 ! radius of earth (m) + tol=0.01 ! tolerance for calculations + nlunit=322 +! spectral resolution defintion + ntrunc=-999 + lon_s=-999 + lat_s=-999 + ! can specify up to 5 values for the stochastic physics parameters + ! (each is an array of length 5) + epbl = -999. ! stochastic physics tendency amplitude + ocnsppt = -999. ! stochastic physics tendency amplitude +! logicals + do_epbl = .false. + do_ocnsppt = .false. + new_lscale = .false. + epblint = 0 + ocnspptint = 0 + epbl_tau = -999. ! time scales + ocnsppt_tau = -999. ! time scales + epbl_lscale = -999. ! length scales + ocnsppt_lscale = -999. ! length scales + iseed_epbl = 0 ! random seeds (if 0 use system clock) + iseed_epbl2 = 0 ! random seeds (if 0 use system clock) + iseed_ocnsppt = 0 ! random seeds (if 0 use system clock) + rewind (nlunit) + open (unit=nlunit, file='input.nml', READONLY, status='OLD', iostat=ios) + read(nlunit,nam_stochy) + + if (mpp_pe()==mpp_root_pe()) then + print *,' in compns_stochy_ocn' + endif + +! PJP stochastic physics additions + IF (epbl(1) > 0 ) THEN + do_epbl=.true. + ENDIF + IF (ocnsppt(1) > 0 ) THEN + do_ocnsppt=.true. + ENDIF +! compute frequencty to update random pattern + IF (epblint == 0.) epblint=deltim + nsepbl=nint(epblint/deltim) ! epblint in seconds + IF(nsepbl<=0 .or. abs(nsepbl-epblint/deltim)>tol) THEN + WRITE(0,*) "ePBL interval is invalid",epblint + iret=9 + return + ENDIF + IF (ocnspptint == 0.) ocnspptint=deltim + nsocnsppt=nint(ocnspptint/deltim) ! ocnspptint in seconds + IF(nsocnsppt<=0 .or. abs(nsocnsppt-ocnspptint/deltim)>tol) THEN + WRITE(0,*) "ePBL interval is invalid",ocnspptint + iret=9 + return + ENDIF +!calculate ntrunc if not supplied + if (ntrunc .LT. 1) then + if (mpp_pe()==mpp_root_pe()) print*,'ntrunc not supplied, calculating' + circ=2*3.1415928*rerth ! start with lengthscale that is circumference of the earth + l_min=circ + do k=1,5 + if (epbl(k).GT.0) l_min=min(epbl_lscale(k),l_min) + if (ocnsppt(k).GT.0) l_min=min(ocnsppt_lscale(k),l_min) + enddo + !ntrunc=1.5*circ/l_min + ntrunc=circ/l_min + if (mpp_pe()==mpp_root_pe()) print*,'ntrunc calculated from l_min',l_min,ntrunc + endif + ! ensure lat_s is a mutiple of 4 with a reminader of two + ntrunc=INT((ntrunc+1)/four)*four+2 + if (mpp_pe()==mpp_root_pe()) print*,'NOTE ntrunc adjusted for even nlats',ntrunc + +! set up gaussian grid for ntrunc if not already defined. + if (lon_s.LT.1 .OR. lat_s.LT.1) then + lat_s=ntrunc*1.5+1 + lon_s=lat_s*2+4 +! Grid needs to be larger since interpolation is bi-linear + lat_s=lat_s*2 + lon_s=lon_s*2 + if (mpp_pe()==mpp_root_pe()) print*,'gaussian grid not set, defining here',lon_s,lat_s + endif +! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +! +! All checks are successful. +! + if (mpp_pe()==mpp_root_pe()) then + print *, 'ocean stochastic physics' + print *, ' do_epbl : ', do_epbl + print *, ' do_ocnsppt : ', do_ocnsppt + endif + iret = 0 + if (iseed_epbl(1) > 0) iseed_epbl2(1)=iseed_epbl(1)-1234567 +! + return + end subroutine compns_stochy_ocn + end module compns_stochy_mod diff --git a/dezouv_stochy.f b/dezouv_stochy.f index 25e896c..e01e170 100644 --- a/dezouv_stochy.f +++ b/dezouv_stochy.f @@ -14,7 +14,6 @@ subroutine dezouv_stochy(dev,zod,uev,vod,epsedn,epsodn, cc cc - use stochy_resol_def use spectral_layout_mod use kinddef implicit none diff --git a/dozeuv_stochy.f b/dozeuv_stochy.f index e67821c..c4a177b 100644 --- a/dozeuv_stochy.f +++ b/dozeuv_stochy.f @@ -12,7 +12,6 @@ module dozeuv_stochy_mod subroutine dozeuv_stochy(dod,zev,uod,vev,epsedn,epsodn, & snnp1ev,snnp1od,ls_node) cc - use stochy_resol_def use spectral_layout_mod use kinddef implicit none diff --git a/epslon_stochy.f b/epslon_stochy.f index 55ef0d1..919a2e1 100644 --- a/epslon_stochy.f +++ b/epslon_stochy.f @@ -10,7 +10,6 @@ module epslon_stochy_mod subroutine epslon_stochy(epse,epso,epsedn,epsodn, & ls_node) cc - use stochy_resol_def use spectral_layout_mod use kinddef implicit none diff --git a/four_to_grid_stochy.F b/four_to_grid_stochy.F index 358be21..3453968 100644 --- a/four_to_grid_stochy.F +++ b/four_to_grid_stochy.F @@ -1,18 +1,17 @@ !>@brief The module 'four_to_grid_mod' contains the subroute four_to_grid module four_to_grid_mod - use spectral_layout_mod, only: num_parthds_stochy => ompthreads implicit none contains -!>@brief The subroutine 'epslon_stochy' calculate coeffients for use in spectral space +!>@brief The subroutine 'four_to_grd' calculate real values form fourrier coefficients !>@details This code is taken from the legacy spectral GFS subroutine four_to_grid(syn_gr_a_1,syn_gr_a_2, & lon_dim_coef,lon_dim_grid,lons_lat,lot) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - use kinddef + use machine implicit none !! real(kind=kind_dbl_prec) syn_gr_a_1(lon_dim_coef,lot) @@ -30,12 +29,6 @@ subroutine four_to_grid(syn_gr_a_1,syn_gr_a_2, integer ibmsign integer init #endif - integer lot_thread - integer num_threads - integer nvar_thread_max - integer nvar_1 - integer nvar_2 - integer thread #ifdef MKL include "fftw/fftw3.f" integer NULL @@ -44,40 +37,11 @@ subroutine four_to_grid(syn_gr_a_1,syn_gr_a_2, external scrft #endif !________________________________________________________ - num_threads = min(num_parthds_stochy,lot) - nvar_thread_max = (lot+num_threads-1)/num_threads - if ( kind_dbl_prec == 8 ) then !------------------------------------ #ifdef MKL -!$omp parallel do num_threads(num_threads) -!$omp+shared(syn_gr_a_1,syn_gr_a_2,lons_lat) -!$omp+shared(lon_dim_coef,lon_dim_grid) -!$omp+shared(lot,num_threads,nvar_thread_max) -!$omp+private(thread,nvar_1,nvar_2,lot_thread,plan) -#else -!$omp parallel do num_threads(num_threads) -!$omp+shared(syn_gr_a_1,syn_gr_a_2,lons_lat) -!$omp+shared(lon_dim_coef,lon_dim_grid) -!$omp+shared(lot,num_threads,nvar_thread_max) -!$omp+shared(ibmsign,scale_ibm) -!$omp+private(thread,nvar_1,nvar_2,lot_thread,init,aux1crs) -#endif - do thread=1,num_threads ! start of thread loop .............. - nvar_1=(thread-1)*nvar_thread_max + 1 - nvar_2=min(nvar_1+nvar_thread_max-1,lot) - - lot_thread=nvar_2 - nvar_1 + 1 - - if (nvar_2 >= nvar_1) then -#ifdef MKL - !call dfftw_plan_many_dft_c2r( - ! plan, 1, N, m, & - ! X, NULL, 1, dimx, & - ! Y, NULL, 1, dimy, & - ! fftw_flag) call dfftw_plan_many_dft_c2r( & - & plan, 1, lons_lat, lot_thread, & + & plan, 1, lons_lat, lot, & & syn_gr_a_1, NULL, 1, size(syn_gr_a_1,dim=1), & & syn_gr_a_2, NULL, 1, size(syn_gr_a_2,dim=1), & & FFTW_ESTIMATE) @@ -89,192 +53,21 @@ subroutine four_to_grid(syn_gr_a_1,syn_gr_a_2, scale_ibm = 1.0d0 call dcrft(init, - & syn_gr_a_1(1,nvar_1) ,lon_dim_coef/2, - & syn_gr_a_2(1,nvar_1) ,lon_dim_grid, - & lons_lat,lot_thread,ibmsign,scale_ibm, + & syn_gr_a_1(1,1) ,lon_dim_coef/2, + & syn_gr_a_2(1,1) ,lon_dim_grid, + & lons_lat,lot,ibmsign,scale_ibm, & aux1crs,22000, & aux1crs(22001),20000) init = 0 call dcrft(init, - & syn_gr_a_1(1,nvar_1) ,lon_dim_coef/2, - & syn_gr_a_2(1,nvar_1) ,lon_dim_grid, - & lons_lat,lot_thread,ibmsign,scale_ibm, + & syn_gr_a_1(1,1) ,lon_dim_coef/2, + & syn_gr_a_2(1,1) ,lon_dim_grid, + & lons_lat,lot,ibmsign,scale_ibm, & aux1crs,22000, & aux1crs(22001),20000) #endif - endif - - enddo ! fin thread loop ...................................... - else !------------------------------------------------------------ -#ifdef MKL -!$omp parallel do num_threads(num_threads) -!$omp+shared(syn_gr_a_1,syn_gr_a_2,lons_lat) -!$omp+shared(lon_dim_coef,lon_dim_grid) -!$omp+shared(lot,num_threads,nvar_thread_max) -!$omp+private(thread,nvar_1,nvar_2,lot_thread,plan) -#else -!$omp parallel do num_threads(num_threads) -!$omp+shared(syn_gr_a_1,syn_gr_a_2,lons_lat) -!$omp+shared(lon_dim_coef,lon_dim_grid) -!$omp+shared(lot,num_threads,nvar_thread_max) -!$omp+shared(ibmsign,scale_ibm) -!$omp+private(thread,nvar_1,nvar_2,lot_thread,init,aux1crs) -#endif - do thread=1,num_threads ! start of thread loop .............. - nvar_1 = (thread-1)*nvar_thread_max + 1 - nvar_2 = min(nvar_1+nvar_thread_max-1,lot) - - lot_thread = nvar_2 - nvar_1 + 1 - - if (nvar_2 >= nvar_1) then -#ifdef MKL - !call sfftw_plan_many_dft_c2r( - ! plan, 1, N, m, & - ! X, NULL, 1, dimx, & - ! Y, NULL, 1, dimy, & - ! fftw_flag) - call sfftw_plan_many_dft_c2r( & - & plan, 1, lons_lat, lot_thread, & - & syn_gr_a_1, NULL, 1, size(syn_gr_a_1,dim=1), & - & syn_gr_a_2, NULL, 1, size(syn_gr_a_2,dim=1), & - & FFTW_ESTIMATE) - call sfftw_execute(plan) - call sfftw_destroy_plan(plan) -#else - init = 1 - ibmsign = -1 - scale_ibm = 1.0d0 - call scrft(init, - & syn_gr_a_1(1,nvar_1) ,lon_dim_coef/2, - & syn_gr_a_2(1,nvar_1) ,lon_dim_grid, - & lons_lat,lot_thread,ibmsign,scale_ibm, - & aux1crs,22000, - & aux1crs(22001),20000, - & aux1crs(22001),0) - init = 0 - call scrft(init, - & syn_gr_a_1(1,nvar_1) ,lon_dim_coef/2, - & syn_gr_a_2(1,nvar_1) ,lon_dim_grid, - & lons_lat,lot_thread,ibmsign,scale_ibm, - & aux1crs,22000, - & aux1crs(22001),20000, - & aux1crs(22001),0) -#endif - endif - enddo ! fin thread loop ...................................... - endif !----------------------------------------------------------- -!! - return - end - subroutine grid_to_four(anl_gr_a_2,anl_gr_a_1, - & lon_dim_grid,lon_dim_coef,lons_lat,lot) -!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - use kinddef - implicit none -!! - real(kind=kind_dbl_prec) anl_gr_a_2(lon_dim_grid,lot) - real(kind=kind_dbl_prec) anl_gr_a_1(lon_dim_coef,lot) - integer lon_dim_grid - integer lon_dim_coef - integer lons_lat - integer lot -!________________________________________________________ - real(kind=kind_dbl_prec) aux1crs(42002) - real(kind=kind_dbl_prec) scale_ibm,rone - integer ibmsign - integer init - integer lot_thread - integer num_threads - integer nvar_thread_max - integer nvar_1,nvar_2 - integer thread -!________________________________________________________ -#ifdef MKL - write(0,*) "ERROR in grid_to_four: srcft and drcft ", - & " must be replaced with MKL's FFTW calls. ABORT." - call sleep(5) - stop -#endif - num_threads=min(num_parthds_stochy,lot) - - nvar_thread_max=(lot+num_threads-1)/num_threads - if ( kind_dbl_prec == 8 ) then !------------------------------------ -!$omp parallel do num_threads(num_threads) -!$omp+shared(anl_gr_a_1,anl_gr_a_2,lons_lat) -!$omp+shared(lon_dim_coef,lon_dim_grid) -!$omp+shared(lot,num_threads,nvar_thread_max) -!$omp+shared(ibmsign,scale_ibm,rone) -!$omp+private(thread,nvar_1,nvar_2,lot_thread,init,aux1crs) - - do thread=1,num_threads ! start of thread loop .............. - nvar_1 = (thread-1)*nvar_thread_max + 1 - nvar_2 = min(nvar_1+nvar_thread_max-1,lot) - - if (nvar_2 >= nvar_1) then - lot_thread = nvar_2 - nvar_1 + 1 - - init = 1 - ibmsign = 1 - rone = 1.0d0 - scale_ibm = rone/lons_lat - call drcft(init, - & anl_gr_a_2(1,nvar_1), lon_dim_grid, - & anl_gr_a_1(1,nvar_1), lon_dim_coef/2, - & lons_lat,lot_thread,ibmsign,scale_ibm, - & aux1crs,22000, - & aux1crs(22001),20000) - init = 0 - call drcft(init, - & anl_gr_a_2(1,nvar_1), lon_dim_grid, - & anl_gr_a_1(1,nvar_1), lon_dim_coef/2, - & lons_lat,lot_thread,ibmsign,scale_ibm, - & aux1crs,22000, - & aux1crs(22001),20000) - - endif - enddo ! fin thread loop ...................................... - else !------------------------------------------------------------ -!$omp parallel do num_threads(num_threads) -!$omp+shared(anl_gr_a_1,anl_gr_a_2,lons_lat) -!$omp+shared(lon_dim_coef,lon_dim_grid) -!$omp+shared(lot,num_threads,nvar_thread_max) -!$omp+shared(ibmsign,scale_ibm,rone) -!$omp+private(thread,nvar_1,nvar_2,lot_thread,init,aux1crs) - - do thread=1,num_threads ! start of thread loop .............. - nvar_1 = (thread-1)*nvar_thread_max + 1 - nvar_2 = min(nvar_1+nvar_thread_max-1,lot) - - if (nvar_2 >= nvar_1) then - lot_thread=nvar_2 - nvar_1 + 1 - - init = 1 - ibmsign = 1 - rone = 1.0d0 - scale_ibm = rone/lons_lat - call srcft(init, - & anl_gr_a_2(1,nvar_1), lon_dim_grid, - & anl_gr_a_1(1,nvar_1), lon_dim_coef/2, - & lons_lat,lot_thread,ibmsign,scale_ibm, - & aux1crs,22000, - & aux1crs(22001),20000, - & aux1crs(22001),0) - init = 0 - call srcft(init, - & anl_gr_a_2(1,nvar_1), lon_dim_grid, - & anl_gr_a_1(1,nvar_1), lon_dim_coef/2, - & lons_lat,lot_thread,ibmsign,scale_ibm, - & aux1crs,22000, - & aux1crs(22001),20000, - & aux1crs(22001),0) - - endif - enddo ! fin thread loop ...................................... - endif !----------------------------------------------------------- -!! return end - end module four_to_grid_mod diff --git a/get_lats_node_a_stochy.f b/get_lats_node_a_stochy.f index 34c78a0..986afea 100644 --- a/get_lats_node_a_stochy.f +++ b/get_lats_node_a_stochy.f @@ -10,7 +10,6 @@ subroutine get_lats_node_a_stochy(me_fake,global_lats_a, & lats_nodes_a_fake,gl_lats_index, & global_time_sort_index,iprint) cc - use stochy_resol_def use spectral_layout_mod implicit none cc diff --git a/get_ls_node_stochy.f b/get_ls_node_stochy.f index fad01e2..655bd78 100644 --- a/get_ls_node_stochy.f +++ b/get_ls_node_stochy.f @@ -7,17 +7,16 @@ module get_ls_node_stochy_mod !>@brief The subroutine 'get_ls_node_stochy' calculates the decomposition of the spherical harmonics based on the processor layout subroutine get_ls_node_stochy(me_fake,ls_node,ls_max_node_fake, -!>@details This code is taken from the legacy spectral GFS c iprint) +!>@details This code is taken from the legacy spectral GFS ! - use stochy_resol_def use spectral_layout_mod implicit none ! integer me_fake, ls_max_node_fake, iprint integer ls_node(ls_dim) - integer ijk, jptls, l, node, nodesio + integer ijk, jptls, l, node, nodesio, jcap1 ! !jw if (liope) then !jw if (icolor.eq.2) then @@ -32,6 +31,7 @@ subroutine get_ls_node_stochy(me_fake,ls_node,ls_max_node_fake, !jw endif !! ls_node = -1 + jcap1=jcap+1 ! jptls = 0 l = 0 diff --git a/get_stochy_pattern.F90 b/get_stochy_pattern.F90 index b3f712f..6b3e6af 100644 --- a/get_stochy_pattern.F90 +++ b/get_stochy_pattern.F90 @@ -1,22 +1,25 @@ !>@brief The module 'get_stochy_pattern_mod' contains the subroutines to retrieve the random pattern in the cubed-sphere grid module get_stochy_pattern_mod -!! the stochastic physics random pattern generators use kinddef, only : kind_dbl_prec, kind_evod - use stochy_resol_def, only : latg, latg2, levs, lonf, skeblevs use spectral_layout_mod, only : ipt_lats_node_a, lat1s_a, lats_dim_a, & lats_node_a, lon_dim_a, len_trie_ls, & - len_trio_ls, ls_dim, nodes, stochy_la2ga + len_trio_ls, ls_dim, nodes, stochy_la2ga, & + coslat_a, latg, latg2, levs, lonf, skeblevs use stochy_namelist_def, only : n_var_lndp, ntrunc, stochini use stochy_data_mod, only : gg_lats, gg_lons, inttyp, nskeb, nshum, nsppt, & - rad2deg, rnlat, rpattern_sfc, rpattern_skeb, & + rnlat, rpattern_sfc, rpattern_skeb, & rpattern_shum, rpattern_sppt, skebu_save, & - skebv_save, skeb_vwts, skeb_vpts, wlon, nlndp - use stochy_gg_def, only : coslat_a + skebv_save, skeb_vwts, skeb_vpts, wlon use stochy_patterngenerator_mod, only: random_pattern, ndimspec, & patterngenerator_advance use stochy_internal_state_mod, only: stochy_internal_state - use mpi_wrapper, only : mp_reduce_sum,is_master + use mpp_mod,only: mpp_npes,mpp_pe,mpp_root_pe,mpp_sum +#ifdef STOCHY_UNIT_TEST + use standalone_stochy_module, only: GFS_control_type, GFS_grid_type,random_seed +#else + use GFS_typedefs, only: GFS_control_type, GFS_grid_type use mersenne_twister, only: random_seed +#endif use dezouv_stochy_mod, only: dezouv_stochy use dozeuv_stochy_mod, only: dozeuv_stochy use four_to_grid_mod, only: four_to_grid @@ -24,116 +27,40 @@ module get_stochy_pattern_mod implicit none private - public get_random_pattern_fv3,get_random_pattern_fv3_vect - public get_random_pattern_fv3_sfc + public get_random_pattern_vector + public get_random_pattern_sfc,get_random_pattern_scalar public dump_patterns logical :: first_call=.true. contains -!>@brief The subroutine 'get_random_pattern_fv3' converts spherical harmonics to the gaussian grid then interpolates to the cubed-sphere grid +!>@brief The subroutine 'get_random_pattern_sfc' converts spherical harmonics to the gaussian grid then interpolates to the target grid !>@details This subroutine is for a 2-D (lat-lon) scalar field -subroutine get_random_pattern_fv3(rpattern,npatterns,& - gis_stochy,xlat,xlon,blksz,nblks,maxlen,pattern_2d) -!\callgraph - -! generate a random pattern for stochastic physics - implicit none - type(random_pattern), intent(inout) :: rpattern(npatterns) - type(stochy_internal_state) :: gis_stochy - real(kind=kind_dbl_prec), intent(in) :: xlat(:,:),xlon(:,:) - integer,intent(in) :: npatterns,blksz(:),nblks,maxlen - - integer i,j,l,lat,ierr,n,nn,k,nt - real(kind=kind_dbl_prec), dimension(lonf,gis_stochy%lats_node_a,1):: wrk2d - - integer :: num2d -! logical lprint - - real(kind=kind_dbl_prec), allocatable, dimension(:,:) :: workg - real (kind=kind_dbl_prec) glolal(lonf,gis_stochy%lats_node_a) - integer kmsk0(lonf,gis_stochy%lats_node_a),len - real(kind=kind_dbl_prec) :: globalvar,globalvar0 - real(kind=kind_dbl_prec) :: pattern_2d(nblks,maxlen) - real(kind=kind_dbl_prec) :: pattern_1d(maxlen) - real(kind=kind_dbl_prec), allocatable, dimension(:,:) :: rslmsk - integer :: blk - - kmsk0 = 0 - glolal = 0. - do n=1,npatterns - call patterngenerator_advance(rpattern(n),1,.false.) - call scalarspect_to_gaugrid( & - rpattern(n)%spec_e,rpattern(n)%spec_o,wrk2d,& - gis_stochy%ls_node,gis_stochy%ls_nodes,gis_stochy%max_ls_nodes,& - gis_stochy%lats_nodes_a,gis_stochy%global_lats_a,gis_stochy%lonsperlat,& - gis_stochy%plnev_a,gis_stochy%plnod_a,1) - glolal = glolal + wrk2d(:,:,1) - enddo - - allocate(workg(lonf,latg)) - workg = 0. - do j=1,gis_stochy%lats_node_a - lat=gis_stochy%global_lats_a(ipt_lats_node_a-1+j) - do i=1,lonf - workg(i,lat) = glolal(i,j) - enddo - enddo - - call mp_reduce_sum(workg,lonf,latg) - - -! interpolate to cube grid - allocate(rslmsk(lonf,latg)) - do blk=1,nblks - len=blksz(blk) - pattern_1d = 0 - associate( tlats=>xlat(blk,:)*rad2deg,& - tlons=>xlon(blk,:)*rad2deg ) - call stochy_la2ga(workg,lonf,latg,gg_lons,gg_lats,wlon,rnlat,& - pattern_1d(1:len),len,rslmsk,tlats,tlons) - pattern_2d(blk,:)=pattern_1d(:) - end associate - enddo - deallocate(rslmsk) - deallocate(workg) - -end subroutine get_random_pattern_fv3 - - -!>@brief The subroutine 'get_random_pattern_fv3_sfc' converts spherical harmonics to the gaussian grid then interpolates to the cubed-sphere grid once -!>@details This subroutine is for a 2-D (lat-lon) scalar field -subroutine get_random_pattern_fv3_sfc(rpattern,npatterns,& - gis_stochy,xlat,xlon,blksz,nblks,maxlen,pattern_3d) +subroutine get_random_pattern_sfc(rpattern,npatterns,& + gis_stochy,pattern_3d) !\callgraph ! generate a random pattern for stochastic physics implicit none type(random_pattern), intent(inout) :: rpattern(npatterns) - type(stochy_internal_state), target :: gis_stochy - real(kind=kind_dbl_prec), intent(in) :: xlat(:,:),xlon(:,:) - integer,intent(in) :: npatterns,blksz(:),nblks,maxlen - real(kind=kind_dbl_prec), intent(out) :: pattern_3d(nblks,maxlen,n_var_lndp) + type(stochy_internal_state), intent(in) :: gis_stochy + integer,intent(in):: npatterns - integer i,j,l,lat,ierr,n,nn,k,nt + integer i,j,lat,n,k real(kind=kind_dbl_prec), dimension(lonf,gis_stochy%lats_node_a,1):: wrk2d - integer :: num2d ! logical lprint real(kind=kind_dbl_prec), allocatable, dimension(:,:) :: workg real (kind=kind_dbl_prec) glolal(lonf,gis_stochy%lats_node_a) - integer kmsk0(lonf,gis_stochy%lats_node_a),len - real(kind=kind_dbl_prec) :: globalvar,globalvar0 - real(kind=kind_dbl_prec) :: pattern_1d(maxlen) - real(kind=kind_dbl_prec), allocatable, dimension(:,:) :: rslmsk - integer :: blk + integer kmsk0(lonf,gis_stochy%lats_node_a) + real(kind=kind_dbl_prec),intent(out) :: pattern_3d(gis_stochy%nx,gis_stochy%ny,n_var_lndp) + real(kind=kind_dbl_prec) :: pattern_1d(gis_stochy%nx) do k=1,n_var_lndp kmsk0 = 0 glolal = 0. do n=1,npatterns - call patterngenerator_advance(rpattern(n),k,.false.) - if (is_master()) print *, 'Random pattern for LNDP PERTS in get_random_pattern_fv3_sfc: k, min, max ',k,minval(rpattern_sfc(n)%spec_o(:,:,k)), maxval(rpattern_sfc(n)%spec_o(:,:,k)) + if (mpp_pe()==mpp_root_pe()) print *, 'Random pattern for SFC-PERTS in get_random_pattern_sfc: k, min, max ',k,minval(rpattern_sfc(n)%spec_o(:,:,k)), maxval(rpattern_sfc(n)%spec_o(:,:,k)) call scalarspect_to_gaugrid( & rpattern(n)%spec_e(:,:,k),rpattern(n)%spec_o(:,:,k),wrk2d,& gis_stochy%ls_node,gis_stochy%ls_nodes,gis_stochy%max_ls_nodes,& @@ -151,69 +78,60 @@ subroutine get_random_pattern_fv3_sfc(rpattern,npatterns,& enddo enddo - call mp_reduce_sum(workg,lonf,latg) - if (is_master()) print *, 'workg after mp_reduce_sum for LNDP PERTS in get_random_pattern_fv3_sfc: k, min, max ',k,minval(workg), maxval(workg) + call mpp_sum(workg,lonf*latg) + if (mpp_pe()==mpp_root_pe()) print *, 'workg after mpp_sum for SFC-PERTS in get_random_pattern_sfc: k, min, max ',k,minval(workg), maxval(workg) ! interpolate to cube grid - allocate(rslmsk(lonf,latg)) - do blk=1,nblks - len=blksz(blk) + do j=1,gis_stochy%ny pattern_1d = 0 - associate( tlats=>xlat(blk,:)*rad2deg,& - tlons=>xlon(blk,:)*rad2deg ) - call stochy_la2ga(workg,lonf,latg,gg_lons,gg_lats,wlon,rnlat,& - pattern_1d(1:len),len,rslmsk,tlats,tlons) - pattern_3d(blk,:,k)=pattern_1d(:) + associate( tlats=>gis_stochy%parent_lats(:,j),& + tlons=>gis_stochy%parent_lons(:,j)) + call stochy_la2ga(workg,lonf,latg,gg_lons,gg_lats,wlon,rnlat,& + pattern_1d(1:gis_stochy%len(j)),gis_stochy%len(j),tlats,tlons) + pattern_3d(:,j,k)=pattern_1d(:) end associate enddo - if (is_master()) print *, '3D pattern for LNDP PERTS in get_random_pattern_fv3_sfc: k, min, max ',k,minval(pattern_3d(:,:,k)), maxval(pattern_3d(:,:,k)) - deallocate(rslmsk) + if (mpp_pe()==mpp_root_pe()) print *, '3D pattern for SFC-PERTS in get_random_pattern_sfc: k, min, max ',k,minval(pattern_3d(:,:,k)), maxval(pattern_3d(:,:,k)) deallocate(workg) enddo ! loop over k, n_var_lndp -end subroutine get_random_pattern_fv3_sfc +end subroutine get_random_pattern_sfc -!>@brief The subroutine 'get_random_pattern_fv3_vect' converts spherical harmonics to a vector on gaussian grid then interpolates to the cubed-sphere grid +!>@brief The subroutine 'get_random_pattern_fv3_vect' converts spherical harmonics to a vector on gaussian grid then interpolates to the target grid !>@details This subroutine is for a 2-D (lat-lon) vector field -subroutine get_random_pattern_fv3_vect(rpattern,npatterns,& - gis_stochy,levs,xlat,xlon,blksz,nblks,maxlen,upattern_3d,vpattern_3d) +subroutine get_random_pattern_vector(rpattern,npatterns,& + gis_stochy,upattern_3d,vpattern_3d) !\callgraph ! generate a random pattern for stochastic physics implicit none - type(stochy_internal_state), target :: gis_stochy - integer, intent(in) :: levs + type(stochy_internal_state), intent(in) :: gis_stochy type(random_pattern), intent(inout) :: rpattern(npatterns) - real(kind=kind_dbl_prec), intent(out) :: upattern_3d(nblks,maxlen,levs) - real(kind=kind_dbl_prec), intent(out) :: vpattern_3d(nblks,maxlen,levs) real(kind=kind_evod), dimension(len_trie_ls,2,1) :: vrtspec_e,divspec_e real(kind=kind_evod), dimension(len_trio_ls,2,1) :: vrtspec_o,divspec_o - real(kind=kind_dbl_prec), intent(in) :: xlat(:,:),xlon(:,:) - integer,intent(in) :: npatterns,blksz(:),nblks,maxlen + integer:: npatterns - integer :: blk,len - real(kind=kind_dbl_prec) :: pattern_1d(maxlen) - real(kind=kind_dbl_prec), allocatable, dimension(:,:) :: rslmsk - integer i,j,l,lat,ierr,n,nn,k,nt + real(kind=kind_dbl_prec) :: upattern_3d(gis_stochy%nx,gis_stochy%ny,levs) + real(kind=kind_dbl_prec) :: vpattern_3d(gis_stochy%nx,gis_stochy%ny,levs) + real(kind=kind_dbl_prec) :: pattern_1d(gis_stochy%nx) + integer i,j,lat,n,nn,k real(kind_dbl_prec), dimension(lonf,gis_stochy%lats_node_a,1):: wrk2du,wrk2dv - integer :: num2d ! logical lprint real, allocatable, dimension(:,:) :: workgu,workgv - integer kmsk0(lonf,gis_stochy%lats_node_a),i1,i2,j1 - real(kind=kind_dbl_prec) :: globalvar,globalvar0 + integer kmsk0(lonf,gis_stochy%lats_node_a) kmsk0 = 0 allocate(workgu(lonf,latg)) allocate(workgv(lonf,latg)) - allocate(rslmsk(lonf,latg)) + print*,'before first_call',skeblevs if (first_call) then - allocate(skebu_save(nblks,maxlen,skeblevs)) - allocate(skebv_save(nblks,maxlen,skeblevs)) + allocate(skebu_save(gis_stochy%nx,gis_stochy%ny,skeblevs)) + allocate(skebv_save(gis_stochy%nx,gis_stochy%ny,skeblevs)) do k=2,skeblevs workgu = 0. workgv = 0. @@ -241,21 +159,20 @@ subroutine get_random_pattern_fv3_vect(rpattern,npatterns,& enddo enddo enddo - call mp_reduce_sum(workgu,lonf,latg) - call mp_reduce_sum(workgv,lonf,latg) + call mpp_sum(workgu,lonf*latg) + call mpp_sum(workgv,lonf*latg) ! interpolate to cube grid - do blk=1,nblks - len=blksz(blk) + do j=1,gis_stochy%ny pattern_1d = 0 - associate( tlats=>xlat(blk,:)*rad2deg,& - tlons=>xlon(blk,:)*rad2deg ) - call stochy_la2ga(workgu,lonf,latg,gg_lons,gg_lats,wlon,rnlat,& - pattern_1d(1:len),len,rslmsk,tlats,tlons) - skebu_save(blk,:,k)=pattern_1d(:) - call stochy_la2ga(workgv,lonf,latg,gg_lons,gg_lats,wlon,rnlat,& - pattern_1d(1:len),len,rslmsk,tlats,tlons) - skebv_save(blk,:,k)=-1*pattern_1d(:) - end associate + associate( tlats=>gis_stochy%parent_lats(1:gis_stochy%len(j),j),& + tlons=>gis_stochy%parent_lons(1:gis_stochy%len(j),j)) + call stochy_la2ga(workgu,lonf,latg,gg_lons,gg_lats,wlon,rnlat,& + pattern_1d(1:gis_stochy%len(j)),gis_stochy%len(j),tlats,tlons) + skebu_save(:,j,k)=pattern_1d(:) + call stochy_la2ga(workgv,lonf,latg,gg_lons,gg_lats,wlon,rnlat,& + pattern_1d(1:gis_stochy%len(j)),gis_stochy%len(j),tlats,tlons) + skebv_save(:,j,k)=-1*pattern_1d(:) + end associate enddo enddo endif @@ -275,6 +192,7 @@ subroutine get_random_pattern_fv3_vect(rpattern,npatterns,& ! if (stochini.AND. first_call) then ! print*,'skipping advance' ! else + print*,'advancing' call patterngenerator_advance(rpattern(n),skeblevs,first_call) ! endif ! ke norm (convert streamfunction forcing to vorticity forcing) @@ -299,35 +217,128 @@ subroutine get_random_pattern_fv3_vect(rpattern,npatterns,& enddo enddo enddo - call mp_reduce_sum(workgu,lonf,latg) - call mp_reduce_sum(workgv,lonf,latg) + call mpp_sum(workgu,lonf*latg) + call mpp_sum(workgv,lonf*latg) ! interpolate to cube grid - do blk=1,nblks - len=blksz(blk) + do j=1,gis_stochy%ny pattern_1d = 0 - associate( tlats=>xlat(blk,:)*rad2deg,& - tlons=>xlon(blk,:)*rad2deg ) - call stochy_la2ga(workgu,lonf,latg,gg_lons,gg_lats,wlon,rnlat,& - pattern_1d(1:len),len,rslmsk,tlats,tlons) - skebu_save(blk,:,skeblevs)=pattern_1d(:) - call stochy_la2ga(workgv,lonf,latg,gg_lons,gg_lats,wlon,rnlat,& - pattern_1d(1:len),len,rslmsk,tlats,tlons) - skebv_save(blk,:,skeblevs)=-1*pattern_1d(:) + associate( tlats=>gis_stochy%parent_lats(:,j),& + tlons=>gis_stochy%parent_lons(:,j)) + call stochy_la2ga(workgu,lonf,latg,gg_lons,gg_lats,wlon,rnlat,& + pattern_1d(1:gis_stochy%len(j)),gis_stochy%len(j),tlats,tlons) + skebu_save(:,j,skeblevs)=pattern_1d(:) + call stochy_la2ga(workgv,lonf,latg,gg_lons,gg_lats,wlon,rnlat,& + pattern_1d(1:gis_stochy%len(j)),gis_stochy%len(j),tlats,tlons) + skebv_save(:,j,skeblevs)=-1*pattern_1d(:) end associate enddo - deallocate(rslmsk) deallocate(workgu) deallocate(workgv) ! interpolate in the vertical ! consider moving to cubed sphere side, more memory, but less interpolations + print*,'looping through levs' do k=1,levs - do blk=1,nblks - upattern_3d(blk,:,k) = skeb_vwts(k,1)*skebu_save(blk,:,skeb_vpts(k,1))+skeb_vwts(k,2)*skebu_save(blk,:,skeb_vpts(k,2)) - vpattern_3d(blk,:,k) = skeb_vwts(k,1)*skebv_save(blk,:,skeb_vpts(k,1))+skeb_vwts(k,2)*skebv_save(blk,:,skeb_vpts(k,2)) + do j=1,gis_stochy%ny + upattern_3d(:,j,k) = skeb_vwts(k,1)*skebu_save(:,j,skeb_vpts(k,1))+skeb_vwts(k,2)*skebu_save(:,j,skeb_vpts(k,2)) + vpattern_3d(:,j,k) = skeb_vwts(k,1)*skebv_save(:,j,skeb_vpts(k,1))+skeb_vwts(k,2)*skebv_save(:,j,skeb_vpts(k,2)) enddo enddo first_call=.false. -end subroutine get_random_pattern_fv3_vect +end subroutine get_random_pattern_vector + +!>@brief The subroutine 'get_random_pattern_scalar' converts spherical harmonics to the gaussian grid then interpolates to the target grid +!>@details This subroutine is for a 2-D (lat-lon) scalar field +subroutine get_random_pattern_scalar(rpattern,npatterns,& + gis_stochy,pattern_2d) + +! generate a random pattern for stochastic physics + implicit none + type(random_pattern), intent(inout) :: rpattern(npatterns) + type(stochy_internal_state) :: gis_stochy + integer,intent(in):: npatterns + + integer i,j,lat,n,pe_print + real(kind=kind_dbl_prec), dimension(lonf,gis_stochy%lats_node_a,1):: wrk2d + +! logical lprint + + real(kind=kind_dbl_prec), allocatable, dimension(:,:) :: workg + real (kind=kind_dbl_prec) glolal(lonf,gis_stochy%lats_node_a) + integer kmsk0(lonf,gis_stochy%lats_node_a) + real(kind=kind_dbl_prec) :: pattern_2d(gis_stochy%nx,gis_stochy%ny) + real(kind=kind_dbl_prec) :: pattern_1d(gis_stochy%nx) + pe_print=111 + !if (mpp_pe()==pe_print) then + ! print*,'in get_random_pattern_scalar',npatterns + ! print*,'nx,ny',gis_stochy%nx,gis_stochy%ny + !endif + + kmsk0 = 0 + glolal = 0. + do n=1,npatterns + call patterngenerator_advance(rpattern(n),1,.false.) + call scalarspect_to_gaugrid( & + rpattern(n)%spec_e,rpattern(n)%spec_o,wrk2d,& + gis_stochy%ls_node,gis_stochy%ls_nodes,gis_stochy%max_ls_nodes,& + gis_stochy%lats_nodes_a,gis_stochy%global_lats_a,gis_stochy%lonsperlat,& + gis_stochy%plnev_a,gis_stochy%plnod_a,1) + glolal = glolal + wrk2d(:,:,1) + enddo + + allocate(workg(lonf,latg)) + workg = 0. + do j=1,gis_stochy%lats_node_a + lat=gis_stochy%global_lats_a(ipt_lats_node_a-1+j) + do i=1,lonf + workg(i,lat) = glolal(i,j) + enddo + enddo + + call mpp_sum(workg,lonf*latg) + !if (mpp_pe()==pe_print) then + ! print*,'before interpolate',maxval(workg),minval(workg) + !endif + +! interpolate to cube grid + ! if (mpp_pe()==pe_print) then + ! write(34) real(workg,kind=4) + ! endif + do j=1,gis_stochy%ny + pattern_1d = 0 + associate( tlats=>gis_stochy%parent_lats(1:gis_stochy%len(j),j),& + tlons=>gis_stochy%parent_lons(1:gis_stochy%len(j),j)) + ! if (mpp_pe()==pe_print) then + ! if (j.EQ.1.OR.j.EQ.gis_stochy%ny) then + ! !if (j.GT.100) then + ! do i=1,gis_stochy%len(j) + ! print*,'lat,lon',j,gis_stochy%parent_lats(i,j),gis_stochy%parent_lons(i,j) + ! print*,'lats',j,minval(gis_stochy%parent_lats(1:gis_stochy%len(j),j)),maxval(gis_stochy%parent_lats(1:gis_stochy%len(j),j)) + ! print*,'lons',j,minval(gis_stochy%parent_lons(1:gis_stochy%len(j),j)),maxval(gis_stochy%parent_lons(1:gis_stochy%len(j),j)) + ! !print*,'lonf,latg',lonf,latg,gis_stochy%nx,gis_stochy%ny,gis_stochy%len(j) + ! enddo + ! endif + ! endif + call stochy_la2ga(workg,lonf,latg,gg_lons,gg_lats,wlon,rnlat,& + pattern_1d(1:gis_stochy%len(j)),gis_stochy%len(j),tlats,tlons) + pattern_2d(:,j)=pattern_1d(:) + ! if (mpp_pe()==pe_print) then + ! print*,'gg_lats=',gg_lats(1),gg_lats(latg) + ! print*,'after interpolate',j,maxval(pattern_1d),minval(pattern_1d) + ! if (j.GT.110) then + ! do i=1,gis_stochy%len(j) + ! print*,'lat,lon',j,gis_stochy%parent_lats(i,j),gis_stochy%parent_lons(i,j),pattern_1d(i) + ! enddo + ! endif + ! endif + end associate + enddo + deallocate(workg) + !if (mpp_pe()==pe_print) then + ! print*,'outside loop',mpp_pe(),maxval(pattern_2d),minval(pattern_2d) + !endif + +end subroutine get_random_pattern_scalar +! !>@brief The subroutine 'scalarspect_to_gaugrid' converts scalar spherical harmonics to a scalar on a gaussian grid !>@details This subroutine is for a 2-D (lat-lon) scalar field @@ -349,8 +360,8 @@ subroutine scalarspect_to_gaugrid(& ! local vars real(kind=kind_dbl_prec) for_gr_a_1(lon_dim_a,nlevs,lats_dim_a) real(kind=kind_dbl_prec) for_gr_a_2(lonf,nlevs,lats_dim_a) - integer i,j,k - integer l,lan,lat + integer i,k + integer lan,lat integer lons_lat call sumfln_stochy(trie_ls,& @@ -393,8 +404,8 @@ subroutine dump_patterns(sfile) character*120 :: sfile integer :: stochlun,k,n stochlun=99 - if (is_master()) then - if (nsppt > 0 .OR. nshum > 0 .OR. nskeb > 0 .OR. nlndp > 0 ) then + if (mpp_pe()==mpp_root_pe()) then + if (nsppt > 0 .OR. nshum > 0 .OR. nskeb > 0) then OPEN(stochlun,file=sfile,form='unformatted') print*,'open ',sfile,' for output' endif @@ -416,13 +427,6 @@ subroutine dump_patterns(sfile) enddo enddo endif - if (nlndp > 0) then - do n=1,nlndp - do k=1,n_var_lndp - call write_pattern(rpattern_sfc(n),k,stochlun) - enddo - enddo - endif close(stochlun) end subroutine dump_patterns !>@brief The subroutine 'write_patterns' writes out a single pattern and the seed associated with the random number sequence @@ -433,7 +437,7 @@ subroutine write_pattern(rpattern,lev,lunptn) type(random_pattern), intent(inout) :: rpattern integer, intent(in) :: lunptn,lev real(kind_dbl_prec), allocatable :: pattern2d(:) - integer nm,nn,ierr,arrlen,isize + integer nm,nn,arrlen,isize integer,allocatable :: isave(:) arrlen=2*ndimspec @@ -454,9 +458,9 @@ subroutine write_pattern(rpattern,lev,lunptn) pattern2d(nm) = rpattern%spec_o(nn,1,lev) pattern2d(ndimspec+nm) = rpattern%spec_o(nn,2,lev) enddo - call mp_reduce_sum(pattern2d,arrlen) + call mpp_sum(pattern2d,arrlen) ! write only on root process - if (is_master()) then + if (mpp_pe()==mpp_root_pe()) then print*,'writing out random pattern (min/max/size)',& minval(pattern2d),maxval(pattern2d),size(pattern2d) !print*,'max/min pattern=',maxval(pattern2d),minval(pattern2d) @@ -497,8 +501,8 @@ subroutine vrtdivspect_to_uvgrid(& real(kind=kind_dbl_prec) trio_ls(len_trio_ls,2,2*nlevs) real(kind=kind_dbl_prec) for_gr_a_1(lon_dim_a,2*nlevs,lats_dim_a) real(kind=kind_dbl_prec) for_gr_a_2(lonf,2*nlevs,lats_dim_a) - integer i,j,k - integer l,lan,lat + integer i,k + integer lan,lat integer lons_lat real (kind=kind_dbl_prec) tx1 diff --git a/getcon_lag_stochy.f b/getcon_lag_stochy.f index 7fe23e4..4f8666f 100644 --- a/getcon_lag_stochy.f +++ b/getcon_lag_stochy.f @@ -10,12 +10,9 @@ module getcon_lag_stochy_mod subroutine getcon_lag_stochy(lats_nodes_a,global_lats_a, & lats_nodes_h,global_lats_h_sn, & lonsperlat,xhalo,yhalo) - use stochy_resol_def, only : jcap,latg,latg2,lonf - use spectral_layout_mod, only : me,nodes - - use stochy_gg_def, only : colrad_a,sinlat_a - use stochy_layout_lag, only : - & ipt_lats_node_h,lat1s_h,lats_dim_h, + use spectral_layout_mod, only : me,nodes,jcap,latg,latg2,lonf, + & colrad_a,sinlat_a, + & ipt_lats_node_h,lat1s_h,lats_dim_h, & lats_node_h,lats_node_h_max,lon_dim_h use setlats_lag_stochy_mod, only: setlats_lag_stochy implicit none diff --git a/getcon_spectral.F90 b/getcon_spectral.F90 index a9e8b21..857b4a7 100644 --- a/getcon_spectral.F90 +++ b/getcon_spectral.F90 @@ -11,14 +11,14 @@ module getcon_spectral_mod subroutine getcon_spectral ( ls_node,ls_nodes,max_ls_nodes, & lats_nodes_a,global_lats_a, & lonsperlat,latsmax, & - lats_nodes_ext,global_lats_ext, & epse,epso,epsedn,epsodn, & snnp1ev,snnp1od, & plnev_a,plnod_a,pddev_a,pddod_a, & - plnew_a,plnow_a,colat1) + plnew_a,plnow_a) ! program log: ! 20110220 henry juang update code to fit mass_dp and ndslfv +! 20201002 philip pegion clean up of code ! use epslon_stochy_mod, only: epslon_stochy use get_lats_node_a_stochy_mod, only: get_lats_node_a_stochy @@ -27,15 +27,14 @@ subroutine getcon_spectral ( ls_node,ls_nodes,max_ls_nodes, & use gozrineo_a_stochy_mod, only: gozrineo_a_stochy use pln2eo_a_stochy_mod, only: pln2eo_a_stochy use setlats_a_stochy_mod, only: setlats_a_stochy - use stochy_resol_def use spectral_layout_mod - use stochy_gg_def use stochy_internal_state_mod + use kinddef implicit none ! - integer i,j,k,l,lat,lan,lons_lat,n - integer ls_node(ls_dim,3),ierr + integer i,j,l,lat,n + integer ls_node(ls_dim,3) ! ! ls_node(1,1) ... ls_node(ls_max_node,1) : values of L ! ls_node(1,2) ... ls_node(ls_max_node,2) : values of jbasev @@ -45,8 +44,6 @@ subroutine getcon_spectral ( ls_node,ls_nodes,max_ls_nodes, & integer, dimension(nodes) :: max_ls_nodes, lats_nodes_a integer, dimension(latg) :: global_lats_a, lonsperlat ! - integer lats_nodes_ext(nodes) - integer global_lats_ext(latg+2*jintmx+2*nypt*(nodes-1)) ! real(kind=kind_dbl_prec), dimension(len_trie_ls) :: epse, epsedn, snnp1ev real(kind=kind_dbl_prec), dimension(len_trio_ls) :: epso, epsodn, snnp1od @@ -66,15 +63,12 @@ subroutine getcon_spectral ( ls_node,ls_nodes,max_ls_nodes, & integer gl_lats_index, latsmax integer global_time_sort_index_a(latg) ! - real fd2 -!! include 'function2' ! real(kind=kind_dbl_prec) global_time_a(latg) ! real(kind=kind_dbl_prec), parameter :: cons0 = 0.d0, cons0p5 = 0.5d0,& cons1 = 1.d0, cons0p92 = 0.92d0 - real(kind=kind_dbl_prec) colat1 ! gl_lats_index = 0 global_lats_a = -1 @@ -85,7 +79,6 @@ subroutine getcon_spectral ( ls_node,ls_nodes,max_ls_nodes, & do lat = 1, latg2 lonsperlat(latg+1-lat) = lonsperlat(lat) end do -! decompostion of gaussian grid across nodes do node=1,nodes call get_lats_node_a_stochy( node-1, global_lats_a,lats_nodes_a(node),& gl_lats_index,global_time_sort_index_a, iprint) @@ -143,9 +136,9 @@ subroutine getcon_spectral ( ls_node,ls_nodes,max_ls_nodes, & if ( kind_dbl_prec == 8 ) then !------------------------------------ call glats_stochy(latg2,colrad_a,wgt_a,wgtcs_a,rcs2_a,iprint) call epslon_stochy(epse,epso,epsedn,epsodn,ls_node) - call pln2eo_a_stochy(plnev_a,plnod_a,epse,epso,colrad_a,ls_node,latg2) + call pln2eo_a_stochy(plnev_a,plnod_a,epse,epso,ls_node,latg2) call gozrineo_a_stochy(plnev_a,plnod_a,pddev_a,pddod_a, & - plnew_a,plnow_a,epse,epso,rcs2_a,wgt_a,ls_node,latg2) + plnew_a,plnow_a,epse,epso,ls_node,latg2) ! else !------------------------------------------------------------ allocate ( colrad_dp(latg2) ) @@ -188,10 +181,10 @@ subroutine getcon_spectral ( ls_node,ls_nodes,max_ls_nodes, & ! do lat=1,latg2 ! - call pln2eo_a_stochy(plnev_dp,plnod_dp,epse_dp,epso_dp,colrad_dp(lat),ls_node,1) + call pln2eo_a_stochy(plnev_dp,plnod_dp,epse_dp,epso_dp,ls_node,1) ! call gozrineo_a_stochy(plnev_dp,plnod_dp,pddev_dp,pddod_dp, plnew_dp,plnow_dp,& - epse_dp,epso_dp,rcs2_dp(lat),wgt_dp(lat),ls_node,1) + epse_dp,epso_dp,ls_node,1) ! do i=1,len_trie_ls plnev_a(i,lat) = plnev_dp(i) @@ -205,7 +198,7 @@ subroutine getcon_spectral ( ls_node,ls_nodes,max_ls_nodes, & enddo enddo ! - deallocate ( colrad_dp, wgt_dp, wgtcs_dp, rcs2_dp , & + deallocate ( wgt_dp, wgtcs_dp, rcs2_dp , & epse_dp, epso_dp, epsedn_dp, epsodn_dp, & plnev_dp, plnod_dp, pddev_dp, pddod_dp , & plnew_dp, plnow_dp ) diff --git a/gozrineo_stochy.f b/gozrineo_stochy.f index e972b69..954e9b4 100644 --- a/gozrineo_stochy.f +++ b/gozrineo_stochy.f @@ -9,9 +9,8 @@ module gozrineo_a_stochy_mod subroutine gozrineo_a_stochy(plnev_a,plnod_a, & pddev_a,pddod_a, & plnew_a,plnow_a, - & epse,epso,rcs2_a,wgt_a,ls_node,num_lat) + & epse,epso,ls_node,num_lat) cc - use stochy_resol_def use spectral_layout_mod use kinddef implicit none @@ -26,8 +25,6 @@ subroutine gozrineo_a_stochy(plnev_a,plnod_a, real(kind=kind_dbl_prec) epse(len_trie_ls) real(kind=kind_dbl_prec) epso(len_trio_ls) cc - real(kind=kind_dbl_prec) rcs2_a(latg2) - real(kind=kind_dbl_prec) wgt_a(latg2) cc integer ls_node(ls_dim,3) cc diff --git a/initialize_spectral_mod.F90 b/initialize_spectral_mod.F90 index 89dd4f8..7150e6a 100644 --- a/initialize_spectral_mod.F90 +++ b/initialize_spectral_mod.F90 @@ -1,5 +1,4 @@ !>@brief The module 'initialize_spectral_mod' cotains the subroutine initialize_spectral -! generato ! !module: stochy_initialize_spectral ! --- initialize module of the ! gridded component of the stochastic physics patteern @@ -20,16 +19,15 @@ module initialize_spectral_mod use kinddef use spectral_layout_mod, only : ipt_lats_node_a, lats_node_a_max,lon_dim_a,len_trie_ls,len_trio_ls & ,nodes,ls_max_node,lats_dim_a,ls_dim,lat1s_a - use stochy_layout_lag, only : lat1s_h use stochy_internal_state_mod - use spectral_layout_mod,only:lon_dims_a, num_parthds_stochy => ompthreads - use stochy_resol_def + use spectral_layout_mod,only:jcap,lon_dims_a,wgt_a,sinlat_a,coslat_a,colrad_a,wgtcs_a,rcs2_a,lats_nodes_h,global_lats_h,& + latg,latg2,lonf,lotls,lat1s_h use stochy_namelist_def - use stochy_gg_def, only : wgt_a,sinlat_a,coslat_a,colrad_a,wgtcs_a,rcs2_a,lats_nodes_h,global_lats_h + use mpp_mod, only : mpp_pe,mpp_root_pe use getcon_spectral_mod, only: getcon_spectral use get_ls_node_stochy_mod, only: get_ls_node_stochy use getcon_lag_stochy_mod, only: getcon_lag_stochy - !use mpi_wrapper, only : is_master + !use mpp_mod #ifndef IBM USE omp_lib #endif @@ -52,9 +50,8 @@ subroutine initialize_spectral(gis_stochy, rc) ! type(stochy_internal_state), pointer, intent(inout) :: gis_stochy type(stochy_internal_state), intent(inout) :: gis_stochy integer, intent(out) :: rc - integer :: ierr, npe_single_member, iret,latghf - integer :: num_parthds_stochy - integer :: i, j, k, l, n, locl + integer :: npe_single_member, iret,latghf + integer :: i, l, locl logical :: file_exists=.false. integer, parameter :: iunit=101 @@ -65,26 +62,16 @@ subroutine initialize_spectral(gis_stochy, rc) ! print*,'before allocate lonsperlat,',& ! allocated(gis_stochy%lonsperlat),'latg=',latg ! +! gis_stochy%nodes=mpp_npes() +! print*,'mpp_npes=',mpp_npes() nodes = gis_stochy%nodes npe_single_member = gis_stochy%npe_single_member lon_dim_a = lon_s + 2 jcap=ntrunc - jcap1 = jcap+1 - jcap2 = jcap+2 latg = lat_s latg2 = latg/2 lonf = lon_s - lnt = jcap2*jcap1/2 - lnuv = jcap2*jcap1 - lnt2 = lnt + lnt - lnt22 = lnt2 + 1 - lnte = (jcap2/2)*((jcap2/2)+1)-1 - lnto = (jcap2/2)*((jcap2/2)+1)-(jcap2/2) - lnted = lnte - lntod = lnto - - gis_stochy%lnt2 = lnt2 allocate(lat1s_a(0:jcap)) allocate(lon_dims_a(latg)) @@ -93,12 +80,11 @@ subroutine initialize_spectral(gis_stochy, rc) allocate(wgtcs_a(latg2)) allocate(rcs2_a(latg2)) -! if (is_master()) then -! print*,'number of threads is',num_parthds_stochy +! if (mpp_pe==mpp_root_pe()) then ! print*,'number of mpi procs is',nodes ! endif ! - ls_dim = (jcap1-1)/nodes+1 + ls_dim = (jcap)/nodes+1 ! print*,'allocating lonsperlat',latg allocate(gis_stochy%lonsperlat(latg)) ! print*,'size=',size(gis_stochy%lonsperlat) @@ -106,6 +92,7 @@ subroutine initialize_spectral(gis_stochy, rc) inquire (file="lonsperlat.dat", exist=file_exists) if ( .not. file_exists ) then + !call mpp_error(FATAL,'Requested lonsperlat.dat data file does not exist') gis_stochy%lonsperlat(:)=lonf else open (iunit,file='lonsperlat.dat',status='old',form='formatted', & @@ -144,8 +131,6 @@ subroutine initialize_spectral(gis_stochy, rc) allocate ( gis_stochy%lats_nodes_a(nodes) ) allocate ( gis_stochy%global_lats_a(latg) ) ! - allocate ( gis_stochy%lats_nodes_ext(nodes) ) - allocate ( gis_stochy%global_lats_ext(latg+2*jintmx+2*nypt*(nodes-1)) ) ! internal parallel structure. Weiyu. !--------------------------------------------------- @@ -226,18 +211,16 @@ subroutine initialize_spectral(gis_stochy, rc) return end if !! - gis_stochy%lats_nodes_ext = 0 call getcon_spectral(gis_stochy%ls_node, gis_stochy%ls_nodes, & gis_stochy%max_ls_nodes, gis_stochy%lats_nodes_a, & gis_stochy%global_lats_a, gis_stochy%lonsperlat, & - gis_stochy%lats_node_a_max, gis_stochy%lats_nodes_ext, & - gis_stochy%global_lats_ext, gis_stochy%epse, & + gis_stochy%lats_node_a_max, gis_stochy%epse, & gis_stochy%epso, gis_stochy%epsedn, & gis_stochy%epsodn, gis_stochy%snnp1ev, & gis_stochy%snnp1od, gis_stochy%plnev_a, & gis_stochy%plnod_a, gis_stochy%pddev_a, & gis_stochy%pddod_a, gis_stochy%plnew_a, & - gis_stochy%plnow_a, gis_stochy%colat1) + gis_stochy%plnow_a) ! gis_stochy%lats_node_a = gis_stochy%lats_nodes_a(gis_stochy%me+1) gis_stochy%ipt_lats_node_a = ipt_lats_node_a diff --git a/lndp_apply_perts.F90 b/lndp_apply_perts.F90 index dabd48e..f802afd 100644 --- a/lndp_apply_perts.F90 +++ b/lndp_apply_perts.F90 @@ -18,9 +18,9 @@ module lndp_apply_perts_mod ! Note on location: requires access to namelist_soilveg subroutine lndp_apply_perts(blksz,lsm, lsoil,dtf, n_var_lndp, lndp_var_list, & - lndp_prt_list, sfc_wts, xlon, xlat, stype, maxsmc,param_update_flag, & + lndp_prt_list, sfc_wts, stype, maxsmc,param_update_flag, & smc, slc, stc, vfrac, ierr) - + use stochy_data_mod, only : gis_stochy implicit none ! intent(in) @@ -30,8 +30,6 @@ subroutine lndp_apply_perts(blksz,lsm, lsoil,dtf, n_var_lndp, lndp_var_list, & real(kind=kind_dbl_prec), intent(in) :: lndp_prt_list(:) real(kind=kind_dbl_prec), intent(in) :: dtf real(kind=kind_dbl_prec), intent(in) :: sfc_wts(:,:,:) - real(kind=kind_dbl_prec), intent(in) :: xlon(:,:) - real(kind=kind_dbl_prec), intent(in) :: xlat(:,:) logical, intent(in) :: param_update_flag ! true = parameters have been updated, apply perts real(kind=kind_dbl_prec), intent(in) :: stype(:,:) @@ -72,7 +70,7 @@ subroutine lndp_apply_perts(blksz,lsm, lsoil,dtf, n_var_lndp, lndp_var_list, & nblks = size(blksz) - call set_printing_nb_i(blksz,xlon,xlat,print_i,print_nb) + call set_printing_nb_i(blksz,gis_stochy%parent_lons,gis_stochy%parent_lats,print_i,print_nb) do nb =1,nblks do i = 1, blksz(nb) diff --git a/makefile b/makefile index ba6dc07..b0e30af 100644 --- a/makefile +++ b/makefile @@ -26,7 +26,6 @@ SRCS_f90 = \ SRCS_f = \ ./stochy_gg_def.f \ - ./stochy_resol_def.f \ ./stochy_layout_lag.f \ ./four_to_grid_stochy.f \ ./glats_stochy.f \ diff --git a/pln2eo_stochy.f b/pln2eo_stochy.f index 1ff4d26..c5316cb 100644 --- a/pln2eo_stochy.f +++ b/pln2eo_stochy.f @@ -7,13 +7,12 @@ module pln2eo_a_stochy_mod !>@brief The subroutine 'pln2eo_a_stochy' calculates the assoicate legendre polynomials !>@details This code is taken from the legacy spectral GFS - subroutine pln2eo_a_stochy(plnev_a,plnod_a,epse,epso,colrad_a, + subroutine pln2eo_a_stochy(plnev_a,plnod_a,epse,epso, & ls_node,num_lat) ! ! use x-number method to archieve accuracy due to recursive to avoid ! underflow and overflow if necessary by henry juang 2012 july ! - use stochy_resol_def use spectral_layout_mod use kinddef implicit none @@ -33,7 +32,6 @@ subroutine pln2eo_a_stochy(plnev_a,plnod_a,epse,epso,colrad_a, real(kind=kind_dbl_prec) epse(len_trie_ls) real(kind=kind_dbl_prec) epso(len_trio_ls) cc - real(kind=kind_dbl_prec) colrad_a(latg2) cc integer ls_node(ls_dim,3) cc @@ -53,7 +51,7 @@ subroutine pln2eo_a_stochy(plnev_a,plnod_a,epse,epso,colrad_a, integer ialp10(0:jcap) real(kind=kind_dbl_prec) aa, bb, w - real(kind=kind_dbl_prec) a,alp1,alp2,alp3,b + real(kind=kind_dbl_prec) alp1,alp2,alp3 real(kind=kind_dbl_prec) cos2,fl,prod,sinlat,coslat cc real(kind=kind_dbl_prec) alp10(0:jcap) diff --git a/setlats_a_stochy.f b/setlats_a_stochy.f index 49f0f46..9db140f 100644 --- a/setlats_a_stochy.f +++ b/setlats_a_stochy.f @@ -9,8 +9,7 @@ module setlats_a_stochy_mod subroutine setlats_a_stochy(lats_nodes_a,global_lats_a, & iprint,lonsperlat) ! - use stochy_resol_def , only : latg,lonf - use spectral_layout_mod , only : nodes,me + use spectral_layout_mod , only : nodes,me,latg,lonf ! implicit none ! diff --git a/setlats_lag_stochy.f b/setlats_lag_stochy.f index 539c96e..ddf8ebd 100644 --- a/setlats_lag_stochy.f +++ b/setlats_lag_stochy.f @@ -11,8 +11,7 @@ module setlats_lag_stochy_mod subroutine setlats_lag_stochy(lats_nodes_a, global_lats_a, & lats_nodes_h, global_lats_h, yhalo) ! - use stochy_resol_def, only : latg - use spectral_layout_mod, only : me,nodes + use spectral_layout_mod, only : me,nodes,latg implicit none ! integer yhalo @@ -63,21 +62,25 @@ subroutine setlats_lag_stochy(lats_nodes_a, global_lats_a, ! set non-polar south yhalos jpt_h = 0 do nn=1,nodes-1 - jpt_h = jpt_h + lats_nodes_h(nn) - lat_val = global_lats_h(jpt_h-yhalo) - do jj=1,yhalo - global_lats_h(jpt_h-yhalo+jj) = min(lat_val+jj,latg) - enddo + if (lats_nodes_h(nn).GT.0) then + jpt_h = jpt_h + lats_nodes_h(nn) + lat_val = global_lats_h(jpt_h-yhalo) + do jj=1,yhalo + global_lats_h(jpt_h-yhalo+jj) = min(lat_val+jj,latg) + enddo + endif enddo ! ! set non-polar north yhalos jpt_h = 0 do nn=1,nodes-1 - jpt_h = jpt_h + lats_nodes_h(nn) - lat_val = global_lats_h(jpt_h+yhalo+1) - do jj=1,yhalo - global_lats_h(jpt_h+yhalo-(jj-1)) = max(lat_val-jj,1) - enddo + if (lats_nodes_h(nn).GT.0) then + jpt_h = jpt_h + lats_nodes_h(nn) + lat_val = global_lats_h(jpt_h+yhalo+1) + do jj=1,yhalo + global_lats_h(jpt_h+yhalo-(jj-1)) = max(lat_val-jj,1) + enddo + endif enddo ! endif diff --git a/spectral_layout.F90 b/spectral_layout.F90 index 291f528..2116690 100644 --- a/spectral_layout.F90 +++ b/spectral_layout.F90 @@ -9,6 +9,7 @@ module spectral_layout_mod ! 20161011 philip pegion : make stochastic pattern generator standalone ! ! 20190503 dom heinzeller : add ompthreads and stochy_la2ga; todo: cleanup nodes, me, ... (defined multiple times in several files) +! 20201002 philip pegion: cleanup of code ! integer :: nodes, & me, & @@ -24,32 +25,37 @@ module spectral_layout_mod len_trio_ls, & len_trie_ls_max, & len_trio_ls_max, & - me_l_0, & lats_dim_ext, & lats_node_ext, & - ipt_lats_node_ext + ipt_lats_node_ext, & + jcap,latg,latg2, & + skeblevs,levs,lnt, & + lonf,lonfx, & + latgd,lotls - integer :: ompthreads = 1 ! integer, allocatable :: lat1s_a(:), lon_dims_a(:),lon_dims_ext(:) + real, allocatable, dimension(:) :: colrad_a, wgt_a, wgtcs_a, rcs2_a, & + sinlat_a, coslat_a + integer ,allocatable, dimension(:) :: lats_nodes_h,global_lats_h -contains + integer lats_dim_h, & + lats_node_h, & + lats_node_h_max, & + ipt_lats_node_h, & + lon_dim_h + INTEGER ,ALLOCATABLE :: lat1s_h(:) - logical function is_master() - if (me == master) then - is_master = .true. - else - is_master = .false. - end if - end function is_master +contains +! ! interpolation from lat/lon or gaussian grid to other lat/lon grid ! !>@brief The subroutine 'stochy_la2ga' intepolates from the global gaussian grid !! to the cubed sphere points !>@details This code is taken from the legacy spectral GFS subroutine stochy_la2ga(regin,imxin,jmxin,rinlon,rinlat,rlon,rlat, & - gauout,len,rslmsk, outlat, outlon) + gauout,len,outlat, outlon) use kinddef , only : kind_io8, kind_io4 implicit none ! interface variables @@ -62,16 +68,14 @@ subroutine stochy_la2ga(regin,imxin,jmxin,rinlon,rinlat,rlon,rlat, & real (kind=kind_io8), intent(in) :: rlat real (kind=kind_io8), intent(out) :: gauout(len) integer, intent(in) :: len - real (kind=kind_io8), intent(in) :: rslmsk(imxin,jmxin) real (kind=kind_io8), intent(in) :: outlat(len) real (kind=kind_io8), intent(in) :: outlon(len) ! local variables - real (kind=kind_io8) :: wei4,wei3,wei2,sum2,sum1,sum3,wei1,sum4 + real (kind=kind_io8) :: sum2,sum1,sum3,sum4 real (kind=kind_io8) :: wsum,wsumiv,sums,sumn,wi2j2,x,y,wi1j1 real (kind=kind_io8) :: wi1j2,wi2j1,aphi,rnume,alamd,denom - integer :: jy,ix,i,j,jq,jx - integer :: j1,j2,ii,i1,i2,kmami,it - integer :: nx,kxs,kxt + integer :: i,j,jq,jx + integer :: j1,j2,ii,i1,i2 integer :: iindx1(len) integer :: iindx2(len) integer :: jindx1(len) @@ -79,43 +83,22 @@ subroutine stochy_la2ga(regin,imxin,jmxin,rinlon,rinlat,rlon,rlat, & real(kind=kind_io8) :: ddx(len) real(kind=kind_io8) :: ddy(len) real(kind=kind_io8) :: wrk(len) - integer :: len_thread_m - integer :: len_thread - integer :: i1_t - integer :: i2_t ! - len_thread_m = (len+ompthreads-1) / ompthreads -! - !$omp parallel do num_threads(ompthreads) default(none) & - !$omp private(i1_t,i2_t,len_thread,it,i,ii,i1,i2) & - !$omp private(j,j1,j2,jq,ix,jy,nx,kxs,kxt,kmami) & - !$omp private(alamd,denom,rnume,aphi,x,y,wsum,wsumiv,sum1,sum2) & - !$omp private(sum3,sum4,wi1j1,wi2j1,wi1j2,wi2j2,wei1,wei2,wei3,wei4) & - !$omp private(sumn,sums) & - !$omp shared(imxin,jmxin) & - !$omp shared(outlon,outlat,wrk,iindx1,rinlon,jindx1,rinlat,ddx,ddy) & - !$omp shared(rlon,rlat,regin,gauout) & - !$omp shared(ompthreads,len_thread_m,len,iindx2,jindx2,rslmsk) - do it=1,ompthreads ! start of threaded loop - i1_t = (it-1)*len_thread_m+1 - i2_t = min(i1_t+len_thread_m-1,len) - len_thread = i2_t-i1_t+1 ! ! find i-index for interpolation -! - do i=i1_t, i2_t + do i=1,len alamd = outlon(i) if (alamd .lt. rlon) alamd = alamd + 360.0 if (alamd .gt. 360.0+rlon) alamd = alamd - 360.0 wrk(i) = alamd iindx1(i) = imxin enddo - do i=i1_t,i2_t + do i=1,len do ii=1,imxin if(wrk(i) .ge. rinlon(ii)) iindx1(i) = ii enddo enddo - do i=i1_t,i2_t + do i=1,len i1 = iindx1(i) if (i1 .lt. 1) i1 = imxin i2 = i1 + 1 @@ -132,15 +115,15 @@ subroutine stochy_la2ga(regin,imxin,jmxin,rinlon,rinlat,rlon,rlat, & ! find j-index for interplation ! if(rlat.gt.0.) then - do j=i1_t,i2_t + do j=1,len jindx1(j)=0 enddo do jx=1,jmxin - do j=i1_t,i2_t + do j=1,len if(outlat(j).le.rinlat(jx)) jindx1(j) = jx enddo enddo - do j=i1_t,i2_t + do j=1,len jq = jindx1(j) aphi=outlat(j) if(jq.ge.1 .and. jq .lt. jmxin) then @@ -168,15 +151,15 @@ subroutine stochy_la2ga(regin,imxin,jmxin,rinlon,rinlat,rlon,rlat, & jindx2(j)=j2 enddo else - do j=i1_t,i2_t + do j=1,len jindx1(j) = jmxin+1 enddo do jx=jmxin,1,-1 - do j=i1_t,i2_t + do j=1,len if(outlat(j).le.rinlat(jx)) jindx1(j) = jx enddo enddo - do j=i1_t,i2_t + do j=1,len jq = jindx1(j) aphi=outlat(j) if(jq.gt.1 .and. jq .le. jmxin) then @@ -220,7 +203,7 @@ subroutine stochy_la2ga(regin,imxin,jmxin,rinlon,rinlat,rlon,rlat, & ! ! quasi-bilinear interpolation ! - do i=i1_t,i2_t + do i=1,len y = ddy(i) j1 = jindx1(i) j2 = jindx2(i) @@ -270,20 +253,17 @@ subroutine stochy_la2ga(regin,imxin,jmxin,rinlon,rinlat,rlon,rlat, & endif ! if j1 .ne. j2 endif enddo - do i=i1_t,i2_t + do i=1,len j1 = jindx1(i) j2 = jindx2(i) i1 = iindx1(i) i2 = iindx2(i) if(wrk(i) .eq. 0.0) then - write(6,*) ' la2ga: bad rslmsk given' + write(6,*) ' la2ga: error' call sleep(2) stop endif enddo - enddo ! end of threaded loop -!$omp end parallel do -! return ! end subroutine stochy_la2ga diff --git a/stochastic_physics.F90 b/stochastic_physics.F90 index b413a4a..0d0c3f9 100644 --- a/stochastic_physics.F90 +++ b/stochastic_physics.F90 @@ -8,8 +8,8 @@ module stochastic_physics private -public :: init_stochastic_physics -public :: run_stochastic_physics +public :: init_stochastic_physics,init_stochastic_physics_ocn +public :: run_stochastic_physics,run_stochastic_physics_ocn contains @@ -19,16 +19,15 @@ module stochastic_physics !allocates and polulates the necessary arrays subroutine init_stochastic_physics(levs, blksz, dtp, input_nml_file_in, fn_nml, nlunit, & + xlon,xlat, & do_sppt_in, do_shum_in, do_skeb_in, lndp_type_in, n_var_lndp_in, use_zmtnblck_out, skeb_npass_out, & lndp_var_list_out, lndp_prt_list_out, ak, bk, nthreads, mpiroot, mpicomm, iret) !\callgraph -!use stochy_internal_state_mod -use stochy_data_mod, only : nshum,rpattern_shum,init_stochdata,rpattern_sppt,nsppt,rpattern_skeb,nskeb,gg_lats,gg_lons,& +!use stochy_internal_state_moa +use stochy_data_mod, only : init_stochdata,gg_lats,gg_lons,& rad2deg,INTTYP,wlon,rnlat,gis_stochy,vfact_skeb,vfact_sppt,vfact_shum,skeb_vpts,skeb_vwts,sl -use stochy_resol_def , only : latg,lonf,skeblevs -use stochy_gg_def,only : colrad_a use stochy_namelist_def -use spectral_layout_mod,only:me,master,nodes,ompthreads +use spectral_layout_mod,only:me,master,nodes,colrad_a,latg,lonf,skeblevs use mpi_wrapper, only : mpi_wrapper_initialize,mype,npes,is_master implicit none @@ -41,6 +40,8 @@ subroutine init_stochastic_physics(levs, blksz, dtp, input_nml_file_in, fn_nml, real(kind=kind_dbl_prec), intent(in) :: dtp character(len=*), intent(in) :: input_nml_file_in(:) character(len=*), intent(in) :: fn_nml +real(kind=kind_dbl_prec), intent(in) :: xlon(:,:) +real(kind=kind_dbl_prec), intent(in) :: xlat(:,:) logical, intent(in) :: do_sppt_in, do_shum_in, do_skeb_in integer, intent(in) :: lndp_type_in, n_var_lndp_in real(kind=kind_dbl_prec), intent(in) :: ak(:), bk(:) @@ -52,7 +53,7 @@ subroutine init_stochastic_physics(levs, blksz, dtp, input_nml_file_in, fn_nml, ! Local variables real(kind=kind_dbl_prec), parameter :: con_pi =4.0d0*atan(1.0d0) -integer :: nblks +integer :: nblks,len real*8 :: PRSI(levs),PRSL(levs),dx real, allocatable :: skeb_vloc(:) integer :: k,kflip,latghf,blk,k2 @@ -63,14 +64,28 @@ subroutine init_stochastic_physics(levs, blksz, dtp, input_nml_file_in, fn_nml, me = mype nodes = npes master = mpiroot -ompthreads = nthreads +gis_stochy%nodes = npes +gis_stochy%me=me +gis_stochy%nx=maxval(blksz) +nblks = size(blksz) +gis_stochy%ny=nblks +rad2deg=180.0/con_pi ! ------------------------------------------ nblks = size(blksz) +allocate(gis_stochy%len(nblks)) +allocate(gis_stochy%parent_lons(gis_stochy%nx,gis_stochy%ny)) +allocate(gis_stochy%parent_lats(gis_stochy%nx,gis_stochy%ny)) +print*,'in init_stochastic_physics',gis_stochy%nx,gis_stochy%ny +do blk=1,nblks + len=blksz(blk) + gis_stochy%parent_lons(1:len,blk)=xlon(blk,1:len)*rad2deg + gis_stochy%parent_lats(1:len,blk)=xlat(blk,1:len)*rad2deg + gis_stochy%len(blk)=len +enddo ! replace -rad2deg=180.0/con_pi INTTYP=0 ! bilinear interpolation gis_stochy%me=me gis_stochy%nodes=nodes @@ -214,34 +229,102 @@ subroutine init_stochastic_physics(levs, blksz, dtp, input_nml_file_in, fn_nml, end subroutine init_stochastic_physics +!!!!!!!!!!!!!!!!!!!! +subroutine init_stochastic_physics_ocn(delt,geoLonT,geoLatT,nx,ny,nz,do_epbl_out,do_sppt_out, & + mpiroot, mpicomm, iret) +use stochy_data_mod, only : init_stochdata_ocn,gg_lats,gg_lons,& + rad2deg,INTTYP,wlon,rnlat,gis_stochy_ocn +use spectral_layout_mod , only : latg,lonf,colrad_a,me,nodes +!use MOM_grid, only : ocean_grid_type +use stochy_namelist_def +use physcons, only: con_pi +use mersenne_twister, only: random_gauss +use mpi_wrapper, only : mpi_wrapper_initialize,mype,npes,is_master + +implicit none +real,intent(in) :: delt +integer,intent(in) :: nx,ny,nz +real,intent(in) :: geoLonT(nx,ny),geoLatT(nx,ny) +logical,intent(inout) :: do_epbl_out,do_sppt_out +integer,intent(in) :: mpiroot, mpicomm +integer, intent(out) :: iret + +real :: dx +integer :: k,latghf,km +rad2deg=180.0/con_pi +call mpi_wrapper_initialize(mpiroot,mpicomm) +me = mype +nodes=npes +gis_stochy_ocn%nodes = npes +gis_stochy_ocn%me=me +gis_stochy_ocn%nx=nx +gis_stochy_ocn%ny=ny +allocate(gis_stochy_ocn%len(ny)) +allocate(gis_stochy_ocn%parent_lons(nx,ny)) +allocate(gis_stochy_ocn%parent_lats(nx,ny)) +gis_stochy_ocn%len(:)=nx +gis_stochy_ocn%parent_lons=geoLonT +gis_stochy_ocn%parent_lats=geoLatT +print*,'ocn parent lats=',minval(gis_stochy_ocn%parent_lats) +! replace +INTTYP=0 ! bilinear interpolation +km=nz +!print*,'in init',nx,ny,nz +print*,'init_stochastic_physics_ocn',maxval(geoLonT),size(geoLonT(:,1)),size(geoLonT(1,:)) +call init_stochdata_ocn(km,delt,iret) +do_epbl_out=do_epbl +do_sppt_out=do_ocnsppt +if ( (.NOT. do_epbl) .AND. (.NOT. do_sppt_out) ) return + +! get interpolation weights +! define gaussian grid lats and lons +latghf=latg/2 +!print *,'define interp weights',latghf,lonf +!print *,allocated(gg_lats),allocated(gg_lons) +allocate(gg_lats(latg)) +!print *,'aloocated lats',latg +allocate(gg_lons(lonf)) +!print *,'aloocated lons',lonf +do k=1,latghf + gg_lats(k)=-1.0*colrad_a(latghf-k+1)*rad2deg + gg_lats(latg-k+1)=-1*gg_lats(k) +enddo +dx=360.0/lonf +!print*,'dx=',dx +do k=1,lonf + gg_lons(k)=dx*(k-1) +enddo +WLON=gg_lons(1)-(gg_lons(2)-gg_lons(1)) +RNLAT=gg_lats(1)*2-gg_lats(2) +end subroutine init_stochastic_physics_ocn + +!!!!!!!!!!!!!!!!!!!! + + !>@brief The subroutine 'run_stochastic_physics' updates the random patterns if !!necessary !>@details It updates the AR(1) in spectral space !allocates and polulates the necessary arrays -subroutine run_stochastic_physics(levs, kdt, phour, blksz, xlat, xlon, sppt_wts, shum_wts, skebu_wts, & +subroutine run_stochastic_physics(levs, kdt, phour, blksz, sppt_wts, shum_wts, skebu_wts, & skebv_wts, sfc_wts,nthreads) !\callgraph !use stochy_internal_state_mod use stochy_data_mod, only : nshum,rpattern_shum,rpattern_sppt,nsppt,rpattern_skeb,nskeb,& - rad2deg,INTTYP,wlon,rnlat,gis_stochy,vfact_sppt,vfact_shum,vfact_skeb, & - rpattern_sfc, nlndp -use get_stochy_pattern_mod,only : get_random_pattern_fv3,get_random_pattern_fv3_vect,dump_patterns, & - get_random_pattern_fv3_sfc -use stochy_resol_def , only : latg,lonf + gis_stochy,vfact_sppt,vfact_shum,vfact_skeb, rpattern_sfc, nlndp +use get_stochy_pattern_mod,only : get_random_pattern_scalar,get_random_pattern_vector,dump_patterns, & + get_random_pattern_sfc use stochy_namelist_def, only : do_shum,do_sppt,do_skeb,fhstoch,nssppt,nsshum,nsskeb,sppt_logit, & lndp_type, n_var_lndp use mpi_wrapper, only: is_master -use spectral_layout_mod,only:ompthreads +use spectral_layout_mod,only:me implicit none ! Interface variables integer, intent(in) :: levs, kdt real(kind=kind_dbl_prec), intent(in) :: phour integer, intent(in) :: blksz(:) -real(kind=kind_dbl_prec), intent(in) :: xlat(:,:) -real(kind=kind_dbl_prec), intent(in) :: xlon(:,:) real(kind=kind_dbl_prec), intent(inout) :: sppt_wts(:,:,:) real(kind=kind_dbl_prec), intent(inout) :: shum_wts(:,:,:) real(kind=kind_dbl_prec), intent(inout) :: skebu_wts(:,:,:) @@ -261,15 +344,14 @@ subroutine run_stochastic_physics(levs, kdt, phour, blksz, xlat, xlon, sppt_wts, if ( (.NOT. do_sppt) .AND. (.NOT. do_shum) .AND. (.NOT. do_skeb) .AND. (lndp_type==0 ) ) return ! Update number of threads in shared variables in spectral_layout_mod and set block-related variables -ompthreads = nthreads nblks = size(blksz) maxlen = maxval(blksz(:)) if ( (lndp_type==1) .and. (kdt==0) ) then ! old land pert scheme called once at start - write(0,*) 'calling get_random_pattern_fv3_sfc' + write(0,*) 'calling get_random_pattern_sfc' allocate(tmpl_wts(nblks,maxlen,n_var_lndp)) - call get_random_pattern_fv3_sfc(rpattern_sfc,nlndp,gis_stochy,xlat,xlon,blksz,nblks,maxlen,tmpl_wts) + call get_random_pattern_sfc(rpattern_sfc,nlndp,gis_stochy,tmpl_wts) DO blk=1,nblks len=blksz(blk) ! for perturbing vars or states, saved value is N(0,1) and apply scaling later. @@ -290,7 +372,7 @@ subroutine run_stochastic_physics(levs, kdt, phour, blksz, xlat, xlon, sppt_wts, allocate(tmpv_wts(nblks,maxlen,levs)) if (do_sppt) then if (mod(kdt,nssppt) == 1 .or. nssppt == 1) then - call get_random_pattern_fv3(rpattern_sppt,nsppt,gis_stochy,xlat,xlon,blksz,nblks,maxlen,tmp_wts) + call get_random_pattern_scalar(rpattern_sppt,nsppt,gis_stochy,tmp_wts) DO blk=1,nblks len=blksz(blk) DO k=1,levs @@ -303,7 +385,7 @@ subroutine run_stochastic_physics(levs, kdt, phour, blksz, xlat, xlon, sppt_wts, endif if (do_shum) then if (mod(kdt,nsshum) == 1 .or. nsshum == 1) then - call get_random_pattern_fv3(rpattern_shum,nshum,gis_stochy,xlat,xlon,blksz,nblks,maxlen,tmp_wts) + call get_random_pattern_scalar(rpattern_shum,nshum,gis_stochy,tmp_wts) DO blk=1,nblks len=blksz(blk) DO k=1,levs @@ -314,7 +396,7 @@ subroutine run_stochastic_physics(levs, kdt, phour, blksz, xlat, xlon, sppt_wts, endif if (do_skeb) then if (mod(kdt,nsskeb) == 1 .or. nsskeb == 1) then - call get_random_pattern_fv3_vect(rpattern_skeb,nskeb,gis_stochy,levs,xlat,xlon,blksz,nblks,maxlen,tmpu_wts,tmpv_wts) + call get_random_pattern_vector(rpattern_skeb,nskeb,gis_stochy,tmpu_wts,tmpv_wts) DO blk=1,nblks len=blksz(blk) DO k=1,levs @@ -327,7 +409,7 @@ subroutine run_stochastic_physics(levs, kdt, phour, blksz, xlat, xlon, sppt_wts, if ( lndp_type .EQ. 2 ) then ! add time check? allocate(tmpl_wts(nblks,maxlen,n_var_lndp)) - call get_random_pattern_fv3_sfc(rpattern_sfc,nlndp,gis_stochy,xlat,xlon,blksz,nblks,maxlen,tmpl_wts) + call get_random_pattern_sfc(rpattern_sfc,nlndp,gis_stochy,tmpl_wts) DO blk=1,nblks len=blksz(blk) ! for perturbing vars or states, saved value is N(0,1) and apply scaling later. @@ -345,4 +427,44 @@ subroutine run_stochastic_physics(levs, kdt, phour, blksz, xlat, xlon, sppt_wts, end subroutine run_stochastic_physics +subroutine run_stochastic_physics_ocn(t_rp,sppt_wts) +!use MOM_forcing_type, only : mech_forcing +!use MOM_grid, only : ocean_grid_type +use stochy_internal_state_mod +use stochy_data_mod, only : nepbl,nocnsppt,rpattern_epbl1,rpattern_epbl2,rpattern_ocnsppt, gis_stochy_ocn +use get_stochy_pattern_mod,only : get_random_pattern_scalar +use stochy_namelist_def +implicit none +!type(ocean_grid_type), intent(in) :: G +real, intent(inout) :: t_rp(:,:,:),sppt_wts(:,:) +real, allocatable :: tmp_wts(:,:) +if (do_epbl .OR. do_ocnsppt) then +allocate(tmp_wts(gis_stochy_ocn%nx,gis_stochy_ocn%ny)) + +!if (mod(Model%kdt,nsocnp) == 1 .or. nsocnp == 1) then +if (do_epbl) then + call get_random_pattern_scalar(rpattern_epbl1,nepbl,gis_stochy_ocn,tmp_wts) + t_rp(:,:,1)=2.0/(1+exp(-1*tmp_wts)) + call get_random_pattern_scalar(rpattern_epbl2,nepbl,gis_stochy_ocn,tmp_wts) + t_rp(:,:,2)=2.0/(1+exp(-1*tmp_wts)) +! print*,'in run_stochastic_physics_ocn 1',minval(t_rp),maxval(t_rp) +else + t_rp=1.0 +endif +if (do_ocnsppt) then + call get_random_pattern_scalar(rpattern_ocnsppt,nocnsppt,gis_stochy_ocn,tmp_wts) + sppt_wts=2.0/(1+exp(-1*tmp_wts)) +! print*,'in run_stochastic_physics_ocn 2',minval(sppt_wts),maxval(sppt_wts) +else + sppt_wts=1.0 +endif +!endif +deallocate(tmp_wts) +else + t_rp=1.0 + sppt_wts=1.0 +endif + +end subroutine run_stochastic_physics_ocn + end module stochastic_physics diff --git a/stochy_data_mod.F90 b/stochy_data_mod.F90 index d835ba4..5c29771 100644 --- a/stochy_data_mod.F90 +++ b/stochy_data_mod.F90 @@ -4,8 +4,8 @@ module stochy_data_mod ! set up and initialize stochastic random patterns. - use spectral_layout_mod, only: len_trie_ls,len_trio_ls,ls_dim,ls_max_node - use stochy_resol_def, only : skeblevs,levs,jcap,lonf,latg + use spectral_layout_mod, only: len_trie_ls,len_trio_ls,ls_dim,ls_max_node,& + skeblevs,levs,jcap,lonf,latg use stochy_namelist_def use constants_mod, only : radius use spectral_layout_mod, only : me, nodes @@ -20,10 +20,12 @@ module stochy_data_mod implicit none private - public :: init_stochdata + public :: init_stochdata,init_stochdata_ocn type(random_pattern), public, save, allocatable, dimension(:) :: & - rpattern_sppt,rpattern_shum,rpattern_skeb, rpattern_sfc + rpattern_sppt,rpattern_shum,rpattern_skeb, rpattern_sfc,rpattern_epbl1,rpattern_epbl2,rpattern_ocnsppt + integer, public :: nepbl=0 + integer, public :: nocnsppt=0 integer, public :: nsppt=0 integer, public :: nshum=0 integer, public :: nskeb=0 @@ -36,7 +38,7 @@ module stochy_data_mod real(kind=kind_dbl_prec),public :: wlon,rnlat,rad2deg real(kind=kind_dbl_prec),public, allocatable :: skebu_save(:,:,:),skebv_save(:,:,:) integer,public :: INTTYP - type(stochy_internal_state),public :: gis_stochy + type(stochy_internal_state),public :: gis_stochy,gis_stochy_ocn contains !>@brief The subroutine 'init_stochdata' determins which stochastic physics @@ -337,6 +339,138 @@ subroutine init_stochdata(nlevs,delt,input_nml_file,fn_nml,nlunit,iret) if (is_master() .and. stochini) CLOSE(stochlun) deallocate(noise_e,noise_o) end subroutine init_stochdata + + subroutine init_stochdata_ocn(nlevs,delt,iret) + + use compns_stochy_mod, only : compns_stochy_ocn + use mpp_domains_mod, only: mpp_broadcast_domain,MPP_DOMAIN_TIME,mpp_domains_init ,mpp_domains_set_stack_size +! initialize random patterns. A spinup period of spinup_efolds times the +! temporal time scale is run for each pattern. + integer, intent(in) :: nlevs + real, intent(in) :: delt + integer, intent(out) :: iret + + integer :: nn,nm,stochlun,n + integer :: l,jbasev,jbasod + integer :: indev,indod,indlsod,indlsev + real(kind_dbl_prec),allocatable :: noise_e(:,:),noise_o(:,:) + include 'function_indlsod' + include 'function_indlsev' + stochlun=99 + levs=nlevs + + iret=0 + call compns_stochy_ocn (delt,iret) + if(is_master()) print*,'in init stochdata_ocn' + if ( (.NOT. do_epbl) .AND. (.NOT. do_ocnsppt) ) return + call initialize_spectral(gis_stochy_ocn, iret) + if (iret/=0) return + allocate(noise_e(len_trie_ls,2),noise_o(len_trio_ls,2)) +! determine number of random patterns to be used for each scheme. + do n=1,size(epbl) + if (epbl(n) > 0) then + nepbl=nepbl+1 + else + exit + endif + enddo + + do n=1,size(ocnsppt) + if (ocnsppt(n) > 0) then + nocnsppt=nocnsppt+1 + else + exit + endif + enddo + + if (nepbl > 0) then + allocate(rpattern_epbl1(nepbl)) + allocate(rpattern_epbl2(nepbl)) + endif + + if (nocnsppt > 0) allocate(rpattern_ocnsppt(nocnsppt)) + + if (nepbl > 0) then + if (is_master()) print *, 'Initialize random pattern for epbl' + call patterngenerator_init(epbl_lscale(1:nepbl),epblint,epbl_tau(1:nepbl),epbl(1:nepbl),iseed_epbl,rpattern_epbl1, & + lonf,latg,jcap,gis_stochy_ocn%ls_node,nepbl,1,0,new_lscale) + call patterngenerator_init(epbl_lscale(1:nepbl),epblint,epbl_tau(1:nepbl),epbl(1:nepbl),iseed_epbl2,rpattern_epbl2, & + lonf,latg,jcap,gis_stochy_ocn%ls_node,nepbl,1,0,new_lscale) + do n=1,nepbl + call getnoise(rpattern_epbl1(n),noise_e,noise_o) + do nn=1,len_trie_ls + rpattern_epbl1(n)%spec_e(nn,1,1)=noise_e(nn,1) + rpattern_epbl1(n)%spec_e(nn,2,1)=noise_e(nn,2) + rpattern_epbl1(n)%spec_e(nn,1,1)=noise_e(nn,1) + rpattern_epbl1(n)%spec_e(nn,2,1)=noise_e(nn,2) + nm = rpattern_epbl1(n)%idx_e(nn) + if (nm .eq. 0) cycle + rpattern_epbl1(n)%spec_e(nn,1,1) = rpattern_epbl1(n)%stdev*rpattern_epbl1(n)%spec_e(nn,1,1)*rpattern_epbl1(n)%varspectrum(nm) + rpattern_epbl1(n)%spec_e(nn,2,1) = rpattern_epbl1(n)%stdev*rpattern_epbl1(n)%spec_e(nn,2,1)*rpattern_epbl1(n)%varspectrum(nm) + enddo + do nn=1,len_trio_ls + rpattern_epbl1(n)%spec_o(nn,1,1)=noise_o(nn,1) + rpattern_epbl1(n)%spec_o(nn,2,1)=noise_o(nn,2) + nm = rpattern_epbl1(n)%idx_o(nn) + if (nm .eq. 0) cycle + rpattern_epbl1(n)%spec_o(nn,1,1) = rpattern_epbl1(n)%stdev*rpattern_epbl1(n)%spec_o(nn,1,1)*rpattern_epbl1(n)%varspectrum(nm) + rpattern_epbl1(n)%spec_o(nn,2,1) = rpattern_epbl1(n)%stdev*rpattern_epbl1(n)%spec_o(nn,2,1)*rpattern_epbl1(n)%varspectrum(nm) + enddo + call patterngenerator_advance(rpattern_epbl1(n),1,.false.) + enddo + do n=1,nepbl + call getnoise(rpattern_epbl2(n),noise_e,noise_o) + do nn=1,len_trie_ls + rpattern_epbl2(n)%spec_e(nn,1,1)=noise_e(nn,1) + rpattern_epbl2(n)%spec_e(nn,2,1)=noise_e(nn,2) + rpattern_epbl2(n)%spec_e(nn,1,1)=noise_e(nn,1) + rpattern_epbl2(n)%spec_e(nn,2,1)=noise_e(nn,2) + nm = rpattern_epbl2(n)%idx_e(nn) + if (nm .eq. 0) cycle + rpattern_epbl2(n)%spec_e(nn,1,1) = rpattern_epbl2(n)%stdev*rpattern_epbl2(n)%spec_e(nn,1,1)*rpattern_epbl2(n)%varspectrum(nm) + rpattern_epbl2(n)%spec_e(nn,2,1) = rpattern_epbl2(n)%stdev*rpattern_epbl2(n)%spec_e(nn,2,1)*rpattern_epbl2(n)%varspectrum(nm) + enddo + do nn=1,len_trio_ls + rpattern_epbl2(n)%spec_o(nn,1,1)=noise_o(nn,1) + rpattern_epbl2(n)%spec_o(nn,2,1)=noise_o(nn,2) + nm = rpattern_epbl2(n)%idx_o(nn) + if (nm .eq. 0) cycle + rpattern_epbl2(n)%spec_o(nn,1,1) = rpattern_epbl2(n)%stdev*rpattern_epbl2(n)%spec_o(nn,1,1)*rpattern_epbl2(n)%varspectrum(nm) + rpattern_epbl2(n)%spec_o(nn,2,1) = rpattern_epbl2(n)%stdev*rpattern_epbl2(n)%spec_o(nn,2,1)*rpattern_epbl2(n)%varspectrum(nm) + enddo + call patterngenerator_advance(rpattern_epbl2(n),1,.false.) + enddo + endif + + if (nocnsppt > 0) then + if (is_master()) print *, 'Initialize random pattern for ocnsppt' + call patterngenerator_init(ocnsppt_lscale(1:nocnsppt),ocnspptint,ocnsppt_tau(1:nocnsppt),ocnsppt(1:nocnsppt),iseed_ocnsppt,rpattern_ocnsppt, & + lonf,latg,jcap,gis_stochy_ocn%ls_node,nocnsppt,1,0,new_lscale) + do n=1,nocnsppt + call getnoise(rpattern_ocnsppt(n),noise_e,noise_o) + do nn=1,len_trie_ls + rpattern_ocnsppt(n)%spec_e(nn,1,1)=noise_e(nn,1) + rpattern_ocnsppt(n)%spec_e(nn,2,1)=noise_e(nn,2) + nm = rpattern_ocnsppt(n)%idx_e(nn) + if (nm .eq. 0) cycle + rpattern_ocnsppt(n)%spec_e(nn,1,1) = rpattern_ocnsppt(n)%stdev*rpattern_ocnsppt(n)%spec_e(nn,1,1)*rpattern_ocnsppt(n)%varspectrum(nm) + rpattern_ocnsppt(n)%spec_e(nn,2,1) = rpattern_ocnsppt(n)%stdev*rpattern_ocnsppt(n)%spec_e(nn,2,1)*rpattern_ocnsppt(n)%varspectrum(nm) + enddo + do nn=1,len_trio_ls + rpattern_ocnsppt(n)%spec_o(nn,1,1)=noise_o(nn,1) + rpattern_ocnsppt(n)%spec_o(nn,2,1)=noise_o(nn,2) + nm = rpattern_ocnsppt(n)%idx_o(nn) + if (nm .eq. 0) cycle + rpattern_ocnsppt(n)%spec_o(nn,1,1) = rpattern_ocnsppt(n)%stdev*rpattern_ocnsppt(n)%spec_o(nn,1,1)*rpattern_ocnsppt(n)%varspectrum(nm) + rpattern_ocnsppt(n)%spec_o(nn,2,1) = rpattern_ocnsppt(n)%stdev*rpattern_ocnsppt(n)%spec_o(nn,2,1)*rpattern_ocnsppt(n)%varspectrum(nm) + enddo + call patterngenerator_advance(rpattern_ocnsppt(n),1,.false.) + enddo + endif + deallocate(noise_e,noise_o) + end subroutine init_stochdata_ocn + + !>@brief This subroutine 'read_pattern' will read in the spectral coeffients from a previous run (stored in stoch_ini, !!turned on by setting STOCHINI=.true.) !>@details Data read in are flat binary, so the number of stochastic physics patterns running must match previous run diff --git a/stochy_internal_state_mod.F90 b/stochy_internal_state_mod.F90 index 220d29e..9cd774d 100644 --- a/stochy_internal_state_mod.F90 +++ b/stochy_internal_state_mod.F90 @@ -20,27 +20,18 @@ module stochy_internal_state_mod !!uses: !------ use spectral_layout_mod - use stochy_gg_def - use stochy_resol_def implicit none private ! ----------------------------------------------- -!>@brief Derived type 'stochy_internal_state' contains all of the spherical harmonic and gaussian grid information -!>@details This code is taken from the legacy spectral GFS type,public::stochy_internal_state ! start type define ! ----------------------------------------------- - ! DH* todo remove - is in spectral_layout? - integer :: me, nodes - integer :: lnt2_s, llgg_s - integer :: lnt2 - integer :: grib_inp + integer :: nodes ! - integer nxpt,nypt,jintmx integer lonf,latg,lats_node_a_max integer npe_single_member @@ -51,6 +42,7 @@ module stochy_internal_state_mod character(32) ,allocatable :: filename_base(:) integer :: ipt_lats_node_a integer :: lats_node_a + integer :: me !jwe integer :: nblck,kdt @@ -63,33 +55,31 @@ module stochy_internal_state_mod integer ,allocatable :: lats_nodes_a (:) integer ,allocatable :: global_lats_a (:) - integer ,allocatable :: lats_nodes_ext (:) - integer ,allocatable :: global_lats_ext(:) integer ,allocatable :: global_lats_h (:) integer :: xhalo,yhalo integer ,allocatable :: lats_nodes_a_fix (:) - real(kind=kind_dbl_prec) ,allocatable :: epse (:) - real(kind=kind_dbl_prec) ,allocatable :: epso (:) - real(kind=kind_dbl_prec) ,allocatable :: epsedn(:) - real(kind=kind_dbl_prec) ,allocatable :: epsodn(:) - real(kind=kind_dbl_prec) ,allocatable :: kenorm_e(:) - real(kind=kind_dbl_prec) ,allocatable :: kenorm_o(:) + real,allocatable :: epse (:) + real,allocatable :: epso (:) + real,allocatable :: epsedn(:) + real,allocatable :: epsodn(:) + real,allocatable :: kenorm_e(:) + real,allocatable :: kenorm_o(:) - real(kind=kind_dbl_prec) ,allocatable :: snnp1ev(:) - real(kind=kind_dbl_prec) ,allocatable :: snnp1od(:) + real,allocatable :: snnp1ev(:) + real,allocatable :: snnp1od(:) - real(kind=kind_dbl_prec) ,allocatable :: plnev_a(:,:) - real(kind=kind_dbl_prec) ,allocatable :: plnod_a(:,:) - real(kind=kind_dbl_prec) ,allocatable :: pddev_a(:,:) - real(kind=kind_dbl_prec) ,allocatable :: pddod_a(:,:) - real(kind=kind_dbl_prec) ,allocatable :: plnew_a(:,:) - real(kind=kind_dbl_prec) ,allocatable :: plnow_a(:,:) + real,allocatable :: plnev_a(:,:) + real,allocatable :: plnod_a(:,:) + real,allocatable :: pddev_a(:,:) + real,allocatable :: pddod_a(:,:) + real,allocatable :: plnew_a(:,:) + real,allocatable :: plnow_a(:,:) - real(kind=kind_dbl_prec) ,allocatable :: trie_ls(:,:,:) - real(kind=kind_dbl_prec) ,allocatable :: trio_ls(:,:,:) + real,allocatable :: trie_ls(:,:,:) + real,allocatable :: trio_ls(:,:,:) INTEGER :: TRIEO_TOTAL_SIZE INTEGER, ALLOCATABLE, DIMENSION(:) :: TRIE_LS_SIZE @@ -102,28 +92,21 @@ module stochy_internal_state_mod ! !! - integer init,jcount,jpt,node,ibmsign,lon_dim,ilat + integer init,jpt,node,ibmsign,lon_dim - real(kind=kind_dbl_prec) colat1, rone, rlons_lat, scale_ibm + integer lotls - integer lotls,lotgr,lots,lots_slg,lotd,lota,lotp +! integer jdt,ksout,maxstp +! integer mdt,idt +! integer mods,n1,n2,ndgf,ndgi,nfiles,nflps + integer nlunit - integer ibrad,ifges,ihour,ini,j,jdt,ksout,maxstp - integer mdt,idt,timetot,timer,time0 - integer mods,n1,n2,ndgf,ndgi,nfiles,nflps - integer n1hyb, n2hyb,nlunit - integer nges,ngpken,niter,nnmod,nradf,nradr - integer nsfcf,nsfci,nsfcs,nsigi,nsigs,nstep - integer nznlf,nznli,nznls,id,iret,nsout,ndfi - - integer ierr,iprint,k,l,locl,n + integer iret,ierr,iprint,k,l,locl,n integer lan,lat - integer spectral_loop - - - integer ikey,nrank_all,kcolor + integer nx,ny,nz + integer, allocatable :: len(:) + real, allocatable :: parent_lons(:,:),parent_lats(:,:) - real(kind=kind_dbl_prec) cons0p5,cons1200,cons3600,cons0 ! ! ----------------------------------------------------- diff --git a/stochy_namelist_def.F90 b/stochy_namelist_def.F90 index 310713a..f29de0a 100644 --- a/stochy_namelist_def.F90 +++ b/stochy_namelist_def.F90 @@ -11,7 +11,7 @@ module stochy_namelist_def public integer, parameter :: max_n_var_lndp = 6 ! must match value used in GFS_typedefs - integer nssppt,nsshum,nsskeb,lon_s,lat_s,ntrunc + integer nssppt,nsshum,nsepbl,nsocnsppt,nsskeb,lon_s,lat_s,ntrunc ! pjp stochastic phyics integer skeb_varspect_opt,skeb_npass @@ -20,15 +20,17 @@ module stochy_namelist_def real(kind=kind_dbl_prec) :: skeb_sigtop1,skeb_sigtop2, & sppt_sigtop1,sppt_sigtop2,shum_sigefold, & skeb_vdof - real(kind=kind_dbl_prec) fhstoch,skeb_diss_smooth,spptint,shumint,skebint,skebnorm + real(kind=kind_dbl_prec) fhstoch,skeb_diss_smooth,epblint,ocnspptint,spptint,shumint,skebint,skebnorm real(kind=kind_dbl_prec), dimension(5) :: skeb,skeb_lscale,skeb_tau real(kind=kind_dbl_prec), dimension(5) :: sppt,sppt_lscale,sppt_tau real(kind=kind_dbl_prec), dimension(5) :: shum,shum_lscale,shum_tau + real(kind=kind_dbl_prec), dimension(5) :: epbl,epbl_lscale,epbl_tau + real(kind=kind_dbl_prec), dimension(5) :: ocnsppt,ocnsppt_lscale,ocnsppt_tau integer,dimension(5) ::skeb_vfilt - integer(8),dimension(5) ::iseed_sppt,iseed_shum,iseed_skeb + integer(8),dimension(5) ::iseed_sppt,iseed_shum,iseed_skeb,iseed_epbl,iseed_ocnsppt,iseed_epbl2 logical stochini,sppt_logit,new_lscale logical use_zmtnblck - logical do_shum,do_sppt,do_skeb + logical do_shum,do_sppt,do_skeb,do_epbl,do_ocnsppt real(kind=kind_dbl_prec), dimension(5) :: lndp_lscale,lndp_tau integer n_var_lndp diff --git a/stochy_resol_def.f b/stochy_resol_def.f deleted file mode 100644 index b915aee..0000000 --- a/stochy_resol_def.f +++ /dev/null @@ -1,46 +0,0 @@ -!>@brief The module 'stochy_resol_def' contains specherical harmoninc and gaussian -!! grid definitions as weel as legeacy GFS indicies - module stochy_resol_def - -! program log: -! 20110220: Henry Juang update index for MASS_DP and NDSLFV -! 20130202: Henry Juang revise reduced grid and add x number -! - implicit none - - integer jcap,jcap1,jcap2,latg,latg2 - integer levh,levm1,levp1,skeblevs,levs,lnt,lnt2,lnt22,levr - integer lnte,lnted,lnto,lntod,lnuv - integer lonf,lonfx,num_p2d,num_p3d - integer nxpt,nypt,jintmx,latgd - integer ntoz,ntcw,ncld,ntke,ixgr,ntiw,ntlnc,ntinc,nto,nto2 - integer ivsupa, ivsinp - integer nlunit, kdt_start - integer,target :: ntrac - integer,target :: ngrids_gg - integer,target :: thermodyn_id, sfcpress_id ! hmhj - logical,target :: adiabatic -! - INTEGER p_gz,p_lapgz,p_zslam,p_zsphi,p_dlam,p_dphi,p_uln,p_vln - INTEGER p_zem,p_dim,p_tem,p_rm,p_dpm,p_qm - INTEGER p_ze ,p_di ,p_te ,p_rq,p_dp ,p_q - INTEGER p_w ,p_x ,p_y ,p_rt,p_dpn,p_zq - INTEGER p_zz ,p_dpphi,p_dplam,p_zzphi,p_zzlam - INTEGER g_uum,g_vvm,g_ttm,g_rm ,g_dpm,g_qm,g_gz,g_zz - INTEGER g_uu ,g_vv ,g_tt ,g_rq ,g_dp ,g_q - INTEGER g_uup,g_vvp,g_ttp,g_rqp,g_dpp,g_zqp,g_rqtk - INTEGER g_u ,g_v ,g_t ,g_rt ,g_dpn,g_zq, g_p, g_dpdt - INTEGER lots,lots_slg,lotd,lota,lotp,lotls,lotgr,lotgr6 - - integer ksz, ksd, kst, ksr, ksdp, ksq, ksplam, kspphi - integer ksu, ksv, kzslam, kzsphi -! - integer kau, kav, kat, kar, kadp, kaps, kazs, kap2 -! - integer kdpphi, kzzphi, kdplam, kzzlam -! - integer kdtphi, kdrphi, kdtlam, kdrlam - integer kdulam, kdvlam, kduphi, kdvphi - - - end module stochy_resol_def diff --git a/sumfln_stochy.f b/sumfln_stochy.f index f0d063c..f4bd783 100644 --- a/sumfln_stochy.f +++ b/sumfln_stochy.f @@ -15,11 +15,10 @@ subroutine sumfln_stochy(flnev,flnod,lat1s,plnev,plnod, & lats_node,ipt_lats_node, & lons_lat,londi,latl,nvars_0) ! - use stochy_resol_def , only : jcap,latgd - use spectral_layout_mod, only : len_trie_ls,len_trio_ls, - & ls_dim,ls_max_node,me,nodes + use spectral_layout_mod , only : len_trie_ls,len_trio_ls, + & ls_dim,ls_max_node,me, + & nodes,jcap use kinddef - use spectral_layout_mod, only : num_parthds_stochy => ompthreads use mpi_wrapper, only : mp_alltoall implicit none @@ -29,6 +28,7 @@ subroutine sumfln_stochy(flnev,flnod,lat1s,plnev,plnod, integer lat1s(0:jcap),latl2 ! integer nvars,nvars_0 + integer :: npes real(kind=kind_dbl_prec) flnev(len_trie_ls,2*nvars) real(kind=kind_dbl_prec) flnod(len_trio_ls,2*nvars) ! @@ -44,14 +44,12 @@ subroutine sumfln_stochy(flnev,flnod,lat1s,plnev,plnod, ! local scalars ! ------------- ! - integer j, k, l, lat, lat1, n, kn, n2,indev,indod + integer j, l, lat, lat1, n, kn, n2,indev,indod ! ! local arrays ! ------------ ! real(kind=kind_dbl_prec), dimension(nvars*2,latl2) :: apev, apod - integer num_threads, nvar_thread_max, nvar_1, nvar_2 - &, thread ! xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ! integer nvarsdim, latl, workdim, londi @@ -73,7 +71,7 @@ subroutine sumfln_stochy(flnev,flnod,lat1s,plnev,plnod, integer, dimension(nodes) :: kpts, kptr, sendcounts, recvcounts, & sdispls ! - integer ierr,ilat,ipt_ls, lmax,lval,i,jj,lonl,nv + integer ilat,ipt_ls, lmax,lval,jj,lonl,nv integer node,nvar,arrsz,my_pe integer ilat_list(nodes) ! for OMP buffer copy ! @@ -90,8 +88,6 @@ subroutine sumfln_stochy(flnev,flnod,lat1s,plnev,plnod, ! xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ! arrsz=2*nvars*ls_dim*workdim*nodes - num_threads = min(num_parthds_stochy,nvars) - nvar_thread_max = (nvars+num_threads-1)/num_threads kpts = 0 ! write(0,*)' londi=',londi,'nvarsdim=',nvarsdim,'workdim=',workdim ! @@ -107,14 +103,7 @@ subroutine sumfln_stochy(flnev,flnod,lat1s,plnev,plnod, lat1 = lat1s(l) if ( kind_dbl_prec == 8 ) then !------------------------------------ -!$omp parallel do num_threads(num_threads) -!$omp+private(thread,nvar_1,nvar_2,n2) - do thread=1,num_threads ! start of thread loop .............. - nvar_1 = (thread-1)*nvar_thread_max + 1 - nvar_2 = min(nvar_1+nvar_thread_max-1,nvars) - - if (nvar_2 >= nvar_1) then - n2 = 2*(nvar_2-nvar_1+1) + n2 = 2*nvars ! compute the even and odd components of the fourier coefficients ! @@ -133,12 +122,12 @@ subroutine sumfln_stochy(flnev,flnod,lat1s,plnev,plnod, & latl2-lat1+1, & (jcap+3-l)/2, & cons1, - & flnev(indev,2*nvar_1-1), + & flnev(indev,1), & len_trie_ls, & plnev(indev,lat1), & len_trie_ls, & cons0, - & apev(2*nvar_1-1,lat1), + & apev(1,lat1), & 2*nvars & ) ! @@ -157,25 +146,16 @@ subroutine sumfln_stochy(flnev,flnod,lat1s,plnev,plnod, & latl2-lat1+1, & (jcap+2-l)/2, & cons1, - & flnod(indod,2*nvar_1-1), + & flnod(indod,1), & len_trio_ls, & plnod(indod,lat1), & len_trio_ls, & cons0, - & apod(2*nvar_1-1,lat1), + & apod(1,lat1), & 2*nvars & ) ! endif - enddo ! end of thread loop .................................. - else !------------------------------------------------------------ -!$omp parallel do num_threads(num_threads) -!$omp+private(thread,nvar_1,nvar_2) - do thread=1,num_threads ! start of thread loop .............. - nvar_1 = (thread-1)*nvar_thread_max + 1 - nvar_2 = min(nvar_1+nvar_thread_max-1,nvars) - enddo ! end of thread loop .................................. - endif !----------------------------------------------------------- ! ccxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ! @@ -186,8 +166,7 @@ subroutine sumfln_stochy(flnev,flnod,lat1s,plnev,plnod, do node = 1, nodes - 1 ilat_list(node+1) = ilat_list(node) + lats_nodes(node) end do -!$omp parallel do num_threads(num_threads) -!$omp+private(node,jj,ilat,lat,ipt_ls,nvar,kn,n2) +!$omp parallel do private(node,jj,ilat,lat,ipt_ls,nvar,kn,n2) do node=1,nodes do jj=1,lats_nodes(node) ilat = ilat_list(node) + jj @@ -237,7 +216,7 @@ subroutine sumfln_stochy(flnev,flnod,lat1s,plnev,plnod, ! ! n2 = nvars + nvars -!$omp parallel do num_threads(num_threads) private(node) +!$omp parallel do private(node) do node=1,nodes sendcounts(node) = kpts(node) * n2 recvcounts(node) = kptr(node) * n2 @@ -245,12 +224,11 @@ subroutine sumfln_stochy(flnev,flnod,lat1s,plnev,plnod, end do work1dr(1:arrsz)=>workr work1ds(1:arrsz)=>works - call mp_alltoall(work1ds,sendcounts,sdispls, - & work1dr,recvcounts,sdispls) + call mp_alltoall(work1ds, sendcounts, sdispls, + & work1dr,recvcounts,sdispls) nullify(work1dr) nullify(work1ds) -!$omp parallel do num_threads(num_threads) -!$omp+private(j,lat,lmax,nvar,lval,n2,lonl,nv) +!$omp parallel do private(j,lat,lmax,nvar,lval,n2,lonl,nv) do j=1,lats_node lat = global_lats(ipt_lats_node-1+j) lonl = lons_lat(lat) @@ -274,8 +252,7 @@ subroutine sumfln_stochy(flnev,flnod,lat1s,plnev,plnod, kptr = 0 ! write(0,*)' kptr=',kptr(1) !! -!$omp parallel do num_threads(num_threads) -!$omp+private(node,l,lval,j,lat,nvar,kn,n2) +!$omp parallel do private(node,l,lval,j,lat,nvar,kn,n2) do node=1,nodes do l=1,max_ls_nodes(node) lval = ls_nodes(l,node)+1 From b516cb1f166cb1819eb238a4c7177e4375e12524 Mon Sep 17 00:00:00 2001 From: pjpegion Date: Mon, 14 Dec 2020 15:30:30 +0000 Subject: [PATCH 02/13] netcdf restart for atmosphere and land work --- CMakeLists.txt | 2 - compns_stochy.F90 | 11 +- four_to_grid_stochy.F | 2 +- get_stochy_pattern.F90 | 331 ++++++++++++------- getcon_spectral.F90 | 2 - spectral_layout.F90 | 2 - standalone_stochy.F90 | 4 +- stochastic_physics.F90 | 141 ++++----- stochy_data_mod.F90 | 681 ++++++++++++++++++++++++++-------------- stochy_gg_def.f | 10 - stochy_layout_lag.f | 14 - stochy_namelist_def.F90 | 2 +- 12 files changed, 740 insertions(+), 462 deletions(-) delete mode 100644 stochy_gg_def.f delete mode 100644 stochy_layout_lag.f diff --git a/CMakeLists.txt b/CMakeLists.txt index ad5c36e..6e3328c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,8 +16,6 @@ list(APPEND _stoch_phys_srcs mpi_wrapper.F90 halo_exchange.fv3.F90 plumes.f90 - stochy_gg_def.f - stochy_layout_lag.f four_to_grid_stochy.F glats_stochy.f sumfln_stochy.f diff --git a/compns_stochy.F90 b/compns_stochy.F90 index d078050..888d868 100644 --- a/compns_stochy.F90 +++ b/compns_stochy.F90 @@ -57,7 +57,7 @@ subroutine compns_stochy (me,sz_nml,input_nml_file,fn_nml,nlunit,deltim,iret) ! namelist /nam_stochy/ntrunc,lon_s,lat_s,sppt,sppt_tau,sppt_lscale,sppt_logit, & iseed_shum,iseed_sppt,shum,shum_tau,& - shum_lscale,fhstoch,stochini,skeb_varspect_opt,sppt_sfclimit, & + shum_lscale,stochini,skeb_varspect_opt,sppt_sfclimit, & skeb,skeb_tau,skeb_vdof,skeb_lscale,iseed_skeb,skeb_vfilt,skeb_diss_smooth, & skeb_sigtop1,skeb_sigtop2,skebnorm,sppt_sigtop1,sppt_sigtop2,& shum_sigefold,spptint,shumint,skebint,skeb_npass,use_zmtnblck,new_lscale, & @@ -132,21 +132,20 @@ subroutine compns_stochy (me,sz_nml,input_nml_file,fn_nml,nlunit,deltim,iret) ! length scale. skeb_varspect_opt = 0 sppt_logit = .false. ! logit transform for sppt to bounded interval [-1,+1] - fhstoch = -999.0 ! forecast interval (in hours) to dump random patterns stochini = .false. ! true= read in pattern, false=initialize from seed #ifdef INTERNAL_FILE_NML read(input_nml_file, nml=nam_stochy) #else rewind (nlunit) - open (unit=nlunit, file=fn_nml, READONLY, status='OLD', iostat=ios) + open (unit=nlunit, file=fn_nml, action='READ', status='OLD', iostat=ios) read(nlunit,nam_stochy) #endif #ifdef INTERNAL_FILE_NML read(input_nml_file, nml=nam_sfcperts) #else rewind (nlunit) - open (unit=nlunit, file=fn_nml, READONLY, status='OLD', iostat=ios) + open (unit=nlunit, file=fn_nml, action='READ', status='OLD', iostat=ios) read(nlunit,nam_sfcperts) #endif @@ -374,7 +373,7 @@ subroutine compns_stochy_ocn (deltim,iret) ! namelist /nam_stochy/ntrunc,lon_s,lat_s,sppt,sppt_tau,sppt_lscale,sppt_logit, & iseed_shum,iseed_sppt,shum,shum_tau, & - shum_lscale,fhstoch,stochini,skeb_varspect_opt,sppt_sfclimit, & + shum_lscale,stochini,skeb_varspect_opt,sppt_sfclimit, & skeb,skeb_tau,skeb_vdof,skeb_lscale,iseed_skeb,skeb_vfilt,skeb_diss_smooth, & skeb_sigtop1,skeb_sigtop2,skebnorm,sppt_sigtop1,sppt_sigtop2,& shum_sigefold,spptint,shumint,skebint,skeb_npass,use_zmtnblck,new_lscale, & @@ -410,7 +409,7 @@ subroutine compns_stochy_ocn (deltim,iret) iseed_epbl2 = 0 ! random seeds (if 0 use system clock) iseed_ocnsppt = 0 ! random seeds (if 0 use system clock) rewind (nlunit) - open (unit=nlunit, file='input.nml', READONLY, status='OLD', iostat=ios) + open (unit=nlunit, file='input.nml', action='READ', status='OLD', iostat=ios) read(nlunit,nam_stochy) if (mpp_pe()==mpp_root_pe()) then diff --git a/four_to_grid_stochy.F b/four_to_grid_stochy.F index 3453968..3d6283b 100644 --- a/four_to_grid_stochy.F +++ b/four_to_grid_stochy.F @@ -11,7 +11,7 @@ module four_to_grid_mod subroutine four_to_grid(syn_gr_a_1,syn_gr_a_2, & lon_dim_coef,lon_dim_grid,lons_lat,lot) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - use machine + use kinddef implicit none !! real(kind=kind_dbl_prec) syn_gr_a_1(lon_dim_coef,lot) diff --git a/get_stochy_pattern.F90 b/get_stochy_pattern.F90 index 6b3e6af..fe1d7b3 100644 --- a/get_stochy_pattern.F90 +++ b/get_stochy_pattern.F90 @@ -7,19 +7,16 @@ module get_stochy_pattern_mod coslat_a, latg, latg2, levs, lonf, skeblevs use stochy_namelist_def, only : n_var_lndp, ntrunc, stochini use stochy_data_mod, only : gg_lats, gg_lons, inttyp, nskeb, nshum, nsppt, & - rnlat, rpattern_sfc, rpattern_skeb, & - rpattern_shum, rpattern_sppt, skebu_save, & + nocnsppt,nepbl,nlndp, & + rnlat, rpattern_sfc, rpattern_skeb, & + rpattern_shum, rpattern_sppt, rpattern_ocnsppt,& + rpattern_epbl1, rpattern_epbl2, skebu_save, & skebv_save, skeb_vwts, skeb_vpts, wlon use stochy_patterngenerator_mod, only: random_pattern, ndimspec, & patterngenerator_advance use stochy_internal_state_mod, only: stochy_internal_state - use mpp_mod,only: mpp_npes,mpp_pe,mpp_root_pe,mpp_sum -#ifdef STOCHY_UNIT_TEST - use standalone_stochy_module, only: GFS_control_type, GFS_grid_type,random_seed -#else - use GFS_typedefs, only: GFS_control_type, GFS_grid_type + use mpi_wrapper, only : mp_reduce_sum,is_master use mersenne_twister, only: random_seed -#endif use dezouv_stochy_mod, only: dezouv_stochy use dozeuv_stochy_mod, only: dozeuv_stochy use four_to_grid_mod, only: four_to_grid @@ -29,7 +26,7 @@ module get_stochy_pattern_mod public get_random_pattern_vector public get_random_pattern_sfc,get_random_pattern_scalar - public dump_patterns + public write_stoch_restart_atm,write_stoch_restart_ocn logical :: first_call=.true. contains @@ -60,7 +57,8 @@ subroutine get_random_pattern_sfc(rpattern,npatterns,& kmsk0 = 0 glolal = 0. do n=1,npatterns - if (mpp_pe()==mpp_root_pe()) print *, 'Random pattern for SFC-PERTS in get_random_pattern_sfc: k, min, max ',k,minval(rpattern_sfc(n)%spec_o(:,:,k)), maxval(rpattern_sfc(n)%spec_o(:,:,k)) + call patterngenerator_advance(rpattern(n),k,.false.) + if (is_master()) print *, 'Random pattern for LNDP PERTS in get_random_pattern_fv3_sfc: k, min, max ',k,minval(rpattern_sfc(n)%spec_o(:,:,k)), maxval(rpattern_sfc(n)%spec_o(:,:,k)) call scalarspect_to_gaugrid( & rpattern(n)%spec_e(:,:,k),rpattern(n)%spec_o(:,:,k),wrk2d,& gis_stochy%ls_node,gis_stochy%ls_nodes,gis_stochy%max_ls_nodes,& @@ -78,21 +76,21 @@ subroutine get_random_pattern_sfc(rpattern,npatterns,& enddo enddo - call mpp_sum(workg,lonf*latg) - if (mpp_pe()==mpp_root_pe()) print *, 'workg after mpp_sum for SFC-PERTS in get_random_pattern_sfc: k, min, max ',k,minval(workg), maxval(workg) + call mp_reduce_sum(workg,lonf,latg) + if (is_master()) print *, 'workg after mp_reduce_sum for LNDP PERTS in get_random_pattern_fv3_sfc: k, min, max ',k,minval(workg), maxval(workg) ! interpolate to cube grid do j=1,gis_stochy%ny pattern_1d = 0 - associate( tlats=>gis_stochy%parent_lats(:,j),& - tlons=>gis_stochy%parent_lons(:,j)) + associate( tlats=>gis_stochy%parent_lats(1:gis_stochy%len(j),j),& + tlons=>gis_stochy%parent_lons(1:gis_stochy%len(j),j)) call stochy_la2ga(workg,lonf,latg,gg_lons,gg_lats,wlon,rnlat,& pattern_1d(1:gis_stochy%len(j)),gis_stochy%len(j),tlats,tlons) pattern_3d(:,j,k)=pattern_1d(:) end associate enddo - if (mpp_pe()==mpp_root_pe()) print *, '3D pattern for SFC-PERTS in get_random_pattern_sfc: k, min, max ',k,minval(pattern_3d(:,:,k)), maxval(pattern_3d(:,:,k)) + if (is_master()) print *, '3D pattern for LNDP PERTS in get_random_pattern_fv3_sfc: k, min, max ',k,minval(pattern_3d(:,:,k)), maxval(pattern_3d(:,:,k)) deallocate(workg) enddo ! loop over k, n_var_lndp @@ -128,7 +126,7 @@ subroutine get_random_pattern_vector(rpattern,npatterns,& kmsk0 = 0 allocate(workgu(lonf,latg)) allocate(workgv(lonf,latg)) - print*,'before first_call',skeblevs + divspec_e = 0; divspec_o = 0. if (first_call) then allocate(skebu_save(gis_stochy%nx,gis_stochy%ny,skeblevs)) allocate(skebv_save(gis_stochy%nx,gis_stochy%ny,skeblevs)) @@ -138,7 +136,6 @@ subroutine get_random_pattern_vector(rpattern,npatterns,& do n=1,npatterns if (.not. stochini) call patterngenerator_advance(rpattern(n),k,first_call) ! ke norm (convert streamfunction forcing to vorticity forcing) - divspec_e = 0; divspec_o = 0. do nn=1,2 vrtspec_e(:,nn,1) = gis_stochy%kenorm_e*rpattern(n)%spec_e(:,nn,k) vrtspec_o(:,nn,1) = gis_stochy%kenorm_o*rpattern(n)%spec_o(:,nn,k) @@ -151,30 +148,30 @@ subroutine get_random_pattern_vector(rpattern,npatterns,& gis_stochy%lats_nodes_a,gis_stochy%global_lats_a,gis_stochy%lonsperlat,& gis_stochy%epsedn,gis_stochy%epsodn,gis_stochy%snnp1ev,gis_stochy%snnp1od,& gis_stochy%plnev_a,gis_stochy%plnod_a,1) - do i=1,lonf - do j=1,gis_stochy%lats_node_a - lat=gis_stochy%global_lats_a(ipt_lats_node_a-1+j) - workgu(i,lat) = workgu(i,lat) + wrk2du(i,j,1) - workgv(i,lat) = workgv(i,lat) + wrk2dv(i,j,1) + do i=1,lonf + do j=1,gis_stochy%lats_node_a + lat=gis_stochy%global_lats_a(ipt_lats_node_a-1+j) + workgu(i,lat) = workgu(i,lat) + wrk2du(i,j,1) + workgv(i,lat) = workgv(i,lat) + wrk2dv(i,j,1) + enddo enddo enddo + call mp_reduce_sum(workgu,lonf,latg) + call mp_reduce_sum(workgv,lonf,latg) + ! interpolate to cube grid + do j=1,gis_stochy%ny + pattern_1d = 0 + associate( tlats=>gis_stochy%parent_lats(1:gis_stochy%len(j),j),& + tlons=>gis_stochy%parent_lons(1:gis_stochy%len(j),j)) + call stochy_la2ga(workgu,lonf,latg,gg_lons,gg_lats,wlon,rnlat,& + pattern_1d(1:gis_stochy%len(j)),gis_stochy%len(j),tlats,tlons) + skebu_save(:,j,k)=pattern_1d(:) + call stochy_la2ga(workgv,lonf,latg,gg_lons,gg_lats,wlon,rnlat,& + pattern_1d(1:gis_stochy%len(j)),gis_stochy%len(j),tlats,tlons) + skebv_save(:,j,k)=-1*pattern_1d(:) + end associate + enddo enddo - call mpp_sum(workgu,lonf*latg) - call mpp_sum(workgv,lonf*latg) -! interpolate to cube grid - do j=1,gis_stochy%ny - pattern_1d = 0 - associate( tlats=>gis_stochy%parent_lats(1:gis_stochy%len(j),j),& - tlons=>gis_stochy%parent_lons(1:gis_stochy%len(j),j)) - call stochy_la2ga(workgu,lonf,latg,gg_lons,gg_lats,wlon,rnlat,& - pattern_1d(1:gis_stochy%len(j)),gis_stochy%len(j),tlats,tlons) - skebu_save(:,j,k)=pattern_1d(:) - call stochy_la2ga(workgv,lonf,latg,gg_lons,gg_lats,wlon,rnlat,& - pattern_1d(1:gis_stochy%len(j)),gis_stochy%len(j),tlats,tlons) - skebv_save(:,j,k)=-1*pattern_1d(:) - end associate - enddo - enddo endif do k=1,skeblevs-1 skebu_save(:,:,k)=skebu_save(:,:,k+1) @@ -184,18 +181,12 @@ subroutine get_random_pattern_vector(rpattern,npatterns,& rpattern(n)%spec_o(:,:,k)=rpattern(n)%spec_o(:,:,k+1) enddo enddo - -! get pattern for last level + ! get pattern for last level workgu = 0. workgv = 0. do n=1,npatterns -! if (stochini.AND. first_call) then -! print*,'skipping advance' -! else - print*,'advancing' call patterngenerator_advance(rpattern(n),skeblevs,first_call) -! endif -! ke norm (convert streamfunction forcing to vorticity forcing) + ! ke norm (convert streamfunction forcing to vorticity forcing) divspec_e = 0; divspec_o = 0. do nn=1,2 vrtspec_e(:,nn,1) = gis_stochy%kenorm_e*rpattern(n)%spec_e(:,nn,skeblevs) @@ -217,9 +208,9 @@ subroutine get_random_pattern_vector(rpattern,npatterns,& enddo enddo enddo - call mpp_sum(workgu,lonf*latg) - call mpp_sum(workgv,lonf*latg) -! interpolate to cube grid + call mp_reduce_sum(workgu,lonf,latg) + call mp_reduce_sum(workgv,lonf,latg) + ! interpolate to cube grid do j=1,gis_stochy%ny pattern_1d = 0 associate( tlats=>gis_stochy%parent_lats(:,j),& @@ -234,15 +225,14 @@ subroutine get_random_pattern_vector(rpattern,npatterns,& enddo deallocate(workgu) deallocate(workgv) -! interpolate in the vertical ! consider moving to cubed sphere side, more memory, but less interpolations - print*,'looping through levs' - do k=1,levs - do j=1,gis_stochy%ny - upattern_3d(:,j,k) = skeb_vwts(k,1)*skebu_save(:,j,skeb_vpts(k,1))+skeb_vwts(k,2)*skebu_save(:,j,skeb_vpts(k,2)) - vpattern_3d(:,j,k) = skeb_vwts(k,1)*skebv_save(:,j,skeb_vpts(k,1))+skeb_vwts(k,2)*skebv_save(:,j,skeb_vpts(k,2)) - enddo - enddo - first_call=.false. + ! interpolate in the vertical ! consider moving to cubed sphere side, more memory, but less interpolations + do k=1,levs + do j=1,gis_stochy%ny + upattern_3d(:,j,k) = skeb_vwts(k,1)*skebu_save(:,j,skeb_vpts(k,1))+skeb_vwts(k,2)*skebu_save(:,j,skeb_vpts(k,2)) + vpattern_3d(:,j,k) = skeb_vwts(k,1)*skebv_save(:,j,skeb_vpts(k,1))+skeb_vwts(k,2)*skebv_save(:,j,skeb_vpts(k,2)) + enddo + enddo + first_call=.false. end subroutine get_random_pattern_vector @@ -268,7 +258,7 @@ subroutine get_random_pattern_scalar(rpattern,npatterns,& real(kind=kind_dbl_prec) :: pattern_2d(gis_stochy%nx,gis_stochy%ny) real(kind=kind_dbl_prec) :: pattern_1d(gis_stochy%nx) pe_print=111 - !if (mpp_pe()==pe_print) then + !if (is_master()) then ! print*,'in get_random_pattern_scalar',npatterns ! print*,'nx,ny',gis_stochy%nx,gis_stochy%ny !endif @@ -294,48 +284,19 @@ subroutine get_random_pattern_scalar(rpattern,npatterns,& enddo enddo - call mpp_sum(workg,lonf*latg) - !if (mpp_pe()==pe_print) then - ! print*,'before interpolate',maxval(workg),minval(workg) - !endif + call mp_reduce_sum(workg,lonf,latg) ! interpolate to cube grid - ! if (mpp_pe()==pe_print) then - ! write(34) real(workg,kind=4) - ! endif do j=1,gis_stochy%ny pattern_1d = 0 associate( tlats=>gis_stochy%parent_lats(1:gis_stochy%len(j),j),& tlons=>gis_stochy%parent_lons(1:gis_stochy%len(j),j)) - ! if (mpp_pe()==pe_print) then - ! if (j.EQ.1.OR.j.EQ.gis_stochy%ny) then - ! !if (j.GT.100) then - ! do i=1,gis_stochy%len(j) - ! print*,'lat,lon',j,gis_stochy%parent_lats(i,j),gis_stochy%parent_lons(i,j) - ! print*,'lats',j,minval(gis_stochy%parent_lats(1:gis_stochy%len(j),j)),maxval(gis_stochy%parent_lats(1:gis_stochy%len(j),j)) - ! print*,'lons',j,minval(gis_stochy%parent_lons(1:gis_stochy%len(j),j)),maxval(gis_stochy%parent_lons(1:gis_stochy%len(j),j)) - ! !print*,'lonf,latg',lonf,latg,gis_stochy%nx,gis_stochy%ny,gis_stochy%len(j) - ! enddo - ! endif - ! endif call stochy_la2ga(workg,lonf,latg,gg_lons,gg_lats,wlon,rnlat,& pattern_1d(1:gis_stochy%len(j)),gis_stochy%len(j),tlats,tlons) pattern_2d(:,j)=pattern_1d(:) - ! if (mpp_pe()==pe_print) then - ! print*,'gg_lats=',gg_lats(1),gg_lats(latg) - ! print*,'after interpolate',j,maxval(pattern_1d),minval(pattern_1d) - ! if (j.GT.110) then - ! do i=1,gis_stochy%len(j) - ! print*,'lat,lon',j,gis_stochy%parent_lats(i,j),gis_stochy%parent_lons(i,j),pattern_1d(i) - ! enddo - ! endif - ! endif end associate enddo deallocate(workg) - !if (mpp_pe()==pe_print) then - ! print*,'outside loop',mpp_pe(),maxval(pattern_2d),minval(pattern_2d) - !endif end subroutine get_random_pattern_scalar ! @@ -396,51 +357,192 @@ subroutine scalarspect_to_gaugrid(& return end subroutine scalarspect_to_gaugrid -!>@brief The subroutine 'dump_patterns' writes out the speherical harmonics to a file, controlled by FHSTOCH + +!>@brief The subroutine 'write_patterns' writes out a single pattern and the seed associated with the random number sequence in netcdf +!>@brief The subroutine 'write_stoch_restart_atm' writes out the speherical harmonics to a file, controlled by restart_interval !>@details Only the active patterns are written out -subroutine dump_patterns(sfile) +subroutine write_stoch_restart_atm(sfile) !\callgraph + use netcdf + use stochy_namelist_def, only : do_sppt,do_shum,do_skeb,lndp_type implicit none - character*120 :: sfile - integer :: stochlun,k,n + character(len=*) :: sfile + integer :: stochlun,k,n,isize,ierr + integer :: ncid,varid1a,varid1b,varid2a,varid2b,varid3a,varid3b,varid4a,varid4b + integer :: seed_dim_id,spec_dim_id,zt_dim_id,ztsfc_dim_id,np_dim_id,npsfc_dim_id + include 'netcdf.inc' + + if ( ( .NOT. do_sppt) .AND. (.NOT. do_shum) .AND. (.NOT. do_skeb) .AND. (lndp_type==0 ) ) return stochlun=99 - if (mpp_pe()==mpp_root_pe()) then + if (is_master()) then if (nsppt > 0 .OR. nshum > 0 .OR. nskeb > 0) then - OPEN(stochlun,file=sfile,form='unformatted') + ierr=nf90_create(trim(sfile),cmode=NF90_CLOBBER,ncid=ncid) print*,'open ',sfile,' for output' + ierr=NF90_PUT_ATT(ncid,NF_GLOBAL,"ntrunc",ntrunc) + call random_seed(size=isize) ! get seed size + ierr=NF90_DEF_DIM(ncid,"len_seed",isize,seed_dim_id) + ierr=NF90_PUT_ATT(ncid,seed_dim_id,"long_name","length of random seed") + ierr=NF90_DEF_DIM(ncid,"num_patterns",NF_UNLIMITED,np_dim_id) ! should be 5 + ierr=NF90_PUT_ATT(ncid,np_dim_id,"long_name","number of random patterns (max of 5)") + if (lndp_type .NE. 0) then + ierr=NF90_DEF_DIM(ncid,"num_patterns_sfc",nlndp,npsfc_dim_id) ! should be 5 + ierr=NF90_PUT_ATT(ncid,npsfc_dim_id,"long_name","number of random patterns for surface)") + ierr=NF90_DEF_DIM(ncid,"n_var_lndp",n_var_lndp,ztsfc_dim_id) + ierr=NF90_PUT_ATT(ncid,ztsfc_dim_id,"long_name","number of sfc perturbation types") + endif + ierr=NF90_DEF_DIM(ncid,"ndimspecx2",2*ndimspec,spec_dim_id) + ierr=NF90_PUT_ATT(ncid,spec_dim_id,"long_name","number of spectral cofficients") + if (do_sppt) then + ierr=NF90_DEF_VAR(ncid,"sppt_seed",NF90_DOUBLE,(/seed_dim_id, np_dim_id/), varid1a) + ierr=NF90_PUT_ATT(ncid,varid1a,"long_name","random number seed for SPPT") + ierr=NF90_DEF_VAR(ncid,"sppt_spec",NF90_DOUBLE,(/spec_dim_id, np_dim_id/), varid1b) + ierr=NF90_PUT_ATT(ncid,varid1b,"long_name","spectral cofficients SPPT") + endif + if (do_shum) then + ierr=NF90_DEF_VAR(ncid,"shum_seed",NF90_DOUBLE,(/seed_dim_id, np_dim_id/), varid2a) + ierr=NF90_PUT_ATT(ncid,varid2a,"long_name","random number seed for SHUM") + ierr=NF90_DEF_VAR(ncid,"shum_spec",NF90_DOUBLE,(/spec_dim_id, np_dim_id/), varid2b) + ierr=NF90_PUT_ATT(ncid,varid2b,"long_name","spectral cofficients SHUM") + endif + if (do_skeb) then + ierr=NF90_DEF_DIM(ncid,"skeblevs",skeblevs,zt_dim_id) + ierr=NF90_PUT_ATT(ncid,zt_dim_id,"long_name","number of vertical levels for SKEB") + ierr=NF90_DEF_VAR(ncid,"skeb_seed",NF90_DOUBLE,(/seed_dim_id, zt_dim_id,np_dim_id/), varid3a) + ierr=NF90_PUT_ATT(ncid,varid3a,"long_name","random number seed for SKEB") + ierr=NF90_DEF_VAR(ncid,"skeb_spec",NF90_DOUBLE,(/spec_dim_id, zt_dim_id,np_dim_id/), varid3b) + ierr=NF90_PUT_ATT(ncid,varid3b,"long_name","spectral cofficients SKEB") + endif + if (nlndp>0) then + ierr=NF90_DEF_VAR(ncid,"sfcpert_seed",NF90_DOUBLE,(/seed_dim_id, ztsfc_dim_id, npsfc_dim_id/), varid4a) + ierr=NF90_PUT_ATT(ncid,varid4a,"long_name","random number seed for SHUM") + ierr=NF90_DEF_VAR(ncid,"sfcpert_spec",NF90_DOUBLE,(/spec_dim_id, ztsfc_dim_id, npsfc_dim_id/), varid4b) + ierr=NF90_PUT_ATT(ncid,varid4b,"long_name","spectral cofficients SHUM") + endif + ierr=NF90_ENDDEF(ncid) + if (ierr .NE. 0) then + write(0,*) 'error creating stochastic restart file' + return + end if endif endif if (nsppt > 0) then do n=1,nsppt - call write_pattern(rpattern_sppt(n),1,stochlun) + call write_pattern(rpattern_sppt(n),ncid,1,n,varid1a,varid1b,.false.,ierr) enddo endif if (nshum > 0) then do n=1,nshum - call write_pattern(rpattern_shum(n),1,stochlun) + call write_pattern(rpattern_shum(n),ncid,1,n,varid2a,varid2b,.false.,ierr) enddo endif if (nskeb > 0) then do n=1,nskeb - do k=1,skeblevs - call write_pattern(rpattern_skeb(n),k,stochlun) + do k=1,skeblevs + call write_pattern(rpattern_skeb(n),ncid,k,n,varid3a,varid3b,.true.,ierr) + enddo + enddo + endif + if (lndp_type .NE. 0 .AND. nlndp>0) then + do n=1,nlndp + do k=1,n_var_lndp + call write_pattern(rpattern_sfc(n),ncid,k,n,varid4a,varid4b,.true.,ierr) + enddo enddo + endif + if (is_master() ) then + ierr=NF90_CLOSE(ncid) + if (ierr .NE. 0) then + write(0,*) 'error writing patterns and closing file' + return + endif + endif + end subroutine write_stoch_restart_atm + + +!>@brief The subroutine 'write_stoch_restart_ocn' writes out the speherical harmonics to a file, controlled by restart_interval +!>@details Only the active patterns are written out +subroutine write_stoch_restart_ocn(sfile) +!\callgraph + use netcdf + use stochy_namelist_def, only : do_ocnsppt,do_epbl + implicit none + character(len=*) :: sfile + integer :: stochlun,k,n,isize,ierr + integer :: ncid,varid1a,varid1b,varid2a,varid2b,varid3a,varid3b + integer :: seed_dim_id,spec_dim_id,np_dim_id + include 'netcdf.inc' + + if ( ( .NOT. do_ocnsppt) .AND. (.NOT. do_epbl) ) return + stochlun=99 + if (is_master()) then + ierr=nf90_create(trim(sfile),cmode=NF90_CLOBBER,ncid=ncid) + print*,'open ',sfile,' for output' + ierr=NF90_PUT_ATT(ncid,NF_GLOBAL,"ntrunc",ntrunc) + call random_seed(size=isize) ! get seed size + ierr=NF90_DEF_DIM(ncid,"len_seed",isize,seed_dim_id) + ierr=NF90_PUT_ATT(ncid,seed_dim_id,"long_name","length of random seed") + ierr=NF90_DEF_DIM(ncid,"num_patterns",NF_UNLIMITED,np_dim_id) ! should be 5 + ierr=NF90_PUT_ATT(ncid,np_dim_id,"long_name","number of random patterns (max of 5)") + ierr=NF90_DEF_DIM(ncid,"ndimspecx2",2*ndimspec,spec_dim_id) + ierr=NF90_PUT_ATT(ncid,spec_dim_id,"long_name","number of spectral cofficients") + if (do_ocnsppt) then + ierr=NF90_DEF_VAR(ncid,"ocnsppt_seed",NF90_DOUBLE,(/seed_dim_id, np_dim_id/), varid1a) + ierr=NF90_PUT_ATT(ncid,varid1a,"long_name","random number seed for SPPT") + ierr=NF90_DEF_VAR(ncid,"ocnsppt_spec",NF90_DOUBLE,(/spec_dim_id, np_dim_id/), varid1b) + ierr=NF90_PUT_ATT(ncid,varid1b,"long_name","spectral cofficients SPPT") + endif + if (do_epbl) then + ierr=NF90_DEF_VAR(ncid,"epbl1_seed",NF90_DOUBLE,(/seed_dim_id, np_dim_id/), varid2a) + ierr=NF90_PUT_ATT(ncid,varid2a,"long_name","random number seed for EPBL1") + ierr=NF90_DEF_VAR(ncid,"epbl1_spec",NF90_DOUBLE,(/spec_dim_id, np_dim_id/), varid2b) + ierr=NF90_PUT_ATT(ncid,varid2b,"long_name","spectral cofficients EPBL1") + ierr=NF90_DEF_VAR(ncid,"epbl1_seed",NF90_DOUBLE,(/seed_dim_id, np_dim_id/), varid3a) + ierr=NF90_PUT_ATT(ncid,varid3a,"long_name","random number seed for EPBL2") + ierr=NF90_DEF_VAR(ncid,"epbl1_spec",NF90_DOUBLE,(/spec_dim_id, np_dim_id/), varid3b) + ierr=NF90_PUT_ATT(ncid,varid3b,"long_name","spectral cofficients EPBL2") + endif + ierr=NF90_ENDDEF(ncid) + if (ierr .NE. 0) then + write(0,*) 'error creating stochastic restart file' + return + end if + endif + if (nocnsppt > 0) then + do n=1,nocnsppt + call write_pattern(rpattern_ocnsppt(n),ncid,1,n,varid1a,varid1b,.false.,ierr) enddo endif - close(stochlun) - end subroutine dump_patterns + if (nepbl > 0) then + do n=1,nepbl + call write_pattern(rpattern_epbl1(n),ncid,1,n,varid2a,varid2b,.false.,ierr) + call write_pattern(rpattern_epbl2(n),ncid,1,n,varid3a,varid3b,.false.,ierr) + enddo + endif + if (is_master() ) then + ierr=NF90_CLOSE(ncid) + if (ierr .NE. 0) then + write(0,*) 'error writing patterns and closing file' + return + endif + endif + end subroutine write_stoch_restart_ocn !>@brief The subroutine 'write_patterns' writes out a single pattern and the seed associated with the random number sequence !>@details Spherical harminoncs are stored with trianglular truncation - subroutine write_pattern(rpattern,lev,lunptn) + subroutine write_pattern(rpattern,outlun,lev,np,varid1,varid2,slice_of_3d,iret) !\callgraph + use netcdf implicit none type(random_pattern), intent(inout) :: rpattern - integer, intent(in) :: lunptn,lev + integer, intent(in) :: outlun,lev + integer, intent(in) :: np,varid1,varid2 + logical, intent(in) :: slice_of_3d + integer, intent(out) :: iret real(kind_dbl_prec), allocatable :: pattern2d(:) - integer nm,nn,arrlen,isize + integer nm,nn,arrlen,isize,ierr integer,allocatable :: isave(:) + include 'netcdf.inc' arrlen=2*ndimspec - + iret=0 allocate(pattern2d(arrlen)) pattern2d=0.0 ! fill in apprpriate pieces of array @@ -458,18 +560,27 @@ subroutine write_pattern(rpattern,lev,lunptn) pattern2d(nm) = rpattern%spec_o(nn,1,lev) pattern2d(ndimspec+nm) = rpattern%spec_o(nn,2,lev) enddo - call mpp_sum(pattern2d,arrlen) + call mp_reduce_sum(pattern2d,arrlen) ! write only on root process - if (mpp_pe()==mpp_root_pe()) then + if (is_master()) then print*,'writing out random pattern (min/max/size)',& minval(pattern2d),maxval(pattern2d),size(pattern2d) !print*,'max/min pattern=',maxval(pattern2d),minval(pattern2d) - write(lunptn) ntrunc call random_seed(size=isize) ! get seed size allocate(isave(isize)) ! get seed call random_seed(get=isave,stat=rpattern%rstate) ! write seed - write(lunptn) isave - write(lunptn) pattern2d + ierr=NF90_PUT_VAR(outlun,varid1,isave,(/1,np/)) + print*,'put seed',ierr,np + if (slice_of_3d) then + ierr=NF90_PUT_VAR(outlun,varid2,pattern2d,(/1,lev,np/)) + else + ierr=NF90_PUT_VAR(outlun,varid2,pattern2d,(/1,np/)) + endif + if (ierr .NE. 0) then + write(0,*) 'error writing to stochastic restart file' + iret = ierr + return + end if endif deallocate(pattern2d) end subroutine write_pattern diff --git a/getcon_spectral.F90 b/getcon_spectral.F90 index 857b4a7..ddb9545 100644 --- a/getcon_spectral.F90 +++ b/getcon_spectral.F90 @@ -120,8 +120,6 @@ subroutine getcon_spectral ( ls_node,ls_nodes,max_ls_nodes, & enddo latsmax = lats_node_a_max -! - ipt_lats_node_ext = 1 ! ipt_lats_node_a = 1 if ( me > 0 ) then diff --git a/spectral_layout.F90 b/spectral_layout.F90 index 2116690..f847776 100644 --- a/spectral_layout.F90 +++ b/spectral_layout.F90 @@ -26,8 +26,6 @@ module spectral_layout_mod len_trie_ls_max, & len_trio_ls_max, & lats_dim_ext, & - lats_node_ext, & - ipt_lats_node_ext, & jcap,latg,latg2, & skeblevs,levs,lnt, & lonf,lonfx, & diff --git a/standalone_stochy.F90 b/standalone_stochy.F90 index 8b4b248..d72e900 100644 --- a/standalone_stochy.F90 +++ b/standalone_stochy.F90 @@ -31,7 +31,7 @@ program standalone_stochy real(kind=kind_dbl_prec) :: skeb_sigtop1,skeb_sigtop2, & sppt_sigtop1,sppt_sigtop2,shum_sigefold, & skeb_vdof -real(kind=kind_dbl_prec) fhstoch,skeb_diss_smooth,spptint,shumint,skebint,skebnorm +real(kind=kind_dbl_prec) skeb_diss_smooth,spptint,shumint,skebint,skebnorm real(kind=kind_dbl_prec), dimension(5) :: skeb,skeb_lscale,skeb_tau real(kind=kind_dbl_prec), dimension(5) :: sppt,sppt_lscale,sppt_tau real(kind=kind_dbl_prec), dimension(5) :: shum,shum_lscale,shum_tau @@ -82,7 +82,7 @@ program standalone_stochy namelist /nam_stochy/ntrunc,lon_s,lat_s,sppt,sppt_tau,sppt_lscale,sppt_logit, & iseed_shum,iseed_sppt,shum,shum_tau,& - shum_lscale,fhstoch,stochini,skeb_varspect_opt,sppt_sfclimit, & + shum_lscale,stochini,skeb_varspect_opt,sppt_sfclimit, & skeb,skeb_tau,skeb_vdof,skeb_lscale,iseed_skeb,skeb_vfilt,skeb_diss_smooth, & skeb_sigtop1,skeb_sigtop2,skebnorm,sppt_sigtop1,sppt_sigtop2,& shum_sigefold,spptint,shumint,skebint,skeb_npass,use_zmtnblck,new_lscale diff --git a/stochastic_physics.F90 b/stochastic_physics.F90 index c83a3cb..2eadf92 100644 --- a/stochastic_physics.F90 +++ b/stochastic_physics.F90 @@ -78,7 +78,7 @@ subroutine init_stochastic_physics(levs, blksz, dtp, input_nml_file_in, fn_nml, allocate(gis_stochy%len(nblks)) allocate(gis_stochy%parent_lons(gis_stochy%nx,gis_stochy%ny)) allocate(gis_stochy%parent_lats(gis_stochy%nx,gis_stochy%ny)) -print*,'in init_stochastic_physics',gis_stochy%nx,gis_stochy%ny +print*,'in init_stochastic_physics',minval(xlon),maxval(xlon),minval(xlat),maxval(xlat) do blk=1,nblks len=blksz(blk) gis_stochy%parent_lons(1:len,blk)=xlon(blk,1:len)*rad2deg @@ -238,7 +238,6 @@ subroutine init_stochastic_physics_ocn(delt,geoLonT,geoLatT,nx,ny,nz,do_epbl_out use spectral_layout_mod , only : latg,lonf,colrad_a,me,nodes !use MOM_grid, only : ocean_grid_type use stochy_namelist_def -use physcons, only: con_pi use mersenne_twister, only: random_gauss use mpi_wrapper, only : mpi_wrapper_initialize,mype,npes,is_master @@ -249,6 +248,7 @@ subroutine init_stochastic_physics_ocn(delt,geoLonT,geoLatT,nx,ny,nz,do_epbl_out logical,intent(inout) :: do_epbl_out,do_sppt_out integer,intent(in) :: mpiroot, mpicomm integer, intent(out) :: iret +real(kind=kind_dbl_prec), parameter :: con_pi =4.0d0*atan(1.0d0) real :: dx integer :: k,latghf,km @@ -307,16 +307,16 @@ end subroutine init_stochastic_physics_ocn !>@details It updates the AR(1) in spectral space !allocates and polulates the necessary arrays -subroutine run_stochastic_physics(levs, kdt, phour, blksz, sppt_wts, shum_wts, skebu_wts, & +subroutine run_stochastic_physics(levs, kdt, fhour, blksz, sppt_wts, shum_wts, skebu_wts, & skebv_wts, sfc_wts,nthreads) !\callgraph !use stochy_internal_state_mod use stochy_data_mod, only : nshum,rpattern_shum,rpattern_sppt,nsppt,rpattern_skeb,nskeb,& gis_stochy,vfact_sppt,vfact_shum,vfact_skeb, rpattern_sfc, nlndp -use get_stochy_pattern_mod,only : get_random_pattern_scalar,get_random_pattern_vector,dump_patterns, & +use get_stochy_pattern_mod,only : get_random_pattern_scalar,get_random_pattern_vector, & get_random_pattern_sfc -use stochy_namelist_def, only : do_shum,do_sppt,do_skeb,fhstoch,nssppt,nsshum,nsskeb,sppt_logit, & +use stochy_namelist_def, only : do_shum,do_sppt,do_skeb,nssppt,nsshum,nsskeb,sppt_logit, & lndp_type, n_var_lndp use mpi_wrapper, only: is_master use spectral_layout_mod,only:me @@ -324,7 +324,7 @@ subroutine run_stochastic_physics(levs, kdt, phour, blksz, sppt_wts, shum_wts, s ! Interface variables integer, intent(in) :: levs, kdt -real(kind=kind_dbl_prec), intent(in) :: phour +real(kind=kind_dbl_prec), intent(in) :: fhour integer, intent(in) :: blksz(:) real(kind=kind_dbl_prec), intent(inout) :: sppt_wts(:,:,:) real(kind=kind_dbl_prec), intent(inout) :: shum_wts(:,:,:) @@ -357,74 +357,70 @@ subroutine run_stochastic_physics(levs, kdt, phour, blksz, sppt_wts, shum_wts, s len=blksz(blk) ! for perturbing vars or states, saved value is N(0,1) and apply scaling later. DO k=1,n_var_lndp - sfc_wts(blk,1:len,k) = tmpl_wts(blk,1:len,k) + !sfc_wts(blk,1:len,k) = tmpl_wts(blk,1:len,k) + sfc_wts(blk,1:len,k) = tmpl_wts(1:len,blk,k) ENDDO ENDDO deallocate(tmpl_wts) -else - ! check to see if it is time to write out random patterns - if (fhstoch.GE. 0 .AND. MOD(phour,fhstoch) .EQ. 0) then - write(STRFH,FMT='(I6.6)') nint(phour) - sfile='stoch_out.F'//trim(STRFH) - call dump_patterns(sfile) - endif - allocate(tmp_wts(nblks,maxlen)) - allocate(tmpu_wts(nblks,maxlen,levs)) - allocate(tmpv_wts(nblks,maxlen,levs)) - if (do_sppt) then - if (mod(kdt,nssppt) == 1 .or. nssppt == 1) then - call get_random_pattern_scalar(rpattern_sppt,nsppt,gis_stochy,tmp_wts) - DO blk=1,nblks - len=blksz(blk) - DO k=1,levs - sppt_wts(blk,1:len,k)=tmp_wts(blk,1:len)*vfact_sppt(k) - ENDDO - if (sppt_logit) sppt_wts(blk,:,:) = (2./(1.+exp(sppt_wts(blk,:,:))))-1. - sppt_wts(blk,:,:) = sppt_wts(blk,:,:)+1.0 - ENDDO - endif - endif - if (do_shum) then - if (mod(kdt,nsshum) == 1 .or. nsshum == 1) then - call get_random_pattern_scalar(rpattern_shum,nshum,gis_stochy,tmp_wts) - DO blk=1,nblks - len=blksz(blk) - DO k=1,levs - shum_wts(blk,1:len,k)=tmp_wts(blk,1:len)*vfact_shum(k) - ENDDO - ENDDO - endif - endif - if (do_skeb) then - if (mod(kdt,nsskeb) == 1 .or. nsskeb == 1) then - call get_random_pattern_vector(rpattern_skeb,nskeb,gis_stochy,tmpu_wts,tmpv_wts) - DO blk=1,nblks - len=blksz(blk) - DO k=1,levs - skebu_wts(blk,1:len,k)=tmpu_wts(blk,1:len,k)*vfact_skeb(k) - skebv_wts(blk,1:len,k)=tmpv_wts(blk,1:len,k)*vfact_skeb(k) - ENDDO - ENDDO - endif - endif - if ( lndp_type .EQ. 2 ) then - ! add time check? - allocate(tmpl_wts(nblks,maxlen,n_var_lndp)) - call get_random_pattern_sfc(rpattern_sfc,nlndp,gis_stochy,tmpl_wts) - DO blk=1,nblks - len=blksz(blk) - ! for perturbing vars or states, saved value is N(0,1) and apply scaling later. - DO k=1,n_var_lndp - sfc_wts(blk,1:len,k) = tmpl_wts(blk,1:len,k) - ENDDO - ENDDO - deallocate(tmpl_wts) - endif - deallocate(tmp_wts) - deallocate(tmpu_wts) - deallocate(tmpv_wts) +endif +allocate(tmp_wts(gis_stochy%nx,gis_stochy%ny)) +allocate(tmpu_wts(gis_stochy%nx,gis_stochy%ny,levs)) +allocate(tmpv_wts(gis_stochy%nx,gis_stochy%ny,levs)) +if (do_sppt) then + if (mod(kdt,nssppt) == 1 .or. nssppt == 1) then + call get_random_pattern_scalar(rpattern_sppt,nsppt,gis_stochy,tmp_wts) + DO blk=1,nblks + len=blksz(blk) + DO k=1,levs + !sppt_wts(blk,1:len,k)=tmp_wts(blk,1:len)*vfact_sppt(k) + sppt_wts(blk,1:len,k)=tmp_wts(1:len,blk)*vfact_sppt(k) + ENDDO + if (sppt_logit) sppt_wts(blk,:,:) = (2./(1.+exp(sppt_wts(blk,:,:))))-1. + sppt_wts(blk,:,:) = sppt_wts(blk,:,:)+1.0 + ENDDO + endif +endif +if (do_shum) then + if (mod(kdt,nsshum) == 1 .or. nsshum == 1) then + call get_random_pattern_scalar(rpattern_shum,nshum,gis_stochy,tmp_wts) + DO blk=1,nblks + len=blksz(blk) + DO k=1,levs + shum_wts(blk,1:len,k)=tmp_wts(1:len,blk)*vfact_shum(k) + ENDDO + ENDDO + endif +endif +if (do_skeb) then + if (mod(kdt,nsskeb) == 1 .or. nsskeb == 1) then + call get_random_pattern_vector(rpattern_skeb,nskeb,gis_stochy,tmpu_wts,tmpv_wts) + DO blk=1,nblks + len=blksz(blk) + DO k=1,levs + skebu_wts(blk,1:len,k)=tmpu_wts(1:len,blk,k)*vfact_skeb(k) + skebv_wts(blk,1:len,k)=tmpv_wts(1:len,blk,k)*vfact_skeb(k) + ENDDO + ENDDO + endif +endif +if ( lndp_type .EQ. 2 ) then + ! add time check? + allocate(tmpl_wts(gis_stochy%nx,gis_stochy%ny,n_var_lndp)) + call get_random_pattern_sfc(rpattern_sfc,nlndp,gis_stochy,tmpl_wts) + DO blk=1,nblks + len=blksz(blk) + ! for perturbing vars or states, saved value is N(0,1) and apply scaling later. + DO k=1,n_var_lndp + sfc_wts(blk,1:len,k) = tmpl_wts(1:len,blk,k) + ENDDO + ENDDO + if (is_master()) print*,'sfc_wts=',sfc_wts(1,1,:) + deallocate(tmpl_wts) +endif + deallocate(tmp_wts) + deallocate(tmpu_wts) + deallocate(tmpv_wts) -end if end subroutine run_stochastic_physics @@ -471,9 +467,7 @@ subroutine finalize_stochastic_physics() use stochy_data_mod, only : nshum,rpattern_shum,rpattern_sppt,nsppt,rpattern_skeb,nskeb,& vfact_sppt,vfact_shum,vfact_skeb, skeb_vwts,skeb_vpts, & rpattern_sfc, nlndp,gg_lats,gg_lons,sl,skebu_save,skebv_save,gis_stochy -use stochy_gg_def, only : wgt_a,sinlat_a,coslat_a,colrad_a,wgtcs_a,rcs2_a,lats_nodes_h,global_lats_h -use spectral_layout_mod, only : lat1s_a ,lon_dims_a -use stochy_layout_lag, only : lat1s_h +use spectral_layout_mod, only : lat1s_h,lat1s_a ,lon_dims_a,wgt_a,sinlat_a,coslat_a,colrad_a,wgtcs_a,rcs2_a,lats_nodes_h,global_lats_h implicit none if (allocated(gg_lats)) deallocate (gg_lats) @@ -515,7 +509,6 @@ subroutine finalize_stochastic_physics() deallocate(gis_stochy%lats_nodes_a_fix) deallocate(gis_stochy%lats_nodes_a) deallocate(gis_stochy%global_lats_a) -deallocate(gis_stochy%lats_nodes_ext) deallocate(gis_stochy%TRIE_LS_SIZE) deallocate(gis_stochy%TRIO_LS_SIZE) deallocate(gis_stochy%TRIEO_LS_SIZE) diff --git a/stochy_data_mod.F90 b/stochy_data_mod.F90 index 5c29771..bcd0cd0 100644 --- a/stochy_data_mod.F90 +++ b/stochy_data_mod.F90 @@ -49,6 +49,8 @@ subroutine init_stochdata(nlevs,delt,input_nml_file,fn_nml,nlunit,iret) ! initialize random patterns. A spinup period of spinup_efolds times the ! temporal time scale is run for each pattern. + use netcdf + implicit none integer, intent(in) :: nlunit,nlevs character(len=*), intent(in) :: input_nml_file(:) character(len=64), intent(in) :: fn_nml @@ -60,9 +62,11 @@ subroutine init_stochdata(nlevs,delt,input_nml_file,fn_nml,nlunit,iret) integer :: nn,nspinup,k,nm,spinup_efolds,stochlun,ierr,n integer :: locl,indev,indod,indlsod,indlsev integer :: l,jbasev,jbasod + integer :: jcapin,varid1,varid2 real(kind_dbl_prec),allocatable :: noise_e(:,:),noise_o(:,:) include 'function_indlsod' include 'function_indlsev' + include 'netcdf.inc' stochlun=99 levs=nlevs @@ -130,56 +134,106 @@ subroutine init_stochdata(nlevs,delt,input_nml_file,fn_nml,nlunit,iret) if (is_master()) then if (stochini) then print*,'opening stoch_ini' - OPEN(stochlun,file='stoch_ini',form='unformatted',iostat=ierr,status='old') + !OPEN(stochlun,file='INPUT/atm_stoch.res.bin',form='unformatted',iostat=ierr,status='old') + ierr=nf90_open('INPUT/atm_stoch.res.nc',nf90_nowrite,ncid=stochlun) if (ierr .NE. 0) then write(0,*) 'error opening stoch_ini' iret = ierr return end if + ierr=NF90_GET_ATT(stochlun,NF_GLOBAL,"ntrunc",jcapin) + if (ierr .NE. 0) then + write(0,*) 'error getting ntrunc' + iret = ierr + return + end if + print*,'ntrunc read in',jcapin endif endif ! no spinup needed if initial patterns are defined correctly. spinup_efolds = 0 if (nsppt > 0) then - if (is_master()) print *, 'Initialize random pattern for SPPT' - call patterngenerator_init(sppt_lscale(1:nsppt),spptint,sppt_tau(1:nsppt),sppt(1:nsppt),iseed_sppt,rpattern_sppt, & + if (is_master()) then + print *, 'Initialize random pattern for SPPT' + if (stochini) then + ierr=NF90_INQ_VARID(stochlun,"sppt_seed", varid1) + if (ierr .NE. 0) then + write(0,*) 'error inquring SPPT seed' + iret = ierr + return + end if + ierr=NF90_INQ_VARID(stochlun,"sppt_spec", varid2) + if (ierr .NE. 0) then + write(0,*) 'error inquring SPPT spec' + iret = ierr + return + end if + endif + endif + call patterngenerator_init(sppt_lscale(1:nsppt),spptint,sppt_tau(1:nsppt),sppt(1:nsppt),iseed_sppt,rpattern_sppt, & lonf,latg,jcap,gis_stochy%ls_node,nsppt,1,0,new_lscale) - do n=1,nsppt - nspinup = spinup_efolds*sppt_tau(n)/spptint - if (stochini) then - call read_pattern(rpattern_sppt(n),1,stochlun) - else - call getnoise(rpattern_sppt(n),noise_e,noise_o) - do nn=1,len_trie_ls - rpattern_sppt(n)%spec_e(nn,1,1)=noise_e(nn,1) - rpattern_sppt(n)%spec_e(nn,2,1)=noise_e(nn,2) - nm = rpattern_sppt(n)%idx_e(nn) - if (nm .eq. 0) cycle - rpattern_sppt(n)%spec_e(nn,1,1) = rpattern_sppt(n)%stdev*rpattern_sppt(n)%spec_e(nn,1,1)*rpattern_sppt(n)%varspectrum(nm) - rpattern_sppt(n)%spec_e(nn,2,1) = rpattern_sppt(n)%stdev*rpattern_sppt(n)%spec_e(nn,2,1)*rpattern_sppt(n)%varspectrum(nm) - enddo - do nn=1,len_trio_ls - rpattern_sppt(n)%spec_o(nn,1,1)=noise_o(nn,1) - rpattern_sppt(n)%spec_o(nn,2,1)=noise_o(nn,2) - nm = rpattern_sppt(n)%idx_o(nn) - if (nm .eq. 0) cycle - rpattern_sppt(n)%spec_o(nn,1,1) = rpattern_sppt(n)%stdev*rpattern_sppt(n)%spec_o(nn,1,1)*rpattern_sppt(n)%varspectrum(nm) - rpattern_sppt(n)%spec_o(nn,2,1) = rpattern_sppt(n)%stdev*rpattern_sppt(n)%spec_o(nn,2,1)*rpattern_sppt(n)%varspectrum(nm) - enddo - do nn=1,nspinup - call patterngenerator_advance(rpattern_sppt(n),1,.false.) - enddo - endif + do n=1,nsppt + nspinup = spinup_efolds*sppt_tau(n)/spptint + if (stochini) then + call read_pattern(rpattern_sppt(n),jcapin,stochlun,1,n,varid1,varid2,.false.,ierr) + if (ierr .NE. 0) then + write(0,*) 'error reading SPPT pattern' + iret = ierr + return + end if + else + call getnoise(rpattern_sppt(n),noise_e,noise_o) + do nn=1,len_trie_ls + rpattern_sppt(n)%spec_e(nn,1,1)=noise_e(nn,1) + rpattern_sppt(n)%spec_e(nn,2,1)=noise_e(nn,2) + nm = rpattern_sppt(n)%idx_e(nn) + if (nm .eq. 0) cycle + rpattern_sppt(n)%spec_e(nn,1,1) = rpattern_sppt(n)%stdev*rpattern_sppt(n)%spec_e(nn,1,1)*rpattern_sppt(n)%varspectrum(nm) + rpattern_sppt(n)%spec_e(nn,2,1) = rpattern_sppt(n)%stdev*rpattern_sppt(n)%spec_e(nn,2,1)*rpattern_sppt(n)%varspectrum(nm) + enddo + do nn=1,len_trio_ls + rpattern_sppt(n)%spec_o(nn,1,1)=noise_o(nn,1) + rpattern_sppt(n)%spec_o(nn,2,1)=noise_o(nn,2) + nm = rpattern_sppt(n)%idx_o(nn) + if (nm .eq. 0) cycle + rpattern_sppt(n)%spec_o(nn,1,1) = rpattern_sppt(n)%stdev*rpattern_sppt(n)%spec_o(nn,1,1)*rpattern_sppt(n)%varspectrum(nm) + rpattern_sppt(n)%spec_o(nn,2,1) = rpattern_sppt(n)%stdev*rpattern_sppt(n)%spec_o(nn,2,1)*rpattern_sppt(n)%varspectrum(nm) + enddo + do nn=1,nspinup + call patterngenerator_advance(rpattern_sppt(n),1,.false.) + enddo + endif enddo endif if (nshum > 0) then - if (is_master()) print *, 'Initialize random pattern for SHUM' - call patterngenerator_init(shum_lscale(1:nshum),shumint,shum_tau(1:nshum),shum(1:nshum),iseed_shum,rpattern_shum, & - lonf,latg,jcap,gis_stochy%ls_node,nshum,1,0,new_lscale) - do n=1,nshum - nspinup = spinup_efolds*shum_tau(n)/shumint - if (stochini) then - call read_pattern(rpattern_shum(n),1,stochlun) + if (is_master()) then + print *, 'Initialize random pattern for SHUM' + if (stochini) then + ierr=NF90_INQ_VARID(stochlun,"shum_seed", varid1) + if (ierr .NE. 0) then + write(0,*) 'error inquring SHUM seed' + iret = ierr + return + end if + ierr=NF90_INQ_VARID(stochlun,"shum_spec", varid2) + if (ierr .NE. 0) then + write(0,*) 'error inquring SHUM spec' + iret = ierr + return + end if + endif + endif + call patterngenerator_init(shum_lscale(1:nshum),shumint,shum_tau(1:nshum),shum(1:nshum),iseed_shum,rpattern_shum, & + lonf,latg,jcap,gis_stochy%ls_node,nshum,1,0,new_lscale) + do n=1,nshum + nspinup = spinup_efolds*shum_tau(n)/shumint + if (stochini) then + call read_pattern(rpattern_shum(n),jcapin,stochlun,1,n,varid1,varid2,.false.,ierr) + if (ierr .NE. 0) then + write(0,*) 'error reading SHUM pattern' + iret = ierr + return + end if else call getnoise(rpattern_shum(n),noise_e,noise_o) do nn=1,len_trie_ls @@ -207,134 +261,177 @@ subroutine init_stochdata(nlevs,delt,input_nml_file,fn_nml,nlunit,iret) if (nskeb > 0) then ! determine number of skeb levels to deal with temperoal/vertical correlations - skeblevs=nint(skeb_tau(1)/skebint*skeb_vdof) + skeblevs=nint(skeb_tau(1)/skebint*skeb_vdof) ! backscatter noise. - call patterngenerator_init(skeb_lscale(1:nskeb),skebint,skeb_tau(1:nskeb),skeb(1:nskeb),iseed_skeb,rpattern_skeb, & + if (is_master()) then + print *, 'Initialize random pattern for SKEB' + if (stochini) then + ierr=NF90_INQ_VARID(stochlun,"skeb_seed", varid1) + if (ierr .NE. 0) then + write(0,*) 'error inquring SKEB seed' + iret = ierr + return + end if + ierr=NF90_INQ_VARID(stochlun,"skeb_spec", varid2) + if (ierr .NE. 0) then + write(0,*) 'error inquring SKEB spec' + iret = ierr + return + end if + endif + endif + call patterngenerator_init(skeb_lscale(1:nskeb),skebint,skeb_tau(1:nskeb),skeb(1:nskeb),iseed_skeb,rpattern_skeb, & lonf,latg,jcap,gis_stochy%ls_node,nskeb,skeblevs,skeb_varspect_opt,new_lscale) - do n=1,nskeb - do k=1,skeblevs - nspinup = spinup_efolds*skeb_tau(n)/skebint - if (stochini) then - call read_pattern(rpattern_skeb(n),k,stochlun) - if (is_master()) print *, 'skeb read',k,rpattern_skeb(n)%spec_o(5,1,k) - else - call getnoise(rpattern_skeb(n),noise_e,noise_o) - do nn=1,len_trie_ls - rpattern_skeb(n)%spec_e(nn,1,k)=noise_e(nn,1) - rpattern_skeb(n)%spec_e(nn,2,k)=noise_e(nn,2) - nm = rpattern_skeb(n)%idx_e(nn) - if (nm .eq. 0) cycle - rpattern_skeb(n)%spec_e(nn,1,k) = rpattern_skeb(n)%stdev*rpattern_skeb(n)%spec_e(nn,1,k)*rpattern_skeb(n)%varspectrum(nm) - rpattern_skeb(n)%spec_e(nn,2,k) = rpattern_skeb(n)%stdev*rpattern_skeb(n)%spec_e(nn,2,k)*rpattern_skeb(n)%varspectrum(nm) - enddo - do nn=1,len_trio_ls - rpattern_skeb(n)%spec_o(nn,1,k)=noise_o(nn,1) - rpattern_skeb(n)%spec_o(nn,2,k)=noise_o(nn,2) - nm = rpattern_skeb(n)%idx_o(nn) - if (nm .eq. 0) cycle - rpattern_skeb(n)%spec_o(nn,1,k) = rpattern_skeb(n)%stdev*rpattern_skeb(n)%spec_o(nn,1,k)*rpattern_skeb(n)%varspectrum(nm) - rpattern_skeb(n)%spec_o(nn,2,k) = rpattern_skeb(n)%stdev*rpattern_skeb(n)%spec_o(nn,2,k)*rpattern_skeb(n)%varspectrum(nm) - enddo - endif - enddo - do nn=1,nspinup - call patterngenerator_advance(rpattern_skeb(n),skeblevs,.false.) - enddo - enddo - - gis_stochy%kenorm_e=1. - gis_stochy%kenorm_o=1. ! used to convert forcing pattern to wind field. -if (skebnorm==0) then - do locl=1,ls_max_node - l = gis_stochy%ls_node(locl) - jbasev = gis_stochy%ls_node(locl+ls_dim) - indev = indlsev(l,l) - jbasod = gis_stochy%ls_node(locl+2*ls_dim) - indod = indlsod(l+1,l) - do n=l,jcap,2 - rnn1 = n*(n+1.) - gis_stochy%kenorm_e(indev) = rnn1/radius**2 - indev = indev + 1 - enddo - do n=l+1,jcap,2 - rnn1 = n*(n+1.) - gis_stochy%kenorm_o(indod) = rnn1/radius**2 - indod = indod + 1 - enddo - enddo - if (is_master()) print*,'using streamfunction ',maxval(gis_stochy%kenorm_e(:)),minval(gis_stochy%kenorm_e(:)) -endif -if (skebnorm==1) then - do locl=1,ls_max_node - l = gis_stochy%ls_node(locl) - jbasev = gis_stochy%ls_node(locl+ls_dim) - indev = indlsev(l,l) - jbasod = gis_stochy%ls_node(locl+2*ls_dim) - indod = indlsod(l+1,l) - do n=l,jcap,2 - rnn1 = n*(n+1.) - gis_stochy%kenorm_e(indev) = sqrt(rnn1)/radius - indev = indev + 1 - enddo - do n=l+1,jcap,2 - rnn1 = n*(n+1.) - gis_stochy%kenorm_o(indod) = sqrt(rnn1)/radius - indod = indod + 1 - enddo - enddo - if (is_master()) print*,'using kenorm ',maxval(gis_stochy%kenorm_e(:)),minval(gis_stochy%kenorm_e(:)) -endif - ! set the even and odd (n-l) terms of the top row to zero -do locl=1,ls_max_node - l = gis_stochy%ls_node(locl) - jbasev = gis_stochy%ls_node(locl+ls_dim) - jbasod = gis_stochy%ls_node(locl+2*ls_dim) - if (mod(l,2) .eq. mod(jcap+1,2)) then - gis_stochy%kenorm_e(indlsev(jcap+1,l)) = 0. - endif - if (mod(l,2) .ne. mod(jcap+1,2)) then - gis_stochy%kenorm_o(indlsod(jcap+1,l)) = 0. - endif -enddo - - endif ! skeb > 0 -! mg, sfc-perts -if (nlndp > 0) then - ones = 1. - call patterngenerator_init(lndp_lscale(1:nlndp),delt,lndp_tau(1:nlndp),ones(1:nlndp),iseed_lndp,rpattern_sfc, & - lonf,latg,jcap,gis_stochy%ls_node,nlndp,n_var_lndp,0,new_lscale) - do n=1,nlndp - if (is_master()) print *, 'Initialize random pattern for LNDP PERTS' - do k=1,n_var_lndp - nspinup = spinup_efolds*lndp_tau(n)/delt - if (stochini) then - call read_pattern(rpattern_sfc(n),k,stochlun) - if (is_master()) print *, 'lndp pattern read',n,k,minval(rpattern_sfc(n)%spec_o(:,:,k)), maxval(rpattern_sfc(n)%spec_o(:,:,k)) - else - call getnoise(rpattern_sfc(n),noise_e,noise_o) + do n=1,nskeb + do k=1,skeblevs + nspinup = spinup_efolds*skeb_tau(n)/skebint + if (stochini) then + call read_pattern(rpattern_skeb(n),jcapin,stochlun,k,n,varid1,varid2,.true.,ierr) + if (ierr .NE. 0) then + write(0,*) 'error reading SKEB pattern' + iret = ierr + return + end if + else + call getnoise(rpattern_skeb(n),noise_e,noise_o) do nn=1,len_trie_ls - rpattern_sfc(n)%spec_e(nn,1,k)=noise_e(nn,1) - rpattern_sfc(n)%spec_e(nn,2,k)=noise_e(nn,2) - nm = rpattern_sfc(n)%idx_e(nn) + rpattern_skeb(n)%spec_e(nn,1,k)=noise_e(nn,1) + rpattern_skeb(n)%spec_e(nn,2,k)=noise_e(nn,2) + nm = rpattern_skeb(n)%idx_e(nn) if (nm .eq. 0) cycle - rpattern_sfc(n)%spec_e(nn,1,k) = rpattern_sfc(n)%stdev*rpattern_sfc(n)%spec_e(nn,1,k)*rpattern_sfc(n)%varspectrum(nm) - rpattern_sfc(n)%spec_e(nn,2,k) = rpattern_sfc(n)%stdev*rpattern_sfc(n)%spec_e(nn,2,k)*rpattern_sfc(n)%varspectrum(nm) + rpattern_skeb(n)%spec_e(nn,1,k) = rpattern_skeb(n)%stdev*rpattern_skeb(n)%spec_e(nn,1,k)*rpattern_skeb(n)%varspectrum(nm) + rpattern_skeb(n)%spec_e(nn,2,k) = rpattern_skeb(n)%stdev*rpattern_skeb(n)%spec_e(nn,2,k)*rpattern_skeb(n)%varspectrum(nm) enddo do nn=1,len_trio_ls - rpattern_sfc(n)%spec_o(nn,1,k)=noise_o(nn,1) - rpattern_sfc(n)%spec_o(nn,2,k)=noise_o(nn,2) - nm = rpattern_sfc(n)%idx_o(nn) + rpattern_skeb(n)%spec_o(nn,1,k)=noise_o(nn,1) + rpattern_skeb(n)%spec_o(nn,2,k)=noise_o(nn,2) + nm = rpattern_skeb(n)%idx_o(nn) if (nm .eq. 0) cycle - rpattern_sfc(n)%spec_o(nn,1,k) = rpattern_sfc(n)%stdev*rpattern_sfc(n)%spec_o(nn,1,k)*rpattern_sfc(n)%varspectrum(nm) - rpattern_sfc(n)%spec_o(nn,2,k) = rpattern_sfc(n)%stdev*rpattern_sfc(n)%spec_o(nn,2,k)*rpattern_sfc(n)%varspectrum(nm) - enddo - do nn=1,nspinup - call patterngenerator_advance(rpattern_sfc(n),k,.false.) + rpattern_skeb(n)%spec_o(nn,1,k) = rpattern_skeb(n)%stdev*rpattern_skeb(n)%spec_o(nn,1,k)*rpattern_skeb(n)%varspectrum(nm) + rpattern_skeb(n)%spec_o(nn,2,k) = rpattern_skeb(n)%stdev*rpattern_skeb(n)%spec_o(nn,2,k)*rpattern_skeb(n)%varspectrum(nm) enddo - if (is_master()) print *, 'lndp pattern initialized, ',n, k, minval(rpattern_sfc(n)%spec_o(:,:,k)), maxval(rpattern_sfc(n)%spec_o(:,:,k)) - endif ! stochini + endif + enddo + do nn=1,nspinup + call patterngenerator_advance(rpattern_skeb(n),skeblevs,.false.) + enddo + enddo + + gis_stochy%kenorm_e=1. + gis_stochy%kenorm_o=1. ! used to convert forcing pattern to wind field. + if (skebnorm==0) then + do locl=1,ls_max_node + l = gis_stochy%ls_node(locl) + jbasev = gis_stochy%ls_node(locl+ls_dim) + indev = indlsev(l,l) + jbasod = gis_stochy%ls_node(locl+2*ls_dim) + indod = indlsod(l+1,l) + do n=l,jcap,2 + rnn1 = n*(n+1.) + gis_stochy%kenorm_e(indev) = rnn1/radius**2 + indev = indev + 1 + enddo + do n=l+1,jcap,2 + rnn1 = n*(n+1.) + gis_stochy%kenorm_o(indod) = rnn1/radius**2 + indod = indod + 1 + enddo + enddo + if (is_master()) print*,'using streamfunction ',maxval(gis_stochy%kenorm_e(:)),minval(gis_stochy%kenorm_e(:)) + endif + if (skebnorm==1) then + do locl=1,ls_max_node + l = gis_stochy%ls_node(locl) + jbasev = gis_stochy%ls_node(locl+ls_dim) + indev = indlsev(l,l) + jbasod = gis_stochy%ls_node(locl+2*ls_dim) + indod = indlsod(l+1,l) + do n=l,jcap,2 + rnn1 = n*(n+1.) + gis_stochy%kenorm_e(indev) = sqrt(rnn1)/radius + indev = indev + 1 + enddo + do n=l+1,jcap,2 + rnn1 = n*(n+1.) + gis_stochy%kenorm_o(indod) = sqrt(rnn1)/radius + indod = indod + 1 + enddo + enddo + if (is_master()) print*,'using kenorm ',maxval(gis_stochy%kenorm_e(:)),minval(gis_stochy%kenorm_e(:)) + endif + ! set the even and odd (n-l) terms of the top row to zero + do locl=1,ls_max_node + l = gis_stochy%ls_node(locl) + jbasev = gis_stochy%ls_node(locl+ls_dim) + jbasod = gis_stochy%ls_node(locl+2*ls_dim) + if (mod(l,2) .eq. mod(jcap+1,2)) then + gis_stochy%kenorm_e(indlsev(jcap+1,l)) = 0. + endif + if (mod(l,2) .ne. mod(jcap+1,2)) then + gis_stochy%kenorm_o(indlsod(jcap+1,l)) = 0. + endif + enddo + + endif ! skeb > 0 +! mg, sfc-perts + if (nlndp > 0) then + if (is_master()) then + print *, 'Initialize random pattern for SFC-PERTS' + if (stochini) then + ierr=NF90_INQ_VARID(stochlun,"sfcpert_seed", varid1) + if (ierr .NE. 0) then + write(0,*) 'error inquring SFC-PERTS seed' + iret = ierr + return + end if + ierr=NF90_INQ_VARID(stochlun,"sfcpert_spec", varid2) + if (ierr .NE. 0) then + write(0,*) 'error inquring SFC-PERTS spec' + iret = ierr + return + end if + endif + endif + ones = 1. + call patterngenerator_init(lndp_lscale(1:nlndp),delt,lndp_tau(1:nlndp),ones(1:nlndp),iseed_lndp,rpattern_sfc, & + lonf,latg,jcap,gis_stochy%ls_node,nlndp,n_var_lndp,0,new_lscale) + do n=1,nlndp + if (is_master()) print *, 'Initialize random pattern for LNDP PERTS' + do k=1,n_var_lndp + nspinup = spinup_efolds*lndp_tau(n)/delt + if (stochini) then + call read_pattern(rpattern_sfc(n),jcapin,stochlun,k,n,varid1,varid2,.true.,ierr) + if (ierr .NE. 0) then + write(0,*) 'error reading SHUM pattern' + iret = ierr + return + endif + if (is_master()) print *, 'lndp pattern read',n,k,minval(rpattern_sfc(n)%spec_o(:,:,k)), maxval(rpattern_sfc(n)%spec_o(:,:,k)) + else + call getnoise(rpattern_sfc(n),noise_e,noise_o) + do nn=1,len_trie_ls + rpattern_sfc(n)%spec_e(nn,1,k)=noise_e(nn,1) + rpattern_sfc(n)%spec_e(nn,2,k)=noise_e(nn,2) + nm = rpattern_sfc(n)%idx_e(nn) + if (nm .eq. 0) cycle + rpattern_sfc(n)%spec_e(nn,1,k) = rpattern_sfc(n)%stdev*rpattern_sfc(n)%spec_e(nn,1,k)*rpattern_sfc(n)%varspectrum(nm) + rpattern_sfc(n)%spec_e(nn,2,k) = rpattern_sfc(n)%stdev*rpattern_sfc(n)%spec_e(nn,2,k)*rpattern_sfc(n)%varspectrum(nm) + enddo + do nn=1,len_trio_ls + rpattern_sfc(n)%spec_o(nn,1,k)=noise_o(nn,1) + rpattern_sfc(n)%spec_o(nn,2,k)=noise_o(nn,2) + nm = rpattern_sfc(n)%idx_o(nn) + if (nm .eq. 0) cycle + rpattern_sfc(n)%spec_o(nn,1,k) = rpattern_sfc(n)%stdev*rpattern_sfc(n)%spec_o(nn,1,k)*rpattern_sfc(n)%varspectrum(nm) + rpattern_sfc(n)%spec_o(nn,2,k) = rpattern_sfc(n)%stdev*rpattern_sfc(n)%spec_o(nn,2,k)*rpattern_sfc(n)%varspectrum(nm) + enddo + do nn=1,nspinup + call patterngenerator_advance(rpattern_sfc(n),k,.false.) + enddo + if (is_master()) print *, 'lndp pattern initialized, ',n, k, minval(rpattern_sfc(n)%spec_o(:,:,k)), maxval(rpattern_sfc(n)%spec_o(:,:,k)) + endif ! stochini enddo ! k, n_var_lndp - enddo ! n, nlndp + enddo ! n, nlndp endif ! nlndp > 0 if (is_master() .and. stochini) CLOSE(stochlun) deallocate(noise_e,noise_o) @@ -342,6 +439,7 @@ end subroutine init_stochdata subroutine init_stochdata_ocn(nlevs,delt,iret) + use netcdf use compns_stochy_mod, only : compns_stochy_ocn use mpp_domains_mod, only: mpp_broadcast_domain,MPP_DOMAIN_TIME,mpp_domains_init ,mpp_domains_set_stack_size ! initialize random patterns. A spinup period of spinup_efolds times the @@ -350,12 +448,14 @@ subroutine init_stochdata_ocn(nlevs,delt,iret) real, intent(in) :: delt integer, intent(out) :: iret - integer :: nn,nm,stochlun,n + integer :: nn,nm,stochlun,n,jcapin integer :: l,jbasev,jbasod - integer :: indev,indod,indlsod,indlsev + integer :: indev,indod,indlsod,indlsev,varid1,varid2,varid3,varid4,ierr + real(kind_dbl_prec),allocatable :: noise_e(:,:),noise_o(:,:) include 'function_indlsod' include 'function_indlsev' + include 'netcdf.inc' stochlun=99 levs=nlevs @@ -390,82 +490,169 @@ subroutine init_stochdata_ocn(nlevs,delt,iret) if (nocnsppt > 0) allocate(rpattern_ocnsppt(nocnsppt)) +! if stochini is true, then read in pattern from a file + if (is_master()) then + if (stochini) then + print*,'opening stoch_ini' + ierr=nf90_open('INPUT/ocn_stoch.res.nc',nf90_nowrite,ncid=stochlun) + if (ierr .NE. 0) then + write(0,*) 'error opening stoch_ini' + iret = ierr + return + end if + ierr=NF90_GET_ATT(stochlun,NF_GLOBAL,"ntrunc",jcapin) + if (ierr .NE. 0) then + write(0,*) 'error getting ntrunc' + iret = ierr + return + end if + print*,'ntrunc read in',jcapin + endif + endif + if (nepbl > 0) then - if (is_master()) print *, 'Initialize random pattern for epbl' - call patterngenerator_init(epbl_lscale(1:nepbl),epblint,epbl_tau(1:nepbl),epbl(1:nepbl),iseed_epbl,rpattern_epbl1, & + if (is_master()) then + print *, 'Initialize random pattern for epbl' + if (stochini) then + ierr=NF90_INQ_VARID(stochlun,"epbl1_seed", varid1) + if (ierr .NE. 0) then + write(0,*) 'error inquring EPBL1 seed' + iret = ierr + return + end if + ierr=NF90_INQ_VARID(stochlun,"epbl1_spec", varid2) + if (ierr .NE. 0) then + write(0,*) 'error inquring EPBL1 spec' + iret = ierr + return + end if + ierr=NF90_INQ_VARID(stochlun,"epbl2_seed", varid3) + if (ierr .NE. 0) then + write(0,*) 'error inquring EPBL2 seed' + iret = ierr + return + end if + ierr=NF90_INQ_VARID(stochlun,"epbl2_spec", varid4) + if (ierr .NE. 0) then + write(0,*) 'error inquring EPBL2 spec' + iret = ierr + return + end if + end if + end if + call patterngenerator_init(epbl_lscale(1:nepbl),epblint,epbl_tau(1:nepbl),epbl(1:nepbl),iseed_epbl,rpattern_epbl1, & lonf,latg,jcap,gis_stochy_ocn%ls_node,nepbl,1,0,new_lscale) - call patterngenerator_init(epbl_lscale(1:nepbl),epblint,epbl_tau(1:nepbl),epbl(1:nepbl),iseed_epbl2,rpattern_epbl2, & + call patterngenerator_init(epbl_lscale(1:nepbl),epblint,epbl_tau(1:nepbl),epbl(1:nepbl),iseed_epbl2,rpattern_epbl2, & lonf,latg,jcap,gis_stochy_ocn%ls_node,nepbl,1,0,new_lscale) - do n=1,nepbl - call getnoise(rpattern_epbl1(n),noise_e,noise_o) - do nn=1,len_trie_ls - rpattern_epbl1(n)%spec_e(nn,1,1)=noise_e(nn,1) - rpattern_epbl1(n)%spec_e(nn,2,1)=noise_e(nn,2) - rpattern_epbl1(n)%spec_e(nn,1,1)=noise_e(nn,1) - rpattern_epbl1(n)%spec_e(nn,2,1)=noise_e(nn,2) - nm = rpattern_epbl1(n)%idx_e(nn) - if (nm .eq. 0) cycle - rpattern_epbl1(n)%spec_e(nn,1,1) = rpattern_epbl1(n)%stdev*rpattern_epbl1(n)%spec_e(nn,1,1)*rpattern_epbl1(n)%varspectrum(nm) - rpattern_epbl1(n)%spec_e(nn,2,1) = rpattern_epbl1(n)%stdev*rpattern_epbl1(n)%spec_e(nn,2,1)*rpattern_epbl1(n)%varspectrum(nm) - enddo - do nn=1,len_trio_ls - rpattern_epbl1(n)%spec_o(nn,1,1)=noise_o(nn,1) - rpattern_epbl1(n)%spec_o(nn,2,1)=noise_o(nn,2) - nm = rpattern_epbl1(n)%idx_o(nn) - if (nm .eq. 0) cycle - rpattern_epbl1(n)%spec_o(nn,1,1) = rpattern_epbl1(n)%stdev*rpattern_epbl1(n)%spec_o(nn,1,1)*rpattern_epbl1(n)%varspectrum(nm) - rpattern_epbl1(n)%spec_o(nn,2,1) = rpattern_epbl1(n)%stdev*rpattern_epbl1(n)%spec_o(nn,2,1)*rpattern_epbl1(n)%varspectrum(nm) - enddo - call patterngenerator_advance(rpattern_epbl1(n),1,.false.) - enddo - do n=1,nepbl - call getnoise(rpattern_epbl2(n),noise_e,noise_o) - do nn=1,len_trie_ls - rpattern_epbl2(n)%spec_e(nn,1,1)=noise_e(nn,1) - rpattern_epbl2(n)%spec_e(nn,2,1)=noise_e(nn,2) - rpattern_epbl2(n)%spec_e(nn,1,1)=noise_e(nn,1) - rpattern_epbl2(n)%spec_e(nn,2,1)=noise_e(nn,2) - nm = rpattern_epbl2(n)%idx_e(nn) - if (nm .eq. 0) cycle - rpattern_epbl2(n)%spec_e(nn,1,1) = rpattern_epbl2(n)%stdev*rpattern_epbl2(n)%spec_e(nn,1,1)*rpattern_epbl2(n)%varspectrum(nm) - rpattern_epbl2(n)%spec_e(nn,2,1) = rpattern_epbl2(n)%stdev*rpattern_epbl2(n)%spec_e(nn,2,1)*rpattern_epbl2(n)%varspectrum(nm) - enddo - do nn=1,len_trio_ls - rpattern_epbl2(n)%spec_o(nn,1,1)=noise_o(nn,1) - rpattern_epbl2(n)%spec_o(nn,2,1)=noise_o(nn,2) - nm = rpattern_epbl2(n)%idx_o(nn) - if (nm .eq. 0) cycle - rpattern_epbl2(n)%spec_o(nn,1,1) = rpattern_epbl2(n)%stdev*rpattern_epbl2(n)%spec_o(nn,1,1)*rpattern_epbl2(n)%varspectrum(nm) - rpattern_epbl2(n)%spec_o(nn,2,1) = rpattern_epbl2(n)%stdev*rpattern_epbl2(n)%spec_o(nn,2,1)*rpattern_epbl2(n)%varspectrum(nm) - enddo - call patterngenerator_advance(rpattern_epbl2(n),1,.false.) - enddo + do n=1,nepbl + if (stochini) then + call read_pattern(rpattern_epbl1(n),jcapin,stochlun,1,n,varid1,varid2,.false.,ierr) + if (ierr .NE. 0) then + write(0,*) 'error reading EPBL1 pattern' + iret = ierr + return + end if + call read_pattern(rpattern_epbl2(n),jcapin,stochlun,1,n,varid3,varid4,.false.,ierr) + if (ierr .NE. 0) then + write(0,*) 'error reading EPBL1 pattern' + iret = ierr + return + end if + else + call getnoise(rpattern_epbl1(n),noise_e,noise_o) + do nn=1,len_trie_ls + rpattern_epbl1(n)%spec_e(nn,1,1)=noise_e(nn,1) + rpattern_epbl1(n)%spec_e(nn,2,1)=noise_e(nn,2) + rpattern_epbl1(n)%spec_e(nn,1,1)=noise_e(nn,1) + rpattern_epbl1(n)%spec_e(nn,2,1)=noise_e(nn,2) + nm = rpattern_epbl1(n)%idx_e(nn) + if (nm .eq. 0) cycle + rpattern_epbl1(n)%spec_e(nn,1,1) = rpattern_epbl1(n)%stdev*rpattern_epbl1(n)%spec_e(nn,1,1)*rpattern_epbl1(n)%varspectrum(nm) + rpattern_epbl1(n)%spec_e(nn,2,1) = rpattern_epbl1(n)%stdev*rpattern_epbl1(n)%spec_e(nn,2,1)*rpattern_epbl1(n)%varspectrum(nm) + enddo + do nn=1,len_trio_ls + rpattern_epbl1(n)%spec_o(nn,1,1)=noise_o(nn,1) + rpattern_epbl1(n)%spec_o(nn,2,1)=noise_o(nn,2) + nm = rpattern_epbl1(n)%idx_o(nn) + if (nm .eq. 0) cycle + rpattern_epbl1(n)%spec_o(nn,1,1) = rpattern_epbl1(n)%stdev*rpattern_epbl1(n)%spec_o(nn,1,1)*rpattern_epbl1(n)%varspectrum(nm) + rpattern_epbl1(n)%spec_o(nn,2,1) = rpattern_epbl1(n)%stdev*rpattern_epbl1(n)%spec_o(nn,2,1)*rpattern_epbl1(n)%varspectrum(nm) + enddo + call patterngenerator_advance(rpattern_epbl1(n),1,.false.) + + call getnoise(rpattern_epbl2(n),noise_e,noise_o) + do nn=1,len_trie_ls + rpattern_epbl2(n)%spec_e(nn,1,1)=noise_e(nn,1) + rpattern_epbl2(n)%spec_e(nn,2,1)=noise_e(nn,2) + rpattern_epbl2(n)%spec_e(nn,1,1)=noise_e(nn,1) + rpattern_epbl2(n)%spec_e(nn,2,1)=noise_e(nn,2) + nm = rpattern_epbl2(n)%idx_e(nn) + if (nm .eq. 0) cycle + rpattern_epbl2(n)%spec_e(nn,1,1) = rpattern_epbl2(n)%stdev*rpattern_epbl2(n)%spec_e(nn,1,1)*rpattern_epbl2(n)%varspectrum(nm) + rpattern_epbl2(n)%spec_e(nn,2,1) = rpattern_epbl2(n)%stdev*rpattern_epbl2(n)%spec_e(nn,2,1)*rpattern_epbl2(n)%varspectrum(nm) + enddo + do nn=1,len_trio_ls + rpattern_epbl2(n)%spec_o(nn,1,1)=noise_o(nn,1) + rpattern_epbl2(n)%spec_o(nn,2,1)=noise_o(nn,2) + nm = rpattern_epbl2(n)%idx_o(nn) + if (nm .eq. 0) cycle + rpattern_epbl2(n)%spec_o(nn,1,1) = rpattern_epbl2(n)%stdev*rpattern_epbl2(n)%spec_o(nn,1,1)*rpattern_epbl2(n)%varspectrum(nm) + rpattern_epbl2(n)%spec_o(nn,2,1) = rpattern_epbl2(n)%stdev*rpattern_epbl2(n)%spec_o(nn,2,1)*rpattern_epbl2(n)%varspectrum(nm) + enddo + call patterngenerator_advance(rpattern_epbl2(n),1,.false.) + endif + enddo endif if (nocnsppt > 0) then - if (is_master()) print *, 'Initialize random pattern for ocnsppt' - call patterngenerator_init(ocnsppt_lscale(1:nocnsppt),ocnspptint,ocnsppt_tau(1:nocnsppt),ocnsppt(1:nocnsppt),iseed_ocnsppt,rpattern_ocnsppt, & + if (is_master()) then + if (stochini) then + ierr=NF90_INQ_VARID(stochlun,"ocnsppt_seed", varid1) + if (ierr .NE. 0) then + write(0,*) 'error inquring OCNSPPT seed' + iret = ierr + return + end if + ierr=NF90_INQ_VARID(stochlun,"ocnsppt_spec", varid2) + if (ierr .NE. 0) then + write(0,*) 'error inquring OCNSPPT spec' + iret = ierr + return + end if + endif + endif + if (is_master()) print *, 'Initialize random pattern for ocnsppt' + call patterngenerator_init(ocnsppt_lscale(1:nocnsppt),ocnspptint,ocnsppt_tau(1:nocnsppt),ocnsppt(1:nocnsppt),iseed_ocnsppt,rpattern_ocnsppt, & lonf,latg,jcap,gis_stochy_ocn%ls_node,nocnsppt,1,0,new_lscale) - do n=1,nocnsppt - call getnoise(rpattern_ocnsppt(n),noise_e,noise_o) - do nn=1,len_trie_ls - rpattern_ocnsppt(n)%spec_e(nn,1,1)=noise_e(nn,1) - rpattern_ocnsppt(n)%spec_e(nn,2,1)=noise_e(nn,2) - nm = rpattern_ocnsppt(n)%idx_e(nn) - if (nm .eq. 0) cycle - rpattern_ocnsppt(n)%spec_e(nn,1,1) = rpattern_ocnsppt(n)%stdev*rpattern_ocnsppt(n)%spec_e(nn,1,1)*rpattern_ocnsppt(n)%varspectrum(nm) - rpattern_ocnsppt(n)%spec_e(nn,2,1) = rpattern_ocnsppt(n)%stdev*rpattern_ocnsppt(n)%spec_e(nn,2,1)*rpattern_ocnsppt(n)%varspectrum(nm) - enddo - do nn=1,len_trio_ls - rpattern_ocnsppt(n)%spec_o(nn,1,1)=noise_o(nn,1) - rpattern_ocnsppt(n)%spec_o(nn,2,1)=noise_o(nn,2) - nm = rpattern_ocnsppt(n)%idx_o(nn) - if (nm .eq. 0) cycle - rpattern_ocnsppt(n)%spec_o(nn,1,1) = rpattern_ocnsppt(n)%stdev*rpattern_ocnsppt(n)%spec_o(nn,1,1)*rpattern_ocnsppt(n)%varspectrum(nm) - rpattern_ocnsppt(n)%spec_o(nn,2,1) = rpattern_ocnsppt(n)%stdev*rpattern_ocnsppt(n)%spec_o(nn,2,1)*rpattern_ocnsppt(n)%varspectrum(nm) - enddo - call patterngenerator_advance(rpattern_ocnsppt(n),1,.false.) - enddo + do n=1,nocnsppt + if (stochini) then + call read_pattern(rpattern_ocnsppt(n),jcapin,stochlun,1,n,varid1,varid2,.false.,ierr) + if (ierr .NE. 0) then + write(0,*) 'error reading SPPT pattern' + iret = ierr + return + end if + else + call getnoise(rpattern_ocnsppt(n),noise_e,noise_o) + do nn=1,len_trie_ls + rpattern_ocnsppt(n)%spec_e(nn,1,1)=noise_e(nn,1) + rpattern_ocnsppt(n)%spec_e(nn,2,1)=noise_e(nn,2) + nm = rpattern_ocnsppt(n)%idx_e(nn) + if (nm .eq. 0) cycle + rpattern_ocnsppt(n)%spec_e(nn,1,1) = rpattern_ocnsppt(n)%stdev*rpattern_ocnsppt(n)%spec_e(nn,1,1)*rpattern_ocnsppt(n)%varspectrum(nm) + rpattern_ocnsppt(n)%spec_e(nn,2,1) = rpattern_ocnsppt(n)%stdev*rpattern_ocnsppt(n)%spec_e(nn,2,1)*rpattern_ocnsppt(n)%varspectrum(nm) + enddo + do nn=1,len_trio_ls + rpattern_ocnsppt(n)%spec_o(nn,1,1)=noise_o(nn,1) + rpattern_ocnsppt(n)%spec_o(nn,2,1)=noise_o(nn,2) + nm = rpattern_ocnsppt(n)%idx_o(nn) + if (nm .eq. 0) cycle + rpattern_ocnsppt(n)%spec_o(nn,1,1) = rpattern_ocnsppt(n)%stdev*rpattern_ocnsppt(n)%spec_o(nn,1,1)*rpattern_ocnsppt(n)%varspectrum(nm) + rpattern_ocnsppt(n)%spec_o(nn,2,1) = rpattern_ocnsppt(n)%stdev*rpattern_ocnsppt(n)%spec_o(nn,2,1)*rpattern_ocnsppt(n)%varspectrum(nm) + enddo + call patterngenerator_advance(rpattern_ocnsppt(n),1,.false.) + endif + enddo endif deallocate(noise_e,noise_o) end subroutine init_stochdata_ocn @@ -474,32 +661,50 @@ end subroutine init_stochdata_ocn !>@brief This subroutine 'read_pattern' will read in the spectral coeffients from a previous run (stored in stoch_ini, !!turned on by setting STOCHINI=.true.) !>@details Data read in are flat binary, so the number of stochastic physics patterns running must match previous run -subroutine read_pattern(rpattern,k,lunptn) +subroutine read_pattern(rpattern,jcapin,lunptn,k,np,varid1,varid2,slice_of_3d,iret) !\callgraph + use netcdf type(random_pattern), intent(inout) :: rpattern - integer, intent(in) :: lunptn + integer, intent(in) :: lunptn,np,varid1,varid2,jcapin + logical, intent(in) :: slice_of_3d real(kind_dbl_prec),allocatable :: pattern2d(:),pattern2din(:) real(kind_dbl_prec) :: stdevin,varin - integer nm,nn,ierr,jcap,isize,k + integer nm,nn,iret,ierr,isize,k,ndimspec2 integer, allocatable :: isave(:) - - allocate(pattern2d(2*ndimspec)) + include 'netcdf.inc' + iret=0 + ndimspec2=2*ndimspec + allocate(pattern2d(ndimspec2)) pattern2d=0. call random_seed(size=isize,stat=rpattern%rstate) ! get size of generator state seed array allocate(isave(isize)) ! read only on root process, and send to all tasks if (is_master()) then - read(lunptn) jcap - read(lunptn) isave - allocate(pattern2din((jcap+1)*(jcap+2))) - print*,'reading in random pattern at ',jcap,ndimspec,size(pattern2din) - read(lunptn) pattern2din + allocate(pattern2din((jcapin+1)*(jcapin+2))) + print*,'reading in random pattern at ',jcapin,ndimspec,size(pattern2din) + !read(lunptn) pattern2din + ierr=NF90_GET_VAR(lunptn,varid1,isave,(/1,np/)) + if (ierr .NE. 0) then + write(0,*) 'error reading seed' + iret = ierr + return + end if + if (slice_of_3d) then + ierr=NF90_GET_VAR(lunptn,varid2,pattern2din,(/1,k,np/),(/ndimspec2,1,1/)) + else + ierr=NF90_GET_VAR(lunptn,varid2,pattern2din,(/1,np/),(/ndimspec2,1/)) + endif + if (ierr .NE. 0) then + write(0,*) 'error reading spec var' + iret = ierr + return + end if print*,'reading in random pattern (min/max/size/seed)',& minval(pattern2din),maxval(pattern2din),size(pattern2din),isave(1:4) - if (jcap .eq. ntrunc) then + if (jcapin .eq. ntrunc) then pattern2d=pattern2din else - call chgres_pattern(pattern2din,pattern2d,jcap,ntrunc) ! chgres of spectral files + call chgres_pattern(pattern2din,pattern2d,jcapin,ntrunc) ! chgres of spectral files ! change the standard deviation of the patterns for a resolution change ! needed for SKEB & SHUM call computevarspec_r(rpattern,pattern2d,varin) diff --git a/stochy_gg_def.f b/stochy_gg_def.f deleted file mode 100644 index fd558b2..0000000 --- a/stochy_gg_def.f +++ /dev/null @@ -1,10 +0,0 @@ -!>@brief The module 'stochy_gg_def' declares array defining the gaussian grid attributes - module stochy_gg_def - use kinddef - implicit none - - real(kind=kind_dbl_prec), allocatable, dimension(:) :: colrad_a, - & wgt_a, wgtcs_a, rcs2_a, sinlat_a, coslat_a -! - integer ,allocatable, dimension(:) :: lats_nodes_h,global_lats_h - end module stochy_gg_def diff --git a/stochy_layout_lag.f b/stochy_layout_lag.f deleted file mode 100644 index c3f5494..0000000 --- a/stochy_layout_lag.f +++ /dev/null @@ -1,14 +0,0 @@ -!>@brief The module 'stochy_layout_lag' contains the decomposition attributes of the gaussian grid - module stochy_layout_lag - use kinddef - implicit none - save -cc - integer lats_dim_h, - x lats_node_h, - x lats_node_h_max, - x ipt_lats_node_h, - x lon_dim_h -cc - INTEGER ,ALLOCATABLE :: lat1s_h(:) - end module stochy_layout_lag diff --git a/stochy_namelist_def.F90 b/stochy_namelist_def.F90 index f29de0a..bf757ba 100644 --- a/stochy_namelist_def.F90 +++ b/stochy_namelist_def.F90 @@ -20,7 +20,7 @@ module stochy_namelist_def real(kind=kind_dbl_prec) :: skeb_sigtop1,skeb_sigtop2, & sppt_sigtop1,sppt_sigtop2,shum_sigefold, & skeb_vdof - real(kind=kind_dbl_prec) fhstoch,skeb_diss_smooth,epblint,ocnspptint,spptint,shumint,skebint,skebnorm + real(kind=kind_dbl_prec) skeb_diss_smooth,epblint,ocnspptint,spptint,shumint,skebint,skebnorm real(kind=kind_dbl_prec), dimension(5) :: skeb,skeb_lscale,skeb_tau real(kind=kind_dbl_prec), dimension(5) :: sppt,sppt_lscale,sppt_tau real(kind=kind_dbl_prec), dimension(5) :: shum,shum_lscale,shum_tau From 170d7e8f3edb8bd52edef8b5d2168910dc34c710 Mon Sep 17 00:00:00 2001 From: pjpegion Date: Tue, 22 Dec 2020 18:38:39 +0000 Subject: [PATCH 03/13] modifictations to CMakelists, still not building properly --- CMakeLists.txt | 3 ++- get_stochy_pattern.F90 | 6 +++--- stochastic_physics.F90 | 4 ++-- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6e3328c..a16a609 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -55,5 +55,6 @@ target_compile_definitions(stochastic_physics PRIVATE INTERNAL_FILE_NML) target_link_libraries(stochastic_physics PUBLIC sp::sp_d) target_link_libraries(stochastic_physics PUBLIC fms) if(OpenMP_Fortran_FOUND) - target_link_libraries(stochastic_physics PUBLIC OpenMP::OpenMP_Fortran) + #target_link_libraries(stochastic_physics PUBLIC OpenMP::OpenMP_Fortran) + target_link_libraries(stochastic_physics PRIVATE OpenMP::OpenMP_Fortran) endif() diff --git a/get_stochy_pattern.F90 b/get_stochy_pattern.F90 index fe1d7b3..a069623 100644 --- a/get_stochy_pattern.F90 +++ b/get_stochy_pattern.F90 @@ -471,7 +471,7 @@ subroutine write_stoch_restart_ocn(sfile) integer :: ncid,varid1a,varid1b,varid2a,varid2b,varid3a,varid3b integer :: seed_dim_id,spec_dim_id,np_dim_id include 'netcdf.inc' - + print*,'in write_restart_ocn',do_ocnsppt,do_epbl,is_master() if ( ( .NOT. do_ocnsppt) .AND. (.NOT. do_epbl) ) return stochlun=99 if (is_master()) then @@ -496,9 +496,9 @@ subroutine write_stoch_restart_ocn(sfile) ierr=NF90_PUT_ATT(ncid,varid2a,"long_name","random number seed for EPBL1") ierr=NF90_DEF_VAR(ncid,"epbl1_spec",NF90_DOUBLE,(/spec_dim_id, np_dim_id/), varid2b) ierr=NF90_PUT_ATT(ncid,varid2b,"long_name","spectral cofficients EPBL1") - ierr=NF90_DEF_VAR(ncid,"epbl1_seed",NF90_DOUBLE,(/seed_dim_id, np_dim_id/), varid3a) + ierr=NF90_DEF_VAR(ncid,"epbl2_seed",NF90_DOUBLE,(/seed_dim_id, np_dim_id/), varid3a) ierr=NF90_PUT_ATT(ncid,varid3a,"long_name","random number seed for EPBL2") - ierr=NF90_DEF_VAR(ncid,"epbl1_spec",NF90_DOUBLE,(/spec_dim_id, np_dim_id/), varid3b) + ierr=NF90_DEF_VAR(ncid,"epbl2_spec",NF90_DOUBLE,(/spec_dim_id, np_dim_id/), varid3b) ierr=NF90_PUT_ATT(ncid,varid3b,"long_name","spectral cofficients EPBL2") endif ierr=NF90_ENDDEF(ncid) diff --git a/stochastic_physics.F90 b/stochastic_physics.F90 index 2eadf92..f8ff9f5 100644 --- a/stochastic_physics.F90 +++ b/stochastic_physics.F90 @@ -444,14 +444,14 @@ subroutine run_stochastic_physics_ocn(t_rp,sppt_wts) t_rp(:,:,1)=2.0/(1+exp(-1*tmp_wts)) call get_random_pattern_scalar(rpattern_epbl2,nepbl,gis_stochy_ocn,tmp_wts) t_rp(:,:,2)=2.0/(1+exp(-1*tmp_wts)) -! print*,'in run_stochastic_physics_ocn 1',minval(t_rp),maxval(t_rp) + print*,'in run_stochastic_physics_ocn 1',minval(t_rp),maxval(t_rp) else t_rp=1.0 endif if (do_ocnsppt) then call get_random_pattern_scalar(rpattern_ocnsppt,nocnsppt,gis_stochy_ocn,tmp_wts) sppt_wts=2.0/(1+exp(-1*tmp_wts)) -! print*,'in run_stochastic_physics_ocn 2',minval(sppt_wts),maxval(sppt_wts) + print*,'in run_stochastic_physics_ocn 2',minval(sppt_wts),maxval(sppt_wts) else sppt_wts=1.0 endif From 79e0d1d104917fb71d25bd087673947daf84a353 Mon Sep 17 00:00:00 2001 From: pjpegion Date: Wed, 23 Dec 2020 21:57:16 +0000 Subject: [PATCH 04/13] remove libsp_4.a dependency --- CMakeLists.txt | 2 +- compns_stochy.F90 | 1 - four_to_grid_stochy.F | 11 +++++------ get_stochy_pattern.F90 | 7 ------- stochastic_physics.F90 | 20 +------------------- 5 files changed, 7 insertions(+), 34 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a16a609..f27ec5f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,6 +17,7 @@ list(APPEND _stoch_phys_srcs halo_exchange.fv3.F90 plumes.f90 four_to_grid_stochy.F + fftpack_stochy.f glats_stochy.f sumfln_stochy.f gozrineo_stochy.f @@ -52,7 +53,6 @@ add_dependencies(stochastic_physics fms) target_compile_definitions(stochastic_physics PRIVATE INTERNAL_FILE_NML) -target_link_libraries(stochastic_physics PUBLIC sp::sp_d) target_link_libraries(stochastic_physics PUBLIC fms) if(OpenMP_Fortran_FOUND) #target_link_libraries(stochastic_physics PUBLIC OpenMP::OpenMP_Fortran) diff --git a/compns_stochy.F90 b/compns_stochy.F90 index 888d868..778c9dc 100644 --- a/compns_stochy.F90 +++ b/compns_stochy.F90 @@ -151,7 +151,6 @@ subroutine compns_stochy (me,sz_nml,input_nml_file,fn_nml,nlunit,deltim,iret) if (me == 0) then print *,' in compns_stochy' - print*,'skeb=',skeb endif ! PJP stochastic physics additions diff --git a/four_to_grid_stochy.F b/four_to_grid_stochy.F index 3d6283b..bdeda85 100644 --- a/four_to_grid_stochy.F +++ b/four_to_grid_stochy.F @@ -24,7 +24,7 @@ subroutine four_to_grid(syn_gr_a_1,syn_gr_a_2, #ifdef MKL integer*8 plan #else - real(kind=kind_dbl_prec) aux1crs(42002) + real(kind=kind_dbl_prec) aux1crs(44002) real(kind=kind_dbl_prec) scale_ibm integer ibmsign integer init @@ -32,9 +32,6 @@ subroutine four_to_grid(syn_gr_a_1,syn_gr_a_2, #ifdef MKL include "fftw/fftw3.f" integer NULL -#else - external dcrft - external scrft #endif !________________________________________________________ @@ -52,7 +49,7 @@ subroutine four_to_grid(syn_gr_a_1,syn_gr_a_2, ibmsign = -1 scale_ibm = 1.0d0 - call dcrft(init, + call dcrft_stochy(init, & syn_gr_a_1(1,1) ,lon_dim_coef/2, & syn_gr_a_2(1,1) ,lon_dim_grid, & lons_lat,lot,ibmsign,scale_ibm, @@ -60,7 +57,7 @@ subroutine four_to_grid(syn_gr_a_1,syn_gr_a_2, & aux1crs(22001),20000) init = 0 - call dcrft(init, + call dcrft_stochy(init, & syn_gr_a_1(1,1) ,lon_dim_coef/2, & syn_gr_a_2(1,1) ,lon_dim_grid, & lons_lat,lot,ibmsign,scale_ibm, @@ -70,4 +67,6 @@ subroutine four_to_grid(syn_gr_a_1,syn_gr_a_2, return end + + end module four_to_grid_mod diff --git a/get_stochy_pattern.F90 b/get_stochy_pattern.F90 index a069623..1c7652a 100644 --- a/get_stochy_pattern.F90 +++ b/get_stochy_pattern.F90 @@ -377,7 +377,6 @@ subroutine write_stoch_restart_atm(sfile) if (is_master()) then if (nsppt > 0 .OR. nshum > 0 .OR. nskeb > 0) then ierr=nf90_create(trim(sfile),cmode=NF90_CLOBBER,ncid=ncid) - print*,'open ',sfile,' for output' ierr=NF90_PUT_ATT(ncid,NF_GLOBAL,"ntrunc",ntrunc) call random_seed(size=isize) ! get seed size ierr=NF90_DEF_DIM(ncid,"len_seed",isize,seed_dim_id) @@ -471,12 +470,10 @@ subroutine write_stoch_restart_ocn(sfile) integer :: ncid,varid1a,varid1b,varid2a,varid2b,varid3a,varid3b integer :: seed_dim_id,spec_dim_id,np_dim_id include 'netcdf.inc' - print*,'in write_restart_ocn',do_ocnsppt,do_epbl,is_master() if ( ( .NOT. do_ocnsppt) .AND. (.NOT. do_epbl) ) return stochlun=99 if (is_master()) then ierr=nf90_create(trim(sfile),cmode=NF90_CLOBBER,ncid=ncid) - print*,'open ',sfile,' for output' ierr=NF90_PUT_ATT(ncid,NF_GLOBAL,"ntrunc",ntrunc) call random_seed(size=isize) ! get seed size ierr=NF90_DEF_DIM(ncid,"len_seed",isize,seed_dim_id) @@ -546,8 +543,6 @@ subroutine write_pattern(rpattern,outlun,lev,np,varid1,varid2,slice_of_3d,iret) allocate(pattern2d(arrlen)) pattern2d=0.0 ! fill in apprpriate pieces of array - !print*,'before collection...',me,maxval(rpattern%spec_e),maxval(rpattern%spec_o) & - ! ,minval(rpattern%spec_e),minval(rpattern%spec_o) do nn=1,len_trie_ls nm = rpattern%idx_e(nn) if (nm == 0) cycle @@ -565,12 +560,10 @@ subroutine write_pattern(rpattern,outlun,lev,np,varid1,varid2,slice_of_3d,iret) if (is_master()) then print*,'writing out random pattern (min/max/size)',& minval(pattern2d),maxval(pattern2d),size(pattern2d) - !print*,'max/min pattern=',maxval(pattern2d),minval(pattern2d) call random_seed(size=isize) ! get seed size allocate(isave(isize)) ! get seed call random_seed(get=isave,stat=rpattern%rstate) ! write seed ierr=NF90_PUT_VAR(outlun,varid1,isave,(/1,np/)) - print*,'put seed',ierr,np if (slice_of_3d) then ierr=NF90_PUT_VAR(outlun,varid2,pattern2d,(/1,lev,np/)) else diff --git a/stochastic_physics.F90 b/stochastic_physics.F90 index f8ff9f5..c71a0ff 100644 --- a/stochastic_physics.F90 +++ b/stochastic_physics.F90 @@ -78,7 +78,6 @@ subroutine init_stochastic_physics(levs, blksz, dtp, input_nml_file_in, fn_nml, allocate(gis_stochy%len(nblks)) allocate(gis_stochy%parent_lons(gis_stochy%nx,gis_stochy%ny)) allocate(gis_stochy%parent_lats(gis_stochy%nx,gis_stochy%ny)) -print*,'in init_stochastic_physics',minval(xlon),maxval(xlon),minval(xlat),maxval(xlat) do blk=1,nblks len=blksz(blk) gis_stochy%parent_lons(1:len,blk)=xlon(blk,1:len)*rad2deg @@ -151,7 +150,6 @@ subroutine init_stochastic_physics(levs, blksz, dtp, input_nml_file_in, fn_nml, endif endif if (do_skeb) then - !print*,'allocating skeb stuff',skeblevs allocate(vfact_skeb(levs)) allocate(skeb_vloc(skeblevs)) ! local allocate(skeb_vwts(levs,2)) ! save for later @@ -208,25 +206,19 @@ subroutine init_stochastic_physics(levs, blksz, dtp, input_nml_file_in, fn_nml, ! get interpolation weights ! define gaussian grid lats and lons latghf=latg/2 -!print *,'define interp weights',latghf,lonf -!print *,allocated(gg_lats),allocated(gg_lons) allocate(gg_lats(latg)) -!print *,'aloocated lats' allocate(gg_lons(lonf)) -!print *,'aloocated lons' do k=1,latghf gg_lats(k)=-1.0*colrad_a(latghf-k+1)*rad2deg gg_lats(latg-k+1)=-1*gg_lats(k) enddo dx=360.0/lonf -!print*,'dx=',dx do k=1,lonf gg_lons(k)=dx*(k-1) enddo WLON=gg_lons(1)-(gg_lons(2)-gg_lons(1)) RNLAT=gg_lats(1)*2-gg_lats(2) -!print *,'done with init_stochastic_physics' end subroutine init_stochastic_physics @@ -266,12 +258,9 @@ subroutine init_stochastic_physics_ocn(delt,geoLonT,geoLatT,nx,ny,nz,do_epbl_out gis_stochy_ocn%len(:)=nx gis_stochy_ocn%parent_lons=geoLonT gis_stochy_ocn%parent_lats=geoLatT -print*,'ocn parent lats=',minval(gis_stochy_ocn%parent_lats) -! replace + INTTYP=0 ! bilinear interpolation km=nz -!print*,'in init',nx,ny,nz -print*,'init_stochastic_physics_ocn',maxval(geoLonT),size(geoLonT(:,1)),size(geoLonT(1,:)) call init_stochdata_ocn(km,delt,iret) do_epbl_out=do_epbl do_sppt_out=do_ocnsppt @@ -280,18 +269,13 @@ subroutine init_stochastic_physics_ocn(delt,geoLonT,geoLatT,nx,ny,nz,do_epbl_out ! get interpolation weights ! define gaussian grid lats and lons latghf=latg/2 -!print *,'define interp weights',latghf,lonf -!print *,allocated(gg_lats),allocated(gg_lons) allocate(gg_lats(latg)) -!print *,'aloocated lats',latg allocate(gg_lons(lonf)) -!print *,'aloocated lons',lonf do k=1,latghf gg_lats(k)=-1.0*colrad_a(latghf-k+1)*rad2deg gg_lats(latg-k+1)=-1*gg_lats(k) enddo dx=360.0/lonf -!print*,'dx=',dx do k=1,lonf gg_lons(k)=dx*(k-1) enddo @@ -444,14 +428,12 @@ subroutine run_stochastic_physics_ocn(t_rp,sppt_wts) t_rp(:,:,1)=2.0/(1+exp(-1*tmp_wts)) call get_random_pattern_scalar(rpattern_epbl2,nepbl,gis_stochy_ocn,tmp_wts) t_rp(:,:,2)=2.0/(1+exp(-1*tmp_wts)) - print*,'in run_stochastic_physics_ocn 1',minval(t_rp),maxval(t_rp) else t_rp=1.0 endif if (do_ocnsppt) then call get_random_pattern_scalar(rpattern_ocnsppt,nocnsppt,gis_stochy_ocn,tmp_wts) sppt_wts=2.0/(1+exp(-1*tmp_wts)) - print*,'in run_stochastic_physics_ocn 2',minval(sppt_wts),maxval(sppt_wts) else sppt_wts=1.0 endif From 41cc63ee01c3b82ac8c3ab5a2fff422b3d10922e Mon Sep 17 00:00:00 2001 From: pjpegion Date: Wed, 6 Jan 2021 15:52:21 +0000 Subject: [PATCH 05/13] updates to use MKL library --- CMakeLists.txt | 10 ++++++++++ get_stochy_pattern.F90 | 7 +++++++ stochastic_physics.F90 | 6 ++++-- 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f27ec5f..ee8b2ee 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,6 +10,16 @@ if(32BIT) set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -fdefault-real-8") endif() endif() +# Set Intel MKL flags for preprocessor, compiler and linker (if defined) +if(MKL_DIR_STOCH) + set (MKL_INC "-m64 -I$ENV{MKLROOT}/include") + set (MKL_LIB "-L$ENV{MKLROOT}/lib/intel64 -Wl,-rpath,$ENV{MKLROOT}/lib/intel64 -lmkl_intel_lp64 -lmkl_sequential -lmkl_core -lpthread -lm -ldl") + set (CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} ${MKL_INC} ${MKL_LIB}") + ADD_DEFINITIONS(-DMKL) + message (STATUS "Enable Intel MKL support") +else() + message (STATUS "Disable Intel MKL support") +endif() list(APPEND _stoch_phys_srcs kinddef.F90 diff --git a/get_stochy_pattern.F90 b/get_stochy_pattern.F90 index 1c7652a..738f7c9 100644 --- a/get_stochy_pattern.F90 +++ b/get_stochy_pattern.F90 @@ -633,8 +633,15 @@ subroutine vrtdivspect_to_uvgrid(& do lan=1,lats_node_a lat = global_lats_a(ipt_lats_node_a-1+lan) lons_lat = lonsperlar(lat) +#ifdef MKL + CALL FOUR_TO_GRID(for_gr_a_1(1,1,lan),for_gr_a_2(1,1,lan),& + lon_dim_a,lonf,lons_lat,nlevs) + CALL FOUR_TO_GRID(for_gr_a_1(1,2,lan),for_gr_a_2(1,2,lan),& + lon_dim_a,lonf,lons_lat,nlevs) +#else CALL FOUR_TO_GRID(for_gr_a_1(1,1,lan),for_gr_a_2(1,1,lan),& lon_dim_a,lonf,lons_lat,2*nlevs) +#endif enddo uug = 0.; vvg = 0. diff --git a/stochastic_physics.F90 b/stochastic_physics.F90 index c71a0ff..b3d4f53 100644 --- a/stochastic_physics.F90 +++ b/stochastic_physics.F90 @@ -19,13 +19,13 @@ module stochastic_physics !>@details It reads the stochastic physics namelist (nam_stoch and nam_sfcperts) !allocates and polulates the necessary arrays -subroutine init_stochastic_physics(levs, blksz, dtp, input_nml_file_in, fn_nml, nlunit, & +subroutine init_stochastic_physics(levs, blksz, dtp, sppt_amp, input_nml_file_in, fn_nml, nlunit, & xlon,xlat, & do_sppt_in, do_shum_in, do_skeb_in, lndp_type_in, n_var_lndp_in, use_zmtnblck_out, skeb_npass_out, & lndp_var_list_out, lndp_prt_list_out, ak, bk, nthreads, mpiroot, mpicomm, iret) !\callgraph !use stochy_internal_state_moa -use stochy_data_mod, only : init_stochdata,gg_lats,gg_lons,& +use stochy_data_mod, only : init_stochdata,gg_lats,gg_lons,nsppt, & rad2deg,INTTYP,wlon,rnlat,gis_stochy,vfact_skeb,vfact_sppt,vfact_shum,skeb_vpts,skeb_vwts,sl use stochy_namelist_def use spectral_layout_mod,only:me,master,nodes,colrad_a,latg,lonf,skeblevs @@ -39,6 +39,7 @@ subroutine init_stochastic_physics(levs, blksz, dtp, input_nml_file_in, fn_nml, integer, intent(in) :: levs, nlunit, nthreads, mpiroot, mpicomm integer, intent(in) :: blksz(:) real(kind=kind_dbl_prec), intent(in) :: dtp +real(kind=kind_dbl_prec), intent(out) :: sppt_amp character(len=*), intent(in) :: input_nml_file_in(:) character(len=*), intent(in) :: fn_nml real(kind=kind_dbl_prec), intent(in) :: xlon(:,:) @@ -148,6 +149,7 @@ subroutine init_stochastic_physics(levs, blksz, dtp, input_nml_file_in, fn_nml, print *,'sppt vert profile',k,sl(k),vfact_sppt(k) enddo endif + sppt_amp=sqrt(SUM(sppt(1:nsppt)**2)) endif if (do_skeb) then allocate(vfact_skeb(levs)) From 438f1dd00d7028fb63a2473be16510f7ad95a200 Mon Sep 17 00:00:00 2001 From: pjpegion Date: Wed, 6 Jan 2021 16:02:33 +0000 Subject: [PATCH 06/13] change MKL_DIR_STOCH to MKL_DIR in CmakeLists.txt --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ee8b2ee..0d3cd10 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,7 +11,7 @@ if(32BIT) endif() endif() # Set Intel MKL flags for preprocessor, compiler and linker (if defined) -if(MKL_DIR_STOCH) +if(MKL_DIR) set (MKL_INC "-m64 -I$ENV{MKLROOT}/include") set (MKL_LIB "-L$ENV{MKLROOT}/lib/intel64 -Wl,-rpath,$ENV{MKLROOT}/lib/intel64 -lmkl_intel_lp64 -lmkl_sequential -lmkl_core -lpthread -lm -ldl") set (CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} ${MKL_INC} ${MKL_LIB}") From 2a661e94b465989cb7f6981682f2d175c3aacdd7 Mon Sep 17 00:00:00 2001 From: pjpegion Date: Tue, 12 Jan 2021 21:24:24 +0000 Subject: [PATCH 07/13] add local fftpack taken from splib --- fftpack_stochy.f | 535 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 535 insertions(+) create mode 100644 fftpack_stochy.f diff --git a/fftpack_stochy.f b/fftpack_stochy.f new file mode 100644 index 0000000..f70f14a --- /dev/null +++ b/fftpack_stochy.f @@ -0,0 +1,535 @@ + SUBROUTINE dcrft_stochy(init,x,ldx,y,ldy,n,m,isign,scale, + & table,n1,wrk,n2,z,nz) + + implicit none + integer init,ldx,ldy,n,m,isign,n1,n2,nz,i,j + real x(2*ldx,*),y(ldy,*),scale,table(44002),wrk,z + + IF (init.ne.0) THEN + CALL rffti_stochy(n,table) + ELSE +!OCL NOVREC + DO j=1,m + y(1,j)=x(1,j) + DO i=2,n + y(i,j)=x(i+1,j) + ENDDO + CALL rfftb_stochy(n,y(1,j),table) + DO i=1,n + y(i,j)=scale*y(i,j) + ENDDO + ENDDO + ENDIF + + RETURN + END + +c +c ****************************************************************** +c ****************************************************************** +c ****** ****** +c ****** FFTPACK ****** +c ****** ****** +c ****************************************************************** +c ****************************************************************** +c + SUBROUTINE RFFTB_STOCHY (N,R,WSAVE) + DIMENSION R(1) ,WSAVE(1) + IF (N .EQ. 1) RETURN + CALL RFFTB1_STOCHY (N,R,WSAVE,WSAVE(N+1),WSAVE(2*N+1)) + RETURN + END + SUBROUTINE RFFTI_STOCHY (N,WSAVE) + DIMENSION WSAVE(1) + IF (N .EQ. 1) RETURN + CALL RFFTI1_STOCHY (N,WSAVE(N+1),WSAVE(2*N+1)) + RETURN + END + SUBROUTINE RFFTB1_STOCHY (N,C,CH,WA,IFAC) + DIMENSION CH(1) ,C(1) ,WA(1) ,IFAC(*) + NF = IFAC(2) + NA = 0 + L1 = 1 + IW = 1 + DO 116 K1=1,NF + IP = IFAC(K1+2) + L2 = IP*L1 + IDO = N/L2 + IDL1 = IDO*L1 + IF (IP .NE. 4) GO TO 103 + IX2 = IW+IDO + IX3 = IX2+IDO + IF (NA .NE. 0) GO TO 101 + CALL RADB4_STOCHY (IDO,L1,C,CH,WA(IW),WA(IX2),WA(IX3)) + GO TO 102 + 101 CALL RADB4_STOCHY (IDO,L1,CH,C,WA(IW),WA(IX2),WA(IX3)) + 102 NA = 1-NA + GO TO 115 + 103 IF (IP .NE. 2) GO TO 106 + IF (NA .NE. 0) GO TO 104 + CALL RADB2_STOCHY (IDO,L1,C,CH,WA(IW)) + GO TO 105 + 104 CALL RADB2_STOCHY (IDO,L1,CH,C,WA(IW)) + 105 NA = 1-NA + GO TO 115 + 106 IF (IP .NE. 3) GO TO 109 + IX2 = IW+IDO + IF (NA .NE. 0) GO TO 107 + CALL RADB3_STOCHY (IDO,L1,C,CH,WA(IW),WA(IX2)) + GO TO 108 + 107 CALL RADB3_STOCHY (IDO,L1,CH,C,WA(IW),WA(IX2)) + 108 NA = 1-NA + GO TO 115 + 109 IF (IP .NE. 5) GO TO 112 + IX2 = IW+IDO + IX3 = IX2+IDO + IX4 = IX3+IDO + IF (NA .NE. 0) GO TO 110 + CALL RADB5_STOCHY (IDO,L1,C,CH,WA(IW),WA(IX2),WA(IX3),WA(IX4)) + GO TO 111 + 110 CALL RADB5_STOCHY (IDO,L1,CH,C,WA(IW),WA(IX2),WA(IX3),WA(IX4)) + 111 NA = 1-NA + GO TO 115 + 112 IF (NA .NE. 0) GO TO 113 + CALL RADBG_STOCHY (IDO,IP,L1,IDL1,C,C,C,CH,CH,WA(IW)) + GO TO 114 + 113 CALL RADBG_STOCHY (IDO,IP,L1,IDL1,CH,CH,CH,C,C,WA(IW)) + 114 IF (IDO .EQ. 1) NA = 1-NA + 115 L1 = L2 + IW = IW+(IP-1)*IDO + 116 CONTINUE + IF (NA .EQ. 0) RETURN + DO 117 I=1,N + C(I) = CH(I) + 117 CONTINUE + RETURN + END + + + + SUBROUTINE RFFTI1_STOCHY (N,WA,IFAC) + DIMENSION WA(1) ,IFAC(*) ,NTRYH(4) + DATA NTRYH(1),NTRYH(2),NTRYH(3),NTRYH(4)/4,2,3,5/ + NL = N + NF = 0 + J = 0 + 101 J = J+1 + IF (J-4) 102,102,103 + 102 NTRY = NTRYH(J) + GO TO 104 + 103 NTRY = NTRY+2 + 104 NQ = NL/NTRY + NR = NL-NTRY*NQ + IF (NR) 101,105,101 + 105 NF = NF+1 + IFAC(NF+2) = NTRY + NL = NQ + IF (NTRY .NE. 2) GO TO 107 + IF (NF .EQ. 1) GO TO 107 + DO 106 I=2,NF + IB = NF-I+2 + IFAC(IB+2) = IFAC(IB+1) + 106 CONTINUE + IFAC(3) = 2 + 107 IF (NL .NE. 1) GO TO 104 + IFAC(1) = N + IFAC(2) = NF + TPI = 6.28318530717959 + ARGH = TPI/FLOAT(N) + IS = 0 + NFM1 = NF-1 + L1 = 1 + IF (NFM1 .EQ. 0) RETURN +!OCL NOVREC + DO 110 K1=1,NFM1 + IP = IFAC(K1+2) + LD = 0 + L2 = L1*IP + IDO = N/L2 + IPM = IP-1 + DO 109 J=1,IPM + LD = LD+L1 + I = IS + ARGLD = FLOAT(LD)*ARGH + FI = 0 +!OCL SCALAR + DO 108 II=3,IDO,2 + I = I+2 + FI = FI+1 + ARG = FI*ARGLD + WA(I-1) = COS(ARG) + WA(I) = SIN(ARG) + 108 CONTINUE + IS = IS+IDO + 109 CONTINUE + L1 = L2 + 110 CONTINUE + RETURN + END + + + SUBROUTINE RADB2_STOCHY (IDO,L1,CC,CH,WA1) + DIMENSION CC(IDO,2,L1) ,CH(IDO,L1,2) , + 1 WA1(1) + DO 101 K=1,L1 + CH(1,K,1) = CC(1,1,K)+CC(IDO,2,K) + CH(1,K,2) = CC(1,1,K)-CC(IDO,2,K) + 101 CONTINUE + IF (IDO-2) 107,105,102 + 102 IDP2 = IDO+2 +!OCL NOVREC + DO 104 K=1,L1 + DO 103 I=3,IDO,2 + IC = IDP2-I + CH(I-1,K,1) = CC(I-1,1,K)+CC(IC-1,2,K) + TR2 = CC(I-1,1,K)-CC(IC-1,2,K) + CH(I,K,1) = CC(I,1,K)-CC(IC,2,K) + TI2 = CC(I,1,K)+CC(IC,2,K) + CH(I-1,K,2) = WA1(I-2)*TR2-WA1(I-1)*TI2 + CH(I,K,2) = WA1(I-2)*TI2+WA1(I-1)*TR2 + 103 CONTINUE + 104 CONTINUE + IF (MOD(IDO,2) .EQ. 1) RETURN + 105 DO 106 K=1,L1 + CH(IDO,K,1) = CC(IDO,1,K)+CC(IDO,1,K) + CH(IDO,K,2) = -(CC(1,2,K)+CC(1,2,K)) + 106 CONTINUE + 107 RETURN + END + + + SUBROUTINE RADB3_STOCHY (IDO,L1,CC,CH,WA1,WA2) + DIMENSION CC(IDO,3,L1) ,CH(IDO,L1,3) , + 1 WA1(1) ,WA2(1) + DATA TAUR,TAUI /-.5,.866025403784439/ + DO 101 K=1,L1 + TR2 = CC(IDO,2,K)+CC(IDO,2,K) + CR2 = CC(1,1,K)+TAUR*TR2 + CH(1,K,1) = CC(1,1,K)+TR2 + CI3 = TAUI*(CC(1,3,K)+CC(1,3,K)) + CH(1,K,2) = CR2-CI3 + CH(1,K,3) = CR2+CI3 + 101 CONTINUE + IF (IDO .EQ. 1) RETURN + IDP2 = IDO+2 +!OCL NOVREC + DO 103 K=1,L1 + DO 102 I=3,IDO,2 + IC = IDP2-I + TR2 = CC(I-1,3,K)+CC(IC-1,2,K) + CR2 = CC(I-1,1,K)+TAUR*TR2 + CH(I-1,K,1) = CC(I-1,1,K)+TR2 + TI2 = CC(I,3,K)-CC(IC,2,K) + CI2 = CC(I,1,K)+TAUR*TI2 + CH(I,K,1) = CC(I,1,K)+TI2 + CR3 = TAUI*(CC(I-1,3,K)-CC(IC-1,2,K)) + CI3 = TAUI*(CC(I,3,K)+CC(IC,2,K)) + DR2 = CR2-CI3 + DR3 = CR2+CI3 + DI2 = CI2+CR3 + DI3 = CI2-CR3 + CH(I-1,K,2) = WA1(I-2)*DR2-WA1(I-1)*DI2 + CH(I,K,2) = WA1(I-2)*DI2+WA1(I-1)*DR2 + CH(I-1,K,3) = WA2(I-2)*DR3-WA2(I-1)*DI3 + CH(I,K,3) = WA2(I-2)*DI3+WA2(I-1)*DR3 + 102 CONTINUE + 103 CONTINUE + RETURN + END + + + SUBROUTINE RADB4_STOCHY (IDO,L1,CC,CH,WA1,WA2,WA3) + DIMENSION CC(IDO,4,L1) ,CH(IDO,L1,4) , + 1 WA1(1) ,WA2(1) ,WA3(1) + DATA SQRT2 /1.414213562373095/ + DO 101 K=1,L1 + TR1 = CC(1,1,K)-CC(IDO,4,K) + TR2 = CC(1,1,K)+CC(IDO,4,K) + TR3 = CC(IDO,2,K)+CC(IDO,2,K) + TR4 = CC(1,3,K)+CC(1,3,K) + CH(1,K,1) = TR2+TR3 + CH(1,K,2) = TR1-TR4 + CH(1,K,3) = TR2-TR3 + CH(1,K,4) = TR1+TR4 + 101 CONTINUE + IF (IDO-2) 107,105,102 + 102 IDP2 = IDO+2 +!OCL NOVREC + DO 104 K=1,L1 + DO 103 I=3,IDO,2 + IC = IDP2-I + TI1 = CC(I,1,K)+CC(IC,4,K) + TI2 = CC(I,1,K)-CC(IC,4,K) + TI3 = CC(I,3,K)-CC(IC,2,K) + TR4 = CC(I,3,K)+CC(IC,2,K) + TR1 = CC(I-1,1,K)-CC(IC-1,4,K) + TR2 = CC(I-1,1,K)+CC(IC-1,4,K) + TI4 = CC(I-1,3,K)-CC(IC-1,2,K) + TR3 = CC(I-1,3,K)+CC(IC-1,2,K) + CH(I-1,K,1) = TR2+TR3 + CR3 = TR2-TR3 + CH(I,K,1) = TI2+TI3 + CI3 = TI2-TI3 + CR2 = TR1-TR4 + CR4 = TR1+TR4 + CI2 = TI1+TI4 + CI4 = TI1-TI4 + CH(I-1,K,2) = WA1(I-2)*CR2-WA1(I-1)*CI2 + CH(I,K,2) = WA1(I-2)*CI2+WA1(I-1)*CR2 + CH(I-1,K,3) = WA2(I-2)*CR3-WA2(I-1)*CI3 + CH(I,K,3) = WA2(I-2)*CI3+WA2(I-1)*CR3 + CH(I-1,K,4) = WA3(I-2)*CR4-WA3(I-1)*CI4 + CH(I,K,4) = WA3(I-2)*CI4+WA3(I-1)*CR4 + 103 CONTINUE + 104 CONTINUE + IF (MOD(IDO,2) .EQ. 1) RETURN + 105 CONTINUE + DO 106 K=1,L1 + TI1 = CC(1,2,K)+CC(1,4,K) + TI2 = CC(1,4,K)-CC(1,2,K) + TR1 = CC(IDO,1,K)-CC(IDO,3,K) + TR2 = CC(IDO,1,K)+CC(IDO,3,K) + CH(IDO,K,1) = TR2+TR2 + CH(IDO,K,2) = SQRT2*(TR1-TI1) + CH(IDO,K,3) = TI2+TI2 + CH(IDO,K,4) = -SQRT2*(TR1+TI1) + 106 CONTINUE + 107 RETURN + END + + + SUBROUTINE RADB5_STOCHY (IDO,L1,CC,CH,WA1,WA2,WA3,WA4) + DIMENSION CC(IDO,5,L1) ,CH(IDO,L1,5) , + 1 WA1(1) ,WA2(1) ,WA3(1) ,WA4(1) + DATA TR11,TI11,TR12,TI12 /.309016994374947,.951056516295154, + 1-.809016994374947,.587785252292473/ + DO 101 K=1,L1 + TI5 = CC(1,3,K)+CC(1,3,K) + TI4 = CC(1,5,K)+CC(1,5,K) + TR2 = CC(IDO,2,K)+CC(IDO,2,K) + TR3 = CC(IDO,4,K)+CC(IDO,4,K) + CH(1,K,1) = CC(1,1,K)+TR2+TR3 + CR2 = CC(1,1,K)+TR11*TR2+TR12*TR3 + CR3 = CC(1,1,K)+TR12*TR2+TR11*TR3 + CI5 = TI11*TI5+TI12*TI4 + CI4 = TI12*TI5-TI11*TI4 + CH(1,K,2) = CR2-CI5 + CH(1,K,3) = CR3-CI4 + CH(1,K,4) = CR3+CI4 + CH(1,K,5) = CR2+CI5 + 101 CONTINUE + IF (IDO .EQ. 1) RETURN + IDP2 = IDO+2 + DO 103 K=1,L1 + DO 102 I=3,IDO,2 + IC = IDP2-I + TI5 = CC(I,3,K)+CC(IC,2,K) + TI2 = CC(I,3,K)-CC(IC,2,K) + TI4 = CC(I,5,K)+CC(IC,4,K) + TI3 = CC(I,5,K)-CC(IC,4,K) + TR5 = CC(I-1,3,K)-CC(IC-1,2,K) + TR2 = CC(I-1,3,K)+CC(IC-1,2,K) + TR4 = CC(I-1,5,K)-CC(IC-1,4,K) + TR3 = CC(I-1,5,K)+CC(IC-1,4,K) + CH(I-1,K,1) = CC(I-1,1,K)+TR2+TR3 + CH(I,K,1) = CC(I,1,K)+TI2+TI3 + CR2 = CC(I-1,1,K)+TR11*TR2+TR12*TR3 + CI2 = CC(I,1,K)+TR11*TI2+TR12*TI3 + CR3 = CC(I-1,1,K)+TR12*TR2+TR11*TR3 + CI3 = CC(I,1,K)+TR12*TI2+TR11*TI3 + CR5 = TI11*TR5+TI12*TR4 + CI5 = TI11*TI5+TI12*TI4 + CR4 = TI12*TR5-TI11*TR4 + CI4 = TI12*TI5-TI11*TI4 + DR3 = CR3-CI4 + DR4 = CR3+CI4 + DI3 = CI3+CR4 + DI4 = CI3-CR4 + DR5 = CR2+CI5 + DR2 = CR2-CI5 + DI5 = CI2-CR5 + DI2 = CI2+CR5 + CH(I-1,K,2) = WA1(I-2)*DR2-WA1(I-1)*DI2 + CH(I,K,2) = WA1(I-2)*DI2+WA1(I-1)*DR2 + CH(I-1,K,3) = WA2(I-2)*DR3-WA2(I-1)*DI3 + CH(I,K,3) = WA2(I-2)*DI3+WA2(I-1)*DR3 + CH(I-1,K,4) = WA3(I-2)*DR4-WA3(I-1)*DI4 + CH(I,K,4) = WA3(I-2)*DI4+WA3(I-1)*DR4 + CH(I-1,K,5) = WA4(I-2)*DR5-WA4(I-1)*DI5 + CH(I,K,5) = WA4(I-2)*DI5+WA4(I-1)*DR5 + 102 CONTINUE + 103 CONTINUE + RETURN + END + + + SUBROUTINE RADBG_STOCHY (IDO,IP,L1,IDL1,CC,C1,C2,CH,CH2,WA) + DIMENSION CH(IDO,L1,IP) ,CC(IDO,IP,L1) , + 1 C1(IDO,L1,IP) ,C2(IDL1,IP), + 2 CH2(IDL1,IP) ,WA(1) + DATA TPI/6.28318530717959/ + ARG = TPI/FLOAT(IP) + DCP = COS(ARG) + DSP = SIN(ARG) + IDP2 = IDO+2 + NBD = (IDO-1)/2 + IPP2 = IP+2 + IPPH = (IP+1)/2 + IF (IDO .LT. L1) GO TO 103 + DO 102 K=1,L1 + DO 101 I=1,IDO + CH(I,K,1) = CC(I,1,K) + 101 CONTINUE + 102 CONTINUE + GO TO 106 + 103 DO 105 I=1,IDO + DO 104 K=1,L1 + CH(I,K,1) = CC(I,1,K) + 104 CONTINUE + 105 CONTINUE +!OCL NOVREC + 106 DO 108 J=2,IPPH + JC = IPP2-J + J2 = J+J + DO 107 K=1,L1 + CH(1,K,J) = CC(IDO,J2-2,K)+CC(IDO,J2-2,K) + CH(1,K,JC) = CC(1,J2-1,K)+CC(1,J2-1,K) + 107 CONTINUE + 108 CONTINUE + IF (IDO .EQ. 1) GO TO 116 + IF (NBD .LT. L1) GO TO 112 +!OCL NOVREC + DO 111 J=2,IPPH + JC = IPP2-J + DO 110 K=1,L1 + DO 109 I=3,IDO,2 + IC = IDP2-I + CH(I-1,K,J) = CC(I-1,2*J-1,K)+CC(IC-1,2*J-2,K) + CH(I-1,K,JC) = CC(I-1,2*J-1,K)-CC(IC-1,2*J-2,K) + CH(I,K,J) = CC(I,2*J-1,K)-CC(IC,2*J-2,K) + CH(I,K,JC) = CC(I,2*J-1,K)+CC(IC,2*J-2,K) + 109 CONTINUE + 110 CONTINUE + 111 CONTINUE + GO TO 116 + 112 DO 115 J=2,IPPH + JC = IPP2-J + DO 114 I=3,IDO,2 + IC = IDP2-I + DO 113 K=1,L1 + CH(I-1,K,J) = CC(I-1,2*J-1,K)+CC(IC-1,2*J-2,K) + CH(I-1,K,JC) = CC(I-1,2*J-1,K)-CC(IC-1,2*J-2,K) + CH(I,K,J) = CC(I,2*J-1,K)-CC(IC,2*J-2,K) + CH(I,K,JC) = CC(I,2*J-1,K)+CC(IC,2*J-2,K) + 113 CONTINUE + 114 CONTINUE + 115 CONTINUE + 116 AR1 = 1. + AI1 = 0. +!OCL NOVREC + DO 120 L=2,IPPH + LC = IPP2-L + AR1H = DCP*AR1-DSP*AI1 + AI1 = DCP*AI1+DSP*AR1 + AR1 = AR1H + DO 117 IK=1,IDL1 + C2(IK,L) = CH2(IK,1)+AR1*CH2(IK,2) + C2(IK,LC) = AI1*CH2(IK,IP) + 117 CONTINUE + DC2 = AR1 + DS2 = AI1 + AR2 = AR1 + AI2 = AI1 +!OCL NOVREC + DO 119 J=3,IPPH + JC = IPP2-J + AR2H = DC2*AR2-DS2*AI2 + AI2 = DC2*AI2+DS2*AR2 + AR2 = AR2H + DO 118 IK=1,IDL1 + C2(IK,L) = C2(IK,L)+AR2*CH2(IK,J) + C2(IK,LC) = C2(IK,LC)+AI2*CH2(IK,JC) + 118 CONTINUE + 119 CONTINUE + 120 CONTINUE +!OCL NOVREC + DO 122 J=2,IPPH + DO 121 IK=1,IDL1 + CH2(IK,1) = CH2(IK,1)+CH2(IK,J) + 121 CONTINUE + 122 CONTINUE +!OCL NOVREC + DO 124 J=2,IPPH + JC = IPP2-J + DO 123 K=1,L1 + CH(1,K,J) = C1(1,K,J)-C1(1,K,JC) + CH(1,K,JC) = C1(1,K,J)+C1(1,K,JC) + 123 CONTINUE + 124 CONTINUE + IF (IDO .EQ. 1) GO TO 132 + IF (NBD .LT. L1) GO TO 128 +!OCL NOVREC + DO 127 J=2,IPPH + JC = IPP2-J + DO 126 K=1,L1 + DO 125 I=3,IDO,2 + CH(I-1,K,J) = C1(I-1,K,J)-C1(I,K,JC) + CH(I-1,K,JC) = C1(I-1,K,J)+C1(I,K,JC) + CH(I,K,J) = C1(I,K,J)+C1(I-1,K,JC) + CH(I,K,JC) = C1(I,K,J)-C1(I-1,K,JC) + 125 CONTINUE + 126 CONTINUE + 127 CONTINUE + GO TO 132 + 128 DO 131 J=2,IPPH + JC = IPP2-J + DO 130 I=3,IDO,2 + DO 129 K=1,L1 + CH(I-1,K,J) = C1(I-1,K,J)-C1(I,K,JC) + CH(I-1,K,JC) = C1(I-1,K,J)+C1(I,K,JC) + CH(I,K,J) = C1(I,K,J)+C1(I-1,K,JC) + CH(I,K,JC) = C1(I,K,J)-C1(I-1,K,JC) + 129 CONTINUE + 130 CONTINUE + 131 CONTINUE + 132 CONTINUE + IF (IDO .EQ. 1) RETURN + DO 133 IK=1,IDL1 + C2(IK,1) = CH2(IK,1) + 133 CONTINUE + DO 135 J=2,IP + DO 134 K=1,L1 + C1(1,K,J) = CH(1,K,J) + 134 CONTINUE + 135 CONTINUE + IF (NBD .GT. L1) GO TO 139 + IS = -IDO + DO 138 J=2,IP + IS = IS+IDO + IDIJ = IS + DO 137 I=3,IDO,2 + IDIJ = IDIJ+2 + DO 136 K=1,L1 + C1(I-1,K,J) = WA(IDIJ-1)*CH(I-1,K,J)-WA(IDIJ)*CH(I,K,J) + C1(I,K,J) = WA(IDIJ-1)*CH(I,K,J)+WA(IDIJ)*CH(I-1,K,J) + 136 CONTINUE + 137 CONTINUE + 138 CONTINUE + GO TO 143 + 139 IS = -IDO +!OCL NOVREC + DO 142 J=2,IP + IS = IS+IDO + DO 141 K=1,L1 + IDIJ = IS + DO 140 I=3,IDO,2 + IDIJ = IDIJ+2 + C1(I-1,K,J) = WA(IDIJ-1)*CH(I-1,K,J)-WA(IDIJ)*CH(I,K,J) + C1(I,K,J) = WA(IDIJ-1)*CH(I,K,J)+WA(IDIJ)*CH(I-1,K,J) + 140 CONTINUE + 141 CONTINUE + 142 CONTINUE + 143 RETURN + END + + From 8d42b0967b9e217c2712eacc527dbbe1a9c26957 Mon Sep 17 00:00:00 2001 From: pjpegion Date: Thu, 14 Jan 2021 15:07:43 +0000 Subject: [PATCH 08/13] fix fftpack for gfortran debug errors --- fftpack_stochy.f | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/fftpack_stochy.f b/fftpack_stochy.f index f70f14a..23e36e4 100644 --- a/fftpack_stochy.f +++ b/fftpack_stochy.f @@ -34,19 +34,20 @@ SUBROUTINE dcrft_stochy(init,x,ldx,y,ldy,n,m,isign,scale, c ****************************************************************** c SUBROUTINE RFFTB_STOCHY (N,R,WSAVE) - DIMENSION R(1) ,WSAVE(1) + DIMENSION R(*) ,WSAVE(44002) IF (N .EQ. 1) RETURN CALL RFFTB1_STOCHY (N,R,WSAVE,WSAVE(N+1),WSAVE(2*N+1)) RETURN END SUBROUTINE RFFTI_STOCHY (N,WSAVE) - DIMENSION WSAVE(1) +c DIMENSION WSAVE(1) + DIMENSION WSAVE(44002) IF (N .EQ. 1) RETURN CALL RFFTI1_STOCHY (N,WSAVE(N+1),WSAVE(2*N+1)) RETURN END SUBROUTINE RFFTB1_STOCHY (N,C,CH,WA,IFAC) - DIMENSION CH(1) ,C(1) ,WA(1) ,IFAC(*) + DIMENSION CH(44002) ,C(*) ,WA(*) ,IFAC(*) NF = IFAC(2) NA = 0 L1 = 1 @@ -108,7 +109,7 @@ SUBROUTINE RFFTB1_STOCHY (N,C,CH,WA,IFAC) SUBROUTINE RFFTI1_STOCHY (N,WA,IFAC) - DIMENSION WA(1) ,IFAC(*) ,NTRYH(4) + DIMENSION WA(*) ,IFAC(*) ,NTRYH(4) DATA NTRYH(1),NTRYH(2),NTRYH(3),NTRYH(4)/4,2,3,5/ NL = N NF = 0 @@ -170,7 +171,7 @@ SUBROUTINE RFFTI1_STOCHY (N,WA,IFAC) SUBROUTINE RADB2_STOCHY (IDO,L1,CC,CH,WA1) DIMENSION CC(IDO,2,L1) ,CH(IDO,L1,2) , - 1 WA1(1) + 1 WA1(*) DO 101 K=1,L1 CH(1,K,1) = CC(1,1,K)+CC(IDO,2,K) CH(1,K,2) = CC(1,1,K)-CC(IDO,2,K) @@ -200,7 +201,7 @@ SUBROUTINE RADB2_STOCHY (IDO,L1,CC,CH,WA1) SUBROUTINE RADB3_STOCHY (IDO,L1,CC,CH,WA1,WA2) DIMENSION CC(IDO,3,L1) ,CH(IDO,L1,3) , - 1 WA1(1) ,WA2(1) + 1 WA1(*) ,WA2(*) DATA TAUR,TAUI /-.5,.866025403784439/ DO 101 K=1,L1 TR2 = CC(IDO,2,K)+CC(IDO,2,K) @@ -240,7 +241,7 @@ SUBROUTINE RADB3_STOCHY (IDO,L1,CC,CH,WA1,WA2) SUBROUTINE RADB4_STOCHY (IDO,L1,CC,CH,WA1,WA2,WA3) DIMENSION CC(IDO,4,L1) ,CH(IDO,L1,4) , - 1 WA1(1) ,WA2(1) ,WA3(1) + 1 WA1(*) ,WA2(*) ,WA3(*) DATA SQRT2 /1.414213562373095/ DO 101 K=1,L1 TR1 = CC(1,1,K)-CC(IDO,4,K) @@ -300,7 +301,7 @@ SUBROUTINE RADB4_STOCHY (IDO,L1,CC,CH,WA1,WA2,WA3) SUBROUTINE RADB5_STOCHY (IDO,L1,CC,CH,WA1,WA2,WA3,WA4) DIMENSION CC(IDO,5,L1) ,CH(IDO,L1,5) , - 1 WA1(1) ,WA2(1) ,WA3(1) ,WA4(1) + 1 WA1(*) ,WA2(*) ,WA3(*) ,WA4(*) DATA TR11,TI11,TR12,TI12 /.309016994374947,.951056516295154, 1-.809016994374947,.587785252292473/ DO 101 K=1,L1 @@ -366,7 +367,7 @@ SUBROUTINE RADB5_STOCHY (IDO,L1,CC,CH,WA1,WA2,WA3,WA4) SUBROUTINE RADBG_STOCHY (IDO,IP,L1,IDL1,CC,C1,C2,CH,CH2,WA) DIMENSION CH(IDO,L1,IP) ,CC(IDO,IP,L1) , 1 C1(IDO,L1,IP) ,C2(IDL1,IP), - 2 CH2(IDL1,IP) ,WA(1) + 2 CH2(IDL1,IP) ,WA(*) DATA TPI/6.28318530717959/ ARG = TPI/FLOAT(IP) DCP = COS(ARG) From 65c6f9cac8e3c203763b06d2d05f21ea88e12731 Mon Sep 17 00:00:00 2001 From: pjpegion Date: Fri, 29 Jan 2021 19:43:32 +0000 Subject: [PATCH 09/13] merge with latest stochastic commits --- lndp_apply_perts.F90 | 2 +- stochastic_physics.F90 | 46 +++++++++++++++++++++--------------------- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/lndp_apply_perts.F90 b/lndp_apply_perts.F90 index b54076f..bd3ef9f 100644 --- a/lndp_apply_perts.F90 +++ b/lndp_apply_perts.F90 @@ -117,7 +117,7 @@ subroutine lndp_apply_perts(blksz, lsm, lsm_noah, lsm_ruc, lsoil, & nblks = size(blksz) - call set_printing_nb_i(blksz,gis_stochy%parent_lons,gis_stochy%parent_lats,print_i,print_nb) + call set_printing_nb_i(blksz,xlon,xlat,print_i,print_nb) do nb =1,nblks do i = 1, blksz(nb) diff --git a/stochastic_physics.F90 b/stochastic_physics.F90 index b3d4f53..3a9c39d 100644 --- a/stochastic_physics.F90 +++ b/stochastic_physics.F90 @@ -410,7 +410,7 @@ subroutine run_stochastic_physics(levs, kdt, fhour, blksz, sppt_wts, shum_wts, s end subroutine run_stochastic_physics -subroutine run_stochastic_physics_ocn(t_rp,sppt_wts) +subroutine run_stochastic_physics_ocn(sppt_wts,t_rp1,t_rp2) !use MOM_forcing_type, only : mech_forcing !use MOM_grid, only : ocean_grid_type use stochy_internal_state_mod @@ -419,32 +419,32 @@ subroutine run_stochastic_physics_ocn(t_rp,sppt_wts) use stochy_namelist_def implicit none !type(ocean_grid_type), intent(in) :: G -real, intent(inout) :: t_rp(:,:,:),sppt_wts(:,:) +real, intent(inout) :: sppt_wts(:,:),t_rp1(:,:),t_rp2(:,:) real, allocatable :: tmp_wts(:,:) if (do_epbl .OR. do_ocnsppt) then -allocate(tmp_wts(gis_stochy_ocn%nx,gis_stochy_ocn%ny)) - -!if (mod(Model%kdt,nsocnp) == 1 .or. nsocnp == 1) then -if (do_epbl) then - call get_random_pattern_scalar(rpattern_epbl1,nepbl,gis_stochy_ocn,tmp_wts) - t_rp(:,:,1)=2.0/(1+exp(-1*tmp_wts)) - call get_random_pattern_scalar(rpattern_epbl2,nepbl,gis_stochy_ocn,tmp_wts) - t_rp(:,:,2)=2.0/(1+exp(-1*tmp_wts)) -else - t_rp=1.0 -endif -if (do_ocnsppt) then - call get_random_pattern_scalar(rpattern_ocnsppt,nocnsppt,gis_stochy_ocn,tmp_wts) - sppt_wts=2.0/(1+exp(-1*tmp_wts)) -else - sppt_wts=1.0 -endif -!endif -deallocate(tmp_wts) + allocate(tmp_wts(gis_stochy_ocn%nx,gis_stochy_ocn%ny)) + if (do_epbl) then + call get_random_pattern_scalar(rpattern_epbl1,nepbl,gis_stochy_ocn,tmp_wts) + t_rp1(:,:)=2.0/(1+exp(-1*tmp_wts)) + call get_random_pattern_scalar(rpattern_epbl2,nepbl,gis_stochy_ocn,tmp_wts) + t_rp2(:,:)=2.0/(1+exp(-1*tmp_wts)) + else + t_rp1(:,:)=1.0 + t_rp2(:,:)=1.0 + endif + if (do_ocnsppt) then + call get_random_pattern_scalar(rpattern_ocnsppt,nocnsppt,gis_stochy_ocn,tmp_wts) + sppt_wts=2.0/(1+exp(-1*tmp_wts)) + else + sppt_wts=1.0 + endif + deallocate(tmp_wts) else - t_rp=1.0 - sppt_wts=1.0 + sppt_wts(:,:)=1.0 + t_rp1(:,:)=1.0 + t_rp2(:,:)=1.0 endif + print*,'in run_stochastic_physics_ocn',minval(t_rp1),maxval(t_rp1) end subroutine run_stochastic_physics_ocn subroutine finalize_stochastic_physics() From 42d90a1c28003bbabe35e0eccfa6792ec0712891 Mon Sep 17 00:00:00 2001 From: pjpegion Date: Tue, 2 Feb 2021 20:01:56 +0000 Subject: [PATCH 10/13] remove MKL support and add error checking for ocean side --- CMakeLists.txt | 11 ----------- compns_stochy.F90 | 6 +++--- four_to_grid_stochy.F | 18 ------------------ get_stochy_pattern.F90 | 13 +++---------- stochastic_physics.F90 | 23 +++++++++++++++-------- stochy_data_mod.F90 | 2 +- stochy_namelist_def.F90 | 2 +- 7 files changed, 23 insertions(+), 52 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0d3cd10..8120eff 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,16 +10,6 @@ if(32BIT) set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -fdefault-real-8") endif() endif() -# Set Intel MKL flags for preprocessor, compiler and linker (if defined) -if(MKL_DIR) - set (MKL_INC "-m64 -I$ENV{MKLROOT}/include") - set (MKL_LIB "-L$ENV{MKLROOT}/lib/intel64 -Wl,-rpath,$ENV{MKLROOT}/lib/intel64 -lmkl_intel_lp64 -lmkl_sequential -lmkl_core -lpthread -lm -ldl") - set (CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} ${MKL_INC} ${MKL_LIB}") - ADD_DEFINITIONS(-DMKL) - message (STATUS "Enable Intel MKL support") -else() - message (STATUS "Disable Intel MKL support") -endif() list(APPEND _stoch_phys_srcs kinddef.F90 @@ -65,6 +55,5 @@ target_compile_definitions(stochastic_physics PRIVATE INTERNAL_FILE_NML) target_link_libraries(stochastic_physics PUBLIC fms) if(OpenMP_Fortran_FOUND) - #target_link_libraries(stochastic_physics PUBLIC OpenMP::OpenMP_Fortran) target_link_libraries(stochastic_physics PRIVATE OpenMP::OpenMP_Fortran) endif() diff --git a/compns_stochy.F90 b/compns_stochy.F90 index 698eb09..61c7f7c 100644 --- a/compns_stochy.F90 +++ b/compns_stochy.F90 @@ -395,7 +395,7 @@ subroutine compns_stochy_ocn (deltim,iret) epbl = -999. ! stochastic physics tendency amplitude ocnsppt = -999. ! stochastic physics tendency amplitude ! logicals - do_epbl = .false. + pert_epbl = .false. do_ocnsppt = .false. new_lscale = .false. epblint = 0 @@ -417,7 +417,7 @@ subroutine compns_stochy_ocn (deltim,iret) ! PJP stochastic physics additions IF (epbl(1) > 0 ) THEN - do_epbl=.true. + pert_epbl=.true. ENDIF IF (ocnsppt(1) > 0 ) THEN do_ocnsppt=.true. @@ -469,7 +469,7 @@ subroutine compns_stochy_ocn (deltim,iret) ! if (mpp_pe()==mpp_root_pe()) then print *, 'ocean stochastic physics' - print *, ' do_epbl : ', do_epbl + print *, ' pert_epbl : ', pert_epbl print *, ' do_ocnsppt : ', do_ocnsppt endif iret = 0 diff --git a/four_to_grid_stochy.F b/four_to_grid_stochy.F index bdeda85..2b8a236 100644 --- a/four_to_grid_stochy.F +++ b/four_to_grid_stochy.F @@ -21,30 +21,13 @@ subroutine four_to_grid(syn_gr_a_1,syn_gr_a_2, integer lons_lat integer lot !________________________________________________________ -#ifdef MKL - integer*8 plan -#else real(kind=kind_dbl_prec) aux1crs(44002) real(kind=kind_dbl_prec) scale_ibm integer ibmsign integer init -#endif -#ifdef MKL - include "fftw/fftw3.f" - integer NULL -#endif !________________________________________________________ -#ifdef MKL - call dfftw_plan_many_dft_c2r( & - & plan, 1, lons_lat, lot, & - & syn_gr_a_1, NULL, 1, size(syn_gr_a_1,dim=1), & - & syn_gr_a_2, NULL, 1, size(syn_gr_a_2,dim=1), & - & FFTW_ESTIMATE) - call dfftw_execute(plan) - call dfftw_destroy_plan(plan) -#else init = 1 ibmsign = -1 scale_ibm = 1.0d0 @@ -63,7 +46,6 @@ subroutine four_to_grid(syn_gr_a_1,syn_gr_a_2, & lons_lat,lot,ibmsign,scale_ibm, & aux1crs,22000, & aux1crs(22001),20000) -#endif return end diff --git a/get_stochy_pattern.F90 b/get_stochy_pattern.F90 index 738f7c9..88833d5 100644 --- a/get_stochy_pattern.F90 +++ b/get_stochy_pattern.F90 @@ -463,14 +463,14 @@ end subroutine write_stoch_restart_atm subroutine write_stoch_restart_ocn(sfile) !\callgraph use netcdf - use stochy_namelist_def, only : do_ocnsppt,do_epbl + use stochy_namelist_def, only : do_ocnsppt,pert_epbl implicit none character(len=*) :: sfile integer :: stochlun,k,n,isize,ierr integer :: ncid,varid1a,varid1b,varid2a,varid2b,varid3a,varid3b integer :: seed_dim_id,spec_dim_id,np_dim_id include 'netcdf.inc' - if ( ( .NOT. do_ocnsppt) .AND. (.NOT. do_epbl) ) return + if ( ( .NOT. do_ocnsppt) .AND. (.NOT. pert_epbl) ) return stochlun=99 if (is_master()) then ierr=nf90_create(trim(sfile),cmode=NF90_CLOBBER,ncid=ncid) @@ -488,7 +488,7 @@ subroutine write_stoch_restart_ocn(sfile) ierr=NF90_DEF_VAR(ncid,"ocnsppt_spec",NF90_DOUBLE,(/spec_dim_id, np_dim_id/), varid1b) ierr=NF90_PUT_ATT(ncid,varid1b,"long_name","spectral cofficients SPPT") endif - if (do_epbl) then + if (pert_epbl) then ierr=NF90_DEF_VAR(ncid,"epbl1_seed",NF90_DOUBLE,(/seed_dim_id, np_dim_id/), varid2a) ierr=NF90_PUT_ATT(ncid,varid2a,"long_name","random number seed for EPBL1") ierr=NF90_DEF_VAR(ncid,"epbl1_spec",NF90_DOUBLE,(/spec_dim_id, np_dim_id/), varid2b) @@ -633,15 +633,8 @@ subroutine vrtdivspect_to_uvgrid(& do lan=1,lats_node_a lat = global_lats_a(ipt_lats_node_a-1+lan) lons_lat = lonsperlar(lat) -#ifdef MKL - CALL FOUR_TO_GRID(for_gr_a_1(1,1,lan),for_gr_a_2(1,1,lan),& - lon_dim_a,lonf,lons_lat,nlevs) - CALL FOUR_TO_GRID(for_gr_a_1(1,2,lan),for_gr_a_2(1,2,lan),& - lon_dim_a,lonf,lons_lat,nlevs) -#else CALL FOUR_TO_GRID(for_gr_a_1(1,1,lan),for_gr_a_2(1,1,lan),& lon_dim_a,lonf,lons_lat,2*nlevs) -#endif enddo uug = 0.; vvg = 0. diff --git a/stochastic_physics.F90 b/stochastic_physics.F90 index 3a9c39d..67e4033 100644 --- a/stochastic_physics.F90 +++ b/stochastic_physics.F90 @@ -225,7 +225,7 @@ subroutine init_stochastic_physics(levs, blksz, dtp, sppt_amp, input_nml_file_in end subroutine init_stochastic_physics !!!!!!!!!!!!!!!!!!!! -subroutine init_stochastic_physics_ocn(delt,geoLonT,geoLatT,nx,ny,nz,do_epbl_out,do_sppt_out, & +subroutine init_stochastic_physics_ocn(delt,geoLonT,geoLatT,nx,ny,nz,pert_epbl_in,do_sppt_in, & mpiroot, mpicomm, iret) use stochy_data_mod, only : init_stochdata_ocn,gg_lats,gg_lons,& rad2deg,INTTYP,wlon,rnlat,gis_stochy_ocn @@ -239,7 +239,7 @@ subroutine init_stochastic_physics_ocn(delt,geoLonT,geoLatT,nx,ny,nz,do_epbl_out real,intent(in) :: delt integer,intent(in) :: nx,ny,nz real,intent(in) :: geoLonT(nx,ny),geoLatT(nx,ny) -logical,intent(inout) :: do_epbl_out,do_sppt_out +logical,intent(in) :: pert_epbl_in,do_sppt_in integer,intent(in) :: mpiroot, mpicomm integer, intent(out) :: iret real(kind=kind_dbl_prec), parameter :: con_pi =4.0d0*atan(1.0d0) @@ -264,9 +264,17 @@ subroutine init_stochastic_physics_ocn(delt,geoLonT,geoLatT,nx,ny,nz,do_epbl_out INTTYP=0 ! bilinear interpolation km=nz call init_stochdata_ocn(km,delt,iret) -do_epbl_out=do_epbl -do_sppt_out=do_ocnsppt -if ( (.NOT. do_epbl) .AND. (.NOT. do_sppt_out) ) return +if (do_sppt_in.neqv.do_ocnsppt) then + write(0,'(*(a))') 'Logic error in stochastic_physics_ocn_init: incompatible', & + & ' namelist settings do_sppt and sppt' + iret = 20 + return +else if (pert_epbl_in.neqv.pert_epbl) then + write(0,'(*(a))') 'Logic error in stochastic_physics_ocn_init: incompatible', & + & ' namelist settings pert_epbl and epbl' + iret = 20 + return +end if ! get interpolation weights ! define gaussian grid lats and lons @@ -421,9 +429,9 @@ subroutine run_stochastic_physics_ocn(sppt_wts,t_rp1,t_rp2) !type(ocean_grid_type), intent(in) :: G real, intent(inout) :: sppt_wts(:,:),t_rp1(:,:),t_rp2(:,:) real, allocatable :: tmp_wts(:,:) -if (do_epbl .OR. do_ocnsppt) then +if (pert_epbl .OR. do_ocnsppt) then allocate(tmp_wts(gis_stochy_ocn%nx,gis_stochy_ocn%ny)) - if (do_epbl) then + if (pert_epbl) then call get_random_pattern_scalar(rpattern_epbl1,nepbl,gis_stochy_ocn,tmp_wts) t_rp1(:,:)=2.0/(1+exp(-1*tmp_wts)) call get_random_pattern_scalar(rpattern_epbl2,nepbl,gis_stochy_ocn,tmp_wts) @@ -444,7 +452,6 @@ subroutine run_stochastic_physics_ocn(sppt_wts,t_rp1,t_rp2) t_rp1(:,:)=1.0 t_rp2(:,:)=1.0 endif - print*,'in run_stochastic_physics_ocn',minval(t_rp1),maxval(t_rp1) end subroutine run_stochastic_physics_ocn subroutine finalize_stochastic_physics() diff --git a/stochy_data_mod.F90 b/stochy_data_mod.F90 index bcd0cd0..9247c4f 100644 --- a/stochy_data_mod.F90 +++ b/stochy_data_mod.F90 @@ -462,7 +462,7 @@ subroutine init_stochdata_ocn(nlevs,delt,iret) iret=0 call compns_stochy_ocn (delt,iret) if(is_master()) print*,'in init stochdata_ocn' - if ( (.NOT. do_epbl) .AND. (.NOT. do_ocnsppt) ) return + if ( (.NOT. pert_epbl) .AND. (.NOT. do_ocnsppt) ) return call initialize_spectral(gis_stochy_ocn, iret) if (iret/=0) return allocate(noise_e(len_trie_ls,2),noise_o(len_trio_ls,2)) diff --git a/stochy_namelist_def.F90 b/stochy_namelist_def.F90 index bf757ba..adc3f02 100644 --- a/stochy_namelist_def.F90 +++ b/stochy_namelist_def.F90 @@ -30,7 +30,7 @@ module stochy_namelist_def integer(8),dimension(5) ::iseed_sppt,iseed_shum,iseed_skeb,iseed_epbl,iseed_ocnsppt,iseed_epbl2 logical stochini,sppt_logit,new_lscale logical use_zmtnblck - logical do_shum,do_sppt,do_skeb,do_epbl,do_ocnsppt + logical do_shum,do_sppt,do_skeb,pert_epbl,do_ocnsppt real(kind=kind_dbl_prec), dimension(5) :: lndp_lscale,lndp_tau integer n_var_lndp From 55d58e3458f98b2e04fbe1ba13b1b93a0078fc7b Mon Sep 17 00:00:00 2001 From: Philip Pegion Date: Wed, 3 Mar 2021 13:58:26 -0600 Subject: [PATCH 11/13] fix Cmakelists.txt --- CMakeLists.txt | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8120eff..12d1006 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -57,3 +57,17 @@ target_link_libraries(stochastic_physics PUBLIC fms) if(OpenMP_Fortran_FOUND) target_link_libraries(stochastic_physics PRIVATE OpenMP::OpenMP_Fortran) endif() + +############################################################################### +### Install +############################################################################### +install( + TARGETS stochastic_physics + EXPORT stochastic_physics-config + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib) + +install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/mod DESTINATION ${CMAKE_INSTALL_PREFIX}) + +install(EXPORT stochastic_physics-config + DESTINATION lib/cmake) From 4de7a358ea7f5bf909c1e399f4df44d5537cfea7 Mon Sep 17 00:00:00 2001 From: pjpegion Date: Mon, 15 Mar 2021 19:07:41 +0000 Subject: [PATCH 12/13] fix CMakeLists.txt conflict --- CMakeLists.txt | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index cde976e..143d489 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -49,11 +49,7 @@ list(APPEND _stoch_phys_srcs ) add_library(stochastic_physics ${_stoch_phys_srcs}) -if(32BIT) - add_dependencies(stochastic_physics FMS::fms_r4) -else() - add_dependencies(stochastic_physics FMS::fms_r8) -endif() +add_dependencies(stochastic_physicsfms) target_compile_definitions(stochastic_physics PRIVATE INTERNAL_FILE_NML) From ca41cac4dc528975c64982c3b12a922ec35730ff Mon Sep 17 00:00:00 2001 From: pjpegion Date: Wed, 17 Mar 2021 15:22:13 +0000 Subject: [PATCH 13/13] resolve CMakeListst.txt conflict --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 143d489..12d1006 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -49,7 +49,7 @@ list(APPEND _stoch_phys_srcs ) add_library(stochastic_physics ${_stoch_phys_srcs}) -add_dependencies(stochastic_physicsfms) +add_dependencies(stochastic_physics fms) target_compile_definitions(stochastic_physics PRIVATE INTERNAL_FILE_NML)