File: sorti.f

package info (click to toggle)
nastran 0.1.95-2
  • links: PTS, VCS
  • area: non-free
  • in suites: bookworm, bullseye, sid
  • size: 122,540 kB
  • sloc: fortran: 284,409; sh: 771; makefile: 324
file content (304 lines) | stat: -rw-r--r-- 8,704 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
      SUBROUTINE SORTI (INPFL,OUTFL,NWDS,KEYWRD,L,NX)
C
C     WITH ENTRY POINT SORTI2 TO SORT TABLE BY 2 KEY WORDS
C
C     THIS SORTING ROUTINE WAS CALLED SORT BEFORE, AND IS NOW RENAMED
C     SORTI. IT IS CAPABLE FOR IN-CORE SORTING AND FILE SORT.
C
C     THE NEW SUBROUTINE SORT IS A TRUNCATED VERSION OF THIS ROUTINE
C     ONLY FOR IN-CORE SORTING. IT CAN HANDLE INTEGER, REAL, BCD(A4),
C     BCD(A8), BCD(A7), AND 2-KEY SORTINGS.
C
C     (95 PERCENT OF NASTRAN ROUTINES ACTUALLY CALL SORT. THE REMAINING
C       5 PERCENT CALL SORTI)
C
C     IF INPFL AND OUTFL ARE ZERO, CALLING ROUTINE SHOULD CALL SORT
C     FOR EFFICIENCY
C
C     THE OLD SHUTTLE EXCHANGE, WHICH WAS VERY SLOW, IS NOW REPLACED BY
C     A SUPER FAST SORTER, A MODIFIED SHELL SORT.
C
C     THIS MODIFIED VERSION ALSO SORTS TABLE OF ANY LENGTH (PREVIOUSLY N
C     OF WORDS PER ENTRY, NWDS, WAS LIMITED TO 20)
C
      INTEGER         OUTFL,SCRA,SCRB,SCRC,DIST1,DIST2,DUMMY,TOTAL,OUT,
     1                SUBR(2),L(NWDS,2),TEMP,FILE,R,BUFA,BUFB,BUFC,
     2                SYSBUF,BUFIN,TWO,TWO31
      COMMON /SETUP / NFILE(6),BUFIN
      COMMON /SYSTEM/ SYSBUF,DUM38(38),NBPW
      COMMON /TWO   / TWO(16)
      EQUIVALENCE     (NFILE(1),SCRB),(NFILE(2),SCRC),(NFILE(3),SCRA)
      DATA    SUBR  / 4HSORT, 4HI    /
C
      KEY2 = 1
      GO TO 10
C
C
      ENTRY SORTI2 (INPFL,OUTFL,NWDS,KEYWRD,L,NX)
C     ==========================================
C
      KEY2 = 2
C
C     IF INPFL EQ 0, CORE BLOCK L OF LENGTH NX IS TO BE SORTED
C     IF INPFL NE 0, INPFL IS TO BE SORTED USING BLOCK L
C
   10 KEYWD = IABS(KEYWRD)
      NNN   = NX
      IF (NNN .LT. NWDS) GO TO 350
      J = 30
      IF (NBPW .GE. 60) J = 62
      TWO31 = 2**J
      IF (INPFL .EQ. 0) GO TO 30
      BUFA  = NX - SYSBUF + 1
C
C     MINIMUM CORE REQUIREMENT = 2 X NUMBER OF WORDS PER ENTRY
C
      NZ  = BUFA - 1
      IF (NZ .LT. NWDS+NWDS) GO TO 360
      CALL OPEN (*370,SCRA,L(BUFA,1),1)
      NN  = (NZ/NWDS)*NWDS
      NNN = NN
      OUT = SCRA
      NREC= 0
   20 CALL READ (*430,*170,INPFL,L,NN,0,NNN)
C
C     SORT PHASE --
C
   30 LEN = NNN/NWDS
      IF (LEN*NWDS .NE. NNN) GO TO 365
      M = LEN
      IF (KEYWRD .GE. 0) GO TO 40
C
C                     - INTEGER SORT ONLY -
C     IF ORIGINAL ORDER IS TO BE MAINTAINED WHERE DUPLICATE KEYWORDS MAY
C     OCCUR, ADD INDICES TO THE KEYWORDS (GOOD FOR BOTH POSITIVE AND
C     NEGATIVE RANGES, AND BE SURE THAT KEYWORDS ARE NOT OVERFLOWED),
C     SORT THE DATA, AND REMOVE THE INDICES LATER
C
C     IF ANY KEYWORD OVERFLOWS, SWITCH TO SHUTTLE EXCHANGE METHOD
C     LIMIT IS THE MAX VALUE BEFORE INTEGER OVERFLOW
C
      IF (LEN.GE.TWO(16) .AND. NBPW.LE.32) GO TO 130
      LIMIT = (TWO31-LEN)/LEN
      DO 35 I = 1,LEN
      J = L(KEYWD,I)
      IF (IABS(J) .GT. LIMIT) GO TO 124
      J = J*LEN + I
      K = -1
      IF (J .LT. 0) K = -LEN
   35 L(KEYWD,I) = J + K
      IF (KEY2 .EQ. 1) GO TO 40
      DO 37 I = 1,LEN
      J = L(KEYWD+1,I)
      IF (IABS(J) .GT. LIMIT) GO TO 120
      J = J*LEN + I
      K = -1
      IF (J .LT. 0) K = -LEN
   37 L(KEYWD+1,I) = J + K
