FrontISTR  5.7.0
Large-scale structural analysis program with finit element method
hecmw_result_io.c
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 #include <stdio.h>
7 #include <stdlib.h>
8 #include <stddef.h>
9 #include <string.h>
10 #include <errno.h>
11 #include <ctype.h>
12 #include "hecmw_log.h"
13 #include "hecmw_malloc.h"
14 #include "hecmw_util.h"
15 #include "hecmw_config.h"
16 #include "hecmw_etype.h"
17 #include "hecmw_result_io.h"
18 
20 
21 static int is_valid_label(char *label) {
22 #define ALLOW_CHAR_FIRST "_" /* and alphabet */
23 #define ALLOW_CHAR "_-+" /* and alphabet, digit */
24  int c;
25  char *p, *q;
26 
27  if (label == NULL) return 0;
28 
29  c = label[0];
30 
31  /* check first character */
32  if (!isalpha(c)) {
33  q = ALLOW_CHAR_FIRST;
34  while (*q) {
35  if (*q == c) break;
36  q++;
37  }
38  if (!*q) return 0;
39  }
40 
41  /* check 2nd character or later */
42  p = &label[1];
43  while (*p) {
44  if (!isalnum(*p)) {
45  q = ALLOW_CHAR;
46  while (*q) {
47  if (*q == *p) break;
48  q++;
49  }
50  if (!*q) return 0;
51  }
52  p++;
53  }
54  return 1;
55 }
56 
58  struct result_list *p, *q;
59 
60  for (p = ResIO.global_list; p; p = q) {
61  q = p->next;
62  HECMW_free(p->label);
63  HECMW_free(p->ptr);
64  HECMW_free(p);
65  }
67 
68  for (p = ResIO.node_list; p; p = q) {
69  q = p->next;
70  HECMW_free(p->label);
71  HECMW_free(p->ptr);
72  HECMW_free(p);
73  }
75 
76  for (p = ResIO.elem_list; p; p = q) {
77  q = p->next;
78  HECMW_free(p->label);
79  HECMW_free(p->ptr);
80  HECMW_free(p);
81  }
83 
84  ResIO.nnode = ResIO.nelem = 0;
85  strcpy(ResIO.head, "");
86 
87  if (ResIO.MPC_exist) {
88  ResIO.MPC_exist = 0;
91  }
92 
95 }
96 
97 static int setup_MPC(int n_elem_type, int *elem_type_index, int *elem_type_item,
98  int *elemID) {
99  int itype, ic_type, is, ie, icel;
100  int nelem_wo_MPC;
101  int *elemID_wo_MPC;
102 
103  ResIO.MPC_exist = 0;
105 
106  for (itype = 0; itype < n_elem_type; itype++) {
107  ic_type = elem_type_item[itype];
108  if (HECMW_is_etype_link(ic_type) ||
109  HECMW_is_etype_patch(ic_type) ||
110  HECMW_is_etype_smoothing(ic_type)) {
111  ResIO.MPC_exist = 1;
112  break;
113  }
114  }
115 
116  if (ResIO.MPC_exist) {
117  ResIO.eid_wo_MPC = (int *) HECMW_calloc(ResIO.nelem, sizeof(int));
118  if (ResIO.eid_wo_MPC == NULL) {
119  HECMW_set_error(errno, "");
120  goto error;
121  }
122  elemID_wo_MPC = (int *) HECMW_calloc(ResIO.nelem, sizeof(int));
123  if (elemID_wo_MPC == NULL) {
124  HECMW_set_error(errno, "");
125  goto error;
126  }
127 
128  nelem_wo_MPC = 0;
129  for (itype = 0; itype < n_elem_type; itype++) {
130  ic_type = elem_type_item[itype];
131  if (HECMW_is_etype_link(ic_type) ||
132  HECMW_is_etype_patch(ic_type) ||
133  HECMW_is_etype_smoothing(ic_type)) {
134  continue;
135  }
136  is = elem_type_index[itype];
137  ie = elem_type_index[itype + 1];
138  for (icel = is; icel < ie; icel++) {
139  if (icel >= ResIO.nelem) {
140  /*
141  * Safeguard for inconsistent n_elem and elem_type_index
142  */
143  HECMW_log(HECMW_LOG_WARN, "result output: ignoring elements type=%d, %d..%d (n_elem=%d)\n",
144  ic_type, icel+1, ie, ResIO.nelem);
145  break;
146  }
147  ResIO.eid_wo_MPC[nelem_wo_MPC] = icel;
148  elemID_wo_MPC[nelem_wo_MPC] = elemID[icel];
149  nelem_wo_MPC++;
150  }
151  }
152  ResIO.nelem = nelem_wo_MPC;
153  ResIO.elem_global_ID = elemID_wo_MPC;
154  }
155 
156  return 0;
157 error:
158  return -1;
159 }
160 
161 int HECMW_result_io_init(int n_node, int n_elem, int *nodeID, int *elemID,
162  int n_elem_type, int *elem_type_index, int *elem_type_item,
163  int i_step, char *header, char *comment) {
164  size_t len;
165  int rtc;
166  char *p, *q;
167 
168  ResIO.nnode = n_node;
169  ResIO.nelem = n_elem;
170  ResIO.istep = i_step;
171 
172  ResIO.node_global_ID = nodeID;
173  ResIO.elem_global_ID = elemID;
174 
175  if (header == NULL) {
176  ResIO.head[0] = '\0';
177  return 0;
178  }
179 
180  len = 0;
181  p = header;
182  q = ResIO.head;
183  while (len < sizeof(ResIO.head) - 1 && *p && *p != '\n') {
184  *q++ = *p++;
185  len++;
186  }
187  *q++ = '\0';
188 
189  if (comment == NULL) {
190  ResIO.comment_line[0] = '\0';
191  return 0;
192  }
193 
194  len = 0;
195  p = comment;
196  q = ResIO.comment_line;
197  while (len < sizeof(ResIO.comment_line) - 1 && *p && *p != '\n') {
198  *q++ = *p++;
199  len++;
200  }
201  *q++ = '\0';
202 
203  rtc = setup_MPC(n_elem_type, elem_type_index, elem_type_item, elemID);
204  if (rtc != 0) {
205  goto error;
206  }
207 
208  return 0;
209 error:
210  return -1;
211 }
212 
213 static int add_to_global_list(struct result_list *result) {
214  struct result_list *p, *q;
215 
216  q = NULL;
217  for (p = ResIO.global_list; p; p = (q = p)->next)
218  ;
219 
220  if (q == NULL) {
221  ResIO.global_list = result;
222  } else {
223  q->next = result;
224  }
225  return 0;
226 }
227 
228 static int add_to_node_list(struct result_list *result) {
229  struct result_list *p, *q;
230 
231  q = NULL;
232  for (p = ResIO.node_list; p; p = (q = p)->next)
233  ;
234 
235  if (q == NULL) {
236  ResIO.node_list = result;
237  } else {
238  q->next = result;
239  }
240  return 0;
241 }
242 
243 static int add_to_elem_list(struct result_list *result) {
244  struct result_list *p, *q;
245 
246  q = NULL;
247  for (p = ResIO.elem_list; p; p = (q = p)->next)
248  ;
249 
250  if (q == NULL) {
251  ResIO.elem_list = result;
252  } else {
253  q->next = result;
254  }
255  return 0;
256 }
257 
258 static struct result_list *make_result_list(int n_dof, char *label,
259  double *ptr) {
260  struct result_list *result;
261  char *new_label;
262 
263  result = HECMW_malloc(sizeof(*result));
264  if (result == NULL) {
265  HECMW_set_error(errno, "");
266  goto error;
267  }
268 
269  new_label = HECMW_strdup(label);
270  if (new_label == NULL) {
271  HECMW_set_error(errno, "");
272  goto error;
273  }
274 
275  result->label = new_label;
276  result->ptr = ptr;
277  result->n_dof = n_dof;
278  result->next = NULL;
279 
280  return result;
281 error:
282  HECMW_free(result);
283  HECMW_free(new_label);
284  return NULL;
285 }
286 
287 int HECMW_result_io_add(int dtype, int n_dof, char *label, double *ptr) {
288  struct result_list *result;
289  size_t n, size;
290  double *data;
291  int i, icel, idof;
292 
293  if (dtype < HECMW_RESULT_DTYPE_MIN && dtype > HECMW_RESULT_DTYPE_MAX) {
295  goto error;
296  }
297 
298  if (!is_valid_label(label)) {
300  goto error;
301  }
302 
303  if (dtype == HECMW_RESULT_DTYPE_NODE) {
304  n = ResIO.nnode;
305  } else if (dtype == HECMW_RESULT_DTYPE_ELEM) {
306  n = ResIO.nelem;
307  } else { // dtype == HECMW_RESULT_DTYPE_GLOBAL
308  n = 1;
309  }
310  size = sizeof(double) * n * n_dof;
311  data = (double *) HECMW_calloc(n * n_dof, sizeof(double));
312  if (data == NULL) {
313  HECMW_set_error(errno, "");
314  goto error;
315  }
316 
317  if (dtype == HECMW_RESULT_DTYPE_ELEM && ResIO.MPC_exist) {
318  for (i = 0; i < ResIO.nelem; i++) {
319  icel = ResIO.eid_wo_MPC[i];
320  for (idof = 0; idof < n_dof; idof++) {
321  data[n_dof * i + idof] = ptr[n_dof * icel + idof];
322  }
323  }
324  } else {
325  memcpy(data, ptr, size);
326  }
327 
328  result = make_result_list(n_dof, label, data);
329  if (result == NULL) {
330  goto error;
331  }
332 
333  if (dtype == HECMW_RESULT_DTYPE_NODE) {
334  if (add_to_node_list(result)) goto error;
335  } else if (dtype == HECMW_RESULT_DTYPE_ELEM) {
336  if (add_to_elem_list(result)) goto error;
337  } else { /* dtype == HECMW_RESULT_DTYPE_GLOBAL */
338  if (add_to_global_list(result)) goto error;
339  }
340 
341  return 0;
342 error:
343  return -1;
344 }
345 
347  int ng_comp;
348  struct result_list *p;
349 
350  ng_comp = 0;
351  for (p = ResIO.global_list; p; p = p->next) {
352  ng_comp++;
353  }
354  return ng_comp;
355 }
356 
358  int nn_comp;
359  struct result_list *p;
360 
361  nn_comp = 0;
362  for (p = ResIO.node_list; p; p = p->next) {
363  nn_comp++;
364  }
365  return nn_comp;
366 }
367 
369  int ne_comp;
370  struct result_list *p;
371 
372  ne_comp = 0;
373  for (p = ResIO.elem_list; p; p = p->next) {
374  ne_comp++;
375  }
376  return ne_comp;
377 }
HECMW_LOG_WARN
#define HECMW_LOG_WARN
Definition: hecmw_log.h:17
hecmw_malloc.h
hecmw_etype.h
hecmwST_result_io_data::eid_wo_MPC
int * eid_wo_MPC
Definition: hecmw_result_io.h:49
hecmwST_result_io_data::node_global_ID
int * node_global_ID
Definition: hecmw_result_io.h:45
HECMW_result_io_finalize
void HECMW_result_io_finalize()
Definition: hecmw_result_io.c:57
HECMW_RESULT_DTYPE_NODE
@ HECMW_RESULT_DTYPE_NODE
Definition: hecmw_result_io.h:16
hecmwST_result_io_data::node_list
struct result_list * node_list
Definition: hecmw_result_io.h:42
HECMW_malloc
#define HECMW_malloc(size)
Definition: hecmw_malloc.h:20
HECMW_UTIL_E0206
#define HECMW_UTIL_E0206
Definition: hecmw_msgno.h:373
HECMW_log
int HECMW_log(int loglv, const char *fmt,...)
Definition: hecmw_log.c:260
HECMW_result_io_count_ng_comp
int HECMW_result_io_count_ng_comp(void)
Definition: hecmw_result_io.c:346
hecmw_result_io.h
hecmwST_result_io_data::MPC_exist
int MPC_exist
Definition: hecmw_result_io.h:48
HECMW_UTIL_E0207
#define HECMW_UTIL_E0207
Definition: hecmw_msgno.h:374
ALLOW_CHAR_FIRST
#define ALLOW_CHAR_FIRST
hecmwST_result_io_data::nelem
int nelem
Definition: hecmw_result_io.h:37
result_list
Definition: hecmw_result_io.h:27
HECMW_calloc
#define HECMW_calloc(nmemb, size)
Definition: hecmw_malloc.h:21
hecmw_log.h
result_list::n_dof
int n_dof
Definition: hecmw_result_io.h:30
result_list::next
struct result_list * next
Definition: hecmw_result_io.h:31
hecmwST_result_io_data::head
char head[HECMW_HEADER_LEN+1]
Definition: hecmw_result_io.h:38
HECMW_result_io_add
int HECMW_result_io_add(int dtype, int n_dof, char *label, double *ptr)
Definition: hecmw_result_io.c:287
HECMW_is_etype_link
int HECMW_is_etype_link(int etype)
Definition: hecmw_etype.c:1987
hecmw_config.h
HECMW_RESULT_DTYPE_MAX
@ HECMW_RESULT_DTYPE_MAX
Definition: hecmw_result_io.h:19
hecmwST_result_io_data::elem_list
struct result_list * elem_list
Definition: hecmw_result_io.h:43
HECMW_strdup
#define HECMW_strdup(s)
Definition: hecmw_malloc.h:23
HECMW_result_io_count_ne_comp
int HECMW_result_io_count_ne_comp(void)
Definition: hecmw_result_io.c:368
hecmwST_result_io_data::nnode
int nnode
Definition: hecmw_result_io.h:36
data
CNFData data
Definition: neu_reporter.cpp:18
hecmwST_result_io_data::global_list
struct result_list * global_list
Definition: hecmw_result_io.h:41
HECMW_is_etype_patch
int HECMW_is_etype_patch(int etype)
Definition: hecmw_etype.c:2048
ResIO
struct hecmwST_result_io_data ResIO
Definition: hecmw_result_io.c:19
result_list::ptr
double * ptr
Definition: hecmw_result_io.h:29
HECMW_result_io_init
int HECMW_result_io_init(int n_node, int n_elem, int *nodeID, int *elemID, int n_elem_type, int *elem_type_index, int *elem_type_item, int i_step, char *header, char *comment)
Definition: hecmw_result_io.c:161
HECMW_RESULT_DTYPE_ELEM
@ HECMW_RESULT_DTYPE_ELEM
Definition: hecmw_result_io.h:17
hecmwST_result_io_data
Definition: hecmw_result_io.h:34
hecmwST_result_io_data::elem_global_ID
int * elem_global_ID
Definition: hecmw_result_io.h:46
hecmwST_result_io_data::comment_line
char comment_line[HECMW_MSG_LEN+1]
Definition: hecmw_result_io.h:39
hecmwST_result_io_data::istep
int istep
Definition: hecmw_result_io.h:35
ALLOW_CHAR
#define ALLOW_CHAR
result_list::label
char * label
Definition: hecmw_result_io.h:28
HECMW_is_etype_smoothing
int HECMW_is_etype_smoothing(int etype)
Definition: hecmw_etype.c:2059
HECMW_set_error
int HECMW_set_error(int errorno, const char *fmt,...)
Definition: hecmw_error.c:37
NULL
#define NULL
Definition: hecmw_io_nastran.c:30
HECMW_free
#define HECMW_free(ptr)
Definition: hecmw_malloc.h:24
HECMW_result_io_count_nn_comp
int HECMW_result_io_count_nn_comp(void)
Definition: hecmw_result_io.c:357
hecmw_util.h