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
) {
231 int resize_factor
= 1;
234 sscanf((strtok(k
->pItem
, " ")), "%i/%i", &x_vec
, &y_vec
);
236 interaction(interaction_counter
).direction
.resize(resize_factor
);
237 interaction(interaction_counter
).direction((resize_factor
-1)).x
= x_vec
;
238 interaction(interaction_counter
).direction((resize_factor
-1)).y
= y_vec
;
240 } while (sscanf(strtok(NULL
, " "), "%i/%i", &x_vec
, &y_vec
) == 2);
242 interaction(interaction_counter
).name
= sscanf(strtok(NULL
, " "));
244 interaction_counter
++;
249 // some output for checking interaction array content
250 for (int i
=0; i
< total_interactions
; i
++){
251 cout
<< "i= " << i
<< endl
;
252 cout
<< interaction(i
).name
<< endl
;
253 cout
<< interaction(i
).direction(0).x
<< endl
;
256 cout
<< "leaving interaction reading !! " << endl
;
257 cout
<< "total interactions " << total_interactions
<< endl
;
261 int main(int argc
, char* argv
[])
264 Array
<Interaction_Parameter
, 1> interaction
;
265 int total_interactions
;
266 total_interactions
= 0;
272 read_ini_structure(argv
[1], lattice
);
274 cout
<< "lattice:" << endl
<< lattice
.sites
;
275 cout
<< "underlying surface:" << endl
<< lattice
.surface
;
278 cout
<< "total interactions before interaction ini reading " << total_interactions
<< endl
;
280 read_ini_interactions(argv
[2], interaction
, total_interactions
);
282 cout
<< " now content output " << endl
;
283 cout
<< "total interactions " << total_interactions
<< endl
;
285 // some output for checking interaction array content
286 for (int i=0; i < 5; i++){
287 cout << "i= " << i << endl;
288 // cout << interaction(i).name << endl;
289 cout << interaction(i).direction(0).x << endl;