Fix uninitialized min_rand variable in Thompson MP when using SPP#892
Conversation
gthompsnWRF
left a comment
There was a problem hiding this comment.
Kinda important to catch the minimum value of rand_pert. Approved.
SamuelTrahanNOAA
left a comment
There was a problem hiding this comment.
This PR will not have consistent results between thread counts due to this line in module_mp_thompson.F90
abs_min_rand = ABS(MINVAL(rand_pert(:,1)))
It doesn't solve the problem correctly though, since it is only getting the minimum of the current block, not the whole domain. The results will vary depending on threading and blocking settings. |
|
Excellent catch, Sam.
… On Apr 4, 2022, at 2:12 PM, Samuel Trahan (NOAA contractor) ***@***.***> wrote:
@grantfirl <https://github.com/grantfirl>
Kinda important to catch the minimum value of rand_pert. Approved.
It doesn't solve the problem correctly though, since it is only getting the minimum of the current block, not the whole domain. The results will vary depending on threading and blocking settings.
—
Reply to this email directly, view it on GitHub <#892 (comment)>, or unsubscribe <https://github.com/notifications/unsubscribe-auth/AB5C2RIEVMQY57BJ3JBL2S3VDNEL3ANCNFSM5SLIWTRQ>.
You are receiving this because your review was requested.
|
|
The random fields are generally normalized somehow, right? Perhaps |
I was going to ask about thread safe, but I just don't know how CCPP code is structured as well as I do WRF where I had implemented this in a thread-safe way. Yes, actually I believe the min value should always be set to -1.0, so in this case, I think it is actually best to set abs_min_rand as a universal constant of 1.0. I realize now how this could be a flaw in my original design because instead of always asking for the lowest possible negative number to add to the original number, I was doing the abs of lowest number at the time, so in the case of slow spin-up, the min_rand number is hardly ever as low as -1.0. So I now believe this can be changed to a simple constant of 1.0 (which would be |
|
All blocks are consolidated into a single 1D array in the stochastic physics wrapper (stochastic_physics_wrapper.F90) before |
|
It will still depend on MPI decomposition (layout_x and layout_y) since different ranks will have different parts of the domain. |
The random fields aren't normalized, but are capped based on namelist settings (magnitude*cutoff), so they will vary from run to run. |
OK, that makes sense now. It looks like only a constant will work in this case. |
|
The only way I see of doing this is an MPI_Allreduce at the model level, and pass the result down to CCPP. It is likely the stochastic physics component already does that calculation, but it may not send the minimum to the model. |
|
Please waste no more energy on this and consider setting this as constant since I think it is the right thing to do. If Jeff has other thoughts, please speak out. |
|
You can do an MPI exchange in the time_vary group (timestep_init phase in CCPP lingo).
… On Apr 4, 2022, at 2:37 PM, Samuel Trahan (NOAA contractor) ***@***.***> wrote:
The only way I see of doing this is an MPI_Allreduce at the model level, and pass the result down to CCPP. It is likely the stochastic physics component already does that calculation, but it may not send the minimum to the model.
—
Reply to this email directly, view it on GitHub <#892 (comment)>, or unsubscribe <https://github.com/notifications/unsubscribe-auth/AB5C2RO3JSIFFU4O4WTFRP3VDNHIDANCNFSM5SLIWTRQ>.
You are receiving this because your review was requested.
|
|
Are the following variables (rand1 and rand2) non-reproducable as well? It seems like if rand_pert(:,1) won't work, rand_pert(i,1) won't work either? |
No. Those are in an i,j loop, so rand1 is a temporary variable containing data at that i,j point. (Likewise with rand2 and rand3). |
It was my understanding that it should not be. This is probably where Judith Berner comes in. |
|
I will see if I can pull in the magnitude*cutoff value to use instead. |
|
@gthompsnWRF If you want to have a meeting, please contact your desired attendees by email, and we'll arrange something. I'd rather not discuss our schedules and locations on github. Joe Olson should be there too, since his PR is the one that sparked all this. |
|
Jeff: yes, this is the best possible solution! I forgot that the random field is not intended to be [-1,1]. This solution is the proper one for certain. |
Thanks, Greg! It doesn't look like it will be too difficult to bring these namelist entries into CCPP (two of the three are already available), so I should have it ready in a day or so. Thanks to @grantfirl for his help here. |
| INTEGER, INTENT(IN) :: rand_perturb_on, kme_stoch | ||
| REAL, DIMENSION(:,:), INTENT(IN) :: & | ||
| rand_pert | ||
| rand_pert,spp_prt_list,spp_stddev_cutoff,n_var_spp, & |
There was a problem hiding this comment.
I believe rand_pert is a 2D var, but how are these namelist variables dimensioned as (:,:) instead of 1-D? Shouldn't these additions be 1-D or at least separated from the (i,j) assumption of the rand_pert variable? Also, I do not find prt_list as intuitive. My first guess of this variable name would be something like "print_list" so is there anything more intuitive?
There was a problem hiding this comment.
@gthompsnWRF, none of this code is really ready to be reviewed yet, as I was just pushing things to my fork to then clone ufs-weather-model and run the stochastic physics RT. I probably should have kept all changes local until I got done with this work. Sorry for the confusion. That said, thanks for finding an error in the declarations here, those fields are 1D, and shouldn't go in this 2D line.
| REAL:: dt, pptrain, pptsnow, pptgraul, pptice | ||
| REAL:: qc_max, qr_max, qs_max, qi_max, qg_max, ni_max, nr_max | ||
| REAL:: rand1, rand2, rand3, min_rand | ||
| REAL:: rand1, rand2, rand3, spp_mp_mag_times_cutoff |
There was a problem hiding this comment.
Couldn't this be made a simpler (and shorter) and intuitive name like: rand_pert_max?
There was a problem hiding this comment.
Yes, I was trying to keep some provenance for the source of this field, but it can be found in the routine itself (spp_prt_list(k)*spp_stddev_cutoff(k)), and rand_pert_max is a better idea.
| do k =1,n_var_spp | ||
| select case (spp_var_list(k)) | ||
| case('mp') | ||
| spp_mp_mag_times_cutoff = spp_prt_list(k)*spp_stddev_cutoff(k) |
There was a problem hiding this comment.
There is no else clause here, so is it safe to have this variable without being initialized somewhere? Can it safely be set to zero (or perhaps did I miss it getting a default value)?
There was a problem hiding this comment.
Yes, I still need to initialize the variable. I think setting it to zero will be fine (it's not used in that case anyway).
| enddo | ||
| endif | ||
|
|
||
| print*, ' spp_mp_mag_times_cutoff is = ', spp_mp_mag_times_cutoff |
There was a problem hiding this comment.
A print statement like this should be reserved for debugging only not in production code.
There was a problem hiding this comment.
Yes, this was just for my testing purposes with this intermediate code. I will remove it once I confirm things are getting passed into the routine and applied correctly.
|
@gthompsnWRF, @SamuelTrahanNOAA, please see the latest changes to this PR, which I believe will resolve your concerns. The code is now working (ran the RT test; baselines change) and calculates the maximum random perturbation value based on namelist settings brought in from stochastic_physics. |
SamuelTrahanNOAA
left a comment
There was a problem hiding this comment.
Three dimension names are incorrect in the meta file. If you correct this, and update submodules, it compiles and runs on hera.intel. I also ran a -DDEBUG=ON test, and it ran as far as expected. (It failed in libpost due to enabling a post output variable it shouldn't.)
|
Thanks, @SamuelTrahanNOAA. I missed this file in my latest commit. It's now fixed. |
| has_reqc=has_reqc, has_reqi=has_reqi, has_reqs=has_reqs, & | ||
| rand_perturb_on=spp_mp_opt, kme_stoch=kme_stoch, & | ||
| rand_pert=spp_wts_mp, & | ||
| rand_pert=spp_wts_mp, spp_var_list=spp_var_list, & |
There was a problem hiding this comment.
It is sorta stupid request, but couldn't the new added arguments be listed in the same order in this block as in the block 40 lines lower? Just think it makes it easier. The order of arguments differs a little.
There was a problem hiding this comment.
Sure, I can make that change.
| dimensions = () | ||
| type = integer | ||
| intent = in | ||
| [spp_prt_list] |
There was a problem hiding this comment.
Clearly I am still being thick, but I don't see how the name "prt_list" gives me any clue of a magnitude of spp perturbation.
There was a problem hiding this comment.
Yes, it could be better named. We followed the same naming convention for SPP as what was already in place for the land perturbation scheme in stochastic_physics. For that scheme, "lndp_prt_list" is used for the perturbation array. At some point, changing to something like *_mag_list would be more descriptive.
There was a problem hiding this comment.
You could use a different name in mp_thompson than GFS_Typedefs so the variable will make sense in both contexts.
There was a problem hiding this comment.
Since spp_prt_list is used across multiple physics suites and UFS submodules, I'd prefer keeping the name the same everywhere. We can certainly address this in a future PR, though.
Description
This suite of PRs fixes the uninitialized min_rand variable in Thompson MP when using SPP and is explained in detail in the ufs-weather-model PR here.
Issue(s) addressed
Fixes NCAR/ccpp-physics Issue #891.
Testing
The RT suite on Hera passed for all normal and debug tests, except for the regional_spp_sppt_shum_skeb RT test, which will now have a new baseline result.
@jwolff-ncar, @willmayfield, @bluefinweiwei, @michelleharrold, @judithberner, @gsketefian