C
C     SORT BY
C     MODIFIED SHELL METHOD, A SUPER FAST SORTER
C
   40 M = M/2
      IF (M .EQ. 0) GO TO 110
      J = 1
      K = LEN - M
   45 I = J
   50 N = I + M
      IF (L(KEYWD,I)-L(KEYWD,N)) 105, 60,95
   60 IF (KEY2 .EQ. 1) GO TO 105
      IF (L(KEYWD+1,I)-L(KEYWD+1,N)) 105,105,95
   95 DO 100 R = 1,NWDS
      TEMP   = L(R,I)
      L(R,I) = L(R,N)
  100 L(R,N) = TEMP
      I = I - M
      IF (I .GE. 1) GO TO 50
  105 J = J + 1
      IF (J-K) 45,45,40
  110 IF (KEYWRD .GE. 0) GO TO 160
      DO 115 I = 1,LEN
      L(KEYWD,I) = L(KEYWD,I)/LEN
      IF (KEY2 .EQ. 2) L(KEYWD+1,I) = L(KEYWD+1,I)/LEN
  115 CONTINUE
      GO TO 160
C
C     SORT BY
C     SHUTTLE EXCHANGE METHOD, A SLOW SORTER
C     (THIS WAS NASTRAN ORIGINAL SORTER, MODIFIED FOR 2-D ARRAY
C     OPERATION WITH 20-COLUMN LIMITATION REMOVED)
C
  120 IF (I .LE. 1) GO TO 123
      J = I - 1
      DO 121 I = 1,J
  121 L(KEYWD+1,I) = L(KEYWD+1,I)/LEN
  123 I = LEN
  124 IF (I .LE. 1) GO TO 130
      J = I - 1
      DO 125 I = 1,J
  125 L(KEYWD,I) = L(KEYWD,I)/LEN
C
  130 DO 155 II = 2,LEN
      JJ = II - 1
      IF (L(KEYWD,II)-L(KEYWD,JJ)) 135,133,155
  133 IF (KEY2 .EQ. 1) GO TO 155
      IF (L(KEYWD+1,II) .GE. L(KEYWD+1,JJ)) GO TO 155
  135 JJ = JJ - 1
      IF (JJ .LE. 0) GO TO 140
      IF (L(KEYWD,II)-L(KEYWD,JJ)) 135,137,140
  137 IF (KEY2 .EQ. 2) IF (L(KEYWD+1,II)-L(KEYWD+1,JJ)) 135,140,140
  140 JJ = JJ + 2
      DO 150 I = 1,NWDS
      TEMP = L(I,II)
      M = II
      DO 145 J = JJ,II
      L(I,M) = L(I,M-1)
  145 M = M - 1
  150 L(I,JJ-1) = TEMP
  155 CONTINUE
C
C     IF CORE SORT, SORT IS COMPLETED. IF FILE SORT, WRITE BLOCK ON
C     SCRATCH FILE TO BE MERGED LATER.
C
  160 IF (INPFL .EQ. 0) GO TO 350
  165 CALL WRITE (SCRA,L,NNN,1)
      NREC = NREC + 1
      IF (NNN-NN) 180,20,180
  170 IF (NNN) 180,180,175
  175 IF (NNN-NWDS-NWDS) 165,30,30
  180 CALL CLOSE (SCRA,1)
C
C     IF ONLY ONE RECORD, BYPASS MERGE
C
      IF (NREC .EQ. 1) GO TO 320
C
C     COMPUTE OPTIMUM DISTRIBUTION OF SORTED RECORDS ON TWO SCRATCH
C     FILES FOR MERGE PHASE USING FIBONACCI SEQUENCE
C
      LEVEL = 0
      DIST1 = 1
      DIST2 = 0
      TOTAL = 1
  190 DUMMY = TOTAL - NREC
      IF (DUMMY .GE. 0) GO TO 195
      DIST1 = DIST1 + DIST2
      DIST2 = DIST1 - DIST2
      TOTAL = DIST1 + DIST2
      LEVEL = LEVEL + 1
      GO TO 190
  195 BUFB  = BUFA - SYSBUF
      BUFC  = BUFB - SYSBUF
      IF (BUFC .LT. 1) GO TO 360
      NN = BUFB - 1
