TYCHO  1.3.0
 All Data Structures Files Functions Variables Enumerations Enumerator
/home/kapf/tycho_docu/TYCHO.c
Go to the documentation of this file.
1 /*
2  Name : TYCHO.c
3  Author : Wolfgang Kapferer
4  Version : 1.3.0
5  Copyright : free software
6  Release : October 2013
7  Description :
8  TYCHO is a multidimensional (1D/2D and 3D) compressible hydrodynamics code written in C and parallelized with OpenMP.
9  A Lagrangian remap version of the Piecewise Parabolic Method developed by Paul Woodward and Phil Colella (1984) is
10  applied. The code is based on the freely available VH-1 Package VH-1 (http://wonka.physics.ncsu.edu/pub/VH-1/index.php).
11  The simulation package is focused on wind-flow experiments with obstacles in it and advection of marker fields for investigating
12  obstacle-gas interactions. In addition momenta and their direction on obstacles are calculated. Thermal diffusion on obstacles,
13  thermal-exchange between obstacles and the surrounding gas and a Sutherland's-law viscosity routine can be switched on in.
14  Gravity is included as a constant background-field and a stratified atmosphere can be set up, if needed.
15  Tycho is now able to calculate sound-pressure maps of the computational from a simulation with a sound emitters.
16 
17 
18  TYCHO is freely available to everyone. You are welcome to download it and do whatever you want with it.
19 
20 
21  ATTENTION THE CODE USES SI UNITS
22  ATTENTION THE CODE USES SI UNITS
23  ATTENTION THE CODE USES SI UNITS
24  */
25 
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <math.h>
29 #include <limits.h>
30 #include <time.h>
31 
32 #ifdef _OPENMP
33 #include <omp.h>
34 #endif
35 
36 /*
37  Header Files with the global variables
38  */
39 #include "variables_global.h"
40 #include "prototypes.h"
41 
42 /*
43 To determine the maximum of two integers
44  */
45 inline int max_array(int a, int b) {
46  double tmp;
47 
48  if (a < b) tmp = b;
49  if (a == b)tmp = b;
50  if (a > b) tmp = a;
51 
52  return tmp;
53 
54 }
55 
67 int main(int argc, char *argv[]) {
68 
69  int tmp1;
70  int i, j, k;
71 
72 #ifndef _OPENMP
73  // For performance analysis issues.
74  clock_t cputime_sim1, cputime_sim2;
75  clock_t cputime_sim1_eta, cputime_sim2_eta;
76 #endif
77 
78 #ifdef _OPENMP
79  // For performance analysis issues.
80  double cputime_sim1, cputime_sim2;
81  double cputime_sim1_eta, cputime_sim2_eta;
82 #endif
83 
84 
87 
88  double seconds, seconds_eta;
89 
90  // File for loading simulation parameter from parameter file.
91  char filename[200];
92 
93  restart = 0;
94 
95  // How many second has a minute ;-)
96  minute_in_sec = 60.0;
97 
98  //for sound-emitter simulations some initial values
100  sound_pressure_level = 0.0;
101  sound_frequency = 0.0;
102  sound_reflexion = 1.0;
104  dt_integrated = 0.0;
105  dB_Map_ready = 0;
106  // Parameterfilename as argument.
107  if (argc > 1) {
108  sprintf(filename, "%s", argv[1]);
109  start_file_reader(filename);
110  }
111 
112  if (argc == 1) {
113  printf("-TYCHO SIMULATION--\n");
114  printf("-Linux Version --\n");
115  printf("-V1.3.0 Oct. 2013--\n");
116  printf("-------------------\n");
117  printf("Please specify a\n");
118  printf("parameter File\n");
119  printf("-------------------\n");
120  exit(11);
121  }
122 
123  // restart logic
124  if (argc == 3) {
125  restart = 1;
126  printf("---------------This is a TYCHO Simulation--------------\n");
127  printf("---------------------Linux Version --------------------\n");
128  printf("---------------Version 1.3.0 released Oct. 2013--------\n");
129  printf("The code will restart from last checkpoint\n");
130  }
131 
132  /*
133  Output on the standardout at programme start
134  */
135  printf("---------------This is a TYCHO Simulation--------------\n");
136  printf("---------------------Linux ----------------------------\n");
137  printf("---------------Version 1.3.0 released Oct. 2013--------\n");
138  printf("The resolution of the simulation is\n%i %i %i\n", x, y, z);
139  printf("The domain extend in meter in x,y and z is\n%g %g %g\n", xmax,
140  ymax, zmax);
141  //to avoid zero time steps
142  if ((xmax == 0.0) && (xmax == 0.0) && (zmax == 0.0)) {
143  printf("Attention the extend of your computational domain is a singularity!\n");
144  printf("We better stop.\n");
145  exit(0);
146  }
147  printf("Your boundary conditions are\n%i %i %i %i %i %i\n",
149  printf("Your simulation endtime in minutes is\n%g\n", endtime_sim / minute_in_sec);
150  if (gravity_on_off == 0) printf("Gravity is off\n");
151  if (gravity_on_off == 1) printf("Gravity is on\n");
152  if (wind_on_off == 1) printf("A wind marker file will be processed\n");
153  if (with_obstacles == 0) printf("No Obstacles within computational domain\n");
154  if (with_sound_emitter == 1) printf("With sound emitter\n");
155  if (with_one_pulse == 1) printf("With a single sound-shock emitted\n");
156  if (advection == 1) printf("A marker field will be advected with the HYDRO solution\n");
157  if (viscosity_on_off == 1) printf("Viscosity is switched on\n");
158  if (obstacle_heat_conductivity != 0.0) printf("Heat Diffusion is switched on\n");
159 #ifdef _OPENMP
160  printf("You are using %i threads in parallel\n", number_of_threads);
161 #endif
162  printf("-------------------------------------------------------\n");
163 
164  //To get output on the standard out
165  fflush(stdout);
166 
167 #ifdef _OPENMP
168  // Sets the number of threads specified in the parameter-file.
169  omp_set_num_threads(number_of_threads);
170 #endif
171 
172  // Get the maximum number of cells in all three dimension.
173  tmp1 = max_array(x, y);
174  max_array_length = max_array(tmp1, z);
175 
176  // The minimum and maximum index of the cells without ghost cells.
177  nminx = 6;
178  nmaxx = nminx + x - 1;
179  nminy = 6;
180  nmaxy = nminy + y - 1;
181  nminz = 6;
182  nmaxz = nminz + z - 1;
183 
184  //Cell Volume
185  if (dimension == 3) cell_volume = (xmax / x)*(ymax / y)*(zmax / z);
186  //Cell Area
187  if (dimension == 2) cell_volume = (xmax / x)*(ymax / y);
188  //Cell length
189  if (dimension == 1) cell_volume = (xmax / x);
190 
191  // Let's start the simulation at the beginning of time.
192  time_sim = 0;
193 
194  // If Gravitational acceleration the famous constant is defined here.
195  if (gravity_on_off == 1) {
196  grav_acc = -9.81;
197  } else {
198  grav_acc = 0.0;
199  }
200 
201  // Gamma for gas physics.
202  Gamma = Gamma1 - 1.0;
203 
204  // Small numbers of error handling.
205  small = 1.0E-50;
206  smallr = 1.0E-50;
207  smallp = 1.0E-50;
208 
209  //C1_visc and S_visc constant for determine the viscosity with Sutherland's law
210  C1_visc = 1.456E-6;
211  S_visc = 110.4;
212 
213  // The point of origin.
214  xmin = 0;
215  ymin = 0;
216  zmin = 0;
217 
218  counter = 0;
219  counter_restart = 0;
220 
221  //
222  intial_soundspeed = 0.0;
223 
224  // Dynamic allocation for global variables and arrays.
226 
227  //To get output on the standard out
228  fflush(stdout);
229 
230  // Initiate variables for the hydro solver.
231  initiate_grid(x, xmin, xmax, y, ymin, ymax, z, zmin, zmax);
232 
233  //To get output on the standard out
234  fflush(stdout);
235 
236  // Make Initial Conditions or read the from a file in or read only the obstacle domain.
237  if (restart == 0) {
238 
239  if (advection == 1) {
240  read_marker_file(x, y, z);
241  initiate_domain_marker(x, y, z);
242  }
243 
244  if (wind_on_off == 1) {
245  read_wind_file(x, y, z);
246  }
247 
248  if (make_ics == 0) make_ic(x, y, z);
249  if (make_ics == 1) read_ic(x, y, z);
250  if (make_ics == 2) {
251  make_ic(x, y, z);
252  read_dom(x, y, z);
253  }
254  if (make_ics == 3) make_sod_ic(x, y, z);
255  if (make_ics == 4) make_kh_instabilities(x, y, z);
256 
257  // Initiate variables for the computational domain if obstacles are involved.
258  if ((with_obstacles == 1) && (make_ics == 0)) initiate_domain(x, y, z);
259  if ((with_obstacles == 1) && (make_ics == 2)) initiate_domain_dom(x, y, z);
260 
261  //read in the sound emitter file
262  if (with_sound_emitter == 1) read_soundemitter(x, y, z);
263 
264  // The initial conditions are written into files.
265  if ((filetype == 0) && ((make_ics == 0) || (make_ics == 2) || (make_ics == 3) || (make_ics == 4))) write_ic_tyc(x, y, z);
266  if ((filetype == 1) && ((make_ics == 0) || (make_ics == 2) || (make_ics == 3) || (make_ics == 4))) write_ic_vtk(x, y, z);
267  if ((filetype == 2) && ((make_ics == 0) || (make_ics == 2) || (make_ics == 3) || (make_ics == 4))) write_ic_amira(x, y, z);
268  if ((filetype == 3) && ((make_ics == 0) || (make_ics == 2) || (make_ics == 3) || (make_ics == 4))) write_ic_ifrit(x, y, z);
269 
270  }
271 
272  if (restart == 1) {
273 
274  read_restart(x, y, z);
275  printf("Restart files are read.\n");
276 
277 
278  //To get output on the standard out
279  fflush(stdout);
280  }
281 
282  // Here the actual hydro solver starts.
283  // calculate a first time-step
284  dt_calc_first(x, y, z);
285 
286  //In the case of a harmonic soundemitter, we have to calculate a new extend,
287  //because of the frequency 100 cells per lambda is quite okay
288  //if the extent of the computational domain is large enough this given extend
289  //will not be changed
290  //if just one soundpulse is emitted (i.e. a weak shock), this is not necessary
291  if ((with_sound_emitter == 1) && (with_one_pulse == 0)) {
292 
293  double x_max_new, y_max_new, z_max_new;
294 
295  x_max_new = xmax;
296  y_max_new = ymax;
297  z_max_new = zmax;
298 
299  double wavelength_divisor = 100.0;
300  x_max_new = (intial_soundspeed / sound_frequency) / wavelength_divisor * x;
301  if (dimension > 1) y_max_new = (intial_soundspeed / sound_frequency) / wavelength_divisor * y;
302  if (dimension > 2) z_max_new = (intial_soundspeed / sound_frequency) / wavelength_divisor * z;
303 
304  if ((x_max_new < xmax) || (y_max_new < ymax) || (z_max_new < zmax)) {
305  xmax = x_max_new;
306  ymax = y_max_new;
307  zmax = z_max_new;
308  printf("New extend due to harmonic soundsource\nextend in x-direction: %g\nextend in y-direction: %g\nextend in z-direction: %g\n", xmax, ymax, zmax);
309  printf("Intial_soundspeed %g [m/s]\n", intial_soundspeed);
310  printf("-------------------------------------------------------\n");
311 
312  dt_calc_first(x, y, z);
313  }
314  }
315 
316  printf("The beginning time-step: %g [s]\n", dt);
317  printf("-------------------------------------------------------\n");
318 
319  //To get output on the standard out
320  fflush(stdout);
321 
322  // For the shock detection we set the variable shock_or_not to zero.
323  shock_or_not = 0;
324 
325  //the present pressure are copied into the pre_old array
326  if ((with_sound_emitter == 1) && (restart == 0)) reset_pressure_integrated(x, y, z);
327  if (with_sound_emitter == 1) pre_old_copy(x, y, z);
328  if (with_sound_emitter == 1) noise_generator(x, y, z);
329  // For performance analysis issues.
330  cputime_sim1 = clock();
331 #ifdef _OPENMP
332  cputime_sim1 = omp_get_wtime();
333 #endif
334 
335  // The main Hydro loop, which runs until counter is smaller then a certain integer.
336  do {
337 
338  // For performance analysis issues.
339  cputime_sim1_eta = clock();
340 #ifdef _OPENMP
341  cputime_sim1_eta = omp_get_wtime();
342 #endif
343 
344  //Noise source, i.e. periodic pressure changes
345  if (with_sound_emitter == 1) noise_generator(x, y, z);
346 
347  //the present pressure are coped into the pre_old array
348  if (with_sound_emitter == 1) pre_old_copy(x, y, z);
349 
350  // The time-step is now copied to the old time-step.
351  olddt = dt;
352 
353  // The time-step due to the CFL criteria is determined.
354  dt_calc(x, y, z);
355 
356  // the arrays where the pressure on the solid is stored
357  // are reseted here
358  pressure_on_solid_reset(x, y, z);
359 
360  /*
361  The Hydro Sweeps forward: In 1D only in x, in 2D in x and y, and
362  finally in 3D in the x,y and z direction.
363  */
364  hydro_sweeps(x, y, z, 0);
365 
366  //if heat diffusion is set on
367  if (obstacle_heat_conductivity != 0.0) diffusion(x, y, z);
368 
369  //Noise source, i.e. periodic pressure changes
370  if (with_sound_emitter == 1) noise_generator(x, y, z);
371 
372  //the present pressure are coped into the pre_old array
373  if (with_sound_emitter == 1) pre_old_copy(x, y, z);
374  // The time-step due to the CFL criteria is determined.
375  dt_calc(x, y, z);
376 
377  // the arrays where the pressure on the solid is stored
378  // are reseted here
379  pressure_on_solid_reset(x, y, z);
380 
381  /*
382  The Hydro Sweeps backward: In 1D only in x, in 2D in x and y, and
383  finally in 3D in the x,y and z direction.
384  */
385  hydro_sweeps(x, y, z, 1);
386 
387  // if heat diffusion is set on
388  if (obstacle_heat_conductivity != 0.0) diffusion(x, y, z);
389 
390  // Velocity Field Analyser
391  velocity_field_analyser(x, y, z);
392 
393  //Noise source, i.e. periodic pressure changes
394  if (with_sound_emitter == 1) noise_generator(x, y, z);
395 
396  //the present pressure are coped into the pre_old array
397  if (with_sound_emitter == 1) pre_old_copy(x, y, z);
398 
399  // Calculate the total pressure on the solid in the computational domain.
400  if (with_obstacles == 1) pressure_on_solid_calc(x, y, z);
401 
402  // What time is it?
403  time_sim = time_sim + 2 * dt;
404 
405  // For performance analysis issues.
406  cputime_sim2_eta = clock();
407 #ifdef _OPENMP
408  cputime_sim2_eta = omp_get_wtime();
409 #endif
410 
411  seconds_eta = (cputime_sim2_eta - cputime_sim1_eta) / (double) CLOCKS_PER_SEC;
412  seconds_eta /= 2.0;
413 
414 #ifdef _OPENMP
415  seconds_eta = (cputime_sim2_eta - cputime_sim1_eta);
416  seconds_eta /= 2.0;
417 #endif
418  //check if we have to reset the pressure_integrated array
419  //and store the stuff in the dba-map;
420  dt_integrated += dt;
421 
422  if ((dt_integrated >= 1.0 / sound_frequency) && (with_sound_emitter == 1) && (with_one_pulse == 0)) {
423 
424  //make a db map;
425  prepare_the_dB_map(x, y, z);
426  //reset stuff for the generation of the next dB map
427  dt_integrated = 0.0;
428  reset_pressure_integrated(x, y, z);
429  }
430 
431  if ((with_sound_emitter == 1) && (with_one_pulse == 1)) {
432  //make a db map;
433  prepare_the_dB_map(x, y, z);
434  }
435 
436  // Write output files at a given frequency
438  if (filetype == 0) write_tyc(x, y, z, counter);
439  if (filetype == 1) write_vtk(x, y, z, counter);
440  if (filetype == 2) write_amira(x, y, z, counter);
441  if (filetype == 3) write_ifrit(x, y, z, counter);
442 
443  // For performance analysis issues.
444  cputime_sim2 = clock();
445 #ifdef _OPENMP
446  cputime_sim2 = omp_get_wtime();
447 #endif
448 
449  seconds = (cputime_sim2 - cputime_sim1) / (double) CLOCKS_PER_SEC;
450 
451 #ifdef _OPENMP
452  seconds = (cputime_sim2 - cputime_sim1);
453 #endif
454 
455  printf("%3.1f percent done\n", 100.0 / (float) endtime_sim * (float) time_sim);
456  printf("time:%g [s], dt:%g [s]\nshock:%i\ncounter:%i\n", time_sim, dt, shock_or_not, counter);
457 
458  if (counter > 0) {
459  if ((((endtime_sim - time_sim) / dt) * seconds_eta) < 60.0) {
460  printf("Estimated time to simulation end: %4.2f seconds\n", ((endtime_sim - time_sim) / dt) * seconds_eta);
461  }
462  if (((((endtime_sim - time_sim) / dt) * seconds_eta) > 60.0) && (((((endtime_sim - time_sim) / dt) * seconds_eta) <= 3600.0))) {
463  printf("Estimated time to simulation end: %4.2f minutes\n", ((endtime_sim - time_sim) / dt) * seconds_eta / 60.0);
464  }
465  if (((((endtime_sim - time_sim) / dt) * seconds_eta) > 3600.0) && ((((endtime_sim - time_sim) / dt) * seconds_eta) <= 3600.0 * 24.0)) {
466  printf("Estimated time to simulation end: %5.2f hours\n", ((endtime_sim - time_sim) / dt) * seconds_eta / 3600.0);
467  }
468  if ((((endtime_sim - time_sim) / dt) * seconds_eta) > 3600.0 * 24.0) {
469  printf("Estimated time to simulation end: %5.2f days\n", ((endtime_sim - time_sim) / dt) * seconds_eta / (3600.0 * 24.0));
470  }
471  if (seconds < 60.0) printf("Time since last output: %4.2g [s]\n", seconds);
472  if ((seconds > 60.0) && (seconds < 3600)) printf("Time since last output: %4.2g [min]\n", seconds / 60.0);
473  if (seconds > 3600.0) printf("Time since last output: %4.2g [h]\n", seconds / 3600.0);
474  }
475  printf("-------------------------------------------------------\n");
476 
477  if (time_sim > restart_frequency * counter_restart) {
478  if (filetype != 0) {
479  write_restart_tyc(x, y, z);
480  printf("Restart files are written.\n");
481  counter_restart++;
482  }
483  }
484 
485  counter++;
486 
487  //To get output on the standard out
488  fflush(stdout);
489  // For performance analysis issues.
490 
491  cputime_sim1 = clock();
492 #ifdef _OPENMP
493  cputime_sim1 = omp_get_wtime();
494 #endif
495  }
496 
497 
498  } while (time_sim <= endtime_sim);
499 
500  printf("\n--------------------------");
501  printf("\n--------------------------\n");
502  printf("Program aborted normally\n");
503  printf("End-time of simulation reached\n");
504  printf("\n--------------------------");
505  printf("\n--------------------------\n");
506 
507  return 0;
508 }