#include "measurements.hpp" #include #include class badcycleException: public std::exception { virtual const char* what() const throw() { return "Could not find a valid cycle on the broken system."; } } badcycleex; void update_distribution_file(std::string id, const std::vector& data, std::string model_string) { std::string filename = model_string + id + ".dat"; std::ifstream file(filename); std::vector data_old(data.size(), 0); if (file.is_open()) { for (unsigned i = 0; i < data.size(); i++) { uint64_t num; file >> num; data_old[i] = num; } file.close(); } std::ofstream file_out(filename); for (unsigned i = 0; i < data.size(); i++) { file_out < void update_field_file(std::string id, const std::vector& data, unsigned N, std::string model_string, unsigned Mx, unsigned My) { std::string filename = model_string + id + "_" + std::to_string(Mx) + "_" + std::to_string(My) + ".dat"; std::ifstream file(filename); uint64_t N_old = 0; std::vector data_old(data.size(), 0); if (file.is_open()) { file >> N_old; for (unsigned j = 0; j < data.size(); j++) { file >> data_old[j]; } file.close(); } std::ofstream file_out(filename); file_out < void correlation(unsigned Mx, unsigned My, std::vector>& data, const fftw_complex* tx1, const fftw_complex* tx2, fftw_plan reverse_plan, fftw_complex *fftw_reverse_in, double *fftw_reverse_out) { for (unsigned i = 0; i < Mx * (My / 2 + 1); i++) { fftw_reverse_in[i][0] = tx1[i][0] * tx2[i][0] + tx1[i][1] * tx2[i][1]; fftw_reverse_in[i][1] = tx1[i][0] * tx2[i][1] - tx1[i][1] * tx2[i][0]; } fftw_execute(reverse_plan); for (unsigned j = 0; j < data.size(); j++) { for (unsigned i = 0; i < (Mx / 2 + 1) * (My / 2 + 1); i++) { data[j][i] += (T)pow(fftw_reverse_out[Mx * (i / (Mx / 2 + 1)) + i % (Mx / 2 + 1)] / (Mx * My), j + 1); } } } void autocorrelation2(double Lx, double Ly, unsigned Mx, unsigned My, std::vector& data, const std::list& pos) { for (std::list::const_iterator it1 = pos.begin(); it1 != pos.end(); it1++) { for (std::list::const_iterator it2 = it1; it2 != pos.end(); it2++) { double Δx_tmp = fabs(it1->x - it2->x); double Δx = Δx_tmp < Lx / 2 ? Δx_tmp : Lx - Δx_tmp; double Δy_tmp = fabs(it1->y - it2->y); double Δy = Δy_tmp < Ly / 2 ? Δy_tmp : Ly - Δy_tmp; data[(unsigned)(Mx * (Δx / Lx)) + (Mx / 2) * (unsigned)(My * (Δy / Ly))]++; } } } void correlation2(double Lx, double Ly, unsigned Mx, unsigned My, std::vector& data, const std::list& pos1, const std::list& pos2) { for (std::list::const_iterator it1 = pos1.begin(); it1 != pos1.end(); it1++) { for (std::list::const_iterator it2 = pos2.begin(); it2 != pos2.end(); it2++) { double Δx_tmp = fabs(it1->x - it2->x); double Δx = Δx_tmp < Lx / 2 ? Δx_tmp : Lx - Δx_tmp; double Δy_tmp = fabs(it1->y - it2->y); double Δy = Δy_tmp < Ly / 2 ? Δy_tmp : Ly - Δy_tmp; data[floor((Mx * Δx) / Lx) + (Mx / 2) * floor((My * Δy) / Ly)]++; } } } template void autocorrelation(unsigned Mx, unsigned My, std::vector>& out_data, fftw_plan forward_plan, double *fftw_forward_in, fftw_complex *fftw_forward_out, fftw_plan reverse_plan, fftw_complex *fftw_reverse_in, double *fftw_reverse_out) { fftw_execute(forward_plan); for (unsigned i = 0; i < My * (Mx / 2 + 1); i++) { fftw_reverse_in[i][0] = pow(fftw_forward_out[i][0], 2) + pow(fftw_forward_out[i][1], 2); fftw_reverse_in[i][1] = 0.0; } fftw_execute(reverse_plan); for (unsigned j = 0; j < out_data.size(); j++) { for (unsigned i = 0; i < (Mx / 2 + 1) * (My / 2 + 1); i++) { out_data[j][i] += (T)pow(fftw_reverse_out[Mx * (i / (Mx / 2 + 1)) + i % (Mx / 2 + 1)] / (Mx * My), j + 1); } } } unsigned edge_r_to_ind(graph::coordinate r, double Lx, double Ly, unsigned Mx, unsigned My) { return floor((Mx * r.x) / Lx) + Mx * floor((My * r.y) / Ly); } ma::ma(unsigned n, double a, unsigned Mx, unsigned My, double beta) : G(2 * n), sc(2 * n), sm(2 * n), sa(3 * n), sl(2 * n), sn(2 * n) { if (beta != 0.0) { model_string = "fracture_" + std::to_string(n) + "_" + std::to_string(a) + "_" + std::to_string(beta) + "_"; } else { model_string = "fracture_" + std::to_string(n) + "_" + std::to_string(a) + "_INF_"; } } ma::ma(unsigned Lx, unsigned Ly, double beta) : G(Lx * Ly / 2), sc(Lx * Ly / 2), sm(Lx * Ly / 2), sa(Lx * Ly), sl(Lx * Ly / 2), sn(Lx * Ly / 2) { if (beta != 0.0) { model_string = "fracture_" + std::to_string(Lx) + "_" + std::to_string(Ly) + "_" + std::to_string(beta) + "_"; } else { model_string = "fracture_" + std::to_string(Lx) + "_" + std::to_string(Ly) + "_INF_"; } } ma::~ma() { update_distribution_file("sc", sc, model_string); update_distribution_file("sm", sm, model_string); update_distribution_file("sa", sa, model_string); update_distribution_file("sl", sl, model_string); update_distribution_file("sn", sn, model_string); } void ma::pre_fracture(const network&) { lv = std::numeric_limits::lowest(); boost::remove_edge_if(trivial, G); avalanches = {}; } void ma::bond_broken(const network& net, const current_info& cur, unsigned i) { long double c = net.thresholds[i] - logl(cur.currents[i]); if (c > lv) { lv = c; avalanches.push_back({i}); } else { avalanches.back().push_back(i); } boost::add_edge(net.G.dual_edges[i].v[0], net.G.dual_edges[i].v[1], {i}, G); } void ma::post_fracture(network &n) { auto post_cracks = find_minimal_crack(G, n); std::vector component(boost::num_vertices(G)); unsigned num = boost::connected_components(G, &component[0]); if (post_cracks.size() > 2 || post_cracks.size() == 0) { throw badcycleex; } for (auto c : post_cracks) { sl[c.second.size() - 1]++; } unsigned crack_component = component[n.G.dual_edges[post_cracks.front().second.front()].v[0]]; std::vector> components(num); for (unsigned i = 0; i < n.G.dual_vertices.size(); i++) { components[component[i]].push_back(n.G.dual_vertices[i].r); } for (unsigned i = 0; i < num; i++) { if (i != crack_component) { sm[components[i].size() - 1]++; } sn[components[i].size() - 1]++; } auto av_it = avalanches.rbegin(); while (true) { for (unsigned e : *av_it) { boost::remove_edge(n.G.dual_edges[e].v[0], n.G.dual_edges[e].v[1], G); n.fuses[e] = false; } auto cracks = find_minimal_crack(G, n); if (cracks.size() == 0) { break; } av_it++; } num = boost::connected_components(G, &component[0]); std::vector> new_components(num); for (unsigned i = 0; i < n.G.dual_vertices.size(); i++) { new_components[component[i]].push_back(n.G.dual_vertices[i].r); } for (unsigned i = 0; i < num; i++) { sc[new_components[i].size() - 1]++; } av_it++; while (av_it != avalanches.rend()) { sa[(*av_it).size() - 1]++; av_it++; } }