Skip to content
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

Flux boundary condition with two components #629

Closed
EavenW opened this issue Feb 16, 2020 · 5 comments
Closed

Flux boundary condition with two components #629

EavenW opened this issue Feb 16, 2020 · 5 comments
Labels
question 💭 No such thing as a stupid question

Comments

@EavenW
Copy link

EavenW commented Feb 16, 2020

New to the ecosystem. I have a u* at the surface that I am trying to impart as a flux boundary condition, but the experiment requires that it rotates as a function of time.
Can this be done as a 2D flux or does it need to be an @inline = @inbounds function?

Thanks

@ali-ramadhan
Copy link
Member

Hi @EavenW hope it wasn't too hard to get started (the documentation needs some more work, sorry about that).

Not totally sure what you mean by a flux boundary condition with two components (sounds like the u and v velocity fields might be further coupled via this boundary condition?).

Sounds like you're trying to impose a (time-dependent?) surface flux boundary condition which can be done a few different ways.

  • If it's independent of time then imposing a flux BC with a 2D array is one option.
  • If it's time-dependent then imposing the flux BC as a function is probably the way to go. The function signature for boundary conditions is f(i, j, grid, t, U, C, params) so the boundary condition can depend on time t, the velocity fields U = (u, v, w) and any tracer quantity in C.
  • If you can write your surface flux BC as a function of only (x, y, t) then a BoundaryFunction can simplify the setup a little. I just realized this isn't showing up in the documentation but the docstring in the file I linked to has an example of how to use it.

PS: Not sure which version you're running but we've been making some improvements to the user interface lately which may break certain things if you upgrade to v0.21 or v0.22. Please don't hesitate to ping us if you have any questions or if something isn't working. We're more than happy to help.

@ali-ramadhan ali-ramadhan added the question 💭 No such thing as a stupid question label Feb 16, 2020
@ali-ramadhan
Copy link
Member

PS²: @EavenW if you're at the Ocean Sciences 2020 meeting and have some simulations in mind that you're trying to set up you should try to meet up with @glwagner!

@glwagner
Copy link
Member

Hi @EavenW, yes, you have to specify the x- and y- components of a momentum flux vector separately on u and v.

Because each flux component is a function of time, you should use our BoundaryFunction wrapper for each component cf @ali-ramadhan comment above.

Thanks for the question — keep them coming!

@glwagner
Copy link
Member

glwagner commented Feb 17, 2020

@EavenW here is some code for you:

using Oceananigans
using Oceananigans.Fields

f = 1e-4 # [s⁻¹] Coriolis parameter

# Use 'const' so boundary functions work on the GPU.
const ω = 2π/f  # [s] Inertial period
const u★ = 0.01 # [m s⁻¹], friction velocity

# fluxes *kinematic* because they are applied to the velocity field. 
x_momentum_flux(x, y, t) = u★^2 * cos* t)
y_momentum_flux(x, y, t) = u★^2 * sin* t)

τˣ = BoundaryFunction{:z, Face, Cell}(x_momentum_flux)
τʸ = BoundaryFunction{:z, Cell, Face}(y_momentum_flux)

u_boundary_condition = HorizontallyPeriodicBCs(top=BoundaryCondition(Flux, τˣ))
v_boundary_condition = HorizontallyPeriodicBCs(top=BoundaryCondition(Flux, τʸ))

As @ali-ramadhan we are redesigning this API this week. So expect changes very soon if you keep Oceananigans updated. We think the API will become clearer and easier to use. This code is young so we certainly appreciate comments and criticism that will help us make the code easier-to-use.

I just noticed that the docstring defined inside the struct does not print at the REPL, so here it is:

    """
        BoundaryFunction{B, X1, X2}(func)
    A wrapper for user-defined boundary condition functions on the
    boundary specified by symbol `B` and at location `(X1, X2)`.

    Example
    =======
    julia> using Oceananigans: BoundaryCondition, BoundaryFunction, Flux, Cell

    julia> top_tracer_flux = BoundaryFunction{:z, Cell, Cell}((x, y, t) -> cos(2π*x) * cos(t))
    (::BoundaryFunction{:z,Cell,Cell,getfield(Main, Symbol("##7#8"))}) (generic function with 1 method)

    julia> top_tracer_bc = BoundaryCondition(Flux, top_tracer_flux);
    """

@EavenW
Copy link
Author

EavenW commented Feb 17, 2020

Thank you so much! This clears up a lot about how to communicate the boundary conditions. And yes, I'll be at OSM albeit presenting something completely different.

@EavenW EavenW closed this as completed Feb 17, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question 💭 No such thing as a stupid question
Projects
None yet
Development

No branches or pull requests

3 participants