File: /nfs/home/0/users/jenkins/mfix.git/model/parse_mod.f

1           MODULE parse
2     
3           Use param
4           Use param1
5           USE funits
6           USE compar
7     
8           IMPLICIT NONE
9     
10     ! Strings indicating arithmetic operation and reaction blocks.
11           CHARACTER(LEN=2), PARAMETER :: START_STR = '@('  ! start
12           CHARACTER(LEN=1), PARAMETER :: END_STR = ')'     ! end
13     
14     ! Strings indicating reaction blocks.
15           CHARACTER(LEN=4), PARAMETER :: RXN_BLK     = 'RXNS'      ! start block
16           CHARACTER(LEN=8), PARAMETER :: DES_RXN_BLK = 'DES_RXNS'  ! start block
17           CHARACTER(LEN=3), PARAMETER :: END_BLK     = 'END'       ! end block
18     
19           LOGICAL READING_RXN
20           LOGICAL READING_RATE
21     
22           LOGICAL DES_RXN
23           LOGICAL TFM_RXN
24     
25     ! Logical indicating that the start of a reaction construct has
26     ! been identified.
27           LOGICAL IN_CONSTRUCT
28     
29     ! Logical indicating that the chemical equation spans additional lines.
30           LOGICAL MORE_ChemEq
31     
32     ! Reaction names
33           CHARACTER(len=32),  DIMENSION(:),   ALLOCATABLE :: RXN_NAME
34     ! chemical Equations
35           CHARACTER(len=512), DIMENSION(:),   ALLOCATABLE :: RXN_CHEM_EQ
36     ! User defined heat of reaction
37           DOUBLE PRECISION,   DIMENSION(:),   ALLOCATABLE :: usrDH
38     ! User defined heat of reaction partitions.
39           DOUBLE PRECISION,   DIMENSION(:,:), ALLOCATABLE :: usrfDH
40     
41     
42     ! Logical indicating that the start of a reaction construct has
43     ! been identified.
44           LOGICAL IN_DES_CONSTRUCT
45     
46     ! Reaction names
47           CHARACTER(len=32),  DIMENSION(:),   ALLOCATABLE :: DES_RXN_NAME
48     ! chemical Equations
49           CHARACTER(len=512), DIMENSION(:),   ALLOCATABLE :: DES_RXN_CHEM_EQ
50     ! User defined heat of reaction
51           DOUBLE PRECISION,   DIMENSION(:),   ALLOCATABLE :: DES_usrDH
52     ! User defined heat of reaction partitions.
53           DOUBLE PRECISION,   DIMENSION(:,:), ALLOCATABLE :: DES_usrfDH
54     
55           CONTAINS
56     
57     !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!
58     !  Function name: setReaction                                          !
59     !                                                                      !
60     !  Purpose:                                                            !
61     !                                                                      !
62     !  Variables referenced: None                                          !
63     !                                                                      !
64     !  Variables modified: None                                            !
65     !                                                                      !
66     !  Local variables: None                                               !
67     !                                                                      !
68     !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!
69           SUBROUTINE setReaction(RxN, lNg, lSAg, lM, lNs, lSAs, lDH, lfDH)
70     
71           use rxn_com
72           use toleranc
73     
74           IMPLICIT NONE
75     
76     ! Pass Arguments:
77     !---------------------------------------------------------------------//
78     ! Data structure for storing reaction data.
79           TYPE(REACTION_BLOCK), POINTER, INTENT(INOUT) :: RxN
80     ! Number of gas speices
81           INTEGER, INTENT(IN) :: lNg
82     ! Gas phase species aliases
83           CHARACTER(len=32), DIMENSION(DIM_N_g), INTENT(IN) :: lSAg
84     ! Number of solids phases
85           INTEGER, INTENT(IN) :: lM
86     ! Number of species in each solids phase.
87           INTEGER, DIMENSION(DIM_M), INTENT(IN) :: lNs
88     ! Solids phase speices aliases.
89           CHARACTER(len=32), DIMENSION(DIM_M, DIM_N_s), INTENT(IN) :: lSAs
90     ! User defined heat of reaction.
91           DOUBLE PRECISION, INTENT(IN) :: lDH
92     ! User defined heat of reaction partition.
93           DOUBLE PRECISION, DIMENSION(0:DIM_M), INTENT(IN) :: lfDH
94     
95     ! Local Variables:
96     !---------------------------------------------------------------------//
97     ! Alias, phase, species, stoich coeff :: Reactants    Products
98           CHARACTER(LEN=32), DIMENSION(50)     :: rAlias    ,  pAlias
99           DOUBLE PRECISION, DIMENSION(50) :: rCoeff    ,  pCoeff
100     
101     ! Number of products and reactants
102           INTEGER rNo, pNo
103     ! Positions in ChemEq delineating the reactants and products.
104           INTEGER rEnd, pStart
105     ! Loop counters
106           INTEGER L, LL, M, lN
107     
108     ! Sum of user specified heat of reaction partitions. If fracDH is set
109     ! by the user, they must sum to one over all phases.
110           DOUBLE PRECISION sumFDH
111     ! Local storage for chemical equations, left-adjusted and trimmed
112           CHARACTER(LEN=512) lChemEq
113     ! Local storage for reaction name, left-adjusted and trimmed
114           CHARACTER(LEN=32)  lName
115     ! Logical indicating the reaction is skipped.
116           LOGICAL Skip
117     
118           LOGICAL pMap(0:lM)
119     
120           INTEGER nSpecies, nPhases
121     
122           LOGICAL blankAlias(0:(DIM_N_g + lM*DIM_N_s))
123     
124     ! Initialize local reaction name and chemical equation variables.
125           lName = trim(adjustl(RxN%Name))
126           lChemEq = trim(adjustl(RxN%ChemEq))
127     
128           RxN%Classification = "Undefined"
129           RxN%Calc_DH = .TRUE.
130           RxN%nSpecies = 0
131           RxN%nPhases = 0
132     
133     ! Verify that the reactants are separated by --> or = signs. If the
134     ! chemical equation is NONE, the reaction is skipped.
135           CALL checkSplit(lName, lChemEq, rEnd, pStart, Skip)
136           IF(Skip) THEN
137              RxN%nSpecies = 0
138              RETURN
139           ENDIF
140     ! Set the flag to calculate heat of reaction.
141           RxN%Calc_DH = .TRUE.
142           IF(lDH /= UNDEFINED) RxN%Calc_DH = .FALSE.
143     
144     ! Pull off the reactants from the chemical equations.
145           CALL splitEntries(lName, lChemEq, 1, rEnd, rNo, rAlias, rCoeff)
146     ! Pull off the products from the chemical equations.
147           CALL splitEntries(lName, lChemEq, pStart, len_trim(lChemEq),     &
148              pNo, pAlias, pCoeff)
149     
150           nSpecies = rNo + pNo
151           RxN%nSpecies = nSpecies
152           Allocate( RxN%Species( nSpecies ))
153     
154           CALL checkBlankAliases(lNg, lSAg, lM, lNs, lSAs, blankAlias)
155     
156     ! Check that species in the chemical equation match a species alias
157     ! in one of the phases.
158           CALL mapAliases(lName, lChemEq, lNg, lSAg, lM, lNs, lSAs, rNo,   &
159              rAlias, rCoeff, -ONE, 0, blankAlias, RxN)
160     
161     ! Check that species in the chemical equation match a species alias
162     ! in one of the phases.
163           CALL mapAliases(lName, lChemEq, lNg, lSAg, lM, lNs, lSAs, pNo,   &
164              pAlias, pCoeff, ONE, rNo, blankAlias, RxN)
165     
166     ! All the relevant data has been collected at this point. Build the
167     ! reaction block data structure.
168           L = max(1,lM)
169           LL = (L * (L-1)/2)
170           Allocate( RxN%rPhase( LL+L ))
171     
172     
173     ! Initialize local map and global values
174           pMap(:) = .FALSE.
175           nPhases = 0
176           DO lN = 1, nSpecies
177              M = RxN%Species(lN)%pMap
178     
179              RxN%Species(lN)%mXfr = M
180              RxN%Species(lN)%xXfr = ZERO
181     
182              IF(.NOT.pMap(M)) THEN
183                 pMap(M) = .TRUE.
184                 nPhases = nPhases + 1
185              ENDIF
186           ENDDO
187           RxN%nPhases = nPhases
188     
189     ! Initialize sum of heat of reaction partitions.
190           sumFDH = ZERO
191     ! The user specified the heat of reaction.
192           IF(.NOT.RxN%Calc_DH) THEN
193     ! Allocate and initialize the heat of reaction storage array.
194              Allocate( RxN%HoR( 0:lM ))
195              RxN%HoR(:) = ZERO
196              DO M=0,lM
197     ! The phase is referenced by the reaction and heat of reaction is
198     ! allocated (in part or fully) this this phase.
199                 IF(pMap(M) .AND. lFDH(M) .NE. UNDEFINED) THEN
200     ! Store the heat of reaction.
201                    RxN%HoR(M) = lFDH(M) * lDH
202                    sumFDH = sumFDH + lFDH(M)
203     ! The phase is not referenced by the reaction, but the heat of reaction
204     ! is allocated (in part or fully) to this phase. Flag error and exit.
205                 ELSEIF(.NOT.pMap(M) .AND. lFDH(M) .NE. UNDEFINED) THEN
206                    IF(myPE == PE_IO) THEN
207                       write(*,1000) trim(lName)
208                       write(*,1001)
209                       write(*,1010)
210     ! Write message to log file.
211                       write(UNIT_LOG,1000) trim(lName)
212                       write(UNIT_LOG,1001)
213                       write(UNIT_LOG,1010)
214                    ENDIF
215     ! Exit MFIX
216                    CALL MFIX_EXIT(myPE)
217                 ENDIF
218              ENDDO
219     ! Logical check: No partition was assigned to an undefined phase.
220              DO M=lM+1,DIM_M
221                 IF(.NOT.RxN%Calc_DH .AND. lFDH(M) .NE. UNDEFINED) THEN
222                    IF(myPE == PE_IO) THEN
223                       write(*,1000) trim(lName)
224                       write(*,1001)
225                       write(*,1010)
226     ! Write message to log file.
227                       write(UNIT_LOG,1000) trim(lName)
228                       write(UNIT_LOG,1001)
229                       write(UNIT_LOG,1010)
230     ! Exit MFIX
231                    ENDIF
232                    CALL MFIX_EXIT(myPE)
233                 ENDIF
234              ENDDO
235           ENDIF
236     
237     ! Verify that the heat of reaction partitions sum to one.
238           IF(.NOT.RxN%Calc_DH .AND. .NOT. COMPARE(sumFDH, ONE)) THEN
239              IF(myPE == PE_IO) THEN
240                 write(*,1002) trim(lName)
241                 write(*,1010)
242     ! Write message to log file.
243                 write(UNIT_LOG,1002) trim(lName)
244                 write(UNIT_LOG,1010)
245     ! Exit MFIX
246                 CALL MFIX_EXIT(myPE)
247              ENDIF
248           ENDIF
249     
250           RETURN
251     
252      1000 FORMAT(/1X,70('*')/' From: From: setReaction:',/                 &
253              ' Message: Heat of reaction is proportioned to a phase not',  &
254              ' referenced',/' by the chemical equation for reaction ',A,'.')
255     
256      1001 FORMAT(/' If this is a catalytic reaction, reference one of the',&
257              ' species of the',/' catalyst phase within the chemical',     &
258              ' equation with a stoichiometric',/' coefficient of zero.'/)
259     
260      1002 FORMAT(/1X,70('*')/' From: From: setReaction:',/                 &
261              ' Message: The heat of reaction partitions (fracDH) to all',  &
262              ' phases do',/' not sum to one for reaction ',A,'.')
263     
264      1010 FORMAT(' Please refer to the Readme file for chemical equation', &
265              ' input formats',/' and correct the data file.',/1X,70('*')/)
266     
267     
268           END SUBROUTINE setReaction
269     
270     
271     !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!
272     !  Function name: checkSplit                                           !
273     !                                                                      !
274     !  Purpose: Determine the location of reactatns and products within    !
275     !  the chemical equation. If the entry is NONE, flag that the reaction !
276     !  is to be skipped for further processing.                            !
277     !                                                                      !
278     !  Variables referenced: None                                          !
279     !                                                                      !
280     !  Variables modified: None                                            !
281     !                                                                      !
282     !  Local variables: None                                               !
283     !                                                                      !
284     !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!
285           SUBROUTINE checkSplit(lName, lChemEq, lrEnd, lpStart, lSkip)
286     
287           IMPLICIT NONE
288     
289     ! Pass Arguments:
290     !---------------------------------------------------------------------//
291     ! Chemical reaction name.
292           CHARACTER(len=*), INTENT(IN) :: lName
293     ! Chemical Equation from deck file.
294           CHARACTER(len=*), INTENT(IN) :: lChemEq
295     ! Position specifying the end of the reactants in lChemEq
296           INTEGER, INTENT(OUT) :: lrEnd
297     ! Position specifying the start of the products in lChemEq
298           INTEGER, INTENT(OUT) :: lpStart
299     ! If the chemical equation is NONE, the the skip flag is set to avoid
300     ! further processing.
301           LOGICAL, INTENT(OUT) :: lSkip
302     
303     ! Local Variables:
304     !---------------------------------------------------------------------//
305     ! Position of the head (>) and tail (-) of an arror (-->)
306           INTEGER hArr, tArr
307     ! Postion of the head and tail of equal signs (=, ==, ===, ...)
308           INTEGER hEqs, tEqs
309     ! Position of the head/tail of a reverse arrow (<--)
310           INTEGER hRArr, tRArr
311     ! A flag generated to point out the location of the entry error.
312           CHARACTER(LEN=512) FLAG
313           FLAG = ''
314     
315     ! If the chemical equation is set to 'none', then the reaction is
316     ! skipped for the simulation.
317           lSkip = .FALSE.
318           IF(INDEX(lChemEq,'NONE') > 0) THEN
319              lSkip = .TRUE.
320              lrEnd = UNDEFINED_I
321              lpStart = UNDEFINED_I
322              RETURN
323           ENDIF
324     
325     ! Search for > (part of -->) and search for < (part of <--)
326           tArr = INDEX(lChemEq,'-', BACK=.FALSE.)
327           hArr = INDEX(lChemEq,">", BACK=.TRUE.)
328     ! Search for the first and last instances of equal signs.
329           tEqs = INDEX(lChemEq,"=", BACK=.FALSE.)
330           hEqs = INDEX(lChemEq,"=", BACK=.TRUE.)
331     ! Search for < (as part of <-- or <-->). Illegal chemical equation.
332           hRArr = INDEX(lChemEq,"<", BACK=.FALSE.)
333           tRArr = INDEX(lChemEq,"-", BACK=.TRUE.)
334     
335     ! An illegal arrow was found! Flag error and exit.
336           IF(hRArr > 0) THEN
337              IF(myPE == PE_IO) THEN
338     ! Construct the error flag.
339                 IF(hArr > 0) THEN
340                    FLAG = setFlag(20, hRArr, hArr)
341                 ELSEIF(tRArr > 0) THEN
342                    FLAG = setFlag(20, hRArr, tRArr)
343                 ELSE
344                    FLAG = setFlag(20, hRArr)
345                 ENDIF
346     ! Write the message to the screen.
347                 write(*,1000) trim(lName)
348                 write(*,1002)'Illegal'
349                 write(*,1010) trim(lChemEq), trim(Flag)
350                 write(*,1001)
351     ! Write message to log file.
352                 write(UNIT_LOG,1000) trim(lName)
353                 write(UNIT_LOG,1002)'Illegal'
354                 write(UNIT_LOG,1010) trim(lChemEq), trim(Flag)
355                 write(UNIT_LOG,1001)
356     ! Exit MFIX
357                 CALL MFIX_EXIT(myPE)
358              ENDIF
359           ENDIF
360     ! If there are more than one operator, flag error and exit.
361           IF(hArr /= 0 .AND. hEqs /= 0) THEN
362              IF(myPE == PE_IO) THEN
363     ! Construct the error flag.
364                 FLAG = setFlag(20, hArr, hEqs)
365     ! Write the message to the screen.
366                 write(*,1000) trim(lName)
367                 write(*,1002)'Too many'
368                 write(*,1010) trim(lChemEq), trim(Flag)
369                 write(*,1001)
370     ! Write message to log file.
371                 write(UNIT_LOG,1000) trim(lName)
372                 write(UNIT_LOG,1002)'Too many'
373                 write(UNIT_LOG,1010) trim(lChemEq), trim(Flag)
374                 write(UNIT_LOG,1001)
375     ! Exit MFIX
376                 CALL MFIX_EXIT(myPE)
377              ENDIF
378     ! If there is no operator (--> or =), flag error and exit.
379           ELSEIF(hArr == 0 .AND. hEqs == 0) THEN
380              IF(myPE == PE_IO) THEN
381                 write(*,1000) trim(lName)
382                 write(*,1002) 'No'
383                 write(*,1011) trim(lChemEq)
384                 write(*,1001)
385     ! Write message to log file.
386                 write(UNIT_LOG,1000) trim(lName)
387                 write(UNIT_LOG,1002) 'No'
388                 write(UNIT_LOG,1011) trim(lChemEq)
389                 write(UNIT_LOG,1001)
390     ! Exit MFIX
391                 CALL MFIX_EXIT(myPE)
392              ENDIF
393     ! The head of an arrow was found.
394           ELSEIF(hArr /= 0) THEN
395     ! Verify that a tail was found.
396              IF(tArr == 0) THEN
397     ! Construct the error flag.
398                 FLAG = setFlag(20, hArr)
399                 IF(myPE == PE_IO) THEN
400                    write(*,1000) trim(lName)
401                    write(*,1003) 'Missing the tail; -->'
402                    write(*,1010) trim(lChemEq), trim(Flag)
403                    write(*,1001)
404     ! Write message to log file.
405                    write(UNIT_LOG,1000) trim(lName)
406                    write(UNIT_LOG,1003) 'Missing the tail; -->'
407                    write(UNIT_LOG,1010) trim(lChemEq), trim(Flag)
408                    write(UNIT_LOG,1001)
409     ! Exit MFIX
410                    CALL MFIX_EXIT(myPE)
411                 ENDIF
412              ELSEIF(tArr > hArr) THEN
413                 IF(myPE == PE_IO) THEN
414                    FLAG = setFlag(20, hArr, INDEX(lChemEq,'-',BACK=.TRUE.))
415                    write(*,1000) trim(lName)
416                    write(*,1003) 'Arror head preceeds the tail; -->'
417                    write(*,1010) trim(lChemEq), trim(Flag)
418                    write(*,1001)
419     ! Write message to log file.
420                    write(UNIT_LOG,1000) trim(lName)
421                    write(UNIT_LOG,1003) 'Arror head preceeds the tail; -->'
422                    write(UNIT_LOG,1010) trim(lChemEq), trim(Flag)
423                    write(UNIT_LOG,1001)
424     ! Exit MFIX
425                    CALL MFIX_EXIT(myPE)
426                 ENDIF
427              ELSE
428     ! An arror was used to seperate reactants and products. Send back the
429     ! ending index of reactants and the starting index for products.
430                 lrEnd = tArr - 1
431                 lpStart = hArr + 1
432              ENDIF
433     ! Equals sign(s) were used to specify the reaction. Send back the ending
434     ! index of reactants and the starting index for products.
435           ELSEIF(hEqs /= 0) THEN
436              lrEnd = tEqs - 1
437              lpStart = hEqs + 1
438     ! Fatal Error. One of the above checks should have caught any problems
439     ! and sent out an error message.
440           ELSE
441              IF(myPE == PE_IO) THEN
442                 write(*,1000) trim(lName)
443                 write(*,1004)
444                 write(*,1011) trim(lChemEq)
445                 write(*,1001)
446     ! Write message to log file.
447                 write(UNIT_LOG,1000) trim(lName)
448                 write(UNIT_LOG,1004)
449                 write(UNIT_LOG,1010) trim(lChemEq), trim(Flag)
450                 write(UNIT_LOG,1001)
451     ! Exit MFIX
452                 CALL MFIX_EXIT(myPE)
453              ENDIF
454           ENDIF
455     
456           RETURN
457     
458      1000 FORMAT(/1X,70('*')/' From: From: setReaction --> checkSplit',/   &
459              ' Message: Error in determining the reactants and products',  &
460              ' in the',/' chemical equation for reaction ',A,'.')
461     
462      1001 FORMAT(' Please refer to the Readme file for chemical equation', &
463              ' input formats',/' and correct the data file.',/1X,70('*')/)
464     
465      1002 FORMAT(/1X,A,' operators were found!')
466     
467      1003 FORMAT(' Incorrect operator format! ',A)
468     
469      1004 FORMAT(' FATAL ERROR: All logical checks failed.')
470     
471      1010 FORMAT(/' Chemical Equation: ',A,/1X, A/)
472     
473      1011 FORMAT(/' Chemical Equation: ',A,/)
474     
475     
476           END SUBROUTINE checkSplit
477     
478     
479     !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!
480     !  Function name: splitEntries()                                       !
481     !                                                                      !
482     !  Purpose: Takes a string of either reactants or products and splits  !
483     !  the string into individual species/stoichiometric entries.          !
484     !                                                                      !
485     !  A call to splitAliasAndCoeff is made to further split the entries   !
486     !  into species aliases and matching stoichiometric coefficients.      !
487     !                                                                      !
488     !  Variables referenced: None                                          !
489     !                                                                      !
490     !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!
491           SUBROUTINE splitEntries(lName, lChemEq, lStart, lEnd, lNo,       &
492              lAlias, lCoeff)
493     
494           IMPLICIT NONE
495     
496     ! Pass Arguments:
497     !---------------------------------------------------------------------//
498     ! Chemical reaction name.
499           CHARACTER(len=*), INTENT(IN) :: lName
500     ! Chemical Equation.
501           CHARACTER(len=*), INTENT(IN) :: lChemEq
502     ! Starting position for substring analysis.
503           INTEGER, INTENT(IN) :: lStart
504     ! Ending position for substring analysis.
505           INTEGER, INTENT(IN) :: lEnd
506     ! The number of individual species found in lSpecies.
507           INTEGER, INTENT(OUT) :: lNo
508     ! Species Aliases from the chemical equation.
509           CHARACTER(LEN=32), DIMENSION(50), INTENT(OUT) :: lAlias
510     ! Stoichiometric coefficient pulled from the chemical equation.
511           DOUBLE PRECISION, DIMENSION(50), INTENT(OUT) :: lCoeff
512     
513     ! Local Variables:
514     !---------------------------------------------------------------------//
515     ! Flag indicating that there are more entries to process.
516           LOGICAL MORE
517     ! Starting position for left-to-right search.
518           INTEGER lPOS
519     ! Position of plus sign charachter found in search.
520           INTEGER rPOS
521     
522     ! Initialize storage variables.
523           lNo = 0
524           lAlias(:) = ''
525           lCoeff(:) = UNDEFINED
526     
527     ! Initialiase local variables.
528           lPOS = lStart
529           MORE = .TRUE.
530     ! Loop through the string, splitting entries separated by a plus sign.
531           DO WHILE(MORE)
532     ! Increment the species counter.
533              lNo = lNo + 1
534     ! Locate the plus sign. (Left to right)
535              rPOS = (lPOS-1) + INDEX(lChemEq(lPOS:lEnd),"+", BACK=.FALSE.)
536     ! A plus sign was found.
537              IF(rPOS .GT. lPOS) THEN
538     ! Extract the entry and split it into the species alias and
539     ! stoichiometric coefficient.
540                 CALL splitAliasAndCoeff(lName, lChemEq, lPOS, rPOS-1,      &
541                    lAlias(lNo), lCoeff(lNo))
542     ! Indicate that there are more entries to process.
543                 MORE = .TRUE.
544     ! No plus sign was found. This is the last entry.
545              ELSE
546     ! Extract the entry and split it into the species alias and
547     ! stoichiometric coefficient.
548                 CALL splitAliasAndCoeff(lName, lChemEq, lPOS, lEnd,        &
549                    lAlias(lNo), lCoeff(lNo))
550     ! Indicate that there are no more entries to process.
551                 MORE = .FALSE.
552              ENDIF
553     ! Move past the found plus sign for next search.
554              lPOS = rPOS + 1
555           ENDDO
556     
557           RETURN
558           END SUBROUTINE splitEntries
559     
560     !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!
561     !  Function name: splitAliasAndCoeff()                                 !
562     !                                                                      !
563     !  Purpose: Take a string containing a species alias and stoichio-     !
564     !  metric coefficient and splits them into their respective parts.     !
565     !                                                                      !
566     !  If no numerical coefficient is found, it is set to one.             !
567     !                                                                      !
568     !  If present, asterisks (*) are assumed to seperate numerical         !
569     !  coefficients and the species alias. If more than one asterisk is    !
570     !  found, and error is reported and MFIX_EXIT is called.               !
571     !                                                                      !
572     !  Variables referenced: None                                          !
573     !                                                                      !
574     !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!
575           SUBROUTINE splitAliasAndCoeff(lName, lChemEq, lStart, lEnd,      &
576              lAlias, lCoeff)
577     
578           IMPLICIT NONE
579     
580     ! Pass Arguments:
581     !---------------------------------------------------------------------//
582     ! Chemical reaction name.
583           CHARACTER(len=*), INTENT(IN) :: lName
584     ! Chemical Equation.
585           CHARACTER(len=*), INTENT(IN) :: lChemEq
586     ! Starting position for substring analysis.
587           INTEGER, INTENT(IN) :: lStart
588     ! Ending position for substring analysis.
589           INTEGER, INTENT(IN) :: lEnd
590     ! Species Aliases from the chemical equation.
591           CHARACTER(LEN=32), INTENT(OUT) :: lAlias
592     ! Stoichiometric coefficient pulled from the chemical equation.
593           DOUBLE PRECISION, INTENT(OUT) :: lCoeff
594     
595     ! Local Variables:
596     !---------------------------------------------------------------------//
597     ! Flag
598           LOGICAL MATCH
599           INTEGER nPOS
600     
601           INTEGER L, N, IOS, aPOS, a2POS
602     
603           CHARACTER(LEN=12), PARAMETER :: Numbers = '.0123456789'
604     
605     ! A flag generated to point out the location of the entry error.
606           CHARACTER(LEN=512) FLAG
607           FLAG = ''
608     
609     ! Locate the first asterisk (if any). Search left-to-right.
610           aPOS = INDEX(lChemEq(lStart:lEnd),"*", BACK=.FALSE.)
611     ! An asterisk was found.
612           IF(aPOS .GT. ZERO) THEN
613     ! Make sure that there isn't another asterisk further down the string.
614              a2POS = INDEX(lChemEq(lStart:lEnd),"*", BACK=.TRUE.)
615              IF(aPOS /= a2POS) THEN
616                 IF(myPE == PE_IO) THEN
617     ! Construct the error flag.
618                    FLAG = setFlag(20, lStart+aPOS, lStart+a2POS)
619     ! Write the message to the screen.
620                    write(*,1000) trim(lName)
621                    write(*,1002)'Too many'
622                    write(*,1010) trim(lChemEq), trim(Flag)
623                    write(*,1001)
624     ! Write message to log file.
625                    write(UNIT_LOG,1000) trim(lName)
626                    write(UNIT_LOG,1002)'Too many'
627                    write(UNIT_LOG,1010) trim(lChemEq), trim(Flag)
628                    write(UNIT_LOG,1001)
629     ! Exit MFIX
630                    CALL MFIX_EXIT(myPE)
631                 ENDIF
632              ELSE
633     ! Store left-of-asterisk as the coefficient. If an error occurs in
634     ! converting the string to double precision, flag the problem and
635     ! call MFIX_EXIT.
636                 READ(lChemEq(lStart:(lStart+aPOS-2)),*,IOSTAT=IOS) lCoeff
637                 IF(IOS .NE. 0 .AND. myPE == PE_IO) THEN
638     ! Construct the error flag.
639                    FLAG = setFlag(20, lStart + int(aPOS/2))
640     ! Write the message to the screen.
641                    write(*,1000) trim(lName)
642                    write(*,1010) trim(lChemEq), trim(Flag)
643                    write(*,1001)
644     ! Write message to log file.
645                    write(UNIT_LOG,1000) trim(lName)
646                    write(UNIT_LOG,1010) trim(lChemEq), trim(Flag)
647                    write(UNIT_LOG,1001)
648     ! Exit MFIX
649                    CALL MFIX_EXIT(myPE)
650                 ENDIF
651     ! Store right-of-asterisk as the species alias.
652                 WRITE(lAlias,"(A)") &
653                    trim(adjustl(lChemEq((lStart+aPOS):lEnd)))
654              ENDIF
655     ! If no asterisk was found, search for numbers and spaces.
656           ELSE
657     ! Initialize the position of last consecutive number.
658              nPOS = 0
659     ! In a left-to-right search, check if the characters in the entry are
660     ! numbers or punctuation.
661              DO L=lStart,lEnd
662                 MATCH = .FALSE.
663                 DO N=1,12
664                    IF(lChemEq(L:L) /= Numbers(N:N)) CYCLE
665     ! Note the position of the number.
666                    nPOS = L
667     ! Flag that a match was made.
668                    MATCH = .TRUE.
669                 ENDDO
670     ! If no match, assume the end of the coefficient was found.
671                 IF(.NOT.MATCH) EXIT
672              ENDDO
673     ! If no numbers or punctuation was found, assumed the stoichiometric
674     ! coefficient is one.
675              IF(trim(lChemEq(lStart:nPOS)) =='') THEN
676                 lCoeff = 1.0d0
677              ELSE
678     ! If leading numbers were found, store as the stoich-coeff.
679                 READ(lChemEq(lStart:nPOS),*,IOSTAT=IOS) lCoeff
680     ! Report any problems in converting the string to double precision.
681                 IF(IOS .NE. 0 .AND. myPE == PE_IO) THEN
682     ! Construct the error flag.
683                    FLAG = setFlag(20, &
684                       lStart+int(len_trim(lChemEq(lStart:nPOS))/2))
685     ! Write the message to the screen.
686                    write(*,1000) trim(lName)
687                    write(*,1010) trim(lChemEq), trim(Flag)
688                    write(*,1001)
689     ! Write message to log file.
690                    write(UNIT_LOG,1000) trim(lName)
691                    write(UNIT_LOG,1010) trim(lChemEq), trim(Flag)
692                    write(UNIT_LOG,1001)
693     ! Exit MFIX
694                    CALL MFIX_EXIT(myPE)
695                 ENDIF
696              ENDIF
697     ! Store right-of-coefficient as the species alias.
698              READ(lChemEq(nPOS+1:lEnd),*,IOSTAT=IOS) lAlias
699           ENDIF
700     ! Quick check to make sure that the species alias is not empty.
701           IF(LEN_TRIM(lAlias) == 0 .AND. myPE == PE_IO) THEN
702     ! Construct the error flag.
703              FLAG = setFlag(20, lStart + int(lEnd/2))
704     ! Write the message to the screen.
705              write(*,1003) trim(lName)
706              write(*,1010) trim(lChemEq), trim(Flag)
707              write(*,1001)
708     ! Write message to log file.
709              write(UNIT_LOG,1003) trim(lName)
710              write(UNIT_LOG,1010) trim(lChemEq), trim(Flag)
711              write(UNIT_LOG,1001)
712     ! Exit MFIX
713              CALL MFIX_EXIT(myPE)
714           ENDIF
715     
716           RETURN
717     
718      1000 FORMAT(/1X,70('*')/' From: From: setReaction -->',               &
719              ' splitAliasAndCoeff',/' Message: Error determining the',     &
720              ' stoichiometric coefficient in the',/' chemical equation',   &
721              ' for reaction ',A,'.')
722     
723     
724      1001 FORMAT(' Please refer to the Readme file for chemical equation', &
725              ' input formats',/' and correct the data file.',/1X,70('*')/)
726     
727      1002 FORMAT(/1X,A,' operators were found!')
728     
729      1003 FORMAT(/1X,70('*')/' From: From: setReaction -->',               &
730              ' splitAliasAndCoeff',/' Message: Error determining the',     &
731              ' speices in the chemical equation for',/' reaction ',A,'.'/)
732     
733      1010 FORMAT(/' Chemical Equation: ',A,/1X, A/)
734     
735      1011 FORMAT(/' Chemical Equation: ',A,/)
736     
737           END SUBROUTINE splitAliasAndCoeff
738     
739     !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!
740     !  Function name: checkBlankAliases()                                  !
741     !                                                                      !
742     !  Purpose: Take a string containing a species alias and stoichio-     !
743     !  metric coefficient and splits them into their respective parts.     !
744     !                                                                      !
745     !  Variables referenced: None                                          !
746     !                                                                      !
747     !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!
748           SUBROUTINE checkBlankAliases(lNg, lSAg, lM, lNs, lSAs, lBA)
749     
750           IMPLICIT NONE
751     
752     ! Number of gas speices
753           INTEGER, INTENT(IN) :: lNg
754     ! Gas phase species aliases
755           CHARACTER(len=32), DIMENSION(DIM_N_g), INTENT(IN) :: lSAg
756     ! Number of solids phases
757           INTEGER, INTENT(IN) :: lM
758     ! Number of species in each solids phase.
759           INTEGER, DIMENSION(DIM_M), INTENT(IN) :: lNs
760     ! Solids phase speices aliases.
761           CHARACTER(len=32), DIMENSION(DIM_M, DIM_N_s), INTENT(IN) :: lSAs
762     
763           LOGICAL, INTENT(OUT) :: lBA(0:(DIM_N_g + lM*DIM_N_s))
764     
765           INTEGER M, N
766     
767     ! Loop counter for continuum and discrete species
768           INTEGER Nsp
769     
770     ! Initialize counters
771           Nsp = 0
772     
773           lBA(0) = .FALSE.
774           DO N = 1, lNg
775              Nsp = Nsp + 1
776              lBA(Nsp) = .FALSE.
777              IF(len_trim(lSAg(N)) == 0) THEN
778                 lBA(Nsp) = .TRUE.
779                 lBA(0) = .TRUE.
780              ENDIF
781           ENDDO
782     
783     ! Compare aliaes between solids phases
784           DO M = 1, lM
785              DO N = 1, lNs(M)
786                 Nsp = Nsp + 1
787                 lBA(Nsp) = .FALSE.
788                 IF(len_trim(lSAs(M,N)) == 0) THEN
789                    lBA(Nsp) = .TRUE.
790                    lBA(0) = .TRUE.
791                 ENDIF
792              ENDDO
793           ENDDO
794     
795           RETURN
796           END SUBROUTINE checkBlankAliases
797     
798     !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!
799     !  Function name: mapAliases()                                         !
800     !                                                                      !
801     !  Purpose: Take a string containing a species alias and stoichio-     !
802     !  metric coefficient and splits them into their respective parts.     !
803     !                                                                      !
804     !  If no numerical coefficient is found, it is set to one.             !
805     !                                                                      !
806     !  If present, asterisks (*) are assumed to seperate numerical         !
807     !  coefficients and the species alias. If more than one asterisk is    !
808     !  found, and error is reported and MFIX_EXIT is called.               !
809     !                                                                      !
810     !  Variables referenced: None                                          !
811     !                                                                      !
812     !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!
813           SUBROUTINE mapAliases(lName, lChemEq, lNg, lSAg, lM, lNs, lSAs,  &
814              lNo, lAlias, lCoeff, lSgn, lStart, lBA, lRxN)
815     
816           use rxn_com
817     
818           IMPLICIT NONE
819     
820     ! Pass Arguments:
821     !---------------------------------------------------------------------//
822     ! Chemical reaction name.
823           CHARACTER(len=*), INTENT(IN) :: lName
824     ! Chemical Equation.
825           CHARACTER(len=*), INTENT(IN) :: lChemEq
826     ! Number of gas speices
827           INTEGER, INTENT(IN) :: lNg
828     ! Gas phase species aliases
829           CHARACTER(len=32), DIMENSION(DIM_N_g), INTENT(IN) :: lSAg
830     ! Number of solids phases
831           INTEGER, INTENT(IN) :: lM
832     ! Number of species in each solids phase.
833           INTEGER, DIMENSION(DIM_M), INTENT(IN) :: lNs
834     ! Solids phase speices aliases.
835           CHARACTER(len=32), DIMENSION(DIM_M, DIM_N_s), INTENT(IN) :: lSAs
836     ! Number of products (or reactants)
837           INTEGER, INTENT(IN) :: lNo
838     ! Species Alaises pulled from the chemical equation.
839           CHARACTER(LEN=32), DIMENSION(50), INTENT(IN) :: lAlias
840     
841           DOUBLE PRECISION, DIMENSION(50), INTENT(IN) :: lCoeff
842     
843           DOUBLE PRECISION, INTENT(IN) :: lSgn
844     
845           INTEGER, INTENT(IN) :: lStart
846     
847           LOGICAL, INTENT(IN) :: lBA(0:(DIM_N_g + lM*DIM_N_s))
848     
849     ! Data structure for storing reaction data.
850           TYPE(REACTION_BLOCK), POINTER, INTENT(INOUT) :: lRxN
851     
852     
853     ! Local Variables:
854     !---------------------------------------------------------------------//
855     ! Loop counters.
856           INTEGER L, M, N
857     ! A flag generated to point out the location of the entry error.
858           CHARACTER(LEN=512) FLAG
859     ! Location in string to locate error.
860           INTEGER lPOS, rPOS
861     
862     ! Initialize the error flag.
863           FLAG = ''
864     
865     ! Loop over the number of (reactants/products)
866           ALOOP : DO L=1, lNo
867     ! Compare entry with gas phase species.
868              DO N = 1, lNg
869                 IF( checkMatch(lSAg(N), lAlias(L))) THEN
870                    lRxN%Species(lStart + L)%pMap = 0
871                    lRxN%Species(lStart + L)%sMap = N
872                    lRxN%Species(lStart + L)%Coeff = lSgn * lCoeff(L)
873                    CYCLE ALOOP
874                 ENDIF
875              ENDDO
876     ! Compare entry with solids phase species.
877              DO M = 1, lM
878                 DO N = 1, lNs(M)
879                    IF(checkMatch(lSAs(M,N),lAlias(L))) THEN
880                       lRxN%Species(lStart + L)%pMap = M
881                       lRxN%Species(lStart + L)%sMap = N
882                       lRxN%Species(lStart + L)%Coeff = lSgn * lCoeff(L)
883                       CYCLE ALOOP
884                    ENDIF
885                 ENDDO
886              ENDDO
887     ! No matching species was located. Flag an error and exit.
888              IF(myPE == PE_IO) THEN
889     ! Construct the error flag.
890                 lPOS = INDEX(lChemEq,trim(lAlias(L)), BACK=.FALSE.)
891                 rPOS = INDEX(lChemEq,trim(lAlias(L)), BACK=.TRUE.)
892                 FLAG = setFlag(20, 1 + int((lPOS + rPOS)/2))
893     ! Write the message to the screen.
894                 write(*,1000) trim(lAlias(L)), trim(lName)
895                 write(*,1010) trim(lChemEq), trim(Flag)
896                 IF(lBA(0)) CALL writeBA()
897                 write(*,1001)
898     ! Write message to log file.
899                 write(UNIT_LOG,1000) trim(lAlias(L)), trim(lName)
900                 write(UNIT_LOG,1010) trim(lChemEq), trim(Flag)
901                 IF(lBA(0)) CALL writeBA(UNIT_LOG)
902                 write(UNIT_LOG,1001)
903              ENDIF
904     ! Exit MFIX
905              CALL MFIX_EXIT(myPE)
906     
907           ENDDO ALOOP
908     
909           RETURN
910     
911      1000 FORMAT(/1X,70('*')/' From: From: setReaction --> mapAliases',/   &
912              ' Message: Unable to match species ',A,' in the chemical',    &
913              ' equation for ',/' reaction ',A,'.')
914     
915      1001 FORMAT(/' Please refer to the Readme file for chemical equation',&
916              ' input formats',/' and correct the data file.',/1X,70('*')/)
917     
918      1010 FORMAT(/' Chemical Equation: ',A,/1X, A/)
919     
920      1011 FORMAT(/' Chemical Equation: ',A,/)
921     
922     
923           contains
924     
925     !......................................................................!
926     !  Function name: checkMatch                                           !
927     !                                                                      !
928     !  Purpose: Takes two species aliases as arguments, converts them to   !
929     !  uppercase and checks if they match.                                 !
930     !                                                                      !
931     !  Variables referenced: None                                          !
932     !                                                                      !
933     !......................................................................!
934           LOGICAL FUNCTION checkMatch(lSA, ceSA)
935     
936           IMPLICIT NONE
937     
938     ! Pass Arguments:
939     !---------------------------------------------------------------------//
940           CHARACTER(LEN=32), INTENT(IN) :: lSA, ceSA
941     
942     ! Local Variables:
943     !---------------------------------------------------------------------//
944           CHARACTER(LEN=32) tlSA
945     
946     ! Copy species alias.
947           tlSA = lSA
948     ! Remove case sensitivity.
949           CALL MAKE_UPPER_CASE (tlSA,32)
950     ! Compare the two strings.
951           checkMatch = .FALSE.
952           IF(trim(tlSA) == trim(ceSA)) checkMatch = .TRUE.
953           RETURN
954           END FUNCTION checkMatch
955     
956     !......................................................................!
957     !  Function name: updateMap                                            !
958     !                                                                      !
959     !  Purpose: Flags that the passed phase is part of the chemical        !
960     !  reaction. If the phase was not already noted, the number of phases  !
961     !  in the reaction is increased and the flag set true. Additionally,   !
962     !  The number of species (either product or reactant) for the phase    !
963     !  is incremented.                                                     !
964     !                                                                      !
965     !  Variables referenced: None                                          !
966     !                                                                      !
967     !......................................................................!
968           SUBROUTINE updateMap(lnP, lpMap, llNoP)
969     
970           IMPLICIT NONE
971     
972     ! Pass Arguments:
973     !---------------------------------------------------------------------//
974           INTEGER, INTENT(INOUT) :: lnP
975     ! Map of phases for the reaction.
976           LOGICAL, INTENT(INOUT) :: lpMap
977           INTEGER, INTENT(INOUT) :: llNoP
978     
979     ! Local Variables:
980     !---------------------------------------------------------------------//
981     ! None
982     
983     ! Increment the number of reactants/products this phase has involved in
984     ! the current reaction.
985           llNoP = llNoP + 1
986     ! If the phase was already identified, return.
987           IF(lpMap) RETURN
988     ! If this is the first time the phase is identififed, set the flag to
989     ! true and increment the total number of phases in the reaction.
990           lnP = lnP + 1
991           lpMap = .TRUE.
992     
993           RETURN
994           END SUBROUTINE updateMap
995     
996     
997     !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!
998     !  Function name: writeBA()                                            !
999     !                                                                      !
1000     !  Purpose: Print out which species were not given aliases.            !
1001     !                                                                      !
1002     !  Variables referenced: None                                          !
1003     !                                                                      !
1004     !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!
1005           SUBROUTINE writeBA(FUNIT)
1006     
1007           IMPLICIT NONE
1008     
1009     ! File unit
1010           INTEGER, OPTIONAL, INTENT(IN) :: FUNIT
1011     
1012           INTEGER M, N
1013     
1014     ! Loop counter for continuum and discrete species
1015           INTEGER Nsp
1016     
1017           IF(.NOT.PRESENT(FUNIT)) THEN
1018              write(*,1000)
1019           ELSE
1020              write(FUNIT,1000)
1021           ENDIF
1022     
1023     ! Initialize counters
1024           Nsp = 0
1025     
1026           DO N = 1, lNg
1027              Nsp = Nsp + 1
1028              IF(lBA(Nsp)) THEN
1029                 IF(.NOT.PRESENT(FUNIT)) THEN
1030                    write(*,1001)N
1031                 ELSE
1032                    write(FUNIT,1001) N
1033                 ENDIF
1034              ENDIF
1035           ENDDO
1036     
1037     ! Compare aliaes between solids phases
1038           DO M = 1, lM
1039              DO N = 1, lNs(M)
1040                 Nsp = Nsp + 1
1041     
1042                 IF(lBA(Nsp)) THEN
1043                    IF(.NOT.PRESENT(FUNIT)) THEN
1044                       write(*,1002)M, N
1045                    ELSE
1046                       write(FUNIT,1002)M, N
1047                    ENDIF
1048                 ENDIF
1049              ENDDO
1050           ENDDO
1051     
1052           RETURN
1053     
1054      1000 FORMAT(' Species aliases were not provided for the following:')
1055      1001 FORMAT(3X, ' Gas phase species ',I2)
1056      1002 FORMAT(3X, ' Solid phase ',I2,' specie ',I2)
1057     
1058           END SUBROUTINE writeBA
1059     
1060           END SUBROUTINE mapAliases
1061     
1062     
1063     !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!
1064     !  Function name: setFlag                                              !
1065     !                                                                      !
1066     !  Purpose: Creates a flag pointing to a particular string location.   !
1067     !                                                                      !
1068     !  Variables referenced: None                                          !
1069     !                                                                      !
1070     !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!
1071           CHARACTER(len=512) FUNCTION setFlag(fill, flg1, flg2) RESULT(OUT)
1072     
1073           IMPLICIT NONE
1074     
1075     ! Pass Arguments:
1076     !---------------------------------------------------------------------//
1077     ! Number of leading spaces to fill with dashes. This is used to jump
1078     ! past any lead-in text.
1079           INTEGER, INTENT(IN) :: fill
1080     ! Location in string to place the pointer.
1081           INTEGER, INTENT(IN) :: flg1
1082     ! Optional - location of second pointer in string
1083           INTEGER, INTENT(IN), OPTIONAL :: flg2
1084     
1085     ! Local Variables:
1086     !---------------------------------------------------------------------//
1087           INTEGER L, FILL1, FILL2
1088     
1089     ! Create a string with "FILL" dash characters.
1090           OUT = ''
1091           DO L = 1, FILL-1
1092              WRITE(OUT,"(A,A)") trim(OUT), '-'
1093           ENDDO
1094     
1095     ! If a second pointer is present, determined the larger of the two.
1096           IF(PRESENT(flg2)) THEN
1097              IF(flg1 < flg2) THEN
1098                 FILL1 = flg1 - 1
1099                 FILL2 = (flg2-flg1) - 1
1100              ELSE
1101                 FILL1 = flg2 - 1
1102                 FILL2 = (flg1-flg2) - 1
1103              ENDIF
1104           ELSE
1105              FILL1 = flg1 - 1
1106              FILL2 = 0
1107           ENDIF
1108     
1109     ! Fill with dashes up to the the first pointer. ----^
1110           DO L = 1, FILL1
1111              WRITE(OUT,"(A,A)") trim(OUT), '-'
1112           ENDDO
1113           WRITE(OUT,"(A,A)") trim(OUT), '^'
1114     ! Fill with dashes up to the second pointer. ----^---^
1115           IF(FILL2 > 0) THEN
1116              DO L = 1, FILL2
1117                 WRITE(OUT,"(A,A)") trim(OUT), '-'
1118              ENDDO
1119              WRITE(OUT,"(A,A)") trim(OUT), '^'
1120           ENDIF
1121     
1122           END FUNCTION setFlag
1123     
1124           END MODULE parse
1125