2 * Determination of lateral interaction parameters on a c(2x2) square lattice
3 * using linear combinations to express each interaction and then counting
4 * them in terms of cluster-expansion coefficients
6 * Michael Rieger, FHI, 2008
18 #include <blitz/array.h> // http://www.oonumerics.org/blitz/
19 #include <random/uniform.h> // blitz Random Number Generator - Mersenne Twister type
20 #include "SimpleIni.h" // Ini File Parser
23 using namespace blitz
;
24 using namespace ranlib
;
41 Array
<Occupation
, 2> sites
;
42 Array
<Atom
, 2> surface
;
43 int Latitude
, Longitude
;
44 int UnitCellSizeX
, UnitCellSizeY
;
53 class Interaction_Parameter
{
56 Array
<Directions
, 1> direction
;
59 void usage(const char *prog
)
61 fprintf(stderr
, "usage: %s structure-ini-file interactions-ini-file\n", prog
);
65 void panic(char *msg
, ...)
70 fprintf(stderr
, "FATAL: ");
71 vfprintf(stderr
, msg
, vargs
);
72 fprintf(stderr
, "\n");
76 const char *str_SI_Error(SI_Error rc
)
79 case SI_OK
: return "no error";
80 case SI_UPDATED
: return "existing value updated";
81 case SI_INSERTED
: return "new value inserted";
82 case SI_FAIL
: return "generic failure";
83 case SI_NOMEM
: return "out of memory";
84 case SI_FILE
: return "file error";
85 default: return "(invalid error)";
89 void read_ini_structure(const char *input_file_name
, Lattice
&lattice
)
91 CSimpleIni
ini(false, true, false);
94 SI_Error rc
= ini
.LoadFile(input_file_name
);
96 panic("Failed loading ini file: %s", str_SI_Error(rc
));
99 const CSimpleIniA::TKeyVal
* section
= ini
.GetSection("UnitCell");
101 panic("Ini file is missing 'UnitCell' section.");
103 #define ASSIGN_KEY(section, key_name, key_member) \
104 tmp = ini.GetValue(section, key_name); \
106 panic("%s definition is missing '%s'", section, key_name); \
107 lattice.key_member = atoi(tmp)
109 ASSIGN_KEY("UnitCell", "SizeX", UnitCellSizeX
);
110 ASSIGN_KEY("UnitCell", "SizeY", UnitCellSizeY
);
111 ASSIGN_KEY("UnitCell", "Longitude", Longitude
);
112 ASSIGN_KEY("UnitCell", "Latitude", Latitude
);
115 if (lattice
.UnitCellSizeX
< 1 || lattice
.UnitCellSizeY
< 1 ||
116 lattice
.Longitude
< 1 || lattice
.Latitude
< 1)
117 panic("Unit cell has unreasonable size.");
119 // Building adsorbate sites array
120 lattice
.sites
.resize(lattice
.Longitude
* lattice
.UnitCellSizeX
+ 1,
121 lattice
.Latitude
* lattice
.UnitCellSizeY
+ 1);
122 lattice
.sites
= empty
;
124 // Building surface sites array
125 lattice
.surface
.resize(lattice
.Longitude
* lattice
.UnitCellSizeX
+ 1,
126 lattice
.Latitude
* lattice
.UnitCellSizeY
+ 1);
127 lattice
.surface
= no_atom
;
130 section
= ini
.GetSection("Surface");
132 panic("Ini file is missing 'Surface' section. Maybe meaningful??");
134 CSimpleIniA::TNamesDepend Pd_positions
;
135 ini
.GetAllValues("Surface", "Pd", Pd_positions
);
136 for (CSimpleIniA::TNamesDepend::const_iterator i
= Pd_positions
.begin();
137 i
!= Pd_positions
.end(); ++i
) {
138 double x_frac
, y_frac
;
139 if (sscanf(i
->pItem
, "%lf/%lf", &x_frac
, &y_frac
) != 2 ||
140 x_frac
< 0 || x_frac
>= 1 ||
141 y_frac
< 0 || y_frac
>= 1)
142 panic("Skrewed coordinates in '%s'", i
->pItem
);
143 lattice
.surface((int)(lattice
.UnitCellSizeX
* x_frac
),
144 (int)(lattice
.UnitCellSizeY
* y_frac
)) = Pd
;
147 // Replicate surface unit cell to full dimension
148 for (int x
= 0; x
< lattice
.Longitude
* lattice
.UnitCellSizeX
+ 1; ++x
)
149 for (int y
= 0; y
< lattice
.Latitude
* lattice
.UnitCellSizeY
+ 1; ++y
)
150 lattice
.surface(x
, y
) =
151 lattice
.surface((x
% lattice
.UnitCellSizeX
),
152 (y
% lattice
.UnitCellSizeY
));
155 section
= ini
.GetSection("Adsorbates");
157 panic("Ini file is missing 'Adsorbates' section. Maybe meaningful??");
159 CSimpleIniA::TNamesDepend CO_positions
;
160 ini
.GetAllValues("Adsorbates", "CO", CO_positions
);
161 for (CSimpleIniA::TNamesDepend::const_iterator i
= CO_positions
.begin();
162 i
!= CO_positions
.end(); ++i
) {
163 double x_frac
, y_frac
;
164 if (sscanf(i
->pItem
, "%lf/%lf", &x_frac
, &y_frac
) != 2 ||
165 x_frac
< 0 || x_frac
>= 1 ||
166 y_frac
< 0 || y_frac
>= 1)
167 panic("Skrewed coordinates in '%s'", i
->pItem
);
168 lattice
.sites((int)(lattice
.UnitCellSizeX
* x_frac
),
169 (int)(lattice
.UnitCellSizeY
* y_frac
)) = CO
;
172 // Replicate adsorbates unit cell to full dimension
173 for (int x
= 0; x
< lattice
.Longitude
* lattice
.UnitCellSizeX
+ 1; ++x
)
174 for (int y
= 0; y
< lattice
.Latitude
* lattice
.UnitCellSizeY
+ 1; ++y
)
175 lattice
.sites(x
, y
) =
176 lattice
.sites((x
% lattice
.UnitCellSizeX
),
177 (y
% lattice
.UnitCellSizeY
));
182 void read_ini_interactions(const char *input_file_name
, Array
<Interaction_Parameter
, 1> &interaction
, int &total_interactions
)
184 CSimpleIni
ini(false, true, false);
187 SI_Error rc
= ini
.LoadFile(input_file_name
);
189 panic("Failed loading ini file: %s", str_SI_Error(rc
));
191 // Parse Interactions Section
192 const CSimpleIniA::TKeyVal
* section
= ini
.GetSection("Interactions");
194 panic("Interactions.ini file is missing 'Interactions' section.");
196 // First we need to get all keys and provide an interaction array of the correct size
197 //total_interactions = 0;
199 CSimpleIniA::TNamesDepend Interaction_types
;
200 ini
.GetAllKeys("Interactions", Interaction_types
);
202 // Counting all key value pairs for each key type
203 for (CSimpleIniA::TNamesDepend::const_iterator i
= Interaction_types
.begin();
204 i
!= Interaction_types
.end(); ++i
) {
205 CSimpleIniA::TNamesDepend Interaction_parameters
;
206 ini
.GetAllValues("Interactions", i
->pItem
, Interaction_parameters
);
207 total_interactions
+= (int) (Interaction_parameters
.size());
210 cout
<< total_interactions
<< endl
;
212 interaction
.resize(total_interactions
);
214 // Counter to access interactions array
215 int interaction_counter
= 0;
217 // constructor for directions array
218 for (int j
= 0; j
< total_interactions
; j
++){
219 interaction(j
).direction(1);
224 for (CSimpleIniA::TNamesDepend::const_iterator i
= Interaction_types
.begin();
225 i
!= Interaction_types
.end(); ++i
) {
226 // Then we need to get all values for this key
227 CSimpleIniA::TNamesDepend Interaction_parameters
;
228 ini
.GetAllValues("Interactions", i
->pItem
, Interaction_parameters
);
229 for (CSimpleIniA::TNamesDepend::const_iterator k
= Interaction_parameters
.begin();
230 k
!= Interaction_parameters
.end(); ++k
) {
233 // Checking what kind of interaction it is, choosing correct reading routine
234 if (key_name
== "pair" ){
237 char Interaction_name
;
238 cout
<< "interaction counter before " << interaction_counter
<< endl
;
239 if (sscanf(k
->pItem
, "%i/%i \"%s\"", &x_vec
, &y_vec
, &Interaction_name
) != 3 )
240 panic("Skrewed Pair Interaction description '%s'", k
->pItem
);
241 interaction(interaction_counter
).name
= Interaction_name
;
242 interaction(interaction_counter
).direction
.resize(1);
243 interaction(interaction_counter
).direction(0).x
= x_vec
;
244 interaction(interaction_counter
).direction(0).y
= y_vec
;
245 interaction_counter
++;
246 cout
<< "interaction counter after pairs " << interaction_counter
<< endl
;
248 else if (key_name
== "trio"){
253 char Interaction_name
;
254 cout
<< "interaction counter before trio" << interaction_counter
<< endl
;
255 if (sscanf(k
->pItem
, "%i/%i:%i/%i \"%s\"", &x_vec
, &y_vec
, &x1_vec
, &y1_vec
, &Interaction_name
) != 5 )
256 panic("Skrewed Trio Interaction description '%s'", k
->pItem
);
257 interaction(interaction_counter
).name
= Interaction_name
;
258 interaction(interaction_counter
).direction
.resize(2);
259 interaction(interaction_counter
).direction(0).x
= x_vec
;
260 interaction(interaction_counter
).direction(0).y
= y_vec
;
261 interaction(interaction_counter
).direction(1).x
= x1_vec
;
262 interaction(interaction_counter
).direction(1).y
= y1_vec
;
263 interaction_counter
++;
264 cout
<< "interaction counter after trios " << interaction_counter
<< endl
;
266 else if (key_name
== "quattro"){
273 char Interaction_name
;
274 if (sscanf(k
->pItem
, "%i/%i:%i/%i:%i/%i \"%s\"", &x_vec
, &y_vec
, &x1_vec
, &y1_vec
,
275 &x2_vec
, &y2_vec
, &Interaction_name
) != 7 )
276 panic("Skrewed Quattro Interaction description '%s'", k
->pItem
);
277 interaction(interaction_counter
).name
= Interaction_name
;
278 interaction(interaction_counter
).direction
.resize(3);
279 interaction(interaction_counter
).direction(0).x
= x_vec
;
280 interaction(interaction_counter
).direction(0).y
= y_vec
;
281 interaction(interaction_counter
).direction(1).x
= x1_vec
;
282 interaction(interaction_counter
).direction(1).y
= y1_vec
;
283 interaction(interaction_counter
).direction(2).x
= x2_vec
;
284 interaction(interaction_counter
).direction(2).y
= y2_vec
;
285 interaction_counter
++;
287 else if (key_name
== "quinto"){
296 char Interaction_name
;
297 if (sscanf(k
->pItem
, "%i/%i:%i/%i:%i/%i:%i/%i \"%s\"", &x_vec
, &y_vec
, &x1_vec
, &y1_vec
,
298 &x2_vec
, &y2_vec
, &x3_vec
, &y3_vec
, &Interaction_name
) != 9 )
299 panic("Skrewed Quinto Interaction description '%s'", k
->pItem
);
300 interaction(interaction_counter
).name
= Interaction_name
;
301 interaction(interaction_counter
).direction
.resize(4);
302 interaction(interaction_counter
).direction(0).x
= x_vec
;
303 interaction(interaction_counter
).direction(0).y
= y_vec
;
304 interaction(interaction_counter
).direction(1).x
= x1_vec
;
305 interaction(interaction_counter
).direction(1).y
= y1_vec
;
306 interaction(interaction_counter
).direction(2).x
= x2_vec
;
307 interaction(interaction_counter
).direction(2).y
= y2_vec
;
308 interaction(interaction_counter
).direction(3).x
= x3_vec
;
309 interaction(interaction_counter
).direction(3).y
= y3_vec
;
310 interaction_counter
++;
314 cout
<< "leaving interaction reading !! " << endl
;
315 cout
<< "total interactions " << total_interactions
<< endl
;
319 int main(int argc
, char* argv
[])
322 Array
<Interaction_Parameter
, 1> interaction
;
323 int total_interactions
;
324 total_interactions
= 0;
330 read_ini_structure(argv
[1], lattice
);
332 cout
<< "lattice:" << endl
<< lattice
.sites
;
333 cout
<< "underlying surface:" << endl
<< lattice
.surface
;
336 cout
<< "total interactions before interaction ini reading " << total_interactions
<< endl
;
338 read_ini_interactions(argv
[2], interaction
, total_interactions
);
340 cout
<< " now content output " << endl
;
341 cout
<< " total interactions are " << total_interactions
;
343 // some output for checking interaction array content
344 for (int i
=0; i
< total_interactions
; i
++){
345 cout
<< "i= " << i
<< endl
;
346 cout
<< interaction(i
).name
<< endl
;
347 cout
<< interaction(i
).direction(0).x
<< endl
;