MBDyn-1.7.3
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups
test_modalext_edge.c
Go to the documentation of this file.
1 /* $Header: /var/cvs/mbdyn/mbdyn/mbdyn-1.0/utils/test_modalext_edge.c,v 1.22 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 <stdlib.h>
33 #include <stdio.h>
34 #include <unistd.h>
35 #include <string.h>
36 #include <strings.h>
37 #include <signal.h>
38 #include <errno.h>
39 
40 #include "mbsleep.h"
41 
42 volatile sig_atomic_t keep_going = 1;
43 
45 int sleeptime = 1;
47 int verbose;
48 enum {
49  RM,
51 } order = RM;
52 
53 static void
54 sh(int signum)
55 {
56  keep_going = 0;
57  signal(signum, SIG_DFL);
58 }
59 
60 static const char *cmd2str(int cmd)
61 {
62  switch (cmd) {
63  case 0:
64  return "EDGE is initializing; MBDyn waits";
65 
66  case 1:
67  return "EDGE is busy; MBDyn waits";
68 
69  case 2:
70  return "EDGE waits (is ready to read kinematics); MBDyn iterates";
71 
72  case 3:
73  return "EDGE is computing; MBDyn waits before reading forces";
74 
75  case 4:
76  return "EDGE converged; MBDyn advances one step";
77 
78  case 5:
79  return "EDGE wants to end simulation";
80 
81  default:
82  return "unknown";
83  }
84 }
85 
86 static int
87 check_flag(const char *flag, int sleeptime)
88 {
89  int rc;
90 
91  while (1) {
92  char buf[BUFSIZ];
93  FILE *f;
94  char c = ' ';
95 
96  f = fopen(flag, "r");
97  if (f == NULL && errno == ENOENT) {
98  fprintf(stderr, "test_modalext_edge: file \"%s\" missing\n", flag);
99  return 1;
100  }
101 
102  fgets(buf, sizeof(buf), f);
103  if (strcmp(buf, "UPDATE,N,0,0,1\n") != 0) {
104  size_t len = strlen(buf);
105  buf[len - 1] = '\0';
106  fprintf(stderr, "test_modalext_edge: expecting \"UPDATE,N,0,0,1\", got \"%s\" from file \"%s\"\n", buf, flag);
107  fclose(f);
108  return -1;
109  }
110  fgets(buf, sizeof(buf), f);
111  if (strcmp(buf, "FLAG,I,1,1,0\n") != 0) {
112  size_t len = strlen(buf);
113  buf[len - 1] = '\0';
114  fprintf(stderr, "test_modalext_edge: expecting \"FLAG,I,1,1,0\", got \"%s\" from file \"%s\"\n", buf, flag);
115  fclose(f);
116  return -1;
117  }
118  rc = fread((void *)&c, 1, 1, f);
119  fclose(f);
120  if (rc == 1) {
121  fprintf(stderr, "test_modalext_edge: got %c (%s) from file \"%s\"\n", c, cmd2str(c - '0'), flag);
122 
123  switch (c) {
124  case '0':
125  case '1':
126  case '3':
127  return 0;
128 
129  case '5':
130  return 1;
131 
132  default:
133  break;
134  }
135  }
136 
137  if (sleeptime) {
138  fprintf(stderr, "test_modalext_edge: sleeping %d s\n", sleeptime);
139  mbsleep(&mbt);
140  }
141  }
142 
143  return 0;
144 }
145 
146 static int
147 put_flag(const char *flag, int cmd)
148 {
149  FILE *f;
150  char ftmpname[] = "mbedgeXXXXXX";
151 
152 #ifdef HAVE_MKSTEMP
153  if (do_rename) {
154  int filedes = mkstemp(ftmpname);
155  f = fdopen(filedes, "w");
156 
157  } else
158 #endif // HAVE_MKSTEMP
159  {
160  f = fopen(flag, "w");
161  }
162 
163  if (f == NULL) {
164  int save_errno = errno;
165  fprintf(stderr, "unable to open flag file \"%s\" for writing (%d: %s)\n",
166  flag, save_errno, strerror(save_errno));
167  exit(EXIT_FAILURE);
168  }
169 
170  fprintf(f, "UPDATE,N,0,0,1\n");
171  fprintf(f, "FLAG,I,1,1,0\n");
172  fprintf(f, "%d", cmd);
173  fclose(f);
174 
175  if (do_rename) {
176 retry:;
177  if (rename(ftmpname, flag) == -1) {
178  switch (errno) {
179  case EBUSY:
180  mbsleep(&mbt);
181  goto retry;
182 
183  default: {
184  int save_errno = errno;
185  fprintf(stderr, "unable to rename flag file \"%s\" (errno=%d: %s)\n",
186  flag, save_errno, strerror(save_errno));
187  exit(EXIT_FAILURE);
188  }
189  }
190  }
191  }
192 
193  return 0;
194 }
195 
196 static int
197 put_rdata(const char *rdata, double fm[6])
198 {
199  FILE *f;
200  int i;
201 
202  f = fopen(rdata, "w");
203  if (f == NULL) {
204  int save_errno = errno;
205 
206  fprintf(stderr, "unable to open rigid data file \"%s\" (%d: %s)\n",
207  rdata, save_errno, strerror(save_errno));
208  exit(EXIT_FAILURE);
209  }
210 
211  fprintf(f,
212  "* rigid-body forces and moments\n"
213  "body_forces,R,1,6,0\n");
214  for (i = 0; i < 6; i++) {
215  fprintf(f, "%e ", fm[i]);
216  }
217  fputc('\n', f);
218  fclose(f);
219 
220  return 0;
221 }
222 
223 static int
224 put_mdata(const char *mdata, int modes, double *fg)
225 {
226  FILE *f;
227  int i;
228 
229  f = fopen(mdata, "w");
230  if (f == NULL) {
231  int save_errno = errno;
232 
233  fprintf(stderr, "unable to open modal data file \"%s\" (%d: %s)\n",
234  mdata, save_errno, strerror(save_errno));
235  exit(EXIT_FAILURE);
236  }
237 
238  fprintf(f,
239  "* modal forces\n"
240  "modal_force_flow,R,%d,1,0\n",
241  modes);
242  for (i = 0; i < modes; i++) {
243  fprintf(f, "%e ", fg[i]);
244  }
245  fputc('\n', f);
246  fclose(f);
247 
248  return 0;
249 }
250 
251 static int
252 do_rigid0(const char *rflag, const char *rdata, double *fm)
253 {
254  if (rflag != NULL) {
255  FILE *f = NULL;
256  int i;
257 
258  f = fopen(rflag, "r");
259  if (f == NULL) {
260  int save_errno = errno;
261  if (save_errno == ENOENT) {
262  put_flag(rflag, 0);
263 
264  } else {
265  fprintf(stderr, "unable to open rigid flag file \"%s\" (%d: %s)\n",
266  rflag, save_errno, strerror(save_errno));
267  exit(EXIT_FAILURE);
268  }
269 
270  } else {
271  fclose(f);
272  }
273 
274  for (i = 0; i < 6; i++) {
275  fm[i] = 0.1*(i + 1);
276  }
277 
278  put_rdata(rdata, fm);
279  }
280 
281  return 0;
282 }
283 
284 static int
285 do_modal0(const char *mflag, const char *mdata, int modes, double **fgp)
286 {
287  if (mflag != NULL) {
288  FILE *f = NULL;
289  int i;
290 
291  f = fopen(mflag, "r");
292  if (f == NULL) {
293  int save_errno = errno;
294  if (save_errno == ENOENT) {
295  put_flag(mflag, 0);
296 
297  } else {
298  fprintf(stderr, "unable to open modal flag file \"%s\" (%d: %s)\n",
299  mflag, save_errno, strerror(save_errno));
300  exit(EXIT_FAILURE);
301  }
302 
303  } else {
304  fclose(f);
305  }
306 
307  *fgp = (double *)malloc(sizeof(double)*modes);
308  for (i = 0; i < modes; i++) {
309  (*fgp)[i] = ((double)i)/10.0;
310  }
311 
312  put_mdata(mdata, modes, *fgp);
313  }
314 
315  return 0;
316 }
317 
318 int
319 do_rigid(const char *rflag, const char *rdata,
320  int niters, int *iterp, int cmd,
321  double *fm)
322 {
323  /* rigid */
324  if (rflag != NULL) {
325  if (check_flag(rflag, sleeptime)) {
326  *iterp = niters;
327  keep_going = 0;
328  return 0;
329  }
330 
331  if (verbose) {
332  char buf[BUFSIZ];
333  FILE *f;
334 
335  f = fopen(rdata, "r");
336  if (f == NULL) {
337  int save_errno = errno;
338 
339  fprintf(stderr, "unable to open rigid data file \"%s\" (%d: %s)\n",
340  rdata, save_errno, strerror(save_errno));
341  exit(EXIT_FAILURE);
342  }
343 
344  while (fgets(buf, sizeof(buf), f) != NULL) {
345  fprintf(stderr, ">> rdata:%s", buf);
346  }
347 
348  fclose(f);
349  }
350 
351  put_rdata(rdata, fm);
352  put_flag(rflag, cmd);
353  }
354 
355  return 0;
356 }
357 
358 int
359 do_modal(const char *mflag, const char *mdata,
360  int niters, int *iterp, int cmd,
361  int modes, double *fg)
362 {
363  /* modal */
364  if (mflag != NULL) {
365  if (check_flag(mflag, sleeptime)) {
366  *iterp = niters;
367  keep_going = 0;
368  return 0;
369  }
370 
371  if (verbose) {
372  char buf[BUFSIZ];
373  FILE *f;
374 
375  f = fopen(mdata, "r");
376  if (f == NULL) {
377  int save_errno = errno;
378 
379  fprintf(stderr, "unable to open modal data file \"%s\" (%d: %s)\n",
380  mdata, save_errno, strerror(save_errno));
381  exit(EXIT_FAILURE);
382  }
383 
384  while (fgets(buf, sizeof(buf), f) != NULL) {
385  fprintf(stderr, ">> mdata:%s", buf);
386  }
387 
388  fclose(f);
389  }
390 
391  put_mdata(mdata, modes, fg);
392  put_flag(mflag, cmd);
393  }
394 
395  return 0;
396 }
397 
398 void
399 usage(void)
400 {
401  fprintf(stderr,
402  "usage: test_modalext_edge [options]\n"
403  "\t-c [random:]<c>\t\tnumber of iterations\n"
404  "\t-m [flag|data]=<file>\tmodal file names (set both)\n"
405  "\t-M <modes>\t\tmodes number\n"
406  "\t-n\t\t\tuse \"rename\" when writing flag files\n"
407  "\t-o {rm|mr}\tprocess rigid,modal (rm) or modal,rigid (mr)\n"
408  "\t-r [flag|data]=<file>\trigid-body file names (set both)\n"
409  "\t-s <sleeptime>\t\tsleep time between tries\n"
410  "\t-v\t\t\tverbose\n" );
411  exit(EXIT_FAILURE);
412 }
413 
414 int
415 main(int argc, char *argv[])
416 {
417  char *rflag = NULL;
418  char *rdata = NULL;
419  char *mflag = NULL;
420  char *mdata = NULL;
421  int iters = 1;
422  int iters_random = 0;
423  unsigned steps;
424  int modes = 5;
425  double fm[6];
426  double *fg = NULL;
427 
428  while (1) {
429  int opt = getopt(argc, argv, "c:m:M:no:r:s:v");
430 
431  if (opt == EOF) {
432  break;
433  }
434 
435  switch (opt) {
436  case 'c':
437  if (strncasecmp(optarg, "random:", sizeof("random:") -1) == 0) {
438  iters_random = 1;
439  iters = atoi(&optarg[sizeof("random:") -1]);
440 
441  } else {
442  iters = atoi(optarg);
443  fprintf(stderr, "iterations: %d\n", iters);
444  }
445  if (iters < 1) {
446  fprintf(stderr, "test_modalext_edge: "
447  "invalid sleep time %s\n",
448  optarg);
449  usage();
450  }
451  break;
452 
453  case 'm':
454  if (strncasecmp(optarg, "flag=", sizeof("flag=") - 1) == 0) {
455  mflag = &optarg[sizeof("flag=") - 1];
456 
457  } else if (strncasecmp(optarg, "data=", sizeof("data=") - 1) == 0) {
458  mdata = &optarg[sizeof("data=") - 1];
459 
460  } else {
461  fprintf(stderr, "test_modalext_edge: "
462  "unknown modal file \"%s\"\n",
463  optarg);
464  usage();
465  }
466  break;
467 
468  case 'M':
469  modes = atoi(optarg);
470  if (modes <= 0) {
471  fprintf(stderr, "test_modalext_edge: "
472  "invalid mode number %s\n",
473  optarg);
474  usage();
475  }
476  break;
477 
478  case 'n':
479 #ifdef HAVE_MKSTEMP
480  do_rename++;
481 #else // ! HAVE_MKSTEMP
482  fprintf(stderr, "test_modalext_edge: "
483  "'-n' meaningless\n");
484 #endif // ! HAVE_MKSTEMP
485  break;
486 
487  case 'o':
488  if (strcmp(optarg, "rm") == 0) {
489  order = RM;
490 
491  } else if (strcmp(optarg, "mr") == 0) {
492  order = MR;
493 
494  } else {
495  fprintf(stderr, "test_modalext_edge: "
496  "invalid order \"%s\"\n",
497  optarg);
498  usage();
499  }
500  break;
501 
502  case 'r':
503  if (strncasecmp(optarg, "flag=", sizeof("flag=") - 1) == 0) {
504  rflag = &optarg[sizeof("flag=") - 1];
505 
506  } else if (strncasecmp(optarg, "data=", sizeof("data=") - 1) == 0) {
507  rdata = &optarg[sizeof("data=") - 1];
508 
509  } else {
510  fprintf(stderr, "test_modalext_edge: "
511  "unknown rigid file \"%s\"\n",
512  optarg);
513  usage();
514  }
515  break;
516 
517  case 's':
518  sleeptime = atoi(optarg);
519  if (sleeptime < 0) {
520  fprintf(stderr, "test_modalext_edge: "
521  "invalid iters %s\n",
522  optarg);
523  usage();
524  }
525  mbt = mbsleep_init(sleeptime);
526  break;
527 
528  case 'v':
529  verbose++;
530  break;
531 
532  default:
533  usage();
534  }
535  }
536 
537  if (mflag == NULL && mdata != NULL) {
538  fprintf(stderr, "test_modalext_edge: "
539  "need modal flag file "
540  "along with modal data file \"%s\"\n",
541  mdata);
542  usage();
543  }
544 
545  if (mflag != NULL && mdata == NULL) {
546  fprintf(stderr, "test_modalext_edge: "
547  "need modal data file "
548  "along with modal flag file \"%s\"\n",
549  mflag);
550  usage();
551  }
552 
553  if (rflag == NULL && rdata != NULL) {
554  fprintf(stderr, "test_modalext_edge: "
555  "need rigid flag file "
556  "along with rigid data file \"%s\"\n",
557  rdata);
558  usage();
559  }
560 
561  if (rflag != NULL && rdata == NULL) {
562  fprintf(stderr, "test_modalext_edge: "
563  "need rigid data file "
564  "along with rigid flag file \"%s\"\n",
565  rflag);
566  usage();
567  }
568 
569  if (mflag == NULL && rflag == NULL) {
570  fprintf(stderr, "test_modalext_edge: "
571  "need at least rigid or modal files\n");
572  usage();
573  }
574 
575  signal(SIGTERM, sh);
576  signal(SIGINT, sh);
577 
578  switch (order) {
579  case RM:
580  do_rigid0(rflag, rdata, fm);
581  do_modal0(mflag, mdata, modes, &fg);
582  break;
583 
584  case MR:
585  do_modal0(mflag, mdata, modes, &fg);
586  do_rigid0(rflag, rdata, fm);
587  break;
588  }
589 
590  for (steps = 0; keep_going > 0; steps++) {
591  int iter;
592  int niters;
593 
594  if (iters_random) {
595  niters = rand() % iters + 1;
596  fprintf(stderr, " iterations within this iter: %d\n", niters);
597 
598  } else {
599  niters = iters;
600  }
601 
602  for (iter = 0; iter < niters; iter++) {
603  int cmd = 2;
604 
605  if (iter == niters - 1) {
606  cmd = 4;
607  }
608 
609  switch (order) {
610  case RM:
611  do_rigid(rflag, rdata, niters, &iter, cmd, fm);
612  do_modal(mflag, mdata, niters, &iter, cmd, modes, fg);
613  break;
614 
615  case MR:
616  do_modal(mflag, mdata, niters, &iter, cmd, modes, fg);
617  do_rigid(rflag, rdata, niters, &iter, cmd, fm);
618  break;
619  }
620 
621  }
622  }
623 
624  if (rflag != NULL) {
625  put_flag(rflag, 5);
626  }
627 
628  if (mflag != NULL) {
629  put_flag(mflag, 5);
630  }
631 
632  return 0;
633 }
mbsleep_t mbt
long int flag
Definition: mbdyn.h:43
static int iters
int do_rigid(const char *rflag, const char *rdata, int niters, int *iterp, int cmd, double *fm)
int verbose
int mbsleep(const mbsleep_t *t)
Definition: mbsleep.c:90
unsigned long mbsleep_t
Definition: mbsleep.h:51
int main(int argc, char *argv[])
static int put_mdata(const char *mdata, int modes, double *fg)
static int put_flag(const char *flag, int cmd)
static int iters_random
int do_modal(const char *mflag, const char *mdata, int niters, int *iterp, int cmd, int modes, double *fg)
void usage(void)
enum @55 order
int do_rename
static void sh(int signum)
static int do_modal0(const char *mflag, const char *mdata, int modes, double **fgp)
mbsleep_t mbsleep_init(long t)
Definition: mbsleep.c:38
static const char * cmd2str(int cmd)
static int put_rdata(const char *rdata, double fm[6])
volatile sig_atomic_t keep_going
static std::stack< cleanup * > c
Definition: cleanup.cc:59
int getopt(int argc, char *const argv[], const char *opts)
Definition: getopt.c:93
int sleeptime
static int do_rigid0(const char *rflag, const char *rdata, double *fm)
static unsigned steps
static int check_flag(const char *flag, int sleeptime)
char * optarg
Definition: getopt.c:74
static doublereal buf[BUFSIZE]
Definition: discctrl.cc:333