MBDyn-1.7.3
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups
module-FMU.cc
Go to the documentation of this file.
1 /* $Header: /var/cvs/mbdyn/mbdyn/mbdyn-1.0/modules/module-FMU/module-FMU.cc,v 1.3 2017/01/12 15:20:16 masarati Exp $ */
2 /*
3  * MBDyn (C) is a multibody analysis code.
4  * http://www.mbdyn.org
5  *
6  * Copyright (C) 1996-2017
7  *
8  * Pierangelo Masarati <masarati@aero.polimi.it>
9  * Paolo Mantegazza <mantegazza@aero.polimi.it>
10  *
11  * Dipartimento di Ingegneria Aerospaziale - Politecnico di Milano
12  * via La Masa, 34 - 20156 Milano, Italy
13  * http://www.aero.polimi.it
14  *
15  * Changing this copyright notice is forbidden.
16  *
17  * This program is free software; you can redistribute it and/or modify
18  * it under the terms of the GNU General Public License as published by
19  * the Free Software Foundation (version 2 of the License).
20  *
21  *
22  * This program is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25  * GNU General Public License for more details.
26  *
27  * You should have received a copy of the GNU General Public License
28  * along with this program; if not, write to the Free Software
29  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30  */
31 
32 /*
33  AUTHOR: Devyesh Tandon <devyeshtandon+mbdyn@gmail.com>
34  Copyright (C) 2016(-2017) all rights reserved.
35  The copyright of this patch is transferred
36  to Pierangelo Masarati and Paolo Mantegazza
37  for use in the software MBDyn as described
38  in the GNU Public License version 2.1
39 
40 */
41 
42 #include "module-FMU.h"
43 #include "solver.h"
44 
45 //#define DEBUG
46 
48  unsigned uLabel, const DofOwner *pDO,
49  DataManager* pDM, MBDynParser& HP)
50 : Elem(uLabel, flag(0)),
51 UserDefinedElem(uLabel, pDO),
52 pDM(pDM)
53 {
54 /* Reading from the input file */
55  if (HP.IsKeyWord("help")) {
56  silent_cout("help text here" << std::endl);
57 
58  if (!HP.IsArg()) {
59  throw NoErr(MBDYN_EXCEPT_ARGS);
60  }
61  }
62 
63  strcpy(FMUlocation, HP.GetStringWithDelims());
64 
65  std::string UClocation;
66  UClocation = UncompressLocation(FMUlocation);
67 
68  if(HP.IsKeyWord("type")){
69  simType = HP.GetString();
70  if (!strcmp(simType, "cosimulation")){
72  }
73  else if (!strcmp(simType, "import")){
75  }
76  else {
77  silent_cout("Unsupported Simulation Type. "
78  "Available options:\n"
79  "cosimulation\n"
80  "import model\n"
81  "Exiting...");
82  }
83  } else {
84  silent_cerr("keyword \"type\" expected");
86  }
87 
88  double relativeTolerance;
89  if(HP.IsKeyWord("tolerance")){
90  relativeTolerance = HP.GetReal();
91  } else {
92  relativeTolerance = 0.001;
93  }
94 
95  while(HP.IsStringWithDelims()){
96  const char* temp = HP.GetStringWithDelims();
97  drivesContainer[temp] = HP.GetDriveCaller();
98  }
99 
101 /* End of reading from input file */
102 
103  if(SIMTYPE == fmu::COSIM){
104  silent_cout("Model defined as co-simulation.\n");
105  } else if ( SIMTYPE == fmu::IMPORT ){
106  silent_cout("Model defined as import.\n");
107  }
108 
110 
112  status = fmi_zip_unzip(FMUlocation, UClocation.c_str(), &callbacks);
113 
114  if(status==jm_status_error){
115  silent_cerr("Failed to uncompress FMU. Exiting\n");
117  }
118  else
119  silent_cout("FMU uncompressed successfully \n");
120 
122  context = fmi_import_allocate_context(&callbacks);
123  version = fmi_import_get_fmi_version(context, FMUlocation, UClocation.c_str());
124 
125  if(version == 1){
126  model = new fmu1(context, SIMTYPE);
127  } else if (version == 2){
128  model = new fmu2(context, SIMTYPE);
129  }
130 
131  silent_cout("Version "<<version<<"\n");
132  model->parseXML(context, UClocation.c_str());
135 
136  currTime = pDM->dGetTime();
138  endTime = (pDM->GetSolver())->dGetFinalTime();
139 
141 
143 
144  if(SIMTYPE == fmu::IMPORT){
145 
146  double dTol = pDM->GetSolver()->dGetTolerance();
147  model->Initialize(dTol, currTime, relativeTolerance);
151  currState = new double[numOfContinousStates];
153 
154 
155  } else if (SIMTYPE == fmu::COSIM ) {
156 
157  model->InitializeAsSlave(UClocation.c_str(), initialTime, endTime);
158  silent_cout("Initialized as slave\n");
160 
161  }
162 
164  jacobianInputVector = new int[drivesContainer.size()];
165  privDriveLength = 0;
166  int k = 0;
167 
168  for (strDriveCon::iterator i = drivesContainer.begin(); i != drivesContainer.end(); i++){
169 
170  if(!(model->CheckInput(i->first))){
171  silent_cout("Variable "<<i->first<<" is not of type input\n");
172  delete i->second;
173  drivesContainer.erase(i->first);
174  } else {
175  if (dynamic_cast<const PrivDriveCaller*>(i->second) != NULL){
177  privDrivesIndex[privDriveLength] = dynamic_cast<const PrivDriveCaller*>(i->second);
178  privDriveLength ++;
179  }
180  k++;
181  }
182 
183  if (drivesContainer.size() == 0){
184  silent_cout("No FMU input was defined in input file. \n");
185  break;
186  }
187  }
188 
189  if ( directionalFlag){
191  }
192 
193 }
194 
196 {
197  delete model;
198 
199  if(directionalFlag){
200  delete[] seedVector;
201  }
202 
203  delete[] jacobianInputVector;
204 
206  delete[] currState;
207  delete[] stateDerivatives;
208  }
209 
210  for (strDriveCon::iterator i = drivesContainer.begin(); i != drivesContainer.end(); i++){
211  delete (i->second);
212  drivesContainer.erase(i);
213  }
214 }
215 
216 
217 void
219 {
220  if (bToBeOutput()) {
221  std::ostream& out = OH.Loadable();
222 
223  for(int i = 0; i < numOfContinousStates; ++i){
224  out << std::setw(4) << currState[i] << " ";
225  }
226 
227  out<<std::endl;
228  }
229 }
230 
231 
233 ModuleFMU::GetEqType(unsigned int i) const
234 {
235  return DofOrder::DIFFERENTIAL;
236 }
237 
238 
239 
240 void
241 ModuleFMU::WorkSpaceDim(integer* piNumRows, integer* piNumCols) const
242 {
243  if(SIMTYPE == fmu::IMPORT){
244  *piNumRows = numOfContinousStates;
245  *piNumCols = numOfContinousStates + privDriveLength;
246  } else {
247  *piNumCols = 0;
248  *piNumRows = 0;
249  }
250 }
251 
252 
255  doublereal dCoef,
256  const VectorHandler& XCurr,
257  const VectorHandler& XPrimeCurr)
258 {
259  WorkMat.SetNullMatrix();
260 #ifdef DEBUG
261  silent_cout(__func__);
262 #endif
263 
265  FullSubMatrixHandler &WM = WorkMat.SetFull();
266 
268  integer iFirstIndex = iGetFirstIndex();
269  {
270  int i = 1;
271  for ( i=1; i<=numOfContinousStates ; i++){
272  WM.PutRowIndex(i, iFirstIndex + i);
273  WM.PutColIndex(i, iFirstIndex + i);
274  }
275 
276  for (int j = 0; j <privDriveLength; j++){
277  WM.PutColIndex(i, privDrivesIndex[j]->iGetIndex()+1);
278  i++;
279  }
280  }
281 
282  if (directionalFlag){
283  FullMatrixHandler jacobian;
285  jacobian.Reset();
286 
287 
288  for (int i=0; i<numOfContinousStates; i++){
289  seedVector[i] = currState[i];
290  }
291 
292  for (int i=0; i<privDriveLength; i++){
294  }
295 
296  model->GetDirectionalDerivatives(&jacobian, jacobianInputVector, privDriveLength, seedVector);
297  for (int i=1; i<=numOfContinousStates; i++){
298  WM.IncCoef(i, i, 1);
299  for(int j=1; j<=numOfContinousStates; j++){
300  WM.IncCoef(i, j, -dCoef*jacobian.dGetCoef(i, j));
301  }
302 
303  for(int j=numOfContinousStates+1; j<=numOfContinousStates + privDriveLength; j++){
304  if(privDrivesIndex[j-numOfContinousStates]->iGetSE()->
305  GetDofType(privDrivesIndex[i-numOfContinousStates]->iGetIndex()+1)
307  WM.IncCoef(i, j, -dCoef*jacobian.dGetCoef(i, j));
308  else
309  WM.IncCoef(i, j, -jacobian.dGetCoef(i, j));
310  }
311  }
312 
313  } else {
314  for(int i=1; i<=numOfContinousStates; i++){
315  WM.IncCoef(i, i, 1.);
316  }
317  }
318  }
319 
320  return WorkMat;
321 }
322 
325  doublereal dCoef,
326  const VectorHandler& XCurr,
327  const VectorHandler& XPrimeCurr)
328 {
329 
330  WorkVec.ResizeReset(0);
331 #ifdef DEBUG
332  silent_cout(__func__);
333 #endif
334  for (strDriveCon::iterator i = drivesContainer.begin(); i != drivesContainer.end(); i++){
335  model->SetValuesByVariable(i->first, (i->second)->dGet());
336  }
337 
338  if(SIMTYPE == fmu::IMPORT){
340  if (currTime != pDM->dGetTime()){
341 
342  currTime = pDM->dGetTime();
343 
344  int iFirstIndex = iGetFirstIndex();
345 
346  //Get Current States
347  for (int i=0; i<numOfContinousStates; i++){
348  currState[i] = XCurr(iFirstIndex + i + 1);
349  }
350 
353 // model->CheckInterrupts(currTime);
354 
356  }
357 
358  //Get Index of the elements
359  integer iFirstIndex = iGetFirstIndex();
360 
361  //Set Index to WorkVec
362  for (int i=1; i<=numOfContinousStates; i++){
363  WorkVec.PutRowIndex(i, iFirstIndex + i);
364  }
365 
366  //Set WorkVec with the difference in the XPrimCurr - FMUDerivative
367  for (int i=1; i<=numOfContinousStates; i++){
368  WorkVec.PutCoef(i, (stateDerivatives[i-1] - XPrimeCurr(i + iFirstIndex)));
369  }
370  }
371 
372  if (SIMTYPE==fmu::COSIM){
374  }
375 
376  return WorkVec;
377 }
378 
379 unsigned int
381 {
382  return model->GetNumOfVar();
383 }
384 
385 unsigned int
386 ModuleFMU::iGetPrivDataIdx(const char *s) const
387 {
388  unsigned int idx = 0;
389 
390 #ifdef DEBUG
391  silent_cout(__func__);
392 #endif
393 
394  idx = model->GetRefValueFromString(s);
395  idx = idx + 1;
396 
397  return idx;
398 }
399 
401 ModuleFMU::dGetPrivData(unsigned int i) const
402 {
403  return model->GetStateFromRefValue(i-1);
404 }
405 
406 int
408 {
409  return 0;
410 }
411 
412 void
413 ModuleFMU::GetConnectedNodes(std::vector<const Node *>& connectedNodes) const
414 {
415  NO_OP;
416 }
417 
418 void
422 {
423 
424  if(SIMTYPE == fmu::IMPORT){
427  for (int i=0; i<numOfContinousStates; i++){
428  X(iGetFirstIndex() + i + 1) = currState[i];
429  XP(iGetFirstIndex() + i + 1) = stateDerivatives[i];
430  }
431  }
432 
433 }
434 
435 std::ostream&
436 ModuleFMU::Restart(std::ostream& out) const
437 {
438  return out << "# ModuleFMU: not implemented" << std::endl;
439 }
440 
441 unsigned int
443 {
444  if (SIMTYPE == fmu::IMPORT){
445  return numOfContinousStates;
446  }
447  // the only other possibility is fmu::COSIM, with 0 Dofs
448  return 0;
449 }
450 
452 ModuleFMU::GetDofType(unsigned int i) const
453 {
454  return DofOrder::DIFFERENTIAL;
455 }
456 
457 
458 unsigned int
460 {
461  return 0;
462 }
463 
464 void
466  integer* piNumRows,
467  integer* piNumCols) const
468 {
469  *piNumRows = 0;
470  *piNumCols = 0;
471 
472 }
473 
476  VariableSubMatrixHandler& WorkMat,
477  const VectorHandler& XCurr)
478 {
479  // should not be called, since initial workspace is empty
480  ASSERT(0);
481 
482  WorkMat.SetNullMatrix();
483 
484  return WorkMat;
485 }
486 
489  SubVectorHandler& WorkVec,
490  const VectorHandler& XCurr)
491 {
492  // should not be called, since initial workspace is empty
493  ASSERT(0);
494 
495  WorkVec.ResizeReset(0);
496 
497  return WorkVec;
498 }
499 
500 extern "C" int
501 module_init(const char *module_name, void *pdm, void *php)
502 {
504 
505  if (!SetUDE("FMU", rf1)) {
506  delete rf1;
507 
508  silent_cerr("ModuleFMU: "
509  "module_init(" << module_name << ") "
510  "failed" << std::endl);
511 
512  return -1;
513  }
514 
515  return 0;
516 }
517 
flag fReadOutput(MBDynParser &HP, const T &t) const
Definition: dataman.h:1064
Definition: mbdynFMI.h:115
void setup_callbacks(jm_callbacks *callbacks)
virtual int GetNumOfEventIndicators(void)=0
DofOrder::Order GetEqType(unsigned int i) const
Definition: module-FMU.cc:233
virtual unsigned int iGetInitialNumDof(void) const
Definition: module-FMU.cc:459
virtual void InitializeAsSlave(const char *, double, double)=0
virtual void SetValuesByVariable(const std::string, double)=0
void PutColIndex(integer iSubCol, integer iCol)
Definition: submat.h:325
virtual void GetStateDerivatives(double *)=0
double endTime
Definition: module-FMU.h:65
long int flag
Definition: mbdyn.h:43
virtual bool bToBeOutput(void) const
Definition: output.cc:890
#define MBDYN_EXCEPT_ARGS
Definition: except.h:63
double * seedVector
Definition: module-FMU.h:90
virtual void GetStates(double *)=0
virtual void ResizeReset(integer)
Definition: vh.cc:55
virtual void CSPropogate(double tcur, double dt)=0
SubVectorHandler & AssRes(SubVectorHandler &WorkVec, doublereal dCoef, const VectorHandler &XCurr, const VectorHandler &XPrimeCurr)
Definition: module-FMU.cc:324
FullSubMatrixHandler & SetFull(void)
Definition: submat.h:1168
DofOrder::Order GetDofType(unsigned int i) const
Definition: module-FMU.cc:452
doublereal dGetTime(void) const
Definition: dataman2.cc:165
fmu::SimulationTypes SIMTYPE
Definition: module-FMU.h:129
fmi_version_enu_t version
Definition: module-FMU.h:68
int numOfEventIndicators
Definition: module-FMU.h:79
virtual ~ModuleFMU(void)
Definition: module-FMU.cc:195
char FMUlocation[1000]
Definition: module-FMU.h:60
unsigned int iGetNumDof(void) const
Definition: module-FMU.cc:442
jm_callbacks callbacks
Definition: module-FMU.h:70
unsigned int iGetNumPrivData(void) const
Definition: module-FMU.cc:380
virtual void GetDirectionalDerivatives(FullMatrixHandler *, int *, int, double *)=0
ModuleFMU(unsigned uLabel, const DofOwner *pDO, DataManager *pDM, MBDynParser &HP)
Definition: module-FMU.cc:47
#define NO_OP
Definition: myassert.h:74
std::vector< Hint * > Hints
Definition: simentity.h:89
double timeStep
Definition: module-FMU.h:64
virtual void Resize(integer iNewRows, integer iNewCols)
Definition: fullmh.cc:174
double initialTime
Definition: module-FMU.h:63
void IncCoef(integer iRow, integer iCol, const doublereal &dCoef)
Definition: submat.h:683
virtual void EventIndicatorInit(void)=0
virtual void SetTime(double time)=0
virtual const doublereal & dGetCoef(integer iRow, integer iCol) const
Definition: fullmh.h:214
strDriveCon drivesContainer
Definition: module-FMU.h:75
DataManager * pDM
Definition: module-FMU.h:80
jm_status_enu_t status
Definition: module-FMU.h:71
virtual void PutRowIndex(integer iSubRow, integer iRow)=0
VariableSubMatrixHandler & AssJac(VariableSubMatrixHandler &WorkMat, doublereal dCoef, const VectorHandler &XCurr, const VectorHandler &XPrimeCurr)
Definition: module-FMU.cc:254
void GetConnectedNodes(std::vector< const Node * > &connectedNodes) const
Definition: module-FMU.cc:413
virtual bool SupportsDirectionalDerivatives()=0
doublereal dGetPrivData(unsigned int i) const
Definition: module-FMU.cc:401
std::string UncompressLocation(const char *location)
double * currState
Definition: module-FMU.h:83
unsigned int iGetPrivDataIdx(const char *s) const
Definition: module-FMU.cc:386
virtual void InitialWorkSpaceDim(integer *piNumRows, integer *piNumCols) const
Definition: module-FMU.cc:465
double currTime
Definition: module-FMU.h:62
virtual int GetRefValueFromString(const char *s)=0
void SetNullMatrix(void)
Definition: submat.h:1159
virtual bool IsKeyWord(const char *sKeyWord)
Definition: parser.cc:910
std::ostream & Loadable(void) const
Definition: output.h:506
virtual double GetStateFromRefValue(unsigned int i)=0
virtual const char * GetStringWithDelims(enum Delims Del=DEFAULTDELIM, bool escape=true)
Definition: parser.cc:1228
int iGetNumConnectedNodes(void) const
Definition: module-FMU.cc:407
jm_status_enu_t fmi_zip_unzip(const char *zip_file_path, const char *output_folder, jm_callbacks *callbacks)
Uncompress a zip file.
#define ASSERT(expression)
Definition: colamd.c:977
virtual void PutCoef(integer iRow, const doublereal &dCoef)=0
virtual void ImportCreateDLL(void)=0
virtual void ResizeReset(integer, integer)
Definition: submat.cc:182
Definition: except.h:79
fmu * model
Definition: module-FMU.h:59
SubVectorHandler & InitialAssRes(SubVectorHandler &WorkVec, const VectorHandler &XCurr)
Definition: module-FMU.cc:488
virtual void Initialize(double dTol, double time, double rTol)=0
virtual std::string GetString(const std::string &sDefVal)
Definition: parser.cc:1074
fmi_import_context_t * context
Definition: module-FMU.h:67
int numOfContinousStates
Definition: module-FMU.h:78
virtual bool IsArg(void)
Definition: parser.cc:807
Definition: elem.h:75
virtual bool IsStringWithDelims(enum Delims Del=DEFAULTDELIM)
Definition: parser.cc:1210
void PutRowIndex(integer iSubRow, integer iRow)
Definition: submat.h:311
int privDriveLength
Definition: module-FMU.h:87
intDriveCon privDrivesIndex
Definition: module-FMU.h:76
Definition: mbdynFMI.h:179
bool SetUDE(const std::string &s, UserDefinedElemRead *rude)
Definition: userelem.cc:97
virtual void Output(OutputHandler &OH) const
Definition: module-FMU.cc:218
std::ostream & Restart(std::ostream &out) const
Definition: module-FMU.cc:436
virtual void WorkSpaceDim(integer *piNumRows, integer *piNumCols) const
Definition: module-FMU.cc:241
const Solver * GetSolver(void) const
Definition: dataman.h:343
const char * simType
Definition: module-FMU.h:61
DriveCaller * GetDriveCaller(bool bDeferred=false)
Definition: mbpar.cc:2033
int module_init(const char *module_name, void *pdm, void *php)
This function registers our user defined element for the math parser.
Definition: module-FMU.cc:501
virtual bool CheckInput(const std::string)=0
virtual void SetOutputFlag(flag f=flag(1))
Definition: output.cc:896
virtual integer iGetFirstIndex(void) const
Definition: dofown.h:127
void SetValue(DataManager *pDM, VectorHandler &X, VectorHandler &XP, SimulationEntity::Hints *ph)
Definition: module-FMU.cc:419
virtual void parseXML(fmi_import_context_t *context, const char *dirPath)=0
VariableSubMatrixHandler & InitialAssJac(VariableSubMatrixHandler &WorkMat, const VectorHandler &XCurr)
Definition: module-FMU.cc:475
double doublereal
Definition: colamd.c:52
virtual void setCallBackFunction()=0
long int integer
Definition: colamd.c:51
virtual doublereal dGetInitialTimeStep(void) const
Definition: solver.h:417
virtual int GetNumOfVar(void)=0
virtual void SetStates(double *states)=0
virtual int GetNumOfContinousStates(void)=0
void Reset(void)
Definition: fullmh.cc:44
int * jacobianInputVector
Definition: module-FMU.h:85
bool directionalFlag
Definition: module-FMU.h:89
double * stateDerivatives
Definition: module-FMU.h:84
virtual doublereal GetReal(const doublereal &dDefval=0.0)
Definition: parser.cc:1056