-
Notifications
You must be signed in to change notification settings - Fork 270
Bug-fix in pkg/seaice EVP solver #929
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
Add CPP flag “SEAICE_EVP_REGULARIZE_DENOMUV” for the regularizations in the calculation of denomU/V
Add two regularizations in the calculation of denomU/V
|
@amc2507 thanks for this. To me this already looks good, and we tested it in independent simulations where it definitely improved the stability of the run. I would like to have a test that uses this code (or at least compiles it). These are the ocean experiments that compile EVP:
Currently only |
|
@mjlosch I did not look at code changes, but have a basic question: why is this new option implemented at pre-processor level (CPP option) and not as a run-time switch ? This would make it easier to switch on/off and to include in a verification exp. secondary test. |
|
I guess, because it's in a stupidly long loop and for performance reasons inserting more fortran if-statements may not be good? But I see that there are already two if-statements in the same loop, so maybe it's not so much of an issue? |
Add a run-time flag for regularizations in EVP
|
@mjlosch Yeah using the CPP flag might be quicker, so the CPP flag was adapted in the beginning. But a run-time flag also sounds good if it's more convenient easier to use. Here is the run-time switch version of the code. The new run-time flag is named as "SEAICEuseEVPreg", following the naming convention of other parameters. However, there has been a existing flag called "SEAICEuseEVPrev". I'm not sure whether it would cause confusion. Do you think if we should consider a more distinct name, such as "SEAICEuseEVPregularization", to better differentiate the two parameters? |
|
Thanks for the update. I agree that the parameter name |
- setting the flag changes results dramatically (only 2-3 digits of agreement remain)
in order to reduce unnecessary files on the disk
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In principle this looks good. I have one suggestion, and I also suggested a verification experiment.
pkg/seaice/seaice_evp.F
Outdated
| IF ( SEAICEevpRegDenomUV ) THEN | ||
| denomU = MAX(seaiceMassU(i,j,bi,bj),SEAICE_area_floor | ||
| & * seaice_rhoIce)*betaFacP1U | ||
| & + 0.5 _d 0*( DWATN(i,j,bi,bj) + DWATN(i-1,j,bi,bj) ) | ||
| & * COSWAT * MAX(areaW(i,j,bi,bj),SEAICE_area_floor) | ||
| denomV = MAX(seaiceMassV(i,j,bi,bj),SEAICE_area_floor | ||
| & * seaice_rhoIce)*betaFacP1V | ||
| & + 0.5 _d 0*( DWATN(i,j,bi,bj) + DWATN(i,j-1,bi,bj) ) | ||
| & * COSWAT * MAX(areaS(i,j,bi,bj),SEAICE_area_floor) | ||
| ELSE | ||
| denomU = seaiceMassU(i,j,bi,bj)*betaFacP1U |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This uses SEAICE_area_floor (default =1e-5), which is also used elsewhere. I know, I suggested to use SEAICE_area_floor rather than hard code it, but now that we have a runtime parameter anyway, would it make sense to change the runtime parameter again into a _RL-variable (default = 1.0 _d -5) and use it to actually regularise denomU/V? E.g. like this (maybe with a better name for the different usage):
| IF ( SEAICEevpRegDenomUV ) THEN | |
| denomU = MAX(seaiceMassU(i,j,bi,bj),SEAICE_area_floor | |
| & * seaice_rhoIce)*betaFacP1U | |
| & + 0.5 _d 0*( DWATN(i,j,bi,bj) + DWATN(i-1,j,bi,bj) ) | |
| & * COSWAT * MAX(areaW(i,j,bi,bj),SEAICE_area_floor) | |
| denomV = MAX(seaiceMassV(i,j,bi,bj),SEAICE_area_floor | |
| & * seaice_rhoIce)*betaFacP1V | |
| & + 0.5 _d 0*( DWATN(i,j,bi,bj) + DWATN(i,j-1,bi,bj) ) | |
| & * COSWAT * MAX(areaS(i,j,bi,bj),SEAICE_area_floor) | |
| ELSE | |
| denomU = seaiceMassU(i,j,bi,bj)*betaFacP1U | |
| IF ( SEAICEevpRegDenomUV .GT. 0. _d 0 ) THEN | |
| denomU = MAX(seaiceMassU(i,j,bi,bj),SEAICEevpRegDenomUV | |
| & * seaice_rhoIce)*betaFacP1U | |
| & + 0.5 _d 0*( DWATN(i,j,bi,bj) + DWATN(i-1,j,bi,bj) ) | |
| & * COSWAT * MAX(areaW(i,j,bi,bj),SEAICEevpRegDenomUV) | |
| denomV = MAX(seaiceMassV(i,j,bi,bj),SEAICEevpRegDenomUV | |
| & * seaice_rhoIce)*betaFacP1V | |
| & + 0.5 _d 0*( DWATN(i,j,bi,bj) + DWATN(i,j-1,bi,bj) ) | |
| & * COSWAT * MAX(areaS(i,j,bi,bj),SEAICEevpRegDenomUV) | |
| ELSE | |
| denomU = seaiceMassU(i,j,bi,bj)*betaFacP1U |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This uses
SEAICE_area_floor(default =1e-5), which is also used elsewhere. I know, I suggested to useSEAICE_area_floorrather than hard code it, but now that we have a runtime parameter anyway, would it make sense to change the runtime parameter again into a_RL-variable (default =1.0 _d -5) and use it to actually regularisedenomU/V? E.g. like this (maybe with a better name for the different usage):
Sorry for replying late, the runtime parameter has now been change to a RL variable named "SEAICE_evpAreaReg" (As it's a regularization of ice area fraction). How do you think?
|
Thanks for the updates. I'll review this later this week. In general, it would have been possible (and totally OK) to first discuss my suggestion before implementing it (i.e. it was not a "please-do-that"-suggestion, but rather a "what-do-we-think-about- this" suggestion), but now that you've already done it, it provides additional information, thanks. |
adjust description, add documentation
Also thank you for the review and the further modification! |
What changes does this PR introduce?
Add two regularizations in the calculation of denomU/V to enhance the stability of EVP solver in pkg/seaice
Add compile-time control via SEAICE_EVP_REGULARIZE_DENOMUV CPP flag (undef by default)
What is the current behaviour?
The EVP solver exhibits numerical instability when solving the momentum equation in near-ice-free conditions. This occurs due to dividing by a near-zero denomU/V.
What is the new behaviour
Add two regularizations to avoid dividing by near-zero denomU/V
Does this PR introduce a breaking change?
No