20#ifndef _TWO_DIMENSIONAL_TABULAR_FUNCTION_H_
21#define _TWO_DIMENSIONAL_TABULAR_FUNCTION_H_
23#include "mbsim/functions/function.h"
24#include "mbsim/utils/utils.h"
30 template<
typename Ret,
typename Arg1,
typename Arg2>
35 int getArg1Size()
const override {
return 1; }
36 int getArg2Size()
const override {
return 1; }
37 std::pair<int, int> getRetSize()
const override {
return std::make_pair(1,1); }
38 void initializeUsingXML(xercesc::DOMElement *element)
override {
39 xercesc::DOMElement * e = MBXMLUtils::E(element)->getFirstElementChildNamed(MBSIM%
"x");
41 setx(MBXMLUtils::E(e)->getText<fmatvec::Vec>());
42 e = MBXMLUtils::E(element)->getFirstElementChildNamed(MBSIM%
"y");
43 sety(MBXMLUtils::E(e)->getText<fmatvec::Vec>());
44 e = MBXMLUtils::E(element)->getFirstElementChildNamed(MBSIM%
"z");
45 setz(MBXMLUtils::E(e)->getText<fmatvec::Mat>(y.size(), x.size()));
47 e = MBXMLUtils::E(element)->getFirstElementChildNamed(MBSIM%
"xyz");
48 if(e) setxyz(MBXMLUtils::E(e)->getText<fmatvec::Mat>());
50 Ret operator()(
const Arg1& xVal_,
const Arg2& yVal_)
override {
53 calcIndex(xVal, x, x.size(), x0Index, x1Index);
54 calcIndex(yVal, y, y.size(), y0Index, y1Index);
58 zVal(3) = xVal * yVal;
59 const double x0 = x(x0Index);
60 const double x1 = x(x1Index);
61 const double y0 = y(y0Index);
62 const double y1 = y(y1Index);
63 const double nenner = (x0 - x1) * (y0 - y1);
64 zInd(0) = z(y0Index, x0Index);
65 zInd(1) = z(y0Index, x1Index);
66 zInd(2) = z(y1Index, x0Index);
67 zInd(3) = z(y1Index, x1Index);
69 zFac(0, 1) = -x0 * y1;
70 zFac(0, 2) = -x1 * y0;
89 void setx(
const fmatvec::VecV &x_) { x <<= x_; }
90 void sety(
const fmatvec::VecV &y_) { y <<= y_; }
91 void setz(
const fmatvec::MatV &z_) { z <<= z_; }
92 void setxyz(
const fmatvec::MatV &xyz) {
93 if(xyz.rows() <= 1 or xyz.cols() <= 1)
94 this->throwError(
"Dimension missmatch in size of xyz");
95 x <<= xyz.row(0)(fmatvec::RangeV(1,xyz.cols()-1)).T();
96 y <<= xyz.col(0)(fmatvec::RangeV(1,xyz.rows()-1));
97 z <<= xyz(fmatvec::RangeV(1,xyz.rows()-1),fmatvec::RangeV(1,xyz.cols()-1));
100 double getxMin() {
return x(0); }
101 double getxMax() {
return x(x.size() - 1); }
102 double getyMin() {
return y(0); }
103 double getyMax() {
return y(y.size() - 1); }
107 Function<Ret(Arg1, Arg2)>::init(stage, config);
109 if (z.cols() != x.size())
110 this->throwError(
"Dimension missmatch in size of x");
111 if (z.rows() != y.size())
112 this->throwError(
"Dimension missmatch in size of y");
113 for (
int i = 1; i < x.size(); i++)
114 if (x(i - 1) >= x(i))
115 this->throwError(
"x values must be strictly monotonic increasing!");
116 for (
int i = 1; i < y.size(); i++)
117 if (y(i - 1) >= y(i))
118 this->throwError(
"y values must be strictly monotonic increasing!");
126 int x0Index{0}, x1Index{0};
127 int y0Index{0}, y1Index{0};
133 void calcIndex(
double x,
const fmatvec::VecV &X,
int xSize,
int &xIndexMinus,
int &xIndexPlus) {
138 fmatvec::Atom::msg(fmatvec::Atom::Warn) <<
"TwoDimensionalTabularFunction: Value (" << x <<
") is smaller than the smallest table value(" << X(0) <<
")!" << std::endl;
140 else if (x >= X(xSize - 1)) {
141 xIndexPlus = xSize - 1;
142 xIndexMinus = xSize - 2;
144 fmatvec::Atom::msg(fmatvec::Atom::Warn) <<
"TwoDimensionalTabularFunction: Value (" << x <<
") is greater than the greatest table value(" << X(xSize - 1) <<
")!" << std::endl;
147 if (x < X(xIndexPlus))
148 while (x < X(xIndexPlus - 1) && xIndexPlus > 1)
150 else if (x > X(xIndexPlus))
151 while (x > X(xIndexPlus) && xIndexPlus < xSize - 1)
153 xIndexMinus = xIndexPlus - 1;
InitStage
The stages of the initialization.
Definition: element.h:62
@ preInit
Definition: element.h:64
Definition: function.h:53
void init(Element::InitStage stage, const InitConfigSet &config) override
plots time series header
Definition: two_dimensional_tabular_function.h:106
Definition: two_dimensional_tabular_function.h:28
namespace MBSim
Definition: bilateral_constraint.cc:30