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

support mathematical expressions in Parameter #2325

Merged
merged 8 commits into from
Jan 31, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,6 @@
[submodule "ThirdParty/jedbrown-cmake-modules"]
path = ThirdParty/jedbrown-cmake-modules
url = https://github.com/jedbrown/cmake-modules.git
[submodule "ThirdParty/exprtk"]
path = ThirdParty/exprtk
url = https://github.com/ArashPartow/exprtk.git
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,7 @@ include_directories( SYSTEM ${CMAKE_CURRENT_SOURCE_DIR}/ThirdParty/googletest/go
include_directories( SYSTEM ${CMAKE_CURRENT_SOURCE_DIR}/ThirdParty/autocheck/include )
include_directories( SYSTEM ${CMAKE_CURRENT_SOURCE_DIR}/ThirdParty/tclap/include )
include_directories( SYSTEM ${CMAKE_CURRENT_SOURCE_DIR}/ThirdParty/json/include )
include_directories( SYSTEM ${CMAKE_CURRENT_SOURCE_DIR}/ThirdParty/exprtk )

include(scripts/cmake/CheckHeaderCompilation.cmake)

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
A function defined by a mathematical expression.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Mathematical expression of the function (currently x,y,z are supported variables). For non-scalar values, an expression should be given for each component.
37 changes: 37 additions & 0 deletions ProcessLib/Parameter/FunctionParameter.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/**
* \copyright
* Copyright (c) 2012-2019, OpenGeoSys Community (http://www.opengeosys.org)
* Distributed under a Modified BSD License.
* See accompanying file LICENSE.txt or
* http://www.opengeosys.org/project/license
*
*/

#include "FunctionParameter.h"

#include "BaseLib/ConfigTree.h"
#include "MeshLib/Mesh.h"

namespace ProcessLib
{
std::unique_ptr<ParameterBase> createFunctionParameter(
std::string const& name, BaseLib::ConfigTree const& config,
MeshLib::Mesh const& mesh)
{
//! \ogs_file_param{prj__parameters__parameter__type}
config.checkConfigParameter("type", "Function");

std::vector<std::string> vec_expressions;

//! \ogs_file_param{prj__parameters__parameter__Function__expression}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

for (auto const& p : config.getConfigSubtreeList("expression"))
{
std::string const expression_str = p.getValue<std::string>();
vec_expressions.emplace_back(expression_str);
}

return std::make_unique<FunctionParameter<double>>(
name, mesh, vec_expressions);
}

} // ProcessLib
116 changes: 116 additions & 0 deletions ProcessLib/Parameter/FunctionParameter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
/**
* \copyright
* Copyright (c) 2012-2019, OpenGeoSys Community (http://www.opengeosys.org)
* Distributed under a Modified BSD License.
* See accompanying file LICENSE.txt or
* http://www.opengeosys.org/project/license
*
*/

#pragma once

#include <utility>
#include <vector>

#include <exprtk.hpp>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The file is large with template definitions. When it was compiled in OGS5 with visual studio 2010, the option of /bigobj is needed. Since the building in appveyor succeeded, I think the new visual studio can handle it without using any additional option.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i tested with VS2017 and so far it's ok.


#include "MeshLib/Elements/Element.h"
#include "MeshLib/Node.h"

#include "Parameter.h"
#include "ProcessLib/Utils/ProcessUtils.h"

namespace ProcessLib
{

/// A parameter class evaluating functions defined by
/// user-provided mathematical expressions.
///
/// Currently, x, y, and z are supported as variables
/// of the functions.
template <typename T>
struct FunctionParameter final : public Parameter<T>
{
typedef exprtk::symbol_table<T> symbol_table_t;
typedef exprtk::expression<T> expression_t;
typedef exprtk::parser<T> parser_t;
typedef exprtk::parser_error::type error_t;

/**
* Constructing from a vector of expressions
*
* @param name_ the parameter's name
* @param mesh_ a mesh object
* @param vec_expression_str_ a vector of mathematical expressions
* The vector size specifies the number of components of the parameter.
*/
FunctionParameter(std::string const& name_,
MeshLib::Mesh const& mesh_,
std::vector<std::string> const& vec_expression_str_)
: Parameter<T>(name_), _mesh(mesh_), _vec_expression_str(vec_expression_str_)
{
_symbol_table.add_constants();
_symbol_table.create_variable("x");
_symbol_table.create_variable("y");
_symbol_table.create_variable("z");

_vec_expression.resize(_vec_expression_str.size());
for (unsigned i=0; i<_vec_expression_str.size(); i++)
{
_vec_expression[i].register_symbol_table(_symbol_table);
parser_t parser;
if (!parser.compile(_vec_expression_str[i], _vec_expression[i]))
{
OGS_FATAL("Error: %s\tExpression: %s\n", parser.error().c_str(),
_vec_expression_str[i].c_str());
}
}
}

bool isTimeDependent() const override { return false; }

int getNumberOfComponents() const override
{
return _vec_expression.size();
}

std::vector<T> operator()(double const /*t*/,
SpatialPosition const& pos) const override
{
std::vector<T> cache(getNumberOfComponents());
auto& x = _symbol_table.get_variable("x")->ref();
auto& y = _symbol_table.get_variable("y")->ref();
auto& z = _symbol_table.get_variable("z")->ref();
if (pos.getCoordinates())
{
auto const coords = pos.getCoordinates().get();
x = coords[0];
y = coords[1];
z = coords[2];
}
else if (pos.getNodeID())
{
auto const& node = *_mesh.getNode(pos.getNodeID().get());
x = node[0];
y = node[1];
z = node[2];
}

for (unsigned i=0; i<_vec_expression.size(); i++)
cache[i] = _vec_expression[i].value();

return cache;
}

private:
MeshLib::Mesh const& _mesh;
std::vector<std::string> const _vec_expression_str;
symbol_table_t _symbol_table;
std::vector<expression_t> _vec_expression;
};

std::unique_ptr<ParameterBase> createFunctionParameter(
std::string const& name, BaseLib::ConfigTree const& config,
MeshLib::Mesh const& mesh);

} // ProcessLib
7 changes: 7 additions & 0 deletions ProcessLib/Parameter/Parameter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

#include "ConstantParameter.h"
#include "CurveScaledParameter.h"
#include "FunctionParameter.h"
#include "GroupBasedParameter.h"
#include "MeshElementParameter.h"
#include "MeshNodeParameter.h"
Expand Down Expand Up @@ -45,6 +46,12 @@ std::unique_ptr<ParameterBase> createParameter(
auto param = createCurveScaledParameter(name, config, curves);
return param;
}
if (type == "Function")
{
INFO("FunctionParameter: %s", name.c_str());
auto param = createFunctionParameter(name, config, *meshes.front());
return param;
}
if (type == "Group")
{
INFO("GroupBasedParameter: %s", name.c_str());
Expand Down
4 changes: 4 additions & 0 deletions ThirdParty/ReadMe.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,7 @@ Is integrated as a submodule.

Header only c++ json parser. Directly integrated because the benchmarks and
tests are too large.

## exprtk ##

Header only c++ mathematical expression parsing and evaluation library
1 change: 1 addition & 0 deletions ThirdParty/exprtk
Submodule exprtk added at e0e880
1 change: 1 addition & 0 deletions scripts/cmake/SubmoduleSetup.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ endif()
set(REQUIRED_SUBMODULES
ThirdParty/autocheck
ThirdParty/cmake-modules
ThirdParty/exprtk
ThirdParty/googletest
ThirdParty/jedbrown-cmake-modules
ThirdParty/tclap
Expand Down