From 873a9f9bedbbfb07d475e271923a7b86464e515f Mon Sep 17 00:00:00 2001 From: pants Date: Wed, 7 Sep 2016 14:55:30 -0400 Subject: more major refactoring --- src/voro_fracture.c | 492 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 492 insertions(+) create mode 100644 src/voro_fracture.c (limited to 'src/voro_fracture.c') diff --git a/src/voro_fracture.c b/src/voro_fracture.c new file mode 100644 index 0000000..237192a --- /dev/null +++ b/src/voro_fracture.c @@ -0,0 +1,492 @@ + + +#include "fracture.h" + +int main(int argc, char *argv[]) { + int opt; + + // defining variables to be (potentially) set by command line flags + uint8_t filename_len; + uint32_t N; + uint_t L; + double beta, inf, cutoff, crack_len; + bool save_data, save_cluster_dist, use_voltage_boundaries, use_dual, save_network, + save_crit_stress, save_stress_field, save_voltage_field, save_toughness, save_conductivity, + save_damage, save_damage_field; + bound_t boundary; + + + // assume filenames will be less than 100 characters + + filename_len = 100; + + + // set default values + + N = 100; + L = 16; + crack_len = 0.; + beta = .3; + inf = 1e10; + cutoff = 1e-9; + boundary = FREE_BOUND; + save_data = false; + save_cluster_dist = false; + use_voltage_boundaries = false; + use_dual = false; + save_network = false; + save_crit_stress = false; + save_stress_field = false; + save_voltage_field = false; + save_damage = false; + save_damage_field = false; + save_conductivity = false; + save_toughness = false; + + + uint8_t bound_i; + char boundc2 = 'f'; + + + // get commandline options + + while ((opt = getopt(argc, argv, "n:L:b:B:dVcoNsCrtDSvel:")) != -1) { + switch (opt) { + case 'n': + N = atoi(optarg); + break; + case 'L': + L = atoi(optarg); + break; + case 'b': + beta = atof(optarg); + break; + case 'l': + crack_len = atof(optarg); + break; + case 'B': + bound_i = atoi(optarg); + switch (bound_i) { + case 0: + boundary = FREE_BOUND; + boundc2 = 'f'; + break; + case 1: + boundary = CYLINDER_BOUND; + boundc2 = 'c'; + break; + case 2: + boundary = TORUS_BOUND; + use_voltage_boundaries = true; + boundc2 = 't'; + break; + case 3: + boundary = EMBEDDED_BOUND; + boundc2 = 'e'; + use_dual = true; + use_voltage_boundaries = true; + break; + default: + printf("boundary specifier must be 0 (FREE_BOUND), 1 (CYLINDER_BOUND), or 2 (TORUS_BOUND).\n"); + exit(EXIT_FAILURE); + } + break; + case 'd': + save_damage = true; + break; + case 'e': + save_damage_field = true; + break; + case 'V': + use_voltage_boundaries = true; + break; + case 'D': + use_dual = true; + break; + case 'c': + save_cluster_dist = true; + break; + case 'o': + save_data = true; + break; + case 'N': + save_network = true; + break; + case 's': + save_crit_stress = true; + break; + case 'S': + save_stress_field = true; + break; + case 'v': + save_voltage_field = true; + break; + case 'r': + save_conductivity = true; + //inf = 1; + break; + case 't': + save_toughness = true; + break; + default: /* '?' */ + exit(EXIT_FAILURE); + } + } + + + char boundc; + if (use_voltage_boundaries) boundc = 'v'; + else boundc = 'c'; + + FILE *data_out; + if (save_data) { + char *data_filename = (char *)malloc(filename_len * sizeof(char)); + snprintf(data_filename, filename_len, "data_v_%c_%c_%u_%g_%g.txt", boundc, boundc2, L, beta, crack_len); + data_out = fopen(data_filename, "a"); + free(data_filename); + } + + uint_t voronoi_max_verts, c_dist_size, a_dist_size; + + voronoi_max_verts = 4 * pow(L, 2); + c_dist_size = voronoi_max_verts; + a_dist_size = voronoi_max_verts; + + if (voronoi_max_verts > CINT_MAX) { + exit(EXIT_FAILURE); + } + + // define arrays for saving cluster and avalanche distributions + uint32_t *cluster_size_dist; + uint32_t *avalanche_size_dist; + char *c_filename; + char *a_filename; + if (save_cluster_dist) { + cluster_size_dist = + (uint32_t *)malloc(c_dist_size * sizeof(uint32_t)); + avalanche_size_dist = + (uint32_t *)malloc(a_dist_size * sizeof(uint32_t)); + + c_filename = (char *)malloc(filename_len * sizeof(char)); + a_filename = (char *)malloc(filename_len * sizeof(char)); + snprintf(c_filename, filename_len, "cstr_v_%c_%c_%d_%g_%g.dat", boundc, boundc2, L, beta, crack_len); + snprintf(a_filename, filename_len, "avln_v_%c_%c_%d_%g_%g.dat", boundc, boundc2, L, beta, crack_len); + + FILE *cluster_out = fopen(c_filename, "rb"); + FILE *avalanche_out = fopen(a_filename, "rb"); + + if (cluster_out != NULL) { + fread(cluster_size_dist, sizeof(uint32_t), c_dist_size, cluster_out); + fclose(cluster_out); + } + if (avalanche_out != NULL) { + fread(avalanche_size_dist, sizeof(uint32_t), a_dist_size, avalanche_out); + fclose(avalanche_out); + } + } + + double *crit_stress; + if (save_crit_stress) { + crit_stress = (double *)malloc(N * sizeof(double)); + } + + double *stress_field; + unsigned int stress_pos = 0; + if (save_stress_field) { + stress_field = (double *)malloc(3 * N * voronoi_max_verts * sizeof(double)); + } + + double *voltage_field; + unsigned int voltage_pos = 0; + if (save_voltage_field) { + voltage_field = (double *)malloc(3 * N * voronoi_max_verts * sizeof(double)); + } + + double *damage_field; + unsigned int damage_pos = 0; + if (save_damage_field) { + damage_field = (double *)malloc(2 * N * voronoi_max_verts * sizeof(double)); + } + + double *conductivity; + if (save_conductivity) { + conductivity = (double *)malloc(N * sizeof(double)); + } + + // define arrays for saving damage distributions + uint32_t *damage; + char *d_filename; + if (save_damage) { + damage = + (uint32_t *)malloc(a_dist_size * sizeof(uint32_t)); + + d_filename = (char *)malloc(filename_len * sizeof(char)); + snprintf(d_filename, filename_len, "damg_v_%c_%c_%d_%g_%g.dat", boundc, boundc2, L, beta, crack_len); + + FILE *damage_out = fopen(d_filename, "rb"); + + if (damage_out != NULL) { + fread(damage, sizeof(uint32_t), a_dist_size, damage_out); + fclose(damage_out); + } + } + + double *toughness; + if (save_toughness) { + toughness = (double *)malloc(N * sizeof(double)); + } + + + // start cholmod + cholmod_common c; + CHOL_F(start)(&c); + + /* if we use voltage boundary conditions, the laplacian matrix is positive + * definite and we can use a supernodal LL decomposition. otherwise we need + * to use the simplicial LDL decomposition + */ + if (use_voltage_boundaries) { + //(&c)->supernodal = CHOLMOD_SUPERNODAL; + (&c)->supernodal = CHOLMOD_SIMPLICIAL; + } else { + (&c)->supernodal = CHOLMOD_SIMPLICIAL; + } + + + printf("\n"); + for (uint32_t i = 0; i < N; i++) { + printf("\033[F\033[JFRACTURE: %0*d / %d\n", (uint8_t)log10(N) + 1, i + 1, N); + + graph_t *g = ini_voro_graph(L, boundary, use_dual, genfunc_hyperuniform, &c); + net_t *net = net_create(g, inf, beta, crack_len, use_voltage_boundaries, &c); + net_t *tmp_net = net_copy(net, &c); + data_t *data = net_fracture(tmp_net, &c, cutoff); + net_free(tmp_net, &c); + + uint_t max_pos = 0; + double max_val = 0; + + for (uint_t j = 0; j < data->num_broken; j++) { + double val = data->extern_field[j]; + + if (val > max_val) { + max_pos = j; + max_val = val; + } + } + + if (save_crit_stress) crit_stress[i] = data->extern_field[max_pos]; + + if (save_conductivity) conductivity[i] = data->conductivity[max_pos]; + + if (save_damage) damage[max_pos]++; + + uint_t av_size = 0; + double cur_val = 0; + for (uint_t j = 0; j < max_pos; j++) { + break_edge(net, data->break_list[j], &c); + + double val = data->extern_field[j]; + if (save_cluster_dist) { + if (val < cur_val) { + av_size++; + } + + if (val > cur_val) { + avalanche_size_dist[av_size]++; + av_size = 0; + cur_val = val; + } + } + } + + if (save_stress_field || save_voltage_field) { + double *tmp_voltages = get_voltage(net, &c); + if (save_voltage_field) { + for (uint_t j = 0; j < g->nv; j++) { + voltage_field[3 * voltage_pos] = g->vx[2 * j]; + voltage_field[3 * voltage_pos + 1] = g->vx[2 * j + 1]; + voltage_field[3 * voltage_pos + 2] = tmp_voltages[j]; + voltage_pos++; + } + } + if (save_stress_field) { + double *tmp_currents = get_current_v(net, tmp_voltages, &c); + for (uint_t j = 0; j < g->ne; j++) { + stress_field[3 * stress_pos] = g->ex[2 * j]; + stress_field[3 * stress_pos + 1] = g->ex[2 * j + 1]; + stress_field[3 * stress_pos + 2] = tmp_currents[j]; + stress_pos++; + } + free(tmp_currents); + } + free(tmp_voltages); + } + + if (save_damage_field) { + for (uint_t j = 0; j < max_pos; j++) { + damage_field[2 * damage_pos] = g->ex[2 * data->break_list[j]]; + damage_field[2 * damage_pos + 1] = g->ex[2 * data->break_list[j] + 1]; + damage_pos++; + } + } + + if (save_toughness) { + double tmp_toughness = 0; + if (max_pos > 0) { + double sigma1 = data->extern_field[0]; + double epsilon1 = sigma1 / data->conductivity[0]; + for (uint_t j = 0; j < max_pos - 1; j++) { + double sigma2 = data->extern_field[j+1]; + double epsilon2 = sigma2 / data->conductivity[j+1]; + if (epsilon2 > epsilon1) { + tmp_toughness += (sigma1 + sigma2) * (epsilon2 - epsilon1) / 2; + sigma1 = sigma2; epsilon1 = epsilon2; + } + } + } + toughness[i] = tmp_toughness; + } + + if (save_cluster_dist) { + uint_t *tmp_cluster_dist = get_cluster_dist(net, &c); + for (uint_t j = 0; j < g->dnv; j++) { + cluster_size_dist[j] += tmp_cluster_dist[j]; + } + free(tmp_cluster_dist); + } + + if (save_network) { + FILE *net_out = fopen("network.txt", "w"); + for (uint_t j = 0; j < g->nv; j++) { + fprintf(net_out, "%f %f ", g->vx[2 * j], + g->vx[2 * j + 1]); + } + fprintf(net_out, "\n"); + for (uint_t j = 0; j < g->ne; j++) { + fprintf(net_out, "%u %u ", g->ev[2 * j], g->ev[2 * j + 1]); + } + fprintf(net_out, "\n"); + for (uint_t j = 0; j < g->dnv; j++) { + fprintf(net_out, "%f %f ", g->dvx[2 * j], + g->dvx[2 * j + 1]); + } + fprintf(net_out, "\n"); + for (uint_t j = 0; j < g->ne; j++) { + fprintf(net_out, "%u %u ", g->dev[2 * j], g->dev[2 * j + 1]); + } + fprintf(net_out, "\n"); + for (uint_t j = 0; j < g->ne; j++) { + fprintf(net_out, "%d ", net->fuses[j]); + } + fclose(net_out); + } + + net_free(net, &c); + graph_free(g, &c); + + if (save_data) { + for (uint_t j = 0; j < data->num_broken; j++) { + fprintf(data_out, "%u %g %g ", data->break_list[j], + data->extern_field[j], data->conductivity[j]); + } + fprintf(data_out, "\n"); + } + + free_break_data(data); + } + + printf("\033[F\033[JFRACTURE: COMPLETE\n"); + + if (save_cluster_dist) { + FILE *cluster_out = fopen(c_filename, "wb"); + FILE *avalanche_out = fopen(a_filename, "wb"); + + fwrite(cluster_size_dist, sizeof(uint32_t), c_dist_size, cluster_out); + fwrite(avalanche_size_dist, sizeof(uint32_t), a_dist_size, avalanche_out); + + fclose(cluster_out); + fclose(avalanche_out); + + free(c_filename); + free(a_filename); + free(cluster_size_dist); + free(avalanche_size_dist); + } + + if (save_voltage_field) { + char *vfld_filename = (char *)malloc(filename_len * sizeof(char)); + snprintf(vfld_filename, filename_len, "vfld_v_%c_%c_%d_%g_%g.dat", boundc, boundc2, L, beta, crack_len); + FILE *vfld_file = fopen(vfld_filename, "ab"); + fwrite(voltage_field, sizeof(double), 3 * voltage_pos, vfld_file); + fclose(vfld_file); + free(vfld_filename); + free(voltage_field); + } + + if (save_stress_field) { + char *cfld_filename = (char *)malloc(filename_len * sizeof(char)); + snprintf(cfld_filename, filename_len, "cfld_v_%c_%c_%d_%g_%g.dat", boundc, boundc2, L, beta, crack_len); + FILE *cfld_file = fopen(cfld_filename, "ab"); + fwrite(stress_field, sizeof(double), 3 * stress_pos, cfld_file); + fclose(cfld_file); + free(cfld_filename); + free(stress_field); + } + + if (save_damage_field) { + char *dfld_filename = (char *)malloc(filename_len * sizeof(char)); + snprintf(dfld_filename, filename_len, "dfld_v_%c_%c_%d_%g_%g.dat", boundc, boundc2, L, beta, crack_len); + FILE *dfld_file = fopen(dfld_filename, "ab"); + fwrite(damage_field, sizeof(double), 2 * damage_pos, dfld_file); + fclose(dfld_file); + free(dfld_filename); + free(damage_field); + } + + if (save_conductivity) { + char *cond_filename = (char *)malloc(filename_len * sizeof(char)); + snprintf(cond_filename, filename_len, "cond_v_%c_%c_%d_%g_%g.dat", boundc, boundc2, L, beta, crack_len); + FILE *cond_file = fopen(cond_filename, "ab"); + fwrite(conductivity, sizeof(double), N, cond_file); + fclose(cond_file); + free(cond_filename); + free(conductivity); + } + + if (save_toughness) { + char *tough_filename = (char *)malloc(filename_len * sizeof(char)); + snprintf(tough_filename, filename_len, "tuff_v_%c_%c_%d_%g_%g.dat", boundc, boundc2, L, beta, crack_len); + FILE *tough_file = fopen(tough_filename, "ab"); + fwrite(toughness, sizeof(double), N, tough_file); + fclose(tough_file); + free(tough_filename); + free(toughness); + } + + if (save_damage) { + FILE *hdam_file = fopen(d_filename, "wb"); + fwrite(damage, sizeof(uint32_t), a_dist_size, hdam_file); + fclose(hdam_file); + free(d_filename); + free(damage); + } + + if (save_data) { + fclose(data_out); + } + + if (save_crit_stress) { + char *str_filename = (char *)malloc(filename_len * sizeof(char)); + snprintf(str_filename, filename_len, "strs_v_%c_%c_%d_%g_%g.dat", boundc, boundc2, L, beta, crack_len); + FILE *str_file = fopen(str_filename, "ab"); + fwrite(crit_stress, sizeof(double), N, str_file); + fclose(str_file); + free(str_filename); + free(crit_stress); + } + + CHOL_F(finish)(&c); + + return 0; +} -- cgit v1.2.3-70-g09d2