E3SM-Project / E3SM-Project/scream
SHOC: unintentional discontinuous functions
- Dominant language
- No language data
- Stars
- 79
- Forks
- 54
- PR merge metrics
- No merged PRs in 30d
Description
In discussing EKAT issue 117, we came across two instances where divide-by-0 avoidance and clipping code lead to a discontinuous function:
Example 1:
```F90
relvar(:,:) = 1.0_r8
relvarmax = 10.0_r8
where (rcm(:ncol,:pver) /= 0.0 .and. rcm2(:ncol,:pver) /= 0.0) &
relvar(:ncol,:pver) = min(relvarmax,max(0.001_r8,rcm(:ncol,:pver)**2.0/rcm2(:ncol,:pver)))
```
For simplicity, assume these are all scalars, not arrays. Suppose rcm2 = 0 and rcm = 1. Then rcm/rcm2 = +Inf. In that case, one would think relvar should be set to relvarmax = 10. But, instead, the above code makes relvar = 1. Yet if rcm2 were just a bit above 0, say rcm2 = 1e-6, the above code would indeed make it 10. So that makes the overall function discontinuous. A similar situation occurs when rcm = 0 but rcm2 != 0. relvar is set to 1 but if rcm were just a bit above 0, it would instead be 0.001.
Example 2:
```F90
testvar=(a*sqrtqw2_1*sqrtthl2_1+(1._rtype-a)*sqrtqw2_2*sqrtthl2_2)
if (testvar .eq. 0._rtype) then
r_qwthl_1=0._rtype
else
r_qwthl_1=max(-1.0_rtype,min(1.0_rtype,(qwthlsec-a*(qw1_1-qw_first) &
*(thl1_1-thl_first)-(1._rtype-a)*(qw1_2-qw_first) &
*(thl1_2-thl_first))/testvar))
endif
```
If testvar = 0, then r_qwthl_1 = 0. But if it deviates from 0 by a tiny bit, then r_qwthl_1 = 1 or -1.
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.