1 /*
2 * patran_to_cgns - Patran Neutral File Import
3 * reads packets 1 (nodes), 2 (elements) and 21 (named groups)
4 * and optionally packet 6 (loads), and writes CGNS
5 */
6
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <ctype.h>
11 #include <math.h>
12
13 #include "cgnsImport.h"
14 #include "getargs.h"
15
16 #define getline() \
17 {if (NULL == fgets (buffer, sizeof(buffer), fp)) \
18 cgnsImportFatal ("premature EOF"); \
19 lineno++;}
20
21 static char options[] = "ldDt:B:";
22
23 static char *usgmsg[] = {
24 "usage : patran_to_cgns [options] Patranfile CGNSfile",
25 "options:",
26 " -l = process packet 6 - distributed loads",
27 " -d = duplicate node checking with rel tol",
28 " -D = duplicate node checking with abs tol",
29 " -t<tol> = duplicate node checking tolerance",
30 " -B<name> = set CGNS base name to <name>",
31 NULL
32 };
33
34 /*---------- print_error -------------------------------------------
35 * print error message and line number
36 *------------------------------------------------------------------*/
37
38 static int lineno = 0;
39
print_error(char * errmsg)40 static void print_error (char *errmsg)
41 {
42 fprintf (stderr, "%s on line %d\n", errmsg, lineno);
43 }
44
45 /*---------- add_face -----------------------------------------------
46 * add an element face to the region list
47 *-------------------------------------------------------------------*/
48
add_face(int elemid,char * data)49 static void add_face (int elemid, char *data)
50 {
51 int n, nodes[8], nnodes;
52 int elemtype, faceid;
53 cgsize_t elemnodes[8], nodeid[8];
54 char errmsg[81];
55 static int facemap[5][7] = {
56 {0, 1, 2, 3, 4, 0, 0},
57 {0, 1, 2, 3, 4, 5, 0},
58 {0, 4, 5, 1, 3, 2, 0},
59 {0, 0, 0, 0, 0, 0, 0},
60 {0, 2, 4, 1, 3, 6, 5}
61 };
62
63 /* check for node flags set */
64
65 for (nnodes = 0, n = 0; n < 8; n++) {
66 if ('1' == data[n])
67 nodes[nnodes++] = n;
68 }
69
70 elemtype = cgnsImportGetElement (elemid, elemnodes);
71 if (!elemtype) {
72 sprintf (errmsg, "element %d not found for packet 6\n", elemid);
73 cgnsImportFatal (errmsg);
74 }
75
76 /* if node flags set, use the node values */
77
78 if (nnodes) {
79 for (n = 0; n < nnodes; n++) {
80 if (nodes[n] >= elemtype) {
81 sprintf (errmsg,
82 "invalid node flags for element %d\n", elemid);
83 cgnsImportFatal (errmsg);
84 }
85 nodeid[n] = elemnodes[nodes[n]];
86 }
87 }
88
89 /* else get nodes from face number */
90
91 else {
92 faceid = atoi (&data[8]);
93 if (faceid < 1 || faceid > 6) {
94 sprintf (errmsg, "invalid faceid for element %d\n", elemid);
95 cgnsImportFatal (errmsg);
96 }
97 faceid = facemap[elemtype-4][faceid];
98 nnodes = cgnsImportGetFace (elemid, faceid, nodeid);
99 if (nnodes < 0) {
100 sprintf (errmsg,
101 "element %d not found for packet 6\n", elemid);
102 cgnsImportFatal (errmsg);
103 }
104 if (0 == nnodes) {
105 sprintf (errmsg,
106 "invalid face number for element %d\n", elemid);
107 cgnsImportFatal (errmsg);
108 }
109 }
110
111 cgnsImportAddReg (nnodes, nodeid);
112 }
113
114 /*========== main ===================================================*/
115
main(int argc,char * argv[])116 int main (int argc, char *argv[])
117 {
118 int n, packet, nlines, nodeid;
119 int nnodes, elemid;
120 cgsize_t nodes[8];
121 int lastid = -1, loadid;
122 int do_loads = 0, do_chk = 0;
123 double xyz[3];
124 char *p, buffer[256], *basename = NULL;
125 FILE *fp;
126
127 if (argc < 2)
128 print_usage (usgmsg, NULL);
129
130 while ((n = getargs (argc, argv, options)) > 0) {
131 switch (n) {
132 case 'l':
133 do_loads = 1;
134 break;
135 case 'D':
136 case 'd':
137 do_chk = n;
138 break;
139 case 't':
140 cgnsImportSetTol (atof (argarg));
141 break;
142 case 'B':
143 basename = argarg;
144 break;
145 }
146 }
147
148 if (argind + 1 >= argc)
149 print_usage (usgmsg, "Patran and/or CGNS filename not specified\n");
150
151 if (NULL == (fp = fopen (argv[argind], "r"))) {
152 sprintf (buffer, "can't open <%s> for reading", argv[argind]);
153 cgnsImportFatal (buffer);
154 }
155 printf ("reading Patran Neutral file from %s\n", argv[argind]);
156 cgnsImportError (print_error);
157
158 getline ();
159
160 /* header - packet 25 */
161
162 if ((packet = atoi (buffer)) == 25) {
163 getline ();
164 fputs (buffer, stdout);
165 getline ();
166 packet = atoi (buffer);
167 }
168
169 /* summary - packet 26 */
170
171 if (packet == 26) {
172 getline ();
173 getline ();
174 packet = atoi (buffer);
175 }
176
177 /* get remaining packets */
178
179 while (packet != 99) {
180
181 /* node */
182
183 if (packet == 1) {
184 nodeid = atoi (&buffer[2]);
185 getline ();
186 p = buffer + 48;
187 for (n = 2; n >= 0; n--) {
188 *p = 0;
189 p -= 16;
190 xyz[n] = atof (p);
191 }
192 getline ();
193 cgnsImportNode (nodeid, xyz[0], xyz[1], xyz[2]);
194 }
195
196 /* element */
197
198 else if (packet == 2) {
199 elemid = atoi (&buffer[2]);
200 n = atoi (&buffer[10]);
201 nlines = atoi (&buffer[18]);
202 if (n == 5 || n == 7 || n == 8) {
203 getline ();
204 nnodes = n == 8 ? n : n-1;
205 lineno++;
206 for (n = 0; n < nnodes; n++) {
207 if (1 != fscanf (fp, "%d", &nodeid) || nodeid < 1)
208 cgnsImportFatal ("missing or invalid node ID");
209 nodes[n] = nodeid;
210 }
211 while (getc (fp) != '\n')
212 ;
213 nlines -= 2;
214 cgnsImportElement (elemid, nnodes, nodes);
215 }
216 while (nlines-- > 0)
217 getline ();
218 }
219
220 /* distributed loads */
221
222 else if (packet == 6 && do_loads) {
223 elemid = atoi (&buffer[2]);
224 loadid = atoi (&buffer[10]);
225 nlines = atoi (&buffer[18]);
226
227 if (loadid != lastid) {
228 sprintf (buffer, "PatranLoad%d", loadid);
229 cgnsImportBegReg (buffer, cgnsREG_NODES);
230 lastid = loadid;
231 }
232 getline ();
233
234 /* add if element load flag is set */
235
236 if ('1' == buffer[0])
237 add_face (elemid, &buffer[9]);
238 while (--nlines > 0)
239 getline ();
240 }
241
242 /* named component */
243
244 else if (packet == 21) {
245 int cnt, type, id;
246 elemid = atoi (&buffer[2]);
247 nnodes = atoi (&buffer[10]) / 2;
248 getline ();
249
250 /* strip leading and trailing spaces */
251
252 buffer[sizeof(buffer)-1] = 0;
253 p = buffer + strlen (buffer);
254 while (--p >= buffer && isspace(*p))
255 ;
256 *++p = 0;
257 for (p = buffer; *p && isspace(*p); p++)
258 ;
259 cgnsImportBegReg (p, cgnsREG_NODES);
260
261 /* currently only handle type 5 (nodes) in groups */
262
263 for (n = 0, cnt = 0; n < nnodes; n++) {
264 if (0 == (n % 5))
265 lineno++;
266 fscanf (fp, "%d%d", &type, &id);
267 if (5 == type) {
268 nodes[cnt++] = id;
269 if (8 == cnt) {
270 cgnsImportAddReg (8, nodes);
271 cnt = 0;
272 }
273 }
274 }
275 while (getc (fp) != '\n')
276 ;
277 if (cnt)
278 cgnsImportAddReg (cnt, nodes);
279 cgnsImportEndReg ();
280 }
281
282 /* all others */
283
284 else {
285 nlines = atoi (&buffer[18]);
286 while (nlines--)
287 getline ();
288 }
289
290 if (NULL == fgets (buffer, sizeof(buffer), fp))
291 break;
292 lineno++;
293 packet = atoi (buffer);
294 }
295
296 fclose (fp);
297 cgnsImportError (NULL);
298
299 /* check for duplicate nodes */
300
301 if (do_chk) {
302 printf ("checking for duplicate nodes...\n");
303 cgnsImportCheck (do_chk == 'd');
304 }
305
306 /* output to CGNS file */
307
308 printf ("writing CGNS data to %s\n", argv[++argind]);
309 cgnsImportOpen (argv[argind]);
310 if (basename != NULL)
311 cgnsImportBase (basename);
312 cgnsImportWrite ();
313 cgnsImportClose ();
314 return 0;
315 }
316