1 |
(* ASCEND modelling environment |
2 |
|
3 |
This program is free software; you can redistribute it and/or modify |
4 |
it under the terms of the GNU General Public License as published by |
5 |
the Free Software Foundation; either version 2, or (at your option) |
6 |
any later version. |
7 |
|
8 |
This program is distributed in the hope that it will be useful, |
9 |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
10 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
11 |
GNU General Public License for more details. |
12 |
|
13 |
You should have received a copy of the GNU General Public License |
14 |
along with this program; if not, write to the Free Software |
15 |
Foundation, Inc., 59 Temple Place - Suite 330, |
16 |
Boston, MA 02111-1307, USA. |
17 |
*) |
18 |
IMPORT "ipopt"; |
19 |
REQUIRE "atoms.a4l"; |
20 |
(* |
21 |
This model is from W A Dollase & W I Newman (1984) 'Statistically most probable |
22 |
stoichiometric formulae', American Mineralogist (69) 553-556, accessed online at |
23 |
http://www.minsocam.org/msa/collectors_corner/arc/formula.htm |
24 |
|
25 |
As of 21 Dec 2010, this file crashes ASCEND if run with IPOPT as the solver. |
26 |
|
27 |
Model written by Roger Mason, with contributions from John Pye. |
28 |
*) |
29 |
|
30 |
|
31 |
(* |
32 |
A general container for the equations of Dollase & Newman |
33 |
*) |
34 |
MODEL formula_base; |
35 |
n IS_A integer_constant; (* number of elements *) |
36 |
m IS_A integer_constant; (* number of constraints *) |
37 |
n :== 4; |
38 |
m :== 3; |
39 |
|
40 |
w[1..n] IS_A factor; (* weight of oxide, per cation *) |
41 |
C[1..m][1..n] IS_A factor; (* constraint coefficients *) |
42 |
Cs[1..m] IS_A factor; (* constraint sums *) |
43 |
x[1..n] IS_A fraction; (* oxide component concentration *) |
44 |
N[1..n] IS_A factor; (* numbers of moles of each oxide *) |
45 |
k IS_A factor; (* 'normalisation factor, to be determinied' *) |
46 |
|
47 |
y[1..n] IS_A fraction; (* given weight fraction analyte *) |
48 |
s[1..n] IS_A factor; (* standard deviation in given weight fraction *) |
49 |
|
50 |
(* objective function *) |
51 |
objective: MINIMIZE SUM[ (y[i] - x[i])^2/s[i]^2 | i IN [1..n]]; (* 1 *) |
52 |
|
53 |
(* molecular structure constraints *) |
54 |
FOR j IN [1..m] CREATE |
55 |
Cs[j] = SUM[ C[j][i]*N[i] | i IN [1..n]]; (* 2 *) |
56 |
END FOR; |
57 |
|
58 |
FOR i IN [1..n] CREATE |
59 |
N[i] = k * x[i]/w[i]; (* 3 *) |
60 |
END FOR; |
61 |
|
62 |
(* sum of concentrations must equal unity *) |
63 |
1 = SUM[ x[i] | i IN [1..n]]; (* 5 *) |
64 |
|
65 |
END formula_base; |
66 |
|
67 |
(* |
68 |
A specific example implementing the above equation: plagioclase feldspar. |
69 |
*) |
70 |
MODEL formula REFINES formula_base; |
71 |
|
72 |
METHODS |
73 |
METHOD specify; |
74 |
FIX C[1..3][1..4]; |
75 |
FIX Cs[1..4]; |
76 |
FIX w[1..4]; |
77 |
FIX y[1..4]; |
78 |
FIX s[1..4]; |
79 |
|
80 |
FIX k; |
81 |
END specify; |
82 |
METHOD values; |
83 |
(* there are 8 total oxygens, *) |
84 |
Cs[1] := 8.0; |
85 |
C[1][1] := 0.5; |
86 |
C[1][2] := 1.0; |
87 |
C[1][3] := 1.5; |
88 |
C[1][4] := 2.0; |
89 |
|
90 |
(* four atoms in tetrahedral sites, and *) |
91 |
Cs[2] := 4.0; |
92 |
C[2][1] := 0.0; |
93 |
C[2][2] := 0.0; |
94 |
C[2][3] := 1.0; |
95 |
C[2][4] := 1.0; |
96 |
|
97 |
(* the sum of Na + Ca is equal to one. *) |
98 |
Cs[3] := 1.0; |
99 |
C[3][1] := 1.0; |
100 |
C[3][2] := 1.0; |
101 |
C[3][3] := 0.0; |
102 |
C[3][4] := 0.0; |
103 |
|
104 |
(* cation weights *) |
105 |
w[1] := 30.9895; (* 22.9898 + 15.9994*(1/2) *) |
106 |
w[2] := 56.0774; (* 40.078 + 15.9994 *) |
107 |
w[3] := 50.9806; (* 26.9815 + 15.9994*(3/2) *) |
108 |
w[4] := 60.0843; (* 28.0855 + 15.9994*(2/1) *) |
109 |
|
110 |
y[1] := 11.19/100 {}; |
111 |
y[2] := 1.07/100 {}; |
112 |
y[3] := 20.35/100 {}; |
113 |
y[4] := 67.39/100 {}; |
114 |
|
115 |
k := 2.62925; |
116 |
|
117 |
s[1] := 0.05 {}; |
118 |
s[2] := 0.05 {}; |
119 |
s[3] := 0.05 {}; |
120 |
s[4] := 0.05 {}; |
121 |
|
122 |
END values; |
123 |
METHOD default_self; |
124 |
x[1] := 11.29/100 {}; |
125 |
x[2] := 1.01/100 {}; |
126 |
x[3] := 20.31/100 {}; |
127 |
x[4] := 67.30/100 {}; |
128 |
END default_self; |
129 |
|
130 |
METHOD on_load; |
131 |
RUN reset; |
132 |
RUN values; |
133 |
RUN specify; |
134 |
END on_load; |
135 |
|
136 |
METHOD self_test; |
137 |
END self_test; |
138 |
|
139 |
END formula; |