Commit 433bde30 authored by Liz Dulac's avatar Liz Dulac Committed by Bolea Sanchez, Vicente Adolfo
Browse files

Add the CURL function to derived variables (#4114)



* Derived Expressions Curl function with correctness test

* Fixing index bug for internal boundaries

* Curl Correctness Test Cleanup

* Remove debug statements in Test

* Merging Bison3.8 parser into ADIOS (ERRORS - cannot build)

* CMake Tweaks

* whoops, missed the cmake file.

* Updated parser merged with adios, updated error message for missing operation, missing curl implementation

* Clean up

* Removed 'var' keyword from grammar and correctness test, and minor changes: ensured only one expression in grammar, turned off scanner debugging, resolved shift/reduce conflicts, ASTNode prettyprint can be called without operand.

* Set Derived_Variable flag to ON (for CI testing)

* Remove unnecessary files

* Cleanup curl code

* Formatting

* Formatting

* Restore examples CMakeLists.txt file

* Restore cmake compile flags

* Unused variable curlV in testing

* Implicit type conversion warnings

* Formatting

* Use float specific math, remove infinity check

* Convert size_t iterator to float math

* Default to DerivedVariables OFF

* Default to DerivedVariables ON

* Change the way to check for dimension equality and function rename

* format

---------

Co-authored-by: default avatarlizdulac <lizadulac@gmail.com>
Co-authored-by: default avatarGreg Eisenhauer <eisen@cc.gatech.edu>
Co-authored-by: default avataranagainaru <ana.gainaru@gmail.com>
parent aeaab4e2
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -185,7 +185,7 @@ adios_option(Sodium "Enable support for Sodium for encryption" AUTO)
adios_option(Catalyst   "Enable support for in situ visualization plugin using ParaView Catalyst" AUTO)
adios_option(Campaign   "Enable support for Campaigns (requires SQLite3 and ZLIB)" AUTO)
adios_option(AWSSDK     "Enable support for S3 compatible storage using AWS SDK's S3 module" OFF)
adios_option(Derived_Variable    "Enable support for derived variables" OFF)
adios_option(Derived_Variable    "Enable support for derived variables" ON)
adios_option(PIP        "Enable support for pip packaging" OFF)

option(ADIOS2_Blosc2_PREFER_SHARED "Prefer shared Blosc2 libraries" ON)
+4 −1
Original line number Diff line number Diff line
@@ -21,7 +21,8 @@ enum ExpressionOperator
    OP_ADD,
    OP_SQRT,
    OP_POW,
    OP_MAGN
    OP_MAGN,
    OP_CURL
};

struct OperatorProperty
@@ -39,6 +40,7 @@ const std::map<ExpressionOperator, OperatorProperty> op_property = {
    {ExpressionOperator::OP_ADD, {"ADD", true}},
    {ExpressionOperator::OP_SQRT, {"SQRT", false}},
    {ExpressionOperator::OP_POW, {"POW", false}},
    {ExpressionOperator::OP_CURL, {"CURL", false}},
    {ExpressionOperator::OP_MAGN, {"MAGNITUDE", false}}};

