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