#Metview Macro

#  **************************** LICENSE START ***********************************
# 
#  Copyright 2018 ECMWF. This software is distributed under the terms
#  of the Apache License version 2.0. In applying this license, ECMWF does not
#  waive the privileges and immunities granted to it by virtue of its status as
#  an Intergovernmental Organization or submit itself to any jurisdiction.
# 
#  ***************************** LICENSE END ************************************
# 

# **************************************************************************
# Function      : vorticity
#
# Syntax        : fieldset vorticity(fs_x:fieldset,fs_y:fieldset)
#                                          
# Category      : DERIVATIVES
#
# OneLineDesc   : Compute relative vorticity of vector fields
#
# Description   : Compute the relative vorticity of vector fields defined on a 
#	              regular lat-lon grid. The computation uses a second order accuracy
#                 finite difference scheme.
#
# Parameters    : fieldset_x - x component of vector field 
#                 fieldset_y - y component of vector field
#                 
# Return Value  : resulting fieldset
#
# Dependencies  : none
#
# Example Usage : 
#                 
#
# **************************************************************************

function vorticity
    _fn_name = "vorticity"
    
    _args = arguments()
    _v = __prepare_gradient_arg(_fn_name, 2, _args)
    if count(_v) <> 5 then
        fail(_fn_name & ": invalid arguments=" & _args)
    end if
    _fs_x = _v[1]
    _fs_y = _v[2]
    _mode = _v[3]
    _pole_missing = _v[4]
    _vector_mode = _v[5]

    if count(_fs_x) <> count(_fs_y) then
        fail(_fn_name & ": different number of fields in fieldsets [fieldset1=",count(_fs_x),", fieldset2=",count(_fs_y),"]")
    end if          
  
    # extract metadata keys
    _keys_x = grib_get(_fs_x,["gridType","paramId"], "key")
    _keys_y = grib_get(_fs_y,["gridType","paramId"], "key")
    
    _vo = nil

    # finite difference
    if _mode = "fdiff" then

        #radius of Earth
        _R = 6371200.0
      
        for _i=1 to count(_fs_x) do
            # get metadata keys
            _grid_type_x = _keys_x[1][_i]
            _grid_type_y = _keys_y[1][_i]
           
            # check if grid is regular latlon 
            if _grid_type_x <> "regular_ll" then
                fail(_fn_name & ": [fieldset_x, field=",_i,"] - unsupported grid (=",_grid_type_x,"), implemented only for regular lat-lon grid")
            end if
            
            if _grid_type_y <> "regular_ll" then
                fail(_fn_name & ": [fieldset_y, field=",_i,"] - unsupported grid (=",_grid_type_y,"), implemented only for regular lat-lon grid")
            end if
        end for    
        
        # compute vorticity
        _dfxdy = first_derivative_y(_fs_x)
        _dfydx = first_derivative_x(_fs_y)
        _vo = _dfydx - _dfxdy + _fs_x*tanlat(_fs_x)/_R

    # finite element
    else if _mode = "felem" then
        _f = nil 
        for _i=1 to count(_fs_x) do
            _f = _f & _fs_x[_i] & _fs_y[_i]
        end for
        _vo = regrid(data: _f, nabla: "uv_vorticity", nabla_poles_missing_values: _pole_missing)
    end if    
   
    _res = _vo

    #set paramid to vorticity when x and y components are 
    #10u/10v or u/v.
    if ("165" in _keys_x[2] and "166" in _keys_y[2]) or
       ("131" in _keys_x[2] and "132" in _keys_y[2]) then
        _res = nil        
        for _i=1 to count(_vo) do
            _param_x = _keys_x[2][_i]
            _param_y = _keys_y[2][_i]
            if (_param_x = "165" and _param_y = "166") or
                (_param_x = "131" and _param_y = "132") then
                _res = _res & grib_set_long(_vo[_i],["paramId",138,"generatingProcessIdentifier",142])   
            else
                _res = _res & _vo[_i]
            end if           	    
        end for
    end if
    
    return _res

end vorticity