const std::map<std::string, ExpressionOperator> string_to_op = {
@@ -49,6 +51,7 @@ const std::map<std::string, ExpressionOperator> string_to_op = {
    {"add", ExpressionOperator::OP_ADD},        {"ADD", ExpressionOperator::OP_ADD},
    {"SQRT", ExpressionOperator::OP_SQRT},      {"sqrt", ExpressionOperator::OP_SQRT},
    {"POW", ExpressionOperator::OP_POW},        {"^", ExpressionOperator::OP_POW},
    {"CURL", ExpressionOperator::OP_CURL},      {"curl", ExpressionOperator::OP_CURL},
    {"MAGNITUDE", ExpressionOperator::OP_MAGN}, {"magnitude", ExpressionOperator::OP_MAGN}};

inline std::string get_op_name(ExpressionOperator op) { return op_property.at(op).name; }
+106 −2
Original line number Diff line number Diff line
@@ -54,15 +54,119 @@ Dims SameDimsFunc(std::vector<Dims> input)
    // check that all dimenstions are the same
    if (input.size() > 1)
    {
        bool dim_are_equal = std::equal(input.begin() + 1, input.end(), input.begin());
        Dims first_element = input[0];
        bool dim_are_equal = std::all_of(input.begin() + 1, input.end(),
                                         [&first_element](Dims x) { return x == first_element; });
        if (!dim_are_equal)
            helper::Throw<std::invalid_argument>("Derived", "Function", "SameDimFunc",
            helper::Throw<std::invalid_argument>("Derived", "Function", "SameDimsFunc",
                                                 "Invalid variable dimensions");
    }
    // return the first dimension
    return input[0];
}

// Input Dims are the same, output is combination of all inputs
Dims CurlDimsFunc(std::vector<Dims> input)
{
    // check that all dimenstions are the same
    if (input.size() > 1)
    {
        Dims first_element = input[0];
        bool dim_are_equal = std::all_of(input.begin() + 1, input.end(),
                                         [&first_element](Dims x) { return x == first_element; });
        if (!dim_are_equal)
            helper::Throw<std::invalid_argument>("Derived", "Function", "CurlDimsFunc",
                                                 "Invalid variable dimensions");
    }
    // return original dimensions with added dimension of number of inputs
    Dims output = input[0];
    output.push_back(input.size());
    return output;
}

/*
 * Linear Interpolation - average difference around point "index"
 *  can be used to approximate derivatives
 *
 * Input:
 *     input - data assumed to be uniform/densely populated
 *     index - index of point of interest
 *     dim - in which dimension we are approximating the partial derivative
 */
// template <class T>
float linear_interp(DerivedData input, size_t index, size_t dim)
{
    size_t stride = 1;
    size_t range;
    size_t offset;
    float result;
    float *data = (float *)input.Data;

    for (size_t i = 0; i < input.Count.size() - (dim + 1); ++i)
    {
        stride *= input.Count[input.Count.size() - (i + 1)];
    }
    size_t ind1 = index - stride;
    size_t ind2 = index + stride;
    range = stride * input.Count[dim];
    offset = index % range;

    if ((offset < stride) && (range - offset <= stride))
    {
        return 0;
    }
    else if (offset < stride)
    {
        result = data[ind2] - data[index];
    }
    else if (range - offset <= stride)
    {
        result = data[index] - data[ind1];
    }
    else
    {
        result = (data[ind2] - data[ind1]) / 2;
    }

    return result;
}

/*
 * Input: 3D vector field F(x,y,z)= {F1(x,y,z), F2(x,y,z), F3(x,y,z)}
 *
 *     inputData - (3) components of 3D vector field
 *
 * Computation:
 *     curl(F(x,y,z)) = (partial(F3,y) - partial(F2,z))i
 *                    + (partial(F1,z) - partial(F3,x))j
 *                    + (partial(F2,x) - partial(F1,y))k
 *
 *     boundaries are calculated only with data in block
 *         (ex: partial derivatives in x direction at point (0,0,0)
 *              only use data from (1,0,0), etc )
 */
DerivedData Curl3DFunc(const std::vector<DerivedData> inputData, DataType type)
{
    size_t dataSize = inputData[0].Count[0] * inputData[0].Count[1] * inputData[0].Count[2];

    DerivedData curl;
    // ToDo - template type
    float *data = (float *)malloc(dataSize * sizeof(float) * 3);
    curl.Start = inputData[0].Start;
    curl.Start.push_back(0);
    curl.Count = inputData[0].Count;
    curl.Count.push_back(3);

    for (size_t i = 0; i < dataSize; ++i)
    {
        data[3 * i] = linear_interp(inputData[2], i, 1) - linear_interp(inputData[1], i, 2);
        data[3 * i + 1] = linear_interp(inputData[0], i, 2) - linear_interp(inputData[2], i, 0);
        data[3 * i + 2] = linear_interp(inputData[1], i, 0) - linear_interp(inputData[0], i, 1);
    }
    curl.Data = data;
    return curl;
}

#define declare_template_instantiation(T)                                                          \
    T *ApplyOneToOne(std::vector<DerivedData>, size_t, std::function<T(T, T)>);

+6 −0
Original line number Diff line number Diff line
@@ -26,11 +26,17 @@ struct OperatorFunctions

DerivedData AddFunc(std::vector<DerivedData> input, DataType type);
DerivedData MagnitudeFunc(std::vector<DerivedData> input, DataType type);
DerivedData Curl3DFunc(std::vector<DerivedData> input, DataType type);

template <class T>
T linear_interp(T *data, size_t index, size_t count, size_t stride = 1);

Dims SameDimsFunc(std::vector<Dims> input);
Dims CurlDimsFunc(std::vector<Dims> input);

const std::map<adios2::detail::ExpressionOperator, OperatorFunctions> OpFunctions = {
    {adios2::detail::ExpressionOperator::OP_ADD, {AddFunc, SameDimsFunc}},
    {adios2::detail::ExpressionOperator::OP_CURL, {Curl3DFunc, CurlDimsFunc}},
    {adios2::detail::ExpressionOperator::OP_MAGN, {MagnitudeFunc, SameDimsFunc}}};

template <class T>
+0 −1
Original line number Diff line number Diff line
@@ -1903,4 +1903,3 @@ adios2::detail::ASTDriver::parse (const std::string input)
  parse.set_debug_level (trace_parsing);
  parse ();
}
Loading