ClimaCore.jl icon indicating copy to clipboard operation
ClimaCore.jl copied to clipboard

Manipulating `AxisTensor`s

Open jb-mackay opened this issue 2 years ago • 5 comments

I'm unsure of the support or best way to manipulate AxisTensor objects like U V and WVectors, such as taking a norm or inner product. One way is of course to manipulate the array with parent, but then I'd have to repackage the result in a Field.

Motivation: In #325 we add the ability to specify boundary conditions as fields, so that we can have a location-varying flux applied at the boundaries. I want to easily be able to compute the wind stress at every point on a boundary field and have this represented as a scalar valued Field.

A current workaround can be seen in ClimaAtmos or ClimaCoupler in which single elements of vectors are used to calculate this stress which is then uniform on the boundary.

@akshaysridhar please chime in, I think we have different understandings of the issue here.

jb-mackay avatar Mar 17 '22 01:03 jb-mackay

Options:

  1. We define a function normal_field(space, boundaryname) which would return a vector field on the boundary space (see #325), that contains the unit-length vector field normal to the boundary
  • at the top and bottom this would be a Contravariant3Vector(1/sqrt(g_{33}))
  • you would then multiply your scalar field by this
  • for wind stress you want the normal gradient of the tangential component, which would be a 2-tensor, with Covariant12Axis and a Contravariant3Axis.
    • define a covariant12 vector field, then multiply it by the normal_field
  1. Define some notion of a NormalAxis/NormalVector, which can only be defined on boundary fields, and can be converted to the other vector/tensor types
  • this gets more complicated, and we would need to store the direction of the normal in the boundary space for this to work.

I would lean toward 1 for now.

simonbyrne avatar Mar 30 '22 16:03 simonbyrne

https://github.com/CliMA/ClimaCoupler.jl/blob/4f6534f511055ea1e47a955c2ea4c131df2998ec/experiments/ClimaCore/sea_breeze/coupledbc.jl#L22

I think you can just do

norm.(uₕ_nearwall)

to get the tangential wind speed, will need to double check though

simonbyrne avatar Mar 30 '22 16:03 simonbyrne

Actually we may need to reconstruct the vector at the boundary?

simonbyrne avatar Mar 30 '22 16:03 simonbyrne

From discussion on Slack: a Covariant3Vector is orthogonal to the surface, since $$\boldsymbol{u}_v = u_3 \boldsymbol{e}^3$$.

To get the unit normal, we can normalize this, i.e. we choose $u_3$ such that $$u_3 u_3 g^{33} = 1$$

In other words, Covariant3Vector(1.0) / norm(Covariant3Vector(1.0)), or equivalently Covariant3Vector(1/sqrt(g^{33}))

simonbyrne avatar May 09 '23 17:05 simonbyrne

I think we should provide a Normal3Vector to handle this.

simonbyrne avatar Jul 11 '23 22:07 simonbyrne