FrontISTR  5.7.0
Large-scale structural analysis program with finit element method
CHECData.cpp
Go to the documentation of this file.
1 /*****************************************************************************
2  * Copyright (c) 2019 FrontISTR Commons
3  * This software is released under the MIT License, see LICENSE.txt
4  *****************************************************************************/
5 /*
6  CHECData Ver.1.0
7 */
8 
9 #include <stdarg.h>
10 #include <assert.h>
11 #include "CHECData.h"
12 #include "hecd_util.h"
13 
14 using namespace std;
15 using namespace hecd_util;
16 
17 //=============================================================================
18 // common
19 //=============================================================================
20 
22 
23 CHECData::~CHECData() { Clear(); }
24 
26  vector<CHECDataBlock *>::iterator iter;
27 
28  for (iter = DB.begin(); iter != DB.end(); iter++) {
29  delete *iter;
30  }
31 
32  DB.clear();
33 }
34 
35 void CHECData::StoreDataBlock(CHECDataBlock *block) { DB.push_back(block); }
36 
37 //=============================================================================
38 // Save
39 //=============================================================================
40 
41 bool CHECData::Save(const char *file_name) {
42  strcpy(fname, file_name);
43  fp = fopen(fname, "w");
44 
45  if (!fp) return false;
46 
47  vector<CHECDataBlock *>::iterator iter;
48 
49  for (iter = DB.begin(); iter != DB.end(); iter++) {
50  (*iter)->Write(this);
51  }
52 
53  fclose(fp);
54  fp = 0;
55  return true;
56 }
57 
58 void CHECData::WriteLine(const char *s) { fprintf(fp, "%s\n", s); }
59 
60 // ----------------------------------------------------------------------------
61 // Header Line
62 // ----------------------------------------------------------------------------
63 // fmt : format of parameters.
64 // Each character specify the parameter's type
65 // 'I': integer, 'F':float, 'S':string
66 // ... : pairs of parameter name and value
67 
68 void CHECData::WriteHeader(const char *name, const char *fmt, ...) {
69  va_list va;
70  va_start(va, fmt);
71  int n = strlen(fmt);
72  char *c = (char *)fmt;
73  char line[256];
74  char param[256];
75  char s[256];
76  strcpy(line, name);
77 
78  for (int i = 0; i < n; i++, c++) {
79  strcpy(param, va_arg(va, char *));
80  strcat(line, ",");
81  strcat(line, param);
82  strcat(line, "=");
83 
84  switch (*c) {
85  case 'I':
86  sprintf(s, "%d", va_arg(va, int));
87  break;
88 
89  case 'F':
90  // sprintf(s, "%lg", va_arg(va, double));
91  ftos(va_arg(va, double), s);
92  break;
93 
94  case 'S':
95  sprintf(s, "%s", va_arg(va, char *));
96  break;
97 
98  default:
99  assert(0);
100  }
101 
102  strcat(line, s);
103  }
104 
105  fprintf(fp, "%s\n", line);
106  va_end(va);
107 }
108 
109 // ----------------------------------------------------------------------------
110 // Parameter Line
111 // ----------------------------------------------------------------------------
112 
113 void CHECData::WriteParameter(const char *fmt, ...) {
114  va_list va;
115  va_start(va, fmt);
116  int n = strlen(fmt);
117  char *c = (char *)fmt;
118  char line[256];
119  char param[256];
120  char s[256];
121  strcpy(line, "!");
122 
123  for (int i = 0; i < n; i++, c++) {
124  strcpy(param, va_arg(va, char *));
125 
126  if (i != 0) strcat(line, ",");
127 
128  strcat(line, param);
129  strcat(line, "=");
130 
131  switch (*c) {
132  case 'I':
133  sprintf(s, "%d", va_arg(va, int));
134  break;
135 
136  case 'F':
137  // sprintf(s, "%lg", va_arg(va, double));
138  ftos(va_arg(va, double), s);
139  break;
140 
141  case 'S':
142  sprintf(s, "%s", va_arg(va, char *));
143  break;
144 
145  default:
146  assert(0);
147  }
148 
149  strcat(line, s);
150  }
151 
152  fprintf(fp, "%s\n", line);
153  va_end(va);
154 }
155 
156 // ----------------------------------------------------------------------------
157 // Data Line
158 // ----------------------------------------------------------------------------
159 // fmt : format of data like one of WriteHeader
160 // ... : values to write the file.
161 
162 void CHECData::WriteData(const char *fmt, ...) {
163  va_list va;
164  va_start(va, fmt);
165  int n = strlen(fmt);
166  char *c = (char *)fmt;
167  char line[256];
168  char s[256];
169  line[0] = 0;
170 
171  for (int i = 0; i < n; i++, c++) {
172  if (i != 0) strcat(line, ",");
173 
174  switch (*c) {
175  case 'I':
176  sprintf(s, "%d", va_arg(va, int));
177  break;
178 
179  case 'F':
180  // sprintf(s, "%lg", va_arg(va, double));
181  ftos(va_arg(va, double), s);
182  break;
183 
184  case 'S':
185  sprintf(s, "%s", va_arg(va, char *));
186  break;
187 
188  default:
189  assert(0);
190  }
191 
192  strcat(line, s);
193  }
194 
195  fprintf(fp, "%s\n", line);
196  va_end(va);
197 }
198 
199 void CHECData::ClearDataLineBuffer() { data_line_buffer[0] = 0; }
200 
201 void CHECData::AddDataLineItems(const char *fmt, ...) {
202  va_list va;
203  va_start(va, fmt);
204  int n = strlen(fmt);
205  char *c = (char *)fmt;
206  char s[256];
207 
208  for (int i = 0; i < n; i++, c++) {
209  switch (*c) {
210  case 'I':
211  sprintf(s, "%d", va_arg(va, int));
212  break;
213 
214  case 'F':
215  // sprintf(s, "%lg", va_arg(va, double));
216  ftos(va_arg(va, double), s);
217  break;
218 
219  case 'S':
220  sprintf(s, "%s", va_arg(va, char *));
221  break;
222 
223  default:
224  assert(0);
225  }
226 
227  strcat(data_line_buffer, s);
228  strcat(data_line_buffer, ",");
229  }
230 
231  va_end(va);
232 }
233 
235  int len = strlen(data_line_buffer);
236  char *p = &data_line_buffer[len - 1];
237 
238  // remove ',' of tail
239  while (p >= data_line_buffer) {
240  if (*p == ',') {
241  *p = 0;
242  break;
243 
244  } else if (*p == ' ') {
245  *p = 0;
246 
247  } else {
248  break;
249  }
250 
251  p--;
252  }
253 
254  fprintf(fp, "%s\n", data_line_buffer);
255  ClearDataLineBuffer();
256 }
257 
258 //=============================================================================
259 // Load
260 //=============================================================================
261 
262 bool CHECData::Load(const char *file_name) {
263  Clear();
264  return AddLoad(file_name);
265 }
266 
267 bool CHECData::AddLoad(const char *file_name) {
268  line_count = 0;
269  fg_header_pushed = false;
270  strcpy(fname, file_name);
271  fp = fopen(fname, "r");
272 
273  if (!fp) return false;
274 
275  char line[256];
276  char header_name[256];
277  CHECDataBlock *block;
278 
279  while (ReadLine(line)) {
280  if (!GetHeaderName(line, header_name)) {
281  fclose(fp);
282  return false;
283  }
284 
285  if (strcmp(header_name, "!END") == 0) break;
286 
287  block = CreateDataBlock(header_name);
288 
289  if (!block) {
290  fclose(fp);
291  return false;
292  }
293 
294  if (!block->Read(this, line)) {
295  fclose(fp);
296  return false;
297  }
298 
299  DB.push_back(block);
300  }
301 
302  fclose(fp);
303  fp = 0;
304  return true;
305 }
306 
307 bool CHECData::ReadLine(char *s, int size) {
308  line_count++;
309 
310  if (fg_header_pushed) {
311  strcpy(s, header_line_buffer);
312  fg_header_pushed = false;
313  return true;
314  }
315 
316  while (fgets(s, size, fp)) {
317  if (s[0] == 0 || s[0] == '#' || s[0] == '\r' || s[0] == '\n') continue;
318 
319  if (s[0] == '!' && s[1] == '!') continue;
320 
321  remove_cr(s);
322  return true;
323  }
324 
325  return false;
326 }
327 
328 void CHECData::PushReadLine(const char *s) {
329  strcpy(header_line_buffer, s);
330  fg_header_pushed = true;
331  line_count--;
332 }
333 
334 CHECDataBlock *CHECData::CreateDataBlock(const char *header_name) {
335  return CreateHECDataBlock(header_name);
336 }
337 
338 bool CHECData::GetHeaderName(const char *header_line, char *header_name) {
339 #define is_separator(x) \
340  (x == ',' || x == ' ' || x == '\t' || x == '\r' || x == '\n')
341  char *p = (char *)header_line;
342 
343  while (*p && is_separator(*p)) p++;
344 
345  if (*p != '!') return false;
346 
347  char *bp = header_name;
348 
349  while (*p && !is_separator(*p)) {
350  *bp = (char)toupper(*p);
351  p++;
352  bp++;
353  }
354 
355  *bp = 0;
356  return true;
357 #undef is_separator
358 }
359 
360 //-----------------------------------------------------------------------------
361 // ParseHeader
362 //-----------------------------------------------------------------------------
363 // rcode[i] : 1 -- set, 0 -- not set, -1 -- error
364 // fmt : string composed by following characters
365 // 'I' : int
366 // 'F' : double
367 // 'S' : char*
368 // 'E' : int (exist or not)
369 // ... : pairs of a parameter name and a pointer of the parameter
370 // example)
371 // char* line = "!SOLVER, TYPE=CG, PRECOND=1, ITERLOG=YES";
372 // int rcode[3];
373 // char type[30]; int precond; char iterlog[30];
374 // ParseHeader(line,rcode,"SIS","TYPE",type,"PRECOND",&precond,"ITERLOG",iterlog);
375 //-----------------------------------------------------------------------------
376 
377 static bool get_param_token(char *&p, char *token) {
378 #define is_separator(x) \
379  (x == ',' || x == ' ' || x == '\t' || x == '\r' || x == '\n')
380 
381  while (*p && is_separator(*p)) p++;
382 
383  if (!*p) return false;
384 
385  char *t = token;
386 
387  if (*p == '=') {
388  t[0] = '=';
389  t[1] = 0;
390  p++;
391  return true;
392  }
393 
394  while (*p && is_separator(*p)) p++;
395 
396  if (!*p) return false;
397 
398  while (*p && !is_separator(*p) && *p != '=') {
399  *t = *p;
400  t++;
401  p++;
402  }
403 
404  *t = 0;
405  return true;
406 }
407 
408 bool CHECData::vParseParameter(char *line, int *rcode, const char *fmt,
409  va_list va) {
410  const int max_param_n = 40;
411  char param_name[max_param_n][20];
412  void *param[max_param_n];
413  int param_n = strlen(fmt);
414  int i;
415  int *ip;
416 
417  for (i = 0; i < param_n; i++) {
418  strcpy(param_name[i], va_arg(va, char *));
419  param[i] = va_arg(va, void *);
420  rcode[i] = 0;
421 
422  if (fmt[i] == 'E') {
423  ip = (int *)param[i];
424  *ip = 0;
425  }
426  }
427 
428  char *p = line;
429  char p_token[50];
430  char eq_token[50];
431  char v_token[50];
432  char p_str[50];
433 
434  while (get_param_token(p, p_token)) {
435  cleanup_token(p_token, p_str);
436  toupper(p_str);
437 
438  for (i = 0; i < param_n; i++) {
439  if (strcmp(p_str, param_name[i]) == 0) break;
440  }
441 
442  if (i == param_n) return false;
443 
444  // ---------------------------------
445  if (fmt[i] == 'E') {
446  rcode[i] = 1;
447  ip = (int *)param[i];
448  *ip = 1;
449  continue;
450  }
451 
452  // ---------------------------------
453  if (!get_param_token(p, eq_token) || eq_token[0] != '=') {
454  rcode[i] = -1;
455  return false;
456  }
457 
458  if (!get_param_token(p, v_token)) {
459  rcode[i] = -1;
460  return false;
461  }
462 
463  switch (fmt[i]) {
464  case 'S':
465  if (sscanf(v_token, "%s", (char *)(param[i])) != 1) {
466  rcode[i] = -1;
467  return false;
468  }
469 
470  break;
471 
472  case 'I':
473  if (sscanf(v_token, "%d", (int *)(param[i])) != 1) {
474  rcode[i] = -1;
475  return false;
476  }
477 
478  break;
479 
480  case 'F':
481  if (sscanf(v_token, "%lf", (double *)(param[i])) != 1) {
482  rcode[i] = -1;
483  return false;
484  }
485 
486  break;
487 
488  default:
489  assert(0);
490  }
491 
492  rcode[i] = 1;
493  }
494 
495  return true;
496 }
497 
498 bool CHECData::ParseParameter(char *line, int *rcode, const char *fmt, ...) {
499  va_list va;
500  va_start(va, fmt);
501  bool fg = vParseParameter(line, rcode, fmt, va);
502  va_end(va);
503  return fg;
504 }
505 
506 bool CHECData::ParseHeader(char *header_line, int *rcode, const char *fmt,
507  ...) {
508  char *p = header_line;
509 
510  while (*p) {
511  if (*p == ',' || *p == '\r' || *p == '\n') {
512  break;
513  }
514 
515  p++;
516  }
517 
518  va_list va;
519  va_start(va, fmt);
520  bool fg = vParseParameter(p, rcode, fmt, va);
521  va_end(va);
522  return fg;
523 }
524 
525 bool CHECData::ReadParameter(int *rcode, const char *fmt, ...) {
526  char line[256];
527 
528  if (!ReadLine(line)) return false;
529 
530  char *p = line;
531 
532  if (*p == '!') p++;
533 
534  va_list va;
535  va_start(va, fmt);
536  bool fg = vParseParameter(p, rcode, fmt, va);
537  va_end(va);
538  return fg;
539 }
540 
541 //-----------------------------------------------------------------------------
542 // ReadData
543 //-----------------------------------------------------------------------------
544 // fmt : string composed by 'I', 'F' or 'S'
545 // ... : pointers of parameter
546 //-----------------------------------------------------------------------------
547 
548 bool CHECData::ReadData(int *rcode, const char *fmt, ...) {
549  char line[256];
550 
551  if (!ReadLine(line)) return false;
552 
553  if (line[0] == '!') {
554  PushReadLine(line);
555  return false;
556  }
557 
558  const int max_param_n = 100;
559  int i;
560  int param_n = strlen(fmt);
561  void *param[max_param_n];
562  va_list va;
563  va_start(va, fmt);
564 
565  for (i = 0; i < param_n; i++) {
566  param[i] = va_arg(va, void *);
567  rcode[i] = 0;
568  }
569 
570  va_end(va);
571  char *token = strtok(line, ",\r\n");
572  i = 0;
573 
574  while (token && i < param_n) {
575  switch (fmt[i]) {
576  case 'I':
577  if (sscanf(token, "%d", (int *)(param[i])) != 1) return false;
578 
579  break;
580 
581  case 'F':
582  if (sscanf(token, "%lf", (double *)(param[i])) != 1) return false;
583 
584  break;
585 
586  case 'S':
587  if (sscanf(token, "%s", (char *)(param[i])) != 1) return false;
588 
589  break;
590 
591  default:
592  assert(0);
593  }
594 
595  rcode[i] = 1;
596  token = strtok(0, ",\r\n");
597  i++;
598  }
599 
600  return true;
601 }
602 
603 int CHECData::ParseDoubleDataArray(char *line, double *data) {
604  int n = 0;
605  char *token = strtok(line, ",\r\n");
606 
607  while (token) {
608  if (sscanf(token, "%lf", &data[n]) != 1) return -(n + 1);
609 
610  n++;
611  token = strtok(0, ",\r\n");
612  }
613 
614  return n;
615 }
616 
617 int CHECData::ParseIntDataArray(char *line, int *data) {
618  int n = 0;
619  char *token = strtok(line, ",\r\n");
620 
621  while (token) {
622  if (sscanf(token, "%d", &data[n]) != 1) return -(n + 1);
623 
624  n++;
625  token = strtok(0, ",\r\n");
626  }
627 
628  return n;
629 }
630 
631 //=============================================================================
632 // Utility
633 //=============================================================================
634 
635 template <class T>
636 T hecdata_get(CHECData *hd, int data_type, const char *name) {
637  vector<CHECDataBlock *>::iterator iter;
638 
639  for (iter = hd->DB.begin(); iter != hd->DB.end(); iter++) {
640  if ((*iter)->data_type == data_type) {
641  T block = (T)(*iter);
642 
643  if (strcmp(block->name, name) == 0) {
644  return block;
645  }
646  }
647  }
648 
649  return 0;
650 }
651 
653  return hecdata_get<CHECDB_Material *>(this, HECDB_MATERIAL, name);
654 }
655 
656 CHECDB_NGroup *CHECData::GetNGroup(const char *name) {
657  return hecdata_get<CHECDB_NGroup *>(this, HECDB_NGROUP, name);
658 }
659 
660 CHECDB_EGroup *CHECData::GetEGroup(const char *name) {
661  return hecdata_get<CHECDB_EGroup *>(this, HECDB_EGROUP, name);
662 }
663 
664 CHECDB_SGroup *CHECData::GetSGroup(const char *name) {
665  return hecdata_get<CHECDB_SGroup *>(this, HECDB_SGROUP, name);
666 }
667 
669  vector<CHECDataBlock *>::iterator iter;
670 
671  for (iter = DB.begin(); iter != DB.end(); iter++) {
672  if ((*iter)->data_type != HECDB_NODE) continue;
673 
674  CHECDB_Node::CNodeItem *nitem = ((CHECDB_Node *)(*iter))->GetNode(id);
675 
676  if (nitem) return nitem;
677  }
678 
679  return 0;
680 }
681 
683  vector<CHECDataBlock *>::iterator iter;
684 
685  for (iter = DB.begin(); iter != DB.end(); iter++) {
686  if ((*iter)->data_type != HECDB_ELEMENT) continue;
687 
688  CHECDB_Element::CElemItem *eitem = ((CHECDB_Element *)(*iter))->GetElem(id);
689 
690  if (eitem) return eitem;
691  }
692 
693  return 0;
694 }
695 
697  vector<CHECDataBlock *>::iterator iter;
698 
699  for (iter = DB.begin(); iter != DB.end(); iter++) {
700  if ((*iter)->data_type != HECDB_ELEMENT) continue;
701 
702  CHECDB_Element::CElemItem *eitem = ((CHECDB_Element *)(*iter))->GetElem(id);
703 
704  if (eitem) return ((CHECDB_Element *)(*iter))->type;
705  }
706 
707  return 0;
708 }
CHECDataBlock
Definition: CHECDataBlock.h:17
CreateHECDataBlock
CHECDataBlock * CreateHECDataBlock(const char *header_name)
Definition: HECDB_util.cpp:16
CHECData::GetMaterial
virtual class CHECDB_Material * GetMaterial(const char *name)
Definition: CHECData.cpp:652
CHECData::ParseHeader
virtual bool ParseHeader(char *header_line, int *rcode, const char *fmt,...)
Definition: CHECData.cpp:506
CHECData.h
CHECDB_SGroup
Definition: CHECDB.h:228
CHECDataBlock::Read
virtual bool Read(class CHECData *hecd, char *header_line)=0
hecd_util::toupper
void toupper(char *s)
Definition: hecd_util.cpp:40
CHECData::CHECData
CHECData()
Definition: CHECData.cpp:21
CHECDB_Element::CElemItem
Definition: CHECDB.h:76
CHECData::GetSGroup
virtual class CHECDB_SGroup * GetSGroup(const char *name)
Definition: CHECData.cpp:664
HECDB_MATERIAL
@ HECDB_MATERIAL
Definition: CHECDB.h:24
CHECData::GetNodeItem
virtual class CHECDB_Node::CNodeItem * GetNodeItem(int id)
Definition: CHECData.cpp:668
CHECData::GetElemItem
virtual class CHECDB_Element::CElemItem * GetElemItem(int id)
Definition: CHECData.cpp:682
CHECData::vParseParameter
virtual bool vParseParameter(char *line, int *rcode, const char *fmt, va_list va)
Definition: CHECData.cpp:408
CHECDB_EGroup
Definition: CHECDB.h:216
CHECData::GetEGroup
virtual class CHECDB_EGroup * GetEGroup(const char *name)
Definition: CHECData.cpp:660
CHECDB_Material
Definition: CHECDB.h:129
CHECData::AddDataLineItems
virtual void AddDataLineItems(const char *fmt,...)
Definition: CHECData.cpp:201
CHECData::WriteParameter
virtual void WriteParameter(const char *fmt="",...)
Definition: CHECData.cpp:113
CHECData::Load
virtual bool Load(const char *file_name)
Definition: CHECData.cpp:262
CHECData::PushReadLine
virtual void PushReadLine(const char *s)
Definition: CHECData.cpp:328
hecd_util::cleanup_token
void cleanup_token(char *s)
Definition: hecd_util.cpp:16
CHECData::CreateDataBlock
virtual CHECDataBlock * CreateDataBlock(const char *header_name)
Definition: CHECData.cpp:334
CHECData::ReadLine
virtual bool ReadLine(char *s, int size=256)
Definition: CHECData.cpp:307
hecd_util::remove_cr
void remove_cr(char *s)
Definition: hecd_util.cpp:78
CHECData::StoreDataBlock
virtual void StoreDataBlock(CHECDataBlock *block)
Definition: CHECData.cpp:35
CHECData::WriteData
virtual void WriteData(const char *fmt,...)
Definition: CHECData.cpp:162
CHECDB_Node
Definition: CHECDB.h:108
CHECData::ReadData
virtual bool ReadData(int *rcode, const char *fmt,...)
Definition: CHECData.cpp:548
CHECData::ReadParameter
virtual bool ReadParameter(int *rcode, const char *fmt,...)
Definition: CHECData.cpp:525
HECDB_NODE
@ HECDB_NODE
Definition: CHECDB.h:22
CHECData::DB
std::vector< CHECDataBlock * > DB
Definition: CHECData.h:30
CHECDB_NGroup
Definition: CHECDB.h:204
CHECData::ParseDoubleDataArray
virtual int ParseDoubleDataArray(char *line, double *data)
Definition: CHECData.cpp:603
CHECData::WriteHeader
virtual void WriteHeader(const char *name, const char *fmt="",...)
Definition: CHECData.cpp:68
CHECDB_Node::CNodeItem
Definition: CHECDB.h:110
HECDB_SGROUP
@ HECDB_SGROUP
Definition: CHECDB.h:28
data
CNFData data
Definition: neu_reporter.cpp:18
CHECData
Definition: CHECData.h:25
CHECData::GetNGroup
virtual class CHECDB_NGroup * GetNGroup(const char *name)
Definition: CHECData.cpp:656
hecdata_get
T hecdata_get(CHECData *hd, int data_type, const char *name)
Definition: CHECData.cpp:636
HECDB_EGROUP
@ HECDB_EGROUP
Definition: CHECDB.h:27
hecd_util.h
CHECData::ClearDataLineBuffer
virtual void ClearDataLineBuffer()
Definition: CHECData.cpp:199
CHECData::Clear
virtual void Clear()
Definition: CHECData.cpp:25
CHECData::~CHECData
virtual ~CHECData()
Definition: CHECData.cpp:23
CHECData::WriteLine
virtual void WriteLine(const char *s)
Definition: CHECData.cpp:58
hecd_util::ftos
void ftos(double x, char *s)
Definition: hecd_util.cpp:93
hecd_util
Definition: hecd_util.cpp:11
CHECData::GetHeaderName
virtual bool GetHeaderName(const char *header_line, char *header_name)
Definition: CHECData.cpp:338
CHECData::ParseParameter
virtual bool ParseParameter(char *line, int *rcode, const char *fmt,...)
Definition: CHECData.cpp:498
CHECData::ParseIntDataArray
virtual int ParseIntDataArray(char *line, int *data)
Definition: CHECData.cpp:617
CHECData::Save
virtual bool Save(const char *file_name)
Definition: CHECData.cpp:41
CHECData::WriteDataLine
virtual void WriteDataLine()
Definition: CHECData.cpp:234
HECDB_NGROUP
@ HECDB_NGROUP
Definition: CHECDB.h:26
CHECDB_Element
Definition: CHECDB.h:62
CHECData::GetElemType
virtual int GetElemType(int id)
Definition: CHECData.cpp:696
CHECData::AddLoad
virtual bool AddLoad(const char *file_name)
Definition: CHECData.cpp:267
is_separator
#define is_separator(x)
HECDB_ELEMENT
@ HECDB_ELEMENT
Definition: CHECDB.h:23