/*-----------------------------------------------------------------------

                         SYRTHES version 4.3
                         -------------------

     This file is part of the SYRTHES Kernel, element of the
     thermal code SYRTHES.

     Copyright (C) 2009 EDF S.A., France

     contact: syrthes-support@edf.fr


     The SYRTHES Kernel is free software; you can redistribute it
     and/or modify it under the terms of the GNU General Public License
     as published by the Free Software Foundation; either version 2 of
     the License, or (at your option) any later version.

     The SYRTHES Kernel is distributed in the hope that it will be
     useful, but WITHOUT ANY WARRANTY; without even the implied warranty
     of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.


     You should have received a copy of the GNU General Public License
     along with the SYRTHES Kernel; if not, write to the
     Free Software Foundation, Inc.,
     51 Franklin St, Fifth Floor,
     Boston, MA  02110-1301  USA

-----------------------------------------------------------------------*/

# include <stdio.h>
# include <stdlib.h>
# include <math.h>
# include <string.h>
# include <assert.h>

# include "syr_usertype.h"
# include "syr_bd.h"
# include "syr_hmt_libmat.h"
# include "syr_hmt_bd.h"
# include "syr_parall.h"
# include "syr_tree.h"
# include "syr_abs.h"
# include "syr_const.h"
# include "syr_proto.h"
# include "syr_hmt_proto.h"

# include "syr_cfd.h"
#ifdef _SYRTHES_CFD_
# include "ple_coupling.h"
#endif

#ifdef _SYRTHES_MPI_
# include <mpi.h>
MPI_Status status;
#endif

struct Performances perfo;
struct Affichages affich;

int lray=0; /* =1 si au moins 1 proc fait du rayt */
int lhumid; /* =1 si les transferts couples sont actifs */
int lmst=0;
int ecraddfile;   /* ecriture ou non de fichiers additionnels (calque sur les sorties chrono) */
int user_stop=0;  /* pour generer un arret premature mais propre du code */ 

extern char nomresu[CHLONG],nomresuc[CHLONG];
extern char nomresur[CHLONG],nomresucr[CHLONG];
extern char nomadd[CHLONG],nomflu[CHLONG];

extern FILE  *fdata,*fadd;
FILE *fresu,*fchro,*fresur,*fchror,*fhisto,*fflu;
FILE *fresucplcfd,*fchrocplcfd;

extern struct Cfd cfd;


/*|======================================================================|
  | SYRTHES 4.3                                       COPYRIGHT EDF 2009 |
  |======================================================================|
  | AUTEURS  : I. RUPP, C. PENIGUEL                                      |
  |======================================================================|
  |  Programme principal                                                 |
  |======================================================================| */

