forked from coppolachan/magneto
-
Notifications
You must be signed in to change notification settings - Fork 0
/
magneto.cpp
128 lines (117 loc) · 4.02 KB
/
magneto.cpp
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
#include <iostream>
#include <chrono>
#include <vector>
#include <random>
#include <fstream>
#include <sstream>
#include <omp.h>
#include "physics.h"
#include "System.h"
#include "helpers.h"
void checkParam(int argc, char* argv[], Config& cfg, LabConfig& labCfg){
std::string key, value;
int eqPos;
std::string argument;
for (int i = 1; i < argc; ++i) {
argument = argv[i];
eqPos = argument.find("=");
key = argument.substr(1, eqPos-1);
value = argument.substr(eqPos+1);
if (key == "L")
cfg.L = atoi(value.c_str());
else if (key == "N1")
cfg.n1 = atoi(value.c_str());
else if (key == "N2")
cfg.n2 = atoi(value.c_str());
else if (key == "N3")
cfg.n3 = atoi(value.c_str());
else if (key == "threads")
cfg.threadCount = atoi(value.c_str());
else if (key == "J")
cfg.J = atoi(value.c_str());
else if (key == "initial")
cfg.initial = value;
else if (key == "alg")
cfg.alg = value;
else if (key == "record")
cfg.recordMain = value == "main";
else if (key == "dist")
labCfg.normalDist = value == "normal";
else if (key == "en")
labCfg.output_filenames[energy] = value;
else if (key == "mag")
labCfg.output_filenames[mag] = value;
else if (key == "cv")
labCfg.output_filenames[cv] = value;
else if (key == "chi")
labCfg.output_filenames[chi] = value;
else if (key == "corr")
labCfg.output_filenames[corrfun] = value;
else if (key == "states")
labCfg.output_filenames[states] = value;
else if (key == "TSteps")
labCfg.TSteps = atoi(value.c_str());
else if (key == "TMin")
labCfg.TMin = atof(value.c_str());
else if (key == "TMax")
labCfg.TMax = atof(value.c_str());
else
std::cerr << "Unknown parameter: " << argument << std::endl;
}
}
int main(int argc, char* argv[]){
if (argc < 2) {
std::cerr << "Too few arguments. See documentation." << std::endl;
return 1;
}
// use cmd arguments
Config cfg;
LabConfig labCfg;
checkParam(argc, argv, cfg, labCfg);
omp_set_num_threads(cfg.threadCount);
// setup temperatures and systems
std::vector<double> temps;
if(labCfg.normalDist)
temps = normalSpace(labCfg.TMin, labCfg.TMax, labCfg.TSteps, 2.269, 1.0);
else
temps = linspace(labCfg.TMin, labCfg.TMax, labCfg.TSteps);
std::vector<System> systems;
auto t0 = std::chrono::high_resolution_clock::now();
for(double T : temps){
cfg.T = T;
systems.push_back(System(cfg, labCfg));
}
// do the computations
std::string progressStr = std::string(labCfg.TSteps, '.');
std::cout << progressStr.c_str() << std::endl;
#pragma omp parallel for
for(unsigned int i=0; i<systems.size(); ++i){
systems[i].compute();
std::cout << ".";
}
std::cout << std::endl;
// save results
std::ofstream fileOut;
for(unsigned int i=0; i<labCfg.output_filenames.size(); ++i){
if(! labCfg.output_filenames[i].empty()){
if(i != states){
fileOut.open(labCfg.output_filenames[i]+".txt");
for (auto& sys : systems)
fileOut << to_string(sys.cfg.T) << sys.results[i] << std::endl;
fileOut.close();
}
else{
for(int j=0; j<systems.size(); ++j){
fileOut.open(labCfg.output_filenames[i]+to_string(j)+".txt");
fileOut << systems[j].results[states] << std::endl;
fileOut.close();
}
}
}
}
// print runtime
auto t1 = std::chrono::high_resolution_clock::now();
double secs = (std::chrono::duration_cast <std::chrono::milliseconds > (t1-t0).count())*0.001;
std::cout << "runtime: " << secs << "s" << std::endl;
return 0;
}