MBDyn-1.7.3
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups
fixedstep.cc
Go to the documentation of this file.
1 /* $Header: /var/cvs/mbdyn/mbdyn/mbdyn-1.0/mbdyn/base/fixedstep.cc,v 1.37 2017/05/02 10:07:30 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 /* fixed step file driver */
33 
34 #include "mbconfig.h" /* This goes first in every *.c,*.cc file */
35 
36 #include <fstream>
37 
38 #include "dataman.h"
39 #include "filedrv.h"
40 #include "fixedstep.h"
41 #include "solver.h"
42 
43 /* FixedStepFileDrive - begin */
44 
45 static const std::vector<doublereal> v0;
46 static const doublereal dFromFile = -std::numeric_limits<doublereal>::max();
47 
49  const DriveHandler* pDH,
50  const char* const sFileName,
51  integer ins, integer ind,
52  doublereal t0, doublereal dt,
53  bool bl, bool pz, Drive::Bailout bo)
54 : FileDrive(uL, pDH, sFileName, ind, v0),
55 dT0(t0), dDT(dt), iNumSteps(ins),
56 bLinear(bl), bPadZeroes(pz), boWhen(bo), pd(0), pvd(0)
57 {
58  ASSERT(iNumDrives > 0);
59  ASSERT(sFileName != NULL);
60  ASSERT(dDT > 0.);
61 
62  std::ifstream in(sFileName);
63  if (!in) {
64  silent_cerr("FixedStepFileDrive(" << uL << "): "
65  "can't open file \"" << sFileName << "\""
66  << std::endl);
68  }
69 
70  /*
71  * Mangia gli eventuali commenti iniziali
72  */
73  unsigned uLineNo = 0;
74  char cTmp = '\0';
75  while (in.get(cTmp), cTmp == '#') {
76  // increase this to enlarge the size of the buffer
77 #define FIXED_BUFSIZE (8192)
78  char tmpbuf[FIXED_BUFSIZE];
79 
80  do {
81  in.getline(tmpbuf, sizeof(tmpbuf));
82  ++uLineNo;
83  if (in.fail()) {
84  silent_cerr("FixedStepFileDrive(" << uL << "): "
85  "can't get line " << uLineNo << " "
86  "from file \"" << sFileName << "\"" << std::endl);
88  }
89  int idx = 0;
90  while (isspace(tmpbuf[idx])) {
91  idx++;
92  }
93 
94  if (dT0 == dFromFile && strncasecmp(&tmpbuf[idx], "initial time:", STRLENOF("initial time:")) == 0) {
95  double d;
96  if (sscanf(&tmpbuf[idx + STRLENOF("initial time:")], "%le", &d) != 1) {
97  silent_cerr("FixedStepFileDrive(" << uL << "): "
98  "can't parse \"initial time\" line \"" << &tmpbuf[idx] << "\" "
99  "from file \"" << sFileName << "\"" << std::endl);
101  }
102  dT0 = d;
103 
104  } else if (dDT == dFromFile && strncasecmp(&tmpbuf[idx], "time step:", STRLENOF("time step:")) == 0) {
105  double d;
106  if (sscanf(&tmpbuf[idx + STRLENOF("time step:")], "%le", &d) != 1) {
107  silent_cerr("FixedStepFileDrive(" << uL << "): "
108  "can't parse \"time step\" line \"" << &tmpbuf[idx] << "\" "
109  "from file \"" << sFileName << "\"" << std::endl);
111  }
112  if (d <= 0.) {
113  silent_cerr("FixedStepFileDrive(" << uL << "): "
114  "invalid time step value " << d << " "
115  "in file \"" << sFileName << "\"" << std::endl);
117  }
118 
119  dDT = d;
120  }
121  } while (strlen(tmpbuf) == STRLENOF(tmpbuf) && tmpbuf[STRLENOF(tmpbuf)] != '\n');
122  }
123 
124  if (dT0 == dFromFile) {
125  silent_cerr("FixedStepFileDrive(" << uL << "): "
126  "expecting \"initial time\" line in file \"" << sFileName << "\""
127  << std::endl);
129  }
130 
131  if (dDT == dFromFile) {
132  silent_cerr("FixedStepFileDrive(" << uL << "): "
133  "expecting \"time step\" line in file \"" << sFileName << "\""
134  << std::endl);
136  }
137 
138  if (cTmp != '#') {
139  in.putback(cTmp);
140  }
141 
142  if (ins == -1) {
143  std::streampos pos = in.tellg();
144 
145  for (ins = 0; !in.eof(); ins++) {
146  char tmpbuf[FIXED_BUFSIZE];
147 
148  do {
149  in.getline(tmpbuf, sizeof(tmpbuf));
150  ++uLineNo;
151  if (in.eof()) {
152  break;
153  }
154 
155  if (in.fail()) {
156  silent_cerr("FixedStepFileDrive(" << uL << "): "
157  "can't get line " << uLineNo << " "
158  "from file \"" << sFileName << "\"" << std::endl);
160  }
161  } while (strlen(tmpbuf) == STRLENOF(tmpbuf) && tmpbuf[STRLENOF(tmpbuf)] != '\n');
162  }
163  iNumSteps = --ins;
164 
165  in.clear();
166  in.seekg(pos);
167 
168  silent_cout("FixedStepFileDrive(" << uL << "): "
169  "counted " << ins << " steps" << std::endl);
170  }
171 
174 
175  /* Attenzione: il primo puntatore e' vuoto
176  * (ne e' stato allocato uno in piu'),
177  * cosi' i drives possono essere numerati da 1 a n */
178  for (integer i = iNumDrives; i-- > 0; ) {
179  pvd[i + 1] = pd + i*iNumSteps;
180  }
181 
182  for (integer j = 0; j < iNumSteps; j++) {
183  for (integer i = 1; i <= iNumDrives; i++) {
184  in >> pvd[i][j];
185  if (in.eof()) {
186  silent_cerr("unexpected end of file '"
187  << sFileName << '\'' << std::endl);
189  }
190 
191  int c;
192  for (c = in.get(); isspace(c); c = in.get()) {
193  if (c == '\n') {
194  if (i != iNumDrives) {
195  silent_cerr("unexpected end of line #" << j + 1 << " (" << uLineNo << ") after channel #" << i << ", column #" << i << " of file '"
196  << sFileName << '\'' << std::endl);
198  }
199 
200  ++uLineNo;
201  break;
202  }
203  }
204 
205  if (i == iNumDrives && c != '\n') {
206  silent_cerr("missing end-of-line at line #" << j + 1 << " (" << uLineNo << ") of file '"
207  << sFileName << '\'' << std::endl);
209  }
210 
211  ++uLineNo;
212  in.putback(c);
213  }
214  }
215 
216  /* All data is available, so initialize the buffer accordingly */
217  ServePending(pDH->dGetTime());
218 }
219 
221 {
222  SAFEDELETEARR(pd);
224 }
225 
226 
227 /* Scrive il contributo del DriveCaller al file di restart */
228 std::ostream&
229 FixedStepFileDrive::Restart(std::ostream& out) const
230 {
231  return out << "0. /* FixedStepFileDrive: not implemented yet! */"
232  << std::endl;
233 }
234 
235 void
237 {
238  doublereal tt = t - dT0;
239 
240  if (tt < 0) {
241  if (boWhen & Drive::BO_LOWER) {
242  throw Solver::EndOfSimulation(EXIT_SUCCESS,
244  "A fixed step file drive lower bound is halting the simulation");
245  }
246 
247  if (bPadZeroes) {
248  for (int i = 1; i <= iNumDrives; i++) {
249  pdVal[i] = 0.;
250  }
251 
252  } else {
253  for (int i = 1; i <= iNumDrives; i++) {
254  pdVal[i] = pvd[i][0];
255  }
256  }
257 
258  } else if (tt > dDT*(iNumSteps - 1)) {
259  if (boWhen & Drive::BO_UPPER) {
260  throw Solver::EndOfSimulation(EXIT_SUCCESS,
262  "A fixed step file drive upper bound is halting the simulation");
263  }
264 
265  if (bPadZeroes) {
266  for (int i = 1; i <= iNumDrives; i++) {
267  pdVal[i] = 0.;
268  }
269 
270  } else {
271  for (int i = 1; i <= iNumDrives; i++) {
272  pdVal[i] = pvd[i][iNumSteps - 1];
273  }
274  }
275 
276  } else {
277  integer j1 = integer(floor(tt/dDT));
278  if (bLinear) {
279  if (j1 == iNumSteps - 1) {
280  for (int i = 1; i <= iNumDrives; i++) {
281  pdVal[i] = pvd[i][j1];
282  }
283 
284  } else {
285  integer j2 = j1 + 1;
286  doublereal dt1 = dT0 + j1*dDT;
287  doublereal dt2 = dt1 + dDT;
288  doublereal dw1 = (dt2 - t)/dDT;
289  doublereal dw2 = (t - dt1)/dDT;
290 
291  for (int i = 1; i <= iNumDrives; i++) {
292  pdVal[i] = pvd[i][j2]*dw2 + pvd[i][j1]*dw1;
293  }
294  }
295 
296  } else {
297  for (int i = 1; i <= iNumDrives; i++) {
298  pdVal[i] = pvd[i][j1];
299  }
300  }
301  }
302 }
303 
304 /* FixedStepFileDrive - end */
305 
306 
307 /* legge i drivers tipo fixed step file */
308 
309 Drive *
310 FixedStepDR::Read(unsigned uLabel, const DataManager *pDM, MBDynParser& HP)
311 {
312  integer isteps = -1;
313  if (!HP.IsKeyWord("count")) {
314  isteps = HP.GetInt();
315  if (isteps <= 0) {
316  silent_cerr("FixedStepFileDrive(" << uLabel << "): "
317  "invalid steps number " << isteps
318  << " at line " << HP.GetLineData()
319  << std::endl);
321  }
322  }
323 
324  integer idrives = HP.GetInt();
325  if (idrives <= 0) {
326  silent_cerr("FixedStepFileDrive(" << uLabel << "): "
327  "invalid channels number " << idrives
328  << " at line " << HP.GetLineData()
329  << std::endl);
331  }
332 
333  if (!HP.IsKeyWord("initial" "time")) {
334  silent_cerr("FixedStepFileDrive(" << uLabel << "): "
335  "warning, keyword \"initial time\" expected at line "
336  << HP.GetLineData() << std::endl);
337  }
338  doublereal t0 = dFromFile;
339  if (!HP.IsKeyWord("from" "file")) {
340  t0 = HP.GetReal();
341  }
342 
343  if (!HP.IsKeyWord("time" "step")) {
344  silent_cerr("FixedStepFileDrive(" << uLabel << "): "
345  "warning, keyword \"time step\" expected at line "
346  << HP.GetLineData() << std::endl);
347  }
348  doublereal dt = dFromFile;
349  if (!HP.IsKeyWord("from" "file")) {
350  dt = HP.GetReal();
351  if (dt <= 0.) {
352  silent_cerr("FixedStepFileDrive(" << uLabel << "): "
353  "invalid time step " << dt
354  << " at line " << HP.GetLineData()
355  << std::endl);
357  }
358  }
359 
360  bool bl(true);
361  if (HP.IsKeyWord("interpolation")) {
362  if (HP.IsKeyWord("const")) {
363  bl = false;
364 
365  } else if (!HP.IsKeyWord("linear")) {
366  silent_cerr("FixedStepFileDrive(" << uLabel << "): "
367  "unknown value for \"interpolation\" "
368  "at line " << HP.GetLineData() << std::endl);
370  }
371  }
372 
373  bool pz(true);
375 
376  if (HP.IsKeyWord("pad" "zeros") || HP.IsKeyWord("pad" "zeroes")) {
377  if (!HP.GetYesNo(pz)) {
378  silent_cerr("FixedStepFileDrive(" << uLabel << "): "
379  "unknown value for \"pad zeros\" "
380  "at line " << HP.GetLineData() << std::endl);
382  }
383 
384  } else if (HP.IsKeyWord("bailout")) {
385  if (HP.IsKeyWord("none")) {
386  bo = Drive::BO_NONE;
387 
388  } else if (HP.IsKeyWord("upper")) {
389  bo = Drive::BO_UPPER;
390 
391  } else if (HP.IsKeyWord("lower")) {
392  bo = Drive::BO_LOWER;
393 
394  } else if (HP.IsKeyWord("any")) {
395  bo = Drive::BO_ANY;
396 
397  } else {
398  silent_cerr("FixedStepFileDrive(" << uLabel << "): "
399  "invalid bailout parameter "
400  "at line " << HP.GetLineData()
401  << std::endl);
403  }
404  }
405 
406  const char* filename = HP.GetFileName();
407 
408  Drive* pDr = NULL;
411  FixedStepFileDrive(uLabel, pDM->pGetDrvHdl(),
412  filename, isteps, idrives,
413  t0, dt, bl, pz, bo));
414 
415  return pDr;
416 }
417 
static char * filename
Definition: ann_sf.c:71
#define MBDYN_EXCEPT_ARGS
Definition: except.h:63
virtual integer GetInt(integer iDefval=0)
Definition: parser.cc:1050
FixedStepFileDrive(unsigned int uL, const DriveHandler *pDH, const char *const sFileName, integer is, integer id, doublereal t0, doublereal dt, bool bl, bool pz, Drive::Bailout bo)
Definition: fixedstep.cc:48
Definition: drive.h:89
#define SAFEDELETEARR(pnt)
Definition: mynewmem.h:713
virtual const char * GetFileName(enum Delims Del=DEFAULTDELIM)
Definition: parsinc.cc:673
Bailout
Definition: drive.h:101
virtual void ServePending(const doublereal &t)
Definition: fixedstep.cc:236
const DriveHandler * pGetDrvHdl(void) const
Definition: dataman.h:340
virtual std::ostream & Restart(std::ostream &out) const
Definition: fixedstep.cc:229
integer iNumDrives
Definition: filedrv.h:47
doublereal * pd
Definition: fixedstep.h:50
#define FIXED_BUFSIZE
doublereal * pdVal
Definition: filedrv.h:48
static const doublereal dFromFile
Definition: fixedstep.cc:46
integer iNumSteps
Definition: fixedstep.h:45
virtual ~FixedStepFileDrive(void)
Definition: fixedstep.cc:220
virtual bool IsKeyWord(const char *sKeyWord)
Definition: parser.cc:910
#define ASSERT(expression)
Definition: colamd.c:977
doublereal dDT
Definition: fixedstep.h:44
#define SAFENEWWITHCONSTRUCTOR(pnt, item, constructor)
Definition: mynewmem.h:698
virtual Drive * Read(unsigned uLabel, const DataManager *pDM, MBDynParser &HP)
Definition: fixedstep.cc:310
doublereal dT0
Definition: fixedstep.h:43
static std::stack< cleanup * > c
Definition: cleanup.cc:59
#define STRLENOF(s)
Definition: mbdyn.h:166
virtual bool GetYesNo(bool &bRet)
Definition: parser.cc:1022
doublereal dGetTime(void) const
Definition: drive.h:386
#define SAFENEWARR(pnt, item, sz)
Definition: mynewmem.h:701
doublereal ** pvd
Definition: fixedstep.h:51
static const std::vector< doublereal > v0
Definition: fixedstep.cc:45
double doublereal
Definition: colamd.c:52
long int integer
Definition: colamd.c:51
virtual HighParser::ErrOut GetLineData(void) const
Definition: parsinc.cc:697
virtual doublereal GetReal(const doublereal &dDefval=0.0)
Definition: parser.cc:1056