diff --git a/CHANGELOG.md b/CHANGELOG.md index fc284367bb8b..d2ecd50e91c5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- Now History creates a copy of the export state(s) so that we can remove the original un-split field to avoid duplicates +- Changed the naming convention for the split name(s) - A small performance improvement. cycle => exit in MAPL_Generic.F90 - Made history global metadata configurable. This can be done in two ways 1. Globally for all collections by setting `COMMENT:`, `CONTACT:`, `CONVENTION:`, `INSTITUTION:`, `REFERENCES:`, and `SOURCE:` at the top of `HISTORY.rc` like `EXPDSC:` diff --git a/base/Base/Base_Base_implementation.F90 b/base/Base/Base_Base_implementation.F90 index c06be8629dd7..4dd6d5037d86 100644 --- a/base/Base/Base_Base_implementation.F90 +++ b/base/Base/Base_Base_implementation.F90 @@ -1,3 +1,4 @@ +#include "MAPL_Exceptions.h" #include "MAPL_ErrLog.h" #include "unused_dummy.H" @@ -3657,50 +3658,54 @@ subroutine genAlias(name, n, splitNameArray, aliasName, rc) integer :: n character(len=*) :: name character(len=*), allocatable :: splitNameArray(:) - character(len=*), optional :: aliasName + character(len=*) :: aliasName integer, optional :: rc integer :: i, k integer :: k1, k2, kk, count + integer :: nn + character(len=ESMF_MAXSTR), allocatable :: tmp(:) + allocate(splitNameArray(n), stat=status) _VERIFY(status) - if (present(aliasName)) then - ! count the separators (";") in aliasName - ! if they match n (i.e. the count = n-1) use each - ! else if count is 0, append 00i to aliasName - ! else return an error - - ! parse the aliasName - count = 0 - k1 = 1 - kk = len_trim(aliasName) - do k=1,kk - if (aliasName(k:k) == ";") then - count = count+1 - k2=k-1 - _ASSERT(count < n, 'Too many split separators') - splitNameArray(count) = aliasName(k1:k2) - k1 = k+1 - end if - end do - if (count == 0) then - do i=1,n - write(splitNameArray(i),'(A,I3.3)') trim(aliasName), i - end do - else if(count == n-1) then - k2 = kk + + ! parse the aliasName + ! count the separators (";") in aliasName + count = 0 + k1 = 1 + kk = len_trim(aliasName) + do k=1,kk + if (aliasName(k:k) == ";") then count = count+1 - splitNameArray(count) = aliasName(k1:k2) - else - _ASSERT(.false.,'Inconsistent number of split separators') end if + end do + nn = count+1 + allocate(tmp(nn), __STAT__) - else - do i=1,n - write(splitNameArray(i),'(A,I3.3)') trim(name), i - end do - end if + count = 0 + do k=1,kk + if (aliasName(k:k) == ";") then + count = count+1 + k2=k-1 + if (count > n) exit ! use atmost n of the aliases + tmp(count) = aliasName(k1:k2) + k1 = k+1 + end if + end do + count = count+1 + k2 = kk + tmp(count) = aliasName(k1:k2) + do i=1,min(nn,n) + splitNameArray(i) = tmp(i) + end do + deallocate(tmp) + ! if the user did no supply enough separated alias field names, + ! append 00i to the original field name + do i=nn+1,n + write(splitNameArray(i),'(A,I3.3)') trim(name), i + end do + _RETURN(ESMF_SUCCESS) end subroutine GenAlias end subroutine MAPL_FieldSplit diff --git a/gridcomps/History/MAPL_HistoryGridComp.F90 b/gridcomps/History/MAPL_HistoryGridComp.F90 index ba766119c54e..a468c68c71ef 100644 --- a/gridcomps/History/MAPL_HistoryGridComp.F90 +++ b/gridcomps/History/MAPL_HistoryGridComp.F90 @@ -275,6 +275,7 @@ subroutine Initialize ( gc, import, dumexport, clock, rc ) type(ESMF_State), pointer :: export (:) => null() type(ESMF_State), pointer :: exptmp (:) + type(ESMF_State) :: expsrc, expdst type(ESMF_Time) :: StartTime type(ESMF_Time) :: CurrTime type(ESMF_Time) :: RingTime @@ -424,6 +425,7 @@ subroutine Initialize ( gc, import, dumexport, clock, rc ) type(ESMF_Field), allocatable :: fldList(:) character(len=ESMF_MAXSTR), allocatable :: regexList(:) type(StringStringMap) :: global_attributes + character(len=ESMF_MAXSTR) :: name ! Begin !------ @@ -1427,7 +1429,7 @@ subroutine Initialize ( gc, import, dumexport, clock, rc ) ! Get Output Export States ! ------------------------ - allocate ( exptmp (size0), stat=status ) + allocate ( exptmp(size0), stat=status ) _VERIFY(STATUS) exptmp(1) = import allocate ( export(nstatelist), stat=status ) @@ -1625,6 +1627,17 @@ subroutine Initialize ( gc, import, dumexport, clock, rc ) _ASSERT(.not. errorFound,'needs informative message') deallocate ( exptmp ) +! Create a copy of the original (i.e. gridded component's export) to +! be able to modify if safely (for example by splitField) +! ------------------------------------------------------------------ + do n=1,nstatelist + expsrc = export(n) + call ESMF_StateGet(expsrc, name=name, __RC__) + expdst = ESMF_StateCreate(name=name, __RC__) + call CopyStateItems(src=expsrc, dst=expdst, __RC__) + export(n) = expdst + end do + ! Associate Output Names with EXPORT State Index ! ---------------------------------------------- list(:)%subVm = .false. @@ -2927,6 +2940,10 @@ subroutine splitUngriddedFields(rc) expState = export(list(n)%expSTATE(k)) +! remove the original unsplit field from the export state copy + call ESMF_FieldGet(fldList(k), name=fldName, __RC__) + call ESMF_StateRemove(expState, itemName=fldName, __RC__) + do i=1,size(splitFields) call ESMF_FieldGet(splitFields(i), name=fldName, & rc=status) @@ -5370,5 +5387,42 @@ subroutine shavebits( state, list, rc) end subroutine + subroutine CopyStateItems(src, dst, rc) + type(ESMF_State), intent(in) :: src + type(ESMF_State), intent(inout) :: dst + integer, optional, intent(out) :: rc + +! local vars + type (ESMF_StateItem_Flag), pointer :: itemTypes(:) + character(len=ESMF_MAXSTR ), pointer :: itemNames(:) + integer :: status + integer :: n, itemCount + type(ESMF_Field) :: field(1) + type(ESMF_FieldBundle) :: bundle(1) + + call ESMF_StateGet(src, itemCount=itemCount, __RC__) + + allocate(itemnames(itemcount), __STAT__) + allocate(itemtypes(itemcount), __STAT__) + + call ESMF_StateGet(src, itemNameList=itemNames, & + itemTypeList=itemTypes, __RC__) + + do n=1,itemCount + if(itemTypes(n)==ESMF_STATEITEM_FIELD) then + call ESMF_StateGet(src, itemNames(n), field(1), __RC__) + call ESMF_StateAdd(dst, field, __RC__) + else if(itemTypes(n)==ESMF_STATEITEM_FieldBundle) then + call ESMF_StateGet(src, itemNames(n), bundle(1), __RC__) + call ESMF_StateAdd(dst, bundle, __RC__) + end if + end do + + deallocate(itemTypes) + deallocate(itemNames) + + _RETURN(ESMF_SUCCESS) + end subroutine CopyStateItems + end module MAPL_HistoryGridCompMod