160 log_.setMultithreading(
true);
161 log_.setCommonPreface(
"\n... ...");
169 std::vector<Index> frames = reader.
getFrames();
170 if (frames.empty()) {
171 throw std::runtime_error(
"networkfit: " +
statefile_ +
" has no frames");
173 frame = frames.front();
180 <<
"Read " <<
statefile_ <<
" frame " << frame <<
": " << n <<
" sites, "
181 << data.
pairs.size() <<
" pairs, box " << data.
box.x() * nm <<
" x "
182 << data.
box.y() * nm <<
" x " << data.
box.z() * nm <<
" nm^3"
189 Eigen::Vector3d::Zero());
194 for (std::size_t c = 0; c <
settings_.carriers.size(); ++c) {
196 std::ostringstream s;
197 s <<
"Traps for " <<
settings_.carriers[c].ToString()
198 <<
" (slow modes of the master equation at " <<
temperature_
199 <<
" K): largest eigenvalue ratio " << std::setprecision(3) << tr.
gap
200 <<
" after " << tr.
slow_modes <<
" slow mode(s)";
201 if (tr.
traps.empty()) {
205 s <<
"\n trap of " << t.
sites.size() <<
" site(s):";
214 s <<
"\n equilibrium weight " << t.
weight <<
"; release rate "
231 <<
"Point process: r_h = " << pp.
hard_core * nm
238 <<
"Connection probability tabulated up to "
240 for (std::size_t c = 0; c < opt.
carriers.size(); ++c) {
244 std::ostringstream s;
245 s <<
"Carrier " << car.state.ToString() <<
": site energies mean "
246 <<
e.mean * ev <<
" eV, sigma " <<
e.sigma * ev <<
" eV (sample), "
247 <<
e.sigma_model * ev <<
" eV = " <<
e.sigma_model * ev / kT
248 <<
" kT (model, corrected for the finite system)";
250 s <<
"\n moving average w_a = " <<
e.w_a <<
", w_b = " <<
e.w_b
251 <<
" (l_b = " <<
e.l_b <<
"), w_c = " <<
e.w_c <<
" (l_c = " <<
e.l_c
252 <<
"), rms of kappa " <<
e.rms <<
", mean correlation over all pairs "
255 s <<
"\n WARNING: l_b is at the end of its grid, extend the grid";
258 s <<
"\n WARNING: l_c is at the end of its grid: the range of "
259 "the correlation is not determined by this system size (see "
260 "the l_c scan in the stats file); extend the grid or use a "
261 "larger microscopic system";
264 s <<
"; no energy disorder (all site energies equal)";
266 s <<
"\n log10(J^2/eV^2) = " << j.model.mean_offset <<
" + "
267 << j.model.mean_slope <<
" r/nm, variance " << j.model.var_offset <<
" + "
268 << j.model.var_slope <<
" r/nm; residual skewness " << j.skewness
269 <<
", excess kurtosis " << j.excess_kurtosis <<
"; " << j.used
271 if (j.excluded > 0) {
272 s <<
", " << j.excluded <<
" zero couplings ignored";
274 s <<
"\n lambda = " << (car.U_nX_nN + car.U_xN_xX) * ev
275 <<
" eV (U_nX_nN " << car.U_nX_nN * ev <<
", U_xN_xX " << car.U_xN_xX * ev
276 <<
"), internal energy U_xX_nN " << car.U_xX_nN * ev <<
" eV";
277 double s2 = (
e.sigma_model * ev / kT) * (
e.sigma_model * ev / kT);
278 s <<
"\n the density of occupied states at " <<
temperature_
279 <<
" K needs about " << std::setprecision(2) << std::scientific
280 << std::exp((s2 + 5.7) / 1.05) <<
" sites" << std::defaultfloat
281 << std::setprecision(6);
286 <<
"Correlation of the site energies of "
287 << opt.
carriers[0].state.ToString() <<
" and "
300 const std::size_t ncar =
settings_.carriers.size();
302 std::vector<std::vector<int>> trap_of(ncar, std::vector<int>(n, 0));
304 for (
Index i : t.sites) {
305 trap_of[t.carrier][i] = 1;
309 out <<
"# segment id, x, y, z [nm] (wrapped), site energies [eV] of";
310 for (
const auto& c :
settings_.carriers) {
311 out <<
" " << c.ToString();
313 out <<
", trap site of";
314 for (
const auto& c :
settings_.carriers) {
315 out <<
" " << c.ToString();
317 out <<
" (1: yes)\n" << std::setprecision(12);
318 for (
Index i = 0; i < n; ++i) {
319 Eigen::Vector3d p = data.
positions[i] * nm;
320 out << i <<
" " << p.x() <<
" " << p.y() <<
" " << p.z();
321 for (std::size_t c = 0; c < ncar; ++c) {
322 out <<
" " << data.
energies[c][i] * ev;
324 for (std::size_t c = 0; c < ncar; ++c) {
325 out <<
" " << trap_of[c][i];
336 const double half = 0.4999 * data.
box.minCoeff();
338 const std::size_t ncar =
settings_.carriers.size();
340 std::vector<std::pair<std::string, double>> rows;
341 rows.emplace_back(
"pairs per site",
342 2.0 *
double(d.pairs.size()) /
double(n));
344 "mean nearest neighbour distance (nm)",
347 for (std::size_t c = 0; c < ncar; ++c) {
348 const std::string name =
settings_.carriers[c].ToString();
349 double sd = Sigma(d.energies[c]);
350 rows.emplace_back(
"sigma " + name +
" (eV)", sd * ev);
351 Log10Stats l = LogJ(d,
Index(c));
352 rows.emplace_back(
"mean log10(J^2/eV^2) " + name, l.mean);
353 rows.emplace_back(
"sd log10(J^2/eV^2) " + name, l.sd);
355 double md = MeanOf(d.energies[c]);
356 std::vector<double> z;
357 for (
double x : d.energies[c]) {
358 z.push_back((x - md) / sd);
362 for (
double r : {0.75, 1.0, 1.5, 2.0}) {
363 std::ostringstream q;
364 q <<
"kappa " << name <<
" at " << std::fixed
365 << std::setprecision(2) << r <<
" nm";
371 const std::vector<double>& a = d.energies[0];
372 const std::vector<double>& b = d.energies[1];
373 double ma = MeanOf(a), mb = MeanOf(b);
374 double sab = 0.0, saa = 0.0, sbb = 0.0;
375 for (
Index i = 0; i < n; ++i) {
376 sab += (a[i] - ma) * (b[i] - mb);
377 saa += (a[i] - ma) * (a[i] - ma);
378 sbb += (b[i] - mb) * (b[i] - mb);
380 rows.emplace_back(
"site energy correlation",
381 sab / std::sqrt(saa * sbb));
387 auto trap_rows = [&](
const Topology& t,
388 std::vector<std::pair<std::string, double>>& rows) {
389 for (std::size_t c = 0; c < ncar; ++c) {
390 const std::string name =
settings_.carriers[c].ToString();
394 Eigen::Vector3d::Zero());
399 rows.emplace_back(
"log10 D zero field " + name +
" (m^2/s)",
406 rows.emplace_back(
"traps found " + name,
double(tr.
traps.size()));
409 auto micro = statistics(data);
410 trap_rows(top, micro);
411 std::vector<double> mean(micro.size(), 0.0), var(micro.size(), 0.0);
415 o.
seed = opt.
seed + std::uint64_t(k);
420 auto rows = statistics(d);
426 for (std::size_t q = 0; q < rows.size(); ++q) {
427 mean[q] += rows[q].second / double(
validate_);
428 var[q] += rows[q].second * rows[q].second / double(
validate_);
431 model = std::move(d);
434 std::ostringstream s;
435 s << std::setprecision(4);
436 s <<
"Validation: " <<
validate_ <<
" model network(s) of " << n
437 <<
" sites (seeds " << opt.
seed <<
" to "
439 <<
"), mean and standard deviation over the networks; " << inserted
440 <<
" trap(s) inserted in total:\n";
441 s <<
" " << std::left << std::setw(38) <<
"quantity" << std::setw(14)
442 <<
"microscopic" << std::setw(14) <<
"model" <<
"sd\n";
443 for (std::size_t q = 0; q < micro.size(); ++q) {
444 double sd = std::sqrt(std::max(0.0, var[q] - mean[q] * mean[q]));
445 s <<
" " << std::left << std::setw(38) << micro[q].first
446 << std::setw(14) << micro[q].second << std::setw(14) << mean[q] << sd
454 out << std::setprecision(8);
456 auto block = [&out](
const std::string& title,
const std::string& columns,
457 const Curve& a,
const Curve* b) {
458 out <<
"# " << title <<
"\n# " << columns <<
"\n";
459 for (std::size_t k = 0; k < a.r.size(); ++k) {
460 bool empty = !a.count.empty() && a.count[k] <= 0.0;
462 << (empty ? std::numeric_limits<double>::quiet_NaN() : a.value[k]);
464 bool bempty = !b->count.empty() && b->count[k] <= 0.0;
466 << (bempty ? std::numeric_limits<double>::quiet_NaN()
474 block(
"nearest neighbour distance distribution D(r)",
476 block(
"spherical contact distribution H(r)",
"r [nm], microscopic, model",
478 block(
"pair correlation function g(r)",
"r [nm], microscopic, model",
481 block(
"connection probability f(r)",
"r [nm], f", res.
connection,
nullptr);
488 block(
"pairs per site in distance bins",
"r [nm], microscopic, model", pd,
491 for (std::size_t c = 0; c <
settings_.carriers.size(); ++c) {
492 const std::string name =
settings_.carriers[c].ToString();
494 block(
"energy correlation kappa(r), carrier " + name,
495 "r [nm], microscopic, fitted moving average",
497 out <<
"# rms of the best kappa fit for each l_c, carrier " << name
499 const Curve& scan = res.
energies[c].l_c_scan;
500 for (std::size_t k = 0; k < scan.r.size(); ++k) {
501 out << scan.r[k] <<
" " << scan.value[k] <<
"\n";
510 block(
"mean log10(J^2/eV^2), carrier " + name,
511 "r [nm], microscopic, model", jd, &jm);
513 block(
"mean log10(J^2/eV^2), carrier " + name,
"r [nm], microscopic",