Calculates and returns a requested quantity from quantities passed in as
keyword arguments.

Parameters
----------

\*args : string
    Names of quantities to be calculated.
assumptions : tuple, optional
    Strings specifying which assumptions to enable. Overrides the default
    assumptions. See below for a list of default assumptions.
add_assumptions : tuple, optional
    Strings specifying assumptions to use in addition to the default
    assumptions. May not be given in combination with the assumptions kwarg.
remove_assumptions : tuple, optional
    Strings specifying assumptions not to use from the default assumptions.
    May not be given in combination with the assumptions kwarg. May not
    contain strings that are contained in add_assumptions, if given.
\*\*kwargs : ndarray, optional
    Keyword arguments used to pass in arrays of data that correspond to
    quantities used for calculations, or unit specifications for quantities.
    For a complete list of kwargs that may be used, see the Quantity Parameters
    section below.

Returns
-------

quantity : ndarray
    Calculated quantity.
    Return type is the same as quantity parameter types.
    If multiple quantities are requested, returns a tuple containing the
    quantities.

Notes
-----

Calculating multiple quantities at once can avoid re-computing intermediate
quantities, but requires more memory.

**Quantity kwargs**

<quantity parameter list goes here>

In addition to the quantities above, kwargs of the form <quantity>_unit or
<quantity>_units can be used with a string specifying a unit for the quantity.
This will cause input data for that quantity to be assumed to be in that
unit, and output data for that quantity to be given in that unit. Note this
must be specified separately for *each* quantity. Acceptable units are the
units available in the Pint package, with the exception that RH can be in
units of "fraction" or "percent".

**Assumptions**

<default assumptions list goes here>

**Assumption descriptions**

<assumptions list goes here>

Examples
--------

Calculating pressure from virtual temperature and density:

>>> calculate('p', Tv=273., rho=1.27)
99519.638400000011

Same calculation, but also returning a list of functions used:

>>> p, funcs = calculate('p', Tv=273., rho=1.27, debug=True)
>>> funcs
(<function atmos.equations.p_from_rho_Tv_ideal_gas>,)

Same calculation with temperature instead, ignoring virtual temperature
correction:

>>> calculate('p', T=273., rho=1.27, add_assumptions=('Tv equals T',))
99519.638400000011

def calculate(*args, **kwargs):
    '''
Calculates and returns a requested quantity from quantities passed in as
keyword arguments.

Parameters
----------

\*args : string
    Names of quantities to be calculated.
assumptions : tuple, optional
    Strings specifying which assumptions to enable. Overrides the default
    assumptions. See below for a list of default assumptions.
add_assumptions : tuple, optional
    Strings specifying assumptions to use in addition to the default
    assumptions. May not be given in combination with the assumptions kwarg.
remove_assumptions : tuple, optional
    Strings specifying assumptions not to use from the default assumptions.
    May not be given in combination with the assumptions kwarg. May not
    contain strings that are contained in add_assumptions, if given.
\*\*kwargs : ndarray, optional
    Keyword arguments used to pass in arrays of data that correspond to
    quantities used for calculations, or unit specifications for quantities.
    For a complete list of kwargs that may be used, see the Quantity Parameters
    section below.

Returns
-------

quantity : ndarray
    Calculated quantity.
    Return type is the same as quantity parameter types.
    If multiple quantities are requested, returns a tuple containing the
    quantities.

Notes
-----

Calculating multiple quantities at once can avoid re-computing intermediate
quantities, but requires more memory.

**Quantity kwargs**

<quantity parameter list goes here>

In addition to the quantities above, kwargs of the form <quantity>_unit or
<quantity>_units can be used with a string specifying a unit for the quantity.
This will cause input data for that quantity to be assumed to be in that
unit, and output data for that quantity to be given in that unit. Note this
must be specified separately for *each* quantity. Acceptable units are the
units available in the Pint package, with the exception that RH can be in
units of "fraction" or "percent".

**Assumptions**

<default assumptions list goes here>

**Assumption descriptions**

<assumptions list goes here>

Examples
--------

Calculating pressure from virtual temperature and density:

>>> calculate('p', Tv=273., rho=1.27)
99519.638400000011

Same calculation, but also returning a list of functions used:

>>> p, funcs = calculate('p', Tv=273., rho=1.27, debug=True)
>>> funcs
(<function atmos.equations.p_from_rho_Tv_ideal_gas>,)

Same calculation with temperature instead, ignoring virtual temperature
correction:

>>> calculate('p', T=273., rho=1.27, add_assumptions=('Tv equals T',))
99519.638400000011
'''
    if len(args) == 0:
        raise ValueError('must specify quantities to calculate')
    # initialize a solver to do the work
    solver = FluidSolver(**kwargs)
    # get the output
    return solver.calculate(*args)