tmain.c - slidergrid - grid of elastic sliders on a frictional surface
HTML git clone git://src.adamsgaard.dk/slidergrid
DIR Log
DIR Files
DIR Refs
DIR README
DIR LICENSE
---
tmain.c (8717B)
---
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <sys/types.h>
5 #include <sys/stat.h>
6 #include <unistd.h>
7 #include "slider.h"
8 #include "grid.h"
9 #include "simulation.h"
10 #include "debug.h"
11 #include "constants.h"
12
13 void print_usage(char* argv0)
14 {
15 printf("%s: simulate a grid of bonded sliders\n"
16 "webpage: https://github.com/anders-dc/slidergrid\n"
17 "usage: %s [OPTION[S]]\n"
18 "options:\n"
19 " -h, --help\t\tprint this information\n"
20 " -v, --version \tprint version information and exit\n"
21 " -V, --verbose \tshow status during simulation\n"
22 , argv0, argv0);
23 }
24
25 void print_version(char* argv0)
26 {
27 printf("%s: simulate a grid of bonded sliders\n"
28 "webpage: https://github.com/anders-dc/slidergrid\n"
29 "version: %.2f\n"
30 "author: Anders Damsgaard, adamsgaard@ucsd.edu\n"
31 "This software is free software, see LICENSE for details.\n"
32 , argv0, VERSION);
33 }
34
35 void print_status(simulation sim)
36 {
37 printf("\r%s: t = %.3f s, t_end = %.3f s (%2.0f%%), "
38 "last output = %06d ",
39 sim.id, sim.time, sim.time_end,
40 sim.time/sim.time_end*100.,
41 sim.file_number);
42 }
43
44 int main(int argc, char** argv)
45 {
46 int i;
47
48 // default values of command-line flags
49 int verbose = 0;
50
51 // parse command-line arguments
52 for (i=1; i<argc; i++) {
53
54 if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) {
55 print_usage(argv[0]);
56 return 0;
57 }
58
59 if (strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "--version") == 0) {
60 print_version(argv[0]);
61 return 0;
62 }
63
64 if (strcmp(argv[i], "-V") == 0 || strcmp(argv[i], "--verbose") == 0) {
65 verbose = 1;
66 continue;
67 }
68 }
69
70
71 // external function which defines the simulation setup and parameters
72 simulation sim = setup_simulation();
73
74 if (verbose) {
75 sim.verbose = 1;
76 printf("Sliders N = %d\n", sim.N);
77 }
78
79 // create bonds between sliders and update neighbor lists
80 find_and_bond_to_neighbors_n2(sim.sliders, sim.N, sim.bond_length_limit);
81
82 // determine time step length
83 sim.dt = find_time_step(sim.sliders, sim.N, 0.07);
84
85 // check simulation parameters for missing or wrong parameter values
86 if (check_simulation_values(&sim)) {
87 fprintf(stderr, "\nFatal error: The simulation configuration is "
88 "invalid.\n\n"
89 "Please check the setup_simulation() configuration, "
90 "which is verified in the function check_simulation_values "
91 "(simulation.c).\n");
92 return EXIT_FAILURE;
93 }
94
95 if (verbose) {
96 printf("starting simulation '%s'\n", sim.id);
97 printf("time step length: dt = %f s\n", sim.dt);
98 }
99
100 // create output file directory with simulation id as name and placed in
101 // current folder if it doesn't already exist
102 char output_folder[400];
103 sprintf(output_folder, "%s-output", sim.id);
104 struct stat st = {0};
105 int status;
106 if (stat(output_folder, &st) == -1) {
107 status = mkdir(output_folder, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
108 if (status != 0) {
109 fprintf(stderr, "Error: Could not create output folder '%s' (%d)\n",
110 output_folder, status);
111 return 1;
112 }
113 }
114
115 // save initial conditions to output files
116 if (write_simulation_output(&sim, output_folder)) {
117 fprintf(stderr, "\nFatal error: Could not write one or more "
118 "output files.\n");
119 return EXIT_FAILURE;
120 }
121
122 // main temporal loop
123 sim.iteration = 0;
124 Float time_since_status = 0.0;
125 Float time_since_file = 0.0;
126 for (sim.time = 0.0;
127 sim.time <= sim.time_end;
128 sim.time += sim.dt) {
129
130 #if defined(DEBUG_FIND_AND_BOND_TO_NEIGHBORS) ||\
131 defined(DEBUG_BOND_DEFORMATION) ||\
132 defined(DEBUG_SLIDER_FORCE_COMPONENTS) ||\
133 defined(DEBUG_SLIDER_FORCE_TORQUE_AND_NEIGHBORS) ||\
134 defined(DEBUG_SLIDER_KINEMATICS)
135 printf("\n---- ITERATION %ld ----\n", sim.iteration);
136 #endif
137
138 /*for (i=0; i<sim.N; i++)
139 printf("%d: vel = %f %f %f\n", i,
140 sim.sliders[i].vel.x,
141 sim.sliders[i].vel.y,
142 sim.sliders[i].vel.z);*/
143
144 for (i=0; i<sim.N; i++) {
145 project_slider_position(&sim.sliders[i], sim.dt, sim.iteration);
146 zero_slider_force_torque(&sim.sliders[i]);
147 }
148
149 /*for (i=0; i<sim.N; i++)
150 printf("%d: pos = %f %f %f, pos_future = %f %f %f\n", i,
151 sim.sliders[i].pos.x,
152 sim.sliders[i].pos.y,
153 sim.sliders[i].pos.z,
154 sim.sliders[i].pos_future.x,
155 sim.sliders[i].pos_future.y,
156 sim.sliders[i].pos_future.z);*/
157
158 // resolve slider-to-slider interaction
159 for (i=0; i<sim.N; i++) {
160 #ifdef DEBUG_BOND_DEFORMATION
161 printf("\n-- Loop of slider %d (%p) --\n",
162 i, &sim.sliders[i]);
163 #endif
164
165 slider_neighbor_interaction(
166 &sim.sliders[i],
167 sim.sliders,
168 sim.N,
169 sim.iteration,
170 sim.dt);
171
172 #ifdef DEBUG_SLIDER_FORCE_TORQUE_AND_NEIGHBORS
173 int j;
174 printf(" main.c: Slider %d:\n\tF = %f %f %f\n"
175 "\tT = %f %f %f\n\tmass = %f\n\tcontacts = ",
176 i,
177 sim.sliders[i].force.x,
178 sim.sliders[i].force.y,
179 sim.sliders[i].force.z,
180 sim.sliders[i].torque.x,
181 sim.sliders[i].torque.y,
182 sim.sliders[i].torque.z,
183 sim.sliders[i].mass);
184 for (j=0; j<MAX_NEIGHBORS; j++)
185 if (sim.sliders[i].neighbors[j] >= 0)
186 printf("%d ", sim.sliders[i].neighbors[j]);
187 //puts("\n");
188 puts("");
189 #endif
190 }
191
192 // add global viscous damping
193 for (i=0; i<sim.N; i++)
194 if (sim.sliders[i].damping_viscosity_linear > 1.0e-16 ||
195 sim.sliders[i].damping_viscosity_angular > 1.0e-16)
196 slider_viscous_damping(&sim.sliders[i]);
197
198 // add global non-viscous damping
199 for (i=0; i<sim.N; i++)
200 if (sim.sliders[i].damping_coefficient > 1.0e-16)
201 slider_nonviscous_damping(&sim.sliders[i]);
202
203
204 for (i=0; i<sim.N; i++)
205 update_kinematics(&sim.sliders[i], sim.dt, sim.iteration);
206
207 #ifdef DEBUG_SLIDER_KINEMATICS
208 for (i=0; i<sim.N; i++) {
209 printf("main.c: Slider %d:\n"
210 "\tpos = %f %f %f\n"
211 "\tvel = %f %f %f\n"
212 "\tacc = %f %f %f\n"
213 "\tangpos = %f %f %f\n"
214 "\tangvel = %f %f %f\n"
215 "\tangacc = %f %f %f\n",
216 i,
217 sim.sliders[i].pos.x,
218 sim.sliders[i].pos.y,
219 sim.sliders[i].pos.z,
220 sim.sliders[i].vel.x,
221 sim.sliders[i].vel.y,
222 sim.sliders[i].vel.z,
223 sim.sliders[i].acc.x,
224 sim.sliders[i].acc.y,
225 sim.sliders[i].acc.z,
226 sim.sliders[i].angpos.x,
227 sim.sliders[i].angpos.y,
228 sim.sliders[i].angpos.z,
229 sim.sliders[i].angvel.x,
230 sim.sliders[i].angvel.y,
231 sim.sliders[i].angvel.z,
232 sim.sliders[i].angacc.x,
233 sim.sliders[i].angacc.y,
234 sim.sliders[i].angacc.z);
235 }
236 puts("");
237 #endif
238
239 if (time_since_file >= sim.file_interval) {
240 if (write_simulation_output(&sim, output_folder)) {
241 fprintf(stderr, "\nFatal error: Could not write one or more "
242 "output files.\n");
243 return EXIT_FAILURE;
244 }
245 time_since_file = 0.0;
246 }
247
248 if (verbose && (time_since_status > sim.dt*100. ||
249 time_since_status >= sim.file_interval)) {
250 print_status(sim);
251 time_since_status = 0.;
252 }
253
254 sim.iteration++;
255 time_since_status += sim.dt;
256 time_since_file += sim.dt;
257 }
258
259 if (verbose)
260 print_status(sim);
261 puts("");
262
263 // end program
264 free(sim.sliders);
265 return EXIT_SUCCESS;
266 }