From 528e99cdf6e5a25d14d64a151f78c6815da079d3 Mon Sep 17 00:00:00 2001 From: Kyle Klenk <kyle.klenk@usask.ca> Date: Thu, 14 Apr 2022 14:41:44 -0600 Subject: [PATCH] added the ability to write data as an array --- build/source/driver/summaActors_init.f90 | 2 +- .../driver/summaActors_wOutputStruc.f90 | 9 +- build/source/engine/alloc_file_access.f90 | 4 +- build/source/engine/allocspaceActors.f90 | 6 +- build/source/engine/ffile_info.f90 | 1 - .../file_access_actor/cppwrap_fileAccess.f90 | 96 +++---- .../interface/job_actor/cppwrap_job.f90 | 2 +- build/source/netcdf/writeOutput.f90 | 235 ++++++++++-------- config/Summa_Actors_Settings.json | 2 +- 9 files changed, 178 insertions(+), 179 deletions(-) diff --git a/build/source/driver/summaActors_init.f90 b/build/source/driver/summaActors_init.f90 index b9b26e5..99b6872 100755 --- a/build/source/driver/summaActors_init.f90 +++ b/build/source/driver/summaActors_init.f90 @@ -78,7 +78,7 @@ contains USE nrtype ! variable types, etc. USE time_utils_module,only:elapsedSec ! calculate the elapsed time ! subroutines and functions: allocate space - USE allocspace4chm_module,only:allocGlobal4chm ! module to allocate space for global data structures + USE allocspace4chm_module,only:allocGlobal ! module to allocate space for global data structures USE allocspace4chm_module,only:allocLocal ! timing variables USE globalData,only:startInit,endInit ! date/time for the start and end of the initialization diff --git a/build/source/driver/summaActors_wOutputStruc.f90 b/build/source/driver/summaActors_wOutputStruc.f90 index 5802231..34f78b4 100644 --- a/build/source/driver/summaActors_wOutputStruc.f90 +++ b/build/source/driver/summaActors_wOutputStruc.f90 @@ -175,9 +175,8 @@ subroutine summaActors_writeToOutputStruc(& err=0; message='summa_manageOutputFiles/' ! identify the start of the writing call date_and_time(values=startWrite) - ! print*, "HRU WRite timestep = ", modelTimeStep - ! print*, "OutputStep = ", outputStep - ! ! initialize the statistics flags + + ! initialize the statistics flags if(modelTimeStep==1)then ! initialize time step index @@ -226,7 +225,7 @@ subroutine summaActors_writeToOutputStruc(& if(err/=0)then; message=trim(message)//trim(cmessage)//'['//trim(structInfo(iStruct)%structName)//']'; return; endif end do ! (looping through structures) - ! ! write GRU parameters + ! write GRU parameters call writeParm(indxGRU,indxHRU,integerMissing,bparStruct,bpar_meta,'bpar',err,cmessage) if(err/=0)then; message=trim(message)//trim(cmessage); return; endif @@ -266,7 +265,7 @@ subroutine summaActors_writeToOutputStruc(& call writeTime(indxGRU,indxHRU,outputStep,finalizeStats%dat, & time_meta,timeStruct%var,err,message) - ! write the model output to the NetCDF file + ! write the model output to the OutputStructure ! Passes the full metadata structure rather than the stats metadata structure because ! we have the option to write out data of types other than statistics. ! Thus, we must also pass the stats parent->child maps from childStruct. diff --git a/build/source/engine/alloc_file_access.f90 b/build/source/engine/alloc_file_access.f90 index 7a9a024..5a83a89 100644 --- a/build/source/engine/alloc_file_access.f90 +++ b/build/source/engine/alloc_file_access.f90 @@ -191,7 +191,7 @@ subroutine allocateDat_rkind_nSteps(metadata,varData,nSnow, nSoil, & nLayers = nSnow+nSoil do iStep=1, nSteps do iVar=1, nVars - select case(metadata(iVar)%vartype) + select case(metadata(iVar)%vartype) case(iLookVarType%scalarv); allocate(varData%var(iVar)%tim(iStep)%dat(1),stat=err) case(iLookVarType%wLength); allocate(varData%var(iVar)%tim(iStep)%dat(nBand),stat=err) case(iLookVarType%midSnow); allocate(varData%var(iVar)%tim(iStep)%dat(nSnow),stat=err) @@ -207,7 +207,7 @@ subroutine allocateDat_rkind_nSteps(metadata,varData,nSnow, nSoil, & case default err=40; message=trim(message)//"1. unknownVariableType[name='"//trim(metadata(iVar)%varname)//"'; type='"//trim(get_varTypeName(metadata(iVar)%vartype))//"']" return - end select + end select end do end do diff --git a/build/source/engine/allocspaceActors.f90 b/build/source/engine/allocspaceActors.f90 index fa49fb0..f10d43a 100755 --- a/build/source/engine/allocspaceActors.f90 +++ b/build/source/engine/allocspaceActors.f90 @@ -65,7 +65,7 @@ USE var_lookup,only:maxvarFreq ! allocation dimension (output freque ! privacy implicit none private -public::allocGlobal4chm +public::allocGlobal public::allocLocal public::resizeData @@ -75,7 +75,7 @@ contains ! ************************************************************************************************ ! public subroutine allocGlobal4chm: allocate space for global data structures ! ************************************************************************************************ - subroutine allocGlobal4chm(metaStruct,dataStruct,err,message) + subroutine allocGlobal(metaStruct,dataStruct,err,message) ! NOTE: safety -- ensure only used in allocGlobal4chm USE globalData,only: gru_struc ! gru-hru mapping structures implicit none @@ -113,7 +113,7 @@ contains ! end association to info in data structures end associate - end subroutine allocGlobal4chm + end subroutine allocGlobal ! ************************************************************************************************ ! public subroutine allocLocal: allocate space for local data structures diff --git a/build/source/engine/ffile_info.f90 b/build/source/engine/ffile_info.f90 index dd1dab4..1dcaccf 100755 --- a/build/source/engine/ffile_info.f90 +++ b/build/source/engine/ffile_info.f90 @@ -41,7 +41,6 @@ subroutine ffile_info(indxGRU,forcFileInfo,numFiles,err,message) USE summaActors_FileManager,only:SETTINGS_PATH ! path for metadata files USE summaActors_FileManager,only:FORCING_PATH ! path for forcing files USE summaActors_FileManager,only:FORCING_FILELIST ! list of model forcing files - USE summaActors_FileManager,only:FORCING_FREQ USE summaActors_FileManager,only:FORCING_START USE globalData,only:data_step USE globalData,only:forc_meta ! forcing metadata diff --git a/build/source/interface/file_access_actor/cppwrap_fileAccess.f90 b/build/source/interface/file_access_actor/cppwrap_fileAccess.f90 index 8173c57..0c53413 100644 --- a/build/source/interface/file_access_actor/cppwrap_fileAccess.f90 +++ b/build/source/interface/file_access_actor/cppwrap_fileAccess.f90 @@ -55,7 +55,6 @@ subroutine mDecisions_C(num_steps,err) bind(C, name='mDecisions_C') integer(c_int),intent(inout) :: num_steps integer(c_int),intent(inout) :: err ! Error Code ! local variables - integer(i4b) :: iStruct character(len=256) :: message ! error message character(LEN=256) :: cmessage ! error message of downwind routine @@ -199,12 +198,8 @@ subroutine Create_Output_File(& type(var_i),pointer :: ncid ! ncid of the output file character(LEN=256) :: startGRUString ! String Variable to convert startGRU character(LEN=256) :: numGRUString ! String Varaible to convert numGRU - character(LEN=256) :: message character(LEN=256) :: cmessage integer(i4b) :: iGRU - integer(i4b) :: iStruct - integer(i4b) :: iStep - integer(i4b) :: iFreq call c_f_pointer(handle_ncid, ncid) @@ -289,25 +284,17 @@ subroutine FileAccessActor_WriteOutput(& indxGRU, & ! index of GRU we are currently writing for indxHRU, & ! index of HRU we are currently writing for err) bind(C, name="FileAccessActor_WriteOutput") - USE globalData,only:fileout - USE summaActors_FileManager,only:OUTPUT_PATH,OUTPUT_PREFIX ! define output file - USE def_output_module,only:def_output ! module to define model output USE globalData,only:gru_struc USE var_lookup,only:maxVarFreq ! # of available output frequencies - USE writeOutput_module,only:writeParm,writeBasin,writeTime,writeData + USE writeOutput_module,only:writeBasin,writeTime,writeData USE globalData,only:structInfo USE globalData,only:outputStructure - USE globalData,only:attr_meta ! attributes metadata structure - USE globalData,only:type_meta ! veg/soil type metadata structure - USE globalData,only:mpar_meta ! local parameter metadata structure - USE globalData,only:bpar_meta ! basin parameter metadata structure USE var_lookup,only:iLookFreq ! named variables for the frequency structure USE globalData,only:bvarChild_map ! index of the child data structure: stats bvar USE netcdf_util_module,only:nc_file_close USE netcdf_util_module,only:nc_file_open USE globalData,only:outputTimeStep - USE globalData,only:finalizeStats USE netcdf implicit none @@ -320,11 +307,8 @@ subroutine FileAccessActor_WriteOutput(& ! local variables type(var_i),pointer :: ncid - character(LEN=256) :: startGRUString - character(LEN=256) :: numGRUString character(LEN=256) :: message character(LEN=256) :: cmessage - integer(i4b) :: iGRU integer(i4b) :: iStruct integer(i4b) :: iStep integer(i4b) :: iFreq @@ -345,62 +329,46 @@ subroutine FileAccessActor_WriteOutput(& ! write time information call writeTime(ncid,outputTimeStep(indxGRU)%dat(:),iStep,time_meta, & outputStructure(1)%timeStruct(1)%gru(indxGRU)%hru(indxHRU)%var,err,cmessage) - - do iStruct=1,size(structInfo) - select case(trim(structInfo(iStruct)%structName)) - case('forc') - call writeData(ncid,outputTimeStep(indxGRU)%dat(:),nHRUrun,maxLayers,indxGRU,iStep,forc_meta, & - outputStructure(1)%forcStat(1),outputStructure(1)%forcStruct(1),'forc', & - forcChild_map,outputStructure(1)%indxStruct(1),err,cmessage) - case('prog') - call writeData(ncid,outputTimeStep(indxGRU)%dat(:),nHRUrun,maxLayers,indxGRU,iStep,prog_meta, & - outputStructure(1)%progStat(1),outputStructure(1)%progStruct(1),'prog', & - progChild_map,outputStructure(1)%indxStruct(1),err,cmessage) - case('diag') - call writeData(ncid,outputTimeStep(indxGRU)%dat(:),nHRUrun,maxLayers,indxGRU,iStep,diag_meta, & - outputStructure(1)%diagStat(1),outputStructure(1)%diagStruct(1),'diag', & - diagChild_map,outputStructure(1)%indxStruct(1),err,cmessage) - case('flux') - call writeData(ncid,outputTimeStep(indxGRU)%dat(:),nHRUrun,maxLayers,indxGRU,iStep,flux_meta, & - outputStructure(1)%fluxStat(1),outputStructure(1)%fluxStruct(1),'flux', & - fluxChild_map,outputStructure(1)%indxStruct(1),err,cmessage) - case('indx') - call writeData(ncid,outputTimeStep(indxGRU)%dat(:),nHRUrun,maxLayers,indxGRU,iStep,indx_meta, & - outputStructure(1)%indxStat(1),outputStructure(1)%indxStruct(1),'indx', & - indxChild_map,outputStructure(1)%indxStruct(1),err,cmessage) - end select - if(err/=0)then; message=trim(message)//trim(cmessage)//'['//trim(structInfo(iStruct)%structName)//']'; return; endif - end do ! (looping through structures) - do iFreq = 1,maxvarFreq - if(outputStructure(1)%finalizeStats(1)%gru(indxGRU)%hru(1)%tim(iStep)%dat(iFreq)) outputTimeStep(indxGRU)%dat(iFreq) = outputTimeStep(indxGRU)%dat(iFreq) + 1 - end do ! ifreq end do ! istep + + do iStruct=1,size(structInfo) + select case(trim(structInfo(iStruct)%structName)) + case('forc') + call writeData(ncid,outputTimeStep(indxGRU)%dat(:),nHRUrun,maxLayers,indxGRU,nSteps,forc_meta, & + outputStructure(1)%forcStat(1),outputStructure(1)%forcStruct(1),'forc', & + forcChild_map,outputStructure(1)%indxStruct(1),err,cmessage) + case('prog') + call writeData(ncid,outputTimeStep(indxGRU)%dat(:),nHRUrun,maxLayers,indxGRU,nSteps,prog_meta, & + outputStructure(1)%progStat(1),outputStructure(1)%progStruct(1),'prog', & + progChild_map,outputStructure(1)%indxStruct(1),err,cmessage) + case('diag') + call writeData(ncid,outputTimeStep(indxGRU)%dat(:),nHRUrun,maxLayers,indxGRU,nSteps,diag_meta, & + outputStructure(1)%diagStat(1),outputStructure(1)%diagStruct(1),'diag', & + diagChild_map,outputStructure(1)%indxStruct(1),err,cmessage) + case('flux') + call writeData(ncid,outputTimeStep(indxGRU)%dat(:),nHRUrun,maxLayers,indxGRU,nSteps,flux_meta, & + outputStructure(1)%fluxStat(1),outputStructure(1)%fluxStruct(1),'flux', & + fluxChild_map,outputStructure(1)%indxStruct(1),err,cmessage) + case('indx') + call writeData(ncid,outputTimeStep(indxGRU)%dat(:),nHRUrun,maxLayers,indxGRU,nSteps,indx_meta, & + outputStructure(1)%indxStat(1),outputStructure(1)%indxStruct(1),'indx', & + indxChild_map,outputStructure(1)%indxStruct(1),err,cmessage) + end select + if(err/=0)then; message=trim(message)//trim(cmessage)//'['//trim(structInfo(iStruct)%structName)//']'; return; endif + end do ! (looping through structures) + ! do iFreq = 1,maxvarFreq + ! if(outputStructure(1)%finalizeStats(1)%gru(indxGRU)%hru(1)%tim(iStep)%dat(iFreq)) outputTimeStep(indxGRU)%dat(iFreq) = outputTimeStep(indxGRU)%dat(iFreq) + 1 + ! end do ! ifreq + end subroutine subroutine FileAccessActor_DeallocateStructures(handle_forcFileInfo, handle_ncid) bind(C,name="FileAccessActor_DeallocateStructures") - USE globalData,only:forcingDataStruct USE netcdf_util_module,only:nc_file_close + USE globalData,only:forcingDataStruct USE globalData,only:structInfo ! information on the data structures USE globalData,only:vecTime - USE globalData,only:statForc_meta ! child metadata for stats - USE globalData,only:statProg_meta ! child metadata for stats - USE globalData,only:statDiag_meta ! child metadata for stats - USE globalData,only:statFlux_meta ! child metadata for stats - USE globalData,only:statIndx_meta ! child metadata for stats - USE globalData,only:statBvar_meta ! child metadata for stats - USE globalData,only:averageFlux_meta ! metadata for time-step average fluxes - USE globalData,only:forcChild_map ! index of the child data structure: stats forc - USE globalData,only:progChild_map ! index of the child data structure: stats prog - USE globalData,only:diagChild_map ! index of the child data structure: stats diag - USE globalData,only:fluxChild_map ! index of the child data structure: stats flux - USE globalData,only:indxChild_map ! index of the child data structure: stats indx - USE globalData,only:bvarChild_map ! index of the child data structure: stats bvar - USE var_lookup,only:childFLUX_MEAN ! look-up values for timestep-average model fluxes - USE globalData,only:gru_struc ! gru->hru mapping structure - USE globalData,only:index_map USE globalData,only:outputTimeStep USE summaActors_deallocateOuptutStruct,only:deallocateOutputStruc - USE globalData,only:startTime,finshTime,refTime,oldTime implicit none type(c_ptr),intent(in), value :: handle_forcFileInfo type(c_ptr),intent(in), value :: handle_ncid diff --git a/build/source/interface/job_actor/cppwrap_job.f90 b/build/source/interface/job_actor/cppwrap_job.f90 index fdb62f7..8422764 100644 --- a/build/source/interface/job_actor/cppwrap_job.f90 +++ b/build/source/interface/job_actor/cppwrap_job.f90 @@ -154,7 +154,7 @@ subroutine cleanUpJobActor(err) bind(C, name='cleanUpJobActor') implicit none integer(c_int), intent(inout) :: err - + err = 0 ! Deallocate Time Varaibles deallocate(startTime%var); diff --git a/build/source/netcdf/writeOutput.f90 b/build/source/netcdf/writeOutput.f90 index 363a63c..471c892 100644 --- a/build/source/netcdf/writeOutput.f90 +++ b/build/source/netcdf/writeOutput.f90 @@ -149,7 +149,7 @@ end subroutine writeParm ! ************************************************************************************** ! public subroutine writeData: write model time-dependent data ! ************************************************************************************** -subroutine writeData(ncid,outputTimestep,nHRUrun,maxLayers,iGRU,iStep, & +subroutine writeData(ncid,outputTimestep,nHRUrun,maxLayers,iGRU,nSteps, & meta,stat,dat,structName,map,indx,err,message) USE data_types,only:var_info ! metadata type USE var_lookup,only:maxVarStat ! index into stats structure @@ -168,13 +168,13 @@ integer(i4b) ,intent(inout) :: outputTimestep(:) ! output time step integer(i4b) ,intent(in) :: nHRUrun ! number of HRUs in the run domain integer(i4b) ,intent(in) :: maxLayers ! maximum number of layers integer(i4b) ,intent(in) :: iGRU -integer(i4b) ,intent(in) :: iStep ! number of timeSteps +integer(i4b) ,intent(in) :: nSteps ! number of timeSteps type(var_info),intent(in) :: meta(:) ! meta data class(*) ,intent(in) :: stat ! stats data class(*) ,intent(in) :: dat ! timestep data character(*) ,intent(in) :: structName integer(i4b) ,intent(in) :: map(:) ! map into stats child struct -type(gru_hru_time_intVec) ,intent(in) :: indx ! index data +type(gru_hru_time_intVec) ,intent(in) :: indx ! index data integer(i4b) ,intent(out) :: err ! error code character(*) ,intent(out) :: message ! error message ! local variables @@ -189,13 +189,16 @@ integer(i4b) :: nLayers ! total number of layers ! output arrays integer(i4b) :: datLength ! length of each data vector integer(i4b) :: maxLength ! maximum length of each data vector -real(rkind) :: timeVal ! timeVal to copy -real(rkind) :: realVec(nHRUrun) ! real vector for all HRUs in the run domain -real(rkind) :: realArray(nHRUrun,maxLayers+1) ! real array for all HRUs in the run domain -integer(i4b) :: intArray(nHRUrun,maxLayers+1) ! integer array for all HRUs in the run domain +real(rkind) :: timeVec(nSteps) ! timeVal to copy +real(rkind) :: realVec(nSteps) ! real vector for all HRUs in the run domain +real(rkind) :: realArray(nSteps,maxLayers+1) ! real array for all HRUs in the run domain +integer(i4b) :: intArray(nSteps,maxLayers+1) ! integer array for all HRUs in the run domain integer(i4b) :: dataType ! type of data integer(i4b),parameter :: ixInteger=1001 ! named variable for integer integer(i4b),parameter :: ixReal=1002 ! named variable for real +integer(i4b) :: stepCounter ! counter to know how much data we have to write +integer(i4b) :: iStep +integer(i4b) :: outputTimeStepUpdateVal(maxVarFreq) ! initialize error control err=0;message="writeData/" ! loop through output frequencies @@ -203,106 +206,136 @@ do iFreq=1,maxvarFreq ! skip frequencies that are not needed if(.not.outFreq(iFreq)) cycle - ! check that we have finalized statistics for a given frequency - if(.not.outputStructure(1)%finalizeStats(1)%gru(iGRU)%hru(1)%tim(iStep)%dat(iFreq)) cycle - ! loop through model variables do iVar = 1,size(meta) - - ! handle time first - if (meta(iVar)%varName=='time')then - ! get variable index - err = nf90_inq_varid(ncid%var(iFreq),trim(meta(iVar)%varName),ncVarID) - call netcdf_err(err,message); if (err/=0) return - ! define HRUs and GRUs (only write once) - ! data bound write - if(structName == "forc")then - timeVal = outputStructure(1)%forcStruct(1)%gru(iGRU)%hru(1)%var(iVar)%tim(iStep) - err = nf90_put_var(ncid%var(iFreq),ncVarID,(/timeVal/),start=(/outputTimestep(iFreq)/),count=(/1/)) - call netcdf_err(err,message); if (err/=0)then; print*, "err"; return; endif - cycle - end if - end if ! id time - - ! define the statistics index - iStat = meta(iVar)%statIndex(iFreq) - ! check that the variable is desired - if (iStat==integerMissing.or.trim(meta(iVar)%varName)=='unknown') cycle - - do iHRU=1,gru_struc(iGRU)%hruCount - ! stats output: only scalar variable type - if(meta(iVar)%varType==iLookVarType%scalarv) then - select type(stat) - class is (gru_hru_time_doubleVec) - realVec(1) = stat%gru(iGRU)%hru(iHRU)%var(map(iVar))%tim(iStep)%dat(iFreq) - err = nf90_put_var(ncid%var(iFreq),meta(iVar)%ncVarID(iFreq),realVec,start=(/iGRU,outputTimestep(iFreq)/),count=(/1,1/)) - class default; err=20; message=trim(message)//'stats must be scalarv and of type gru_hru_doubleVec'; return - end select ! stat - - ! non-scalar variables: regular data structures - else - - ! initialize the data vectors - select type (dat) - class is (gru_hru_time_doubleVec); realArray(:,:) = realMissing; dataType=ixReal - class is (gru_hru_time_intVec); intArray(:,:) = integerMissing; dataType=ixInteger - class default; err=20; message=trim(message)//'data must not be scalarv and either of type gru_hru_doubleVec or gru_hru_intVec'; return - end select - - - ! get the model layers - nSoil = indx%gru(iGRU)%hru(iHRU)%var(iLookIndex%nSoil)%tim(iStep)%dat(1) - nSnow = indx%gru(iGRU)%hru(iHRU)%var(iLookIndex%nSnow)%tim(iStep)%dat(1) - nLayers = indx%gru(iGRU)%hru(iHRU)%var(iLookIndex%nLayers)%tim(iStep)%dat(1) - - ! get the length of each data vector - select case (meta(iVar)%varType) - case(iLookVarType%wLength); datLength = maxSpectral - case(iLookVarType%midToto); datLength = nLayers - case(iLookVarType%midSnow); datLength = nSnow - case(iLookVarType%midSoil); datLength = nSoil - case(iLookVarType%ifcToto); datLength = nLayers+1 - case(iLookVarType%ifcSnow); datLength = nSnow+1 - case(iLookVarType%ifcSoil); datLength = nSoil+1 - case default; cycle - end select ! vartype + stepCounter = 0 + + if (meta(iVar)%varName=='time' .and. structName == 'forc')then + ! get variable index + err = nf90_inq_varid(ncid%var(iFreq),trim(meta(iVar)%varName),ncVarID) + call netcdf_err(err,message); if (err/=0) return + do iStep = 1, nSteps + ! check if we want this timestep + if(.not.outputStructure(1)%finalizeStats(1)%gru(iGRU)%hru(1)%tim(iStep)%dat(iFreq)) cycle + stepCounter = stepCounter+1 + timeVec(stepCounter) = outputStructure(1)%forcStruct(1)%gru(iGRU)%hru(1)%var(iVar)%tim(iStep) + end do ! iStep + ! Write the values + err = nf90_put_var(ncid%var(iFreq),ncVarID,timeVec(1:stepCounter),start=(/outputTimestep(iFreq)/),count=(/stepCounter/)) + call netcdf_err(err,message); if (err/=0)then; print*, "err"; return; endif + ! save the value of the number of steps to update outputTimestep at the end of the function + outputTimeStepUpdateVal(iFreq) = stepCounter + cycle + end if ! id time + + ! define the statistics index + iStat = meta(iVar)%statIndex(iFreq) + ! check that the variable is desired + if (iStat==integerMissing.or.trim(meta(iVar)%varName)=='unknown') cycle - ! get the data vectors - select type (dat) - class is (gru_hru_time_doubleVec); realArray(1,1:datLength) = dat%gru(iGRU)%hru(iHRU)%var(iVar)%tim(iStep)%dat(:) - class is (gru_hru_time_intVec); intArray(1,1:datLength) = dat%gru(iGRU)%hru(iHRU)%var(iVar)%tim(iStep)%dat(:) + do iHRU=1,gru_struc(iGRU)%hruCount + ! stats output: only scalar variable type + if(meta(iVar)%varType==iLookVarType%scalarv) then + select type(stat) + class is (gru_hru_time_doubleVec) + do iStep = 1, nSteps + if(.not.outputStructure(1)%finalizeStats(1)%gru(iGRU)%hru(1)%tim(iStep)%dat(iFreq)) cycle + stepCounter = stepCounter + 1 + realVec(stepCounter) = stat%gru(iGRU)%hru(iHRU)%var(map(iVar))%tim(iStep)%dat(iFreq) + end do + err = nf90_put_var(ncid%var(iFreq),meta(iVar)%ncVarID(iFreq),realVec(1:stepCounter),start=(/iGRU,outputTimestep(iFreq)/),count=(/1,stepCounter/)) + if (outputTimeStepUpdateVal(iFreq) /= stepCounter ) then + print*, "ERROR Missmatch in Steps" + return + endif + class default; err=20; message=trim(message)//'stats must be scalarv and of type gru_hru_doubleVec'; return + end select ! stat + + ! non-scalar variables: regular data structures + else + + ! initialize the data vectors + select type (dat) + class is (gru_hru_time_doubleVec); realArray(:,:) = realMissing; dataType=ixReal + class is (gru_hru_time_intVec); intArray(:,:) = integerMissing; dataType=ixInteger class default; err=20; message=trim(message)//'data must not be scalarv and either of type gru_hru_doubleVec or gru_hru_intVec'; return - end select - - ! get the maximum length of each data vector - select case (meta(iVar)%varType) - case(iLookVarType%wLength); maxLength = maxSpectral - case(iLookVarType%midToto); maxLength = maxLayers - case(iLookVarType%midSnow); maxLength = maxLayers-nSoil - case(iLookVarType%midSoil); maxLength = nSoil - case(iLookVarType%ifcToto); maxLength = maxLayers+1 - case(iLookVarType%ifcSnow); maxLength = (maxLayers-nSoil)+1 - case(iLookVarType%ifcSoil); maxLength = nSoil+1 - case default; cycle - end select ! vartype - - ! write the data vectors - select case(dataType) - case(ixReal); err = nf90_put_var(ncid%var(iFreq),meta(iVar)%ncVarID(iFreq),realArray,start=(/iGRU,1,outputTimestep(iFreq)/),count=(/1,maxLength,1/)) - case(ixInteger); err = nf90_put_var(ncid%var(iFreq),meta(iVar)%ncVarID(iFreq),intArray,start=(/iGRU,1,outputTimestep(iFreq)/),count=(/1,maxLength,1/)) - case default; err=20; message=trim(message)//'data must be of type integer or real'; return - end select ! data type - - end if ! not scalarv - end do ! HRU Loop - - ! process error code - if (err/=0) message=trim(message)//trim(meta(iVar)%varName)//'_'//trim(get_statName(iStat)) - call netcdf_err(err,message); if (err/=0) return + end select + + + ! get the model layers + nSoil = indx%gru(iGRU)%hru(iHRU)%var(iLookIndex%nSoil)%tim(iStep)%dat(1) + nSnow = indx%gru(iGRU)%hru(iHRU)%var(iLookIndex%nSnow)%tim(iStep)%dat(1) + nLayers = indx%gru(iGRU)%hru(iHRU)%var(iLookIndex%nLayers)%tim(iStep)%dat(1) + + ! get the length of each data vector + select case (meta(iVar)%varType) + case(iLookVarType%wLength); datLength = maxSpectral + case(iLookVarType%midToto); datLength = nLayers + case(iLookVarType%midSnow); datLength = nSnow + case(iLookVarType%midSoil); datLength = nSoil + case(iLookVarType%ifcToto); datLength = nLayers+1 + case(iLookVarType%ifcSnow); datLength = nSnow+1 + case(iLookVarType%ifcSoil); datLength = nSoil+1 + case default; cycle + end select ! vartype + + ! get the data vectors + select type (dat) + class is (gru_hru_time_doubleVec) + do iStep = 1, nSteps + if(.not.outputStructure(1)%finalizeStats(1)%gru(iGRU)%hru(1)%tim(iStep)%dat(iFreq)) cycle + stepCounter = stepCounter + 1 + realArray(stepCounter,1:datLength) = dat%gru(iGRU)%hru(iHRU)%var(iVar)%tim(iStep)%dat(:) + end do + + class is (gru_hru_time_intVec) + do iStep = 1, nSteps + if(.not.outputStructure(1)%finalizeStats(1)%gru(iGRU)%hru(1)%tim(iStep)%dat(iFreq)) cycle + stepCounter = stepCounter + 1 + intArray(stepCounter,1:datLength) = dat%gru(iGRU)%hru(iHRU)%var(iVar)%tim(iStep)%dat(:) + end do + class default; err=20; message=trim(message)//'data must not be scalarv and either of type gru_hru_doubleVec or gru_hru_intVec'; return + end select + + ! get the maximum length of each data vector + select case (meta(iVar)%varType) + case(iLookVarType%wLength); maxLength = maxSpectral + case(iLookVarType%midToto); maxLength = maxLayers + case(iLookVarType%midSnow); maxLength = maxLayers-nSoil + case(iLookVarType%midSoil); maxLength = nSoil + case(iLookVarType%ifcToto); maxLength = maxLayers+1 + case(iLookVarType%ifcSnow); maxLength = (maxLayers-nSoil)+1 + case(iLookVarType%ifcSoil); maxLength = nSoil+1 + case default; cycle + end select ! vartype + + ! write the data vectors + select case(dataType) + case(ixReal) + err = nf90_put_var(ncid%var(iFreq),meta(iVar)%ncVarID(iFreq),realArray(1:stepCounter,:),start=(/iGRU,1,outputTimestep(iFreq)/),count=(/1,maxLength,stepCounter/)) + if (outputTimeStepUpdateVal(iFreq) /= stepCounter ) then + print*, "ERROR Missmatch in Steps" + return + endif + case(ixInteger) + err = nf90_put_var(ncid%var(iFreq),meta(iVar)%ncVarID(iFreq),intArray(1:stepCounter,:),start=(/iGRU,1,outputTimestep(iFreq)/),count=(/1,maxLength,stepCounter/)) + if (outputTimeStepUpdateVal(iFreq) /= stepCounter ) then + print*, "ERROR Missmatch in Steps" + return + endif + case default; err=20; message=trim(message)//'data must be of type integer or real'; return + end select ! data type + + end if ! not scalarv + end do ! HRU Loop - end do ! iVar -end do ! iFreq + ! process error code + if (err/=0) message=trim(message)//trim(meta(iVar)%varName)//'_'//trim(get_statName(iStat)) + call netcdf_err(err,message); if (err/=0) return + end do ! iVar + outputTimeStep(iFreq) = outputTimeStep(iFreq) + outputTimeStepUpdateVal(iFreq) + end do ! iFreq end subroutine writeData diff --git a/config/Summa_Actors_Settings.json b/config/Summa_Actors_Settings.json index b20a2ee..75e7a3c 100644 --- a/config/Summa_Actors_Settings.json +++ b/config/Summa_Actors_Settings.json @@ -1,7 +1,7 @@ { "SummaActor": { "OuputStrucureSize": 250, - "maxGRUPerJob": 1 + "maxGRUPerJob": 500 }, "JobActor": { -- GitLab