1 /*============================================================================
2 * Main program
3 *============================================================================*/
4
5 /*
6 This file is part of Code_Saturne, a general-purpose CFD tool.
7
8 Copyright (C) 1998-2021 EDF S.A.
9
10 This program is free software; you can redistribute it and/or modify it under
11 the terms of the GNU General Public License as published by the Free Software
12 Foundation; either version 2 of the License, or (at your option) any later
13 version.
14
15 This program is distributed in the hope that it will be useful, but WITHOUT
16 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
18 details.
19
20 You should have received a copy of the GNU General Public License along with
21 this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
22 Street, Fifth Floor, Boston, MA 02110-1301, USA.
23 */
24
25 /*----------------------------------------------------------------------------*/
26
27 #include "cs_defs.h"
28
29 /*----------------------------------------------------------------------------
30 * Standard C library headers
31 *----------------------------------------------------------------------------*/
32
33 #include <errno.h>
34 #include <locale.h>
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <string.h>
38
39 /*----------------------------------------------------------------------------
40 * Local headers
41 *----------------------------------------------------------------------------*/
42
43 #include "bft_mem.h"
44 #include "bft_printf.h"
45
46 #include "cs_ale.h"
47 #include "cs_atmo.h"
48 #include "cs_all_to_all.h"
49 #include "cs_base.h"
50 #include "cs_base_cuda.h"
51 #include "cs_base_fortran.h"
52 #include "cs_benchmark.h"
53 #include "cs_boundary_zone.h"
54 #include "cs_calcium.h"
55 #include "cs_cdo_main.h"
56 #include "cs_cell_to_vertex.h"
57 #include "cs_control.h"
58 #include "cs_coupling.h"
59 #include "cs_ctwr.h"
60 #include "cs_domain_setup.h"
61 #include "cs_ext_library_info.h"
62 #include "cs_fan.h"
63 #include "cs_field.h"
64 #include "cs_field_pointer.h"
65 #include "cs_file.h"
66 #include "cs_fp_exception.h"
67 #include "cs_gradient.h"
68 #include "cs_gui.h"
69 #include "cs_gui_boundary_conditions.h"
70 #include "cs_gui_conjugate_heat_transfer.h"
71 #include "cs_gui_mesh.h"
72 #include "cs_gui_mobile_mesh.h"
73 #include "cs_gui_output.h"
74 #include "cs_gui_particles.h"
75 #include "cs_gui_radiative_transfer.h"
76 #include "cs_gui_util.h"
77 #include "cs_io.h"
78 #include "cs_join.h"
79 #include "cs_lagr.h"
80 #include "cs_lagr_tracking.h"
81 #include "cs_les_inflow.h"
82 #include "cs_log.h"
83 #include "cs_log_setup.h"
84 #include "cs_log_iteration.h"
85 #include "cs_matrix_default.h"
86 #include "cs_mesh.h"
87 #include "cs_mesh_adjacencies.h"
88 #include "cs_mesh_coherency.h"
89 #include "cs_mesh_location.h"
90 #include "cs_mesh_quality.h"
91 #include "cs_mesh_quantities.h"
92 #include "cs_mesh_bad_cells.h"
93 #include "cs_mesh_smoother.h"
94 #include "cs_notebook.h"
95 #include "cs_opts.h"
96 #include "cs_param_cdo.h"
97 #include "cs_paramedmem_coupling.h"
98 #include "cs_parameters.h"
99 #include "cs_physical_properties.h"
100 #include "cs_post.h"
101 #include "cs_post_default.h"
102 #include "cs_preprocess.h"
103 #include "cs_preprocessor_data.h"
104 #include "cs_probe.h"
105 #include "cs_property.h"
106 #include "cs_prototypes.h"
107 #include "cs_random.h"
108 #include "cs_restart.h"
109 #include "cs_restart_map.h"
110 #include "cs_runaway_check.h"
111 #include "cs_sles.h"
112 #include "cs_sles_default.h"
113 #include "cs_sat_coupling.h"
114 #include "cs_syr_coupling.h"
115 #include "cs_system_info.h"
116 #include "cs_time_moment.h"
117 #include "cs_timer.h"
118 #include "cs_timer_stats.h"
119 #include "cs_tree.h"
120 #include "cs_turbomachinery.h"
121 #include "cs_utilities.h"
122 #include "cs_volume_mass_injection.h"
123 #include "cs_volume_zone.h"
124
125 #if defined(HAVE_CUDA)
126 #endif
127
128 /*----------------------------------------------------------------------------*/
129
130 BEGIN_C_DECLS
131
132 /*! \cond DOXYGEN_SHOULD_SKIP_THIS */
133
134 /*=============================================================================
135 * Local Macro definitions
136 *============================================================================*/
137
138 /*============================================================================
139 * Public function prototypes
140 *============================================================================*/
141
142 /*============================================================================
143 * Static global variables
144 *============================================================================*/
145
146 static cs_opts_t opts;
147
148 /*============================================================================
149 * Private function definitions
150 *============================================================================*/
151
152 /*! (DOXYGEN_SHOULD_SKIP_THIS) \endcond */
153
154 /*============================================================================
155 * Public function definitions
156 *============================================================================*/
157
158 /*----------------------------------------------------------------------------
159 * Main function for Code_Saturne run.
160 *
161 * This function is called by main().
162 *----------------------------------------------------------------------------*/
163
164 static void
_run(void)165 _run(void)
166 {
167 int ivoset = 0;
168
169 int check_mask = 0;
170 cs_halo_type_t halo_type = CS_HALO_STANDARD;
171
172 /* System information */
173
174 #if defined(HAVE_MPI)
175 cs_system_info(cs_glob_mpi_comm);
176 #else
177 cs_system_info();
178 #endif
179 cs_ext_library_info();
180
181 #if defined(HAVE_CUDA)
182 cs_base_cuda_select_default_device();
183 #endif
184
185 cs_timer_stats_initialize();
186 cs_timer_stats_define_defaults();
187
188 if (cs_glob_tree == NULL)
189 cs_glob_tree = cs_tree_node_create(NULL);
190
191 cs_gui_parallel_io();
192 if (cs_glob_n_ranks > 1)
193 cs_user_parallel_io();
194 cs_file_defaults_info();
195
196 cs_gui_mpi_algorithms();
197
198 bft_printf("\n");
199
200 cs_base_update_status("initializing\n");
201
202 /* Initialize random number generator
203 (used in only some cases, but safe to do, and inexpensive) */
204
205 cs_random_seed(cs_glob_rank_id + 1);
206
207 /* Initialize global structures for main mesh */
208
209 cs_mesh_location_initialize();
210 cs_glob_mesh = cs_mesh_create();
211 cs_glob_mesh_builder = cs_mesh_builder_create();
212 cs_glob_mesh_quantities = cs_mesh_quantities_create();
213 cs_boundary_zone_initialize();
214 cs_volume_zone_initialize();
215
216 cs_preprocess_mesh_define();
217
218 cs_turbomachinery_define();
219
220 /* Check if an internally generated cartesian mesh is used */
221 if (cs_gui_mesh_build_cartesian())
222 cs_gui_mesh_cartesian_define();
223
224 cs_user_mesh_cartesian_define();
225
226 /* Call main calculation initialization function or help */
227
228 cs_io_log_initialize();
229
230 cs_field_define_keys_base();
231 cs_parameters_define_field_keys();
232
233 cs_sles_initialize();
234 cs_sles_set_default_verbosity(cs_sles_default_get_verbosity);
235
236 cs_preprocessor_data_read_headers(cs_glob_mesh,
237 cs_glob_mesh_builder);
238
239 cs_gui_zones();
240 cs_user_zones();
241
242 /* Create a new structure for the computational domain */
243 cs_glob_domain = cs_domain_create();
244
245 /* Define MPI-based Couplings if applicable */
246
247 cs_gui_syrthes_coupling();
248 cs_user_syrthes_coupling();
249 cs_user_saturne_coupling();
250
251 /* Initialize Fortran API and calculation setup */
252
253 if ((opts.preprocess | opts.verif) == false && opts.benchmark <= 0) {
254
255 int _rank_id = cs_glob_rank_id, _n_ranks = cs_glob_n_ranks;
256
257 cs_base_fortran_bft_printf_to_f();
258
259 const char default_restart_mesh[] = "restart_mesh_input";
260 if (cs_file_isreg(default_restart_mesh))
261 cs_restart_map_set_mesh_input(default_restart_mesh);
262
263 CS_PROCF(csinit, CSINIT)(&_rank_id, &_n_ranks);
264
265 CS_PROCF(initi1, INITI1)();
266
267 CS_PROCF (haltyp, HALTYP) (&ivoset);
268 if (ivoset)
269 halo_type = CS_HALO_EXTENDED;
270
271 if (cs_glob_ale > 0) {
272 cs_gui_mobile_mesh_get_boundaries(cs_glob_domain);
273 if (cs_glob_mesh->time_dep < CS_MESH_TRANSIENT_COORDS)
274 cs_glob_mesh->time_dep = CS_MESH_TRANSIENT_COORDS;
275 }
276
277 cs_cdo_initialize_setup(cs_glob_domain);
278
279 /* Setup linear solvers */
280 cs_gui_linear_solvers();
281 cs_user_linear_solvers();
282
283 cs_base_fortran_bft_printf_to_c();
284
285 cs_ctwr_build_zones();
286
287 cs_timer_stats_set_start_time(cs_glob_time_step->nt_cur);
288
289 }
290 else if (opts.verif)
291 halo_type = CS_HALO_EXTENDED;
292
293 /* Discover applications visible through MPI (requires communication);
294 this is done after main calculation initialization so that the user
295 may have the option of assigning a name to this instance. */
296
297 #if defined(HAVE_MPI)
298 cs_coupling_discover_mpi_apps(opts.app_name, NULL);
299 #endif
300
301 if (opts.app_name != NULL)
302 BFT_FREE(opts.app_name);
303
304 /* Initialize couplings and communication if necessary */
305
306 cs_syr_coupling_all_init();
307 cs_sat_coupling_all_init();
308
309 cs_paramedmem_coupling_all_init();
310
311 /* Initialize main post-processing */
312
313 cs_gui_postprocess_writers();
314 cs_user_postprocess_writers();
315 cs_post_init_writers();
316
317 cs_gui_postprocess_meshes();
318 cs_user_postprocess_meshes();
319 cs_user_postprocess_probes();
320
321 /* Print info on fields and associated keys and other setup options */
322
323 if (opts.verif == false && opts.preprocess == false && opts.benchmark <= 0)
324 cs_log_setup();
325
326 /* Preprocess mesh */
327
328 cs_preprocess_mesh(halo_type);
329 cs_mesh_adjacencies_initialize();
330
331 /* Initialization for turbomachinery computations */
332
333 cs_turbomachinery_initialize();
334
335 /* Initialization of internal coupling */
336
337 cs_internal_coupling_initialize();
338
339 cs_internal_coupling_dump();
340
341 /* Initialize meshes for the main post-processing */
342
343 check_mask = ((opts.preprocess | opts.verif) == true) ? 2 + 1 : 0;
344
345 cs_post_init_meshes(check_mask);
346
347 cs_user_mesh_modify_partial(cs_glob_mesh,
348 cs_glob_mesh_quantities);
349
350 /* Compute iterations or quality criteria depending on verification options */
351
352 if (opts.verif == true) {
353 bft_printf(_("\n Computing quality criteria\n"));
354 cs_mesh_quality(cs_glob_mesh, cs_glob_mesh_quantities);
355 cs_mesh_coherency_check();
356 cs_mesh_bad_cells_postprocess(cs_glob_mesh, cs_glob_mesh_quantities);
357 }
358 else if (opts.preprocess == true)
359 cs_mesh_coherency_check();
360
361 if (opts.benchmark > 0) {
362 int mpi_trace_mode = (opts.benchmark == 2) ? 1 : 0;
363 cs_benchmark(mpi_trace_mode);
364 }
365
366 if (check_mask && cs_syr_coupling_n_couplings())
367 bft_error(__FILE__, __LINE__, 0,
368 _("Coupling with SYRTHES is not possible in mesh preprocessing\n"
369 "or verification mode."));
370
371 if (opts.preprocess == false && opts.benchmark <= 0) {
372
373 /* Check that mesh seems valid */
374
375 cs_mesh_quantities_check_vol(cs_glob_mesh,
376 cs_glob_mesh_quantities,
377 (opts.verif ? 1 : 0));
378
379 cs_mesh_adjacencies_update_mesh();
380
381 #if defined(HAVE_ACCEL)
382 cs_preprocess_mesh_update_device(cs_alloc_mode);
383 #endif
384
385 /* Initialization related to CDO/HHO schemes */
386
387 cs_cdo_initialize_structures(cs_glob_domain,
388 cs_glob_mesh,
389 cs_glob_mesh_quantities);
390
391 /* Initialize gradient computation */
392
393 cs_gradient_initialize();
394
395 if (opts.verif == false) {
396
397 /* Initialize sparse linear systems resolution */
398
399 cs_user_matrix_tuning();
400
401 cs_matrix_initialize();
402
403 /* Update Fortran mesh sizes and quantities */
404
405 cs_base_fortran_bft_printf_to_f();
406 cs_preprocess_mesh_update_fortran();
407
408 /* Choose between standard and user solver */
409
410 if (cs_user_solver_set() == 0) {
411
412 if (cs_domain_get_cdo_mode(cs_glob_domain) == CS_DOMAIN_CDO_MODE_ONLY) {
413
414 /* Only C language is called within CDO */
415
416 cs_base_fortran_bft_printf_to_c();
417
418 /*----------------------------------------------
419 * Call main calculation function (CDO Kernel)
420 *----------------------------------------------*/
421
422 cs_cdo_main(cs_glob_domain);
423
424 /* Return to the default behavior */
425
426 cs_base_fortran_bft_printf_to_f();
427
428 }
429 else {
430
431 /* Additional initializations required by some models */
432
433 cs_fan_build_all(cs_glob_mesh, cs_glob_mesh_quantities);
434
435 cs_ctwr_build_all();
436
437 cs_volume_mass_injection_flag_zones();
438
439 /* Setup couplings and fixed-mesh postprocessing */
440
441 cs_syr_coupling_init_meshes();
442
443 cs_paramedmem_coupling_define_mesh_fields();
444
445 cs_post_default_write_meshes();
446
447 cs_turbomachinery_restart_mesh();
448
449 /*----------------------------------------------
450 * Call main calculation function (code Kernel)
451 *----------------------------------------------*/
452
453 CS_PROCF(caltri, CALTRI)();
454
455 }
456
457 }
458 else {
459
460 /*--------------------------------
461 * Call user calculation function
462 *--------------------------------*/
463
464 cs_user_solver(cs_glob_mesh,
465 cs_glob_mesh_quantities);
466
467 }
468
469 }
470
471 /* Finalize gradient computation */
472
473 cs_gradient_finalize();
474
475 /* Finalize synthetic inlet condition generation */
476
477 cs_les_inflow_finalize();
478
479 }
480
481 /* Finalize linear system resolution */
482
483 cs_sles_default_finalize();
484
485 /* Finalize sparse linear systems resolution */
486
487 cs_matrix_finalize();
488
489 /* Finalize user extra operations */
490 if (opts.verif == false)
491 cs_user_extra_operations_finalize(cs_glob_domain);
492
493 /* Switch logging back to C (may be moved depending on Fortran dependencies) */
494
495 cs_base_fortran_bft_printf_to_c();
496
497 bft_printf(_("\n Destroying structures and ending computation\n"));
498 bft_printf_flush();
499
500 /* Final stage for CDO/HHO schemes */
501
502 cs_cdo_finalize(cs_glob_domain);
503
504 /* Free cs_domain_structure */
505
506 cs_domain_free(&cs_glob_domain);
507
508 /* Free coupling-related data */
509
510 cs_syr_coupling_all_finalize();
511 #if defined(HAVE_MPI)
512 cs_sat_coupling_all_finalize();
513 cs_paramedmem_coupling_all_finalize();
514 cs_coupling_finalize();
515 #endif
516
517 cs_control_finalize();
518
519 /* Free remapping/intersector related structures (stl or medcoupling) */
520 cs_utilities_destroy_all_remapping();
521
522 /* Free the checkpoint multiwriter structure */
523 cs_restart_multiwriters_destroy_all();
524
525 /* Print some mesh statistics */
526
527 cs_gui_usage_log();
528 cs_mesh_selector_stats(cs_glob_mesh);
529
530 /* Finalizations related to some models */
531
532 cs_atmo_finalize();
533 cs_ctwr_all_destroy();
534 cs_fan_destroy_all();
535
536 /* Free internal coupling */
537
538 cs_internal_coupling_finalize();
539
540 /* Free memory related to properties */
541
542 cs_property_destroy_all();
543 cs_thermal_table_finalize();
544
545 /* Free turbomachinery related structures */
546
547 cs_turbomachinery_finalize();
548 cs_join_finalize();
549
550 /* Free post processing or logging related structures */
551
552 cs_probe_finalize();
553 cs_post_finalize();
554 cs_log_iteration_destroy_all();
555
556 /* Free moments info */
557
558 cs_time_moment_destroy_all();
559
560 /* Free field info */
561
562 cs_gui_radiative_transfers_finalize();
563 cs_gui_finalize();
564
565 cs_notebook_destroy_all();
566
567 cs_field_pointer_destroy_all();
568 cs_field_destroy_all();
569 cs_field_destroy_all_keys();
570
571 /* Free Lagrangian related structures */
572
573 cs_lagr_finalize();
574
575 /* Free main mesh after printing some statistics */
576
577 cs_cell_to_vertex_free();
578 cs_mesh_adjacencies_finalize();
579
580 cs_boundary_zone_finalize();
581 cs_volume_zone_finalize();
582 cs_mesh_location_finalize();
583 cs_mesh_quantities_destroy(cs_glob_mesh_quantities);
584 cs_mesh_destroy(cs_glob_mesh);
585
586 /* Free parameters tree info */
587
588 cs_tree_node_free(&cs_glob_tree);
589
590 /* CPU times and memory management finalization */
591
592 cs_all_to_all_log_finalize();
593 cs_io_log_finalize();
594
595 cs_timer_stats_finalize();
596
597 cs_file_free_defaults();
598
599 cs_base_time_summary();
600
601 #if defined(HAVE_ACCEL)
602 int n_alloc_hd_remain = cs_get_n_allocations_hd();
603 if (n_alloc_hd_remain > 0)
604 bft_printf(_("Warning: %d remaining host-device allocations\n"
605 " (possible memory leak)\n"), n_alloc_hd_remain);
606 #endif
607
608 cs_base_mem_finalize();
609
610 cs_log_printf_flush(CS_LOG_N_TYPES);
611
612 cs_runaway_check_finalize();
613 }
614
615 /*============================================================================
616 * Main program
617 *============================================================================*/
618
619 int
main(int argc,char * argv[])620 main(int argc,
621 char *argv[])
622 {
623 /* Initialize wall clock timer */
624
625 (void)cs_timer_wtime();
626
627 /* First analysis of the command line to determine if MPI is required,
628 and MPI initialization if it is. */
629
630 #if defined(HAVE_MPI)
631 cs_base_mpi_init(&argc, &argv);
632 #endif
633
634 #if defined(HAVE_OPENMP) /* Determine default number of OpenMP threads */
635 {
636 int t_id;
637 #pragma omp parallel private(t_id)
638 {
639 t_id = omp_get_thread_num();
640 if (t_id == 0)
641 cs_glob_n_threads = omp_get_max_threads();
642 }
643 }
644 #endif
645
646 /* Default initialization */
647
648 #if defined(_CS_ARCH_Linux)
649
650 if (getenv("LANG") != NULL)
651 setlocale(LC_ALL,"");
652 else
653 setlocale(LC_ALL, "C");
654 setlocale(LC_NUMERIC, "C");
655
656 #endif
657
658 /* Trap floating-point exceptions on most systems */
659
660 #if defined(DEBUG)
661 cs_fp_exception_enable_trap();
662 #endif
663
664 /* Initialize memory management */
665
666 cs_base_mem_init();
667
668 /* Initialize internationalization */
669
670 #if defined(ENABLE_NLS)
671 bindtextdomain(PACKAGE, cs_base_get_localedir());
672 textdomain(PACKAGE);
673 #endif
674
675 /* Parse command line */
676
677 cs_opts_define(argc, argv, &opts);
678
679 /* Initialize error handling */
680
681 cs_base_error_init(opts.sig_defaults);
682
683 /* Open 'run_solver.log' (log) files */
684
685 cs_base_trace_set(opts.trace);
686 cs_base_fortran_bft_printf_set("run_solver", opts.logrp);
687
688 /* Log-file header and command line arguments recap */
689
690 cs_base_logfile_head(argc, argv);
691
692 /* Load setup parameters if present */
693
694 const char s_param[] = "setup.xml";
695 if (cs_file_isreg(s_param)) {
696 cs_gui_load_file(s_param);
697 cs_notebook_load_from_file();
698 }
699
700 /* Call main run() method */
701
702 _run();
703
704 /* Return */
705
706 cs_exit(EXIT_SUCCESS);
707
708 /* Never called, but avoids compiler warning */
709 return 0;
710 }
711
712 /*----------------------------------------------------------------------------*/
713
714 END_C_DECLS
715