void syrthes(int rang_deb,int nbproc_ray)
{         
  
  int i,n,nex,nemax,exist_myfile,ecrit;
  int un=1,deux=2;
  struct Maillage maillnodes;
  struct MaillageCL maillnodeus;
  struct MaillageCL maillnoderc;
  struct MaillageBord maillnodebord;
  int nelray_orig;

  struct Clim diric,flux,echang,rayinf;
  struct Contact rescon;
  struct Cvol *fluxvol;
  struct Variable variable;
  /* isa  double **tmpsa,**tmps,**tmpmax,**tmpmin;*/


  struct Couple scoupr,rcoups;
  struct Cperio perio;
  struct Prophy physol;

  struct Histo histos;
  struct PasDeTemps pasdetemps;
  struct GestionFichiers gestionfichiers;
  struct Bilan bilansurf,bilanvol,bilansolaire;
  struct Matrice matr;

  struct Travail trav,trave;
  double tcpud,tcpu1,tcpu2;
  double tchroso=0,thisso=0;

  /* pour les couplages surfacique et volumiques CFD */
  struct Climcfd scoupf,scouvf;

  struct Maillage maillnodray;
  double *tmpray;
  double **radios;
  struct FacForme ***listefdf;  /* facteurs de forme (sauf Fii)   listefdf[nbprocray][nbfacloc][numenface]  */
  double *diagfdf;             /* diagonale de la matrice des facteurs de forme */
  struct ProphyRay phyray;
  double **firay,*trayeq,*erayeq,**epropr;
  struct Clim fimpray,timpray;
  struct SymPer raysymper;
  struct Compconnexe volconnexe;
  struct PropInfini propinf;
  struct MatriceRay matrray;

  struct SDparall sdparall;
  struct SDparall_ray sdparall_ray;

  struct Mask mask;
  struct Horizon horiz;
  struct Vitre vitre;
  struct Meteo meteo;
  struct Myfile myfile;

  /* humidite */
  /* -------- */
  struct ConstPhyhmt constphyhmt;
  struct ConstMateriaux *constmateriaux;
  struct Humid humid;
  struct HmtClimhhh hmtclimhhh;
  double **var_ele;


  struct Mst mst;

  double *x,*br,*xm1,*gd,*res,*z,*di,*resm1;

  struct Soleil soleil;
  struct Lieu lieu;
  struct node *arbre_solaire;
  double size_min_solaire,dim_boite_solaire[6];

  char c,chi[5],chn[20];
  int rc,cv;
  FILE *fstop;
  int ok;


  /*======================= Parallelisme ==============================================*/
  /*===================================================================================*/
  
  syrthes_initsdparall(&sdparall,&sdparall_ray);

#ifdef _SYRTHES_MPI_
  syrthes_initmpi(rang_deb,&sdparall);
  sdparall.request=(MPI_Request*)malloc(2*syrglob_nparts*sizeof(MPI_Request));
#endif

  /*======================= Gestion des affichages du code ============================*/
  /*===================================================================================*/
  
  affich.cond_creemaill= 0;    /* affichage des maillages crees (maillnodeus,aretes)   */
  affich.cond_mat=       0;    /* affichage coeff des matrices conduction       */
  affich.cond_clim=      0;    /* affichage des conditions aux limites          */
  affich.cond_prophy=    0;    /* affichage des proprietes physiques            */
  affich.cond_perio=     0;    /* affichage des infos periodicite               */
  affich.cond_rescon=    0;    /* affichage des infos resistances de contact    */

  affich.ray_mem_devel=  0;    /* affichage memoire pour calcul des fdf         */
  affich.ray_mem_user=   0;
  affich.ray_resray=     0;
  affich.ray_fi2teq=     0;
  affich.ray_orient=     0;
  affich.ray_fdf=        0;
  affich.ray_soleil=     0;
  affich.ray_extrbord=   0;

  affich.correspFS=      0;    /* affichage correspondants fluide/solide        */
  affich.correspSR=      0;    /* affichage correspondants solide/rayonnement   */
  affich.passageSR=      0;    /* affichage des tansferts solide/rayonnement    */

  affich.cfd=            0;    /* affichage des infos de couplage avec la CFD   */

  affich.mst=            0;    /* affichage des tansferts solide/rayonnement    */

  affich.maill_parall=   0;    /* affichages des infos de maillage complementaires */

 

  /*======================= Init pour calcul des performances =========================*/
  /*===================================================================================*/
  perfo.cpu_deb=cpusyrt();
  perfo.mem_max=perfo.mem_cond_max=perfo.mem_cond_max=0;
  perfo.mem_ray=perfo.mem_ray_max=0;

  perfo.cpu_iter_soleil=perfo.cpu_iter_ray=perfo.cpu_iter_cond=0;


  /*=================================== Head of listing ===============================*/
  /*===================================================================================*/
  pasdetemps.lstops=0;
  if (syrglob_nparts==1 ||syrglob_rang==0)
    syrban(un);


  /*======== Reading key-words to initialize dimensions ===============================*/
  /*===================================================================================*/

  lire_firstdata(&variable,&maillnodes,&gestionfichiers,&pasdetemps,&humid,&meteo);
  fflush(stdout);

  if (syrglob_nparts==1 ||syrglob_rang==0)
    {	    
      printf("\n"); for (i=0;i<90;i++) printf("="); 
      if (SYRTHES_LANG == FR) {printf("\n INITIALISATIONS POUR LA CONDUCTION\n"); 
	                         printf(" =================================\n"); }
      else if (SYRTHES_LANG == EN)  {printf("\n CONDUCTION INITIALIZATIONS\n"); 
                                       printf(" ==========================\n"); }
    }

  /*============ Allocations of arrays depending on number of variables ===============*/
  /*===================================================================================*/

  alloue_nbvar(gestionfichiers.champmax,humid,&variable,&fluxvol);

  /*=========================== Basic Initializations =================================*/
  /*===================================================================================*/

  touta0(&maillnodes,&maillnodebord,&maillnodeus,
	 &diric,&perio,
	 &flux,&echang,&rescon,&rayinf,fluxvol,
	 &scoupr,&rcoups,&hmtclimhhh);
  fflush(stdout);


  /*=========================== Ecriture initiale de l'entete du fichier additionnel===*/
  /*===================================================================================*/

  /* Writing head of additional file */
  ecraddfile=ecrire_chrono(0,gestionfichiers,pasdetemps,maillnodes,maillnodebord,variable,
			   maillnodray,phyray,tmpray,firay,sdparall_ray,
			   humid,constphyhmt,constmateriaux,scoupf,cfd,trav,trave);

  /* on a calcule la frequence d'ecriture du fichier additionnel,
     mais on ecrit toujours l'enete pour l'avoir dans les initialisations */
  ecrire_entete(&fadd,nomadd,pasdetemps.ntsyr,pasdetemps.rdtts,pasdetemps.tempss);
  
  fflush(fadd);
  fflush(stdout);

  /*=========================== Reading data ==========================================*/
  /*===================================================================================*/
  

  /* mesh */
  /* ---- */
  lire_maill(&maillnodes,&maillnodebord,&sdparall);
  fflush(stdout);

  alloue_tvar(maillnodes.npoin,&variable);

  /* data */
  /* ---- */
  lire_donnees(maillnodes,&variable,&physol,&histos,&bilansurf,&bilanvol,humid);
  fflush(stdout);


  /* radiation */
  /* --------- */
#ifdef _SYRTHES_MPI_  
  if (lray)  syrthes_initmpi_ray(nbproc_ray,sdparall,&sdparall_ray);
  fflush(stdout);
#endif

  nelray_orig=0;
  if (lray)  /* a appeler meme si le proc ne fait pas de ray ???? pas sur */
    {
      lire_donnees_ray(maillnodes,&maillnodray,&gestionfichiers,
		       &(phyray.bandespec),&propinf,
		       &mask,&soleil,&horiz,&vitre,&sdparall_ray);
      nelray_orig=maillnodray.nelem;
      fflush(stdout);
   }

  tcpu1=cpusyrt();
  perfo.cpu_lect=tcpu1-perfo.cpu_deb;


  /*============================== Specific files =====================================*/
  /*===================================================================================*/
  /* personal file */
  /* ------------- */
  /* premiere passe pour voir si il y a une lecture utilisateur d'un fichierperso */
  exist_myfile = user_read_myfile(&myfile);
  fflush(stdout);

  /* si l'utilisateur a programme la lecture d'un fichier perso */
  if (exist_myfile) user_read_myfile(&myfile);

    
  /* weather file */
  /* ------------ */
  if (meteo.actif){      /* si il faut lire un fichier standard */
    if (lray) lire_meteo(&meteo,phyray.bandespec.nb);
    else      lire_meteo(&meteo,1);
    fflush(stdout);
 }

  /*================= Boundary conditions initialization ==============================*/
  /*===================================================================================*/



  init_clim(&maillnodes,&maillnodebord,&maillnodeus,&maillnoderc,  
	    &diric,&perio,&flux,&echang,&rescon,&rayinf,fluxvol,
	    humid,&hmtclimhhh,
	    variable,sdparall);
  fflush(stdout);



  tcpu2=cpusyrt();
  perfo.cpu_init_cond=tcpu2-perfo.cpu_deb;


  /*========================== Radiation Initializations ==============================*/
  /*===================================================================================*/
  /* attention : a appeler meme si le proc ne fait pas de ray. C'est gere a l'interieur */
  if (lray) 
    {
 
      if (syrglob_nparts==1 ||syrglob_rang==0){	   
	printf("\n"); for (i=0;i<90;i++) printf("="); 
	if (SYRTHES_LANG == FR)  {printf("\n INITIALISATIONS POUR LE RAYONNEMENT\n"); 
	  printf(" ===================================\n"); }
	else if (SYRTHES_LANG == EN) {printf("\n RADIATION INITIALIZATIONS\n"); 
	  printf(" =========================\n"); }
	fflush(stdout);
      }
 
      tcpu1=cpusyrt();

      if (sdparall_ray.nparts>1) 
	init_radiation_parall(gestionfichiers,&maillnodray,maillnodes,maillnodebord,
			      maillnodeus,&listefdf,&diagfdf,&scoupr,&rcoups,
			      &volconnexe,&propinf,&fimpray,&timpray,
			      &phyray,&raysymper,&soleil,&bilansolaire,
			      &arbre_solaire,&size_min_solaire,dim_boite_solaire,
			      &lieu,meteo,&horiz,&vitre,&mask,
			      &tmpray,&radios,&firay,&trayeq,&erayeq,&epropr,
			      &sdparall_ray,sdparall);
      else
	init_radiation(gestionfichiers,&maillnodray,maillnodes,maillnodebord,
		       maillnodeus,&listefdf,&diagfdf,&scoupr,&rcoups,
		       &volconnexe,&propinf,&fimpray,&timpray,
		       &phyray,&raysymper,&soleil,&bilansolaire,
		       &arbre_solaire,&size_min_solaire,dim_boite_solaire,
		       &lieu,meteo,&horiz,&vitre,&mask,
		       &tmpray,&radios,&firay,&trayeq,&erayeq,&epropr,
		       &sdparall_ray,sdparall);


      fflush(stdout);
      tcpu2=cpusyrt();
      perfo.cpu_init_ray=tcpu2-tcpu1;
      
      if (syrglob_nparts==1 ||syrglob_rang==0){	    
	if (SYRTHES_LANG == FR)  {printf("\n ==> OK... Fin des initialisation pour le rayonnement\n"); }
	else if (SYRTHES_LANG == EN) {printf("\n ==> OK... End of radiation initializations\n");} 
	fflush(stdout);
      }

    }

  /*======================== HMT Initializations ======================================*/
  /*===================================================================================*/
  if (humid.actif){
    if (syrglob_nparts==1 ||syrglob_rang==0){	    
      printf("\n"); for (i=0;i<90;i++) printf("="); 
      if (SYRTHES_LANG == FR)  {printf("\n INITIALISATIONS POUR LES TRANSFERTS COUPLES\n"); 
 	                        printf(  " ===========================================\n"); }
      else if (SYRTHES_LANG == EN) {printf("\n HMT INITIALIZATIONS\n"); 
	                            printf(  " ===================\n"); }
      fflush(stdout);
    }
    hmt_init(maillnodes,&constphyhmt,&constmateriaux,&humid,&var_ele);
    fflush(stdout);

    if (syrglob_nparts==1 ||syrglob_rang==0){	    
      if (SYRTHES_LANG == FR)  {printf("\n ==> OK... Fin des initialisation pour les transferts couples\n"); }
      else if (SYRTHES_LANG == EN) {printf("\n ==> OK... End of HMT initializations\n");} 
      fflush(stdout);
      }
  }

  
  /*======================== Initialisations semi-transparent =========================*/
  /*===================================================================================*/
  if (lmst) 
    {
      decode_mst(maillnodes,&mst,sdparall);
      nummst(&mst,maillnodes);
      lire_limite_mst(&mst);
      inimst(&mst,maillnodes);
      fflush(stdout);
   }

  /*================== CFD coupling Initializations ===================================*/
  /*===================================================================================*/

  scoupf.exist=scoupf.existglob=0;
  scouvf.exist=scouvf.existglob=0;

#ifdef _SYRTHES_CFD_ 

  if (syrglob_nparts==1 ||syrglob_rang==0){	    
    if (SYRTHES_LANG == FR)  {printf("\n INITIALISATIONS DU COUPLAGE AVEC LA CFD\n"); 
                                printf(" =======================================\n"); }
    else if (SYRTHES_LANG == EN) {printf("\n CFD COUPLING INITIALIZATIONS\n"); 
                                    printf(" ============================\n"); }
    fflush(stdout);
  }
      
  cfd_init_couplage(sdparall, maillnodeus.ndim, &cfd);
  fflush(stdout);

  ok=0;
  if (cfd.coupl_surf) {
    scoupf.exist=ok=1;
    cfd_surf_init(maillnodes,maillnodeus,&scoupf,sdparall,&cfd);
    fflush(stdout);
 }
  MPI_Allreduce(&ok,&(scoupf.existglob),1,MPI_INT,MPI_SUM,sdparall.syrthes_comm_world);

  ok=0;
  if (cfd.coupl_vol) {
    scouvf.exist=ok=1;
    cfd_vol_init(maillnodes,&scouvf,sdparall,&cfd);
    fflush(stdout);
 }
  MPI_Allreduce(&ok,&(scouvf.existglob),1,MPI_INT,MPI_SUM,sdparall.syrthes_comm_world);

  cfd_synchro(&pasdetemps,cfd);
  fflush(stdout);

  if (syrglob_nparts==1 ||syrglob_rang==0){	    
    if (SYRTHES_LANG == FR)  {printf("\n ==> OK... Fin des initialisation pour le couplage CFD\n"); }
    else if (SYRTHES_LANG == EN) {printf("\n ==> OK... End of CFD coupling initializations\n");} 
    fflush(stdout);
  }

#endif 


  /*=============================== Initial Conditions ================================*/
  /*===================================================================================*/
  if (syrglob_nparts==1 ||syrglob_rang==0){	    
    printf("\n"); for (i=0;i<90;i++) printf("="); 
    if (SYRTHES_LANG == FR)  {printf("\n MISE EN PLACE DES CONDITIONS INITIALES\n"); 
                                printf(" ======================================\n"); }
    else if (SYRTHES_LANG == EN) {printf("\n SETTING INITIAL CONDITIONS\n"); 
                                    printf(" ==========================\n"); }
    fflush(stdout);
  }

  /* conditions initiales programmees */
  if (!humid.actif){
    user_cini_fct(maillnodes,variable.var[variable.adr_t]);
    user_cini(maillnodes,variable.var[variable.adr_t],&pasdetemps,meteo,myfile);
    fflush(stdout);
  }
  else{
    user_hmt_cini_fct(maillnodes,variable.var[variable.adr_t],
		      variable.var[variable.adr_pv],variable.var[variable.adr_pt]);
    user_hmt_cini(maillnodes,variable.var[variable.adr_t],
		  variable.var[variable.adr_pv],variable.var[variable.adr_pt],
		  humid,&pasdetemps,meteo,myfile);
    fflush(stdout);
  }

  /* lecture du fichier suite */
  if (pasdetemps.suite) lire_suite(maillnodes,&pasdetemps,&variable);
  fflush(stdout);

  /* initialisation des variables n-1 et n-2 */
  recopie(maillnodes.npoin,variable);


  if (!humid.actif){  /*  ??????????? a voir ce qu'il faut appeler en hmt */
    /* conditions physiques programmees */
    user_cphyso_fct(maillnodes,variable.var[variable.adr_t],physol,pasdetemps.tempss);
    user_cphyso    (maillnodes,variable.var[variable.adr_t],physol,&pasdetemps,meteo,myfile);
    fflush(stdout);
    
    verify_initial_cphy(maillnodes,physol);
    fflush(stdout);
   
    
    /* flux volumiques programmes */
    if (fluxvol[ADR_T].nelem) user_cfluvs_fct(maillnodes,variable.var[variable.adr_t],fluxvol[ADR_T],pasdetemps.tempss);
    user_cfluvs    (maillnodes,variable.var[variable.adr_t],fluxvol[ADR_T],&pasdetemps,meteo,myfile);
    fflush(stdout);
    if (fluxvol[ADR_T].nelem) verify_initial_cvol(maillnodes,fluxvol); 
    fflush(stdout);
 }
  
  else {
    if (fluxvol[ADR_T].nelem || fluxvol[ADR_PV].nelem || fluxvol[ADR_PT].nelem )
      user_hmt_cfluvs_fct(maillnodes,
			  variable.var[variable.adr_t_m1], fluxvol[ADR_T],
			  variable.var[variable.adr_pv_m1],fluxvol[ADR_PV],
			  variable.var[variable.adr_pt_m1],fluxvol[ADR_PT],
			  pasdetemps.tempss);
    
    user_hmt_cfluvs(maillnodes,
		    variable.var[variable.adr_t_m1], fluxvol[ADR_T],
		    variable.var[variable.adr_pv_m1],fluxvol[ADR_PV],
		    variable.var[variable.adr_pt_m1],fluxvol[ADR_PT],
		    &pasdetemps,humid,meteo,myfile);

    fflush(stdout);

    if (fluxvol[ADR_T].nelem || fluxvol[ADR_PV].nelem || fluxvol[ADR_PT].nelem )
      verify_initial_cvol(maillnodes,fluxvol); 

    if (syrglob_nparts==1 ||syrglob_rang==0){	    
      if (SYRTHES_LANG == FR)  {printf("\n ==> OK... Fin des conditions initiales\n"); }
      else if (SYRTHES_LANG == EN) {printf("\n ==> OK... End of initial conditions\n");} 
      fflush(stdout);
    }

 }

  /*========================== End of data initializations ============================*/
  fclose(fdata);


  /*=============================== General Allocations ===============================*/
  /*===================================================================================*/

  alloue_resol(lray,nelray_orig,variable.nbvar,
	       maillnodes,maillnodray,maillnodeus,
	       &matr,&matrray,physol,&trav,&trave);

 
/*   thisso  = (int)(pasdetemps.tempss/histos.freq) * histos.freq; */
/*   tchroso = (int)(pasdetemps.tempss/gestionfichiers.freq_chrono_s) * gestionfichiers.freq_chrono_s; */
  
 
  /*=============================== Min/max calculations ==============================*/
  /*===================================================================================*/

  if (syrglob_nparts==1 || syrglob_rang==0)
    {
      if (SYRTHES_LANG == FR) printf("\n *** extreme : Min/Max en debut de calcul\n");
      else if (SYRTHES_LANG == EN) printf("\n *** extreme : Min/Max at the beginning of the calculation\n");
    }
  calcul_extreme(pasdetemps.tempss,maillnodes,physol,variable,humid,sdparall);
  fflush(stdout);

  /* si besoin, ouverture du fichier de bilan */  
  if ( (syrglob_nparts==1 ||syrglob_rang==0)
       && (bilansurf.nb>0 || bilanvol.nb>0 || bilansolaire.nb>0) )
    {
      if ((fflu=fopen(nomflu,"w")) == NULL)
	{
	  if (SYRTHES_LANG == FR)
	    printf("Impossible d'ouvrir le fichier de donnees %s\n",nomflu);
	  else if (SYRTHES_LANG == EN)
	    printf("Impossible to open the data file %s\n",nomflu);
	  syrthes_exit(1) ;
	}
    }
  fflush(stdout);

  /*============ Fichier additionnel : gestion de l'entete  ===========================*/
  /*===================================================================================*/
 recale_file_fadd(&fadd);

  /*=============================== End of initializations ============================*/
  /*===================================================================================*/
  tcpu2=cpusyrt();
  perfo.cpu_init_tot=tcpu2-perfo.cpu_deb;

  if (syrglob_nparts==1 ||syrglob_rang==0)
    {	    
      if (SYRTHES_LANG == FR)
	{
	  printf("\n       >>>> Temps CPU :\n"); 
	  printf("              - lecture des donnees                 : %f \n",perfo.cpu_lect); 
	  printf("              - Initialisations pour la conduction  : %f \n",perfo.cpu_init_cond); 
	  printf("              - Initialisations pour le rayonnement : %f \n",perfo.cpu_init_ray); 
	  printf("              - Total                               : %f \n",perfo.cpu_init_tot); 
	  printf("            Memoire : \n");
	  printf("              - pour la conduction : %.3f Mo\n",perfo.mem_cond_max/1.e6);
	  if (lray)
	    printf("              - memoire necessaire pour  rayonnement   : %.3f Mo\n",perfo.mem_ray_max/1.e6);
	  printf("\n FIN DE LA PHASE D'INITIALISATION\n");
	  printf(" ================================\n");
	}
      else if (SYRTHES_LANG == EN)
	{
	  printf("\n       >>>> Temps CPU :\n"); 
	  printf("              - data reading               : %f \n",perfo.cpu_lect); 
	  printf("              - conduction initialisations : %f \n",perfo.cpu_init_cond); 
	  printf("              - radiation initialisations  : %f \n",perfo.cpu_init_ray); 
	  printf("              - Total                               : %f \n",perfo.cpu_init_tot); 
	  printf("            Memory : \n");
	  printf("              - for solving conduction     : %.3f Mo\n",perfo.mem_cond_max/1.e6);
	  if (lray)
	    printf("              - for solving radiation      : %.3f Mo\n",perfo.mem_ray_max/1.e6);
	  printf("\n END OF INITIALIZATION PHASE\n");
	  printf(" ===========================\n");
	}
    }
  fflush(stdout);

  /* =======================================================================
         I T E R A T I V E       S O L V E R 
     ======================================================================= */

  do
    {
                                            
      /* Updating Time
	 ============= */
      pasdetemps.ntsyr++;  pasdetemps.nbpaso++;
      pasdetemps.rdttsprec=pasdetemps.rdtts;
      
      if (pasdetemps.dtauto.actif || pasdetemps.dtmult.actif)
	caldtvar(&pasdetemps,maillnodes.npoin,
		 variable.var[variable.adr_t_m1],variable.var[variable.adr_t],sdparall);  /* ???? attention dt auto calcule sur la Temp */

      pasdetemps.tempss+=pasdetemps.rdtts;
     
      /* Writing flags
	 ============= */
      if (syrglob_nparts==1 || syrglob_rang==0)
	{
	  printf("\n *******************************************************************************************\n");

	  if (SYRTHES_LANG == FR){
	    if (pasdetemps.tempss<=3600)
	      printf(" ITERATION NTSYR=%7d -- TEMPS=%18.12e s -- dt=%18.12e\n",
		     pasdetemps.ntsyr,pasdetemps.tempss,pasdetemps.rdtts);
	    else if (pasdetemps.tempss>3600 && pasdetemps.tempss<=86400)
	      printf(" ITERATION NTSYR=%7d -- TEMPS=%18.12e s =%.2f heures -- dt=%18.12e\n",
		     pasdetemps.ntsyr,pasdetemps.tempss,pasdetemps.tempss/3600,pasdetemps.rdtts);
	    else if (pasdetemps.tempss>86400 && pasdetemps.tempss<=2678400)
	      printf(" ITERATION NTSYR=%7d -- TEMPS=%18.12e s =%.2f jours -- dt=%18.12e\n",
		     pasdetemps.ntsyr,pasdetemps.tempss,pasdetemps.tempss/3600/24,pasdetemps.rdtts);
	    else if (pasdetemps.tempss>2678400 && pasdetemps.tempss<=31536000)
	      printf(" ITERATION NTSYR=%7d -- TEMPS=%18.12e s =%.2f mois -- dt=%18.12e\n",
		     pasdetemps.ntsyr,pasdetemps.tempss,pasdetemps.tempss/3600/24/30.417,pasdetemps.rdtts);
	    else if (pasdetemps.tempss>31536000)
	      printf(" ITERATION NTSYR=%7d -- TEMPS=%18.12e s =%.2f annees -- dt=%18.12e\n",
		     pasdetemps.ntsyr,pasdetemps.tempss,pasdetemps.tempss/3600/24/365,pasdetemps.rdtts);
	  }
	  else if (SYRTHES_LANG == EN){
	    if (pasdetemps.tempss<=3600)
	      printf(" ITERATION NTSYR=%7d -- TIME=%18.12e s -- dt=%18.12e\n",
		     pasdetemps.ntsyr,pasdetemps.tempss,pasdetemps.rdtts);
	    else if (pasdetemps.tempss>3600 && pasdetemps.tempss<=86400)
	      printf(" ITERATION NTSYR=%7d -- TIME=%18.12e s =%.2f hours -- dt=%18.12e\n",
		     pasdetemps.ntsyr,pasdetemps.tempss,pasdetemps.tempss/3600,pasdetemps.rdtts);
	    else if (pasdetemps.tempss>86400 && pasdetemps.tempss<=2678400)
	      printf(" ITERATION NTSYR=%7d -- TIME=%18.12e s =%.2f days -- dt=%18.12e\n",
		     pasdetemps.ntsyr,pasdetemps.tempss,pasdetemps.tempss/3600/24,pasdetemps.rdtts);
	    else if (pasdetemps.tempss>2678400 && pasdetemps.tempss<=31536000)
	      printf(" ITERATION NTSYR=%7d -- TIME=%18.12e s =%.2f months -- dt=%18.12e\n",
		     pasdetemps.ntsyr,pasdetemps.tempss,pasdetemps.tempss/3600/24/30.417,pasdetemps.rdtts);
	    else if (pasdetemps.tempss>31536000)
	      printf(" ITERATION NTSYR=%7d -- TIME=%18.12e s =%.2f years -- dt=%18.12e\n",
		     pasdetemps.ntsyr,pasdetemps.tempss,pasdetemps.tempss/3600/24/365,pasdetemps.rdtts);
	  }
	  printf(" *******************************************************************************************\n");
	  fflush(stdout);
	}
      tcpud=cpusyrt();

      /* Writing head of additional file (if needed) */
      ecraddfile=ecrire_chrono(0,gestionfichiers,pasdetemps,maillnodes,maillnodebord,variable,
			       maillnodray,phyray,tmpray,firay,sdparall_ray,humid,constphyhmt,constmateriaux,
			       scoupf,cfd,
			       trav,trave);
      if(ecraddfile)  ecrire_entete(&fadd,nomadd,pasdetemps.ntsyr,pasdetemps.rdtts,pasdetemps.tempss);
      fflush(stdout);fflush(fadd);

      /*============================ Radiative solver =====================================*/
      /*===================================================================================*/
      if (lray) 

	{
	  if (syrglob_nparts==1 ||syrglob_rang==0)
	    {
	      if (SYRTHES_LANG == FR)      printf("\n  ---RESOLUTION DU SYSTEME RADIATIF---\n");
	      else if (SYRTHES_LANG == EN) printf("\n ---RADIATION SOLVER---\n");
	    }

	  radiation(&pasdetemps,gestionfichiers,maillnodes,maillnodray,maillnodeus,
		    variable.var[variable.adr_t],variable.var[variable.adr_t_m1],
		    scoupr,rcoups,listefdf,diagfdf,tmpray,
		    radios,firay,trayeq,erayeq,phyray,epropr,fimpray,&propinf,matrray,
		    &soleil,bilansolaire,lieu,meteo,myfile,
		    arbre_solaire,size_min_solaire,dim_boite_solaire,
		    volconnexe,horiz,vitre,trav,sdparall,sdparall_ray);

	  fflush(stdout);
	}

      if (lmst) resoumst(&mst,maillnodes,variable.var[variable.adr_t]);

      /*======================== CFD Coupling =============================================*/
      /*===================================================================================*/
#ifdef _SYRTHES_CFD_

      /* Echange fluide/solide */
      if (cfd.coupl_vol)  cfd_trans_vol (maillnodes,scouvf,variable.var[variable.adr_t],cfd);
      if (cfd.coupl_surf) cfd_trans_surf(maillnodes,maillnodeus,scoupf,
					 variable.var[variable.adr_t],cfd);
      fflush(stdout);
      
#endif

      /*========================== Conduction solver ======================================*/
      /*===================================================================================*/
      
      tcpu1=cpusyrt();

      if (!humid.actif)
	ressol(&pasdetemps,
               maillnodes,maillnodeus,maillnoderc,maillnodebord,  
	       diric,perio,scoupf,scouvf,flux,echang,
	       rescon,scoupr,rayinf,fluxvol[ADR_T],mst,
	       variable,physol,meteo,myfile,
	       matr,trav,trave,
	       sdparall);
      else
	hmt_resol(&pasdetemps, 
		  maillnodes,maillnodeus,maillnoderc,maillnodebord,  
		  perio,scoupf,scouvf,rescon,scoupr,rayinf,
		  hmtclimhhh,
		  fluxvol,mst,variable,var_ele,humid,
		  constphyhmt,constmateriaux,meteo,myfile,
		  matr,trav,trave,sdparall);
	
      fflush(stdout);

 
      /*=============================== Min/max calculation ===============================*/
      /*===================================================================================*/
      
      if (gestionfichiers.champmax)       
	{
	  calchampmax(maillnodes.npoin,variable.var[variable.adr_t],
		      variable.var[variable.adr_tmin],variable.var[variable.adr_tmax]);
	  if (variable.nbvar>1)
	    calchampmax(maillnodes.npoin,variable.var[variable.adr_pv],
			variable.var[variable.adr_pvmin],variable.var[variable.adr_pvmax]);
	  if (variable.nbvar>2)
	    calchampmax(maillnodes.npoin,variable.var[variable.adr_pt],
			variable.var[variable.adr_ptmin],variable.var[variable.adr_ptmax]);
	}

      calcul_extreme(pasdetemps.tempss,maillnodes,physol,variable,humid,sdparall);
      fflush(stdout);

      
      /*=============================== Calculs des bilans ================================*/
      /*===================================================================================*/

      if (bilansurf.nb) 
	bilsurf(maillnodes,maillnodeus,scoupf,flux,echang,
		rescon,scoupr,rayinf,hmtclimhhh,constphyhmt,
		variable,bilansurf,pasdetemps.tempss);
      fflush(stdout);

      
      if (bilanvol.nb) 
	bilvol(maillnodes,scouvf,fluxvol[ADR_T],
	       variable,bilanvol,pasdetemps.tempss,
	       humid,var_ele,constphyhmt,constmateriaux);

      fflush(stdout);

      
      /*=============================== Ecritures chrono ==================================*/
      /*===================================================================================*/

      if (gestionfichiers.freq_chrono){
	ecrit=ecrire_chrono(1,gestionfichiers,pasdetemps,maillnodes,maillnodebord,variable,
			    maillnodray,phyray,tmpray,firay,sdparall_ray,humid,constphyhmt,constmateriaux,
			    scoupf,cfd,trav,trave);
	if (gestionfichiers.champflux && ecrit) ecrire_flux(maillnodes,variable,physol);
	if (ecraddfile && ecrit) user_add_var_in_file(maillnodes,fluxvol,variable,physol,pasdetemps);
      }

      if (histos.actif) ecrire_histo(pasdetemps,maillnodes,histos,variable,
				     humid,constphyhmt,constmateriaux);
      fflush(stdout);

      
      /*==================================== CPU times  ===================================*/
      /*===================================================================================*/
      tcpu2=cpusyrt();
      perfo.cpu_1iter_cond=tcpu2-tcpu1;
      perfo.cpu_iter_cond+=perfo.cpu_1iter_cond;

      if (syrglob_nparts==1 ||syrglob_rang==0){
	if (SYRTHES_LANG == FR)
	  printf("\n  >>>> Temps de resolution : ");
	else if (SYRTHES_LANG == EN)
	  printf("\n  >>>> Solving CPU time : ");
      }
      
      if (lray && soleil.actif)
	{
	  if (syrglob_nparts==1 ||syrglob_rang==0)
	    if (SYRTHES_LANG == FR)
	      printf("%.2f s [cond: %.2f] [ray: %.2f] [solaire: %.2f] <<<<\n",
		     perfo.cpu_1iter_soleil+perfo.cpu_1iter_ray+perfo.cpu_1iter_cond,
		     perfo.cpu_1iter_cond,
		     perfo.cpu_1iter_ray,
		     perfo.cpu_1iter_soleil);
	    else if (SYRTHES_LANG == EN)
	      printf("%.2f s [cond: %.2f] [rad: %.2f] [solar: %.2f] <<<<\n",
		     perfo.cpu_1iter_soleil+perfo.cpu_1iter_ray+perfo.cpu_1iter_cond,
		     perfo.cpu_1iter_cond,
		     perfo.cpu_1iter_ray,
		     perfo.cpu_1iter_soleil);
	}
      else if (lray)
	{
	  if (syrglob_nparts==1 ||syrglob_rang==0)
	    if (SYRTHES_LANG == FR)
	      printf("%.2f s [cond: %.2f] [rad: %.2f] <<<<\n",
		     perfo.cpu_1iter_ray+perfo.cpu_1iter_cond,perfo.cpu_1iter_cond, perfo.cpu_1iter_ray);
	    else if (SYRTHES_LANG == EN)
	      printf("%.2f s [cond: %.2f] [rad: %.2f] <<<<\n",
		     perfo.cpu_1iter_ray+perfo.cpu_1iter_cond, perfo.cpu_1iter_cond,  perfo.cpu_1iter_ray);
	}
      else
	{
	  if (syrglob_nparts==1 ||syrglob_rang==0)
	    printf("%.2f s <<<<\n",perfo.cpu_1iter_cond);
	}

      fflush(stdout);
  /*=============================== Next time step ====================================*/
  /*===================================================================================*/

      pasdetemps.premier=pasdetemps.suiteprem=0;
	    
      if (pasdetemps.ntsyr==pasdetemps.ntsmax-1) pasdetemps.ldern=1;
      
      /* test d'arret premature du code */
      if ((fstop=fopen("syrthes.stop","r")) != NULL) pasdetemps.lstops=1;
    

#ifdef _SYRTHES_CFD_
      cfd_synchro(&pasdetemps,cfd);
#endif

      tcpu1=cpusyrt();
    }
  while (!pasdetemps.lstops && !user_stop && pasdetemps.ntsyr<pasdetemps.ntsmax);

/* =======================================================================
          E N D    O F     I T E R A T I O N              
   ======================================================================= */




  /*======================== Final results ============================================*/
  /*===================================================================================*/

  /* fichier resultat final */
  if (gestionfichiers.suppchampfinal==0){
    ecrire_resu(gestionfichiers,pasdetemps,maillnodes,variable,
		maillnodray,phyray,tmpray,firay,sdparall_ray,
		humid,constphyhmt,constmateriaux,scoupf,cfd,trav,trave);
    fclose(fresu);
#ifdef _SYRTHES_CFD_ 
    fclose(fresucplcfd);
#endif
  }

  if (lray && fresur) fclose(fresur);
  
  if (gestionfichiers.freq_chrono>0){
    if (fchro) fclose(fchro);
    if (lray && fchror) fclose(fchror);
#ifdef _SYRTHES_CFD_ 
    if (fchrocplcfd) fclose(fchrocplcfd);
#endif
  }    
  
  if ((syrglob_nparts==1 || syrglob_rang==0) && fflu) fclose(fflu);
  
  perfo.cpu_tot=cpusyrt()-perfo.cpu_deb;
  

  /* Closing files
     ~~~~~~~~~~~~~ */
  if (syrglob_nparts==1 ||syrglob_rang==0)
    {
      if (SYRTHES_LANG == FR)
	{
	  printf("\n\n ============================================================================\n"); 
	  
	  
	  printf("\n\n          ================================================\n");
	  printf("                       SYRTHES : BILAN DU CALCUL\n\n");
	  printf("                  CONDUCTION :  %9d PAS DE TEMPS\n",pasdetemps.nbpaso);
	  printf("                                %9d       NOEUDS\n",maillnodes.npoin);
	  printf("                                %9d     ELEMENTS\n",maillnodes.nelem);
	  if (lray)
	    {
	      printf("                 RAYONNEMENT :  %9d PAS DE TEMPS\n",pasdetemps.nbparay);
	      printf("                                %9d     FACETTES\n",maillnodray.nelem);
	    }
	  printf("          ================================================\n\n\n\n");
	  printf("     MEMOIRE (Mo)\n");
	  printf("     =======\n");
	  printf("     MEMOIRE NECESSAIRE POUR LA CONDUCTION . . . . . . %12.4f\n",perfo.mem_cond_max/1.e6);
	  if (lray)
	    printf("     MEMOIRE NECESSAIRE POUR LE RAYONNEMENT. . . . . . %12.4f\n",perfo.mem_ray_max/1.e6);
	  
	  printf("\n     TEMPS CPU (secondes)\n");
	  printf("     =========\n");
	  printf("     PHASE INITIALE POUR LA CONDUCTION . . . . . . . . %12.4f\n",fabs(perfo.cpu_init_cond));
	  printf("     RESOLUTION DE LA CONDUCTION . . . . . . . . . . . %12.4f\n",fabs(perfo.cpu_iter_cond));
	  if (lray)
	    {
	      printf("     PHASE INITIALE POUR LE RAYONNEMENT. . . . . . . . %12.4f\n",fabs(perfo.cpu_init_ray));
	      printf("     RESOLUTION DU RAYONNEMENT . . . . . . . . . . . . %12.4f\n",fabs(perfo.cpu_iter_ray));
	    }
	  printf("     T E M P S   T O T A L   . . . . . . . . . . . . . %12.4f\n",fabs(perfo.cpu_tot));
	  printf("     D U R E E S M O Y E N N E S\n");                       
	  printf("        - RESOLUTION DE LA CONDUCTION\n");                  
	  printf("                             par pas de temps  . .%12.4f\n",fabs(perfo.cpu_iter_cond)/pasdetemps.nbpaso);
	  if (lray)
	    {
	      printf("        - RESOLUTION DU RAYONNEMENT\n");              
	      printf("                             par pas de temps  . .%12.4f\n",fabs(perfo.cpu_iter_ray)/max(pasdetemps.nbparay,1)); 
	    }
	}
      else if (SYRTHES_LANG == EN)
	{
	  printf("\n\n ============================================================================\n"); 
	  
	  
	  printf("\n\n          ================================================\n");
	  printf("                       SYRTHES : CALCULATION SUMMARY\n\n");
	  printf("                  CONDUCTION :  %9d TIME STEP\n",pasdetemps.nbpaso);
	  printf("                                %9d       NODES\n",maillnodes.npoin);
	  printf("                                %9d     ELEMENTS\n",maillnodes.nelem);
	  if (lray)
	    {
	      printf("                 RADIATION :  %9d TIME STEP\n",pasdetemps.nbparay);
	      printf("                                %9d     FACES\n",maillnodray.nelem);
	    }
	  printf("          ================================================\n\n\n\n");
	  printf("     MEMORY (Mo)\n");
	  printf("     =======\n");
	  printf("     MEMORY REQUIRED FOR CONDUCTION . . . . . . %12.4f\n",perfo.mem_cond_max/1.e6);
	  if (lray)
	    printf("     MEMORY REQUIRED FOR RADIATION. . . . . . %12.4f\n",perfo.mem_ray_max/1.e6);
	  
	  printf("\n     CPU TIME (seconds)\n");
	  printf("     =========\n");
	  printf("     INITIAL PHASE FOR CONDUCTION . . . . . . . . %12.4f\n",fabs(perfo.cpu_init_cond));
	  printf("     SOLVING CONDUCTION . . . . . . . . . . . %12.4f\n",fabs(perfo.cpu_iter_cond));
	  if (lray)
	    {
	      printf("     INITIAL PHASE FOR RADIATION . . . . . . . . %12.4f\n",fabs(perfo.cpu_init_ray));
	      printf("     SOLVING RADIATION . . . . . . . . . . . . %12.4f\n",fabs(perfo.cpu_iter_ray));
	    }
	  printf("     T O T A L  C P U  T I M E  . . . . . . . . . . . . . %12.4f\n",fabs(perfo.cpu_tot));
	  printf("     A V E R A G E   C P U   T I M E\n");                       
	  printf("        - SOLVING CONDUCTION\n");                  
	  printf("                             for each time step  . .%12.4f\n",fabs(perfo.cpu_iter_cond)/pasdetemps.nbpaso);
	  if (lray)
	    {
	      printf("        - SOLVING RADIATION\n");              
	      printf("                             for each time step  . .%12.4f\n",fabs(perfo.cpu_iter_ray)/max(pasdetemps.nbparay,1)); 
	    }
	}
    }

  fflush(stdout);
  
  /* Banniere
     ~~~~~~~~ */
  /*  fclose(fgeom);*/
  fclose(fadd);
  if (syrglob_nparts==1 ||syrglob_rang==0)
    syrban(deux);

  fflush(stdout);

#ifdef _SYRTHES_MPI_
  if (syrglob_nparts>1)
    MPI_Barrier(sdparall.syrthes_comm_world);

  if (sdparall.syrthes_comm_world != MPI_COMM_NULL &&
      sdparall.syrthes_comm_world != MPI_COMM_WORLD)
    MPI_Comm_free(&(sdparall.syrthes_comm_world));
    
  
#endif

#ifdef _SYRTHES_CFD_
  cfd_fin(&cfd);
#endif

}  
/*|======================================================================|
  | SYRTHES 4.3                                       COPYRIGHT EDF 2009 |
  |======================================================================|
  | AUTEURS  : I. RUPP, C. PENIGUEL                                      |
  |======================================================================|
  |  MPI Initializations                                                 |
  |======================================================================| */
void syrthes_initsdparall(struct SDparall *sdparall,struct SDparall_ray *sdparall_ray)
{
  sdparall->rang=0;
  sdparall->nparts=1;

  sdparall_ray->rang=0;
  sdparall_ray->nparts=1;

  sdparall_ray->rangray=1;
  sdparall_ray->npartsray=1;
}

/*|======================================================================|
  | SYRTHES 4.3                                       COPYRIGHT EDF 2009 |
  |======================================================================|
  | AUTEURS  : I. RUPP, C. PENIGUEL                                      |
  |======================================================================|
  |  MPI Initializations                                                 |
  |======================================================================| */
#ifdef _SYRTHES_MPI_
void syrthes_initmpi(int rang_deb,struct SDparall *sdparall)
{
  int size_tot,w_rank,size,rank, flag;

  MPI_Comm_rank(MPI_COMM_WORLD, &w_rank);
  MPI_Comm_size(MPI_COMM_WORLD, &size_tot);

  /* Default initialization */

  sdparall->rang = w_rank;
  sdparall->nparts = size_tot;
  sdparall->syrthes_comm_world = MPI_COMM_WORLD;

#if defined(_SYRTHES_CFD_)
  if (cfd.do_coupling > 0) { /* Split MPI communicator */

    int  app_num;

    printf("\n  CFD Coupling detected: define a new MPI communicator\n");

    if (cfd.name == NULL) {

      if (cfd.app_num > -1) {

        char *app_name = NULL;
        
        app_name = (char *)malloc(2*sizeof(char));
        sprintf(app_name,"%d",cfd.app_num);
        app_name[1] = '\0';
        app_num = ple_coupling_mpi_name_to_id(MPI_COMM_WORLD, app_name);

        free(app_name);

      }
      else {
        printf("\n Error in syrthes_init_mpi()\n");
        printf("\n Cannot split mpi comminucator for code coupling\n");
        printf(" No app_name neither app_num is defined. Check command line\n");
        syrthes_exit(1);
      }

    }
    else
        app_num = ple_coupling_mpi_name_to_id(MPI_COMM_WORLD, cfd.name);

    if (cfd.name == NULL)
      printf("  App_num related to the current SYRTHES application: %d\n", app_num);
    else
      printf("  (App_name, App_num) related to the current SYRTHES application:"
             " (%s, %d)\n", cfd.name, app_num);

    MPI_Comm_split(MPI_COMM_WORLD, app_num, w_rank, &(sdparall->syrthes_comm_world));
    
    syr_cfd_coupling_mpi_init(cfd.name, sdparall->syrthes_comm_world);

  }
#endif /* End if _SYRTHES_CFD_ */

  MPI_Comm_rank(sdparall->syrthes_comm_world,&rank);
  MPI_Comm_size(sdparall->syrthes_comm_world,&size);

  sdparall->nparts = size;
  sdparall->rang = rank;

  /* Define a flag to know if we have to free MPI_COMM */
  flag = 0; /* Default: do not free mpi communicator */

  if (size == 1) {
#if defined(_SYRTHES_CFD_)
    if (cfd.do_coupling == 0)
      flag = 1;
#else
    flag = 1;
#endif /* End if _SYRTHES_CFD_ */
  }

  if (flag == 1) {

    /* SYRTHES is running in sequential but MPI is used with code coupling */
    if (sdparall->syrthes_comm_world != MPI_COMM_WORLD)
      MPI_Comm_free(&(sdparall->syrthes_comm_world));
    sdparall->syrthes_comm_world = MPI_COMM_NULL;

    printf("\n  Free MPI communicator. Not useful anymore.\n");

  }

  syrglob_comm_world = sdparall->syrthes_comm_world;
  syrglob_rang = rank;
  syrglob_nparts = size;

  printf("  End of MPI initialization\n\n");
}
#endif /* End _SYRTHES_MPI_ */

