mbsim 4.0.0 MBSim Kernel

bidirectional_function.h
1 /* Copyright (C) 2004-2016 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@gmail.com
18 */
19
20 #ifndef _BIDIRECTIONAL_FUNCTION_H_
21 #define _BIDIRECTIONAL_FUNCTION_H_
22
23 #include "mbsim/functions/function.h"
24 #include "mbsim/utils/utils.h"
25
26 namespace MBSim {
27
28 template<typename Sig> class BidirectionalFunction;
29
30 template<typename Ret, typename Arg>
31 class BidirectionalFunction<Ret(Arg)> : public Function<Ret(Arg)> {
32 using B = fmatvec::Function<Ret(Arg)>;
33 public:
34 BidirectionalFunction(Function<Ret(Arg)> *fn_=nullptr, Function<Ret(Arg)> *fp_=nullptr) : fn(fn_), fp(fp_) {
35 if(fn) fn->setParent(this);
36 if(fp) fp->setParent(this);
37 }
38 ~BidirectionalFunction() override {
39 delete fn;
40 delete fp;
41 }
42 int getArgSize() const override {
43 return fn->getArgSize();
44 }
45 std::pair<int, int> getRetSize() const override {
46 return fp->getRetSize();
47 }
48 Ret operator()(const Arg &x) override {
49 return (ToDouble<Arg>::cast(x)>=0)?(*fp)(x):(*fn)(-x);
50 }
51 typename B::DRetDArg parDer(const Arg &x) override {
52 return (ToDouble<Arg>::cast(x)>=0)?fp->parDer(x):fn->parDer(-x);
53 }
54 typename B::DRetDArg parDerDirDer(const Arg &xDir, const Arg &x) override {
55 return (ToDouble<Arg>::cast(x)>=0)?fp->parDerDirDer(xDir,x):fn->parDerDirDer(-xDir,-x);
56 }
57 void setNegativeDirectionalFunction(Function<Ret(Arg)> *fn_) {
58 fn = fn_;
59 fn->setParent(this);
60 fn->setName("NegativeDirectional");
61 }
62 void setPositiveDirectionalFunction(Function<Ret(Arg)> *fp_) {
63 fp = fp_;
64 fp->setParent(this);
65 fp->setName("PostiveDirectional");
66 }
67 void initializeUsingXML(xercesc::DOMElement *element) override {
68 xercesc::DOMElement *e;
69 e=MBXMLUtils::E(element)->getFirstElementChildNamed(MBSIM%"negativeDirectionalFunction");
70 setNegativeDirectionalFunction(ObjectFactory::createAndInit<Function<Ret(Arg)>>(e->getFirstElementChild()));
71 e=MBXMLUtils::E(element)->getFirstElementChildNamed(MBSIM%"positiveDirectionalFunction");
72 setPositiveDirectionalFunction(ObjectFactory::createAndInit<Function<Ret(Arg)>>(e->getFirstElementChild()));
73 }
74 void init(Element::InitStage stage, const InitConfigSet &config) override {
75 Function<Ret(Arg)>::init(stage, config);
76 fn->init(stage, config);
77 fp->init(stage, config);
78 }
79 private:
80 Function<Ret(Arg)> *fn, *fp;
81 };
82
83 }
84
85 #endif
MBSim::ObjectFactory::createAndInit
static ContainerType * createAndInit(const xercesc::DOMElement *element)
Definition: objectfactory.h:103
MBSim::ToDouble
Definition: utils.h:61
MBSim::Element::InitStage
InitStage
The stages of the initialization.
Definition: element.h:62
MBSim::Function
Definition: contact_kinematics.h:32
MBSim::BidirectionalFunction
Definition: bidirectional_function.h:28
MBSim
namespace MBSim
Definition: bilateral_constraint.cc:30
MBSim::BidirectionalFunction< Ret(Arg)>::init
void init(Element::InitStage stage, const InitConfigSet &config) override
plots time series header
Definition: bidirectional_function.h:74