#2103 closed Bug (fixed)
Segfault from BDY indexing and code error from fldread data load without time interpolation
Reported by: | lovato | Owned by: | lovato |
---|---|---|---|
Priority: | normal | Milestone: | 2018 release-4.0 |
Component: | OCE | Version: | trunk |
Severity: | minor | Keywords: | BDY OPA SBC v4.0 |
Cc: |
Description (last modified by lovato)
Context
1) BDY indexing randomly generate a segmentation fault
2) BDY data reading with fldread produces an error because code attempt to read data record beyond the end of file timeline
Analysis
1)
In the re-calculation of fmask without the land boundary condition (shlat) included in src/OCE/BDY/bdyini.F90 the temporary array zfmask is not set to zero is missing.
Thus, with certain domain decompositions and with land exclusion, the following loop may not fill the outer bound of the domain.
(in addition if compiled with check-bounds option the indexes generated in this piece of code point outside array boundaries)
! For the flagu/flagv calculation below we require a version of fmask without ! the land boundary condition (shlat) included: DO ij = 2, jpjm1 DO ii = 2, jpim1 zfmask(ii,ij) = tmask(ii,ij ,1) * tmask(ii+1,ij ,1) & & * tmask(ii,ij+1,1) * tmask(ii+1,ij+1,1) END DO END DO ! Lateral boundary conditions CALL lbc_lnk( zfmask, 'F', 1. )
2)
The revision made to the code after 2016 merge party bounded the update of file names in fldread only for the case of time-interpolation.
So when time interpolation is disabled the code block because it tries to read and after record that do not exist in the netcdf file
Fix
1)
Simply add the zeroing of zfmask before the loop, as in the example below
! For the flagu/flagv calculation below we require a version of fmask without ! the land boundary condition (shlat) included: zfmask(:,:) = 0 DO ij = 2, jpjm1 DO ii = 2, jpim1 zfmask(ii,ij) = tmask(ii,ij ,1) * tmask(ii+1,ij ,1) & & * tmask(ii,ij+1,1) * tmask(ii+1,ij+1,1) END DO END DO ! Lateral boundary conditions CALL lbc_lnk( zfmask, 'F', 1. )
2)
Always check if the current file has reached the last record, independently from the use of time interpolation and update the name of the next file to be read.
Move the endif instance of time interpolation check in fldread as in the following
CALL fld_clopn( sd(jf) ) ! Do we need to open a new year/month/week/day file? IF( sd(jf)%ln_tint ) THEN ! if kn_fsbc*rdt is larger than nfreqh (which is kind of odd), ! it is possible that the before value is no more the good one... we have to re-read it ! if before record is not just just before the after record... IF( .NOT. ll_firstcall .AND. MOD( sd(jf)%nrec_a(1), sd(jf)%nreclast ) /= 1 & & .AND. sd(jf)%nrec_b(1) /= sd(jf)%nrec_a(1) - 1 ) THEN sd(jf)%nrec_a(1) = sd(jf)%nrec_a(1) - 1 ! move back to before record CALL fld_get( sd(jf), imap ) ! read after data sd(jf)%fdta(:,:,:,1) = sd(jf)%fdta(:,:,:,2) ! re-swap before record field sd(jf)%nrec_b(1) = sd(jf)%nrec_a(1) ! update before record informations sd(jf)%nrec_b(2) = sd(jf)%nrec_a(2) - NINT( sd(jf)%nfreqh * 3600 ) ! assume freq to be in hours in this case sd(jf)%rotn(1) = sd(jf)%rotn(2) ! update before rotate informations sd(jf)%nrec_a(1) = sd(jf)%nrec_a(1) + 1 ! move back to after record ENDIF ENDIF ! temporal interpolation? ! do we have to change the year/month/week/day of the forcing field?? ! if we do time interpolation we will need to open next year/month/week/day file before the end of the current ! one. If so, we are still before the end of the year/month/week/day when calling fld_rec so sd(jf)%nrec_a(1) ! will be larger than the record number that should be read for current year/month/week/day ! do we need next file data? ! This applies to both cases with or without time interpolation IF( sd(jf)%nrec_a(1) > sd(jf)%nreclast ) THEN sd(jf)%nrec_a(1) = sd(jf)%nrec_a(1) - sd(jf)%nreclast ! IF( .NOT. ( sd(jf)%ln_clim .AND. sd(jf)%cltype == 'yearly' ) ) THEN ! close/open the current/new file llnxtmth = sd(jf)%cltype == 'monthly' .OR. nday == nmonth_len(nmonth) ! open next month file? llnxtyr = sd(jf)%cltype == 'yearly' .OR. (nmonth == 12 .AND. llnxtmth) ! open next year file? ! if the run finishes at the end of the current year/month/week/day, we will allow next ! year/month/week/day file to be not present. If the run continue further than the current ! year/month/week/day, next year/month/week/day file must exist isecend = nsec_year + nsec1jan000 + (nitend - kt) * NINT(rdt) ! second at the end of the run llstop = isecend > sd(jf)%nrec_a(2) ! read more than 1 record of next year ! we suppose that the date of next file is next day (should be ok even for weekly files...) CALL fld_clopn( sd(jf), nyear + COUNT((/llnxtyr /)) , & & nmonth + COUNT((/llnxtmth/)) - 12 * COUNT((/llnxtyr /)), & & nday + 1 - nmonth_len(nmonth) * COUNT((/llnxtmth/)), llstop ) IF( sd(jf)%num <= 0 .AND. .NOT. llstop ) THEN ! next year file does not exist CALL ctl_warn('next year/month/week/day file: '//TRIM(sd(jf)%clname)// & & ' not present -> back to current year/month/day') CALL fld_clopn( sd(jf) ) ! back to the current year/month/day sd(jf)%nrec_a(1) = sd(jf)%nreclast ! force to read the last record in the current year file ENDIF ENDIF ENDIF ! open need next file? ! read after data IF( PRESENT(jpk_bdy) ) THEN
Commit History (1)
Changeset | Author | Time | ChangeLog |
---|---|---|---|
9807 | lovato | 2018-06-16T00:51:16+02:00 | trunk: apply bugfix to BDY indexing and fldread file advancement - #2103 |
Change History (4)
comment:1 Changed 5 years ago by nicolasmartin
- Description modified (diff)
comment:2 Changed 5 years ago by lovato
comment:3 Changed 5 years ago by lovato
- Description modified (diff)
- Resolution set to fixed
- Status changed from new to closed
The proposed solution was implemented at trunk revision r9807
comment:4 Changed 20 months ago by nemo
- Keywords OPA v4.0 added
In 9807: