/*-----------------------------------------------------------------------

                         SYRTHES version 4.0
                         -------------------

     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 <string.h>
# include <math.h>

# include "post_usertype.h"
# include "post_bd.h"
# include "post_proto.h"

char nomgeom[200],nomresu[200],nomgeom_gene[200],nomresu_gene[200];
char nomtout[200],nomtoutg[200],nomtoutr[200];

#define max(a,b) (a>b  ? a:b)

/*|======================================================================|
  | SYRTHES 4.0                                       COPYRIGHT EDF 2009 |
  |======================================================================|
  | AUTEURS  : I. RUPP, C. PENIGUEL                                      |
  |======================================================================|
  | post_syrthes                                                         |
  |        Programme principal du post-processeur de SYRTHES parallele   |
  |======================================================================| */

main(argc,argv)
     rp_int argc;
     char *argv[];
{                                                                     
  FILE *fgeom,*fresu,*ftoutg,*ftoutr;
  FILE **ftabresu;

  char *s,ch1[200],chnum[6],*exten_geom,*exten_resu,*exten_chro,*exten_add;
  char nomg[200],nomr[200],ch[200],nomvar[30];
  rp_int numarg,typvar;
  rp_int geom=0,resu=0,chro=0,add=0,ecr_geom=1;

  rp_int n,nump_min,nump_max,np,npmax,nbdt,npart=0,numpart_deb=0;

  double *var,*toutvar;

  rp_int ntsyr,num_ele_deb,num_eleb_deb,npointot,nelemtot;
  double rdtts,tempss;

  struct Maillage maillnodes,maillnodebord,toutnodes,toutnodebord;
  struct SDparall *sdparall;

  rp_int ndiele;
  rp_int i,j,ok,nbvar;


  /* ----------------------------------------------------------------------------------------------- */
  /*      Interpretation de la ligne de commande                                                     */
  /* ----------------------------------------------------------------------------------------------- */

  s=(char*)malloc(10*sizeof(char));

  strcpy(nomtout,"all\0");

  if (argc==1)
    {
      if (SYRTHES_LANG == FR)
        {
	  printf("\n post_syrthes : post-processeur pour la version parallele de SYRTHES\n");
	  printf(" --> taper << post_syrthes -h >>  pour avoir des informations\n\n");
	}
      else if (SYRTHES_LANG == EN)
	{
	  printf("\n post_syrthes : post-processor for the parallel version of SYRTHES\n");
	  printf(" --> type << post_syrthes -h >>  for information\n\n");
	}
	exit(1);
    }

  numarg=0;
  while (++numarg < argc) {

    s = argv[numarg];

    if (strcmp (s, "-h") == 0) 
      {
	if (SYRTHES_LANG == FR)
	  {
	    printf("\n post_syrthes : post-processeur pour la version parallele de SYRTHES\n");
	    printf("                  reconstruction des resultats globaux\n\n");
	    printf("             Usage : post_syrthes [-h] -n nb_part  -m geom.syr  -r resu.res  -o complet\n");
	    printf("                        -h          : mode d'emploi\n\n");
	    printf("                        -n          : nombre de partitions a recoller\n\n");
	    printf("                        -g          : sans ecriture du fichier geometrique complet\n\n");
	    printf("                        -m geom.syr : nom generique des fihiers de maillage\n");
	    printf("                                       geom_part00000.syr\n");
	    printf("                                       geom_part00001.syr\n");
	    printf("                                           etc...\n");
	    printf("                        -r resu.res : nom generique des fihiers de resultats\n");
	    printf("                                           resu_part00000.res\n");
	    printf("                                           resu_part00001.res\n");
	    printf("                                           etc...\n");
	    printf("                        -o complet  : prefixe des fichiers resultats complets.\n");
	    printf("                                     creation des fichiers :\n");
	    printf("                                           complet.syr   (facultatif)\n");
	    printf("                                           complet.res\n\n");
	    printf("             Exemples :  a.out -n 2 -m geom.syr -r resu.res -o complet\n");
	  }
	else if (SYRTHES_LANG == EN)
	  {
	    printf("\n post_syrthes : post-processor for the parallel version of SYRTHES\n");
	    printf("                  reconstruction of the global results\n\n");
	    printf("             Usage : post_syrthes [-h] -n nb_part  -m geom.syr  -r resu.res  -o complet\n");
	    printf("                        -h          : help\n\n");
	    printf("                        -n          : number of partitions to be considered\n\n");
	    printf("                        -g          : without writing the global geometric file\n\n");
	    printf("                        -m geom.syr : generic geometric file name\n");
	    printf("                                       geom_part00000.syr\n");
	    printf("                                       geom_part00001.syr\n");
	    printf("                                           etc...\n");
	    printf("                        -r resu.res : generic result file name\n");
	    printf("                                           resu_part00000.res\n");
	    printf("                                           resu_part00001.res\n");
	    printf("                                           etc...\n");
	    printf("                        -o complet  : prefix for destination files\n");
	    printf("                                           complet.syr\n");
	    printf("                                           complet.res\n\n");
	    printf("             Examples :  a.out -n 2 -m geom.syr -r resu.res -o complet\n");
	  }

	exit(1);
      }
    else if (strcmp (s, "-n") == 0) 
      {
	s = argv[++numarg];
	npart=atoi(s);
      }
    else if (strcmp (s, "-g") == 0) 
      {
	s = argv[++numarg];
	ecr_geom=0;
      }
    else if (strcmp (s, "-m") == 0) 
      {
	s = argv[++numarg];
	strcpy(nomgeom,argv[numarg]);
	geom=1;
      }
    else if (strcmp (s, "-r") == 0) 
      {
	s = argv[++numarg];
	strcpy(nomresu,argv[numarg]);
	resu=1;
      }
    else if (strcmp (s, "-o") == 0) 
      {
	s = argv[++numarg];
	strcpy(nomtout,argv[numarg]);
      }

  }

  /* ------------------------------------------------------------------------ */
  /*                                  Banniere                                */
  /* ------------------------------------------------------------------------ */
  printf("    *****************************************************\n");
  printf("    *                                                   *\n");
  printf("    *   SSSS YY  YY RRRRR  TTTTTT HH   HH  EEEEE  SSSS  *\n");
  printf("    *   SS    YYYY  RR  RR   TT   HH   HH  EE     SS    *\n");
  printf("    *   SSS    YY   RRRRR    TT   HHHHHHH  EEE    SSS   *\n");
  printf("    *     SS   YY   RR  RR   TT   HH   HH  EE       SS  *\n");
  printf("    *   SSSS   YY   RR   RR  TT   HH   HH  EEEEE  SSSS  *\n");
  printf("    *                                                   *\n");
  printf("    *****************************************************\n");
  if (SYRTHES_LANG == FR)      
    printf("    *    POST-PROCESSEUR  POUR  TRAITEMENT  PARALLELE   * \n");
  else if (SYRTHES_LANG == EN) 
    printf("    *     POST-PROCESSOR  FOR  PARALLEL  COMPUTATION    * \n");
  printf("    *****************************************************\n\n\n");


  /* ------------------------------------------------------------------------ */
  /*                 gestion des fichiers                                     */
  /* ------------------------------------------------------------------------ */
  

  /* controles, initialisations */
  if (!npart){
    if (SYRTHES_LANG == FR){
      printf("Le nombre de partitions a concatener n'a pas ete indique\n");
      printf("--> utilisez l'option -n dans la ligne de commandes\n\n");
      exit(1);
    }
    else {
      printf("Number of partitions to process not defined\n");
      printf("--> option -n has to be used\n\n");
      exit(1);
    }
  }

  if (geom==0){
    if (SYRTHES_LANG == FR){
      printf("Les fichiers a post-traiter n'ont pas ete definis\n");
      printf("--> utilisez les options -m et -r dans la ligne de commandes\n\n");
      exit(1);
    }
    else {
      printf("Files to process not defined\n");
      printf("--> use option -m and/or -r \n\n");
      exit(1);
    }
  }

  /* controle de l'extension des noms de fichier */
  exten_geom=strstr(nomgeom,".syr");
  if (!exten_geom){
    if (SYRTHES_LANG == FR) printf("Le format du fichier geometrique n'est pas reconnu (.syr obligatoire) \n");
    else printf("Geometric file format unknown (.syr is required)\n");
  }
  /* noms des fichiers sans extension */
  strncpy(nomgeom_gene,nomgeom,strlen(nomgeom)-4); strcat(nomgeom_gene+strlen(nomgeom)-4,"\0"); 

  if (resu){
    exten_resu=strstr(nomresu,".res");
    exten_chro=strstr(nomresu,".rdt"); if (exten_chro) chro=1;
    exten_add=strstr(nomresu,".add"); if (exten_add) add=1;
    if (!exten_resu && !exten_chro && !exten_add){
      if (SYRTHES_LANG == FR) printf("Le format du fichier resultat n'est pas reconnu (.res ou .rdt ou .add obligatoire) \n");
      else printf("Result file format unknown (.res or .rdt or .add required)\n");
    }
    /* noms des fichiers sans extension */
    strncpy(nomresu_gene,nomresu,strlen(nomresu)-4); strcat(nomresu_gene+strlen(nomresu)-4,"\0");
  }


  /* ouverture/fermeture du fichier final pour verifier que tout est OK */
  if (ecr_geom)
    {
      strcpy(ch1,nomtout);
      strcat(ch1,".syr\0");
      if ((ftoutg=fopen(ch1,"w")) == NULL){
	if (SYRTHES_LANG == FR)       printf("Impossible d'ouvrir le fichier %s\n",ch1);
	else if (SYRTHES_LANG == EN)  printf("Impossible to open the file %s\n",ch1);
	exit(1) ;
      }
      fclose(ftoutg);
    }
  
  if (resu){
    strcpy(ch1,nomtout);
    if (chro) strcat(ch1,".rdt\0");
    else if (add) strcat(ch1,".add\0");
    else      strcat(ch1,".res\0");
    if ((ftoutr=fopen(ch1,"w")) == NULL){
      if (SYRTHES_LANG == FR)       printf("Impossible d'ouvrir le fichier %s\n",ch1);
      else if (SYRTHES_LANG == EN)  printf("Impossible to open the file %s\n",ch1);
      exit(1) ;
    }
  }

  /* ------------------------------------------------------------------------ */
  /*                        initialisations                                   */
  /* ------------------------------------------------------------------------ */


  /* il faudrait initialiser affich.*   */


  /* ------------------------------------------------------------------------ */
  /*              boucle sur les partitions                                   */
  /* ------------------------------------------------------------------------ */

  sdparall=(struct SDparall*)malloc(npart*sizeof(struct SDparall));
  for (n=0;n<npart;n++) 
    sdparall[n].nparts=npart;
 
  num_ele_deb=0;
  num_eleb_deb=0;

  if (SYRTHES_LANG == FR) printf("\n\nGeometrie \n------------\n");
  else if (SYRTHES_LANG == EN) printf("\n\nGeometry------------\n");
 

 for (n=0;n<npart;n++)  

    {
      sdparall[n].rang=n+numpart_deb;
      sprintf(chnum,"%05d",n+numpart_deb);

      /* ouverture du fichier geometrique */
      strcpy(nomg,"\0");
      strncpy(nomg,nomgeom_gene,strlen(nomgeom_gene)); strcpy(nomg+strlen(nomgeom_gene),"\0"); 
      strcat(nomg,"_part"); strncat(nomg,chnum,5); strcat(nomg,".syr");
      
      if ((fgeom=fopen(nomg,"r")) == NULL){
	if (SYRTHES_LANG == FR)       printf("Impossible d'ouvrir le fichier %s\n",nomg);
	else if (SYRTHES_LANG == EN)  printf("Impossible to open the file %s\n",nomg);
	exit(1) ;
      }
  
 
      if (SYRTHES_LANG == FR) printf("\n\nPartition %d\n",n+numpart_deb);
      else if (SYRTHES_LANG == EN) printf("\n\nPart    %d\n",n+numpart_deb);
    


      /* lecture du maillage */
      lire_syrthes(fgeom,&maillnodes,&maillnodebord,sdparall+n);


      /* recherche des nombres min et max en vue du dimensionnement */
      nump_max=post_cherche_max(maillnodes.npoin,sdparall[n])+1;
      nump_min=post_cherche_min(maillnodes.npoin,sdparall[n])+1;

      /* allocation des tableaux de maillage */
      post_alloue_tab(geom,resu,n,nump_max,maillnodes,maillnodebord,
		      &toutnodes,&toutnodebord);

      /* concatenation des donnees */
      post_concat(geom,resu,num_ele_deb,num_eleb_deb,maillnodes,maillnodebord,
		  toutnodes,toutnodebord,sdparall[n]);


      num_ele_deb+=maillnodes.nelem;
      num_eleb_deb+=maillnodebord.nelem;

      /* liberation des tableaux locaux */
      post_libere_tabmaill(&maillnodes,&maillnodebord); 

      
      fflush(stdout);
    }


  
  /* -------------------------------------------------------------------- */
  /* ecriture de la geometrie complete                                    */
  /* -------------------------------------------------------------------- */
  if (ecr_geom)
    {
      strcpy(ch1,nomtout);
      strcat(ch1,".syr\0");
      ecrire_geom(ch1,toutnodes,toutnodebord);
    }

  /* liberation des structures du maillage complet */
  for (n=0;n<toutnodes.ndim;n++) free(toutnodes.coord[n]);
  for (n=0;n<toutnodes.ndmat;n++) free(toutnodes.node[n]);
  free(toutnodes.nref);
  free(toutnodes.nrefe);




  /* -------------------------------------------------------------------- */
  /* traitement des fichiers resultats                                    */
  /* -------------------------------------------------------------------- */
  /* La numerotation globale est sauvegardee dans sdparall                */

  
  if (resu){      

    if (SYRTHES_LANG == FR){
      printf("\n\nTraitement des pas de temps... \n");
      printf("----------------------------------\n");
    }
    else if (SYRTHES_LANG == EN){
      printf("\n\nProcessing time steps...\n");
      printf("----------------------------\n");
    }
    
    /* nbre max d'element par part */
    for (n=0;n<npart;n++){
      np = max(sdparall[n].nbno_interne + sdparall[n].nbno_front, sdparall[n].nbele); 
      npmax=max(npmax,np);
    }
    var=(double*)malloc(npmax*sizeof(double));


    /* ouverture des fichiers */
    ftabresu = (FILE**)malloc(npart*sizeof(FILE*));
    for (n=0;n<npart;n++)
      {	
	sprintf(chnum,"%05d",n+numpart_deb);
	strncpy(nomr,nomresu_gene,strlen(nomresu_gene)); strcpy(nomr+strlen(nomresu_gene),"\0"); 
	strcat(nomr,"_part"); strncat(nomr,chnum,5); 
	if (chro)     strcat(nomr,".rdt");
	else if (add) strcat(nomr,".add");
	else          strcat(nomr,".res");
	
	if ((ftabresu[n]=fopen(nomr,"r")) == NULL){
	  if (SYRTHES_LANG == FR)      printf("Impossible d'ouvrir le fichier %s\n",nomr);
	  else if (SYRTHES_LANG == EN) printf("Impossible to open the file %s\n",nomr);
	  exit(1) ;
	}
      }

    /* lecture des resultats */
    
    nbdt=0;
    while (!feof(ftabresu[0]))
      {

	nbvar=0;

	do{
	  for (n=0;n<npart;n++)
	    {	
	      /* dans le cas ou on a teste s'il y a une var supplementaire, il y a une ligne d'entete en moins a lire */
	      if (nbdt>0 && nbvar==0 && n==0)  post_lire_entete_dt(ftabresu[n],&ntsyr,&rdtts,&tempss,2);
	      else if (nbvar==0)               post_lire_entete_dt(ftabresu[n],&ntsyr,&rdtts,&tempss,3);
	      
	      if (nbvar==0 || (nbvar>0 && n!=0)) ok=post_lire_entete_var(ftabresu[n],nomvar,&typvar);

	      if (n==0) {
		printf(" - Iteration SYRTHES %d - Variable %s\n",ntsyr,nomvar);

		if (typvar==2) toutvar=(double*)malloc(toutnodes.nelem*sizeof(double));
		else   	       toutvar=(double*)malloc(toutnodes.npoin*sizeof(double));
	      }

	      np = sdparall[n].nbno_interne + sdparall[n].nbno_front;
	      post_lire_var(ftabresu[n],np,var);
	      
	      post_concat_var(np,var,toutvar,sdparall[n]);
	    }
	  if (nbvar==0) ecrire_entete(ftoutr,ntsyr,rdtts,tempss);
	  if (typvar==2) ecrire_resu(ftoutr,toutnodes.nelem,toutvar,nomvar,typvar);
	  else           ecrire_resu(ftoutr,toutnodes.npoin,toutvar,nomvar,typvar);
	  
	  nbvar++;
	}while(post_lire_entete_var(ftabresu[0],nomvar,&typvar));
	
	nbdt++;
      }


  } /* fin du if resu */


  for (n=0;n<npart;n++) fclose(ftabresu[n]);
  fclose(ftoutr);
  
  free(var);
      
 


  printf("\n\n\n");
  printf("    *****************************************************\n");
  printf("    *                  S Y R T H E S                    *\n");
  printf("    *****************************************************\n");
  if (SYRTHES_LANG == FR)      
    printf("    *     FIN NORMALE DU POST-PROCESSING PARALLELE      *\n");
  else if (SYRTHES_LANG == EN) 
    printf("    *  END OF POST-PROCESSOR FOR PARALLEL COMPUTATION   * \n");
  printf("    *****************************************************\n\n");

  exit(0);
}  

