1 //#**************************************************************
2 //#
3 //# filename: mbs_communication.cpp
4 //#
5 //# author: Gerstmayr Johannes
6 //#
7 //# generated: March 2010
8 //# description: Load/Save mbs data, WCDriver and Windows communication
9 //#
10 //# remarks:
11 //#
12 //# Copyright (c) 2003-2013 Johannes Gerstmayr, Linz Center of Mechatronics GmbH, Austrian
13 //# Center of Competence in Mechatronics GmbH, Institute of Technical Mechanics at the
14 //# Johannes Kepler Universitaet Linz, Austria. All rights reserved.
15 //#
16 //# This file is part of HotInt.
17 //# HotInt is free software: you can redistribute it and/or modify it under the terms of
18 //# the HOTINT license. See folder 'licenses' for more details.
19 //#
20 //# bug reports are welcome!!!
21 //# WWW: www.hotint.org
22 //# email: bug_reports@hotint.org or support@hotint.org
23 //#***************************************************************************************
24
25 #include "windows.h" //for shell execute
26 #include <direct.h> //for getcwd
27 #include <io.h> //file operation _access
28 #include <stdio.h>
29 #include <stdlib.h>
30
31 #include "mbs.h"
32 #include "parser.h"
33 #include "script_parser.h"
34 #include "myfile.h"
35 #include "element.h"
36 #include "sensors.h"
37 #include "node.h"
38 #include "material.h"
39 #include "elementdataaccess.h"
40
41
SaveSolutionVector(const mystr & filename)42 int MultiBodySystem::SaveSolutionVector(const mystr& filename) //rv=1 --> OK
43 {
44 int opt = ios::out;
45
46
47 ofstream* storeout = new ofstream;
48 #ifdef my_new_stdiostream
49 storeout->open(filename.c_str(), opt); //with read sharing allowed!
50 #else
51 storeout->open(filename.c_str(), opt, filebuf::sh_read); //with read sharing allowed!
52 #endif
53
54 if ((int)storeout->good() == 0 || storeout->fail())
55 {
56 UO() << "ERROR: could not write solution!!!\n";
57 UO() << "good=" << storeout->good() << ", fail=" << storeout->fail() << "\n";
58 UO() << "file=" << filename.c_str() << "\n";
59
60 //storeout->close();
61 //storeout->delete;
62 //return 0;
63 }
64 storeout->precision(19);
65 int len = GetSolVector().Length();
66
67 char str[256];
68 sprintf(str, "HOTINTDataVersion%.3f", GetHotintVersion().GetDoubleValue());
69 (*storeout) << str << "\n";
70 (*storeout) << len << " 0" << "\n"; //checksums!
71 (*storeout) << "1\n"; //only one step stored
72
73 char strtime[64];
74 char strtime2[64];
75 sprintf(strtime, "%.14f", GetTime());
76 sprintf(strtime2, "%.17f", GetTime());
77
78 if (strlen(strtime) < strlen(strtime2)-4)
79 (*storeout) << strtime << "\n";
80 else
81 (*storeout) << strtime2 << "\n";
82
83 (*storeout) << len << "\n";
84 for (int i = 1; i <= len; i++)
85 {
86 (*storeout) << GetSol(i) << "\n";
87 }
88
89 storeout->close();
90 delete storeout;
91
92 return 1;
93 }
94
LoadInitialVector(const mystr & filename)95 int MultiBodySystem::LoadInitialVector(const mystr& filename) //rv=1 --> OK
96 {
97 CMFile storein(filename, TFMread);
98 Vector x0(GetSystemSize());
99
100 stored_initialconditions = GetSolVector();
101
102 if (!storein.IsGood())
103 {
104 UO() << "ERROR: could not open stored solution!!!\n";
105 return 0;
106 }
107 else
108 {
109 //storein->seekg(0,ios::beg);
110
111 //read either version or length:
112 mystr header;
113 storein.RWSoleStr(header);
114
115 if (header.Length() > 17 && header.Left(17) == mystr("HOTINTDataVersion"))
116 {
117 //UO() << "Load initial vector with header\n"; //--> e.g. stored in Data manager
118
119 mystr version_str = header.Right(header.Length()-17);
120 //UO() << "Version number ='" << version << "'\n";
121
122 HotintVersionInfo data_version(atof(version_str));
123
124 if (data_version > GetHotintVersion())
125 {
126 UO() << "Warning: This is a solution vector of another HOTINT version, the data may be corrupt!\n";
127 }
128
129 int ndof, checksum2, nsteps;
130 storein.RWInt(ndof);
131 storein.RWInt(checksum2);
132 storein.RWInt(nsteps);
133
134 if (ndof != x0.Length()) {UO() << "Warning: Stored solution does have different size!!!\n";}
135 if (nsteps != 1) {UO() << "Warning: Stored solution contains " << nsteps << " data units, only the first data unit is loaded!\n";}
136 }
137
138 double time;
139 int len;
140
141 storein.RWDouble(time);
142 storein.RWInt(len);
143
144 //UO() << "time=" << time << ", len=" << len << "\n";
145
146 if (len > x0.Length()) {UO() << "ERROR: Stored solution is incompatible!!!\n";}
147 else
148 {
149 for (int i=1; i <= len; i++) //additionally check for storein->good() ....???
150 {
151 storein.RWDouble(x0(i));
152 }
153 stored_initialconditions = x0;
154 //UO() << "WARNING: solution vector added!!!!!\n";
155
156 //UO() << "Stored solution loaded!\n";
157 }
158 }
159
160 return 1;
161 }
162
163
164 //type=1: element
165 //type=2: force i //$ DR 2012-10 old:force value of element i
166 //type=3: sensor i
167 //type=4: geomelement i
168 //type=5: node i
169 //type=6: material i
170 //type=50: KB options (old)
GetElementData(int i,int type,int value,ElementDataContainer & edc)171 void MultiBodySystem::GetElementData(int i, int type, int value, ElementDataContainer& edc)
172 {
173 switch (type)
174 {
175 case 1: //element data
176 {
177 GetElement(i).GetElementData(edc);
178 break;
179 }
180 case 2: //force value of element i, force value
181 {
182 //GetElement(i).GetLoad(value).GetElementData(edc); //$ DR 2012-10 old code
183 GetLoad(i).GetElementData(edc);
184 break;
185 }
186 case 3: //sensor i data
187 {
188 GetSensor(i).GetElementData(edc);
189 break;
190 }
191 case 4: //geomelement i data
192 {
193 GetDrawElement(i)->GetElementData(edc);
194 break;
195 }
196 case 5: //Node i data
197 {
198 GetNode(i).GetElementData(edc);
199 break;
200 }
201 case 6: //Material i data
202 {
203 GetMaterial(i).GetElementData(edc);
204 break;
205 }
206 default: ;
207 }
208 }
209
SetElementData(int i,int type,int value,ElementDataContainer & edc)210 int MultiBodySystem::SetElementData(int i, int type, int value, ElementDataContainer& edc)
211 {
212 int rv = 1;
213 switch (type)
214 {
215 case 1: //element data
216 {
217 rv = GetElement(i).SetElementData(edc);
218 break;
219 }
220 case 2: //force value of element i, force value
221 {
222 //rv = GetElement(i).GetLoad(value).SetElementData(edc); //$ DR 2012-10 old code
223 rv = GetLoad(i).SetElementData(edc);
224 break;
225 }
226 case 3: //sensor i data
227 {
228 rv = GetSensor(i).SetElementData(edc);
229 break;
230 }
231 case 4: //geomelement i data
232 {
233 rv = GetDrawElement(i)->SetElementData(edc);
234 break;
235 }
236 case 5: //Node i data
237 {
238 rv = GetNode(i).SetElementData(edc);
239 break;
240 }
241 case 6: //Node i data
242 {
243 rv = GetMaterial(i).SetElementData((ElementDataContainer &)edc);
244 break;
245 }
246 //#ifdef KB_INCLUDES
247 // case 50: //edit KB menu
248 // {
249 // kbmenu.SetElementData(edc);
250 // break;
251 // }
252 //#endif
253 default: ;
254 }
255 return rv;
256 }
257
258 //$AD 2013-07-08: Manipulate Content of arrays in IOElements from 2D Draw Window
InsertIOElemConNode(int elemnr,int list_idx,int input_nr,Vector2D pos)259 void MultiBodySystem::InsertIOElemConNode(int elemnr, int list_idx, int input_nr, Vector2D pos)
260 {
261 GetElement(elemnr).InsertConNode(list_idx, input_nr, pos);
262 }
DeleteIOElemConNode(int elemnr,int list_idx)263 void MultiBodySystem::DeleteIOElemConNode(int elemnr, int list_idx)
264 {
265 GetElement(elemnr).DeleteConNode(list_idx);
266 }
267 //$AD 2013-07-10: Change Position of a single element (MBS element, conNode, ...)
MoveConNode2D(int elemnr,int list_idx,double delta_x,double delta_y)268 void MultiBodySystem::MoveConNode2D(int elemnr, int list_idx, double delta_x, double delta_y)
269 {
270 GetElement(elemnr).MoveConNode2D(list_idx, delta_x, delta_y);
271 }
MoveElement(int elemnr,double delta_x,double delta_y,double delta_z)272 void MultiBodySystem::MoveElement(int elemnr, double delta_x, double delta_y, double delta_z)
273 {
274 GetElement(elemnr).MoveElement(delta_x, delta_y, delta_z);
275 }
276
277 //action=1: option=0: Set initial conditions, option=1: Initialize
278 //action=2: Add Element: deprecated
279 //action=3: Assemble system
280 //action=4: Delete Element value
281 //action=5: Delete force value
282 //action=6: Add force: deprecated
283 //action=7: Add sensor:: deprecated
284 //action=8: Delete sensor value
285 //action=9: Add GeomElement: deprecated
286 //action=10:Delete GeomElement value
287 //action=11: Add Node: deprecated
288 //action=12: Delete Node value
289 //action=13: Swap element: deprecated
290 //action=14: Add Material: deprecated
291 //action=15: Delete Material value
292
293 //action=20: ModelFunction: option=1: get ModelFunctionList
294 //
295 //action=30: Call Element functions in response to action in IOBlockView Window...
296
297 //action=101: save MBS system to file (file name in edc.Find("File_name")+directory, .GetText() (option=1: with Options, =0: only MBS)
298 //action=102: load MBS system from file (file name in edc.Find("File_name")+directory, .GetText()
299 //action=103: save actual solution vector (file name in edc.Find("File_name")+directory, .GetText()
300 //action=104: load initial solution vector (file name in edc.Find("File_name")+directory, .GetText()
301 //action=105: clear initial solution vector (setlen = 0 means initial solution is not used)
302 //action=106: LoadMBSEDCConfiguration
303 //action=107: SaveMBSEDCConfiguration; ; all:value==0, solver:value==1, hotint:value==2;
304 //
305 //action=110: Load EDC from file (file name in edc.Find("File_name")+directory, .GetText()
306 //action=111: Save EDC to file (file name in edc.Find("File_name")+directory, .GetText()
307 //action=112: The input-edc gets written into a mystr, the mystr is returned in the same edc
308 //
309 //action=121: plot single sensor value in matlab
310 //action=122: plot two sensors (x-y-plot) in matlab
311 //action=123: plot n sensors (vs time) in matlab
312 //
313 //action=201: GetNSensors()
314 //action=202: Get Element Names in edc-data
315 //action=203: Get Sensor Names in edc-data
316 // option 1: return writeresult flag as int element data
317 //action=204: Get Sensor value of sensor number 'value' in edc-data
318 //action=205: Get GeomElement Names in edc-data
319 //action=206: Get Number of nodes
320 //action=207: Get Name of nodes
321 //action=208: Get Number of total DOF
322 //action=209: Get Material Names in edc-data
323 //action=210: Get/Set EditAllOptions in edc-data Get:option==0, Set:option==1; all:value==0, solver:value==1, hotint:value==2;
324 //action=211: Get/Set Model ElementDataContainer
325 //action=212: SetOptions: Options2EDC/EDC2Options, etc.
326 //action=213: Get Sensors data array(reference), DataArray:option=0, TimesArray:option=1
327 //action=214: Get Load Names in edc-data //$ DR 2012-10
328 //
329 //action=301: Show System properties
330 //action=302: Check System properties
331
332 //action=320: Compute Eigenmodes (option=1: sparse, =0: direct)
333
CallCompFunction(int action,int option,int value,ElementDataContainer * edc)334 int MultiBodySystem::CallCompFunction(int action, int option, int value, ElementDataContainer* edc)
335 {
336 Vector3D defaultbodycol(0.2,0.2,0.8);
337 Vector3D defaultconstraintcol(0.2,0.8,0.2);
338 Vector3D defaultbodypos(0.,0.,0.);
339 Vector3D defaultbodyvel(0.,0.,0.);
340 Vector3D defaultbodyangle(0.,0.,0.);
341 Vector3D defaultbodyangularvel(0.,0.,0.);
342 Vector3D defaultbodysize(1.,1.,1.);
343 double defaultbodyrho = 1000;
344 Vector3D defaultconstraintdim(0.1,0.1,16.);
345
346 int defaultsensorvisible = 1;
347 SensorSignalStorageMode defaultSignalStorageMode = (SensorSignalStorageMode)(SSM_OwnFile | SSM_CommonFile);
348 int defaultsensorprecision = 17;
349 Vector3D defaultsensordrawdim(0.001,6,0);
350
351
352 //flexible bodies:
353 double defaultbodyEm = 1e8;
354 double defaultbodynu = 0.;
355
356 int rv = 1;
357 switch(action)
358 {
359 case 1: //Set initial conditions
360 {
361 if (option == 0)
362 SetInitialConditions();
363 else if (option == 1)
364 Initialize(); //this resets the whole MBS model
365
366 break;
367 }
368 case 2: //Add Element of type "value"
369 {
370 UO(UO_LVL_warn)<<"Warning: CallCompFunction: a deprecated function is called!";
371 break;
372 }
373 case 3: //Assemble system
374 {
375 Assemble();
376 break;
377 }
378 case 4: //Delete element "value"
379 {
380 if(value<=NE())
381 {
382 DeleteElement(value);
383 }
384 else
385 {
386 UO() << "Error: element " << value << " does not exist!!!\n";
387 }
388 break;
389 }
390 case 5: //Delete force "value"
391 {
392 if(value<=NLoads())
393 {
394 DeleteLoad(value);
395 }
396 else
397 {
398 UO() << "Error: load " << value << " does not exist!!!\n";
399 }
400 break;
401 }
402 case 6: //Add Force type "value"
403 {
404 UO(UO_LVL_warn)<<"Warning: CallCompFunction: a deprecated function is called!";
405 break;
406 }
407 case 7: //Add Sensor type "value"
408 {
409 UO(UO_LVL_warn)<<"Warning: CallCompFunction: a deprecated function is called!";
410 break; }
411 case 8: //Delete sensor "value"
412 {
413 if (value >= 1 && value <= this->NSensors())
414 {
415 DeleteSensor(value);
416 }
417 else
418 {
419 UO() << "Error: sensor " << value << " does not exist!!!\n";
420 }
421 break;
422 }
423 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
424 case 9: //Add GeomElement SensorTypeNameList above!!!
425 {
426 UO(UO_LVL_warn)<<"Warning: CallCompFunction: a deprecated function is called!";
427 break; }
428 case 10: //action: Delete GeomElement "value"
429 {
430 if (value >= 1 && value <= NDrawElements())
431 {
432 DeleteDrawElement(value);
433 }
434 else
435 {
436 UO() << "Error: geom element " << value << " does not exist!!!\n";
437 }
438 break;
439 }
440 case 11: //action: Add Node
441 {
442 UO(UO_LVL_warn)<<"Warning: CallCompFunction: a deprecated function is called!";
443 break;
444 }
445 case 12: //action: Delete Node "value"
446 {
447 if (value >= 1 && value <= NNodes())
448 {
449 DeleteNode(value); //delte this node and reorder node references in elements!
450 }
451 else
452 {
453 UO() << "Error: Node " << value << " does not exist!!!\n";
454 }
455 break;
456 }
457 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
458 case 13: //action: Swap element "value" with element "option"
459 {
460 UO(UO_LVL_warn)<<"Warning: CallCompFunction: a deprecated function is called!";
461 break; }
462
463 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
464 case 14: //action: Add Material
465 {
466 UO(UO_LVL_warn)<<"Warning: CallCompFunction: a deprecated function is called!";
467 break; }
468 case 15: //action: Delete Material "value"
469 {
470 if (value >= 1 && value <= NMaterials())
471 {
472 DeleteMaterial(value); //delete this material and reorder material numbers in elements!
473 }
474 else
475 {
476 UO() << "Error: Material " << value << " does not exist!!!\n";
477 }
478 break;
479 }
480 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
481 //action=20: ModelFunction: option=1: get ModelFunctionList
482 case 20: //action: Get ModelFunctionList
483 {
484 if (option == 1) //get ModelFunctionList
485 {
486 ElementData ed;
487 //$ YV 2013-01-04: model function index is now 1-based
488 for (int i=1; i <= GetModelsLibrary()->GetModelsCount(); i++)
489 {
490 ed.SetText(GetModelsLibrary()->GetModelInterface(i)->GetMBSModelName());
491 ed.SetToolTipText(GetModelsLibrary()->GetModelInterface(i)->GetMBSModelDescription());
492 edc->Add(ed);
493 }
494 //GetIOption(12) = GetModelFunctionsIndex0();
495 }
496 else if (option == 2) //ModelFunctionChanged
497 {
498 if (GetModelDataContainer()) {GetModelDataContainer()->Reset();} // DR hack
499 ModelFunctionChanged();
500 }
501 else if (option == 3) //Initialize
502 {
503 Initialize();
504 }
505 else if (option == 4) //get modelfunctionindex
506 {
507 ElementData ed;
508 ed.SetInt(GetModelFunctionsIndex0(),"model_function_index");
509 edc->Add(ed);
510 }
511 break;
512 }
513 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
514 case 30: //action: Call Element functions in response to action in IOBlockView Window...
515 {
516 int elnr = option;
517 Element& elem = GetElement(elnr);
518
519 if (value == 0)
520 {
521 if (GetElement(elnr).GetElementSpecification().Compare(mystr("IOMouseResponseElement")) )
522 rv = 1;
523 else
524 rv = 0;
525 }
526
527 // allow modifications 1 -> add 1, and -1 -> subtract 1
528 if (value == 1)
529 {
530 elem.Increase();
531 }
532 if (value == -1)
533 {
534 elem.Decrease();
535 }
536 break;
537 }
538 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
539 case 31: // action: call MBS-wide response to a Keyboard input
540 {
541 int key = option;
542 int nr_of_changes = RespondToKey(key);
543 rv = nr_of_changes;
544 break;
545 }
546 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
547 //load/save etc.
548 case 101: //save to file
549 {
550 mystr filename, dirname;
551 GetElemDataText(this, *edc, "File_name", filename);
552 GetElemDataText(this, *edc, "Directory_name", dirname); //include backslash --> dirname+filename==filepath
553
554 isloadsavemode = 1;
555 SaveToFile(dirname+filename,option);
556 isloadsavemode = 0;
557 break;
558 }
559 case 102: //load from file
560 {
561 mystr filename, dirname;
562 GetElemDataText(this, *edc, "File_name", filename);
563 GetElemDataText(this, *edc, "Directory_name", dirname); //include backslash --> dirname+filename==filepath
564
565 isloadsavemode = 1;
566 rv = LoadFromFile(dirname+filename);
567 isloadsavemode = 0;
568
569 break;
570 }
571 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
572 case 103: //save actual solution vector
573 {
574 mystr filename, dirname;
575 GetElemDataText(this, *edc, "File_name", filename);
576 GetElemDataText(this, *edc, "Directory_name", dirname); //include backslash --> dirname+filename==filepath
577
578 SaveSolutionVector(dirname+filename);
579 break;
580 }
581 case 104: //load initial solution vector
582 {
583 mystr filename, dirname;
584 GetElemDataText(this, *edc, "File_name", filename);
585 GetElemDataText(this, *edc, "Directory_name", dirname); //include backslash --> dirname+filename==filepath
586
587 LoadInitialVector(dirname+filename);
588 break;
589 }
590 case 105: //clear initial solution vector (setlen = 0 means initial solution is not used)
591 {
592 //UO() << "Stored initial vector cleared!\n";
593 stored_initialconditions.SetLen(0);
594 break;
595 }
596 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
597 case 106: //Load_MBS_EDC_config_file
598 {
599 mystr filename = "hotint_cfg.txt";
600 CMFile file(filename, TFMread);
601
602 //set default options, if file can not be loaded!
603 SetSolverDialogOptions();
604
605 SetOptions2EDCOptions();//copy numbered i/d/t options to EDC Tree to
606
607 OpenLogFile(0);
608
609 ElementDataContainer fileedc;
610
611 if (file.IsGood())
612 {
613 UO() << "load configuration file 'hotint_cfg.txt'\n";
614
615 mystr str;
616 file.RWF(str); //read file
617
618 // AD 2013-10-22 use new routine to parse
619 EDCParser().ParseAndExecuteString(str,fileedc);
620 // EDCParser().String2TreeEDC(/*this, */str, fileedc);
621
622 //$ DR 2013-03-18 for release version, do not use stored model name
623 if(!fileedc.TreeGetBool("GeneralOptions.Application.reload_last_model",0))
624 {
625 fileedc.TreeDelete("GeneralOptions.ModelFile.hotint_input_data_filename");
626 fileedc.TreeDelete("GeneralOptions.ModelFile.internal_model_function_name");
627 mystr tmp("");
628 fileedc.TreeSetString("GeneralOptions.ModelFile.hotint_input_data_filename", tmp.c_str());
629 tmp = mystr("new model");
630 fileedc.TreeSetString("GeneralOptions.ModelFile.internal_model_function_name", tmp.c_str());
631 }
632
633 //replace default option parameters with loaded parameters
634 GetMBS_EDC_Options()->TreeReplaceEDCDataWith(&fileedc);
635 }
636 else
637 {
638 UO() << "Warning: Could not read hotint configuration file 'hotint_cfg.txt'. Default values are used instead. Press 'Save Hotint Options' to create this file.\n";
639 rv = 0;
640 }
641
642 //at this point, use arguments of program start to add some functionality:
643 mystr modeldata_argstr = "";
644 mystr mbsedc_argstr = "";
645 int narg = __argc;
646
647 for (int i=0; i < narg; i++)
648 {
649 mystr argstr = __argv[i];
650 UO(UO_LVL_ext) << "hotint.exe argument " << i << "='" << argstr << "'";
651
652 //$ RL 2012-7-25:[
653 if(i == 0) // i==0 --> store application path
654 {
655 // get application path, (path of hotint.exe)
656 mystr app_path("");
657 {
658 int until;
659 for(until=argstr.Length()-1;until>=0;until--)
660 {
661 if(argstr.PosPeek(until) == '\\')
662 break; // until <=> last backslash
663 }
664 for(int i=0;i<=until;i++)
665 {
666 app_path += argstr.PosPeek(i); // path until last backslash
667 }
668 argstr = "GeneralOptions.Paths.application_path=\"" + app_path+ "\"";
669 }
670 }
671 else if(i == 1) // i==1 --> from drag&drop or command line
672 {
673 mystr hid_file("");
674 int pos = argstr.Find(mystr(".hid"));
675 if(pos == -1)
676 {
677 pos = argstr.Find(mystr(".hmc")); //$ DR 2012-12-10 this ending is also supported
678 }
679 if(pos == -1 && GetMBS_EDC_Options()->TreeGetBool("GeneralOptions.ModelFile.accept_txt_file_as_model_file",0))
680 {
681 pos = argstr.Find(mystr(".txt"));
682 }
683 if (pos != -1)
684 {
685 if(DoesFileExist(argstr) && argstr.Find(mystr("=")) == -1)
686 {
687 hid_file = argstr;
688 argstr = "GeneralOptions.ModelFile.hotint_input_data_filename=\"" + argstr+ "\"";
689 // get path of Hotint Input Data file
690 mystr path("");
691 {
692 int until;
693 for(until=hid_file.Length()-1;until>=0;until--)
694 {
695 if(hid_file.PosPeek(until) == '\\')
696 break; // until <=> last backslash
697 }
698 for(int i=0;i<=until;i++)
699 {
700 path += hid_file.PosPeek(i); // path until last backslash
701 }
702 GetMBS_EDC_Options()->TreeSetString("GeneralOptions.Paths.hotint_input_data_path", path.c_str());
703 }
704 }
705 }
706 }
707 //$ RL 2012-7-25:]
708
709 int pos = argstr.Find('=');
710 if (pos != -1)
711 {
712 mystr name = argstr.Left(pos);
713 //UO(UO_LVL_ext) << "name = '" << name << "'\n";
714 name.EraseSpaces(); //name anyway should not contain spaces ...
715
716 if (GetMBS_EDC_Options()->TreeFind(name))
717 {
718 UO(UO_LVL_ext) << " ... parsed to MBS_EDC_Option";
719 mbsedc_argstr += argstr + mystr("\n");
720 }
721 else
722 {
723 UO(UO_LVL_ext) << " ... parsed to ModelData";
724 modeldata_argstr += argstr + mystr("\n");
725 }
726 }
727 UO() << "\n";
728 } // end of for loop narg
729
730 if (mbsedc_argstr.Length() != 0)
731 {
732 UO() << "mbs-edc-argstring=" << mbsedc_argstr << "\n";
733 // AD 2013-10-22 use new routine to parse
734 EDCParser().ParseAndExecuteString(mbsedc_argstr,mbs_edc_args);
735 // EDCParser().String2TreeEDC(/*this, */mbsedc_argstr, mbs_edc_args);
736 GetMBS_EDC_Options()->TreeReplaceEDCDataWith(&mbs_edc_args);
737 }
738 if (modeldata_argstr.Length() != 0) //write information in to modeldata container ==> will not be overwritten later
739 {
740 // AD 2013-10-22 use new routine to parse
741 EDCParser().ParseAndExecuteString(modeldata_argstr,modeldata_edc_args);
742 // EDCParser().String2TreeEDC(/*this, */modeldata_argstr, modeldata_edc_args);
743
744 if (GetModelDataContainer())
745 {
746 GetModelDataContainer()->TreeReplaceEDCDataWith(&modeldata_edc_args);
747 }
748 else
749 {
750 SetModelDataContainer(modeldata_edc_args);
751 }
752 }
753
754 edc->CopyFrom(*GetMBS_EDC_Options()); //some options are written in configuration
755
756 SetEDCOptions2Options(); //copy EDC Tree to numbered i/d/t options for fast access
757 SetComputationSolverOptions(); //copy EDC Tree to MBSSolSet()
758
759 OpenLogFile(0);
760
761 break;
762 }
763 case 107: //Save_MBS_EDC_config_file
764 {
765 //!AD 2012-06-26: revised
766 //!AD 2012-04-17: solver options and hotint options can be stored separately - use autogenerated functions, changed names to better distinguish various EDCs
767 mystr filename = "hotint_cfg.txt";
768 CMFile file_read(filename, TFMread);
769
770 // read from current configuration file;
771 ElementDataContainer edc_configfile;
772 if (file_read.IsGood())
773 {
774 mystr str;
775 file_read.RWF(str);
776 // AD 2013-10-22 use new routine to parse
777 EDCParser().ParseAndExecuteString(str, edc_configfile);
778 // EDCParser().String2TreeEDC(/*this, */str, edc_configfile);
779 }
780 else
781 {
782 UO() << "Error: could not read hotint configuration file 'hotint_cfg.txt'\n";
783 }
784 // delete &file_read;
785
786
787 ////// actualize solver option part of the options edc //AD: revision
788 //// SetComputationSolverOptions(); // <-- wrong
789 //// SetOptions2EDCOptions();
790 SetSolverDialogOptions();
791 SetOptions2EDCOptions();
792
793 // pick the data that will be written to file
794 ElementDataContainer edc_tosave;
795 if(value == 1) // save solver options only
796 {
797 SolverOptions2EDC(&edc_tosave);
798 UO() << "save configuration file 'hotint_cfg.txt': solver options only\n";
799 }
800 else if(value == 2) // save hotint options only
801 {
802 Options2EDC(&edc_tosave);
803 UO() << "save configuration file 'hotint_cfg.txt': hotint options only\n";
804 }
805 else // rest of old code...
806 {
807 edc_tosave = *GetMBS_EDC_Options();
808 UO() << "save configuration file 'hotint_cfg.txt': all options\n";
809 }
810 // replace in the content of the config file
811 edc_configfile.TreeReplaceEDCDataWith(&edc_tosave);
812
813 //$ AD 2011-09: do not write ComputationSteps to the config file
814 RemoveVariableFromEDCTree(edc_configfile, mystr("SolverOptions.ComputationSteps"), 0);
815
816 // edc contains window placement etc...
817 if( value != 1 )
818 {
819 edc_configfile.TreeReplaceEDCDataWith(edc);
820 }
821
822 // write to configfile
823 CMFile file_write(filename, TFMwrite);
824
825 //UO() << "load arrow=" << edcnew.TreeGetDouble("PostProcOptions.Loads.arrow_size") << "\n";
826
827 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
828 //set some default values, which should not be loaded:
829 edc_configfile.TreeSetDouble("SolverOptions.start_time", 0.); //do not load any starttime except 0.
830 edc_configfile.TreeSetBool("ViewingOptions.Animation.animate_deformation", 0); //animate at startup
831 edc_configfile.TreeSetBool("ViewingOptions.Animation.RecordSingleFrames.record", 0); //do not record at beginning
832 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
833
834
835 mystr str;
836 EDCParser().EDC2String(edc_configfile, str);
837
838 if(UO().GetGlobalMessageLevel()==UO_LVL_dbg2) //$ DR 2011-09-15
839 {
840 UO(UO_LVL_dbg2) << str << "\n";
841 }
842 file_write.RW(mystr("%HOTINT configuration file 'hotint_cfg.txt'\n"));
843 file_write.RW(mystr("%handle this file with care, it can crash the startup of HOTINT\n"));
844 file_write.RW(mystr("%in case that nothing works anymore ==> delete this file ==> defaults will be created ==> save configuration ==> new 'hotint_cfg.txt' will be created\n"));
845 file_write.RW(mystr("%\n"));
846 file_write.RW(str);
847
848 break;
849 }
850
851 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
852 //Load and Save ANY EDC
853 //action=110: Load EDC from file (file name in edc.Find("File_name")+directory, .GetText()
854 case 110:
855 {
856 mystr filename = edc->TreeGetString("File_name");
857 mystr the_string;
858 edc->Reset();
859
860 File2Str(filename, the_string);
861 EDCParser().ParseAndExecuteString(the_string, *edc);
862 break;
863
864 //the_file.RWF(the_string);
865 //ElementDataContainer the_edc,testedc;
866 ////EDCParser().String2EDC(the_string, the_edc, testedc);
867
868 //EDCParser().String2TreeEDC(the_string, the_edc);
869 //edc->CopyFrom(the_edc);
870 //break;
871 }
872 //action=111: Save EDC to file (file name in edc.Find("File_name")+directory, .GetText()
873 case 111:
874 {
875 mystr filename = edc->TreeGetString("File_name");
876 edc->Delete(edc->Find("File_name"));
877 CMFile the_file(filename, TFMwrite);
878 mystr the_string;
879
880 EDCParser().EDC2String(*edc, the_string);
881 the_file.RW(the_string);
882 break;
883 }
884 //action=112: The input-edc gets written into a mystr, the mystr is returned in the same edc
885 case 112:
886 {
887 mystr clipboardtext;
888 EDCParser().EDC2String(*edc, clipboardtext, mystr(" "));
889
890 //edc = new ElementDataContainer;
891 ElementData ed;
892 ed.SetText(clipboardtext, "ClipBoardText");
893 edc->Add(ed);
894 break;
895 }
896 case 113: //$ DR 2013-06-12
897 {
898 mystr str = edc->TreeGetString("File_name");
899 int fromfile = edc->TreeGetInt("is_file");
900 AddModelData(str/*,fromfile*/);
901 break;
902 }
903 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
904 //plot in matlab
905 case 121: //plot sensor 'value' in matlab
906 {
907 if (GetSensor(value).GetSignalStorageMode() & SSM_OwnFile == 0) return 0;
908
909 UO().CallWCDriverFunction(4); //Set Programm directory as current
910
911 mystr dir = GetMBS_EDC_Options()->TreeGetString("GeneralOptions.Paths.sensor_output_path"); //GetTOption80);
912 //mystr filename = mystr("S")+mystr(GetSensor(value).GetSensorNumber())+mystr("-")+GetSensor(value).GetTypeName()+mystr(".txt");
913 mystr filename = mystr("S")+mystr(value)+mystr("-")+GetSensor(value).GetSensorName()+mystr(".txt");
914 mystr dir2 = dir.Left(dir.Length()-1); //without the '/' sign
915
916 ofstream plotfunc((dir+mystr("MBSplotfunc.m")).c_str());
917
918 char buffer[_MAX_PATH*4];
919
920 _getcwd( buffer, _MAX_PATH*4); //about 1000 characters ...
921 mystr oldpath = buffer;
922
923 _chdir(dir.c_str());
924 _getcwd( buffer, _MAX_PATH*4); //about 1000 characters ...
925 mystr path = buffer;
926
927 char str[1024];
928 //if (path[path.Length()-1] != '\\') path += '\\';
929
930 sprintf(str, "f1=load('%s');\n",(filename).c_str());
931 plotfunc << str;
932 plotfunc << "h=plot(f1(:,1),f1(:,2),'k');\n";
933
934 plotfunc << "title(' Y: " << GetSensor(value).GetSensorName() << "','Fontsize',16);\n";
935 plotfunc << "xlabel(' Time [s] ','Fontsize',16);\n";
936 //$ YV 2012-06: there is no type name for the sensors
937 //plotfunc << "ylabel('" << GetSensor(value).GetTypeName() << "','Fontsize',16);\n";
938 plotfunc << "set(h,'LineWidth',1.0);\n";
939 //plotfunc << "legend('" << GetSensor(value).GetTypeName() << "');\n";
940 plotfunc << "waitfor(h);\n"; //wait till window is closed
941 plotfunc << "exit;\n"; //exit instance of matlab; too many instances will need enormous memory and may crash system
942 plotfunc.close();
943 ShellExecute(NULL, "open", "matlab",
944 " -nosplash /r MBSplotfunc",
945 path.c_str(), SW_HIDE);
946 //path.c_str(), SW_SHOW);
947
948 _chdir(oldpath.c_str());
949
950 break;
951 }
952 case 122: //plot two sensors 'edc.xsensor' vs 'edc.ysensor' in matlab
953 {
954 int xsensor = edc->TreeGetInt("xsensor");
955 int ysensor = edc->TreeGetInt("ysensor");
956
957 if (GetSensor(xsensor).GetSignalStorageMode() & SSM_OwnFile == 0) return 0;
958 if (GetSensor(ysensor).GetSignalStorageMode() & SSM_OwnFile == 0) return 0;
959
960 UO().CallWCDriverFunction(4); //Set Programm directory as current
961
962 mystr dir = GetMBS_EDC_Options()->TreeGetString("GeneralOptions.Paths.sensor_output_path"); //GetTOption80);
963 mystr dir2 = dir.Left(dir.Length()-1); //without the '/' sign
964 mystr filename = mystr("S")+mystr(xsensor)+mystr("-")+GetSensor(xsensor).GetSensorName()+mystr(".txt");
965 mystr filename2 = mystr("S")+mystr(ysensor)+mystr("-")+GetSensor(ysensor).GetSensorName()+mystr(".txt");
966
967 ofstream plotfunc((dir+mystr("MBSplotfunc.m")).c_str());
968
969 char buffer[_MAX_PATH*4];
970
971 _getcwd( buffer, _MAX_PATH*4); //about 1000 characters ...
972 mystr oldpath = buffer;
973
974 _chdir(dir.c_str());
975 _getcwd( buffer, _MAX_PATH*4); //about 1000 characters ...
976 mystr path = buffer;
977
978 char str[1024];
979
980 sprintf(str, "f1=load('%s');\n",(filename).c_str());
981 plotfunc << str;
982 sprintf(str, "f2=load('%s');\n",(filename2).c_str());
983 plotfunc << str;
984 plotfunc << "h=plot(f1(:,2),f2(:,2),'k');\n";
985 plotfunc << "title({[' X: " << GetSensor(xsensor).GetSensorName() << " '];[' Y: " << GetSensor(ysensor).GetSensorName() << " ']},'Fontsize',16);\n";
986 //$ YV 2012-06: there is no type name for the sensors
987 //plotfunc << "xlabel('" << GetSensor(xsensor).GetTypeName() << "','Fontsize',16);\n";
988 //plotfunc << "ylabel('" << GetSensor(ysensor).GetTypeName() << "','Fontsize',16);\n";
989 plotfunc << "xlabel('" << GetSensor(xsensor).GetSensorName() << "','Fontsize',16);\n";
990 plotfunc << "ylabel('" << GetSensor(ysensor).GetSensorName() << "','Fontsize',16);\n";
991 plotfunc << "set(h,'LineWidth',1.0);\n";
992 plotfunc << "waitfor(h);\n"; //wait till window is closed
993 plotfunc << "exit;\n"; //exit instance of matlab; too many instances will need enormous memory and may crash system
994 plotfunc.close();
995 ShellExecute(NULL, "open", "matlab",
996 " -nosplash /r MBSplotfunc",
997 path.c_str(), SW_HIDE);
998 //path.c_str(), SW_SHOW);
999
1000 _chdir(oldpath.c_str());
1001
1002 break;
1003
1004 }
1005 case 123: //time plot of N sensors in matlab
1006 {
1007 if(option <=0)
1008 {
1009 return 0; //no sensors selected
1010 }
1011 TArray<int> ysensor;
1012 ysensor.SetLen(option);
1013
1014 for(int sensNr=1;sensNr<=option;sensNr++)
1015 {
1016 ysensor(sensNr) = edc->TreeGetInt("y"+mystr(sensNr)+"sensor");
1017 if (GetSensor(ysensor(sensNr)).GetSignalStorageMode() & SSM_OwnFile == 0) return 0;
1018 }
1019 UO().CallWCDriverFunction(4); //Set Programm directory as current
1020
1021 mystr dir = GetMBS_EDC_Options()->TreeGetString("GeneralOptions.Paths.sensor_output_path"); //GetTOption80);
1022 mystr dir2 = dir.Left(dir.Length()-1); //without the '/' sign
1023
1024
1025 ofstream plotfunc((dir+mystr("MBSplotfunc.m")).c_str());
1026
1027 char buffer[_MAX_PATH*4];
1028
1029 _getcwd( buffer, _MAX_PATH*4); //about 1000 characters ...
1030 mystr oldpath = buffer;
1031
1032 _chdir(dir.c_str());
1033 _getcwd( buffer, _MAX_PATH*4); //about 1000 characters ...
1034 mystr path = buffer;
1035
1036 char str[1024];
1037 plotfunc << "scrsz = get(0,'ScreenSize');\n";
1038 plotfunc << "fig = figure;\n";
1039 plotfunc << "set(fig,'Position',[1 (scrsz(4)/2-60) scrsz(3)*2/3 scrsz(4)/2]);\n";
1040 for(int sensNr=1;sensNr<=option;sensNr++)
1041 {
1042 mystr filename = mystr("S")+mystr(ysensor(sensNr))+mystr("-")+GetSensor(ysensor(sensNr)).GetSensorName()+mystr(".txt");
1043 sprintf(str, mystr("f") + mystr(sensNr) + +mystr("=load('%s');\n"),(filename).c_str());
1044 plotfunc << str;
1045 plotfunc << "h(" << sensNr << ")=plot(f" << sensNr << "(:,1),f" << sensNr << "(:,2),";
1046 if(sensNr==1){plotfunc << "'k'";}
1047 else if(sensNr==1){plotfunc << "'k'";}
1048 else if(sensNr==2){plotfunc << "'b'";}
1049 else if(sensNr==3){plotfunc << "'g'";}
1050 else if(sensNr==4){plotfunc << "'r'";}
1051 else if(sensNr==5){plotfunc << "'c'";}
1052 else if(sensNr==6){plotfunc << "'m'";}
1053 else if(sensNr==7){plotfunc << "'k--'";}
1054 else if(sensNr==8){plotfunc << "'b--'";}
1055 else {plotfunc << "'k'";}
1056 plotfunc << ",'linewidth',1);\n";
1057 plotfunc << "hold on;\n";
1058 }
1059 //plotfunc << "title({[' Y1: " << GetSensor(ysensor(1)).GetSensorName() << " ']";
1060 //for(int sensNr=2;sensNr<=option;sensNr++)
1061 //{
1062 // plotfunc << ";[' Y" << sensNr << ": " << GetSensor(ysensor(sensNr)).GetSensorName() << " ']";
1063 //}
1064 //plotfunc << "},'Fontsize',16);\n";
1065 int sameSensorType = 1;
1066 for(int sensNr=2;sensNr<=option;sensNr++)
1067 {
1068 if(!GetSensor(ysensor(sensNr-1)).GetTypeName().Compare(GetSensor(ysensor(sensNr)).GetTypeName()))
1069 {
1070 sameSensorType = 0;
1071 break;
1072 }
1073 }
1074 if(sameSensorType)
1075 {
1076 plotfunc << "ylabel('" << GetSensor(ysensor(1)).GetTypeName() << "','Fontsize',16);\n";// same type
1077 }
1078 else
1079 {
1080 plotfunc << "ylabel({['" << GetSensor(ysensor(1)).GetTypeName() << "']";
1081 for(int sensNr=2;sensNr<=option;sensNr++)
1082 {
1083 plotfunc << ";['" << GetSensor(ysensor(sensNr)).GetTypeName() << "']"; // different types
1084 }
1085 plotfunc << "},'Fontsize',16);\n"; //$ MS 2011-4-5
1086 }
1087
1088 plotfunc << "xlabel('time','Fontsize',16);\n";
1089 plotfunc << "legend('" << GetSensor(ysensor(1)).GetSensorName();
1090 for(int sensNr=2;sensNr<=option;sensNr++)
1091 {
1092 plotfunc << "','" << GetSensor(ysensor(sensNr)).GetSensorName();
1093 }
1094 plotfunc << "');\n";
1095 //plotfunc << "set(h,'LineWidth',1.0);\n";
1096 plotfunc << "waitfor(h(1));\n"; //wait till window is closed
1097 plotfunc << "exit;\n"; //exit instance of matlab; too many instances will need enormous memory and may crash system
1098 plotfunc.close();
1099 ShellExecute(NULL, "open", "matlab",
1100 " -nosplash /r MBSplotfunc",
1101 dir.c_str(), SW_HIDE);
1102 //path.c_str(), SW_HIDE);
1103 //path.c_str(), SW_SHOW);
1104
1105 _chdir(oldpath.c_str());
1106
1107 break;
1108
1109 }
1110 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1111 //information exchange, etc.
1112 case 201: //NSensors
1113 {
1114 return NSensors();
1115 break;
1116 }
1117 case 202: //Element names
1118 {
1119 for (int i=1; i <= NE(); i++)
1120 {
1121 int flag = 0; //add information on constraint, rigid, flexible, actuator, spring?
1122 ElementData ed;
1123 ed.SetInt(flag, GetElement(i).GetElementName().c_str()); edc->Add(ed);
1124 }
1125 break;
1126 }
1127 case 203: //Sensor names
1128 {
1129 for (int i=1; i <= NSensors(); i++)
1130 {
1131 int flag = 0; //add information on type?
1132 if(value==1)
1133 {
1134 flag = GetSensor(i).GetSignalStorageMode() != SSM_None; // write result data
1135 }
1136 ElementData ed;
1137 //$ YV 2012-06: display names do not seem to be actually used
1138 /*
1139 if(option ==1) // return the displaynames (plottool caption)
1140 {
1141 ed.SetInt(flag, GetSensor(i).GetDisplayName().c_str()); edc->Add(ed);
1142 }
1143 else //if(option==0) // return sensornames
1144 {
1145 ed.SetInt(flag, GetSensor(i).GetSensorName().c_str()); edc->Add(ed);
1146 }
1147 */
1148 ed.SetInt(flag, GetSensor(i).GetSensorName().c_str()); edc->Add(ed);
1149 }
1150 break;
1151 }
1152 case 204: //Sensor value
1153 {
1154 ElementData ed;
1155 if(option==1) // return time & all system values
1156 {
1157 Vector v(1+NSensors());
1158 v[0] = GetTime();
1159 for(int i=1; i <= NSensors(); i++)
1160 {
1161 v[i] = GetSensor(i).GetLastValue();
1162 }
1163 ed.SetVector(v.GetVecPtr(),v.GetLen(),"values");
1164 edc->Add(ed);
1165 }
1166 else //if(option==0) // return single value from sensor #value
1167 {
1168 double v = GetSensor(value).GetLastValue();
1169 ed.SetDouble(v, "value"); edc->Add(ed);
1170 }
1171 break;
1172 }
1173 case 205: //GeomElement names //MBS: DrawElement == GeomElement
1174 {
1175 for (int i=1; i <= NDrawElements(); i++)
1176 {
1177 int flag = 0; //add information on type?
1178 ElementData ed;
1179 ed.SetInt(flag, GetDrawElement(i)->GetName().c_str()); edc->Add(ed);
1180 }
1181 break;
1182 }
1183 case 206: //NNodes
1184 {
1185 return NNodes();
1186 break;
1187 }
1188 case 207: //Nodes names
1189 {
1190 for (int i=1; i <= NNodes(); i++)
1191 {
1192 int flag = 0; //add information on type?
1193 ElementData ed;
1194 ed.SetInt(flag, (GetNode(i).GetObjectName()+mystr("-")+mystr(GetNode(i).SOS())+("DOF")).c_str()); edc->Add(ed);
1195 }
1196 break;
1197 }
1198 case 208: //N initial values
1199 {
1200 int ss = GetSystemSize();
1201 return ss;
1202 break;
1203 }
1204 case 209: //Material names
1205 {
1206 for (int i=1; i <= NMaterials(); i++)
1207 {
1208 int flag = 0; //add information on type?
1209 ElementData ed;
1210 //ed.SetInt(flag, (GetMaterial(i).GetMaterialName()+mystr("-")+mystr(GetMaterial(i).GetTypeSpec())).c_str()); edc->Add(ed);
1211 ed.SetInt(flag, (GetMaterial(i).GetMaterialName()).c_str()); edc->Add(ed); //$ DR 2013-01-21 change for script language
1212 }
1213 break;
1214 }
1215 case 210: //EditAllOptions
1216 //!AD: revised 2012-07-26
1217 {
1218 if (option==0) //Get all mbs_edc_options and mbssolset into edc
1219 {
1220 edc->Reset();
1221
1222 if(value == 1) // save solver options only
1223 {
1224 SolverOptions2EDC(edc);
1225 }
1226 else if(value == 2) // save hotint options only
1227 {
1228 Options2EDC(edc);
1229 }
1230 else if(value == 0) // entire edc - currently no dialog active for all options
1231 {
1232 SetOptions2EDCOptions();//copy numbered i/d/t options to EDC Tree options ==> this is because old dialogs modify the i/d/toptions //JG
1233 edc->CopyFrom(*GetMBS_EDC_Options());
1234 }
1235
1236 ////--------------------------------------------
1237 ////RL:b
1238 //ElementDataContainer edcnew;
1239 ////copy mbssolset to edc:
1240 //Options2EDC(&edcnew);
1241 ////replace edcnew data in edc:
1242 //edc->TreeReplaceEDCDataWith(&edcnew);
1243 ////RL:e
1244 ////--------------------------------------------
1245 }
1246 else if (option==1) //Write modified edc-data to mbs_edc_options
1247 {
1248 GetMBS_EDC_Options()->TreeReplaceEDCDataWith(edc); // overwrite MBS-EDC first
1249
1250 if(value == 1) // update solver options only
1251 {
1252 SetComputationSolverOptions();
1253 }
1254 else if(value == 2) // update hotint options only
1255 {
1256 SetEDCOptions2Options();
1257 }
1258 else if(value == 0) // update entire edc - currently no dialog active for all options
1259 {
1260 SetComputationSolverOptions();
1261 SetEDCOptions2Options();
1262 }
1263
1264 //==>this must always be done, otherwise the EDC options are overwritten by other functions!!!!
1265 //<<<<<<< mbs_communication.cpp
1266 //
1267 // //$ JG: instantly change log values:
1268 // MBSSolSet().nls_log_rel_error_goal = edc->TreeGetInt("SolverOptions.Newton.Log.rel_error_goal");
1269 // MBSSolSet().nls_log_jacobian_update_info = edc->TreeGetInt("SolverOptions.Newton.Log.jacobian_update_info");
1270 // MBSSolSet().nls_log_contractivity = edc->TreeGetInt("SolverOptions.Newton.Log.contractivity");
1271 // MBSSolSet().nls_log_iteration_error = edc->TreeGetInt("SolverOptions.Newton.Log.iteration_error");
1272 // MBSSolSet().nls_log_solution_vector = edc->TreeGetInt("SolverOptions.Newton.Log.solution_vector");
1273 // MBSSolSet().nls_log_jacobian = edc->TreeGetInt("SolverOptions.Newton.Log.jacobian");
1274 //
1275 // MBSSolSet().output_level = edc->TreeGetInt("SolverOptions.Log.output_level");
1276 // MBSSolSet().outprec_double = edc->TreeGetInt("SolverOptions.Log.output_precision_double");
1277 // MBSSolSet().outprec_vector = edc->TreeGetInt("SolverOptions.Log.output_precision_vector");
1278 // MBSSolSet().outprec_matrix = edc->TreeGetInt("SolverOptions.Log.output_precision_matrix");
1279 // MBSSolSet().max_errors = edc->TreeGetInt("SolverOptions.Log.max_error_messages");
1280 // MBSSolSet().max_warnings = edc->TreeGetInt("SolverOptions.Log.max_warning_messages");
1281 // MBSSolSet().log_detailed_comp_output = edc->TreeGetInt("SolverOptions.Log.detailed_computation_output");
1282 // MBSSolSet().comp_output_every_x_sec = edc->TreeGetDouble("SolverOptions.Log.computation_output_every_x_sec");
1283 // MBSSolSet().write_MK2file = edc->TreeGetInt("SolverOptions.Log.write_mass_and_stiffness_matrix");
1284 //
1285 // MBSSolSet().withgraphics = edc->TreeGetDouble("SolverOptions.Misc.with_graphics");
1286 //=======
1287
1288 OpenLogFile(1);
1289 }
1290
1291 break;
1292 }
1293 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1294 case 211: //Model Data
1295 {
1296 if (option==0 && GetModelDataContainer() != 0) //Get Data in EDC
1297 {
1298 edc->Reset();
1299 edc->CopyFrom(*GetModelDataContainer());
1300 }
1301 else if (option==1) //Set Data in EDC
1302 {
1303 if (!GetModelDataContainer()) //generate empty modeldatacontainer
1304 {
1305 ElementDataContainer edcnew;
1306 SetModelDataContainer(edcnew);
1307 }
1308 else
1309 {
1310 GetModelDataContainer()->Reset();
1311 }
1312 GetModelDataContainer()->CopyFrom(*edc);
1313 }
1314 else if (option==2) //Load Model Data
1315 {
1316 }
1317 else if (option==3) //Save Model Data
1318 {
1319 ElementDataContainer* medc = GetModelDataContainer();
1320 mystr filestr;
1321 EDCParser().EDC2String(*medc, filestr);
1322
1323 {
1324 mystr filename = GetTOption( 88); //directory+filename
1325 int opt = ios::out;
1326
1327
1328 ofstream* storeout = new ofstream;
1329 #ifdef my_new_stdiostream
1330 storeout->open(filename.c_str(), opt); //with read sharing allowed!
1331 #else
1332 storeout->open(filename.c_str(), opt, filebuf::sh_read); //with read sharing allowed!
1333 #endif
1334
1335 if ((int)storeout->good() == 0 || storeout->fail())
1336 {
1337 UO() << "ERROR: could not write model data!!!\n";
1338 UO() << "good=" << storeout->good() << ", fail=" << storeout->fail() << "\n";
1339 UO() << "file=" << filename.c_str() << "\n";
1340 }
1341 else
1342 {
1343 (*storeout) << filestr.c_str() << "\n";
1344 }
1345
1346 storeout->close();
1347 delete storeout;
1348
1349 }
1350 }
1351
1352 break;
1353 }
1354 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1355 case 212: //SetOptions
1356 {
1357 if (option==1)
1358 {
1359 SetOptions2EDCOptions();//copy numbered i/d/t options to EDC Tree options
1360 }
1361 else if (option==2)
1362 {
1363 SetEDCOptions2Options();//copy EDC Tree options to numbered i/d/t options
1364 }
1365 break;
1366 }
1367 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1368 case 214: //Load names
1369 {
1370 for (int i=1; i <= NLoads(); i++)
1371 {
1372 int flag = 0; //add information on type?
1373 ElementData ed;
1374 ed.SetInt(flag, GetLoad(i).LoadName().c_str()); edc->Add(ed);
1375 }
1376 break;
1377 }
1378
1379 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1380 case 301: //Compute system information
1381 {
1382 int rs = GetResortSize();
1383 int sos = GetSecondOrderSize();
1384 //int sos_rs = GetSecondOrderSize_RS();
1385 int es = GetFirstOrderSize();
1386 int is = GetImplicitSize();
1387 int ss = GetSystemSize();
1388
1389 int nbodies=0;
1390 int njoints=0;
1391 for (int i=1; i <= NE(); i++)
1392 {
1393 if (GetElement(i).IsType(TBody)) nbodies++;
1394 else njoints++;
1395 }
1396
1397 UO() << "++++++++++++++++++++++++++++++++++\n";
1398 UO() << "System properties:\n";
1399 UO() << "2nd order ODE=" << sos << " (sos)\n";
1400 UO() << "Algebraic Equ=" << is << " (is)\n";
1401 UO() << "1st order ODE=" << es << " (es)\n";
1402 UO() << "number of initial values=" << ss << " (=2*sos+es+is)\n";
1403 UO() << "Resorted equ =" << rs << "\n";
1404 UO() << "N. of bodies=" << nbodies << "\n";
1405 UO() << "N. of joints=" << njoints << "\n";
1406
1407 UO() << "++++++++++++++++++++++++++++++++++\n";
1408 break;
1409 }
1410 case 302: //check system; rv==0 --> OK, rv==1 --> can not compute, rv==2 --> can not draw and not compute
1411 {
1412 rv = CheckSystemConsistency();
1413 break;
1414 }
1415
1416 case 320:
1417 {
1418 rv = ComputeEigenmodes();
1419 break;
1420 }
1421 default: ;
1422 }
1423
1424 return rv;
1425 }
1426
1427 //$ DR 2012-11-29 new code according to skript-language
SaveToFile(mystr filename,int save_options)1428 void MultiBodySystem::SaveToFile(mystr filename,int save_options)
1429 {
1430 mystr el = "\n"; //end of line
1431 mystr ob = "{"; //open bracket
1432 mystr cb = "}"; //closing bracket
1433 mystr ds = ": "; //double stop
1434 mystr eq = "= "; //equal sign
1435
1436 ofstream of(filename.c_str());
1437
1438 //++++++++++++++++
1439 //header:
1440 char str[32];
1441 /*sprintf(str, "%0.3f\n\n", HOTINT_version_info);*/
1442
1443 _SYSTEMTIME time;
1444 GetSystemTime(&time);
1445
1446 // do not use HOTINT_data_file_version in header
1447 mystr header = "";
1448
1449 header += mystr("%======================================================================\n");
1450 header += mystr("% HOTINT model \n");
1451 header += mystr("%\n");
1452 header += mystr("% model name: ") + mystr(MBS_EDC_TreeGetString("GeneralOptions.ModelFile.internal_model_function_name")) + mystr("\n");
1453 header += mystr("%\n");
1454 header += mystr("% saved on: ")+mystr(time.wDay)+mystr(".")+mystr(time.wMonth)+mystr(".")+mystr(time.wYear)+mystr(" at ")+mystr(time.wHour)+mystr(":")+mystr(time.wMinute)+mystr("\n");
1455 header += mystr("%======================================================================\n");
1456 header +=mystr("HOTINT_data_file_version = \"")+mystr(GetHotintVersion().GetString())+mystr("\" % version of HOTINT, that has been used to generate this file \n\n");
1457
1458 of << header;
1459
1460 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1461 // Check if the mbs can be saved at all
1462 bool error = 0;
1463
1464 if(error)
1465 {
1466 UO() << "Writing of output file aborted due to the error(s) above! \n";
1467 of << "% Writing of output file aborted, because nodes are not available for skript language.";
1468 of.close();
1469 return;
1470 }
1471
1472 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1473 //materials:
1474 for (int i=1; i<=NMaterials(); i++)
1475 {
1476 mystr otext = "";
1477 ElementDataContainer edc;
1478 Material& m = GetMaterial(i);
1479 m.GetElementData(edc);
1480
1481 otext += "Material" + mystr(i);
1482 otext += el + ob + el; // open bracket
1483
1484 mystr str;
1485 EDCParser().EDC2String(edc, str, " ");
1486 otext += str; // element data
1487 otext += cb + el; // close bracket
1488
1489 if(m.GetType() & TMatBeam)
1490 {
1491 otext += "AddBeamProperties(Material" +mystr(i)+ ")" + el +el;
1492 }
1493 else
1494 {
1495 otext += "AddMaterial(Material" +mystr(i)+ ")" + el +el;
1496 }
1497
1498 of << otext; // write the string to file
1499 }
1500
1501 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1502 // nodes:
1503 for (int i=1; i<=NNodes(); i++)
1504 {
1505 mystr otext = "";
1506 ElementDataContainer edc;
1507 Node& m = GetNode(i);
1508 m.GetElementData(edc);
1509
1510 otext += "Node" + mystr(i);
1511 otext += el + ob + el; // open bracket
1512
1513 mystr str;
1514 EDCParser().EDC2String(edc, str, " ");
1515 otext += str; // element data
1516 otext += cb + el; // close bracket
1517 otext += "AddNode(Node" +mystr(i)+ ")" + el +el;
1518
1519 of << otext; // write the string to file
1520 }
1521
1522 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1523 //elements:
1524 for (int i=1; i<=NE(); i++)
1525 {
1526 mystr otext = "";
1527 ElementDataContainer edc;
1528 Element& e = GetElement(i);
1529 e.GetElementData(edc);
1530
1531 otext += "Element" + mystr(i);
1532 otext += el + ob + el; // open bracket
1533
1534 mystr str;
1535 EDCParser().EDC2String(edc, str, " ");
1536 otext += str; // element data
1537 otext += cb + el; // close bracket
1538
1539 if (e.IsType(TConstraint) && !e.IsType(TController))
1540 {
1541 otext += "AddConnector(Element" +mystr(i)+ ")" + el +el; // add the element
1542 }
1543 else
1544 {
1545 otext += "AddElement(Element" +mystr(i)+ ")" + el +el; // add the element
1546 }
1547 of << otext; // write the string to file
1548 }
1549
1550 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1551 //loads:
1552 for (int i=1; i<=NLoads(); i++)
1553 {
1554 mystr otext = "";
1555 ElementDataContainer edc;
1556 MBSLoad& l = GetLoad(i);
1557 l.GetElementData(edc);
1558
1559 otext += "Load" + mystr(i);
1560 otext += el + ob + el; // open bracket
1561
1562 mystr str;
1563 EDCParser().EDC2String(edc, str, " ");
1564 otext += str; // element data
1565 otext += cb + el; // close bracket
1566 otext += "AddLoad(Load" +mystr(i)+ ")" + el +el; // add the element
1567 of << otext; // write the string to file
1568 }
1569
1570 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1571 //sensors:
1572 for (int i=1; i<=NSensors(); i++)
1573 {
1574 mystr otext = "";
1575 ElementDataContainer edc;
1576 Sensor& s = GetSensor(i);
1577 s.GetElementData(edc);
1578
1579 otext += "Sensor" + mystr(i);
1580 otext += el + ob + el; // open bracket
1581
1582 mystr str;
1583 EDCParser().EDC2String(edc, str, " ");
1584 otext += str; // element data
1585 otext += cb + el; // close bracket
1586 otext += "AddSensor(Sensor" +mystr(i)+ ")" + el +el; // add the element
1587 of << otext; // write the string to file
1588 }
1589
1590 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1591 // GeomElements:
1592 for (int i=1; i<=NDrawElements(); i++)
1593 {
1594 mystr otext = "";
1595 ElementDataContainer edc;
1596 GeomElement *e = GetDrawElement(i);
1597 e->GetElementData(edc);
1598
1599 otext += "GeomElement" + mystr(i);
1600 otext += el + ob + el; // open bracket
1601
1602 mystr str;
1603 EDCParser().EDC2String(edc, str, " ");
1604 otext += str; // element data
1605 otext += cb + el; // close bracket
1606
1607 otext += "AddGeomElement(GeomElement" +mystr(i)+ ")" + el +el; // add the element
1608
1609 of << otext; // write the string to file
1610 }
1611
1612 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1613 //options:
1614 if(save_options)
1615 {
1616 ElementDataContainer edc;
1617
1618 //SolverOptions2EDC(edc); // save solver options only
1619 //Options2EDC(edc); // save hotint options only
1620
1621 // entire edc - currently no dialog active for all options
1622 SetOptions2EDCOptions();//copy numbered i/d/t options to EDC Tree options ==> this is because old dialogs modify the i/d/toptions //JG
1623 edc.CopyFrom(*GetMBS_EDC_Options());
1624
1625 ////+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1626 ////set some default values, which should not be loaded:
1627 //edc_configfile.TreeSetDouble("SolverOptions.start_time", 0.); //do not load any starttime except 0.
1628 //edc_configfile.TreeSetBool("ViewingOptions.Animation.animate_deformation", 0); //animate at startup
1629 //edc_configfile.TreeSetBool("ViewingOptions.Animation.RecordSingleFrames.record", 0); //do not record at beginning
1630 ////+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1631
1632 edc.TreeDelete("GeneralOptions.ModelFile.hotint_input_data_filename");
1633 edc.TreeDelete("GeneralOptions.ModelFile.internal_model_function_name");
1634 edc.TreeDelete("GeneralOptions.ModelFile.recent_file1");
1635 edc.TreeDelete("GeneralOptions.ModelFile.recent_file2");
1636 edc.TreeDelete("GeneralOptions.ModelFile.recent_file3");
1637 edc.TreeDelete("GeneralOptions.ModelFile.recent_file4");
1638 edc.TreeDelete("GeneralOptions.ModelFile.recent_file5");
1639
1640 mystr opts;
1641 EDCParser().EDC2String(edc, opts, "");
1642 of << "%======================================================================\n";
1643 of << "% Solver Options \n";
1644 of << opts; // write the string to file
1645 }
1646
1647 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1648 //the end
1649 of.close();
1650
1651 UO(UO_LVL_all) << "\nMBS system saved as '" << filename << "'\n";
1652 }
1653
LoadFromFile(mystr filename)1654 int MultiBodySystem::LoadFromFile(mystr filename)
1655 {
1656 Destroy();
1657 int rv = ReadModelData(filename);
1658 if(rv)
1659 {
1660 SetModelData_Initialized(1);
1661 //Assemble(); // this is done by ModelChanged() wich is called later anyway
1662 }
1663 else
1664 {
1665 UO() << "ERROR in LoadFromFile during reading '" << filename << "'\n";
1666 }
1667 return rv;
1668 }
1669
1670
1671 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1672 //these functions are called from WCDriver via WinCompInterface:
GetObjectFactory()1673 MBSObjectFactoryInterface * MultiBodySystem::GetObjectFactory()
1674 {
1675 return EDCParser().GetObjectFactory();
1676 }
1677
1678
1679 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1680 //++++++++++++++++++ EDC_MBS_OPTIONS ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1681 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1682
GetMBS_EDC_Options()1683 ElementDataContainer* MultiBodySystem::GetMBS_EDC_Options()
1684 {
1685 return mbs_edc_options;
1686 }
GetMBS_EDC_Options() const1687 const ElementDataContainer* MultiBodySystem::GetMBS_EDC_Options() const
1688 {
1689 return mbs_edc_options;
1690 }
SetMBS_EDC_Options(const ElementDataContainer & edc)1691 void MultiBodySystem::SetMBS_EDC_Options(const ElementDataContainer& edc)
1692 {
1693 if (mbs_edc_options != 0) delete mbs_edc_options;
1694
1695 mbs_edc_options = new ElementDataContainer;
1696
1697 mbs_edc_options->CopyFrom(edc);
1698 }
1699
1700 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
GetMBS_EDC_Variables()1701 ElementDataContainer* MultiBodySystem::GetMBS_EDC_Variables()
1702 {
1703 return mbs_edc_global_variables;
1704 }
GetMBS_EDC_Variables() const1705 const ElementDataContainer* MultiBodySystem::GetMBS_EDC_Variables() const
1706 {
1707 return mbs_edc_global_variables;
1708 }
SetMBS_EDC_Variables(const ElementDataContainer & edc)1709 void MultiBodySystem::SetMBS_EDC_Variables(const ElementDataContainer& edc)
1710 {
1711 if (mbs_edc_global_variables != 0) delete mbs_edc_global_variables;
1712
1713 mbs_edc_global_variables = new ElementDataContainer;
1714
1715 mbs_edc_global_variables->CopyFrom(edc);
1716 }
1717
1718 //get values in MBS_EDC:
MBS_EDC_TreeGetDouble(double & data,const char * name) const1719 void MultiBodySystem::MBS_EDC_TreeGetDouble(double& data, const char* name) const
1720 {
1721 data = GetMBS_EDC_Options()->TreeGetDouble(name);
1722 }
MBS_EDC_TreeGetInt(int & data,const char * name) const1723 void MultiBodySystem::MBS_EDC_TreeGetInt(int& data, const char* name) const
1724 {
1725 data = GetMBS_EDC_Options()->TreeGetInt(name); //(int == bool internally)
1726 }
MBS_EDC_TreeGetString(const char * name) const1727 const char* MultiBodySystem::MBS_EDC_TreeGetString(const char* name) const
1728 {
1729 return GetMBS_EDC_Options()->TreeGetString(name);
1730 }
1731
1732 //set values in MBS_EDC:
MBS_EDC_TreeSetDouble(double data,const char * name)1733 void MultiBodySystem::MBS_EDC_TreeSetDouble(double data, const char* name)
1734 {
1735 GetMBS_EDC_Options()->TreeSetDouble(name, data);
1736 }
MBS_EDC_TreeSetInt(int data,const char * name)1737 void MultiBodySystem::MBS_EDC_TreeSetInt(int data, const char* name)
1738 {
1739 GetMBS_EDC_Options()->TreeSetInt(name, data); //(int == bool internally)
1740 }
MBS_EDC_TreeSetString(const char * data,const char * name)1741 void MultiBodySystem::MBS_EDC_TreeSetString(const char* data, const char* name)
1742 {
1743 GetMBS_EDC_Options()->TreeSetString(name, data);
1744 }
1745
MBSParser() const1746 const CMBSParser& MultiBodySystem::MBSParser() const {return *mbs_parser;}
MBSParser()1747 CMBSParser& MultiBodySystem::MBSParser() {return *mbs_parser;}
1748
EDCParser() const1749 const CEDCParser& MultiBodySystem::EDCParser() const {return *edc_parser;}
EDCParser()1750 CEDCParser& MultiBodySystem::EDCParser() {return *edc_parser;}
1751
File2Str(const char * filename,mystr & str)1752 int MultiBodySystem::File2Str(const char* filename, mystr& str)
1753 {
1754 mystr filen = filename;
1755 CMFile file(filename, TFMread);
1756 UO() << "--------------------------------\n";
1757
1758 //read parameters from file
1759 if (file.IsGood())
1760 {
1761 UO() << "read " << filename << "\n";
1762
1763 //read file
1764 file.RWF(str);
1765 }
1766 else
1767 {
1768 UO() << "*****************\n";
1769 UO() << "*****************\n";
1770 UO() << "*****************\n";
1771 UO() << "ERROR: failed to read model data from " << filename << "\n";
1772 UO() << "*****************\n";
1773 UO() << "*****************\n";
1774 UO() << "*****************\n";
1775
1776 return 0; // error
1777 }
1778 return 1;
1779 }
1780
1781 //this function reads a file and stores it in an edc
File2EDC(const char * filename,ElementDataContainer * edc_file)1782 int MultiBodySystem::File2EDC(const char* filename, ElementDataContainer* edc_file)
1783 {
1784 //$ DR 2013-01-14:[ added call for stl-files
1785 mystr filen = filename;
1786 if(filen.Find(".stl")>0)
1787 {
1788 return STLFile2EDC(filen, 0, edc_file);
1789 }
1790 //$ DR 2013-01-14:]
1791
1792 CMFile file(filename, TFMread);
1793 UO() << "--------------------------------\n";
1794
1795 //read parameters from file
1796 if (file.IsGood())
1797 {
1798 UO() << "read " << filename << "\n";
1799
1800 //read file
1801 mystr str;
1802 file.RWF(str);
1803
1804 // overwrite edc with contents from file
1805 // EDCParser().String2TreeEDC(/*this, */str, *edc_file);
1806
1807 EDCParser().ParseAndExecuteString(str, *edc_file);
1808 }
1809 else
1810 {
1811 UO() << "*****************\n";
1812 UO() << "*****************\n";
1813 UO() << "*****************\n";
1814 UO() << "ERROR: failed to read model data from " << filename << "\n";
1815 UO() << "*****************\n";
1816 UO() << "*****************\n";
1817 UO() << "*****************\n";
1818
1819 return 0; // error
1820 }
1821 return 1;
1822 }
1823
1824 //DR 2013-01-14 this function reads a stl-file and writes the data in the edc
STLFile2EDC(char * file,int binary,ElementDataContainer * return_value)1825 int MultiBodySystem::STLFile2EDC(char* file, int binary, ElementDataContainer* return_value)
1826 {
1827 int initsize = 10000;
1828 TArray<Vector3D> newnormals(initsize);
1829 TArray<Vector3D> newpoints(3*initsize);
1830 double stl_tolerance=1e-4; //tolerance for equal points when reading
1831
1832 if (!binary)
1833 {
1834 ifstream ist(file);
1835
1836 char buf[200];
1837 Vector3D pts[3];
1838 Vector3D normal;
1839
1840 int cntface = 0;
1841 int vertex = 0;
1842 int badnormals = 0;
1843
1844 while (ist.good())
1845 {
1846 ist >> buf;
1847 if (strcmp (buf, "facet") == 0)
1848 {
1849 cntface++;
1850 }
1851
1852 normal = 0;
1853
1854 if (strcmp (buf, "normal") == 0)
1855 {
1856 ist >> normal.X()
1857 >> normal.Y()
1858 >> normal.Z();
1859 if (normal.Norm() > 0)
1860 normal /= normal.Norm();
1861 }
1862
1863
1864 if (strcmp (buf, "vertex") == 0)
1865 {
1866 ist >> pts[vertex].X()
1867 >> pts[vertex].Y()
1868 >> pts[vertex].Z();
1869
1870
1871 vertex++;
1872 if (vertex == 3)
1873 {
1874 if (normal.Norm() <= 1e-5)
1875 {
1876 Vector3D v1 = pts[1]-pts[0];
1877 Vector3D v2 = pts[2]-pts[0];
1878 normal = v1.Cross(v2);
1879 if (normal.Norm() != 0) normal *= 1./normal.Norm();
1880 }
1881
1882 vertex = 0;
1883
1884 if ( (Dist (pts[0], pts[1]) < 1e-16) ||
1885 (Dist (pts[0], pts[2]) < 1e-16) ||
1886 (Dist (pts[1], pts[2]) < 1e-16) )
1887 {
1888 ;
1889 }
1890 else
1891 {
1892 newnormals.Add(normal);
1893 newpoints.Add(pts[0]);
1894 newpoints.Add(pts[1]);
1895 newpoints.Add(pts[2]);
1896 }
1897 }
1898 }
1899 }
1900
1901 } //end read STL ASCII format
1902 else
1903 {
1904 //read STL BINARY format
1905
1906 int binary_mode = 1;
1907 CMFile infile(file, TFMread, binary_mode);
1908
1909 Vector3D pts[3];
1910 Vector3D normal;
1911
1912 int nofacets = 0;
1913 int vertex = 0;
1914
1915 if (sizeof(int) != 4 || sizeof(float) != 4)
1916 UO() << "for stl-binary compatibility only use 32 bit compilation!!!";
1917
1918 //specific settings for stl-binary format
1919 const int namelen = 80; //length of name of header in file
1920 const int nospaces = 2; //number of spaces after a triangle
1921
1922 //read header: name
1923 char buf[namelen+1];
1924
1925 mystr str;
1926 //read leading 80 characters
1927 infile.RWchars(namelen, str);
1928 //global_uo << "STL-header=" << str << "\n";
1929
1930 //read 4-byte int number of facets
1931 infile.RWbinaryInt(nofacets);
1932 //global_uo << "No. facets=" << nofacets << "\n";
1933
1934 float f;
1935 char spaces[nospaces];
1936
1937 //read triangles:
1938 int cntface, j;
1939 for (cntface = 1; cntface <= nofacets; cntface++)
1940 {
1941 //read 3 floats for triangle normal
1942 infile.RWbinaryFloat(f); normal.X() = (double)f;
1943 infile.RWbinaryFloat(f); normal.Y() = (double)f;
1944 infile.RWbinaryFloat(f); normal.Z() = (double)f;
1945
1946 //read 3 x 3 floats for (x,y,z) coordinates of triangle points
1947 for (j = 0; j < 3; j++)
1948 {
1949 infile.RWbinaryFloat(f); pts[j].X() = (double)f;
1950 infile.RWbinaryFloat(f); pts[j].Y() = (double)f;
1951 infile.RWbinaryFloat(f); pts[j].Z() = (double)f;
1952 }
1953
1954 //read two bytes for attributes (usually unused)
1955 infile.RWchar(spaces[0]);
1956 infile.RWchar(spaces[1]);
1957 //global_uo << "sp1=" << (int)spaces[0] << ", sp1=" << (int)spaces[1] << "\n";
1958
1959 newnormals.Add(normal);
1960 newpoints.Add(pts[0]);
1961 newpoints.Add(pts[1]);
1962 newpoints.Add(pts[2]);
1963 }
1964
1965 }
1966
1967 //now sort points and generate a consistent surface mesh (not necessary for graphical representation)
1968 Box3D box;
1969 for (int i=1; i <= newpoints.Length(); i++) box.Add(newpoints(i));
1970
1971 IVector pnums;
1972 pnums.SetLen(newpoints.Length());
1973 IVector items;
1974
1975 double boxeps = stl_tolerance+1e-12;
1976 double eps2 = Sqr(stl_tolerance);
1977
1978 TArray<Vector3D> locpoints;
1979
1980 SearchTree st(20,20,20, box);
1981 for (int i=1; i <= newpoints.Length(); i++)
1982 {
1983 Box3D b(newpoints(i), newpoints(i));
1984 b.Increase(boxeps);
1985 st.GetItemsInBox(b, items);
1986
1987 int found = 0;
1988 for (int j=1; j <= items.Length(); j++)
1989 {
1990 if (Dist2(newpoints(i), locpoints(items(j))) <= eps2)
1991 {
1992 found = items(j);
1993 break;
1994 }
1995 }
1996 if (found)
1997 {
1998 pnums(i) = found;
1999 }
2000 else
2001 {
2002 pnums(i) = locpoints.Add(newpoints(i));
2003 st.AddItem(Box3D(newpoints(i),newpoints(i)), pnums(i));
2004 }
2005 }
2006
2007 Matrix m(newnormals.Length(), 3);
2008 Matrix n(newnormals.Length(), 3);
2009 for (int i=1; i <= newnormals.Length(); i++)
2010 {
2011 m(i,1) = pnums(3*i-2);
2012 m(i,2) = pnums(3*i-1);
2013 m(i,3) = pnums(3*i);
2014 n(i,1) = newnormals(i).X();
2015 n(i,2) = newnormals(i).Y();
2016 n(i,3) = newnormals(i).Z();
2017 }
2018
2019 //ElementDataContainer edc;
2020
2021 ElementData ed;
2022 ed.SetMatrix(m.GetMatPtr(),m.Getrows(),m.Getcols(),"triangles");
2023 return_value->Add(ed);
2024
2025 ed.SetMatrix(n.GetMatPtr(),n.Getrows(),n.Getcols(),"normals");
2026 return_value->Add(ed);
2027
2028 Matrix p(newnormals.Length(), 3);
2029 for (int i=1; i <= locpoints.Length(); i++)
2030 {
2031 p(i,1) = locpoints(i).X();
2032 p(i,2) = locpoints(i).Y();
2033 p(i,3) = locpoints(i).Z();
2034 }
2035
2036 ed.SetMatrix(p.GetMatPtr(),p.Getrows(),p.Getcols(),"points");
2037 return_value->Add(ed);
2038
2039 //return_value.SetEDC(edc.GetCopy(),"MeshData");
2040 return 1;
2041 }
2042
2043 //this function computes mass, moment of inertia, volume and center of gravity based on the data about the geometry and the material
ComputeInertia(ElementDataContainer * data,ElementDataContainer * return_value)2044 int MultiBodySystem::ComputeInertia(ElementDataContainer* data, ElementDataContainer* return_value)
2045 {
2046 int material_number = 0;
2047 double rho = 0;
2048
2049 // set rho according to material_number or directly entered density, if there is no material_number
2050 if(!data->Find("material_number")) // if there is no material_number search for entry "density"
2051 {
2052 rho = data->TreeGetDouble("density",0);
2053 }
2054 else
2055 {
2056 material_number = data->TreeGetInt("material_number",0);
2057 if(material_number <= NMaterials())
2058 {
2059 rho = GetMaterial(material_number).Density();
2060 }
2061 else
2062 {
2063 return 0; // not a valid material_number
2064 }
2065 }
2066
2067 if(!rho) { return 0; }// density == 0
2068 // rho is now set
2069
2070 // start the computation of the inertia values
2071 Matrix3D Iphi(0.);
2072 double mass, volume;
2073 Vector3D cog;
2074
2075 if(data->Find("MeshData"))
2076 {
2077 //see Maple file "maple/integration_triangle_volume.mws" and paper 'computing moments of piecewise polynomial surfaces'
2078 double im11=0, im12=0, im13=0, im22=0, im23=0, im33=0;
2079 double vol=0;
2080 Vector3D center(0.,0.,0.);
2081
2082 int dummy = 0;
2083 int Npoints, Ntrigs;
2084
2085 double * p;
2086 double * t;
2087 data->TreeGetMatrix("MeshData.points",&p,Npoints,dummy);
2088 if(dummy!=3) {return 0;} // error
2089 data->TreeGetMatrix("MeshData.triangles",&t,Ntrigs,dummy);
2090 if(dummy!=3) {return 0;} // error
2091
2092 Matrix pts(Npoints,3,p);
2093 Matrix trigs(Ntrigs,3,t);
2094
2095 for (int i=1; i <= Ntrigs; i++)
2096 {
2097 //const Vector3D& p1 = locpoints(trigs(i).Get(1));
2098 //const Vector3D& p2 = locpoints(trigs(i).Get(2));
2099 //const Vector3D& p3 = locpoints(trigs(i).Get(3));
2100
2101 const Vector3D& p1 = Vector3D(pts(trigs(i,1),1),pts(trigs(i,1),2),pts(trigs(i,1),3));
2102 const Vector3D& p2 = Vector3D(pts(trigs(i,2),1),pts(trigs(i,2),2),pts(trigs(i,2),3));
2103 const Vector3D& p3 = Vector3D(pts(trigs(i,3),1),pts(trigs(i,3),2),pts(trigs(i,3),3));
2104
2105 double v1x = p2.X()-p1.X();
2106 double v1y = p2.Y()-p1.Y();
2107 double v1z = p2.Z()-p1.Z();
2108
2109 double v2x = p3.X()-p1.X();
2110 double v2y = p3.Y()-p1.Y();
2111 double v2z = p3.Z()-p1.Z();
2112 double px = p1.X();
2113 double py = p1.Y();
2114 double pz = p1.Z();
2115
2116 im11 += v1x*v1x*v1z*(v1x*v2y-v2x*v1y)/20.0+px*px*pz*(v1x*v2y-v2x*v1y)/2.0+(
2117 2.0*px*v1x*v1z+v1x*v1x*pz)*(v1x*v2y-v2x*v1y)/12.0+(2.0*v2x*v1x*v1z+v1x*v1x*v2z)
2118 *(v1x*v2y-v2x*v1y)/60.0+(2.0*px*v2x*v1z+2.0*px*v1x*v2z+2.0*v2x*v1x*pz)*(v1x*v2y
2119 -v2x*v1y)/24.0+(v2x*v2x*v1z+2.0*v2x*v1x*v2z)*(v1x*v2y-v2x*v1y)/60.0+(px*px*v1z+
2120 2.0*px*v1x*pz)*(v1x*v2y-v2x*v1y)/6.0+(px*px*v2z+2.0*px*v2x*pz)*(v1x*v2y-v2x*v1y
2121 )/6.0+(2.0*px*v2x*v2z+v2x*v2x*pz)*(v1x*v2y-v2x*v1y)/12.0+v2x*v2x*v2z*(v1x*v2y-
2122 v2x*v1y)/20.0;
2123 double MapleGenVar1 = ((px*v1y+v1x*py)*v1z+v1x*v1y*pz)*(v1x*v2y-v2x*v1y)/12.0+((
2124 v2x*v1y+v1x*v2y)*v1z+v1x*v1y*v2z)*(v1x*v2y-v2x*v1y)/60.0+((px*v2y+v2x*py)*v1z+(
2125 px*v1y+v1x*py)*v2z+(v2x*v1y+v1x*v2y)*pz)*(v1x*v2y-v2x*v1y)/24.0+(v2x*v2y*v1z+(
2126 v2x*v1y+v1x*v2y)*v2z)*(v1x*v2y-v2x*v1y)/60.0+(px*py*v2z+(px*v2y+v2x*py)*pz)*(
2127 v1x*v2y-v2x*v1y)/6.0;
2128 im12 += MapleGenVar1+((px*v2y+v2x*py)*v2z+v2x*v2y*pz)*(v1x*v2y-v2x*v1y)/12.0
2129 +px*py*pz*(v1x*v2y-v2x*v1y)/2.0+(px*py*v1z+(px*v1y+v1x*py)*pz)*(v1x*v2y-v2x*v1y
2130 )/6.0+v1x*v1y*v1z*(v1x*v2y-v2x*v1y)/20.0+v2x*v2y*v2z*(v1x*v2y-v2x*v1y)/20.0;
2131 im13 += px*pz*pz*(v1x*v2y-v2x*v1y)/4.0+v1x*v1z*v1z*(v1x*v2y-v2x*v1y)/40.0+
2132 v2x*v2z*v2z*(v1x*v2y-v2x*v1y)/40.0+(px*v1z*v1z+2.0*v1x*pz*v1z)*(v1x*v2y-v2x*v1y
2133 )/24.0+(v2x*v1z*v1z+2.0*v1x*v2z*v1z)*(v1x*v2y-v2x*v1y)/120.0+(2.0*(px*v2z+v2x*
2134 pz)*v1z+2.0*v1x*pz*v2z)*(v1x*v2y-v2x*v1y)/48.0+(2.0*v2x*v2z*v1z+v1x*v2z*v2z)*(
2135 v1x*v2y-v2x*v1y)/120.0+(2.0*px*pz*v2z+v2x*pz*pz)*(v1x*v2y-v2x*v1y)/12.0+(px*v2z
2136 *v2z+2.0*v2x*pz*v2z)*(v1x*v2y-v2x*v1y)/24.0+(2.0*px*pz*v1z+v1x*pz*pz)*(v1x*v2y-
2137 v2x*v1y)/12.0;
2138 im22 += py*py*pz*(v1x*v2y-v2x*v1y)/2.0+v2y*v2y*v2z*(v1x*v2y-v2x*v1y)/20.0+
2139 v1y*v1y*v1z*(v1x*v2y-v2x*v1y)/20.0+(2.0*py*v1y*v1z+v1y*v1y*pz)*(v1x*v2y-v2x*v1y
2140 )/12.0+(2.0*v2y*v1y*v1z+v1y*v1y*v2z)*(v1x*v2y-v2x*v1y)/60.0+(2.0*py*v2y*v1z+2.0
2141 *py*v1y*v2z+2.0*v2y*v1y*pz)*(v1x*v2y-v2x*v1y)/24.0+(v2y*v2y*v1z+2.0*v2y*v1y*v2z
2142 )*(v1x*v2y-v2x*v1y)/60.0+(py*py*v1z+2.0*py*v1y*pz)*(v1x*v2y-v2x*v1y)/6.0+(py*py
2143 *v2z+2.0*py*v2y*pz)*(v1x*v2y-v2x*v1y)/6.0+(2.0*py*v2y*v2z+v2y*v2y*pz)*(v1x*v2y-
2144 v2x*v1y)/12.0;
2145 im23 += v2y*v2z*v2z*(v1x*v2y-v2x*v1y)/40.0+py*pz*pz*(v1x*v2y-v2x*v1y)/4.0+
2146 v1y*v1z*v1z*(v1x*v2y-v2x*v1y)/40.0+(py*v1z*v1z+2.0*v1y*pz*v1z)*(v1x*v2y-v2x*v1y
2147 )/24.0+(v2y*v1z*v1z+2.0*v1y*v2z*v1z)*(v1x*v2y-v2x*v1y)/120.0+(2.0*(py*v2z+v2y*
2148 pz)*v1z+2.0*v1y*pz*v2z)*(v1x*v2y-v2x*v1y)/48.0+(2.0*v2y*v2z*v1z+v1y*v2z*v2z)*(
2149 v1x*v2y-v2x*v1y)/120.0+(2.0*py*pz*v2z+v2y*pz*pz)*(v1x*v2y-v2x*v1y)/12.0+(py*v2z
2150 *v2z+2.0*v2y*pz*v2z)*(v1x*v2y-v2x*v1y)/24.0+(2.0*py*pz*v1z+v1y*pz*pz)*(v1x*v2y-
2151 v2x*v1y)/12.0;
2152 im33 += v2z*v1z*v1z*(v1x*v2y-v2x*v1y)/60.0+v1z*v1z*v1z*(v1x*v2y-v2x*v1y)/
2153 60.0+pz*v2z*v1z*(v1x*v2y-v2x*v1y)/12.0+pz*pz*v1z*(v1x*v2y-v2x*v1y)/6.0+v2z*v2z*
2154 v1z*(v1x*v2y-v2x*v1y)/60.0+pz*pz*v2z*(v1x*v2y-v2x*v1y)/6.0+pz*v2z*v2z*(v1x*v2y-
2155 v2x*v1y)/12.0+pz*pz*pz*(v1x*v2y-v2x*v1y)/6.0+v2z*v2z*v2z*(v1x*v2y-v2x*v1y)/60.0
2156 +pz*v1z*v1z*(v1x*v2y-v2x*v1y)/12.0;
2157
2158 vol += 1./6.*v1z*(v1x*v2y-v2x*v1y)+1./6.*v2z*(v1x*v2y-v2x*v1y)+1./2.*pz*(v1x*v2y-v2x*v1y);
2159
2160 center.X() += v1x*v1z*(v1x*v2y-v2x*v1y)/12.0+(v2x*v1z+v1x*v2z)*(v1x*v2y-v2x*v1y)/24.0+v2x*v2z*(v1x*v2y-v2x*v1y)/12.0+(px*v1z+v1x*pz)*(v1x*v2y-v2x*v1y)/6.0+(px*v2z+v2x*pz)*(v1x*v2y-v2x*v1y)/6.0+px*pz*(v1x*v2y-v2x*v1y)/2.0;
2161 center.Y() += v1y*v1z*(v1x*v2y-v2x*v1y)/12.0+(v2y*v1z+v1y*v2z)*(v1x*v2y-v2x*v1y)/24.0+v2y*v2z*(v1x*v2y-v2x*v1y)/12.0+(py*v1z+v1y*pz)*(v1x*v2y-v2x*v1y)/6.0+(py*v2z+v2y*pz)*(v1x*v2y-v2x*v1y)/6.0+py*pz*(v1x*v2y-v2x*v1y)/2.0;
2162 center.Z() += v1z*v1z*(v1x*v2y-v2x*v1y)/24.0+v2z*v1z*(v1x*v2y-v2x*v1y)/24.0+v2z*v2z*(v1x*v2y-v2x*v1y)/24.0+pz*v1z*(v1x*v2y-v2x*v1y)/6.0+pz*v2z*(v1x*v2y-v2x*v1y)/6.0+pz*pz*(v1x*v2y-v2x*v1y)/4.0;
2163 }
2164 volume = vol;
2165 mass = volume*rho;
2166 Iphi = rho * Matrix3D(im22+im33,-im12,-im13, -im12, im11+im33, -im23, -im13, -im23, im11+im22);
2167 if (vol != 0)
2168 {
2169 cog = center * (1./vol);
2170 }
2171 }
2172 else if(data->Find("Cube"))
2173 {
2174 double x,y,z;
2175 data->TreeGetVector3D("Cube.body_dimensions",x,y,z);
2176
2177 volume = x*y*z;
2178 mass = volume*rho;
2179 Iphi(1,1)= 1./12.*mass*(Sqr(y)+Sqr(z));
2180 Iphi(2,2)= 1./12.*mass*(Sqr(x)+Sqr(z));
2181 Iphi(3,3)= 1./12.*mass*(Sqr(x)+Sqr(y));
2182 cog = Vector3D(0.);
2183 }
2184 else if(data->Find("Cylinder"))
2185 {
2186
2187 }
2188
2189 // set the new edc
2190 ElementData ed;
2191 ed.SetDouble(volume,"volume"); return_value->Add(ed);
2192 ed.SetDouble(mass,"mass"); return_value->Add(ed);
2193 ed.SetVector3D(cog.X(),cog.Y(),cog.Z(),"center_of_mass"); return_value->Add(ed);
2194 ed.SetMatrix(Iphi.GetMatPtr(),3,3,"moment_of_inertia"); return_value->Add(ed);
2195
2196 return 1;
2197
2198 }
2199
2200 //this function reads a column of a file and returns it as vector, rv = 1.. success, 0..file is not good
LoadVectorFromFile(const char * filename,int col,ElementDataContainer * return_value)2201 int MultiBodySystem::LoadVectorFromFile(const char* filename, int col, ElementDataContainer* return_value)
2202 {
2203 CMatrixFile file( filename, TFMread );
2204 if(file.IsGood())
2205 {
2206 file.ReadSingleColumn(col);
2207 TArray<double>& coldata = file.Column(col);
2208 Vector test;
2209 test.SetVector(coldata);
2210 // set the new edc
2211 ElementData ed;
2212 ed.SetVector(test.GetVecPtr(), test.Length(),"vector"); return_value->Add(ed);
2213 return 1;
2214 }
2215 else
2216 {
2217 return 0;
2218 }
2219 }
2220
AddReplaceModelDataEDC(ElementDataContainer & edc)2221 void MultiBodySystem::AddReplaceModelDataEDC(/*const */ElementDataContainer& edc)
2222 {
2223 //$ DR 2013-06-12:[ code that has been in AddModelData
2224 // verbosity level is needed for further opertation
2225 if (edc.TreeFind("LoggingOptions.output_level")) // temporary solution - best would be to have an entry like "GeneralOptions.show_general_warnings" in edc_file //$ PG 2012-2-3: substituted SolverOptions.Log.output_level by LoggingOptions.output_level
2226 {
2227 GetOptions()->LoggingOptions()->OutputLevel() = edc.TreeGetInt("LoggingOptions.output_level"); //$ PG 2012-2-3: substituted solset.output_level by GetOptions()->LoggingOptions()->OutputLevel() and SolverOptions.Log.output_level by LoggingOptions.output_level
2228 }
2229 //$ DR 2013-06-12:] code that has been in AddModelData
2230
2231 bool show_warnings = ( GetOptions()->LoggingOptions()->OutputLevel() >= UO_LVL_dbg1 ); //$ PG 2012-2-3: substituted solset.output_level by GetOptions()->LoggingOptions()->OutputLevel()
2232
2233 ElementData* edmodel;
2234
2235 // loop over all default main branches
2236 for (int i=1; i <= edc.Length(); i++)
2237 {
2238 // get i-th main branch
2239 if(!GetMBS_EDC_Options()->TreeFind(edc.GetPtr(i)->GetDataName()))
2240 {
2241 ElementDataContainer edci;edci.TreeAdd("",edc.Get(i));
2242 edc_modeldata->TreeReplaceEDCDataWith(&edci, show_warnings, mystr(edc.GetPtr(i)->GetDataName())+mystr("."));
2243 }
2244 }
2245
2246 //$ DR 2013-06-12:[ code that has been in AddModelData
2247 // replace solveroptions & other settings
2248 ElementData* eddef;
2249 ElementData* edfile;
2250
2251 // loop over all default main branches
2252 for (int i=1; i <= GetMBS_EDC_Options()->Length(); i++)
2253 {
2254 // get i-th main branch
2255 //eddef = edc_default.GetPtr(i);
2256 eddef = GetMBS_EDC_Options()->GetPtr(i);
2257 edfile = edc.TreeFind(eddef->GetDataName());
2258 // replace the default settings by the user's file settings
2259 if (edfile != 0 && eddef->IsEDC() && edfile->IsEDC())
2260 {
2261 if(GetMBS_EDC_Options()->TreeFind(edfile->GetDataName()))
2262 {
2263 UO(UO_LVL_ext) << "replacing hotint option: " << edfile->GetDataName() << "\n";
2264 // use file parameters (when existing) instead of default variables
2265 eddef->GetEDC()->TreeReplaceEDCDataWith(edfile->GetEDC(), show_warnings, mystr(edfile->GetDataName())+mystr("."));
2266 }
2267 }
2268 }
2269 // overwrite default options by user file data
2270 EDC2SolverOptions(GetMBS_EDC_Options());
2271 EDC2Options(GetMBS_EDC_Options()); // copy EDC to i/d/toptions
2272
2273 OpenLogFile(0);
2274
2275 UO() << "done.\n";
2276 UO() << "--------------------------------\n";
2277 //$ DR 2013-06-12:] code that has been in AddModelData
2278 }
2279
2280
ReadModelData(mystr filename)2281 int MultiBodySystem::ReadModelData(mystr filename)
2282 {
2283 ElementDataContainer edc_file;
2284
2285 // read parameters from file and store it in ElementDataContainer of mbs (details: see forum)
2286 CMFile file(filename, TFMread);
2287 UO() << "--------------------------------\n";
2288 int rv = 1;
2289
2290 //read parameters from file
2291 if (file.IsGood())
2292 {
2293 UO(UO_LVL_0) << "read " << filename << "\n";
2294
2295 //read file
2296 mystr str;
2297 file.RWF(str);
2298
2299 //$ DR 2013-03-09:[
2300 // Get the variables of the parameter variation
2301 ElementDataContainer edc_tmp;
2302 ElementData ed_tmp;
2303 if(GetMBS_EDC_Options()->TreeGetInt("SolverOptions.ParameterVariation.activate"))
2304 {
2305 mystr varname = GetMBS_EDC_Options()->TreeGetString("SolverOptions.ParameterVariation.MBS_EDC_variable_name");
2306 double val = edc_modeldata->TreeGetDouble(varname);
2307 ed_tmp.SetDouble(val,varname);
2308 edc_tmp.Add(ed_tmp);
2309 if(GetMBS_EDC_Options()->TreeGetInt("SolverOptions.ParameterVariation.Var2.activate"))
2310 {
2311 varname = GetMBS_EDC_Options()->TreeGetString("SolverOptions.ParameterVariation.Var2.MBS_EDC_variable_name");
2312 val = edc_modeldata->TreeGetDouble(varname);
2313 ed_tmp.SetDouble(val,varname);
2314 edc_tmp.Add(ed_tmp);
2315 }
2316 }
2317 //$ DR 2013-03-09:]
2318 //$ RE & MSax 2013-06-27:[
2319 else if(GetMBS_EDC_Options()->TreeGetInt("SolverOptions.Optimization.activate") && edc_modeldata)
2320 {
2321 int number_of_params = GetMBS_EDC_Options()->TreeGetInt("SolverOptions.Optimization.Parameters.number_of_params");
2322 for (int col=1; col <= number_of_params; col++)
2323 {
2324 mystr varname = GetMBS_EDC_Options()->TreeGetString(mystr("SolverOptions.Optimization.Parameters.param_name")+mystr(col));
2325 double val = edc_modeldata->TreeGetDouble(varname);
2326 ed_tmp.SetDouble(val,varname);
2327 edc_tmp.Add(ed_tmp);
2328 }
2329 }
2330 //$ RE & MSax 2013-06-27:]
2331
2332
2333
2334 //$!AD 26-09-2013: parse line by line directly into modeldata EDC [
2335 // NEW CODE:
2336 edc_modeldata = 0;
2337 if (edc_modeldata != 0)
2338 {
2339 delete edc_modeldata;
2340 edc_modeldata = 0;
2341 }
2342 edc_modeldata = new ElementDataContainer;
2343
2344 // overwrite edc with contents from file
2345 //edc_modeldata = &edc_file; //JG, this is just temporary in order to get variables, change to MBSParser->readedc_global/local!!!
2346 ElementData ed;
2347 ed.SetText(filename, "last_file_name");edc_modeldata->Add(ed); // path is stored e.g. for getting relative paths in include command
2348
2349 //$ DR 2013-03-09:[
2350 // set the values for the parameter variation and save them with flagging them as readonly
2351 for(int i=1; i<=edc_tmp.Length();i++)
2352 {
2353 edc_modeldata->Add(edc_tmp.Get(i));
2354 edc_modeldata->Last().SetLocked(1);
2355 }
2356 edc_tmp.Reset();
2357 //$ DR 2013-03-09:]
2358
2359 this->EDCParser().GetMBSParser()->SetLocalEDC2(edc_modeldata);
2360 rv = this->EDCParser().ParseAndExecuteString(str, *edc_modeldata);
2361 edc_file = *(edc_modeldata->GetCopy()); //$ DR+AD 2013-10-01 bugfix, copy is necessary for solver options
2362
2363 // OLD CODE:
2364 ////////
2365 //////////UO() << "WARNING:set read EDC==>modeldata!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n";
2366 ////////rv = EDCParser().String2TreeEDC(/*this, */str, edc_file);
2367 //////////UO() << "delete read EDC!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n";
2368 //////////delete read EDC
2369 ////////edc_modeldata = 0;
2370
2371 ////////SetModelDataContainer(edc_file); //store empty edc to avoid crashes (due to null-pointer exeptions) at start of Generate - function
2372 ////////
2373 //$!AD ]
2374 }
2375 else // FileNotGood
2376 {
2377 UO() << "*****************\n";
2378 UO() << "*****************\n";
2379 UO() << "*****************\n";
2380 UO() << "ERROR: failed to read model data from " << filename << "\n";
2381 UO() << "*****************\n";
2382 UO() << "*****************\n";
2383 UO() << "*****************\n";
2384 SetModelDataContainer(edc_file); //store empty edc to avoid crashes (due to null-pointer exeptions) at start of Generate - function
2385
2386 return 0; //$JG2012-02-21 changed from 2 to 0 in case of error
2387 }
2388
2389 // verbosity level is needed for further opertation
2390 if (edc_file.TreeFind("LoggingOptions.output_level")) // temporary solution - best would be to have an entry like "GeneralOptions.show_general_warnings" in edc_file //$ PG 2012-2-3: substituted SolverOptions.Log.output_level by LoggingOptions.output_level
2391 {
2392 GetOptions()->LoggingOptions()->OutputLevel() = edc_file.TreeGetInt("LoggingOptions.output_level"); //$ PG 2012-2-3: substituted solset.output_level by GetOptions()->LoggingOptions()->OutputLevel(), and SolverOptions.Log.output_level by LoggingOptions.output_level
2393 }
2394 bool show_warnings = ( GetOptions()->LoggingOptions()->OutputLevel() >= UO_LVL_warn ); //$ PG 2012-2-3: substituted solset.output_level by GetOptions()->LoggingOptions()->OutputLevel()
2395
2396 // load default parameter settings
2397 ElementDataContainer* edc_default = GetMBS_EDC_Options();
2398
2399 RemoveVariableFromEDCTree(*edc_default, mystr("SolverOptions.ComputationSteps"), 1);
2400
2401 ElementData* eddef;
2402 ElementData* edfile;
2403
2404 //$ AD: 2011-11-08: special treatment for Computation Step entries in EDC
2405 // as these entries would produce a popupwindow every time when using TreeReplace
2406 // copy computation steps manually, assume that entry does NOT exist in default EDC
2407 ElementData* edcsfile = edc_file.TreeFind("SolverOptions.ComputationSteps");
2408 if(edcsfile != 0 && edcsfile->IsEDC())
2409 {
2410 ElementDataContainer* edc_solopt_default = edc_default->TreeFind("SolverOptions")->GetEDC();
2411 edc_solopt_default->Add(*edcsfile);
2412 UO(UO_LVL_ext) << "Added Computation Steps: (" << edcsfile->GetEDC()->Length() << ")\n";
2413 // one could eliminate entries from FileEDC now...
2414 RemoveVariableFromEDCTree(edc_file, mystr("SolverOptions.ComputationSteps"), 0);
2415 }
2416
2417
2418 // loop over all default main branches
2419 for (int i=1; i <= edc_default->Length(); i++)
2420 {
2421
2422 // get i-th main branch
2423 eddef = edc_default->GetPtr(i);
2424 edfile = edc_file.TreeFind(eddef->GetDataName());
2425
2426 // replace the default settings by the user's file settings
2427 if (edfile != 0 && eddef->IsEDC() && edfile->IsEDC())
2428 {
2429 UO(UO_LVL_ext) << "replacing defaults: " << edfile->GetDataName() << "\n";
2430
2431 // use file parameters (when existing) instead of default variables
2432 eddef->GetEDC()->TreeReplaceEDCDataWith(edfile->GetEDC(), show_warnings, mystr(edfile->GetDataName())+mystr("."));
2433 }
2434 }
2435
2436 // overwrite default options by user file data
2437 EDC2SolverOptions(edc_default);
2438 EDC2Options(edc_default); // copy EDC to i/d/toptions
2439
2440 UO() << "done.\n";
2441 UO() << "--------------------------------\n";
2442
2443 return rv; //1==success, 0==error
2444 }
2445
2446 // use add model data after command read model data; assumption: model data container is not empty!!!
2447 //$ DR 2013-07-25: assumption is not necessary anymore.
2448 //$ AD 2013-10-22: uses ParseAndExecuteString to instantly write to edc_modeldata
AddModelData(mystr filename)2449 int MultiBodySystem::AddModelData(mystr filename)
2450 {
2451 UO(UO_LVL_0) << "read " << filename << "\n";
2452
2453 ElementDataContainer edc_file;
2454
2455 // store file name for include command with relative paths
2456 ElementData ed;
2457 ed.SetText(filename, "last_file_name");
2458 if(edc_modeldata != 0)
2459 {
2460 edc_modeldata->TreeSet("",ed);
2461 }
2462 else
2463 {
2464 SetModelDataContainer(edc_file); //store empty edc to avoid crashes (due to null-pointer exeptions)
2465 }
2466
2467 //$ AD 2013-10-22: read the string and parse it directly into the modeldatacontainer
2468 mystr str;
2469 int rv = File2Str(filename, str);
2470 if(!rv)return rv;
2471
2472 EDCParser().ParseAndExecuteString(str, *edc_modeldata);
2473
2474 // replace solveroptions & other settings
2475 bool show_warnings = GetOptions()->LoggingOptions()->OutputLevel() >= UO_LVL_dbg1;
2476 ElementData* eddef;
2477 ElementData* edfile;
2478
2479 // loop over all default main branches
2480 for (int i=1; i <= GetMBS_EDC_Options()->Length(); i++)
2481 {
2482 // get i-th main branch
2483 //eddef = edc_default.GetPtr(i);
2484 eddef = GetMBS_EDC_Options()->GetPtr(i);
2485 edfile = edc_modeldata->TreeFind(eddef->GetDataName());
2486 // replace the default settings by the user's file settings
2487 if (edfile != 0 && eddef->IsEDC() && edfile->IsEDC())
2488 {
2489 if(GetMBS_EDC_Options()->TreeFind(edfile->GetDataName()))
2490 {
2491 UO(UO_LVL_ext) << "replacing hotint option: " << edfile->GetDataName() << "\n";
2492 // use file parameters (when existing) instead of default variables
2493 eddef->GetEDC()->TreeReplaceEDCDataWith(edfile->GetEDC(), show_warnings, mystr(edfile->GetDataName())+mystr("."));
2494 }
2495 }
2496 }
2497 // overwrite default options by user file data
2498 EDC2SolverOptions(GetMBS_EDC_Options());
2499 EDC2Options(GetMBS_EDC_Options()); // copy EDC to i/d/toptions
2500
2501 OpenLogFile(0);
2502
2503 UO() << "done.\n";
2504 UO() << "--------------------------------\n";
2505
2506 return 1; //success
2507 }
2508
2509 // remove a variable or branch from the edc by name - this is used to prevent ComputationSteps to be written to file and to be remembered from a previous model
RemoveVariableFromEDCTree(ElementDataContainer & edc,mystr & varname,int warning)2510 int MultiBodySystem::RemoveVariableFromEDCTree(ElementDataContainer& edc, mystr& varname, int warning)
2511 {
2512 mystr treename, elementname;
2513 edc.SplitIntoTreeAndElementName(varname, treename, elementname);
2514 ElementData* ed_branch = edc.TreeFind(varname);
2515
2516 if (ed_branch != 0) // variable exists
2517 {
2518 ElementDataContainer* edc_nesting;
2519 if(treename.Length())
2520 {
2521 edc_nesting = edc.TreeFind(treename)->GetEDC();
2522 }
2523 else
2524 {
2525 edc_nesting = &edc;
2526 }
2527
2528 if (warning)
2529 {
2530 if( ed_branch -> IsEDC() ) UO(UO_LVL_ext) << "removing sub-edc " + varname + " from edc\n";
2531 else UO(UO_LVL_ext) << "removing entry " + varname + "from edc \n";
2532 }
2533
2534 edc_nesting->Delete(edc_nesting->Find(elementname));
2535 return 1;
2536 }
2537 return 0;
2538 }
2539
AddFileSensor(const char * filename,const mystr sensor_name,const int ncolumns,const int colTime,const int colSignal,const int interpolation,const int nrOfHeaderLines)2540 int MultiBodySystem::AddFileSensor(const char* filename, const mystr sensor_name, const int ncolumns, const int colTime, const int colSignal, const int interpolation, const int nrOfHeaderLines)
2541 {
2542 /*
2543 MathFunction mf;
2544 if(mf.SetPiecewiseFromFile(filename, ncolumns, colTime, colSignal, interpolation, nrOfHeaderLines)) // interpolation: 0...steps, 1...piecewise linear
2545 {
2546 InstantMessageText(mystr("Error1: File " + mystr(filename) + " not found!"));
2547 return 1; // error
2548 }
2549 Vector2D posDraw(0.,0.); // drawing position
2550 Vector3D drawDim = Vector3D(0.2,0.2,0.); // draw dimension of control element
2551 IOTime lt_time(this);
2552 lt_time.SetElementName(sensor_name+"-IOTime");
2553 lt_time.SetRefPos2D(Vector2D(0.,3.0)+posDraw);//define reference position for drawing
2554 lt_time.SetDrawDim(drawDim); //define size of rectangle for drawing (B, H, dummy)
2555 int nLt_time = AddElement(<_time);
2556
2557 IOMathFunction iom_ty(this);
2558 iom_ty.SetIOMathFunction(mf);
2559 iom_ty.SetRefPos2D(Vector2D(0.5,3.0)+posDraw);
2560 iom_ty.SetDrawDim(drawDim);
2561 iom_ty.SetElementName(sensor_name+"-IOMathFcn"); //Change name of element from default name
2562 iom_ty.AddInput(nLt_time, IOInputTypeElement, 1); // connection(nLt_time, typ=io, output 1)
2563 int nIo_ty = AddElement(&iom_ty);
2564
2565 MBSSensor sens_mes(this, TMBSSensor(TSOutputSensor), nIo_ty, 1); //measure output 1
2566 sens_mes.SetSensorName(sensor_name);
2567 AddSensor(&sens_mes);
2568 */
2569 return 0; //success
2570 }
AddFileSensor2(const char * filename,const mystr sensor_name,const int colTime,const int colSignal,const int interpolation,mystr comment)2571 int MultiBodySystem::AddFileSensor2(const char* filename, const mystr sensor_name, const int colTime, const int colSignal, const int interpolation, mystr comment)
2572 {
2573 /*
2574 MBSSensor sens_mes(this, TMBSSensor(TSFile), colTime, colSignal); //measure output 1
2575 if(sens_mes.SetTSFile(filename, colTime, colSignal, interpolation, comment)) // set file name
2576 {
2577 return 1; // error, don't add sensor
2578 }
2579 sens_mes.SetSensorName(sensor_name);
2580 AddSensor(&sens_mes);
2581 */
2582 return 0; //success
2583 }
2584
2585 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2586 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
SetOptions2EDCOptions()2587 void MultiBodySystem::SetOptions2EDCOptions()
2588 {
2589 ElementDataContainer* edc = GetMBS_EDC_Options();
2590 ElementDataContainer edcnew;
2591 Options2EDC(&edcnew); //copy options to edc:
2592 edc->TreeReplaceEDCDataWith(&edcnew);//replace edcnew data in edc:
2593 }
2594
SetEDCOptions2Options()2595 void MultiBodySystem::SetEDCOptions2Options()
2596 {
2597 ElementDataContainer* edc = GetMBS_EDC_Options();
2598 EDC2Options(edc);
2599 }
2600
SetComputationSolverOptions()2601 void MultiBodySystem::SetComputationSolverOptions()
2602 {
2603 ElementDataContainer* edc = GetMBS_EDC_Options();
2604 EDC2SolverOptions(edc);
2605 }
2606
SetSolverDialogOptions()2607 void MultiBodySystem::SetSolverDialogOptions()
2608 {
2609 //update computation options with solver settings:
2610
2611 ElementDataContainer* edc = GetMBS_EDC_Options();
2612 ElementDataContainer edcnew;
2613
2614 //copy mbssolset to edc:
2615 SolverOptions2EDC(&edcnew);
2616 //replace edcnew data in edc:
2617 edc->TreeReplaceEDCDataWith(&edcnew);
2618
2619 }
2620
2621