/*|======================================================================|
  | SYRTHES 4.3                                       COPYRIGHT EDF 2009 |
  |======================================================================|
  | AUTEURS  : I. RUPP, C. PENIGUEL                                      |
  |======================================================================|
  |  MPI Initializations for radiation                                   |
  |======================================================================| */
void syrthes_initmpi_ray(int nbproc_ray,
			 struct SDparall sdparall,
			 struct SDparall_ray *sdparall_ray)
{
  int i,size;
  int*       list_ranks;

#ifdef _SYRTHES_MPI_
  MPI_Group  group_syrthes_world;
  MPI_Group  group_syrthes_ray;
  MPI_Comm   syrthes_comm_ray;
#endif


  sdparall_ray->rang      = sdparall.rang;
  sdparall_ray->nparts    = sdparall.nparts;

  sdparall_ray->rangray   = sdparall.rang;
  sdparall_ray->npartsray = sdparall.nparts;


#ifdef _SYRTHES_MPI_

  /* s'il n'y a pas eu d'option -r, alors  nbproc_ray vaut -1 */
  /* --> on le met egal au nbre de proc conduction            */

  if (nbproc_ray<0) nbproc_ray = sdparall.nparts;

  /* meme nombre de proc en cond et ray */
  if (nbproc_ray == sdparall.nparts)
    {
      sdparall_ray->syrthes_comm_world = sdparall.syrthes_comm_world;
      sdparall_ray->syrthes_comm_ray   = sdparall.syrthes_comm_world;
    }
  else
    {
      sdparall_ray->npartsray = nbproc_ray;
      sdparall_ray->syrthes_comm_world = sdparall.syrthes_comm_world;


      /* Get the group underlying MPI_COMM_WORLD */
      MPI_Comm_group(sdparall.syrthes_comm_world, &group_syrthes_world);

      list_ranks = (int*) malloc(nbproc_ray*sizeof(int));
      for (i=0; i<nbproc_ray; i++) list_ranks[i] = i;
      
      /* Create the new group */
      MPI_Group_incl(group_syrthes_world, nbproc_ray, list_ranks,
		     &group_syrthes_ray);


      /* Create the new communicator */
      MPI_Comm_create(sdparall.syrthes_comm_world, group_syrthes_ray,
		      &(sdparall_ray->syrthes_comm_ray));

      if (sdparall_ray->rang < sdparall_ray->npartsray)
	MPI_Comm_rank(sdparall_ray->syrthes_comm_ray, &(sdparall_ray->rangray));
      else
	/* si le proc ne resoud pas le rayonnement, on met son rang a -1 */
	sdparall_ray->rangray=-1;
    }
#endif

}
/*|======================================================================|
  | SYRTHES 4.3                                       COPYRIGHT EDF 2009 |
  |======================================================================|
  | AUTEURS  : I. RUPP, C. PENIGUEL                                      |
  |======================================================================|
  |  Sortie en erreur                                                    |
  |======================================================================| */
void syrthes_exit(int status)
{

#ifdef _SYRTHES_MPI_
  MPI_Abort(syrglob_comm_world, status);
#endif

  exit(status);

}

