MFIX  2016-1
parse_rxn.f
Go to the documentation of this file.
1 !vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvC
2 ! C
3 ! Module name: PARSE_RXN(LINE, LMAX) C
4 ! Purpose: Parse input line C
5 ! C
6 ! Author: P. Nicoletti Date: 30-JUN-97 C
7 ! C
8 ! Revision Number: 1 C
9 ! Purpose: This routine was complete rewritten as part of the effort C
10 ! to simplify reaction inputs in MFiX.
11 ! Author: J. Musser Date: 01-Oct-12 C
12 ! Reviewer: Date: dd-mmm-yy C
13 ! C
14 ! Literature/Document References: C
15 ! C
16 ! Variables referenced: C
17 ! Variables modified: C
18 ! C
19 ! Local variables: C
20 ! C
21 !^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^C
22  SUBROUTINE parse_rxn(LINE, lNoOfRxns, lName, lChemEq, lDH, lFDH)
23 
24 !-----------------------------------------------
25 ! M o d u l e s
26 !-----------------------------------------------
27  USE compar
28  USE funits
29  USE param
30  USE param1
31  USE parse
32 
33  IMPLICIT NONE
34 
35 ! Input line from mfix.dat.
36  CHARACTER(len=*), INTENT(IN) :: LINE
37 ! Array of reaction names.
38  INTEGER, INTENT(INOUT) :: lNoOfRxns
39 ! Array of reaction names.
40  CHARACTER(len=*), INTENT(INOUT), DIMENSION(DIMENSION_RXN) :: lName
41 ! Array of Chemical reaction equations.
42  CHARACTER(len=*), INTENT(INOUT), DIMENSION(DIMENSION_RXN) :: lChemEq
43 ! Array of User defined heat of reactions.
44  DOUBLE PRECISION, INTENT(INOUT), DIMENSION(DIMENSION_RXN) :: lDH
45 ! Array of User defined heat of reaction phase partitions.
46  DOUBLE PRECISION, INTENT(INOUT), DIMENSION(DIMENSION_RXN, 0:DIM_M) :: lFDH
47 
48 
49 !-----------------------------------------------
50 ! L o c a l P a r a m e t e r s
51 !-----------------------------------------------
52 !-----------------------------------------------
53 ! L o c a l V a r i a b l e s
54 !-----------------------------------------------
55 
56  CHARACTER, PARAMETER :: CT_BEG = '{'
57  CHARACTER, PARAMETER :: CT_END = '}'
58 
59 ! Positions of braces {...}
60  INTEGER bIDX, eIDX
61 ! Reaction Name
62  CHARACTER(LEN=128) :: INPUT
63 ! Index of reaction.
64  INTEGER IDX
65 
66 ! Copy line to input for processing.
67  input = trim(adjustl(line))
68 
69 ! Look for the start and end of a reaction construct by checking for
70 ! left and right braces.
71  bidx = index(input,ct_beg)
72  eidx = index(input,ct_end)
73 
74 ! If not already inside/reading from a reaction construct, check to see
75 ! if this is the start of a construct.
76  IF(.NOT.in_construct) THEN
77 
78 ! An identifier for the end of a construct was found.
79  IF(eidx .GT. 0) THEN
80  IF(eidx .GT. bidx) THEN
81 ! The reaction construct is specified in a single line.
82 ! rxn_name { A + B --> AB }
83  idx = getreactionindex(lnoofrxns, 'NEW')
84 ! Pull off the reaction construct name.
85  CALL getname(input,(bidx-1), lname(idx))
86 ! Process the rest of the line.
87  IF(isfracdh(input(bidx+1:eidx-1)))THEN
88  WRITE(*, 1002) 'FracDH', trim(adjustl(input))
89  WRITE(*, 1000)
90  CALL mfix_exit(mype)
91  ELSEIF(isdh(input(bidx+1:eidx-1)))THEN
92  WRITE (*, 1002) 'DH', trim(adjustl(input))
93  WRITE(*, 1000)
94  CALL mfix_exit(mype)
95  ELSEIF(.NOT.ischemeq(input(bidx+1:eidx-1)))THEN
96  WRITE (*, 1003) trim(adjustl(input))
97  WRITE(*, 1000)
98  CALL mfix_exit(mype)
99  ENDIF
100  CALL getchemeq(input(bidx+1:eidx-1), lchemeq(idx))
101  ELSE
102 ! The format given in the deck file is incorrect. Brace mismatch.
103  WRITE(*, 1001) trim(adjustl(line))
104  WRITE(*, 1000)
105  CALL mfix_exit(mype)
106  ENDIF
107  ELSE
108 ! This is the start of a reaction construct.
109  IF(bidx .GT. 0) THEN
110 ! Get the reaction index.
111  idx = getreactionindex(lnoofrxns, 'NEW')
112 ! Extract the reaction name.
113  CALL getname(input,(bidx-1), lname(idx))
114 ! Process any data.
115  IF(len_trim(adjustl(input(bidx+1:eidx-1))) .GT. 0) &
116  CALL readconstruct(input(bidx+1:eidx-1), &
117  lchemeq(idx), ldh(idx), lfdh(idx,:))
118  in_construct = .true.
119  ELSE
120 ! Format Error.
121  WRITE(*, 1004) trim(adjustl(input))
122  WRITE(*, 1000)
123  CALL mfix_exit(mype)
124  ENDIF
125  ENDIF
126  ELSE
127 
128  IF(bidx .GT. 0) THEN
129 ! Format Error.
130  WRITE(*, 1005) trim(adjustl(input))
131  WRITE(*, 1000)
132  CALL mfix_exit(mype)
133 ! This is the last line of the reaction construct which may or may not
134 ! contain additional data.
135  ELSEIF(eidx .GT. 0) THEN
136  idx = getreactionindex(lnoofrxns)
137  CALL readconstruct(input(bidx+1:eidx-1), lchemeq(idx), &
138  ldh(idx), lfdh(idx,:))
139  in_construct = .false.
140 
141 ! Reading from somewhere inside of a reaction construct.
142  ELSE
143  idx = getreactionindex(lnoofrxns)
144  CALL readconstruct(input(bidx+1:), lchemeq(idx), &
145  ldh(idx), lfdh(idx,:))
146  ENDIF
147  ENDIF
148 
149  RETURN
150 
151  1001 FORMAT(//1x,70('*')/' From: PARSE_RXN',/ &
152  ' Error 1001: Mismatch of braces "{...}" in reaction ', &
153  ' construct.',//' INPUT: ',a)
154 
155  1002 FORMAT(//1x,70('*')/' From: PARSE_RXN',/ &
156  ' Error 1002: Input format error in reaction construct.', &
157  ' Opening and',/' closing braces were found on the same line',&
158  ' along with the',/' keyword ',a,'.',/' Single line', &
159  ' constructs can only contain a chemical equation.',// &
160  ' INPUT: ',a,// &
161  ' Example 1: RXN_NAME { chem_eq = "A + B --> AB" }',// &
162  ' Example 2: RXN_NAME {',/14x,'chem_eq = "A + B --> AB"',/14x,&
163  'DH = 2.5d4',/14x,'fracDH(0) = 1.0',/12x,'}')
164 
165  1003 FORMAT(//1x,70('*')/' From: PARSE_RXN',/ &
166  ' Error 1003: Input format error in reaction construct.', &
167  ' Opening and',/' closing braces were found on the same line',&
168  ' and chem_eq was NOT found.',/' Single line constructs can', &
169  ' only contain a chemical equation.',//' INPUT: ',a,// &
170  ' Example 1: RXN_NAME { chem_eq = "A + B --> AB" }',// &
171  ' Example 2: RXN_NAME {',/14x,'chem_eq = "A + B --> AB"',/14x,&
172  'DH = 2.5d4',/14x,'fracDH(0) = 1.0',/12x,'}')
173 
174  1004 FORMAT(//1x,70('*')/' From: PARSE_RXN',/ &
175  ' Error 1004: Data within the reaction block was identified', &
176  ' outside of a',/' reaction construct. ',//' INPUT: ',a)
177 
178  1005 FORMAT(//1x,70('*')/' From: PARSE_RXN',/ &
179  ' Error 1005: The start of a new reaction construct was', &
180  ' found before the',/' closing of the previous construct.',// &
181  ' INPUT: ',a)
182 
183  1000 FORMAT(/' Please refer to the Readme file on the required input',&
184  ' format and make',/' the necessary corrections to the data', &
185  ' file.',/1x,70('*')//)
186 
187  CONTAINS
188 
189 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!
190 ! Function name: getReactionIndex() !
191 ! !
192 ! Purpose: Extract the reaction name from a construct. !
193 ! !
194 ! Variables referenced: None !
195 ! !
196 ! Variables modified: None !
197 ! !
198 ! Local variables: None !
199 ! !
200 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!
201  INTEGER FUNCTION getreactionindex(lNOR, STAT)
203  use rxns
204 
205  IMPLICIT NONE
206 ! Number of reactions.
207  INTEGER, INTENT(INOUT) :: lNOR
208 ! Status
209  CHARACTER(len=*), INTENT(IN), OPTIONAL :: STAT
210 
211  IF(.NOT.PRESENT(stat)) THEN
212  getreactionindex = lnor
213 
214  ELSE
215  IF(stat == 'NEW') THEN
216 ! Increment the number of reactions processed from the data file and
217 ! return the new value as the index of the reactoin being processed.
218  lnor = lnor + 1
219  getreactionindex = lnor
220  ELSE
221  WRITE(*,*) ' Unknown status'
222  CALL mfix_exit(mype)
223  ENDIF
224  ENDIF
225 
226  RETURN
227  END FUNCTION getreactionindex
228 
229 
230 
231 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!
232 ! Function name: readConstruct(IN, ChemEq, uDH, uFDH) !
233 ! !
234 ! Purpose: !
235 ! !
236 ! Variables referenced: None !
237 ! !
238 ! Variables modified: None !
239 ! !
240 ! Local variables: None !
241 ! !
242 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!
243  SUBROUTINE readconstruct(IN, ChemEq, uDH, uFDH)
245  IMPLICIT NONE
246 
247 ! Input string being parsed.
248  CHARACTER(len=*), INTENT(IN) :: IN
249 ! Chemical equation.
250  CHARACTER(len=*), INTENT(OUT) :: ChemEq
251 ! User defined heat of reaction.
252  DOUBLE PRECISION, INTENT(OUT) :: uDH
253 ! User defined splitting of heat of reaction
254  DOUBLE PRECISION, INTENT(OUT) :: uFDH(0:dim_m)
255 
256 ! The input line contains no additional data.
257  IF(len_trim(adjustl(in)) == 0) RETURN
258 
259 ! The input contains chemical equation data.
260  IF(more_chemeq .OR. ischemeq(in)) THEN
261  CALL getchemeq(in, chemeq)
262 ! The input contains heat of reaction parsing data.
263  ELSEIF(isfracdh(in)) THEN
264  CALL getfracdh(in, ufdh(:))
265 ! The input contains heat of reaction data.
266  ELSEIF(isdh(in)) THEN
267  CALL getdh(in, udh)
268 ! The entry doesn't match any of the keywords.
269  ELSE
270 ! Unidentified keyword.
271  WRITE(*, 1001) trim(adjustl(in))
272  WRITE(*, 1000)
273  CALL mfix_exit(mype)
274  ENDIF
275 
276  RETURN
277 
278  1001 FORMAT(//1x,70('*')/' From: PARSE_RXN --> readConstruct',/ &
279  ' Error 1001: Unidentified keyword in reaction construct.'//, &
280  ' INPUT: ',a)
281 
282  1000 FORMAT(/' Please refer to the Readme file on the required input',&
283  ' format and make',/' the necessary corrections to the data', &
284  ' file.',/1x,70('*')//)
285 
286  END SUBROUTINE readconstruct
287 
288 
289 
290 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!
291 ! Function name: isChemEq(INPUT) !
292 ! !
293 ! Purpose: Checks if the line contains the chemical Eq. !
294 ! !
295 ! Variables referenced: None !
296 ! !
297 ! Variables modified: None !
298 ! !
299 ! Local variables: None !
300 ! !
301 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!
302  LOGICAL FUNCTION ischemeq(INPUT)
304 ! Input line.
305  CHARACTER(len=*), INTENT(IN) :: INPUT
306 
307 ! Check to see if the line contains 'END'
308  IF (index(line(1:),"CHEM_EQ") == 0) THEN
309 ! 'CHEM_EQ' was not found. This line does not contains a chemical eq.
310  ischemeq = .false.
311  ELSE
312 ! 'CHEM_EQ' was found. This line contains all or part of a chemical eq.
313  ischemeq = .true.
314  ENDIF
315 
316  END FUNCTION ischemeq
317 
318 
319 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!
320 ! Function name: isDH(INPUT) !
321 ! !
322 ! Purpose: Checks if the line contains user defined heat of reaction. !
323 ! !
324 ! Variables referenced: None !
325 ! !
326 ! Variables modified: None !
327 ! !
328 ! Local variables: None !
329 ! !
330 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!
331  LOGICAL FUNCTION isdh(INPUT)
333 ! Input line.
334  CHARACTER(len=*), INTENT(IN) :: INPUT
335 
336 ! Check to see if the line contains 'END'
337  IF (index(line(1:),"DH") == 0) THEN
338 ! 'DH' was not found. This line does not contains a heat of reaction.
339  isdh = .false.
340  ELSE
341 ! 'DH' was found. This line contains the heat of reaction
342  isdh = .true.
343  ENDIF
344 
345  END FUNCTION isdh
346 
347 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!
348 ! Function name: isDH(INPUT) !
349 ! !
350 ! Purpose: Checks if the line contains user defined heat of reaction. !
351 ! !
352 ! Variables referenced: None !
353 ! !
354 ! Variables modified: None !
355 ! !
356 ! Local variables: None !
357 ! !
358 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!
359  LOGICAL FUNCTION isfracdh(INPUT)
361 ! Input line.
362  CHARACTER(len=*), INTENT(IN) :: INPUT
363 
364 ! Check to see if the line contains 'END'
365  IF (index(line(1:),"FRACDH") == 0) THEN
366 ! 'FRACDH' was not found.
367  isfracdh = .false.
368  ELSE
369 ! 'FRACDH' was found.
370  isfracdh = .true.
371  ENDIF
372 
373  END FUNCTION isfracdh
374 
375 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!
376 ! Subroutine name: get_ChemEq(INPUT, lNAME, IER) !
377 ! !
378 ! Purpose: Extract the reaction name from a construct. !
379 ! !
380 ! Variables referenced: None !
381 ! !
382 ! Variables modified: None !
383 ! !
384 ! Local variables: None !
385 ! !
386 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!
387  SUBROUTINE getname(INPUT, rPOS, lNAME)
389 ! Input line.
390  CHARACTER(len=*), INTENT(IN) :: INPUT
391 ! End of search location for reaction name.
392  INTEGER, INTENT(IN) :: rPOS
393 ! Name of reaction pulled from input.
394  CHARACTER(LEN=32) , INTENT(OUT) :: lNAME
395 
396  INTEGER NAME_LEN
397 
398 ! Initialize the return value.
399  lname = ''
400 ! Verify that the name is not too long. This should be caught by
401 ! preprocessing of the data file. However, if the user changed the
402 ! reaction name after compiling (an error check for later) this check
403 ! prevents and overflow error.
404  name_len = len_trim(adjustl(input(1:rpos)))
405  IF(name_len .GT. 32) THEN
406  WRITE(*, 1001) trim(adjustl(input))
407  WRITE(*, 1000)
408  CALL mfix_exit(mype)
409 ! Verify that the name was not deleted after compiling.
410 ! prevents and overflow error.
411  ELSEIF(name_len .EQ. 0) THEN
412  WRITE(*, 1002) trim(adjustl(input))
413  WRITE(*, 1000)
414  CALL mfix_exit(mype)
415  ELSE
416  lname = trim(adjustl(input(1:rpos)))
417  ENDIF
418 
419 ! There shouldn't be any crazy characters at this point because the
420 ! code should fail to compile if the reaction names are not defined
421 ! or contain invalid characters.
422 
423  1001 FORMAT(//1x,70('*')/' From: PARSE_RXN --> get_ChemEq',/ &
424  ' Error 1001: Reaction name too long! Reaaction names are', &
425  ' limited to 32',/' characters.',//' Reaction Name: ',a)
426 
427  1002 FORMAT(//1x,70('*')/' From: PARSE_RXN --> get_ChemEq',/ &
428  ' Error 1002: Unable to determine reaction name.',// &
429  ' INPUT: ',a)
430 
431  1000 FORMAT(/' Please refer to the Readme file on the required input',&
432  ' format and make',/' the necessary corrections to the data', &
433  ' file.',/1x,70('*')//)
434 
435  RETURN
436  END SUBROUTINE getname
437 
438 
439 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!
440 ! Subroutine name: getDH(INPUT, lDH) !
441 ! !
442 ! Purpose: Extract the reaction name from a construct. !
443 ! !
444 ! Variables referenced: None !
445 ! !
446 ! Variables modified: None !
447 ! !
448 ! Local variables: None !
449 ! !
450 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!
451  SUBROUTINE getdh(INPUT, lDH)
453 ! Input line.
454  CHARACTER(len=*), INTENT(IN) :: INPUT
455 ! Name of reaction pulled from input.
456  DOUBLE PRECISION, INTENT(OUT) :: lDH
457 
458  INTEGER lQ
459  INTEGER lLMAX
460 ! read/write output status
461  INTEGER IOS
462 
463  llmax = len_trim(input)
464 
465  IF(index(input,"DH") .EQ. 0) THEN
466  WRITE (*, 1100) trim(adjustl(input))
467  WRITE(*, 1000)
468  CALL mfix_exit(mype)
469  ENDIF
470 
471  lq = index(input(:llmax),'=')
472 
473  IF(lq .EQ. 0) THEN
474  WRITE (*, 1001) trim(adjustl(input))
475  WRITE(*, 1000)
476  CALL mfix_exit(mype)
477  ENDIF
478 
479 ! Convert the entrying into an double precision value.
480  READ(input(lq+1:),*,iostat=ios) ldh
481  IF(ios .NE. 0) THEN
482  WRITE(*, 1002) trim(adjustl(input))
483  WRITE(*, 1000)
484  CALL mfix_exit(mype)
485  ENDIF
486 
487 
488  1001 FORMAT(//1x,70('*')/' From: PARSE_RXN --> getDH',/ &
489  ' Error 1001: Input format error for DH.',//' INPUT: ',a)
490 
491  1002 FORMAT(//1x,70('*')/' From: PARSE_RXN --> getDH',/ &
492  ' Error 1002: Unable to determine DH value from input.',/ &
493  ' Cannot convert specified value to double precision value.',/&
494  /' INPUT: ',a)
495 
496  1000 FORMAT(/' Please refer to the Readme file on the required input',&
497  ' format and make',/' the necessary corrections to the data', &
498  ' file.',/1x,70('*')//)
499 
500  1100 FORMAT(//1x,70('*')/' From: PARSE_RXN',/ &
501  ' Error 1105: DH was initially located within the input line',&
502  /' however its location cannot be determined.',&
503  ' INPUT: ',a)
504 
505  RETURN
506  END SUBROUTINE getdh
507 
508 
509 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!
510 ! Subroutine name: getfracDH(INPUT, lChemEq) !
511 ! !
512 ! Purpose: Extract the reaction name from a construct. !
513 ! !
514 ! Variables referenced: None !
515 ! !
516 ! Variables modified: None !
517 ! !
518 ! Local variables: None !
519 ! !
520 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!
521  SUBROUTINE getfracdh(INPUT, lFracDH)
523  USE param
524  USE param1
525 
526  IMPLICIT NONE
527 
528 ! Input line.
529  CHARACTER(len=*), INTENT(IN) :: INPUT
530 ! Name of reaction pulled from input.
531  DOUBLE PRECISION, INTENT(OUT) :: lFracDH(0:dim_m)
532 
533 
534  INTEGER POS, lP, rP, lQ
535  INTEGER lLMAX
536 ! read/write output status
537  INTEGER IOS
538 ! Phase Index
539  INTEGER pIDX
540 
541  llmax = len_trim(input)
542  pos = index(input,"FRACDH")
543 
544  IF(pos == 0) THEN
545  WRITE (*, 1100) trim(adjustl(input))
546  WRITE(*, 1100)
547  CALL mfix_exit(mype)
548  ENDIF
549 
550  lp = index(input(:llmax),'(')
551  rp = index(input(:llmax),')')
552  lq = index(input(:llmax),'=')
553 
554  IF(lp .EQ. rp .AND. lp .EQ. zero) THEN
555  WRITE(*, 1001) trim(adjustl(input))
556  WRITE(*, 1000)
557  CALL mfix_exit(mype)
558  ELSEIF(lp .GE. rp) THEN
559  WRITE(*, 1002) trim(adjustl(input))
560  WRITE(*, 1000)
561  CALL mfix_exit(mype)
562  ELSEIF(rp .GE. lq) THEN
563  WRITE(*, 1002) trim(adjustl(input))
564  WRITE(*, 1000)
565  CALL mfix_exit(mype)
566  ENDIF
567 ! Convert the entrying into an integer value.
568  READ(input(lp+1:rp-1),*,iostat=ios) pidx
569  IF(ios .NE. 0) THEN
570  WRITE(*, 1003) trim(adjustl(input))
571  WRITE(*, 1000)
572  CALL mfix_exit(mype)
573  ELSEIF(pidx .LT. 0 .OR. pidx .GT. dim_m)THEN
574  WRITE(*, 1004) trim(adjustl(input))
575  WRITE(*, 1000)
576  CALL mfix_exit(mype)
577  ENDIF
578 
579 ! Convert the entrying into an double precision value.
580  READ(input(lq+1:),*,iostat=ios) lfracdh(pidx)
581  IF(ios .NE. 0) THEN
582  WRITE(*, 1005)trim(adjustl(input))
583  WRITE(*, 1000)
584  CALL mfix_exit(mype)
585  ENDIF
586 
587  RETURN
588 
589  1001 FORMAT(//1x,70('*')/' From: PARSE_RXN --> getFracDH',/ &
590  ' Error 1001: Unable to determine phase association for', &
591  ' fracDH. When',/' specifying heat of reaction (DH), the', &
592  ' fraction of DH assigned to',/' each phase must be', &
593  ' given explicitly.',//' Example: fracDH(0) = 0.25 ! 25% of',&
594  ' DH is assigned to gas phase',/' fracDH(1) = 0.75 ',&
595  ' ! 75% of DH is assigned to solids phase 1',//' Note:', &
596  ' fracDH(0) + fracDH(1) + ... + frachDH(M) == 1.0',// &
597  ' INPUT: ',a)
598 
599  1002 FORMAT(//1x,70('*')/' From: PARSE_RXN --> getFracDH',/ &
600  ' Error 1002: Input format error for fracDH.',// &
601  ' INPUT: ',a)
602 
603  1003 FORMAT(//1x,70('*')/' From: PARSE_RXN --> getFracDH',/ &
604  ' Error 1003: Unable to determine phase index for fracDH.',//&
605  ' INPUT: ',a)
606 
607  1004 FORMAT(//1x,70('*')/' From: PARSE_RXN --> getFracDH',/ &
608  ' Error 1004: Phase index for fracDH exceeds DIM_M!',// &
609  ' INPUT: ',a)
610 
611  1005 FORMAT(//1x,70('*')/' From: PARSE_RXN --> getFracDH',/ &
612  ' Error 1005: Unable to determine fracDH value from input.',/ &
613  ' Cannot convert specified value to double precision value.',/&
614  /' INPUT: ',a)
615 
616 
617  1000 FORMAT(/' Please refer to the Readme file on the required input',&
618  ' format and make',/' the necessary corrections to the data', &
619  ' file.',/1x,70('*')//)
620 
621  1100 FORMAT(//1x,70('*')/' From: PARSE_RXN',/ &
622  ' Error 1105: fracDH was initially located within the', &
623  ' input line,',/' however its location cannot be determined.',&
624  ' INPUT: ',a)
625 
626 
627 
628  END SUBROUTINE getfracdh
629 
630 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!
631 ! Subroutine name: getChemEq(INPUT, lChemEq) !
632 ! !
633 ! Purpose: Extract the reaction name from a construct. !
634 ! !
635 ! Variables referenced: None !
636 ! !
637 ! Variables modified: None !
638 ! !
639 ! Local variables: None !
640 ! !
641 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!
642  SUBROUTINE getchemeq(IN, lChemEq)
644  IMPLICIT NONE
645 
646 ! Input line.
647  CHARACTER(len=*), INTENT(IN) :: IN
648 ! Name of reaction pulled from input.
649  CHARACTER(len=*), INTENT(OUT) :: lChemEq
650 
651 ! read/write output status
652  INTEGER IOS
653 
654  INTEGER POS, lPOS, rPOS, ldP, lsP, aPOS
655  INTEGER lLMAX
656 
657 ! Chemical equations start with the keyword: CHEM_EQ. If this is not a
658 ! continuation of the previous line, search for the keyword and
659 ! flag an error if not found.
660  IF(.NOT.more_chemeq) THEN
661  llmax = len_trim(in)
662  pos = index(in,"CHEM_EQ")
663 
664  IF(pos == 0) THEN
665  WRITE (*, 1105) 'Chem_Eq'
666  CALL mfix_exit(mype)
667  ENDIF
668 ! Initialize
669  lchemeq = ''
670 ! Update POS to skip over the keyword: CHEM_EQ
671  pos = pos+7
672  ELSE
673  pos = 1
674  ENDIF
675 
676 ! Search for quote marks bounding the chemical equation.
677  ldp = pos + index(in(pos:),'"') ! double quote "
678  lsp = pos + index(in(pos:),"'") ! single quote '
679 
680  IF(ldp .GT. pos .AND. lsp .EQ. pos) THEN
681 ! The chemical equation is bounded by double quotes
682  lpos = ldp
683 ! Search for the second quote mark.
684  rpos = lpos + index(in(lpos+1:),'"')
685  ELSEIF(ldp .EQ. pos .AND. lsp .GT. pos) THEN
686 ! The chemical equation is bounded by single quotes
687  lpos = lsp
688 ! Search for the second quote mark.
689  rpos = lpos + index(in(lpos+1:),"'")
690  ELSE
691 ! Different errors are thrown depending if this is a continuation
692 ! (MORE_ChemEq) or the start of a chemical equation.
693  IF(.NOT.more_chemeq) THEN
694  WRITE(*, 1001) trim(adjustl(in))
695  WRITE(*, 1000)
696  ELSE
697  IF(isfracdh(in)) THEN
698  WRITE(*, 1002) 'Keyword fracDH was found inside', &
699  ' the chemical equation!', trim(adjustl(in))
700  WRITE(*, 1000)
701  ELSEIF(isdh(in)) THEN
702  WRITE(*, 1002) 'Keyword DH was found inside', &
703  ' the chemical equation!', trim(adjustl(in))
704  WRITE(*, 1000)
705  ELSE
706  WRITE(*, 1002) 'Unbalanced or missing parentheses', '', &
707  trim(adjustl(in))
708  WRITE(*, 1000)
709  ENDIF
710  ENDIF
711  CALL mfix_exit(mype)
712  ENDIF
713 
714 ! Mismatch/Unbalanced parentheses
715  IF(lpos .EQ. rpos) THEN
716 ! Different errors are thrown depending if this is a continuation
717 ! (MORE_ChemEq) or the start of a chemical equation.
718  IF(.NOT.more_chemeq) THEN
719  WRITE(*, 1001) trim(adjustl(in))
720  WRITE(*, 1000)
721  ELSE
722  WRITE(*, 1002) 'Unbalanced or missing parentheses', '', &
723  trim(adjustl(in))
724  WRITE(*, 1000)
725  ENDIF
726  CALL mfix_exit(mype)
727  ENDIF
728 
729 ! Search for an ampersand.
730  apos = lpos + index(in(lpos+1:),'&')
731 ! An ampersand was found.
732  IF(apos .GT. lpos) THEN
733  more_chemeq = .true.
734 ! The ampersand should be further to the right than the last quote mark.
735  IF(apos .LE. rpos) THEN
736  WRITE(*, 1003) trim(adjustl(in))
737  WRITE(*, 1000)
738  CALL mfix_exit(mype)
739  ENDIF
740  ELSE
741  more_chemeq = .false.
742  ENDIF
743 
744 ! Store the chemical equation.
745  WRITE(lchemeq,"(A,1X,A)",iostat=ios) trim(lchemeq), &
746  trim(adjustl(in(lpos:rpos-1)))
747  IF(ios .NE. 0) THEN
748  WRITE(*, 1004) trim(lchemeq), trim(adjustl(in))
749  WRITE(*, 1000)
750  CALL mfix_exit(mype)
751  ENDIF
752 
753  RETURN
754 
755  1001 FORMAT(//1x,70('*')/' From: PARSE_RXN --> getChemEq',/ &
756  ' Error 1001: Unbalanced or missing parentheses for chem_eq.',&
757  //' INPUT: ',a,//' Example 1: RXN_NAME { chem_eq = ', &
758  '"A + B --> AB" }',//' Example 2: RXN_NAME {',/14x, &
759  'chem_eq = "A + B --> AB"',/14x, 'DH = 2.5d4',/14x, &
760  'fracDH(0) = 1.0',/12x,'}')
761 
762  1002 FORMAT(//1x,70('*')/' From: PARSE_RXN --> getChemEq',/ &
763  ' Error 1002: Chemical equation continuation input error.', &
764  //' > ',2a//' INPUT: ',a)
765 
766  1003 FORMAT(//1x,70('*')/' From: PARSE_RXN --> getChemEq',/ &
767  ' Error 1003: Input format error for chem_eq. An amperand', &
768  ' (&)',/' was located within the parentheses.',//' INPUT: ',a)
769 
770  1004 FORMAT(//1x,70('*')/' From: PARSE_RXN --> getChemEq',/ &
771  ' Error 1004: Unable to process chemical equation input.',/ &
772  ' A possible error is variable overflow as the total length', &
773  ' is limited',/' to 512 characters.',//' lChemEq: ',a,// &
774  ' INPUT: ',a)
775 
776  1000 FORMAT(/' Please refer to the Readme file on the required input',&
777  ' format and make',/' the necessary corrections to the data', &
778  ' file.',/1x,70('*')//)
779 
780  1105 FORMAT(//1x,70('*')/' From: PARSE_RXN --> getChemEq',/ &
781  ' Error 1105: chem_eq was initially located within the', &
782  ' input line,',/' however its location cannot be determined.',&
783  ' INPUT: ',a)
784 
785  END SUBROUTINE getchemeq
786 
787  END SUBROUTINE parse_rxn
logical function ischemeq(INPUT)
Definition: parse_rxn.f:303
logical more_chemeq
Definition: parse_mod.f:31
integer function getreactionindex(lNOR, STAT)
Definition: parse_rxn.f:202
Definition: rxns_mod.f:1
logical function isdh(INPUT)
Definition: parse_rxn.f:332
integer, parameter dim_m
Definition: param_mod.f:67
subroutine getdh(INPUT, lDH)
Definition: parse_rxn.f:452
logical in_construct
Definition: parse_mod.f:28
subroutine getname(INPUT, rPOS, lNAME)
Definition: parse_rxn.f:388
Definition: param_mod.f:2
Definition: parse_mod.f:1
subroutine getfracdh(INPUT, lFracDH)
Definition: parse_rxn.f:522
integer mype
Definition: compar_mod.f:24
subroutine readconstruct(IN, ChemEq, uDH, uFDH)
Definition: parse_rxn.f:244
logical function isfracdh(INPUT)
Definition: parse_rxn.f:360
subroutine parse_rxn(LINE, lNoOfRxns, lName, lChemEq, lDH, lFDH)
Definition: parse_rxn.f:23
subroutine getchemeq(IN, lChemEq)
Definition: parse_rxn.f:643
double precision, parameter zero
Definition: param1_mod.f:27