-
Notifications
You must be signed in to change notification settings - Fork 7
Add wind forcing and bottom drag tendency terms #219
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
Changes from 17 commits
768efd1
2c2e681
e388683
2032459
7e59f74
2bd5ae0
3e5bc43
b20d41b
7903896
b467a8f
c8f0607
28b1a0a
da040da
d75b2e6
e0ba780
b502913
602c6b1
fa7e3e5
b4ed972
3b549a0
677d981
1d3c340
3b2cced
e98791a
2bd6c87
f5599f3
97139ab
45f937c
dfbd2c6
388b3cc
4c1caf6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -29,3 +29,6 @@ The following auxiliary variables are currently available: | |
| | VelDel2RelVortVertex | curl of laplacian of horizontal velocity on cells | ||
| | HTracersEdge | thickness-weighted tracers used for fluxes through edges. May be centered, upwinded or a combination of the two | ||
| | Del2TracersCell | laplacian of tracers on cells | ||
| | ZonalStressEdge | zonal component of wind stress on cells | ||
| | MeridStressEdge | meridional component of wind stress on cells | ||
| | NormalStressEdge | normal component of wind stress on edge | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. generic comment - do we want this in AuxState? Would it make sense to have a 'forcing module' where this lives?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These are grouped in the |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -203,6 +203,29 @@ int Tendencies::readTendConfig(Config *TendConfig ///< [in] Tendencies subconfig | |
| return DivFactorErr; | ||
| } | ||
|
|
||
| I4 WindForcingErr = | ||
| TendConfig->get("WindForcingTendencyEnable", this->WindForcing.Enabled); | ||
| if (WindForcingErr != 0) { | ||
| LOG_CRITICAL("Tendencies: WindForcingTendencyEnable not found in " | ||
| "TendConfig"); | ||
| return WindForcingErr; | ||
| } | ||
|
|
||
| I4 BottomDragErr = | ||
| TendConfig->get("BottomDragTendencyEnable", this->BottomDrag.Enabled); | ||
| if (BottomDragErr != 0) { | ||
| LOG_CRITICAL("Tendencies: BottomDragTendencyEnable not found in " | ||
| "TendConfig"); | ||
| return BottomDragErr; | ||
| } | ||
|
|
||
| I4 BottomDragCoeffErr = | ||
| TendConfig->get("BottomDragCoeff", this->BottomDrag.Coeff); | ||
| if (BottomDragCoeffErr != 0 && this->BottomDrag.Enabled) { | ||
| LOG_CRITICAL("Tendencies: BottomDragCoeff not found in TendConfig"); | ||
| return BottomDragCoeffErr; | ||
| } | ||
|
|
||
| I4 TrHAdvErr = TendConfig->get("TracerHorzAdvTendencyEnable", | ||
| this->TracerHorzAdv.Enabled); | ||
| if (TrHAdvErr != 0) { | ||
|
|
@@ -258,7 +281,8 @@ Tendencies::Tendencies(const std::string &Name, ///< [in] Name for tendencies | |
| CustomTendencyType InCustomVelocityTend) | ||
| : ThicknessFluxDiv(Mesh), PotientialVortHAdv(Mesh), KEGrad(Mesh), | ||
| SSHGrad(Mesh), VelocityDiffusion(Mesh), VelocityHyperDiff(Mesh), | ||
| TracerHorzAdv(Mesh), TracerDiffusion(Mesh), TracerHyperDiff(Mesh), | ||
| WindForcing(Mesh), BottomDrag(Mesh), TracerHorzAdv(Mesh), | ||
| TracerDiffusion(Mesh), TracerHyperDiff(Mesh), | ||
| CustomThicknessTend(InCustomThicknessTend), | ||
| CustomVelocityTend(InCustomVelocityTend) { | ||
|
|
||
|
|
@@ -338,9 +362,13 @@ void Tendencies::computeVelocityTendenciesOnly( | |
| OMEGA_SCOPE(LocSSHGrad, SSHGrad); | ||
| OMEGA_SCOPE(LocVelocityDiffusion, VelocityDiffusion); | ||
| OMEGA_SCOPE(LocVelocityHyperDiff, VelocityHyperDiff); | ||
| OMEGA_SCOPE(LocWindForcing, WindForcing); | ||
| OMEGA_SCOPE(LocBottomDrag, BottomDrag); | ||
|
|
||
| deepCopy(LocNormalVelocityTend, 0); | ||
|
|
||
| const Array2DReal &NormalVelEdge = State->NormalVelocity[VelTimeLevel]; | ||
|
|
||
| // Compute potential vorticity horizontal advection | ||
| const Array2DReal &FluxLayerThickEdge = | ||
| AuxState->LayerThicknessAux.FluxLayerThickEdge; | ||
|
|
@@ -398,6 +426,27 @@ void Tendencies::computeVelocityTendenciesOnly( | |
| }); | ||
| } | ||
|
|
||
| // Compute wind forcing | ||
| const auto &NormalStressEdge = AuxState->WindForcingAux.NormalStressEdge; | ||
| const auto &MeanLayerThickEdge = | ||
| AuxState->LayerThicknessAux.MeanLayerThickEdge; | ||
| if (LocWindForcing.Enabled) { | ||
| parallelFor( | ||
| {NEdgesAll, NChunks}, KOKKOS_LAMBDA(int IEdge, int KChunk) { | ||
| LocWindForcing(LocNormalVelocityTend, IEdge, KChunk, | ||
| NormalStressEdge, MeanLayerThickEdge); | ||
| }); | ||
| } | ||
|
|
||
| // Compute bottom drag | ||
| if (LocBottomDrag.Enabled) { | ||
| parallelFor( | ||
| {NEdgesAll, NChunks}, KOKKOS_LAMBDA(int IEdge, int KChunk) { | ||
|
||
| LocBottomDrag(LocNormalVelocityTend, IEdge, KChunk, NormalVelEdge, | ||
| KECell, MeanLayerThickEdge); | ||
| }); | ||
| } | ||
|
|
||
| if (CustomVelocityTend) { | ||
| CustomVelocityTend(LocNormalVelocityTend, State, AuxState, ThickTimeLevel, | ||
| VelTimeLevel, Time); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -43,6 +43,13 @@ | |
| DcEdge(Mesh->DcEdge), DvEdge(Mesh->DvEdge), | ||
| MeshScalingDel4(Mesh->MeshScalingDel4), EdgeMask(Mesh->EdgeMask) {} | ||
|
|
||
| WindForcingOnEdge::WindForcingOnEdge(const HorzMesh *Mesh) | ||
| : SaltWaterDensity(1.026e3) {} | ||
|
||
|
|
||
| BottomDragOnEdge::BottomDragOnEdge(const HorzMesh *Mesh) | ||
| : Coeff(0), CellsOnEdge(Mesh->CellsOnEdge), NVertLevels(Mesh->NVertLevels) { | ||
mark-petersen marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| TracerHorzAdvOnCell::TracerHorzAdvOnCell(const HorzMesh *Mesh) | ||
| : NEdgesOnCell(Mesh->NEdgesOnCell), EdgesOnCell(Mesh->EdgesOnCell), | ||
| CellsOnEdge(Mesh->CellsOnEdge), EdgeSignOnCell(Mesh->EdgeSignOnCell), | ||
|
|
||
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.
I think these should be
ZonalStressCellandMeridStressCell, no? Later in the code these are defined on cells.Also, I think having wind in the name would be good to differentiate from other potential sources of stress?
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.
I think that defining it on cells makes sense, given that eventually these fields are coupled on cell centers.
I think in one of our recent meetings we decided to keep the stress generic. It could be helpful to specify that it is at the top or surface though. Stress from both sea ice and wind currently aren't separable in MPAS-Ocean when they are passed from the coupler. We could decide to change this, of course.
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.
@cbegeman I don't understand your second comment. It's not clear to me what external forced bottom stresses there may be (perhaps wave radiation stress is one)
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.
I didn't mean to imply that we would have externally forced bottom stresses. Just that I think we're using these variables to refer to only stresses at the surface but the variable name quite generic.
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.
Oh, I see. Thanks for the clarification. appending
Surfacedoes make sense for clarity. And I fully agree, these should be on cells, not edges.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.
Yes, thanks for catching this.
To clarify how I came up with the names, in the code these variables are part of
WindForcingAuxVarsclass. For me this means that the full name ofZonalStressCellis reallyWindForcingAuxVars.ZonalStressCell, and that makes it clear that this variable refers only to the wind stress (at the surface).However, I see how this can be confusing, especially since the user docs do not mention the groupings of auxiliary variables. Moreover, there are no class prefixes in stream field names, so currently the name of
ZonalStressCellused for I/O isWindStressZonal.