C
C     COPY N SORTED RECORDS ONTO SECOND SCRATCH FILE
C
      CALL OPEN (*370,SCRA,L(BUFA,1),0)
      CALL OPEN (*380,SCRB,L(BUFB,1),1)
      N = DIST2 - DUMMY
      DO 205 I = 1,N
  200 CALL READ  (*440,*205,SCRA,L,NN,0,NFLAG)
      CALL WRITE (SCRB,L,NN,0)
      GO TO 200
  205 CALL WRITE (SCRB,L,NFLAG,1)
      CALL CLOSE (SCRB,1)
      CALL CLOSE (SCRA,2)
      NFILE(4) = SCRB
      NFILE(5) = SCRC
      K = 4
C
C     MERGE PHASE ---
C     INPUT FILE WITH GREATER NUMBER IF RECORDS = IN1
C     INPUT FILE WITH LESSER  NUMBER OF RECORDS = IN2
C     EACH PASS MERGES ALL RECORDS FROM IN2 WITH LIKE NUMBER OF RECORDS
C     (INCLUDING DUMMY RECORDS) FROM IN1 ONTO OUT. FOR NEXT PASS IN1
C     BECOMES IN2, IN2 BECOMES OUT, AND OUT BECOMES IN1.
C
      DO 310 I = 1,LEVEL
      K = K - 1
      IF (K .EQ. 0) K = 3
      IN1 = NFILE(K)
      IN2 = NFILE(K+1)
      OUT = NFILE(K+2)
      LAST= 2
      CALL OPEN (*390,IN1,L(BUFA,1),2)
      CALL OPEN (*400,IN2,L(BUFB,1),2)
      CALL OPEN (*410,OUT,L(BUFC,1),1)
      DO 300 J = 1,DIST2
      IF1 = NWDS
      IF2 = NWDS
      CALL READ (*450,*275,IN1,L,NWDS,0,IF1)
      IF (DUMMY) 210,210,280
  210 CALL READ (*460,*290,IN2,L(1,2),NWDS,0,IF2)
  220 IF (L(KEYWD,1)-L(KEYWD,2)) 260,230,270
  230 IF (KEY2 .EQ. 2) IF (L(KEYWD+1,1)-L(KEYWD+1,2)) 260,260,270
  260 CALL WRITE (OUT,L,NWDS,0)
      CALL READ  (*450,*275,IN1,L,NWDS,0,IF1)
      IF (IF2) 260,260,220
  270 CALL WRITE (OUT,L(1,2),NWDS,0)
      CALL READ  (*460,*290,IN2,L(1,2),NWDS,0,IF2)
      IF (IF1) 270,270,220
  275 IF (IF2) 300,300,270
  280 DUMMY = DUMMY - 1
      IF2 = 0
  290 IF (IF1) 300,300,260
  300 CALL WRITE (OUT,0,0,1)
      DIST2 = DIST1 - DIST2
      DIST1 = DIST1 - DIST2
      IF (DIST2 .EQ. 0) LAST = 1
      CALL CLOSE (IN1,LAST)
      CALL CLOSE (IN2,1)
  310 CALL CLOSE (OUT,1)
C
C     COPY PHASE ---
C     IF OUTPUT FILE IS NOT SPECIFIED, NFILE(6) WILL CONTAIN NAME OF
C     SCRATCH FILE CONTAINING OUTPUT
C
  320 NFILE(6) = OUT
      IF (OUTFL .EQ. 0) GO TO 350
      CALL OPEN (*410,OUT,L(BUFA,1),0)
      IF (INPFL .NE. OUTFL) GO TO 330
      CALL CLOSE (INPFL,1)
      CALL OPEN  (*420,INPFL,L(BUFIN,1),1)
  330 CALL READ  (*470,*340,OUT,L,NZ,0,NFLAG)
      CALL WRITE (OUTFL,L,NZ,0)
      GO TO 330
  340 CALL WRITE (OUTFL,L,NFLAG,1)
      CALL CLOSE (OUT,1)
  350 RETURN
C
C     ERRORS
C
  360 J = -8
      FILE = 0
      GO TO  500
  365 J = -37
      GO TO  500
  370 FILE = SCRA
      GO TO  480
  380 FILE = SCRB
      GO TO  480
  390 FILE = IN1
      GO TO  480
  400 FILE = IN2
      GO TO  480
  410 FILE = OUT
      GO TO  480
  420 FILE = INPFL
      GO TO  480
  430 FILE = INPFL
      GO TO  490
  440 FILE = SCRA
      GO TO  490
  450 FILE = IN1
      GO TO  490
  460 FILE = IN2
      GO TO  490
  470 FILE = OUT
      GO TO  490
  480 J = -1
      GO TO  500
  490 J = -2
  500 CALL MESAGE (J,FILE,SUBR)
      RETURN
      END