mbsim 4.0.0 MBSim Kernel

symbolic_function.h
1 /* Copyright (C) 2004-2009 MBSim Development Team
2 *
3 * This library is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU Lesser General Public
5 * License as published by the Free Software Foundation; either
6 * version 2.1 of the License, or (at your option) any later version.
7 *
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public
14 * License along with this library; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16 *
17 * Contact: martin.o.foerg@googlemail.com
18 */
19
20 #ifndef _MBSIM_SYMBOLIC_FUNCTION_H_
21 #define _MBSIM_SYMBOLIC_FUNCTION_H_
22
23 #include <mbsim/functions/function.h>
24 #include <fmatvec/symbolic_function.h>
25
26 namespace MBSim {
27
28 template<typename Sig> class SymbolicFunction;
29
30 template<typename Ret, typename Arg>
31 class SymbolicFunction<Ret(Arg)> : public Function<Ret(Arg)>, public fmatvec::SymbolicFunction<Ret(Arg)> {
32
33 public:
34 SymbolicFunction() = default;
35
36 void init(Element::InitStage stage, const InitConfigSet &config) override {
37 Function<Ret(Arg)>::init(stage, config);
38 if(stage == Element::preInit) {
39 fmatvec::SymbolicFunction<Ret(Arg)>::init();
40 // checkFunctionIODim();
41 }
42 }
43
44 void initializeUsingXML(xercesc::DOMElement *element) override {
45 Function<Ret(Arg)>::initializeUsingXML(element);
46
47 auto definition=MBXMLUtils::E(element)->getFirstElementChildNamed(MBSIM%"definition");
48
49 std::stringstream func(MBXMLUtils::E(definition)->getText<std::string>());
50 char buf[3];
51 func.read(buf, 2); buf[2]=0;
52 if(buf!=std::string("f("))
53 throw MBXMLUtils::DOMEvalException("Function does not start with 'f(': "+
54 MBXMLUtils::E(definition)->getText<std::string>(), definition);
55 typename fmatvec::SymbolicFunction<Ret(Arg)>::ArgS argS;
56 func >> argS;
57 this->setIndependentVariable(argS);
58 func.read(buf, 2); buf[2]=0;
59 if(buf!=std::string(")="))
60 throw MBXMLUtils::DOMEvalException("Function does not end with ')=': "+
61 MBXMLUtils::E(definition)->getText<std::string>(), definition);
62 typename fmatvec::SymbolicFunction<Ret(Arg)>::RetS retS;
63 func >> retS;
64 this->setDependentFunction(retS);
65
66 // check symbolic function arguments: we need to throw errors during initializeUsingXML to enable the ObjectFactory
67 // to test other possible combinations (more general ones)
68 // checkFunctionIODim();
69 }
70
71 private:
72
73 // void checkFunctionIODim() {
74 // // check function <-> template argument dimension
75 // if(this->argSize!=0 && fmatvec::Helper<typename fmatvec::SymbolicFunction<Ret(Arg)>::ArgS>::size1(this->argS)!=this->argSize)
76 // this->throwError("The dimension of the parameter does not match.");
77 // if(this->retSize1!=0 && fmatvec::Helper<typename fmatvec::SymbolicFunction<Ret(Arg)>::RetS>::size1(this->retS)!=this->retSize1)
78 // this->throwError("The output row dimension does not match.");
79 // if(this->retSize2!=0 && fmatvec::Helper<typename fmatvec::SymbolicFunction<Ret(Arg)>::RetS>::size2(this->retS)!=this->retSize2)
80 // this->throwError("The output column dimension does not match.");
81 // }
82 };
83
84 template<typename Ret, typename Arg1, typename Arg2>
85 class SymbolicFunction<Ret(Arg1, Arg2)> : public Function<Ret(Arg1, Arg2)>,
86 public fmatvec::SymbolicFunction<Ret(Arg1, Arg2)> {
87
88 public:
89 SymbolicFunction() = default;
90
91 void init(Element::InitStage stage, const InitConfigSet &config) override {
92 Function<Ret(Arg1, Arg2)>::init(stage, config);
93 if(stage == Element::preInit) {
94 fmatvec::SymbolicFunction<Ret(Arg1, Arg2)>::init();
95 // checkFunctionIODim();
96 }
97 }
98
99 void initializeUsingXML(xercesc::DOMElement *element) override {
100 Function<Ret(Arg1, Arg2)>::initializeUsingXML(element);
101
102 auto definition=MBXMLUtils::E(element)->getFirstElementChildNamed(MBSIM%"definition");
103
104 std::stringstream func(MBXMLUtils::E(definition)->getText<std::string>());
105 char buf[3];
106 func.read(buf, 2); buf[2]=0;
107 if(buf!=std::string("f("))
108 throw MBXMLUtils::DOMEvalException("Function does not start with 'f(': "+
109 MBXMLUtils::E(definition)->getText<std::string>(), definition);
110 typename fmatvec::SymbolicFunction<Ret(Arg1,Arg2)>::Arg1S arg1S;
111 func >> arg1S;
112 this->setIndependentVariable1(arg1S);
113 func.read(buf, 1);
114 if(buf[0]!=',')
115 throw MBXMLUtils::DOMEvalException("Function must have two arguments: "+
116 MBXMLUtils::E(definition)->getText<std::string>(), definition);
117 typename fmatvec::SymbolicFunction<Ret(Arg1,Arg2)>::Arg2S arg2S;
118 func >> arg2S;
119 this->setIndependentVariable2(arg2S);
120 func.read(buf, 2); buf[2]=0;
121 if(buf!=std::string(")="))
122 throw MBXMLUtils::DOMEvalException("Function does not end with ')=': "+
123 MBXMLUtils::E(definition)->getText<std::string>(), definition);
124 typename fmatvec::SymbolicFunction<Ret(Arg1,Arg2)>::RetS retS;
125 func >> retS;
126 this->setDependentFunction(retS);
127
128 // check symbolic function arguments: we need to throw errors during initializeUsingXML to enable the ObjectFactory
129 // to test other possible combinations (more general ones)
130 // checkFunctionIODim();
131 }
132
133 private:
134
135 // void checkFunctionIODim() {
136 // // check function <-> template argument dimension
137 // if(this->arg1Size!=0 && fmatvec::Helper<typename fmatvec::SymbolicFunction<Ret(Arg1,Arg2)>::Arg1S>::size1(this->arg1S)!=this->arg1Size)
138 // this->throwError("The dimension of the parameter does not match.");
139 // if(this->arg2Size!=0 && fmatvec::Helper<typename fmatvec::SymbolicFunction<Ret(Arg1,Arg2)>::Arg2S>::size1(this->arg2S)!=this->arg2Size)
140 // this->throwError("The dimension of the parameter does not match.");
141 // if(this->retSize1!=0 && fmatvec::Helper<typename fmatvec::SymbolicFunction<Ret(Arg1,Arg2)>::RetS>::size1(this->retS)!=this->retSize1)
142 // this->throwError("The output row dimension does not match.");
143 // if(this->retSize2!=0 && fmatvec::Helper<typename fmatvec::SymbolicFunction<Ret(Arg1,Arg2)>::RetS>::size2(this->retS)!=this->retSize2)
144 // this->throwError("The output column dimension does not match.");
145 // }
146 };
147
148 }
149
150 #endif
MBSim::SymbolicFunction< Ret(Arg)>::init
void init(Element::InitStage stage, const InitConfigSet &config) override
plots time series header
Definition: symbolic_function.h:36
MBSim::SymbolicFunction
Definition: symbolic_function.h:28
MBSim::Element::InitStage
InitStage
The stages of the initialization.
Definition: element.h:62
MBXMLUtils::DOMEvalException
MBSim::Function
Definition: contact_kinematics.h:32
MBSim::Element::preInit
Definition: element.h:64
MBSim::SymbolicFunction< Ret(Arg1, Arg2)>::init
void init(Element::InitStage stage, const InitConfigSet &config) override
plots time series header
Definition: symbolic_function.h:91
MBSim
namespace MBSim
Definition: bilateral_constraint.cc:30