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
19 #include <blitz/array.h> // http://www.oonumerics.org/blitz/
20 #include <random/uniform.h> // blitz Random Number Generator - Mersenne Twister type
21 #include "SimpleIni.h" // Ini File Parser
24 using namespace blitz
;
25 using namespace ranlib
;
42 Array
<Occupation
, 2> sites
;
43 Array
<Atom
, 2> surface
;
44 int Latitude
, Longitude
;
45 int UnitCellSizeX
, UnitCellSizeY
;
54 class Interaction_Parameter
{
57 Array
<Directions
, 1> direction
;
60 void usage(const char *prog
)
62 fprintf(stderr
, "usage: %s structure-ini-file interactions-ini-file\n", prog
);
66 void panic(char *msg
, ...)
71 fprintf(stderr
, "FATAL: ");
72 vfprintf(stderr
, msg
, vargs
);
73 fprintf(stderr
, "\n");
77 const char *str_SI_Error(SI_Error rc
)
80 case SI_OK
: return "no error";
81 case SI_UPDATED
: return "existing value updated";
82 case SI_INSERTED
: return "new value inserted";
83 case SI_FAIL
: return "generic failure";
84 case SI_NOMEM
: return "out of memory";
85 case SI_FILE
: return "file error";
86 default: return "(invalid error)";
90 void read_ini_structure(const char *input_file_name
, Lattice
&lattice
)
92 CSimpleIni
ini(false, true, false);
95 SI_Error rc
= ini
.LoadFile(input_file_name
);
97 panic("Failed loading ini file: %s", str_SI_Error(rc
));
100 const CSimpleIniA::TKeyVal
* section
= ini
.GetSection("UnitCell");
102 panic("Ini file is missing 'UnitCell' section.");
104 #define ASSIGN_KEY(section, key_name, key_member) \
105 tmp = ini.GetValue(section, key_name); \
107 panic("%s definition is missing '%s'", section, key_name); \
108 lattice.key_member = atoi(tmp)
110 ASSIGN_KEY("UnitCell", "SizeX", UnitCellSizeX
);
111 ASSIGN_KEY("UnitCell", "SizeY", UnitCellSizeY
);
112 ASSIGN_KEY("UnitCell", "Longitude", Longitude
);
113 ASSIGN_KEY("UnitCell", "Latitude", Latitude
);
116 if (lattice
.UnitCellSizeX
< 1 || lattice
.UnitCellSizeY
< 1 ||
117 lattice
.Longitude
< 1 || lattice
.Latitude
< 1)
118 panic("Unit cell has unreasonable size.");
120 // Building adsorbate sites array
121 lattice
.sites
.resize(lattice
.Longitude
* lattice
.UnitCellSizeX
+ 1,
122 lattice
.Latitude
* lattice
.UnitCellSizeY
+ 1);
123 lattice
.sites
= empty
;
125 // Building surface sites array
126 lattice
.surface
.resize(lattice
.Longitude
* lattice
.UnitCellSizeX
+ 1,
127 lattice
.Latitude
* lattice
.UnitCellSizeY
+ 1);
128 lattice
.surface
= no_atom
;
131 section
= ini
.GetSection("Surface");
133 panic("Ini file is missing 'Surface' section. Maybe meaningful??");
135 CSimpleIniA::TNamesDepend Pd_positions
;
136 ini
.GetAllValues("Surface", "Pd", Pd_positions
);
137 for (CSimpleIniA::TNamesDepend::const_iterator i
= Pd_positions
.begin();
138 i
!= Pd_positions
.end(); ++i
) {
139 double x_frac
, y_frac
;
140 if (sscanf(i
->pItem
, "%lf/%lf", &x_frac
, &y_frac
) != 2 ||
141 x_frac
< 0 || x_frac
>= 1 ||
142 y_frac
< 0 || y_frac
>= 1)
143 panic("Skrewed coordinates in '%s'", i
->pItem
);
144 lattice
.surface((int)(lattice
.UnitCellSizeX
* x_frac
),
145 (int)(lattice
.UnitCellSizeY
* y_frac
)) = Pd
;
148 // Replicate surface unit cell to full dimension
149 for (int x
= 0; x
< lattice
.Longitude
* lattice
.UnitCellSizeX
+ 1; ++x
)
150 for (int y
= 0; y
< lattice
.Latitude
* lattice
.UnitCellSizeY
+ 1; ++y
)
151 lattice
.surface(x
, y
) =
152 lattice
.surface((x
% lattice
.UnitCellSizeX
),
153 (y
% lattice
.UnitCellSizeY
));
156 section
= ini
.GetSection("Adsorbates");
158 panic("Ini file is missing 'Adsorbates' section. Maybe meaningful??");
160 CSimpleIniA::TNamesDepend CO_positions
;
161 ini
.GetAllValues("Adsorbates", "CO", CO_positions
);
162 for (CSimpleIniA::TNamesDepend::const_iterator i
= CO_positions
.begin();
163 i
!= CO_positions
.end(); ++i
) {
164 double x_frac
, y_frac
;
165 if (sscanf(i
->pItem
, "%lf/%lf", &x_frac
, &y_frac
) != 2 ||
166 x_frac
< 0 || x_frac
>= 1 ||
167 y_frac
< 0 || y_frac
>= 1)
168 panic("Skrewed coordinates in '%s'", i
->pItem
);
169 lattice
.sites((int)(lattice
.UnitCellSizeX
* x_frac
),
170 (int)(lattice
.UnitCellSizeY
* y_frac
)) = CO
;
173 // Replicate adsorbates unit cell to full dimension
174 for (int x
= 0; x
< lattice
.Longitude
* lattice
.UnitCellSizeX
+ 1; ++x
)
175 for (int y
= 0; y
< lattice
.Latitude
* lattice
.UnitCellSizeY
+ 1; ++y
)
176 lattice
.sites(x
, y
) =
177 lattice
.sites((x
% lattice
.UnitCellSizeX
),
178 (y
% lattice
.UnitCellSizeY
));
183 void read_ini_interactions(const char *input_file_name
, Array
<Interaction_Parameter
, 1> &interaction
, int &total_interactions
)
185 CSimpleIni
ini(false, true, false);
188 SI_Error rc
= ini
.LoadFile(input_file_name
);
190 panic("Failed loading ini file: %s", str_SI_Error(rc
));
192 // Parse Interactions Section
193 const CSimpleIniA::TKeyVal
* section
= ini
.GetSection("Interactions");
195 panic("Interactions.ini file is missing 'Interactions' section.");
197 // First we need to get all keys and provide an interaction array of the correct size
198 //total_interactions = 0;
200 CSimpleIniA::TNamesDepend Interaction_types
;
201 ini
.GetAllKeys("Interactions", Interaction_types
);
203 // Counting all key value pairs for each key type
204 for (CSimpleIniA::TNamesDepend::const_iterator i
= Interaction_types
.begin();
205 i
!= Interaction_types
.end(); ++i
) {
206 CSimpleIniA::TNamesDepend Interaction_parameters
;
207 ini
.GetAllValues("Interactions", i
->pItem
, Interaction_parameters
);
208 total_interactions
+= (int) (Interaction_parameters
.size());
211 cout
<< " total interactions after counting " << total_interactions
<< endl
;
213 interaction
.resize(total_interactions
);
215 // Counter to access interactions array
216 int interaction_counter
= 0;
218 // constructor for directions array
219 for (int j
= 0; j
< total_interactions
; j
++){
220 interaction(j
).direction(1);
223 cout
<< " gone through interactions array " << endl
;
226 for (CSimpleIniA::TNamesDepend::const_iterator i
= Interaction_types
.begin();
227 i
!= Interaction_types
.end(); ++i
) {
228 // Then we need to get all values for this key
229 CSimpleIniA::TNamesDepend Interaction_parameters
;
230 ini
.GetAllValues("Interactions", i
->pItem
, Interaction_parameters
);
231 cout
<< " getting values for " << i
->pItem
<< endl
;
232 for (CSimpleIniA::TNamesDepend::const_iterator k
= Interaction_parameters
.begin();
233 k
!= Interaction_parameters
.end(); ++k
) {
235 cout
<< "getting first token of " << k
->pItem
<< endl
;
237 int resize_factor
= 1; // at least one possible interaction vector for each interaction parameter
241 char * p_key_value
= NULL
;
244 p_key_value
= (strdup(k
->pItem
));
245 cout
<< p_key_value
<< endl
;
246 // char *p_key_value = &key_value; // pointer to working copy
247 // cout << p_key_value << *p_key_value << endl << endl;
248 // pointer for string tokens
250 pch
= strtok(p_key_value
," :"); // get first string token
252 cout
<< "first token of " << i
->pItem
<< " and " << k
->pItem
<< " is: " << pch
<< endl
<< endl
;
254 // pch = strtok(NULL," :");
256 // cout << "second token is: " << pch << endl;
258 while (pch
!= NULL
) { // until not reached the end of the interaction parameter line
259 if (sscanf(pch
, "%i/%i", &x_vec
, &y_vec
) != 2) { // check if it is a x/y pair
260 cout
<< "assigning name " << endl
;
261 interaction(interaction_counter
).name
= pch
; // no x/y pair, so it's name of interaction
262 pch
= strtok(NULL
," :");
264 else { // it is an x/y pair
265 cout
<< "assigning direction " << endl
;
266 cout
<< "resize factor is " << resize_factor
<< endl
;
267 interaction(interaction_counter
).direction
.resize(resize_factor
); // resize directions array, provide memory
268 interaction(interaction_counter
).direction((resize_factor
-1)).x
= x_vec
; // assign values
269 interaction(interaction_counter
).direction((resize_factor
-1)).y
= y_vec
;
270 resize_factor
++; // increase directions counter for possible next interaction
271 pch
= strtok(NULL
," :"); // get next token
275 interaction_counter
++; // reached end of interaction parameter line, increase interactions counter
276 resize_factor
= 1; // reset directions counter for next interaction parameter
277 }; // end for loop for each interaction parameter
278 }; // end for loop for each interaction type
280 cout
<< "finished interaction assignment" << endl
;
281 // some output for checking interaction array content
282 for (int i
=0; i
< total_interactions
; i
++){
283 cout
<< "i= " << i
<< endl
;
284 cout
<< interaction(i
).name
<< endl
;
285 cout
<< interaction(i
).direction(0).x
<< endl
;
289 cout
<< "leaving interaction reading !! " << endl
;
290 cout
<< "total interactions " << total_interactions
<< endl
;
294 int main(int argc
, char* argv
[])
297 Array
<Interaction_Parameter
, 1> interaction
;
298 int total_interactions
;
299 total_interactions
= 0;
305 read_ini_structure(argv
[1], lattice
);
307 cout
<< "lattice:" << endl
<< lattice
.sites
;
308 cout
<< "underlying surface:" << endl
<< lattice
.surface
;
311 cout
<< "total interactions before interaction ini reading " << total_interactions
<< endl
;
313 read_ini_interactions(argv
[2], interaction
, total_interactions
);
315 cout
<< " now content output " << endl
;
316 cout
<< "total interactions " << total_interactions
<< endl
;
318 // some output for checking interaction array content
319 for (int i=0; i < 5; i++){
320 cout << "i= " << i << endl;
321 // cout << interaction(i).name << endl;
322 cout << interaction(i).direction(0).x << endl;