-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathCPLAP.f90
More file actions
2918 lines (2915 loc) · 104 KB
/
CPLAP.f90
File metadata and controls
2918 lines (2915 loc) · 104 KB
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
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
program cplap
!
!*********************************************************************
!
! This program reads in the chemical formula for a solid phase
! and its energy. It then asks for the limiting phases of the
! combinations of the elements and their energies. These are
! used to calculate the stability region in the space defined
! by the chemical potentials of the constituent elements of the
! solid.
!
! The calculation is done by solving the system of linear equations
! resulting from the inequalities defined by the limiting constituent
! compound energies and the total energy expression of the solid. The
! chemical potential of the anionic species can be set as a free
! parameter.
!
! e.g. :
!
! If the system is X Y2 Z with energy E ->
!
! we have mu_Z = E - mu_X - 2 mu_Y (*)
!
! with limiting phases X2 Z (energy E1)
! Y Z (energy E2)
!
! we must have 2 mu_X + mu_Z < E1 (**)
! and mu_Y + mu_Z < E2 (**)
!
! in order that the system be grown (otherwise phases X2 Z or Y Z will
! be formed)
!
! Also E < mu_X < 0 etc
!
! We can substitute in our expression (*) for mu_Z, then giving 3
! equations with 2 unknowns. All combinations of the equations are
! solved (if a solution exists for the combination) and a number of
! intersection points are found (or not if the system has no solution).
! Those intersection points that satisfy the limiting inequalities (**)
! are the results we want, giving the corner points of the polyhedron
! defining the stability region in chemical potential space. (In the
! example the polyhedron will be 2D).
!
! The limiting inequalities are returned, which can be used to
! generate a plot in mathematica/matlab if the space is 3D or less.
! The corner points of the polyhedron defining the stability
! region are also returned. The user can request a density of points
! (in units of energy), and a grid of points of that density in the
! stability region are returned.
!
! The process can be started from a file. If this is done the user
! is asked for a value of one of the chemical potentials (not the
! chemical potential that is a free parameter). The problem is then
! solved with this value of chemical potential, reducing the space
! by one dimension.
!
! J. Buckeridge October 2011
!
! HACK - 10/03/2016: Check if solutions found are compatible with the
! limiting inequalities has been moved to subroutine
! all_eqns_solve. Having it there avoids allocating very large
! arrays. A check has also been added a the program stops if too
! much memory is used (i.e. if array 'results' has more than
! nmax*nmax rows)
!
! BUGFIX - 29/10/2025: Problems identified with the restart (c) option,
! where, if the reduced system is binary, there was an error in
! some of the energies outputted. Fixed by subtracting the fixed
! chemical potential value from the total energy. Also, minor
! problem with the neqns has been fixed, so that the correct lim-
! iting inequalities are written. A test is required too to get
! the correct energies for the inequalities related to the pure
! elements.
!
!*********************************************************************
!
implicit none
!
integer, parameter :: nmax = 300
real*8, parameter :: small = 1.d-12
logical, parameter :: ltrue = .true.
logical, parameter :: lfalse = .false.
!
integer i, j, k, l, n, nspecies, nlimits, restart, num(nmax), nadd, nspecies_dep
integer limittotno(nmax), limitnum(nmax,nmax), ndepend, neqns, numtmp
integer numres, numsol, values(8), fixnum, str_num, comp_array(nmax), depnum
integer input, extra, memtest
integer nrel, func1, func2, rel_array(nmax), z_zero, cnt_z(nmax)
real*8 mu(nmax), energy, limite(nmax), eqns(nmax,nmax)
real*8 results(nmax*nmax,nmax), sum1, sum2, sum3, sum4
real*8 tmp1, tmp2
real*8 mumax(nmax), mumin(nmax), grid, gridpt(nmax), fixe
real*8 bintemp, Ebin_min, Ebin_max, enertemp
real*8 avgpos(nmax,3)
character*1 read_tmp
character*2 name(nmax), limitname(nmax,nmax), fixname, depname, tmp_str
character*3 str2, str3
character*4 str4
character*5 zone, ineq_name(nmax), strdep
character*8 date
character*9 ineq_str(nmax)
character*10 time
character*25 strtemp
character*60 string, char
character*100 str1, compounds(nmax)
character*100 line
character*200 eqn_str, formstr
character*1000 lngstr
logical check1, check2, check_eqns, check_low, check_ab, check_dep, check_lim
logical check_fix, check_read
!
open(unit=11, file="restart.dat", status="old", iostat=restart)
open(unit=12, file="results.dat", status="replace")
!
! Write banner
!
write(*,'(a)') "_____________________________________________________________"
write(*,'(a)') " "
write(*,'(a)') " CCCC PPPPP LL AAAA PPPPP !! "
write(*,'(a)') " CC CC PP PP LL AA AA PP PP !! "
write(*,'(a)') " CC PP PP LL AA AA PP PP !! "
write(*,'(a)') " CC PPPPP LL AAAAAA PPPPP !! "
write(*,'(a)') " CC CC PP LL AA AA PP "
write(*,'(a)') " CCCC PP LLLLLL AA AA PP !! "
write(*,'(a)') "_____________________________________________________________"
write(*,'(a)') " "
write(*,'(a)') " Chemical Potential Limits Analysis Program "
write(*,'(a)') "_____________________________________________________________"
write(*,'(a)') " "
write(*,'(a)') " Version 1.1 2013 "
write(*,'(a)') " John Buckeridge (j.buckeridge@ucl.ac.uk) "
write(*,'(a)') "_____________________________________________________________"
check_ab = lfalse
check_fix = lfalse
if(restart /= 0) then
write(*,*)
write(*,'(a)') "************************ New run ************************"
write(*,'(a)') "_____________________________________________________________"
write(*,*)
!
! Check for input file. If found read data from it
!
open(unit=13, status="old", file="input.dat", iostat=input)
if(input == 0) then
write(*,'(a)') "Reading input from input.dat..."
write(*,*)
!
! First read in the number of elements in the compound
!
write(*,'(a)') "Reading in number of species in system..."
do
read(13,'(a100)') line
if(line(1:1) /= "#") then
read(line,*) nspecies
exit
endif
enddo
if(nspecies < 2) then
write(*,'(a)') "SYNTAX ERROR reading in number of species (must be greater than one)"
write(*,'(a)') "ERROR IS FATAL"
goto 200
endif
write(*,'(a)') "...found ok"
write(*,*)
!
! Now read in formula of compound
!
write(*,'(a)') "Reading in formula of compound of interest..."
do
read(13,'(a100)') line
if(line(1:1) /= "#") then
read(line,*) (num(i),name(i),i=1,nspecies), energy
exit
endif
enddo
!
! Check energy is negative
!
if(energy > 0.d0) then
write(*,'(a)') "FATAL ERROR: ENERGY OF SYSTEM IS POSITIVE!!"
goto 200
endif
!
! Check that element numbers in formula aren't negative
!
do i=1,nspecies
if(num(i) < 1) then
write(*,'(a)') "FATAL ERROR: Incorrect syntax when entering numbers in chemical formula"
write(*,'(a,i3)') " Error occurred for element", i
goto 200
endif
enddo
write(*,'(a)') "...found ok"
write(*,*)
string = '(a7, (1x,i2,1x,a2))'
write(string(5:7),'(i3)') nspecies
write(*,string) "System:", (num(i),name(i),i=1,nspecies)
write(*,*)
!
! Read in which (if any) element is to be set as a dependent variable
!
write(*,'(a)') "Reading in dependent variable..."
do
read(13,'(a100)') line
if(line(1:1) /= "#") then
read(line,*) depname
exit
endif
enddo
!
! If none is set give a warning to the user
!
if(depname(1:1) == "n") then
write(*,'(a)') "WARNING: No depedent variable set. Solution may still be found -"
write(*,'(a)') " however only the intersection points with the compound"
write(*,'(a)') " are consistent with its formation. It is advisable to set"
write(*,'(a)') " a dependent variable."
write(*,*)
check_dep = lfalse
nspecies_dep = nspecies
else
!
! Check that the element is actually in the system
!
check_dep = ltrue
nspecies_dep = nspecies - 1
j = 0
do i=1,nspecies
if(depname == name(i)) then
j = j+1
depnum = i
endif
enddo
if(j == 0) then
write(*,'(a)') "FATAL ERROR: Dependent variable element not found in system!"
goto 200
endif
!
! Change order of species in system so that dependent variable element is last
! in the list (ie element nspecies)
!
tmp_str = name(nspecies)
name(nspecies) = depname
name(depnum) = tmp_str
numtmp = num(nspecies)
num(nspecies) = num(depnum)
num(depnum) = numtmp
write(*,'(a)') "...found ok"
write(*,*)
endif
!
! Read in limiting phases and their energies. First read in the total number
!
write(*,'(a)') "Reading in competing phases..."
do
read(13,'(a100)') line
if(line(1:1) /= "#") then
read(line,*) nlimits
exit
endif
enddo
!
! Check that the number is not less than zero
!
if(nlimits < 0) then
write(*,'(a)') "FATAL ERROR: Found negative number of competing phases!"
goto 200
endif
!
! Check if there are no limiting compounds. If there are, read them in sequentially.
! Check that the number in the input file matches the stated total amount. If not warn
! user and reset total amount
!
check_lim = ltrue
if(nlimits == 0) then
check_lim = lfalse
else
do i=1,nlimits
check_read = lfalse
do
read(13,'(a100)',end=5001) line
if(line(1:1) /= "#") then
read(line,*,end=5001) limittotno(i)
exit
endif
enddo
if(limittotno(i) > nspecies) then
write(*,'(a28,i3,a36)') "FATAL ERROR: Competing phase", i, "has more elements than the material!"
goto 200
endif
if(limittotno(i) < 1 ) then
write(*,'(a28,i3,a26)') "FATAL ERROR: Competing phase", i, "has less than one element!"
goto 200
endif
do
read(13,'(a100)',end=5001) line
if(line(1:1) /= "#") then
read(line,*,end=5001) (limitnum(i,j),limitname(i,j),j=1,limittotno(i)), limite(i)
exit
endif
enddo
check_read = ltrue
enddo
5001 if(check_read .neqv. ltrue) then
write(*,'(a)') "WARNING: Found less competing phases than supposed total amount"
write(*,'(a29,i3)') " Actual number found:", i-1
nlimits = i-1
endif
write(*,'(a)') "...found ok"
write(*,*)
!
! Check that elements in the compounds are compatible with those in the material
!
write(*,'(a)') "Checking competing phase formulae..."
do i=1,nlimits
l = 0
do j=1,limittotno(i)
do k=1,nspecies
if(limitname(i,j) == name(k)) l = l+1
enddo
enddo
if(l == 0) then
write(*,'(a)') "FATAL ERROR: Competing phase found with element not contained in &
&material!!"
write(*,'(a44,i3)') " Error found in competing phase:", i
goto 200
endif
enddo
!
! Check that element numbers in compounds aren't negative
!
do i=1,nlimits
do j=1,limittotno(i)
if(limitnum(i,j) < 1) then
write(*,'(a)') "FATAL ERROR: Incorrect syntax when entering numbers in chemical formula"
write(*,'(a44,i3)') " Error found in competing phase", i
goto 200
endif
enddo
enddo
write(*,'(a)') "...all ok"
write(*,*)
endif
!
! If no input.dat file found then interactive mode is activated
!
else
write(*,'(a)') "No input.dat file found - beginning interactive mode..."
write(*,*)
!
! Read in the number of species, chemical formula and energy
!
write(*,'(a)') "Enter number of elements in the material:"
70 read(*,*) nspecies
if(nspecies < 2) then
write(*,'(a)') "ERROR: System must consist of more than one element!!"
write(*,'(a)') "Please re-enter number of elements in the material:"
goto 70
endif
!
write(*,*)
write(*,'(a)') "Enter chemical formula of material and its energy in the form"
write(*,*)
write(*,'(a)') "n_a A n_b B n_c C ... energy"
write(*,*)
write(*,'(a)') "where n_a etc. are the integer numbers for species A etc."
write(*,'(a)') "(e.g. if the material is calcite then 1 Ca 1 C 3 O and then"
write(*,'(a)') "the energy must be entered. Please keep the energy units"
write(*,'(a)') "consistent when entering all data)"
read(*,*) (num(i),name(i),i=1,nspecies), energy
write(*,*)
!
! Check energy is negative
!
if(energy > 0.d0) then
write(*,'(a)') "FATAL ERROR: ENERGY OF SYSTEM IS POSITIVE!!"
goto 200
endif
!
! Check that element numbers in formula aren't negative
!
do i=1,nspecies
if(num(i) < 1) then
write(*,'(a)') "FATAL ERROR: Incorrect syntax when entering numbers in chemical formula"
write(*,'(a,i3)') " Error occurred for element", i
goto 200
endif
enddo
!
! Ask if an element is to be set as a dependent variable
!
write(*,'(a)') "Do you wish to set an element as a dependent variable (y/n)?"
5000 read(*,'(a3)') str2
if(str2(1:1) == "y" .or. str2(1:1) == "Y") then
check_dep = ltrue
nspecies_dep = nspecies - 1
write(*,*)
write(*,'(a)') "Enter element whose chemical potential will be the"
write(*,'(a)') "dependent variable:"
8000 read(*,*) depname
j = 0
do i=1,nspecies
if(depname == name(i)) then
j = j+1
depnum = i
endif
enddo
if(j == 0) then
write(*,'(a)') "ERROR: Element not found in system. Please enter another&
& element:"
goto 8000
endif
!
! Change order of species in system so that dependent variable element is last
! in the list (ie element nspecies)
!
tmp_str = name(nspecies)
name(nspecies) = depname
name(depnum) = tmp_str
numtmp = num(nspecies)
num(nspecies) = num(depnum)
num(depnum) = numtmp
elseif(str2(1:1) == "n" .or. str2(1:1) == "N") then
write(*,*)
write(*,'(a)') "WARNING: No depedent variable set. Solution may still be found -"
write(*,'(a)') " however only the intersection points with the compound"
write(*,'(a)') " are consistent with its formation. It is advisable to set"
write(*,'(a)') " a dependent variable."
write(*,*)
check_dep = lfalse
nspecies_dep = nspecies
else
write(*,'(a)') "SYNTAX ERROR: please enter yes or no:"
goto 5000
endif
!
! Echo to user which chemical potential will be the dependent variable
!
if(check_dep) then
write(*,'(a5,1x,a)') "mu_"//trim(name(nspecies_dep + 1)), "will be the dependent &
&variable"
write(*,*)
endif
!
! Read in limiting phases and their energies. Care will have to be taken when
! reading in each one, so the user will have to provide quite a lot of information
!
write(*,'(a)') "---"
write(*,'(a)')
write(*,'(a)') "Now the competing phases and their energies must be entered."
write(*,'(a)') "First enter the total number of competing phases:"
8001 read(*,*) nlimits
!
! Check that the number is not less than zero
!
if(nlimits < 0) then
write(*,'(a)') "ERROR: Number cannot be negative!"
write(*,'(a)') "Enter number of competing phases again:"
goto 8001
endif
!
! Check if there are no limiting compounds. If so tell user that range of allowed
! chemical potentials is only limited by the allowed elemental values determined
! by the system energy
!
check_lim = ltrue
if(nlimits == 0) then
write(*,'(a)') "No competing phases: element chemical potentials can take any"
write(*,'(a)') "value in range between zero and system energy"
check_lim = lfalse
endif
write(*,*)
write(*,'(a)') "Now for each phase enter the number of elements, then the"
write(*,'(a)') "formula and energy, in the same format as for the material"
write(*,'(a)') "formula."
write(*,*)
do i=1,nlimits
write(*,'(a48,i3)') "Enter number of elements in competing phase no. ", i
read(*,*) limittotno(i)
!
! Check that the number of elements in the compound doesn't exceed the number
! of elements in the material, or is less than one
!
if(limittotno(i) > nspecies) then
write(*,'(a)') "ERROR: Competing phase has more elements than the material!!"
write(*,*)
write(*,'(a55,i3)') "Enter a new number of elements for competing phase no. ", i
read(*,*) limittotno(i)
endif
if(limittotno(i) < 1 ) then
write(*,'(a)') "ERROR: Competing phase cannot have less than one element!!"
write(*,*)
write(*,'(a55,i3)') "Enter a new number of elements for competing phase no. ", i
read(*,*) limittotno(i)
endif
write(*,*)
write(*,'(a57,i3)') "Enter chemical formula and energy of competing phase no. ", i
read(*,*) (limitnum(i,j),limitname(i,j),j=1,limittotno(i)), limite(i)
write(*,*)
enddo
!
! Check that elements in the compounds are compatible with those in the material
!
write(*,'(a)') "Checking competing phase formulae..."
write(*,*)
do i=1,nlimits
l = 0
do j=1,limittotno(i)
do k=1,nspecies
if(limitname(i,j) == name(k)) l = l+1
enddo
enddo
if(l == 0) then
write(*,'(a)') "FATAL ERROR: Competing phase found with element not contained in &
&material!!"
write(*,'(a44,i3)') " Error found in competing phase ", i
goto 200
endif
enddo
!
! Check that element numbers in compounds aren't negative
!
do i=1,nlimits
do j=1,limittotno(i)
if(limitnum(i,j) < 1) then
write(*,'(a)') "FATAL ERROR: Incorrect syntax when entering numbers in chemical formula"
write(*,'(a44,i3)') " Error found in competing phase ", i
goto 200
endif
enddo
enddo
write(*,'(a)') "...all ok"
write(*,*)
endif
!
! Construct matrix containing all linear equations. First go through all limiting
! compound formulae and determine the resulting linear equation for each
!
eqns = 0.d0
if(check_lim .eqv. lfalse) goto 100
check1 = lfalse
do i=1,nlimits
!
! First check if the dependent variable element is present. If so fill elements of
! this line of the matrix appropriately, not yet taking into account the presence
! of other elements in the compound (skip this if no dependent variable set)
!
if(check_dep) then
do j=1,limittotno(i)
if(limitname(i,j) == name(nspecies)) then
check1 = ltrue
ndepend = j
endif
enddo
endif
if(check1) then
do j=1,nspecies_dep
eqns(i,j) = eqns(i,j) - dble(limitnum(i,ndepend)) * (dble(num(j))/&
&dble(num(nspecies_dep + 1)))
enddo
eqns(i,nspecies_dep + 1) = limite(i) - dble(limitnum(i,ndepend)) * (energy/&
&dble(num(nspecies_dep + 1)))
check1 = lfalse
!
! If the dependent variable is not present the energy must still be put in the
! last column
!
else
eqns(i,nspecies_dep + 1) = limite(i)
endif
!
! Now fill matrix elements according to presence of other chemical elements besides
! the dependent variable element. If the dependent variable element is present
! in the compound these numbers will be added to those determined previously. If not
! they will be added to zero (with matrix elements corresponding to chemical
! elements not present in the compound remaining as zero)
!
do j=1,limittotno(i)
do k=1,nspecies_dep
if(limitname(i,j) == name(k)) then
eqns(i,k) = eqns(i,k) + dble(limitnum(i,j))
endif
enddo
enddo
enddo
!
! Now add equations corresponding to the limits imposed by the chemical potential
! ranges of the individual elements of the material (i.e. E < mu_X < 0). If no
! limiting compounds were inputted, definition of eqns array begins here
!
100 do i=1,nspecies_dep
eqns(nlimits+i,i) = dble(num(i))
eqns(nlimits+i+nspecies_dep,i) = dble(num(i))
eqns(nlimits+i+nspecies_dep,nspecies_dep + 1) = energy
enddo
!
! Now shift all equations forward one row in the matrix and add linear equation
! corresponding to the dependent variable equal to zero
!
do i=nlimits+2*nspecies_dep,1,-1
eqns(i+1,:) = eqns(i,:)
enddo
do i=1,nspecies_dep
eqns(1,i) = dble(num(i))
enddo
eqns(1,nspecies_dep + 1) = energy
neqns = nlimits + 2*nspecies_dep + 1
else
!
! Restart file exists: read in data from restart file
!
write(*,*)
write(*,'(a)') "Found restart file..."
write(*,*)
do i=1,4
read(11,*)
enddo
read(11,*) char, char, char, nspecies
rewind(unit=11)
read(11,*)
read(11,*)
read(11,*) char, char, char, (num(i),name(i),i=1,nspecies)
write(*,*)
string = '(a7, (1x,i2,1x,a2))'
write(string(5:7),'(i3)') nspecies
write(*,string) "System:", (num(i),name(i),i=1,nspecies)
read(11,*)
read(11,*)
read(11,*)
read(11,*) char, char, char, char, nlimits
!
! Set check_lim
!
if(nlimits > 0) then
check_lim = ltrue
else
check_lim = lfalse
endif
!
do i=1,5
read(11,*)
enddo
read(11,*) char, energy
read(11,*)
read(11,*) char, char, strdep
if(strdep(1:1) == "n") then
check_dep = lfalse
nspecies_dep = nspecies
else
check_dep = ltrue
nspecies_dep = nspecies - 1
write(*,*)
write(*,'(a19,2x,a5)') "Dependent variable:", strdep
endif
do i=1,5
read(11,*)
enddo
!
! Read in inequality relations to set up matrix eqns, containing the linear equations
! solved in the original run
!
eqns = 0.d0
do i=1,nlimits+1
read(11,*) (eqns(i,j), char, j=1,nspecies_dep), char, eqns(i,nspecies_dep + 1)
enddo
do i=1,nspecies_dep
read(11,*) eqns(nlimits+1+i,i), char, char, eqns(nlimits+1+i,nspecies_dep + 1)
enddo
do i=1,nspecies_dep
read(11,*) eqns(nlimits+1+nspecies_dep+i,i), char, char, eqns(nlimits+1+&
&nspecies_dep+i,nspecies_dep + 1)
enddo
read(11,*)
read(11,*)
!
! Read in limiting compounds (if any)
!
if(nlimits > 0) then
limittotno = 0
limitnum = 0
limitname = " "
limite = 0.d0
do
read(11,'(a1)') read_tmp
if(read_tmp == "*") exit
enddo
read(11,*)
read(11,*) char, char, numtmp, char, str1, char, char, char, limite(1)
!
! Parse out compound's elements from its name (contained in str1). Do this by
! checking for lower case letters in the string, and for numbers
!
! Start with the first limiting compound
!
str_num = len_trim(str1)
i = 0
do
i = i+1
check_low = lfalse
if(i > str_num) exit
if(i == str_num) then
j = 1
else
j = 0
do
j = j+1
if((iachar(str1(i+j:i+j)) >= iachar('A') .and. iachar(str1(i+j:i+j))&
<= iachar('Z')) .or. (j + i > str_num)) exit
enddo
endif
if(j == 1) then
limittotno(1) = limittotno(1) + 1
limitname(1,limittotno(1)) = str1(i:i)
else
if(iachar(str1(i+1:i+1)) >= iachar('a') .and. iachar(str1(i+1:i+1)) &
<= iachar('z')) then
limittotno(1) = limittotno(1) + 1
limitname(1,limittotno(1)) = str1(i:i+1)
check_low = ltrue
else
limittotno(1) = limittotno(1) + 1
limitname(1,limittotno(1)) = str1(i:i)
endif
endif
if(check_low) then
if(j > 2) then
do k=j,3,-1
limitnum(1,limittotno(1)) = limitnum(1,limittotno(1)) + (iachar(&
&str1(i+k-1:i+k-1)) - iachar('0')) * int(10.d0**(-k) * 10.d0**j)
enddo
else
limitnum(1,limittotno(1)) = 1
endif
else
if(j > 1) then
do k=j,2,-1
limitnum(1,limittotno(1)) = limitnum(1,limittotno(1)) + (iachar(&
&str1(i+k-1:i+k-1)) - iachar('0')) * int(10.d0**(-k) * 10.d0**j)
enddo
else
limitnum(1,limittotno(1)) = 1
endif
endif
i = i + j - 1
enddo
!
! Now the other limiting compounds (if any)
!
if(nlimits > 1) then
do
do
read(11,'(a1)') read_tmp
if(read_tmp == "_") exit
enddo
str1 = " "
read(11,*)
read(11,*) char, char, numtmp, char, str1, char, char, char, limite&
&(numtmp)
str_num = len_trim(str1)
i = 0
do
i = i+1
check_low = lfalse
if(i > str_num) exit
if(i == str_num) then
j = 1
else
j = 0
do
j = j+1
if((iachar(str1(i+j:i+j)) >= iachar('A') .and. iachar(str1(i+j&
&:i+j)) <= iachar('Z')) .or. (j + i > str_num)) exit
enddo
endif
if(j == 1) then
limittotno(numtmp) = limittotno(numtmp) + 1
limitname(numtmp,limittotno(numtmp)) = str1(i:i)
else
if(iachar(str1(i+1:i+1)) >= iachar('a') .and. iachar(str1(i+1:i+1))&
<= iachar('z')) then
limittotno(numtmp) = limittotno(numtmp) + 1
limitname(numtmp,limittotno(numtmp)) = str1(i:i+1)
check_low = ltrue
else
limittotno(numtmp) = limittotno(numtmp) + 1
limitname(numtmp,limittotno(numtmp)) = str1(i:i)
endif
endif
if(check_low) then
if(j > 2) then
do k=j,3,-1
limitnum(numtmp,limittotno(numtmp)) = limitnum(numtmp,&
&limittotno(numtmp)) + (iachar(str1(i+k-1:i+k-1)) -&
&iachar('0')) * int(10.d0**(-k) * 10.d0**j)
enddo
else
limitnum(numtmp,limittotno(numtmp)) = 1
endif
else
if(j > 1) then
do k=j,2,-1
limitnum(numtmp,limittotno(numtmp)) = limitnum(numtmp,&
&limittotno(numtmp)) + (iachar(str1(i+k-1:i+k-1)) -&
&iachar('0')) * int(10.d0**(-k) * 10.d0**j)
enddo
else
limitnum(numtmp,limittotno(numtmp)) = 1
endif
endif
i = i + j - 1
enddo
if(numtmp == nlimits) exit
enddo
endif
endif
!
! Three restart options are available. Ask the user which is appropriate
!
write(*,*)
write(*,*)
write(*,'(a)') "From restart file can:"
write(*,*)
write(*,'(a)') " (a) Change which element's chemical potential is the"
write(*,'(a)') " dependent variable (or set a dependent variable if"
write(*,'(a)') " not done previously)"
write(*,'(a)') " (b) Enter additional competing phases (can be read from"
write(*,'(a)') " a file extra_phases.dat)"
write(*,'(a)') " (c) Set the value of chemical potential for a particular"
write(*,'(a)') " element to a constant"
write(*,*)
write(*,'(a)') "Enter appropriate choice (a/b/c):"
90 read(*,'(a1)') read_tmp
!
if(read_tmp(1:1) == 'a' .or. read_tmp(1:1) == 'A') then
!
! Dependent variable must be changed. Ask user which element's chemical potential
! will be the new dependent variable. Also output file will be slightly different
! to the (b) option case, so need to set a check here
!
check_ab = ltrue
check_dep = ltrue
nspecies_dep = nspecies - 1
write(*,*)
write(*,'(a)') "Enter element whose chemical potential will be the (new)"
write(*,'(a)') "dependent variable:"
80 read(*,*) fixname
j = 0
do i=1,nspecies
if(fixname == name(i)) then
j = j+1
fixnum = i
endif
enddo
if(j == 0) then
write(*,'(a)') "ERROR: Element not found in system. Please enter another&
& element:"
goto 80
endif
!
! Change order of species in system so that new dependent variable element is last
! in the list (ie element nspecies)
!
tmp_str = name(nspecies)
name(nspecies) = fixname
name(fixnum) = tmp_str
numtmp = num(nspecies)
num(nspecies) = num(fixnum)
num(fixnum) = numtmp
!
! Now create eqns array from the limiting compounds and system, as was done for the
! original calculation
!
eqns = 0.d0
if(check_lim .eqv. lfalse) goto 110
check1 = lfalse
do i=1,nlimits
!
! First check if the dependent variable element is present. If so fill elements of
! this line of the matrix appropriately, not yet taking into account the presence
! of other elements in the compound
!
do j=1,limittotno(i)
if(limitname(i,j) == name(nspecies_dep + 1)) then
check1 = ltrue
ndepend = j
endif
enddo
if(check1) then
do j=1,nspecies_dep
eqns(i,j) = eqns(i,j) - dble(limitnum(i,ndepend)) * (dble(num(j))/&
&dble(num(nspecies_dep + 1)))
enddo
eqns(i,nspecies_dep + 1) = limite(i) - dble(limitnum(i,ndepend)) * (energy/&
&dble(num(nspecies_dep + 1)))
check1 = lfalse
!
! If the dependent variable is not present the energy must still be put in the
! last column
!
else
eqns(i,nspecies_dep + 1) = limite(i)
endif
!
! Now fill matrix elements according to presence of other chemical elements besides
! the dependent variable element. If the dependent variable element is present
! in the compound these numbers will be added to those determined previously. If not
! they will be added to zero (with matrix elements corresponding to chemical
! elements not present in the compound remaining as zero)
!
do j=1,limittotno(i)
do k=1,nspecies_dep
if(limitname(i,j) == name(k)) then
eqns(i,k) = eqns(i,k) + dble(limitnum(i,j))
endif
enddo
enddo
enddo
!
! Now add equations corresponding to the limits imposed by the chemical potential
! ranges of the individual elements of the material (i.e. E < mu_X < 0). If no
! limiting compounds were inputted, definition of eqns array begins here
!
110 do i=1,nspecies_dep
eqns(nlimits+i,i) = dble(num(i))
eqns(nlimits+i+nspecies_dep,i) = dble(num(i))
eqns(nlimits+i+nspecies_dep,nspecies_dep + 1) = energy
enddo
!
! Now shift all equations forward one row in the matrix and add linear equation
! corresponding to the dependent variable equal to zero
!
do i=nlimits+2*nspecies_dep,1,-1
eqns(i+1,:) = eqns(i,:)
enddo
do i=1,nspecies_dep
eqns(1,i) = dble(num(i))
enddo
eqns(1,nspecies_dep + 1) = energy
neqns = nlimits + 2*nspecies_dep + 1
!
! If option b is selected, new limiting compounds must be read in
!
elseif(read_tmp(1:1) == 'b' .or. read_tmp(1:1) == 'B') then
!
check_ab = ltrue
!
! Check for file containing additional phases. If it exists read data from it
!
open(unit=14, status="old", file="extra_phases.dat", iostat=extra)
if(extra == 0) then
write(*,'(a)') "Reading additional competing phases from extra_phases.dat..."
write(*,*)
write(*,'(a)') "Reading total number of additional phases..."
do
read(14,'(a100)') line
if(line(1:1) /= "#") then
read(line,*) nadd
exit
endif
enddo
!
! Check that the number is not less than zero
!
if(nadd < 0) then
write(*,'(a)') "FATAL ERROR: Found negative number of additional competing phases!"
goto 200
endif
write(*,'(a)') "...found ok"
write(*,*)
!
! Check if there are no limiting compounds. If there are, read them in sequentially.
! Check that the number in the input file matches the stated total amount. If not warn
! user and reset total amount
!
if(nadd == 0) then
write(*,'(a)') "Zero additional competing phases found"
goto 130
else
write(*,'(a)') "Reading in formulae of each addtional competing phase..."
write(*,*)
do i=nlimits+1,nlimits+nadd
check_read = lfalse
do
read(14,'(a100)',end=5002) line
if(line(1:1) /= "#") then
read(line,*,end=5002) limittotno(i)
exit
endif
enddo
if(limittotno(i) > nspecies) then
write(*,'(a28,i3,a36)') "FATAL ERROR: Competing phase", i, "has more elements than the material!"
goto 200
endif
if(limittotno(i) < 1 ) then
write(*,'(a28,i3,a26)') "FATAL ERROR: Competing phase", i, "has less than one element!"
goto 200
endif
do
read(14,'(a100)',end=5002) line