E3SM-Project / E3SM-Project/scream

SHOC: unintentional discontinuous functions

Open
#1,089 7 comments 0 reactions 1 assignee Claimed by @bogensch View on GitHub
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.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.