MBDyn-1.7.3
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups
trim.cc
Go to the documentation of this file.
1 /* $Header: /var/cvs/mbdyn/mbdyn/mbdyn-1.0/utils/trim.cc,v 1.24 2017/01/12 15:10:28 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 #include "mbconfig.h" /* This goes first in every *.c,*.cc file */
33 
34 #include <cstring>
35 #include <sys/types.h>
36 #include <sys/socket.h>
37 #include <netinet/in.h>
38 #include <netdb.h>
39 #include <cstdio>
40 #include <cstdlib>
41 #include <cerrno>
42 #include <sys/socket.h>
43 #include <netinet/in.h>
44 #include <sys/un.h>
45 #include <arpa/inet.h>
46 #include <unistd.h>
47 #include <fcntl.h>
48 #include <signal.h>
49 
50 #include <iostream>
51 #include <sstream>
52 #include <vector>
53 
54 #include "sock.h"
55 #include "s2s.h"
56 
57 #include "solman.h"
58 #include "linsol.h"
59 
60 /* I/O classes (stream, using cin/cout) or socket,
61  * using MBDyn native socket communication */
62 
63 class BasicIO {
64 public:
65  virtual ~BasicIO(void) { NO_OP; };
66  virtual int ReadMeasures(s2s_t& s2s) = 0;
67  virtual int SendControls(s2s_t& s2s) = 0;
68 };
69 
70 class SocketBasicIO : public BasicIO {
71 public:
72  int ReadMeasures(s2s_t& s2s);
73  int SendControls(s2s_t& s2s);
74 };
75 
77 
78 class StreamBasicIO : public BasicIO {
79 public:
80  int ReadMeasures(s2s_t& s2s);
81  int SendControls(s2s_t& s2s);
82 };
83 
85 
86 int
88 {
89  int len = recv(s2s.sock, (char *)&s2s.dbuf[0], sizeof(double)*s2s.nChannels, 0);
90 
91  switch (len) {
92  case -1: {
93  int save_errno = errno;
94  const char *err_msg = strerror(save_errno);
95 
96  silent_cerr("recv(" << s2s.sock << ",\"" << s2s.buf << "\") "
97  "failed (" << save_errno << ": " << err_msg << ")"
98  << std::endl);
99  return -1;
100  }
101 
102  case 0:
103  return 0;
104 
105  default:
106  if ((unsigned)len < sizeof(double)*s2s.nChannels) {
107  silent_cerr("recv(" << s2s.sock << " \"" << s2s.buf << "\") "
108  "returned only partial results"
109  << std::endl);
110  return -1;
111  }
112  return 1;
113  }
114 }
115 
116 int
118 {
119  int len;
120 
121  len = send(s2s.sock, (char *)&s2s.dbuf[0], sizeof(double)*s2s.nChannels, 0);
122 
123  if ( len < 0 ) {
124  return len;
125  }
126 
127  return len/sizeof(double);
128 }
129 
130 int
132 {
133  for (int i = 0; i < s2s.nChannels; i++) {
134  std::cin >> s2s.dbuf[i];
135  if (!std::cin) {
136  if (i != 0) {
137  return -1;
138  }
139  return 0;
140  }
141  }
142 
143  return 1;
144 }
145 
146 int
148 {
149  static const char *sep = " ";
150 
151  for (int i = 0; i < s2s.nChannels - 1; i++) {
152  std::cout << s2s.dbuf[i] << sep;
153  }
154  std::cout << s2s.dbuf[s2s.nChannels - 1] << std::endl;
155 
156  return s2s.nChannels;
157 }
158 
159 class IO {
160 private:
165 
166 public:
167  IO(void) : measures(stream_basic_IO), controls(stream_basic_IO) {};
168  IO(int argc, char *argv[]);
169  ~IO(void) {};
170 
171  int nMeasures(void) const { return s2s_measures.nChannels; };
172  int nControls(void) const { return s2s_controls.nChannels; };
173 
174  int Parse(int argc, char *argv[]);
175  int Setup(int argc, char *argv[]);
176 
177  const std::vector<double> &Measures(void) const { return s2s_measures.dbuf; };
178  std::vector<double> &Controls(void) { return s2s_controls.dbuf; };
179 
182 };
183 
184 IO::IO(int argc, char *argv[])
185 : measures(stream_basic_IO), controls(stream_basic_IO)
186 {
187  if (Setup(argc, argv) == EXIT_FAILURE) {
188  throw;
189  }
190 }
191 
192 int
193 IO::Parse(int argc, char *argv[])
194 {
195  while (true) {
196  int opt = getopt(argc, argv, "c:f:H:m:");
197  if (opt == EOF) {
198  break;
199  }
200 
201  s2s_t *s2s = 0;
202 
203  switch (opt) {
204  case 'H':
205  if (strncasecmp(optarg, "measures:", STRLENOF("measures:")) == 0) {
206  optarg += STRLENOF("measures:");
207  s2s = &s2s_measures;
208 
209  } else if (strncasecmp(optarg, "controls:", STRLENOF("controls:")) == 0) {
210  optarg += STRLENOF("controls:");
211  s2s = &s2s_controls;
212 
213  } else {
214  silent_cerr("unknown value \"" << optarg << "\" for -H switch" << std::endl);
215  throw;
216  }
217 
218  if (strncasecmp(optarg, "inet:", STRLENOF("inet:")) == 0) {
219  optarg += STRLENOF("inet:");
220  s2s->host = optarg;
221 
222  } else if (strncasecmp(optarg, "path:", STRLENOF("path:")) == 0) {
223  optarg += STRLENOF("path:");
224  s2s->path = optarg;
225 
226  } else if (strcasecmp(optarg, "stdin") == 0) {
227  if (s2s != &s2s_measures) {
228  silent_cerr("invalid value \"" << optarg << "\" for -H switch" << std::endl);
229  throw;
230  }
231  break;
232 
233  } else if (strcasecmp(optarg, "stdout") == 0) {
234  if (s2s != &s2s_controls) {
235  silent_cerr("invalid value \"" << optarg << "\" for -H switch" << std::endl);
236  throw;
237  }
238  break;
239 
240  } else {
241  silent_cerr("unknown value \"" << optarg << "\" for -H switch" << std::endl);
242  throw;
243  }
244 
245  break;
246 
247  case 'c': {
248  char *next;
249 
250  s2s_controls.nChannels = strtoul(optarg, &next, 10);
251 
252  if (next == NULL || next[0] != '\0') {
253  silent_cerr("invalid value \"" << optarg << "\" for -c switch" << std::endl);
254  throw;
255  }
256  } break;
257 
258  case 'm': {
259  char *next;
260 
261  s2s_measures.nChannels = strtoul(optarg, &next, 10);
262 
263  if (next == NULL || next[0] != '\0') {
264  silent_cerr("invalid value \"" << optarg << "\" for -m switch" << std::endl);
265  throw;
266  }
267  } break;
268  }
269  }
270 
271  return 0;
272 }
273 
274 int
275 IO::Setup(int argc, char *argv[])
276 {
277  try {
278  Parse(argc, argv);
279 
280  } catch (...) {
281  return EXIT_FAILURE;
282  }
283 
285  try {
287 
288  } catch (...) {
289  return EXIT_FAILURE;
290  }
291  }
292 
294  try {
296 
297  } catch (...) {
298  return EXIT_FAILURE;
299  }
300  }
301 
302  if (s2s_measures.sock == -1) {
304 
305  if (s2s_measures.nChannels == 0) {
306  std::string buf;
307  std::getline(std::cin, buf);
308 
309  std::istringstream str(buf);
310 
311  for (;; s2s_measures.nChannels++) {
312  double d;
313 
314  str >> d;
315 
316  if (!str) {
317  break;
318  }
319 
320  s2s_measures.dbuf.insert(s2s_measures.dbuf.end(), d);
321  }
322 
323  } else {
325  }
326 
327  } else {
329 
330  if (s2s_measures.nChannels == 0) {
331  silent_cerr("number of measures required in socket mode" << std::endl);
332  return EXIT_FAILURE;
333  }
334 
336  }
337 
338  if (s2s_controls.sock == -1) {
340 
341  } else {
343  }
344 
345  if (s2s_controls.nChannels == 0) {
346  silent_cerr("number of controls required" << std::endl);
347  return EXIT_FAILURE;
348  }
349 
351 
352 
353  return EXIT_SUCCESS;
354 
355 }
356 
358 protected:
359  double tol;
360 
361 public:
362  ConvergenceCheck(int n, double t) : tol(t) {};
363  virtual ~ConvergenceCheck(void) {};
364 
365  virtual bool Check(const std::vector<double> &measures) = 0;
366 };
367 
369 private:
370  double rho;
371  std::vector<double> prevMeasures;
372  std::vector<double> prevDiff;
373  std::vector<double> diff;
374 
375 public:
376  FFDConvergenceCheck(int n, double t, double r);
378 
379  bool Check(const std::vector<double> &measures);
380 };
381 
383 : ConvergenceCheck(n, t),
384 rho(r),
385 prevMeasures(n, 0.),
386 prevDiff(n, 0.),
387 diff(n, 0.)
388 {
389  return;
390 }
391 
392 bool
393 FFDConvergenceCheck::Check(const std::vector<double> &measures)
394 {
395  double d = 0.;
396 
397  for (unsigned i = 0; i < measures.size(); i++) {
398  /*
399  diff = rho * (measures - prevMeasures) + (1 - rho) * prevDiff
400  */
401  diff[i] = (1 - rho)*prevDiff[i];
402  prevDiff[i] = measures[i] - prevMeasures[i];
403  diff[i] += rho*prevDiff[i];
404  prevMeasures[i] = measures[i];
405 
406  d += diff[i]*diff[i];
407  }
408 
409  if (std::sqrt(d) < tol) {
410  return true;
411  }
412 
413  return false;
414 }
415 
416 class TrimEval {
417 protected:
418  IO &io;
420 
421 public:
422  TrimEval(IO &io, ConvergenceCheck &cc) : io(io), cc(cc) {};
423  ~TrimEval(void) {};
424 
425  int FuncEval(std::vector<double> &X, std::vector<double> &F, int nSteps, int maxSteps);
426 };
427 
428 int
429 TrimEval::FuncEval(std::vector<double> &X, std::vector<double> &F, int nSteps, int maxSteps)
430 {
431  if (X.size() != io.Controls().size()) {
432  return -1;
433  }
434 
435  std::vector<double> Xref(X.size());
436  std::vector<double> deltaX(X.size());
437 
438  for (unsigned int i = 0; i < X.size(); i++) {
439  Xref[i] = io.Controls()[i];
440  deltaX[i] = X[i] - Xref[i];
441  }
442 
443  int currStep;
444  for (currStep = 0; currStep < nSteps; currStep++) {
445  for (unsigned int i = 0; i < X.size(); i++) {
446  io.Controls()[i] = Xref[i] + (deltaX[i]*currStep)/nSteps;
447  }
448 
449  io.SendControls();
450  io.ReadMeasures();
451  }
452 
453  for (; currStep < maxSteps; currStep++) {
454  if (cc.Check(io.Measures())) {
455  return 1;
456  }
457 
458  io.SendControls();
459  io.ReadMeasures();
460  }
461 
462  return 0;
463 }
464 
465 class NRTrim {
466 private:
467  IO &io;
469 
470 public:
471  NRTrim(IO &io, int n, double t);
472  ~NRTrim(void) {};
473 
474  int DoTrim(const std::vector<double> expectedMeasures,
475  const std::vector<double> incrControls,
476  std::vector<double> controls);
477 };
478 
479 NRTrim::NRTrim(IO &io, int n, double t)
480 : io(io),
481 pcc(0)
482 {
483  pcc = new FFDConvergenceCheck(n, t, .99);
484 }
485 
486 int
487 NRTrim::DoTrim(const std::vector<double> expectedMeasures,
488  const std::vector<double> incrControls,
489  std::vector<double> controls)
490 {
491  TrimEval te(io, *pcc);
492  std::vector<double> Xref(incrControls.size()),
493  X(incrControls.size());
494  std::vector<double> Fref(expectedMeasures.size()),
495  F(expectedMeasures.size(), 0.);
496  LinSol LS;
497  SolutionManager *psm(LS.GetSolutionManager(expectedMeasures.size()));
498  MatrixHandler *pM = psm->pMatHdl();
499  VectorHandler *pR = psm->pResHdl();
500  VectorHandler *pX = psm->pSolHdl();
501 
502  if (expectedMeasures.size() != incrControls.size()) {
503  return -1;
504  }
505 
506  for (unsigned int i = 0; i < incrControls.size(); i++) {
507  Xref[i] = io.Controls()[i];
508  }
509 
510  for (unsigned int i = 0; i < expectedMeasures.size(); i++) {
511  Fref[i] = io.Measures()[i];
512  }
513 
514  for (unsigned int c = 0; c < incrControls.size(); c++) {
515  for (unsigned int i = 0; i < incrControls.size(); i++) {
516  X[i] = Xref[i];
517  }
518  X[c] += incrControls[c];
519 
520  te.FuncEval(X, F, 10, 1000);
521 
522  for (unsigned int i = 0; i < expectedMeasures.size(); i++) {
523  pM->PutCoef(i + 1, c + 1, F[i] - Fref[i]);
524  }
525  }
526 
527  while (!pcc->Check(io.Measures())) {
528  for (unsigned int i = 0; i < expectedMeasures.size(); i++) {
529  pR->PutCoef(i + 1, expectedMeasures[i] - Fref[i]);
530  }
531 
532  psm->Solve();
533 
534  for (unsigned int i = 0; i < incrControls.size(); i++) {
535  X[i] = Xref[i] + pX->operator()(i + 1);
536  Xref[i] = X[i];
537  }
538 
539  te.FuncEval(X, F, 10, 1000);
540 
541  for (unsigned int i = 0; i < expectedMeasures.size(); i++) {
542  Fref[i] = F[i];
543  }
544  }
545 
546  return 0;
547 }
548 
549 int
550 main(int argc, char *argv[])
551 {
552  IO io(argc, argv);
553  if (io.nControls() != 4) {
554  silent_cerr("need 4 controls" << std::endl);
555  throw;
556  }
557 
558  NRTrim trim(io, 4, 1.e-6);
559 
560  std::vector<double> F(4, 0.);
561  std::vector<double> I(4, 0.);
562  std::vector<double> X(4, 0.);
563 
564  F[0] = .6;
565  F[1] = .0;
566  F[2] = .0;
567  F[3] = 260.;
568 
569  I[0] = .5/180*M_PI;
570  I[1] = .5/180*M_PI;
571  I[2] = .5/180*M_PI;
572  I[3] = .1/180*M_PI;
573 
574  trim.DoTrim(F, I, X);
575 }
576 
virtual VectorHandler * pResHdl(void) const =0
NRTrim(IO &io, int n, double t)
Definition: trim.cc:479
virtual ~BasicIO(void)
Definition: trim.cc:65
#define M_PI
Definition: gradienttest.cc:67
Definition: trim.cc:159
virtual bool Check(const std::vector< double > &measures)=0
std::string buf
Definition: s2s.h:68
int nControls(void) const
Definition: trim.cc:172
TrimEval(IO &io, ConvergenceCheck &cc)
Definition: trim.cc:422
int Parse(int argc, char *argv[])
Definition: trim.cc:193
ConvergenceCheck * pcc
Definition: trim.cc:468
SolutionManager *const GetSolutionManager(integer iNLD, integer iLWS=0) const
Definition: linsol.cc:455
~FFDConvergenceCheck(void)
Definition: trim.cc:377
int Setup(int argc, char *argv[])
Definition: trim.cc:275
int SendControls(s2s_t &s2s)
Definition: trim.cc:117
BasicIO & measures
Definition: trim.cc:162
int DoTrim(const std::vector< double > expectedMeasures, const std::vector< double > incrControls, std::vector< double > controls)
Definition: trim.cc:487
#define NO_OP
Definition: myassert.h:74
std::vector< double > prevDiff
Definition: trim.cc:372
int nMeasures(void) const
Definition: trim.cc:171
BasicIO & controls
Definition: trim.cc:164
void prepare(void)
int SendControls(void)
Definition: trim.cc:181
Definition: linsol.h:39
int nChannels
Definition: s2s.h:56
virtual ~ConvergenceCheck(void)
Definition: trim.cc:363
~NRTrim(void)
Definition: trim.cc:472
int SendControls(s2s_t &s2s)
Definition: trim.cc:147
const std::vector< double > & Measures(void) const
Definition: trim.cc:177
int ReadMeasures(s2s_t &s2s)
Definition: trim.cc:131
~TrimEval(void)
Definition: trim.cc:423
static StreamBasicIO stream_basic_IO
Definition: trim.cc:84
virtual MatrixHandler * pMatHdl(void) const =0
Definition: trim.cc:63
std::vector< double > dbuf
Definition: s2s.h:69
IO(void)
Definition: trim.cc:167
int sock
Definition: s2s.h:66
s2s_t s2s_controls
Definition: trim.cc:163
virtual void PutCoef(integer iRow, integer iCol, const doublereal &dCoef)
Definition: mh.cc:384
virtual void Solve(void)=0
const char * path
Definition: s2s.h:57
int ReadMeasures(s2s_t &s2s)
Definition: trim.cc:87
int main(int argc, char *argv[])
Definition: trim.cc:550
double tol
Definition: trim.cc:359
GradientExpression< UnaryExpr< FuncSqrt, Expr > > sqrt(const GradientExpression< Expr > &u)
Definition: gradient.h:2974
virtual void PutCoef(integer iRow, const doublereal &dCoef)=0
ConvergenceCheck & cc
Definition: trim.cc:419
static SocketBasicIO socket_basic_IO
Definition: trim.cc:76
s2s_t s2s_measures
Definition: trim.cc:161
std::vector< double > prevMeasures
Definition: trim.cc:371
static std::stack< cleanup * > c
Definition: cleanup.cc:59
int getopt(int argc, char *const argv[], const char *opts)
Definition: getopt.c:93
#define STRLENOF(s)
Definition: mbdyn.h:166
int ReadMeasures(void)
Definition: trim.cc:180
virtual int SendControls(s2s_t &s2s)=0
const char * host
Definition: s2s.h:59
ConvergenceCheck(int n, double t)
Definition: trim.cc:362
Definition: s2s.h:54
std::vector< double > diff
Definition: trim.cc:373
virtual int ReadMeasures(s2s_t &s2s)=0
IO & io
Definition: trim.cc:418
Definition: trim.cc:465
std::vector< double > & Controls(void)
Definition: trim.cc:178
char * optarg
Definition: getopt.c:74
virtual VectorHandler * pSolHdl(void) const =0
~IO(void)
Definition: trim.cc:169
static doublereal buf[BUFSIZE]
Definition: discctrl.cc:333
IO & io
Definition: trim.cc:467
FFDConvergenceCheck(int n, double t, double r)
Definition: trim.cc:382
bool Check(const std::vector< double > &measures)
Definition: trim.cc:393
int FuncEval(std::vector< double > &X, std::vector< double > &F, int nSteps, int maxSteps)
Definition: trim.cc:429