## *TEST* ## 'awk' PROGRAM NAME: feinp_generic2stl_awkprogTESTcpenta ## ## in $FEDIR/scripts ## where FEDIR=/apps/nns_com/fea ## ## Compare with 'full' awk-prog, 'feinp_generic2stl_awkprog'. ######################################################################## ## PURPOSE: FOR TESTING OF REFORMATTING OF 'GENERIC' CPENTA RECORDS ## into an STL file. ## ## ** This awk-program READs a 'GENERIC' FE input file and ## ** EXTRACTs data from 'generic' GRID and 'generic' ELEMENT records ## ** (CPENTA only -- for test) into an STL output file. ## ## Each 'generic' ELEMENT record is expected to be a single ## 'free-format' record [fields are space(s)-separated], ## generally of the form ## elname eid pid g1 g2 g3 ... ## where elname is an element name like CBEAM ## eid = element-id (an integer) ## pid = property id, usually (an integer) ## gi's are ids of grid/node points (integers). ######################################################################## ## CALLED BY: TEST SCRIPT 'feinp_nas2stl_nogui_TESTawkprogs' ## in $FEDIR/scripts. ## ## *** To prepare for incorporation into ## 'feinp_generic2stl_awkprog' ## which is called in 'feinp_nas2stl_bygui' ## ## which is a "NASTRAN-to-STL" file creation utility. ## ## *** COMPARE THIS AWK-PROG WITH 'feinp_generic2stl_awkprog'. ## ## The 'generic' ELEMENT-info file is created in (and is used as input ## in) 'feinp_nas2stl_bygui'. See that script for more info. ## Or see 'feinp_nas2stl_nogui_TESTawkprogs'. ## ######################################################################## ## INPUT: GENERIC-FE input filename ## OUTPUT: stdout ######################################################################## ## TEST FILES: Test NASTRAN files with various elements are ## in directory /apps/nns_com/fea/demos_nas2stl. ## and/or in /apps/simtec_2000/test_files_nas2stl ## Some of these NASTRAN input files are from ## /apps/msc/msc70/msc70/nast/demo ## and /apps/msc/msc70/msc70/nast/tpl. ## Others may be from NNS NASTRAN users. ######################################################################## ## SUPPORTED 'GENERIC' FE RECORD TYPES BELOW: ## - GRID & CPENTA ######################################################################## ## MAINTENANCE HISTORY: ## Written by: B.Montandon O06 13Sep2000 Extracted from ## 'feinp_generic2stl_awkprog' ## which was developed to support ## 2D & 3D elements (CTRIAx,CQUADx, ## CTETRA,CPENTA,CHEXA) --- to ## support trouble-shooting of ## CPENTA-data/to/STL recs. # Updated by: B.Montandon O06 13Sep2000 ######################################################################## ######################################################################### ## awk-prog to TRANSLATE a 'GENERIC' CPENTA file to an STL file. ######################################################################## ## NOTE1: THIS LOGIC FOR LOOKING UP GRID INFO ## ASSUMES *ALL* THE generic 'GRID' RECORDS ARE BEFORE ## THE 'element-connectivity' RECORDS --- and are sorted by gridid. ######################################################################### ######################################################################## ## NOTE2: AS A RULE OF THUMB, WE USE *next* AS SOON AS POSSIBLE IN THE ## main awk logic --- to skip unnecessary processing. ######################################################################## ######################################################################### ## SAMPLE NASTRAN INPUT FOR CONVERSION TO A 'GENERIC' FE FILE FOR TESTING: # FILEIN="/apps/nns_com/fea/demos_nas2stl/cbeams_1_free.dat" BEGIN { printf ("SOLID - FROM NASTRAN INPUT %-65s\n",FILE_IN); DEBUG=0; i=0; jpent=0; ## i is a GRID rec counter; j's are element rec counters. } { ############################################################################## ## *GRID*-RECORD PROCESSING SECTION: ############################################################################## ## LOOK FOR *GRID* IN THE FIRST FIELD. INCREMENT THE GRID-REC COUNT, i. ############################################################################## FLD1CAPS=toupper($1) if ( FLD1CAPS=="GRID" ) {i++ ## EXIT, WITH MSG TO OUTFILE, IF A GRID REC HAS LESS THAN 6 FIELDS. if (NF<6) { print "*ERROR: There must be at least 6 fields in GRID recs:" print "*ERROR: String GRID, two integers, and 3 x,y,z coordinates." exit } #################################################### ## STORE THE GRID-ID in the g[.] array. (pre-sorted) #################################################### g[i]=$2 ################################################################ ## STORE THE 4th,5th,6th FIELDS IN THE gx[.],gy[.],gz[.] arrays. ################################################################ gx[i]=$4; gy[i]=$5; gz[i]=$6 ## *FOR TESTING* -- show the just-captured GRID data: if (DEBUG==1) { print "DEBUG - GRID READ: i="i" g[i]="g[i]" gx[i]="gx[i]" gy[i]="gy[i]" gz[i]="gz[i] } next } ####################################################################### ## END OF the *GRID*-RECORD PROCESSING SECTION ####################################################################### ####################################################################### ## *CPENTA*-RECORD PROCESSING SECTION: ####################################################################### ## LOOK FOR *CPENTA* IN THE FIRST FIELD. ## INCREMENT THE CPENTA-REC COUNT, jpent. ####################################################################### # FLD1CAPS=toupper($1) ## DONE ABOVE. if ( FLD1CAPS=="CPENTA" ) {jpent++ ################################################################ ## STORE THE *CPENTA* ELEMENT-ID IN THE *e* VAR. ## STORE THE 4th, 5th, 6th, 7th, 8th, 9th FIELDS ## (6 corner grid ids of the 'prism' element) ## IN THE g1, g2, g3, g4, g5, g6 VARS. ################################################################ e=$2; g1=$4; g2=$5; g3=$6; g4=$7; g5=$8; g6=$9 ## *FOR TESTING* -- show the just-captured *CPENTA* data: if (DEBUG==1) { print "DEBUG - ELEMENT READ: jpent=CPENTA-count="jpent" e=element-id="e print " g1="g1" g2="g2" g3="g3 print " g4="g4" g5="g5" g6="g6 } ################################################################### ## binary-SEARCH THE g[.] GRID-ID array FOR A MATCH, g[k], WITH g1. ## FOR A MATCH, SET x1,y1,z1 to gz[k],gy[k],gz[k]. ################################################################### k=binarySearch(g, i, g1) if ( k==-1 ) { print "*ERROR: NO GRID COORDS FOUND for GRID "g1" of CPENTA "e"." next } else { x1=gx[k] ; y1=gy[k] ; z1=gz[k] ## *FOR TESTING* -- show the just-captured *CPENTA* data: if (DEBUG==1) { print "FOUND g1="g1": at k="k" g[k]="g[k]" whose xyz coordinates" print "we use to set x1="x1" y1="y1" z1="z1 } } ################################################################### ## binary-SEARCH THE g[.] GRID-ID array FOR A MATCH, g[k], WITH g2. ## FOR A MATCH, SET x2,y2,z2 to gz[k],gy[k],gz[k]. ################################################################### k=binarySearch(g, i, g2) if ( k==-1 ) { print "*ERROR: NO GRID COORDS FOUND for GRID "g2" of CPENTA "e"." next } else { x2=gx[k] ; y2=gy[k] ; z2=gz[k] ## *FOR TESTING* -- show the just-captured *CPENTA* data: if (DEBUG==1) { print "FOUND g2="g2": at k="k" g[k]="g[k]" whose xyz coordinates" print "we use to set x2="x2" y2="y2" z2="z2 } } ################################################################### ## binary-SEARCH THE g[.] GRID-ID array FOR A MATCH, g[k], WITH g3. ## FOR A MATCH, SET x3,y3,z3 to gz[k],gy[k],gz[k]. ################################################################### k=binarySearch(g, i, g3) if ( k==-1 ) { print "*ERROR: NO GRID COORDS FOUND for GRID "g3" of CPENTA "e"." next } else { x3=gx[k] ; y3=gy[k] ; z3=gz[k] ## *FOR TESTING* -- show the just-captured *CPENTA* data: if (DEBUG==1) { print "FOUND g3="g3": at k="k" g[k]="g[k]" whose xyz coordinates" print "we use to set x3="x3" y3="y3" z3="z3 } } ################################################################### ## binary-SEARCH THE g[.] GRID-ID array FOR A MATCH, g[k], WITH g4. ## FOR A MATCH, SET x4,y4,z4 to gz[k],gy[k],gz[k]. ################################################################### k=binarySearch(g, i, g4) if ( k==-1 ) { print "*ERROR: NO GRID COORDS FOUND for GRID "g4" of CPENTA "e"." next } else { x4=gx[k] ; y4=gy[k] ; z4=gz[k] ## *FOR TESTING* -- show the just-captured *CPENTA* data: if (DEBUG==1) { print "FOUND g4="g4": at k="k" g[k]="g[k]" whose xyz coordinates" print "we use to set x4="x4" y4="y4" z4="z4 } } ################################################################### ## binary-SEARCH THE g[.] GRID-ID array FOR A MATCH, g[k], WITH g5. ## FOR A MATCH, SET x5,y5,z5 to gz[k],gy[k],gz[k]. ################################################################### k=binarySearch(g, i, g5) if ( k==-1 ) { print "*ERROR: NO GRID COORDS FOUND for GRID "g5" of CPENTA "e"." next } else { x5=gx[k] ; y5=gy[k] ; z5=gz[k] ## *FOR TESTING* -- show the just-captured *CPENTA* data: if (DEBUG==1) { print "FOUND g5="g5": at k="k" g[k]="g[k]" whose xyz coordinates" print "we use to set x5="x5" y5="y5" z5="z5 } } ################################################################### ## binary-SEARCH THE g[.] GRID-ID array FOR A MATCH, g[k], WITH g6. ## FOR A MATCH, SET x6,y6,z6 to gz[k],gy[k],gz[k]. ################################################################### k=binarySearch(g, i, g6) if ( k==-1 ) { print "*ERROR: NO GRID COORDS FOUND for GRID "g6" of CPENTA "e"." next } else { x6=gx[k] ; y6=gy[k] ; z6=gz[k] ## *FOR TESTING* -- show the just-captured *CPENTA* data: if (DEBUG==1) { print "FOUND g6="g6": at k="k" g[k]="g[k]" whose xyz coordinates" print "we use to set x6="x6" y6="y6" z6="z6 } } ####################################################################### ####################################################################### ## WE NOW MAKE THE PENTA-PRISM (2 end-triangles, then 3 rectangles) ## OUT OF 2 TRIANGLES, THEN 2*3=6 TRIANGLES. ####################################################################### ####################################################################### ################################################################ ## CALCULATE THE FACET NORMAL OF END-TRIANGLE#1 (using pts 1,3,2) ## of THE CURRENT *CPENTA* ELEMENT. ################################################################ ax=x3-x1; ay=y3-y1; az=z3-z1 bx=x2-x1; by=y2-y1; bz=z2-z1 cx=ay*bz-az*by cy=az*bx-ax*bz cz=ax*by-ay*bx if ( cx==0 && cy==0 && cz==0 ) { print "*ERROR: A normal of a face of CPENTA-id "e" is all zeros." print "*ERROR: Probably a RecFmt problem with one of its GRID records." print "*ERROR: See grid & element extracted data in "FILE_IN next } ################################################################ ## OUTPUT THE SET OF STL RECS CORRESPONDING TO END-TRIANGLE#1 ## of THE CURRENT *CPENTA* ELEMENT. ################################################################ print "facet normal "cx" "cy" "cz print " outer loop" print " vertex "x1" "y1" "z1 print " vertex "x3" "y3" "z3 print " vertex "x2" "y2" "z2 print " endloop" print "endfacet" ################################################################ ## CALCULATE THE FACET NORMAL OF END-TRIANGLE#2 (using pts 4,5,6) ## of THE CURRENT *CPENTA* ELEMENT. ################################################################ ax=x5-x4; ay=y5-y4; az=z5-z4 bx=x6-x4; by=y6-y4; bz=z6-z4 cx=ay*bz-az*by cy=az*bx-ax*bz cz=ax*by-ay*bx if ( cx==0 && cy==0 && cz==0 ) { print "*ERROR: A normal of a face of CPENTA-id "e" is all zeros." print "*ERROR: Probably a RecFmt problem with one of its GRID records." print "*ERROR: See grid & element extracted data in "FILE_IN next } ################################################################ ## OUTPUT THE SET OF STL RECS CORRESPONDING TO END-TRIANGLE#2 ## of THE CURRENT *CPENTA* ELEMENT. ################################################################ print "facet normal "cx" "cy" "cz print " outer loop" print " vertex "x4" "y4" "z4 print " vertex "x5" "y5" "z5 print " vertex "x6" "y6" "z6 print " endloop" print "endfacet" ################################################################ ## CALCULATE THE FACET NORMAL OF RECTANGLE1-TRIANGLE1 ## (using pts 2,3,5) of THE CURRENT *CPENTA* ELEMENT. ################################################################ ax=x3-x2; ay=y3-y2; az=z3-z2 bx=x5-x2; by=y5-y2; bz=z5-z2 cx=ay*bz-az*by cy=az*bx-ax*bz cz=ax*by-ay*bx if ( cx==0 && cy==0 && cz==0 ) { print "*ERROR: A normal of a face of CPENTA-id "e" is all zeros." print "*ERROR: Probably a RecFmt problem with one of its GRID records." print "*ERROR: See grid & element extracted data in "FILE_IN next } ################################################################ ## OUTPUT THE SET OF STL RECS CORRESPONDING TO RECTANGLE1-TRIANGLE1 ## of THE CURRENT *CPENTA* ELEMENT. ################################################################ print "facet normal "cx" "cy" "cz print " outer loop" print " vertex "x2" "y2" "z2 print " vertex "x3" "y3" "z3 print " vertex "x5" "y5" "z5 print " endloop" print "endfacet" ################################################################ ## CALCULATE THE FACET NORMAL OF RECTANGLE1-TRIANGLE2 ## (using pts 3,6,5) of THE CURRENT *CPENTA* ELEMENT. ################################################################ ax=x6-x3; ay=y6-y3; az=z6-z3 bx=x5-x3; by=y5-y3; bz=z5-z3 cx=ay*bz-az*by cy=az*bx-ax*bz cz=ax*by-ay*bx if ( cx==0 && cy==0 && cz==0 ) { print "*ERROR: A normal of a face of CPENTA-id "e" is all zeros." print "*ERROR: Probably a RecFmt problem with one of its GRID records." print "*ERROR: See grid & element extracted data in "FILE_IN next } ################################################################ ## OUTPUT THE SET OF STL RECS CORRESPONDING TO RECTANGLE1-TRIANGLE2 ## of THE CURRENT *CPENTA* ELEMENT. ################################################################ print "facet normal "cx" "cy" "cz print " outer loop" print " vertex "x3" "y3" "z3 print " vertex "x6" "y6" "z6 print " vertex "x5" "y5" "z5 print " endloop" print "endfacet" ################################################################ ## CALCULATE THE FACET NORMAL OF RECTANGLE2-TRIANGLE1 ## (using pts 1,4,3) of THE CURRENT *CPENTA* ELEMENT. ################################################################ ax=x4-x1; ay=y4-y1; az=z4-z1 bx=x3-x1; by=y3-y1; bz=z3-z1 cx=ay*bz-az*by cy=az*bx-ax*bz cz=ax*by-ay*bx if ( cx==0 && cy==0 && cz==0 ) { print "*ERROR: A normal of a face of CPENTA-id "e" is all zeros." print "*ERROR: Probably a RecFmt problem with one of its GRID records." print "*ERROR: See grid & element extracted data in "FILE_IN next } ################################################################ ## OUTPUT THE SET OF STL RECS CORRESPONDING TO RECTANGLE2-TRIANGLE1 ## of THE CURRENT *CPENTA* ELEMENT. ################################################################ print "facet normal "cx" "cy" "cz print " outer loop" print " vertex "x1" "y1" "z1 print " vertex "x4" "y4" "z4 print " vertex "x3" "y3" "z3 print " endloop" print "endfacet" ################################################################ ## CALCULATE THE FACET NORMAL OF RECTANGLE2-TRIANGLE2 ## (using pts 3,4,6) of THE CURRENT *CPENTA* ELEMENT. ################################################################ ax=x4-x3; ay=y4-y3; az=z4-z3 bx=x6-x3; by=y6-y3; bz=z6-z3 cx=ay*bz-az*by cy=az*bx-ax*bz cz=ax*by-ay*bx if ( cx==0 && cy==0 && cz==0 ) { print "*ERROR: A normal of a face of CPENTA-id "e" is all zeros." print "*ERROR: Probably a RecFmt problem with one of its GRID records." print "*ERROR: See grid & element extracted data in "FILE_IN next } ################################################################ ## OUTPUT THE SET OF STL RECS CORRESPONDING TO RECTANGLE2-TRIANGLE2 ## of THE CURRENT *CPENTA* ELEMENT. ################################################################ print "facet normal "cx" "cy" "cz print " outer loop" print " vertex "x3" "y3" "z3 print " vertex "x4" "y4" "z4 print " vertex "x6" "y6" "z6 print " endloop" print "endfacet" ################################################################ ## CALCULATE THE FACET NORMAL OF RECTANGLE3-TRIANGLE1 ## (using pts 1,2,5) of THE CURRENT *CPENTA* ELEMENT. ################################################################ ax=x2-x1; ay=y2-y1; az=z2-z1 bx=x5-x1; by=y5-y1; bz=z5-z1 cx=ay*bz-az*by cy=az*bx-ax*bz cz=ax*by-ay*bx if ( cx==0 && cy==0 && cz==0 ) { print "*ERROR: A normal of a face of CPENTA-id "e" is all zeros." print "*ERROR: Probably a RecFmt problem with one of its GRID records." print "*ERROR: See grid & element extracted data in "FILE_IN next } ################################################################ ## OUTPUT THE SET OF STL RECS CORRESPONDING TO RECTANGLE3-TRIANGLE1 ## of THE CURRENT *CPENTA* ELEMENT. ################################################################ print "facet normal "cx" "cy" "cz print " outer loop" print " vertex "x1" "y1" "z1 print " vertex "x2" "y2" "z2 print " vertex "x5" "y5" "z5 print " endloop" print "endfacet" ################################################################ ## CALCULATE THE FACET NORMAL OF RECTANGLE3-TRIANGLE2 ## (using pts 1,5,4) of THE CURRENT *CPENTA* ELEMENT. ################################################################ ax=x5-x1; ay=y5-y1; az=z5-z1 bx=x4-x1; by=y4-y1; bz=z4-z1 cx=ay*bz-az*by cy=az*bx-ax*bz cz=ax*by-ay*bx if ( cx==0 && cy==0 && cz==0 ) { print "*ERROR: A normal of a face of CPENTA-id "e" is all zeros." print "*ERROR: Probably a RecFmt problem with one of its GRID records." print "*ERROR: See grid & element extracted data in "FILE_IN next } ################################################################ ## OUTPUT THE SET OF STL RECS CORRESPONDING TO RECTANGLE3-TRIANGLE2 ## of THE CURRENT *CPENTA* ELEMENT. ################################################################ print "facet normal "cx" "cy" "cz print " outer loop" print " vertex "x1" "y1" "z1 print " vertex "x5" "y5" "z5 print " vertex "x4" "y4" "z4 print " endloop" print "endfacet" next } ####################################################################### ## END OF if ( FLD1CAPS=="CPENTA" ) ## i.e. END OF the *CPENTA*-RECORD PROCESSING SECTION. ####################################################################### ## END OF main-section of awk program } END { # j=jtria+jquad+jtet+jpent+jhex j=jpent if ( j==0 ) { print "*ERROR: No CTETRA, CPENTA, or CHEXA elements were found in the input file." } printf ("ENDSOLID - %12d triangles generated from %12d CTRIAx elements.\n",jtria,jtria) printf ("ENDSOLID - 2 x %12d triangles generated from %12d CQUADx elements.\n",jquad,jquad) printf ("ENDSOLID - 4 x %12d triangles generated from %12d CTETRA elements.\n",jtet,jtet) printf ("ENDSOLID - 8 x %12d triangles generated from %12d CPENTA elements.\n",jpent,jpent) printf ("ENDSOLID - 12 x %12d triangles generated from %12d CHEXA elements.\n",jhex,jhex) } ## START OF function *binarySearch* ######################################################################## ## NOTE: *function* statement is not recognized within ## awk BEGIN, *body=main*, and END sections. ######################################################################## ## ## DESCRIPTION OF A BINARY SEARCH ALGORITHM ## ## from http://www.ics.hawaii.edu/~yongsi/ics665/principle.html ## ## We have a sorted array A and a key K. Our task is to determine whether ## the key K is present in this array A. If we do find A[i] = K, ## return the array index i. Otherwise, return i = -1. ## ## The search Binary search works in the following way: ## ## 1. Compare K with the middle value (M) in remaiding part of array A. ## 2. If K = M, we are done. ## 3. If K < M, we continue our search to the lower end of array A and ## entirely ignore the other end. ## 4. If K > M, we continue, but confine ourselves to the higher end. ## ######################################################################## ## EXAMPLE: A = {1 3 4 6 8 9 11}. K = 4. ## ## M = 6 ## Compare K with 6. It is smaller. Continue search with A = 1 3 4. ## M = 3 ## Compare K with 3. It is bigger. Continue search with A = 3 4. (4 only?) ## M = 4 ## Compare K with 4. It is equal. We are done, we found K in A. ######################################################################## ## ## The algorithm (C-like) for Binary Search is listed below: ######################################################################## function binarySearch(ARRAY,ARRAY_SIZE,KEY, low,high,middle) { low=1 high=ARRAY_SIZE while ( low <= high ) { middle = int( (low+high)/2 ) ## FOR TESTING: # print "low= "low" high="high" middle="middle if ( KEY == ARRAY[ middle ] ) { return middle } else if ( KEY < ARRAY[ middle ] ) { high = middle - 1 } else { low = middle + 1 } } return -1 } ## END OF awk program