-
Notifications
You must be signed in to change notification settings - Fork 274
Description
Feature request
Currently, binary operations on fields are limited to arithmetic operators (+, -, *, /, ^). Comparison operators like >, <, >=, <=, == are not supported. It would be useful to support these, returning an AbstractOperation with eltype Bool.
A related issue is that Field(a > b) should produce a Field with eltype Bool (and Bool-valued backing data), rather than the current default of eltype(grid).
MWE (desired behavior)
using Oceananigans
grid = RectilinearGrid(size=(4, 4, 4), extent=(1, 1, 1))
a = CenterField(grid)
b = CenterField(grid)
set!(a, (x, y, z) -> x)
set!(b, (x, y, z) -> 0.5)
# This should work and return a BinaryOperation with eltype Bool
op = a > b
eltype(op) # should be Bool
# Creating a Field from it should produce Bool-valued data
f = Field(op)
eltype(f) # should be Bool
compute!(f)
f[1, 1, 1] # should be false (or true), not 0.0 (or 1.0)Current behavior
a > b where a and b are fields is not defined and throws a MethodError.
Implementation notes
Two things need to change:
-
Register comparison operators as binary operations. The
@binarymacro insrc/AbstractOperations/binary_operations.jlcould be used to register>,<,>=,<=,==, though operator precedence / location semantics should be considered. -
Derive
eltypefrom the operation, not just the grid. Currently,BinaryOperation,UnaryOperation, andMultiaryOperationall setT = eltype(grid). For comparison operations,Tshould beBool. This could be handled by a trait or dispatch on the operator, e.g.:result_eltype(op, grid) = eltype(grid) # default for arithmetic result_eltype(::typeof(>), grid) = Bool # for comparisons
Similarly,
Fieldconstruction from a boolean operation should allocateBool-valued data via something likenew_data(Bool, grid, loc, indices).