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