1 /* Siconos is a program dedicated to modeling, simulation and control
2 * of non smooth dynamical systems.
3 *
4 * Copyright 2021 INRIA.
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18 #include "FirstOrderLinearR.hpp"
19 #include "Interaction.hpp"
20 #include "PluggedObject.hpp"
21 #include "SimpleMatrix.hpp"
22 #include "BlockVector.hpp"
23 #include "SimulationGraphs.hpp"
24 #include "SiconosAlgebraProd.hpp" // for matrix-vector prod
25
26 #include <iostream>
27
28 // #define DEBUG_NOCOLOR
29 // #define DEBUG_STDOUT
30 // #define DEBUG_MESSAGES
31 #include "siconos_debug.h"
32 using namespace RELATION;
33
FirstOrderLinearR()34 FirstOrderLinearR::FirstOrderLinearR():
35 FirstOrderR(LinearR)
36 {
37 ;
38 }
39
40 // Constructor with C and B plug-in names
FirstOrderLinearR(const std::string & Cname,const std::string & Bname)41 FirstOrderLinearR::FirstOrderLinearR(const std::string& Cname, const std::string& Bname):
42 FirstOrderR(LinearR)
43 {
44 // Warning: we cannot allocate memory for C/D matrix since no interaction
45 // is connected to the relation. This will be done during initialize.
46 // We only set the name of the plugin-function and connect it to the user-defined function.
47 _pluginJachx->setComputeFunction(Cname);
48 _pluginJacglambda->setComputeFunction(Bname);
49 }
50
51 // Constructor from a complete set of data (plugin)
FirstOrderLinearR(const std::string & Cname,const std::string & Dname,const std::string & Fname,const std::string & Ename,const std::string & Bname)52 FirstOrderLinearR::FirstOrderLinearR(const std::string& Cname, const std::string& Dname, const std::string& Fname, const std::string& Ename, const std::string& Bname): FirstOrderR(LinearR)
53 {
54 _pluginJachx->setComputeFunction(Cname);
55 _pluginJachlambda->setComputeFunction(Dname);
56 _pluginJacglambda->setComputeFunction(Bname);
57 _pluginf->setComputeFunction(Fname);
58 _plugine->setComputeFunction(Ename);
59 }
60
61 // Minimum data (C, B as pointers) constructor
FirstOrderLinearR(SP::SimpleMatrix C,SP::SimpleMatrix B)62 FirstOrderLinearR::FirstOrderLinearR(SP::SimpleMatrix C, SP::SimpleMatrix B):
63 FirstOrderR(LinearR)
64 {
65 _C = C;
66 _B = B;
67 }
68
69 // // Constructor from a complete set of data
FirstOrderLinearR(SP::SimpleMatrix C,SP::SimpleMatrix D,SP::SimpleMatrix F,SP::SiconosVector E,SP::SimpleMatrix B)70 FirstOrderLinearR::FirstOrderLinearR(SP::SimpleMatrix C, SP::SimpleMatrix D, SP::SimpleMatrix F, SP::SiconosVector E, SP::SimpleMatrix B):
71 FirstOrderR(LinearR)
72 {
73 _C = C;
74 _B = B;
75 _D = D;
76 _F = F;
77 _e = E;
78 }
79
initialize(Interaction & inter)80 void FirstOrderLinearR::initialize(Interaction& inter)
81 {
82
83 FirstOrderR::initialize(inter);
84
85 // get interesting size
86 unsigned int sizeY = inter.dimension();
87 unsigned int sizeX = inter.getSizeOfDS();
88
89 VectorOfBlockVectors& DSlink = inter.linkToDSVariables();
90 unsigned int sizeZ = DSlink[FirstOrderR::z]->size();
91 VectorOfSMatrices& relationMat = inter.relationMatrices();
92 VectorOfVectors & relationVec= inter.relationVectors();
93
94 if(!_C && _pluginJachx->fPtr)
95 relationMat[FirstOrderR::mat_C].reset(new SimpleMatrix(sizeY, sizeX));
96 if(!_D && _pluginJachlambda->fPtr)
97 relationMat[FirstOrderR::mat_D].reset(new SimpleMatrix(sizeY, sizeY));
98 if(!_B && _pluginJacglambda->fPtr)
99 relationMat[FirstOrderR::mat_B].reset(new SimpleMatrix(sizeX, sizeY));
100 if(!_F && _pluginf->fPtr)
101 relationMat[FirstOrderR::mat_F].reset(new SimpleMatrix(sizeY, sizeZ));
102 if(!_e && _plugine->fPtr)
103 relationVec[FirstOrderR::e].reset(new SiconosVector(sizeY));
104
105 checkSize(inter);
106 }
107
108
checkSize(Interaction & inter)109 void FirstOrderLinearR::checkSize(Interaction& inter)
110 {
111
112 VectorOfBlockVectors& DSlink = inter.linkToDSVariables();
113
114 // get interesting size
115 unsigned int sizeY = inter.dimension();
116 unsigned int sizeX = inter.getSizeOfDS();
117 unsigned int sizeZ = DSlink[FirstOrderR::z]->size();
118
119 // Check if various operators sizes are consistent.
120 // Reference: interaction.
121
122 if(_C)
123 {
124 if(_C->size(0) == 0)
125 _C->resize(sizeX, sizeY);
126 else
127 assert((_C->size(0) == sizeY && _C->size(1) == sizeX) && "FirstOrderLinearR::initialize , inconsistent size between C and Interaction.");
128 }
129 if(_B)
130 {
131 if(_B->size(0) == 0)
132 _B->resize(sizeY, sizeX);
133 else
134 assert((_B->size(1) == sizeY && _B->size(0) == sizeX) && "FirstOrderLinearR::initialize , inconsistent size between B and interaction.");
135 }
136 // C and B are the minimum inputs. The others may remain null.
137
138 if(_D)
139 {
140 if(_D->size(0) == 0)
141 _D->resize(sizeY, sizeY);
142 else
143 assert((_D->size(0) == sizeY || _D->size(1) == sizeY) && "FirstOrderLinearR::initialize , inconsistent size between C and D.");
144 }
145
146 if(_F)
147 {
148 if(_F->size(0) == 0)
149 _F->resize(sizeY, sizeZ);
150 else
151 assert(((_F->size(0) == sizeY) && (_F->size(1) == sizeZ)) && "FirstOrderLinearR::initialize , inconsistent size between C and F.");
152 }
153
154 if(_e)
155 {
156 if(_e->size() == 0)
157 _e->resize(sizeY);
158 else
159 assert(_e->size() == sizeY && "FirstOrderLinearR::initialize , inconsistent size between C and e.");
160 }
161 }
computeC(double time,BlockVector & z,SimpleMatrix & C)162 void FirstOrderLinearR::computeC(double time, BlockVector& z, SimpleMatrix& C)
163 {
164 if(_pluginJachx->fPtr)
165 {
166 auto zp = z.prepareVectorForPlugin();
167 ((FOMatPtr1)(_pluginJachx->fPtr))(time, C.size(0), C.size(1), &(C)(0, 0), zp->size(), &(*zp)(0));
168 z = *zp;
169 }
170 }
171
computeD(double time,BlockVector & z,SimpleMatrix & D)172 void FirstOrderLinearR::computeD(double time, BlockVector& z, SimpleMatrix& D)
173 {
174 if(_pluginJachlambda->fPtr)
175 {
176 auto zp = z.prepareVectorForPlugin();
177 ((FOMatPtr1)(_pluginJachlambda->fPtr))(time, D.size(0), D.size(1), &(D)(0, 0), zp->size(), &(*zp)(0));
178 z = *zp;
179 }
180 }
181
computeF(double time,BlockVector & z,SimpleMatrix & F)182 void FirstOrderLinearR::computeF(double time, BlockVector& z, SimpleMatrix& F)
183 {
184 if(_pluginf->fPtr)
185 {
186 auto zp = z.prepareVectorForPlugin();
187 ((FOMatPtr1)(_pluginf->fPtr))(time, F.size(0), F.size(1), &(F)(0, 0), zp->size(), &(*zp)(0));
188 z = *zp;
189 }
190 }
191
computee(double time,BlockVector & z,SiconosVector & e)192 void FirstOrderLinearR::computee(double time, BlockVector& z, SiconosVector& e)
193 {
194
195 if(_plugine->fPtr)
196 {
197 auto zp = z.prepareVectorForPlugin();
198 ((FOVecPtr) _plugine->fPtr)(time, e.size(), &(e)(0), zp->size(), &(*zp)(0));
199 z = *zp;
200 }
201 }
202
computeB(double time,BlockVector & z,SimpleMatrix & B)203 void FirstOrderLinearR::computeB(double time, BlockVector& z, SimpleMatrix& B)
204 {
205 if(_pluginJacglambda->fPtr)
206 {
207 auto zp = z.prepareVectorForPlugin();
208 ((FOMatPtr1) _pluginJacglambda->fPtr)(time, B.size(0), B.size(1), &(B)(0, 0), zp->size(), &(*zp)(0));
209 z = *zp;
210 }
211 }
212
computeh(double time,const BlockVector & x,const SiconosVector & lambda,BlockVector & z,SiconosVector & y)213 void FirstOrderLinearR::computeh(double time, const BlockVector& x, const SiconosVector& lambda,
214 BlockVector& z, SiconosVector& y)
215 {
216
217 y.zero();
218 if(_pluginJachx->fPtr)
219 {
220 if(!_C)
221 _C.reset(new SimpleMatrix(y.size(),x.size()));
222 computeC(time, z, *_C);
223 }
224 if(_pluginJachlambda->fPtr)
225 {
226 if(!_D)
227 _D.reset(new SimpleMatrix(y.size(),lambda.size()));
228 computeD(time, z, *_D);
229 }
230 if(_pluginf->fPtr)
231 {
232 if(!_F)
233 _F.reset(new SimpleMatrix(y.size(),z.size()));
234 computeF(time, z, *_F);
235 }
236 if(_plugine->fPtr)
237 {
238 if(!_e)
239 _e.reset(new SiconosVector(y.size()));
240 computee(time, z, *_e);
241 }
242
243 if(_C)
244 prod(*_C, x, y, false);
245
246 if(_D)
247 prod(*_D, lambda, y, false);
248
249 if(_e)
250 y += *_e;
251
252 if(_F)
253 prod(*_F, z, y, false);
254
255 }
256
computeOutput(double time,Interaction & inter,unsigned int level)257 void FirstOrderLinearR::computeOutput(double time, Interaction& inter, unsigned int level)
258 {
259 DEBUG_BEGIN("FirstOrderLinearR::computeOutput \n");
260 VectorOfBlockVectors& DSlink = inter.linkToDSVariables();
261 BlockVector& z = *DSlink[FirstOrderR::z];
262 BlockVector& x = *DSlink[FirstOrderR::x];
263
264 SiconosVector& y = *inter.y(level);
265 SiconosVector& lambda = *inter.lambda(level);
266
267 computeh(time, x, lambda, z, y);
268
269 DEBUG_END("FirstOrderLinearR::computeOutput \n");
270 }
271
computeg(double time,const SiconosVector & lambda,BlockVector & z,BlockVector & r)272 void FirstOrderLinearR::computeg(double time, const SiconosVector& lambda, BlockVector& z, BlockVector& r)
273 {
274 if(_pluginJacglambda->fPtr)
275 {
276 if(!_B)
277 _B.reset(new SimpleMatrix(r.size(),lambda.size()));
278 computeB(time, z, *_B);
279 }
280
281 prod(*_B, lambda, r, false);
282
283 }
284
285
computeInput(double time,Interaction & inter,unsigned int level)286 void FirstOrderLinearR::computeInput(double time, Interaction& inter, unsigned int level)
287 {
288
289
290 SiconosVector& lambda = *inter.lambda(level);
291 VectorOfBlockVectors& DSlink = inter.linkToDSVariables();
292 BlockVector& z = *DSlink[FirstOrderR::z];
293 computeg(time, lambda, z, *DSlink[FirstOrderR::r]);
294 }
295
296
display() const297 void FirstOrderLinearR::display() const
298 {
299 std::cout << " ===== Linear Time Invariant relation display ===== " <<std::endl;
300 std::cout << "| C " <<std::endl;
301 if(_C) _C->display();
302 else std::cout << "->nullptr" <<std::endl;
303 std::cout << "| D " <<std::endl;
304 if(_D) _D->display();
305 else std::cout << "->nullptr" <<std::endl;
306 std::cout << "| F " <<std::endl;
307 if(_F) _F->display();
308 else std::cout << "->nullptr" <<std::endl;
309 std::cout << "| e " <<std::endl;
310 if(_e) _e->display();
311 else std::cout << "->nullptr" <<std::endl;
312 std::cout << "| B " <<std::endl;
313 if(_B) _B->display();
314 else std::cout << "->nullptr" <<std::endl;
315 std::cout << " ================================================== " <<std::endl;
316 }
317