#!/usr/bin/perl
# cast2unv.pl         SOURCE    LC    03/07/03
#
# [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]
# CHAMPANEY Laurent  Universite de Versailles St Quentin le 03 / 07 / 03
# SANSOU Roody - DICOT Franck
#
# Transfert de fichiers maillage de CAST3M vers UNIVERSEL
#
#  Usage :
#    mode GUI :
#       cast2unv.pl 
#    mode ligne de commande  :
#       cast2unv.pl [-v][-h][-t][-s=S|P|M] nom
#  
#  lit nom.sauv et le converti en nom.unv en utilisant les infos
#   contenues dans nom.c2u
#
#  pour avoir des infos : cast2unv.pl -h
#
# ========================================================
#
#use strict "vars";
use Getopt::Long;
use Tk ;
use Tk::FileSelect ;
use Tk::ROText;
use File::Basename;
#
# Analyse des arguments
my @knownoptions = ("help|h",
                    "trid|t",
                    "shell|s=s",
                    "verbose|v");
GetOptions (@knownoptions) || exit ;
my $verb1 = 1;
if ($opt_verbose){$verb1=1};
my $trid1 = 0;
if ($opt_trid){$trid1=1};
if ($opt_help){sortie_usage(); exit();};


# Initialisations {{{
#
# Info generales
my $generic;
my $generic_ext;
my $line;
my $dime;
my $ifour;
# Les tableaux
my @noeuds;
my @points;
my @mail;
my %noms_mail;
my @mchaml;
my @chpo;
my @list_tabl;
my @list_pile;
my @liste_bord;
# Les Tableaux de correspondance
my @corresp_num_el;
# Les Tableaux de dimension
my @mail_tyel;
my @mail_nbel;
my @mail_nbno;
my @nb_comp_mchaml;
my @nb_comp_chpo;
# Initialisations     0    1    2    3    4    5    6
my @typ_el_cast = qw(POI0 POI1 SEG2 SEG3 TRI3 TRI4 TRI6 TRI7 QUA4 QUA5 QUA8 QUA9 RAC2 RAC3 CUB8 CU20 PRI6 PR15 LIA3 LIA4 LIA6 LIA8 MULT TET4 TE10 PYR5 PY13 ATTA SUPE RAP3 LIP6 LIP8 POLY CU27 PR21 TE15 PY19 SEG4 QU16 TR12 PR18 SEG6 TR21 QU36 C216 P126 TE56 PY91);
#
my $num_el_unv = 0;
#
# Correspondance elt cast3m/unv :  {{{
# 
my @corresp_typ_el;
# En axisymetrique
$corresp_typ_el[2][0] = 171; # SEG2 -> Axi Linear shell
$corresp_typ_el[3][0] = 172; # SEG2 -> Axi Parabolic shell
$corresp_typ_el[4][0] = 81;  # TRI3 -> Axi Solid Linear Triangle
$corresp_typ_el[6][0] = 82;  # TRI6 -> Axi Solid Parabolic Triangle
$corresp_typ_el[8][0] = 84;  # QUA4 -> Axi Solid Linear Quadrilateral
$corresp_typ_el[10][0]= 85;  # QUA8 -> Axi Solid Parabolic Quadrilateral
# En deformations planes
$corresp_typ_el[2][1] = 21;  # SEG2 -> Linear Beam
$corresp_typ_el[3][1] = 24;  # SEG3 -> Parabolic Beam
$corresp_typ_el[4][1] = 51;  # TRI3 -> Plain Strain Linear Triangle
$corresp_typ_el[6][1] = 52;  # TRI6 -> Plain Strain Parabolic Triangle
$corresp_typ_el[8][1] = 54;  # QUA4 -> Plain Strain Linear Quadrilateral
$corresp_typ_el[10][1]= 55;  # QUA8 -> Plain Strain Parabolic Quadrilateral
# En contraintes planes
$corresp_typ_el[2][2] = 21;  # SEG2 -> Linear Beam
$corresp_typ_el[3][2] = 24;  # SEG3 -> Parabolic Beam
$corresp_typ_el[4][2] = 41;  # TRI3 -> Plain Stress Linear Triangle
$corresp_typ_el[6][2] = 42;  # TRI6 -> Plain Stress Parabolic Triangle
$corresp_typ_el[8][2] = 44;  # QUA4 -> Plain Stress Linear Quadrilateral
$corresp_typ_el[10][2]= 45;  # QUA8 -> Plain Stress Parabolic Quadrilateral
# en 3D
$corresp_typ_el[2][3] = 21;  # SEG2 -> Linear Beam
$corresp_typ_el[3][3] = 24;  # SEG3 -> Parabolic Beam
$corresp_typ_el[4][3] = 91;  # TRI3 -> Thin Shell Linear Triangle
$corresp_typ_el[6][3] = 92;  # TRI6 -> Thin Shell Parabolic Triangle
$corresp_typ_el[8][3] = 94;  # QUA4 -> Thin Shell Linear Quadrilateral
$corresp_typ_el[10][3]= 95;  # QUA8 -> Thin Shell Parabolic Quadrilateral
$corresp_typ_el[14][3]= 115; # CUB8 -> Solid Linear Brick
$corresp_typ_el[15][3]= 116; # CU20 -> Solid Parabolic Brick
$corresp_typ_el[16][3]= 112; # PRI6 -> Solid Linear Wedge
$corresp_typ_el[17][3]= 113; # PR15 -> Solid Parabolic Wedge
$corresp_typ_el[23][3]= 111; # TET4 -> Solid Linear Tetrahedron
$corresp_typ_el[24][3]= 118; # TE10 -> Solid Parabolic Tetrahedron
# }}}
#
# Nom des elements unv {{{
my @unv_name;
$unv_name[21]  ="Linear Beam";
$unv_name[24]  ="Parabolic Beam";
$unv_name[171] ="Axi Linear shell";
$unv_name[172] ="Axi Parabolic shell";
$unv_name[41]  ="Plain Stress Linear Triangle";
$unv_name[42]  ="Plain Stress Parabolic Triangle";
$unv_name[44]  ="Plain Stress Linear Quadrilateral";
$unv_name[45]  ="Plain Stress Parabolic Quadrilateral";
$unv_name[51]  ="Plain Strain Linear Triangle";
$unv_name[52]  ="Plain Strain Parabolic Triangle";
$unv_name[54]  ="Plain Strain Linear Quadrilateral";
$unv_name[55]  ="Plain Strain Parabolic Quadrilateral";
$unv_name[61]  ="Plate Linear Triangle";
$unv_name[62]  ="Plate Parabolic Triangle";
$unv_name[64]  ="Plate Linear Quadrilateral";
$unv_name[65]  ="Plate Parabolic Quadrilateral";
$unv_name[71]  ="Membrane Linear Triangle";
$unv_name[72]  ="Membrane Parabolic Triangle";
$unv_name[74]  ="Membrane Linear Quadrilateral";
$unv_name[75]  ="Membrane Parabolic Quadrilateral";
$unv_name[81]  ="Axi Solid Linear Triangle";
$unv_name[82]  ="Axi Solid Parabolic Triangle";
$unv_name[84]  ="Axi Solid Linear Quadrilateral";
$unv_name[85]  ="Axi Solid Parabolic Quadrilateral";
$unv_name[91]  ="Thin Shell Linear Triangle";
$unv_name[92]  ="Thin Shell Parabolic Triangle";
$unv_name[94]  ="Thin Shell Linear Quadrilateral";
$unv_name[95]  ="Thin Shell Parabolic Quadrilateral";
$unv_name[115] ="Solid Linear Brick";
$unv_name[116] ="Solid Parabolic Brick";
$unv_name[112] ="Solid Linear Wedge";
$unv_name[113] ="Solid Parabolic Wedge";
$unv_name[111] ="Solid Linear Tetrahedron";
$unv_name[118] ="Solid Parabolic Tetrahedron";
# }}}
#
# Correspondance Element - Nbre de noeuds {{{
my @corresp_nb_el;  
$corresp_nb_el[2] = 2;  # SEG2
$corresp_nb_el[3] = 3;  # SEG3
$corresp_nb_el[4] = 3;  # TRI3
$corresp_nb_el[6] = 6;  # TRI6
$corresp_nb_el[8] = 4;  # QUA4
$corresp_nb_el[10]= 8;  # QUA8
$corresp_nb_el[14]= 8;  # CUB8
$corresp_nb_el[15]= 20; # CU20
$corresp_nb_el[16]= 6;  # PRI6
$corresp_nb_el[17]= 15; # PR15
$corresp_nb_el[23]= 4;  # TET4
$corresp_nb_el[24]= 10; # TE10
# }}}
#
# }}}

if($#ARGV==-1) { 
        xcast2unv();
} else {
        $file1 = $ARGV[0];
        cast2unv();
}

#
sub xcast2unv {{{
$main_win = MainWindow->new ;
$verb1 = 1;
load_usage();

# Fenetre du menu
# ~~~~~~~~~~~~~~~	

# Title for the main window
$main_win->title( "Conversion CAST3M vers UNIVERSEL" ) ;
 
# Fichier 
$main_win->Label( -text => "Fichier .sauv :")
  -> grid( -row => 1, -column => 0 , 
	   -pady => 4,
	   -padx => 2,
	   -sticky => 'w' ) ;

$main_win->Entry( -textvariable => \$file1,-width => 35)
  -> grid( -row => 1, -column => 1 ,
	   -pady => 4,
	   -padx => 2,
	   -sticky => 'w' ) ;
$op_select = $main_win->Button( -text => "...",
				  -command => \&open_file )
  -> grid( -row => 1, -column => 2 ,
	   -pady => 4,
	   -padx => 2,
	   -sticky => 'w' ) ;

#
# Mode 
$main_win->Label( -text => "Shell")
  -> grid( -row => 2, -column => 0 , 
	   -pady => 4,
	   -padx => 2,
	   -sticky => 'e' ) ;
$mode_displayed = "Thin Shell";
$main_win->Optionmenu(-options=>[["Thin Shell","S"],
				 ["Plate","P" ],
				 ["Membrane", "M"]],
			-textvariable => $mode_displayed,
		       -variable=>\$opt_shell)
  -> grid( -row => 2, -column => 1 ,
	   -pady => 4,
	   -padx => 2,
	   -sticky => 'w' ) ;
#
#--------------------------------------------------
# #
# # Mode 
# $main_win->Label( -text => "Densité")
#   -> grid( -row => 3, -column => 0 , 
# 	   -pady => 4,
# 	   -padx => 2,
# 	   -sticky => 'e' ) ;
# $main_win->Entry( -textvariable => \$densi1,-width => 5)
#   -> grid( -row => 3, -column => 1 ,
# 	   -pady => 4,
# 	   -padx => 2,
# 	   -sticky => 'w' ) ;
#-------------------------------------------------- 
# Conversion
$op_sort_bt = $main_win->Button( -text => "Conversion",
				  -command => \&convert )
  -> grid( -row => 4, -column => 1 ,
	   -pady => 4,
	   -padx => 2,
	   -sticky => 'e' ) ;

$main_win->Checkbutton( -text => "Trid",
			variable => \$trid1,
			-command => 
			sub { } )
  -> grid( -row => 4, -column => 0 ,
	   -pady => 4,
	   -padx => 2,
	   -sticky => 'e' ) ;

# Help 
$main_win->Button( -text => "Help",
				  -command => \&appel_help )
  -> grid( -row => 2, -column => 2 ,
	   -pady => 4,
	   -padx => 2,
	   -sticky => 'nsew' ) ;

# Fin 
$main_win->Button( -text => "Sortie",
				  -command => sub{exit} )
  -> grid( -row => 4, -column => 2 ,
	   -pady => 4,
	   -padx => 2,
	   -sticky => 'w' ) ;
# Copyright
$main_win->Label( -text => "[cast2unv.pl - L.CHAMPANEY - LEMA/UVSQ - 2003]")
  -> grid( -row => 5, -column => 0 , -columnspan => 3,
	   -pady => 4,
	   -padx => 2,
	   -sticky => 'nsew' ) ;

# Help
$help_win = MainWindow->new ;
$help_win->resizable(0,0) ;
$help_win->geometry("+0-20") ;
$help_win->withdraw() ;
$help_txt = $help_win->Scrolled("ROText",
			-width=>56,
			-height=>25) -> pack(-expand=>1);
$help_win->Button( -text => "Sortie",
                                  -command => \&help_fin )
  ->  pack(-expand=>1);

$help_txt->insert('end',$help_text);

#
sub appel_help {
      $help_win->deiconify() ;
      $help_win->raise() ;
      return;
}; 
sub help_fin {
      $help_win->withdraw() ;
      return;
} ;
#
# Pour l'ouverture
$open_FS = $main_win -> FileSelect(-filter => "*.sauv");
sub open_file { $file1 = $open_FS -> Show; }
# Appel à la conversion
sub convert { if ($file1){ cast2unv(); $file1 = ""; } }
#
# Activate the Main window
$main_win->deiconify() ;
$main_win->raise() ;
# -----------------------------------------------------> Main loop <---
MainLoop ;
#
return;
#
}}};
#
sub cast2unv {{{
#--------------------------------------------------
# if($#ARGV==-1) { sortie_usage(); exit();}
# else {
#         ($generic , $generic_ext) = ( $ARGV[0] =~ /([-_\/\w]*)\.?(\w*)/ ) ;
# }
#-------------------------------------------------- 
# Cas des shell
if ($opt_shell) {
       if ($opt_shell eq 'P') {
$corresp_typ_el[4][3] = 61;  # TRI3 -> Plate Linear Triangle
$corresp_typ_el[6][3] = 62;  # TRI6 -> Plate Parabolic Triangle
$corresp_typ_el[8][3] = 64;  # QUA4 -> Plate Linear Quadrilateral
$corresp_typ_el[10][3]= 65;  # QUA8 -> Plate Parabolic Quadrilateral
       };
       if ($opt_shell eq 'M') {
$corresp_typ_el[4][3] = 71;  # TRI3 -> Membrane Linear Triangle
$corresp_typ_el[6][3] = 72;  # TRI6 -> Membrane Parabolic Triangle
$corresp_typ_el[8][3] = 74;  # QUA4 -> Membrane Linear Quadrilateral
$corresp_typ_el[10][3]= 75;  # QUA8 -> Membrane Parabolic Quadrilateral
       };
};

($file0,$rep0,$ext0) = fileparse($file1, '\..*');
#($generic , $generic_ext) = ( $file1 =~ /([-_:\/\w\s]*)\.?(\w*)/ ) ;
$generic = $rep0.$file0;

#########       Lecture du fichier Castem         ##########
# {{{
my $fic = "$generic.sauv";
open( FIC, $fic) || die "\n$fic inexistant\n\n";

# Analyse du fichier de sauvegarde CAST3M et remplissage des Tableaux

if ($verb1) {print "\nLecture de $fic\n";};

   while ($line = <FIC>)
  {
    if ($line =~ /NIVEAU.*DIMENSION\s*(\d*)/)
       {$dime = $1;
        if ($verb1) 
          {print "  Dimension $dime\n";};
           };
      
    if ($line =~ /\sIFOUR\s*(\S*)\sNIFOUR.*/) 
       {my $ifour0 = $1;
        if ($ifour0 == 0)
           {$ifour = 0;
            if ($verb1) 
               {print "  Mode axisymetrique\n";
                };
            }; 
        if ($ifour0 == -1)
           {$ifour = 1;
            if ($verb1) 
               {print "  Mode deformations planes\n";
                };
            };
        if ($ifour0 == -2)
           {$ifour = 2;
            if ($verb1) 
               {print "  Mode contraintes planes\n";
                };
            };
        if ($ifour0 == 2)
           {$ifour = 3;
            if ($verb1) 
               {print "  Mode tridimensionnel\n";
                };
            };
#  En mode trid, on force le mode tridimensionnel pour
#  que les triangles et les quadrangles soient des coques
        if ($trid1)
           {$ifour = 3;
            if ($verb1) 
               {print "\n!!!!  Mode tridimensionnel force !!!!\n\n";
                };
            };
         };
         
    if ($line =~ /PILE NUMERO\s*(\d*)NBRE OBJETS NOMMES\s*(\d*)NBRE OBJETS\s*(\d*)/) 
       {my $pile = $1;
        my $nommes1 = $2;
        my $objets1 = $3;
#    print "Pile $pile - objets nommes $nommes1 - objets $objets1\n"

#    PILE des coordonnees des noeuds
        if ($pile == 32)
         {{{
            if ($verb1) 
               {print "  Lecture de la configurations : ";
                };
            my $nbsaut1 = int($nommes1 / 8);
            if ( $nommes1 % 8) {$nbsaut1 ++};
            my $nbsaut2 = int($nommes1 / 10);
            if ( $nommes1 % 10) {$nbsaut2 ++};
            my $nbsaut1 = ($nbsaut1 + $nbsaut2) + 1;
            for my $i (1 .. $nbsaut1) {$line = <FIC>};
            #print "$nbsaut1\n";
            my $nblus1 = int($objets1 / 10);
            if ( $objets1 % 10) {$nblus1 ++};
            #print "$nblus1\n";
            my $nbp1 = 0;
            for my $i (1 .. $nblus1) {
              $line = <FIC>;
                          chomp($line);
              my @temp1 = unpack ("A8" x (length($line)/8), $line);
              for my $j (1 .. (length($line)/8)) {
                my $nn1 = $temp1[$j - 1] + 0;
                $noeuds[$nbp1] = $nn1;
                #$noeuds[$nn1] = $nbp1;
                $nbp1++;
              };
            };
            if ($verb1) {print "$nbp1 noeuds lus\n";};
         }}};

#    PILE des configurations
        if ($pile == 33) {{{
            if ($verb1) {print "  Lecture des POINTs : ";};
            my $nbsaut1 = int($nommes1 / 8);
            if ( $nommes1 % 8) {$nbsaut1 ++};
            my $nbsaut1 = (2 * $nbsaut1 ) ;
            #print "$nbsaut1\n";
            #
            for my $i (1 .. $nbsaut1) {$line = <FIC>};
            $line = <FIC>;
            chomp($line);
            my $nblus1 = int($line / 3);
            if ( $line % 3) {$nblus1 ++};
            my $nn1 = 0;
            my $incr1 = 0;
            for my $i (1 .. $nblus1) {
              $line = <FIC>;
                          chomp($line);
              my @temp1 = unpack ("A22" x (length($line)/22), $line);
              for my $j (1 .. (length($line)/22)) {
                $points[$nn1][$incr1] = $temp1[$j - 1] * 1.;
                #print "points[$nn1][$iincr1]=$points[$nn1][$incr1] \n";
                if (($incr1 + 1) % ($dime + 1)) {$incr1++}
                else { $incr1=0; $nn1++;};
              };
            };
            if ($verb1) {print "$nn1 points lus\n";};
        }}};
        
#    PILE des maillages
        if ($pile == 1) {{{
            if ($verb1) {print "  Lecture des MAILLAGEs : ";};
            my $nblus1 = int($nommes1 / 8);
            if ( $nommes1 % 8) {$nblus1 ++};
            #print "$nbsaut1\n";
            my @noms_mail_temp;
            my $nommes2 = 0;
            for my $i (1 .. $nblus1) {
                $line = <FIC>;
                chomp($line);
                my @temp1 = unpack ("A9" x (length($line)/9), $line);
                for my $j (1 .. (length($line)/9)) {
                    $noms_mail_temp[$nommes2] = "$temp1[$j - 1]" ;
                    $noms_mail_temp[$nommes2] =~ s/ //g;
                    $nommes2 ++;
                };
            };
            my $nblus1 = int($nommes1 / 10);
            if ( $nommes1 % 10) {$nblus1 ++};
            $nommes2 = 0;
            for my $i (1 .. $nblus1) {
                $line = <FIC>;
                chomp($line);
                my @temp1 = unpack ("A8" x (length($line)/8), $line);
                for my $j (1 .. (length($line)/8)) {
                    $noms_mail{$noms_mail_temp[$nommes2]} = $temp1[$j - 1] + 0;
#     print "$noms_mail_temp[$nommes2],$noms_mail{$noms_mail_temp[        $nommes2]}\n"; 
                    $nommes2 ++;
                };
            };
            
            for my $k (1 .. $objets1) {
              $line = <FIC>;
                          chomp($line);
              my @temp1 = unpack ("A8" x 5, $line);
              # Info sur le type d'element
              $mail_tyel[$k-1] = $temp1[0] + 0;
              my $nbel_el1 = $temp1[4] + 0;
              $mail_nbel[$k-1] = $nbel_el1;
              my $nbnd_el1 = $temp1[3] + 0;
              $mail_nbno[$k-1] = $nbnd_el1;
              #print "$k : $nbel_el1 - $nbnd_el1\n";
              # On saute les sous references
              if (( $temp1[1] + 0) != 0) {$line = <FIC>};
              if ($mail_tyel[$k-1] != 0) {
                if (( $temp1[2] + 0) != 0) {$line = <FIC>};
                my $nbsaut1 = int($nbel_el1 / 10);
                if ( $nbel_el1 % 10) {$nbsaut1 ++};
                  # On saute les couleurs
                  for my $i (1 .. $nbsaut1) {$line = <FIC>};
                  my $nblus1 = int(($nbel_el1*$nbnd_el1)/ 10);
                  if (($nbel_el1*$nbnd_el1) % 10) {$nblus1 ++};
                  # On lit les connectivites
                  my $nd1 = 0;
                  my $el1 = 0;
                  for my $i (1 .. $nblus1) {
                    $line = <FIC>;
                    chomp($line);
                    my @temp1 = unpack ("A8" x (length($line)/8), $line);
                    for my $j (1 .. (length($line)/8)) {
                    $mail[$k-1][$el1][$nd1] = $temp1[$j - 1] + 0;
                    #print "mail[$k,$el1,$nd1]=$mail[$k][$el1][$nd1] \n";
                    if (($nd1 + 1) % ($nbnd_el1)) {$nd1++}
                    else { $nd1=0; $el1++}
                    };
                  };
                  #print "Maillage $k : $el1 elements\n";
              }
              # Cas des maillages avec sous reference
              else { 
                chomp($line);
                my @temp2 = unpack ("A8" x (length($line)/8), $line);
                for my $j (1 .. (length($line)/8)) {
                    $mail[$k-1][1][$j] = $temp2[$j - 1] + 0;
                };
                if (( $temp1[2] + 0) != 0) {$line = <FIC>};
              };
            };
            if ($verb1) {print "$objets1 maillages\n";};
        }}};
    };
        
};
close(FIC);
# }}}
#########     Fin de lecture du fichier CASTEM    ##########
#
##########    On lit le fichier des noms de maillages à convertir
# {{{
my $fit = "$generic.c2u";
open( FIT, "$fit") || die "\n$fit inexistant\n\n";
if ($verb1) {print "\nLecture de $fit\n   Maillage(s) à transferer :\n   ";};
my $nb_CARTES = 0;
my @CARTES;
my $nb_NSET = 0;
my @NSET;
my $nb_ELSET = 0;
my @ELSET;
my $nb_SDLOAD = 0;
my @SDLOAD;
my $nb_SURFAC = 0;
my @SURFAC;
$line = "NULL";
while ($line = <FIT>) {
        chomp $line;
        if ($line) {
                $ELSET[$nb_ELSET][1] = $line;
                $ELSET[$nb_ELSET][2] = uc $line;
                $nb_ELSET++;
                if ($verb1) {print "$line "};
        };
};

close(FIT);

# }}}
##########        Fin de lecture des noms de maillages
#
##########        On a lu le fichier, on peut travailler
# {{{
#  Ecriture de l'entète : bloc 151

my $fis = "$generic.unv";             # recuperation du nom de fichier
open( FIS, ">$fis") || die "\nimpossible de creer $fis\n\n";
if ($verb1) {print "\n\nEcriture de $fis\n";};
printf FIS ("%6d\n%6d\n",-1,151);     # -1 et 151 en debut de bloc
print FIS "$generic\n";                 # ecriture du nom
printf FIS ("%6d\n",-1);              # -1 en fin de bloc

#  Ecriture des noeuds : bloc 2411 {{{
printf FIS ("%6d\n%6d",-1,2411);      # -1 et 2411 en debut de bloc

my $nbtot_noeuds = $#noeuds+1;        # recuperation du nombre de noeuds

for my $i (1 .. $nbtot_noeuds)
 {my $poin1 = $noeuds[$i-1];        # Boucle principale traitant 
    print FIS ("$noeuds\n");          #        noeuds après noeuds
    printf FIS ("%10d%10d%10d%10d\n",$i,1,1,11); 
    
     if ($dime==2)                    # Condition sur la dimension
     {for my $ico1 (1 .. 2)           # Boucle pour dimension 2
       {                              # recuperation des coordonnees 
        my $coor1 = $points[$poin1 - 1][$ico1 - 1];
        my $aa = sprintf ('%25.16E',$coor1 );
           $aa =~ tr/E/D/;            # On remplace l'exposant e par D 
           print FIS "$aa";           # On affiche les coordonnees XY
        };                            # fin de Boucle
print FIS "  0.0000000000000000D+000" # Coordonees en Z 
        }
        
        
    else {
        for my $ico1 (1 .. $dime)     # Boucle pour autre dimension
       {
        my $coor1 = $points[$poin1 - 1][$ico1 - 1];
        my $aa = sprintf ('%25.16E',$coor1 );
           $aa =~ tr/E/D/;
           print FIS "$aa";
        };};
};
printf FIS ("\n%6d\n",-1);            # -1 de fin de bloc
# }}} 

#

# Les NSET : ne sert pas {{{
for my $i (0 .. ($nb_NSET-1)) { {{
        #print "$noms_mail{$NSET[$i][2]}-$NSET[$i][2]\n";
    if ($noms_mail{$NSET[$i][2]}) {
        if ($verb1) {print     "*NSET,NSET=$NSET[$i][1]\n";};
        print FIS "*NSET,NSET=$NSET[$i][1]\n";
        my $nmail1 = $noms_mail{$NSET[$i][2]} - 1;
        if ($mail_tyel[$nmail1] == 1) {
            my $nbno1 = $mail_nbel[$nmail1];
            #print "$NSET[$i][2] - $nbno1 noeuds\n";
            for my $j (0 ... ($nbno1 - 1)) {
                print FIS "$mail[$nmail1][$j][0],\n";
            }
        }
        else {
            print "$NSET[$i][2] n'est pas de type POI1\n";
        };
    }
    else {
        print "$NSET[$i][2] inexistant dans le maillage cast3m\n";
    };
}} };
# }}}
#
#     Repertoire des types d'element : bloc 2412

printf FIS ("%6d\n%6d\n",-1,2412);


# Les ELSET
for my $i (0 .. ($nb_ELSET-1)) {{{
        #print "$noms_mail{$ELSET[$i][2]}-$ELSET[$i][2]\n";
	if ($noms_mail{$ELSET[$i][2]}) {
		my $nmail1 = $noms_mail{$ELSET[$i][2]} - 1;
		my $ttype1 = $ELSET[$i][3];
		my $typma1 = $mail_tyel[$nmail1];
		if ($typma1 == 0) {
			my $nbref1 = $#{ $mail[$nmail1][1]} ;
			if ($verb1) {print "$ELSET[$i][2] : $nbref1 types d'elements\n";};
			for my $ref1 (1 .. $nbref1){
				my $nmail2 = $mail[$nmail1][1][$ref1] - 1;
				my $nom2 = "$ELSET[$i][1]";
				ab_elset($nmail2,$nom2,$ttype1,$i+1);
			}
		}
		else {
			ab_elset($nmail1,$ELSET[$i][1],$ttype1,$i+1);
		}
	}
	else {
		print "$ELSET[$i][2] inexistant dans le maillage cast3m\n";
	};
}}}
#
printf FIS ("%6d\n",-1);

# Pour compter les elemnts à chercher
my $reste;
#
# Les SURFACE, si il y en a    : pas utilise
if ($nb_SURFAC != 0){{{
    for my $i (1 .. $nb_SURFAC){
        ab_surfac($i);
    }
}}}
#
# On ecrit les cartes supplementaires si besoin
if ($nb_CARTES) { for (@CARTES) {print FIS "$_"}};
#
# Les SDLOAD, si il y en a :    pas utilise
if ($nb_SDLOAD != 0){{{
    print FIS "**\n";
    print FIS "*STEP\n";
    print FIS "*STATIC\n";
    for my $i (1 .. $nb_SDLOAD){
        ab_sdload($i);
    }
    print FIS "*ENDSTEP\n";
}}};
#
close(FIS);
# }}}
#
# On sort
if ($verb1){print "\nConversion effectuee\n\n";};
return;
#
}}};
#
#==========================================================================
# Ecriture des elements dans le cas sans bord
#==========================================================================
#
sub ab_elset
{{{ 
    my($nmail1, $nom1, $ttype1,$num2) = @_;
    my $typma1 = $mail_tyel[$nmail1];
    if ($corresp_typ_el[$typma1][$ifour])
       {my $nom_elem1;
 # Reconnaissance du type d'element par le numero qui lui est associe
        if ($ttype1) {
                $nom_elem1 = $ttype1;              
        } 
        else {
                $nom_elem1 = "$corresp_typ_el[$typma1][$ifour]";
              
        };
        if ($verb1)      
          {print "Maillage $nom1 : $unv_name[$nom_elem1]\n";
          }
 # Appel de la fonction correspondant au type d'element         
           my $nom_de_code = "ab_" . $typ_el_cast[$typma1]; 
           for my $el1 (0 .. ($mail_nbel[$nmail1] - 1)) {
                $num_el_unv ++;
                printf FIS ("%10d",$num_el_unv);
                printf FIS ("%10d",$nom_elem1);
                printf FIS ("%10d%10d",$num2,$num2);
                printf FIS ("%10d",7);
                printf FIS ("%10d\n",$corresp_nb_el[$typma1]);
                &$nom_de_code($nmail1,$el1);
           };
         } 
         else 
           {print "$typ_el_cast[$typma1] non supporte\n";
            };
    return;
}}};
#
#==========================================================================
# Ecriture d'un element SEG2
#==========================================================================
#
sub ab_SEG2 
{{{
    my($nmail1, $el1) = @_;
    my $no1 = $mail[$nmail1][$el1][0];
    my $no2 = $mail[$nmail1][$el1][1];
    if ($ifour){printf FIS ("%10d%10d%10d\n",0,1,1)};
    printf FIS ("%10d%10d\n",$no1,$no2);
    $corresp_num_el[$nmail1][$el1] = $num_el_unv;
    return;
}}};
#
#==========================================================================
# Ecriture d'un element SEG3
#==========================================================================
#
sub ab_SEG3 
{{{
    my($nmail1, $el1) = @_;
    my $no1 = $mail[$nmail1][$el1][0];
    my $no2 = $mail[$nmail1][$el1][1];
    my $no3 = $mail[$nmail1][$el1][2];
    if ($ifour){printf FIS ("%10d%10d%10d\n",0,1,1)};
    printf FIS ("%10d%10d%10d\n",$no1,$no2,$no3);
    $corresp_num_el[$nmail1][$el1] = $num_el_unv;
    return;
}}};
#
#==========================================================================
# Ecriture d'un element TRI3 (cas sans bords)
#==========================================================================
#                           #////////////////////////////// CONNU
sub ab_TRI3 
{{{
    my($nmail1, $el1) = @_;
    my $no1 = $mail[$nmail1][$el1][0];
    my $no2 = $mail[$nmail1][$el1][1];
    my $no3 = $mail[$nmail1][$el1][2];
    my $x1 = $points[$noeuds[$no1-1] - 1][0];
    my $y1 = $points[$noeuds[$no1-1] - 1][1];
    my $x2 = $points[$noeuds[$no2-1] - 1][0];
    my $y2 = $points[$noeuds[$no2-1] - 1][1];
    my $x3 = $points[$noeuds[$no3-1] - 1][0];
    my $y3 = $points[$noeuds[$no3-1] - 1][1];
    my $pv1 = (($x2 - $x1)*($y3 - $y1)) - (($x3 - $x1)*($y2 - $y1));
    #print "$no1 $no2 $no3 - $x1 $y1 $x2 $y2 $x3 $y3 : $pv1\n";
    if ($pv1 > 0.) 
          {
         printf FIS ("%10d%10d%10d\n",$no1,$no2,$no3);
         $corresp_num_el[$nmail1][$el1] = $num_el_unv;
          }
    else { 
        printf FIS ("%10d%10d%10d\n",$no1,$no3,$no2);
        $corresp_num_el[$nmail1][$el1] = -1 * $num_el_unv;
         };
    return;
}}};
#
#==========================================================================
# Ecriture d'un element TRI6 (cas sans bords)
#==========================================================================
#                              #////////////////////////////// CONNU
sub ab_TRI6 
{{{
    my($nmail1, $el1) = @_;
    my $no1 = $mail[$nmail1][$el1][0];
    my $no2 = $mail[$nmail1][$el1][1];
    my $no3 = $mail[$nmail1][$el1][2];
    my $no4 = $mail[$nmail1][$el1][3];
    my $no5 = $mail[$nmail1][$el1][4];
    my $no6 = $mail[$nmail1][$el1][5];
    my $x1 = $points[$noeuds[$no1-1] - 1][0];
    my $y1 = $points[$noeuds[$no1-1] - 1][1];
    my $x2 = $points[$noeuds[$no3-1] - 1][0];
    my $y2 = $points[$noeuds[$no3-1] - 1][1];
    my $x3 = $points[$noeuds[$no5-1] - 1][0];
    my $y3 = $points[$noeuds[$no5-1] - 1][1];
    my $pv1 = (($x2 - $x1)*($y3 - $y1)) - (($x3 - $x1)*($y2 - $y1));
    if ($pv1 > 0.) 
         {
        printf FIS ("%10d%10d%10d%10d%10d%10d\n",$no1,$no2,$no3,$no4,$no5,$no6);
        $corresp_num_el[$nmail1][$el1] = $num_el_unv;
         } 
    else {
        printf FIS ("%10d%10d%10d%10d%10d%10d\n",$no1,$no6,$no5,$no4,$no3,$no2);    
        $corresp_num_el[$nmail1][$el1] = -1 * $num_el_unv;
         };
    return;
}}};
#
#==========================================================================
# Ecriture d'un element QUA4 (cas sans bords)
#==========================================================================
#                               ////////////////////////// CONNU
sub ab_QUA4 
{{{
    my($nmail1, $el1) = @_;
       my $no1 = $mail[$nmail1][$el1][0];
    my $no2 = $mail[$nmail1][$el1][1];
    my $no3 = $mail[$nmail1][$el1][2];
    my $no4 = $mail[$nmail1][$el1][3];
    my $x1 = $points[$noeuds[$no1-1] - 1][0];
    my $y1 = $points[$noeuds[$no1-1] - 1][1];
    my $x2 = $points[$noeuds[$no2-1] - 1][0];
    my $y2 = $points[$noeuds[$no2-1] - 1][1];
    my $x3 = $points[$noeuds[$no3-1] - 1][0];
    my $y3 = $points[$noeuds[$no3-1] - 1][1];
    my $pv1 = (($x2 - $x1)*($y3 - $y1)) - (($x3 - $x1)*($y2 - $y1));
    if ($pv1 > 0.) 
    {printf FIS ("%10d%10d%10d%10d\n",$no1,$no2,$no3,$no4);
     $corresp_num_el[$nmail1][$el1] = $num_el_unv;
    } 
    else {
        printf FIS ("%10d%10d%10d%10d\n",$no1,$no4,$no3,$no2);
        $corresp_num_el[$nmail1][$el1] = -1 * $num_el_unv;
         };
    return;
}}};
#
#==========================================================================
# Ecriture d'un element QUA8 (cas sans bords)
#==========================================================================
#                            //////////////////////////// CONNU
sub ab_QUA8 
{{{
    my($nmail1, $el1) = @_;
    my $no1 = $mail[$nmail1][$el1][0];
    my $no2 = $mail[$nmail1][$el1][1];
    my $no3 = $mail[$nmail1][$el1][2];
    my $no4 = $mail[$nmail1][$el1][3];
    my $no5 = $mail[$nmail1][$el1][4];
    my $no6 = $mail[$nmail1][$el1][5];
    my $no7 = $mail[$nmail1][$el1][6];
    my $no8 = $mail[$nmail1][$el1][7];
    my $x1 = $points[$noeuds[$no1-1] - 1][0];
    my $y1 = $points[$noeuds[$no1-1] - 1][1];
    my $x2 = $points[$noeuds[$no3-1] - 1][0];
    my $y2 = $points[$noeuds[$no3-1] - 1][1];
    my $x3 = $points[$noeuds[$no5-1] - 1][0];
    my $y3 = $points[$noeuds[$no5-1] - 1][1];
    my $pv1 = (($x2 - $x1)*($y3 - $y1)) - (($x3 - $x1)*($y2 - $y1));
    if ($pv1 > 0.) {
       printf FIS ("%10d%10d%10d%10d%10d%10d%10d%10d\n",$no1,$no2,$no3,$no4,$no5,$no6,$no7,$no8);
        $corresp_num_el[$nmail1][$el1] = $num_el_unv;
    } else {
        printf FIS ("%10d%10d%10d%10d%10d%10d%10d%10d\n",$no1,$no8,$no7,$no6,$no5,$no4,$no3,$no2);
        $corresp_num_el[$nmail1][$el1] = -1 * $num_el_unv;
    };
    return;
}}};
#
#==========================================================================
# Ecriture d'un element CUB8 (cas sans bords)
#==========================================================================
#                                 ??????????????????????????????????
sub ab_CUB8 
{{{
    my($nmail1, $el1) = @_;
    my $no1 = $mail[$nmail1][$el1][0];
    my $no2 = $mail[$nmail1][$el1][1];
    my $no3 = $mail[$nmail1][$el1][2];
    my $no4 = $mail[$nmail1][$el1][3];
    my $no5 = $mail[$nmail1][$el1][4];
    my $no6 = $mail[$nmail1][$el1][5];
    my $no7 = $mail[$nmail1][$el1][6];
    my $no8 = $mail[$nmail1][$el1][7];
    my $x1 = $points[$noeuds[$no1-1] - 1][0];
    my $y1 = $points[$noeuds[$no1-1] - 1][1];
    my $z1 = $points[$noeuds[$no1-1] - 1][2];
    my $x2 = $points[$noeuds[$no2-1] - 1][0];
    my $y2 = $points[$noeuds[$no2-1] - 1][1];
    my $z2 = $points[$noeuds[$no2-1] - 1][2];
    my $x3 = $points[$noeuds[$no3-1] - 1][0];
    my $y3 = $points[$noeuds[$no3-1] - 1][1];
    my $z3 = $points[$noeuds[$no3-1] - 1][2];
    my $x5 = $points[$noeuds[$no5-1] - 1][0];
    my $y5 = $points[$noeuds[$no5-1] - 1][1];
    my $z5 = $points[$noeuds[$no5-1] - 1][2];
    my $vx1 = $x2 - $x1; my $vy1 = $y2 - $y1; my $vz1 = $z2 - $z1;
    my $vx2 = $x3 - $x1; my $vy2 = $y3 - $y1; my $vz2 = $z3 - $z1;
    my $vx3 = $x5 - $x1; my $vy3 = $y5 - $y1; my $vz3 = $z5 - $z1;
    my $pvx1 = ($vy1 * $vz2) - ($vz1 * $vy2);
    my $pvy1 = ($vz1 * $vx2) - ($vx1 * $vz2);
    my $pvz1 = ($vx1 * $vy2) - ($vy1 * $vx2);
    my $pv1 = ($pvx1*$vx3)+($pvy1*$vy3)+($pvz1*$vz3);
    if ($pv1 > 0.) {
       printf FIS ("%10d%10d%10d%10d%10d%10d%10d%10d\n",$no1,$no2,$no3,$no4,$no5,$no6,$no7,$no8);
       $corresp_num_el[$nmail1][$el1] = $num_el_unv;
    } else {
       printf FIS ("%10d%10d%10d%10d%10d%10d%10d%10d\n",$no5,$no6,$no7,$no8,$no1,$no2,$no3,$no4);
       $corresp_num_el[$nmail1][$el1] = -1 * $num_el_unv;
    };
    return;
}}};
#
#==========================================================================
# Ecriture d'un element PRI6 (cas sans bords)
#==========================================================================
#                                    ?????????????????????????????????
sub ab_PRI6 
{{{
    my($nmail1, $el1) = @_;
    my $no1 = $mail[$nmail1][$el1][0];
    my $no2 = $mail[$nmail1][$el1][1];
    my $no3 = $mail[$nmail1][$el1][2];
    my $no4 = $mail[$nmail1][$el1][3];
    my $no5 = $mail[$nmail1][$el1][4];
    my $no6 = $mail[$nmail1][$el1][5];
    my $x1 = $points[$noeuds[$no1-1] - 1][0];
    my $y1 = $points[$noeuds[$no1-1] - 1][1];
    my $z1 = $points[$noeuds[$no1-1] - 1][2];
    my $x2 = $points[$noeuds[$no2-1] - 1][0];
    my $y2 = $points[$noeuds[$no2-1] - 1][1];
    my $z2 = $points[$noeuds[$no2-1] - 1][2];
    my $x3 = $points[$noeuds[$no3-1] - 1][0];
    my $y3 = $points[$noeuds[$no3-1] - 1][1];
    my $z3 = $points[$noeuds[$no3-1] - 1][2];
    my $x5 = $points[$noeuds[$no4-1] - 1][0];
    my $y5 = $points[$noeuds[$no4-1] - 1][1];
    my $z5 = $points[$noeuds[$no4-1] - 1][2];
    my $vx1 = $x2 - $x1; my $vy1 = $y2 - $y1; my $vz1 = $z2 - $z1;
    my $vx2 = $x3 - $x1; my $vy2 = $y3 - $y1; my $vz2 = $z3 - $z1;
    my $vx3 = $x5 - $x1; my $vy3 = $y5 - $y1; my $vz3 = $z5 - $z1;
    my $pvx1 = ($vy1 * $vz2) - ($vz1 * $vy2);
    my $pvy1 = ($vz1 * $vx2) - ($vx1 * $vz2);
    my $pvz1 = ($vx1 * $vy2) - ($vy1 * $vx2);
    my $pv1 = ($pvx1*$vx3)+($pvy1*$vy3)+($pvz1*$vz3);
    if ($pv1 > 0.) {
        printf FIS ("%10d%10d%10d%10d%10d%10d\n",$no1,$no2,$no3,$no4,$no5,$no6);
        $corresp_num_el[$nmail1][$el1] = $num_el_unv;
    } else {
        printf FIS ("%10d%10d%10d%10d%10d%10d\n",$no1,$no3,$no2,$no4,$no6,$no5);
        $corresp_num_el[$nmail1][$el1] = -1 * $num_el_unv;
    };
    return;
}}};
#
#==========================================================================
# Ecriture d'un element TET4 (cas sans bords)
#==========================================================================
#                         ///////////////////////////CONNU
sub ab_TET4 
{{{
   my($nmail1, $el1) = @_;
# Relève des numeros des noeuds constituant l'element
   my $no1 = $mail[$nmail1][$el1][0];
   my $no2 = $mail[$nmail1][$el1][1];
   my $no3 = $mail[$nmail1][$el1][2];
   my $no4 = $mail[$nmail1][$el1][3];
# Operation sur les numeros de noeuds afin d'etablir le bon rangement des noeuds sur l'element
   my $x1 = $points[$noeuds[$no1-1] - 1][0];
   my $y1 = $points[$noeuds[$no1-1] - 1][1];
   my $z1 = $points[$noeuds[$no1-1] - 1][2];
   my $x2 = $points[$noeuds[$no2-1] - 1][0];
   my $y2 = $points[$noeuds[$no2-1] - 1][1];
   my $z2 = $points[$noeuds[$no2-1] - 1][2];
   my $x3 = $points[$noeuds[$no3-1] - 1][0];
   my $y3 = $points[$noeuds[$no3-1] - 1][1];
   my $z3 = $points[$noeuds[$no3-1] - 1][2];
   my $x5 = $points[$noeuds[$no4-1] - 1][0];
   my $y5 = $points[$noeuds[$no4-1] - 1][1];
   my $z5 = $points[$noeuds[$no4-1] - 1][2];
   my $vx1 = $x2 - $x1; my $vy1 = $y2 - $y1; my $vz1 = $z2 - $z1;
   my $vx2 = $x3 - $x1; my $vy2 = $y3 - $y1; my $vz2 = $z3 - $z1;
   my $vx3 = $x5 - $x1; my $vy3 = $y5 - $y1; my $vz3 = $z5 - $z1;
   my $pvx1 = ($vy1 * $vz2) - ($vz1 * $vy2);
   my $pvy1 = ($vz1 * $vx2) - ($vx1 * $vz2);
   my $pvz1 = ($vx1 * $vy2) - ($vy1 * $vx2);
   my $pv1 = ($pvx1*$vx3)+($pvy1*$vy3)+($pvz1*$vz3);
# Ecriture de la deuxième ligne concernant les numeros des noeuds constituant l'element en fonction de leur rangement
   if ($pv1 > 0.)
      {printf FIS ("%10d%10d%10d%10d\n",$no1,$no2,$no3,$no4);
       $corresp_num_el[$nmail1][$el1] = $num_el_unv;}
   else 
      {printf FIS ("%10d%10d%10d%10d\n",$no1,$no3,$no2,$no4);
       $corresp_num_el[$nmail1][$el1] = -1 * $num_el_unv;}
    return;
}}};

#==========================================================================
# Ecriture d'un element TE10 (cas sans bords)
#==========================================================================
#          /////////////////////// DERNIER CONNU
sub ab_TE10 
{{{
    my($nmail1, $el1) = @_;
    my $no1 = $mail[$nmail1][$el1][0];
    my $no2 = $mail[$nmail1][$el1][1];
    my $no3 = $mail[$nmail1][$el1][2];
    my $no4 = $mail[$nmail1][$el1][3];
    my $no5 = $mail[$nmail1][$el1][4];
    my $no6 = $mail[$nmail1][$el1][5];
    my $no7 = $mail[$nmail1][$el1][6];
    my $no8 = $mail[$nmail1][$el1][7];
    my $no9 = $mail[$nmail1][$el1][8];
    my $no10 = $mail[$nmail1][$el1][9];
    my $x1 = $points[$noeuds[$no1-1] - 1][0];
    my $y1 = $points[$noeuds[$no1-1] - 1][1];
    my $z1 = $points[$noeuds[$no1-1] - 1][2];
    my $x2 = $points[$noeuds[$no3-1] - 1][0];
    my $y2 = $points[$noeuds[$no3-1] - 1][1];
    my $z2 = $points[$noeuds[$no3-1] - 1][2];
    my $x3 = $points[$noeuds[$no5-1] - 1][0];
    my $y3 = $points[$noeuds[$no5-1] - 1][1];
    my $z3 = $points[$noeuds[$no5-1] - 1][2];
    my $x5 = $points[$noeuds[$no10-1] - 1][0];
    my $y5 = $points[$noeuds[$no10-1] - 1][1];
    my $z5 = $points[$noeuds[$no10-1] - 1][2];
    my $vx1 = $x2 - $x1; my $vy1 = $y2 - $y1; my $vz1 = $z2 - $z1;
    my $vx2 = $x3 - $x1; my $vy2 = $y3 - $y1; my $vz2 = $z3 - $z1;
    my $vx3 = $x5 - $x1; my $vy3 = $y5 - $y1; my $vz3 = $z5 - $z1;
    my $pvx1 = ($vy1 * $vz2) - ($vz1 * $vy2);
    my $pvy1 = ($vz1 * $vx2) - ($vx1 * $vz2);
    my $pvz1 = ($vx1 * $vy2) - ($vy1 * $vx2);
    my $pv1 = (($pvx1*$vx3)+($pvy1*$vy3)+($pvz1*$vz3));
#
    if ($pv1 > 0.) {
        printf FIS ("%10d%10d%10d%10d%10d%10d%10d%10d\n",$no1,$no2,$no3,$no4,$no5,$no6,$no7,$no8);
        printf FIS ("%10d%10d\n",$no9,$no10);
        $corresp_num_el[$nmail1][$el1] = $num_el_unv;
    } else {
        printf FIS ("%10d%10d%10d%10d%10d%10d%10d%10d\n",$no1,$no6,$no5,$no4,$no3,$no2,$no7,$no9);
        printf FIS ("%10d%10d\n",$no8,$no10);
        $corresp_num_el[$nmail1][$el1] = -1 * $num_el_unv;
   };
    return;
}}};
#
#==========================================================================
# Ecriture d'un element CU20 (cas sans bords)
#==========================================================================
#
sub ab_CU20 
{{{
    my($nmail1, $el1) = @_;
    my $no1 = $mail[$nmail1][$el1][0];
    my $no2 = $mail[$nmail1][$el1][1];
    my $no3 = $mail[$nmail1][$el1][2];
    my $no4 = $mail[$nmail1][$el1][3];
    my $no5 = $mail[$nmail1][$el1][4];
    my $no6 = $mail[$nmail1][$el1][5];
    my $no7 = $mail[$nmail1][$el1][6];
    my $no8 = $mail[$nmail1][$el1][7];
    my $no9 = $mail[$nmail1][$el1][8];
    my $no10 = $mail[$nmail1][$el1][9];
    my $no11 = $mail[$nmail1][$el1][10];
    my $no12 = $mail[$nmail1][$el1][11];
    my $no13 = $mail[$nmail1][$el1][12];
    my $no14 = $mail[$nmail1][$el1][13];
    my $no15 = $mail[$nmail1][$el1][14];
    my $no16 = $mail[$nmail1][$el1][15];
    my $no17 = $mail[$nmail1][$el1][16];
    my $no18 = $mail[$nmail1][$el1][17];
    my $no19 = $mail[$nmail1][$el1][18];
    my $no20 = $mail[$nmail1][$el1][19];
    my $x1 = $points[$noeuds[$no1-1] - 1][0];
    my $y1 = $points[$noeuds[$no1-1] - 1][1];
    my $z1 = $points[$noeuds[$no1-1] - 1][2];
    my $x2 = $points[$noeuds[$no3-1] - 1][0];
    my $y2 = $points[$noeuds[$no3-1] - 1][1];
    my $z2 = $points[$noeuds[$no3-1] - 1][2];
    my $x3 = $points[$noeuds[$no5-1] - 1][0];
    my $y3 = $points[$noeuds[$no5-1] - 1][1];
    my $z3 = $points[$noeuds[$no5-1] - 1][2];
    my $x5 = $points[$noeuds[$no13-1] - 1][0];
    my $y5 = $points[$noeuds[$no13-1] - 1][1];
    my $z5 = $points[$noeuds[$no13-1] - 1][2];
    my $vx1 = $x2 - $x1; my $vy1 = $y2 - $y1; my $vz1 = $z2 - $z1;
    my $vx2 = $x3 - $x1; my $vy2 = $y3 - $y1; my $vz2 = $z3 - $z1;
    my $vx3 = $x5 - $x1; my $vy3 = $y5 - $y1; my $vz3 = $z5 - $z1;
    my $pvx1 = ($vy1 * $vz2) - ($vz1 * $vy2);
    my $pvy1 = ($vz1 * $vx2) - ($vx1 * $vz2);
    my $pvz1 = ($vx1 * $vy2) - ($vy1 * $vx2);
    my $pv1 = ($pvx1*$vx3)+($pvy1*$vy3)+($pvz1*$vz3);
    if ($pv1 > 0.) {
       printf FIS ("%10d%10d%10d%10d%10d%10d%10d%10d\n",$no1,$no2,$no3,$no4,$no5,$no6,$no7,$no8);
       printf FIS ("%10d%10d%10d%10d%10d%10d%10d%10d\n",$no9,$no10,$no11,$no12,$no13,$no14,$no15,$no16);
       printf FIS ("%10d%10d%10d%10d\n",$no17,$no18,$no19,$no10);
        $corresp_num_el[$nmail1][$el1] = $num_el_unv;
    } else {
       printf FIS ("%10d%10d%10d%10d%10d%10d%10d%10d\n",$no1,$no8,$no7,$no6,$no5,$no4,$no3,$no2);
       printf FIS ("%10d%10d%10d%10d%10d%10d%10d%10d\n",$no9,$no12,$no11,$no10,$no13,$no20,$no19,$no18);
       printf FIS ("%10d%10d%10d%10d\n",$no17,$no16,$no15,$no14);
        $corresp_num_el[$nmail1][$el1] = -1 * $num_el_unv;
    };
    return;
}}};
#
#==========================================================================
# Ecriture d'un element PR15 (cas sans bords)
#==========================================================================
#
sub ab_PR15 
{{{
    my($nmail1, $el1) = @_;
    my $no1 = $mail[$nmail1][$el1][0];
    my $no2 = $mail[$nmail1][$el1][1];
    my $no3 = $mail[$nmail1][$el1][2];
    my $no4 = $mail[$nmail1][$el1][3];
    my $no5 = $mail[$nmail1][$el1][4];
    my $no6 = $mail[$nmail1][$el1][5];
    my $no7 = $mail[$nmail1][$el1][6];
    my $no8 = $mail[$nmail1][$el1][7];
    my $no9 = $mail[$nmail1][$el1][8];
    my $no10 = $mail[$nmail1][$el1][9];
    my $no11 = $mail[$nmail1][$el1][10];
    my $no12 = $mail[$nmail1][$el1][11];
    my $no13 = $mail[$nmail1][$el1][12];
    my $no14 = $mail[$nmail1][$el1][13];
    my $no15 = $mail[$nmail1][$el1][14];
    my $x1 = $points[$noeuds[$no1-1] - 1][0];
    my $y1 = $points[$noeuds[$no1-1] - 1][1];
    my $z1 = $points[$noeuds[$no1-1] - 1][2];
    my $x2 = $points[$noeuds[$no3-1] - 1][0];
    my $y2 = $points[$noeuds[$no3-1] - 1][1];
    my $z2 = $points[$noeuds[$no3-1] - 1][2];
    my $x3 = $points[$noeuds[$no5-1] - 1][0];
    my $y3 = $points[$noeuds[$no5-1] - 1][1];
    my $z3 = $points[$noeuds[$no5-1] - 1][2];
    my $x5 = $points[$noeuds[$no10-1] - 1][0];
    my $y5 = $points[$noeuds[$no10-1] - 1][1];
    my $z5 = $points[$noeuds[$no10-1] - 1][2];
    my $vx1 = $x2 - $x1; my $vy1 = $y2 - $y1; my $vz1 = $z2 - $z1;
    my $vx2 = $x3 - $x1; my $vy2 = $y3 - $y1; my $vz2 = $z3 - $z1;
    my $vx3 = $x5 - $x1; my $vy3 = $y5 - $y1; my $vz3 = $z5 - $z1;
    my $pvx1 = ($vy1 * $vz2) - ($vz1 * $vy2);
    my $pvy1 = ($vz1 * $vx2) - ($vx1 * $vz2);
    my $pvz1 = ($vx1 * $vy2) - ($vy1 * $vx2);
    my $pv1 = ($pvx1*$vx3)+($pvy1*$vy3)+($pvz1*$vz3);
    if ($pv1 > 0.) {
       printf FIS ("%10d%10d%10d%10d%10d%10d%10d%10d\n",$no1,$no2,$no3,$no4,$no5,$no6,$no7,$no8);
       printf FIS ("%10d%10d%10d%10d%10d%10d%10d\n",$no9,$no10,$no11,$no12,$no13,$no14,$no15);
        $corresp_num_el[$nmail1][$el1] = $num_el_unv;
    } else {
       printf FIS ("%10d%10d%10d%10d%10d%10d%10d%10d\n",$no1,$no6,$no5,$no4,$no3,$no2,$no7,$no9);
       printf FIS ("d%10d%10d%10d%10d%10d%10d%10d\n",$no8,$no10,$no15,$no14,$no13,$no12,$no11);
        $corresp_num_el[$nmail1][$el1] = -1 * $num_el_unv;
    };
    return;
}}};
#
#==========================================================================
# Ecriture d'un element PYR5 (cas sans bords)
#==========================================================================
#                          ?????????????????????????????????????
sub ab_PYR5 
{{{
    my($nmail1, $el1) = @_;
    print FIS "$num_el_unv";
    my $no1 = $mail[$nmail1][$el1][0];
    my $no2 = $mail[$nmail1][$el1][1];
    my $no3 = $mail[$nmail1][$el1][2];
    my $no4 = $mail[$nmail1][$el1][3];
    my $no4 = $mail[$nmail1][$el1][5];
    my $x1 = $points[$noeuds[$no1-1] - 1][0];
    my $y1 = $points[$noeuds[$no1-1] - 1][1];
    my $z1 = $points[$noeuds[$no1-1] - 1][2];
    my $x2 = $points[$noeuds[$no2-1] - 1][0];
    my $y2 = $points[$noeuds[$no2-1] - 1][1];
    my $z2 = $points[$noeuds[$no2-1] - 1][2];
    my $x3 = $points[$noeuds[$no3-1] - 1][0];
    my $y3 = $points[$noeuds[$no3-1] - 1][1];
    my $z3 = $points[$noeuds[$no3-1] - 1][2];
    my $x5 = $points[$noeuds[$no5-1] - 1][0];
    my $y5 = $points[$noeuds[$no5-1] - 1][1];
    my $z5 = $points[$noeuds[$no5-1] - 1][2];
    my $vx1 = $x2 - $x1; my $vy1 = $y2 - $y1; my $vz1 = $z2 - $z1;
    my $vx2 = $x3 - $x1; my $vy2 = $y3 - $y1; my $vz2 = $z3 - $z1;
    my $vx3 = $x5 - $x1; my $vy3 = $y5 - $y1; my $vz3 = $z5 - $z1;
    my $pvx1 = ($vy1 * $vz2) - ($vz1 * $vy2);
    my $pvy1 = ($vz1 * $vx2) - ($vx1 * $vz2);
    my $pvz1 = ($vx1 * $vy2) - ($vy1 * $vx2);
    my $pv1 = ($pvx1*$vx3)+($pvy1*$vy3)+($pvz1*$vz3);
    if ($pv1 > 0.) {
        print FIS ",$no1,$no2,$no3,$no4,$no5\n";
        $corresp_num_el[$nmail1][$el1] = $num_el_unv;
    } else {
        print FIS ",$no1,$no4,$no3,$no2,$no5\n";
        $corresp_num_el[$nmail1][$el1] = -1 * $num_el_unv;
    };
    return;
}}};
#
#==========================================================================
# Ecriture d'un element PY13 (cas sans bords)
#==========================================================================
#
sub ab_PY13 
{{{
    my($nmail1, $el1) = @_;
    print FIS "$num_el_unv";
    my $no1 = $mail[$nmail1][$el1][0];
    my $no2 = $mail[$nmail1][$el1][1];
    my $no3 = $mail[$nmail1][$el1][2];
    my $no4 = $mail[$nmail1][$el1][3];
    my $no5 = $mail[$nmail1][$el1][4];
    my $no6 = $mail[$nmail1][$el1][5];
    my $no7 = $mail[$nmail1][$el1][6];
    my $no8 = $mail[$nmail1][$el1][7];
    my $no9 = $mail[$nmail1][$el1][8];
    my $no10 = $mail[$nmail1][$el1][9];
    my $no11 = $mail[$nmail1][$el1][10];
    my $no12 = $mail[$nmail1][$el1][11];
    my $no13 = $mail[$nmail1][$el1][12];
    my $x1 = $points[$noeuds[$no1-1] - 1][0];
    my $y1 = $points[$noeuds[$no1-1] - 1][1];
    my $z1 = $points[$noeuds[$no1-1] - 1][2];
    my $x2 = $points[$noeuds[$no3-1] - 1][0];
    my $y2 = $points[$noeuds[$no3-1] - 1][1];
    my $z2 = $points[$noeuds[$no3-1] - 1][2];
    my $x3 = $points[$noeuds[$no5-1] - 1][0];
    my $y3 = $points[$noeuds[$no5-1] - 1][1];
    my $z3 = $points[$noeuds[$no5-1] - 1][2];
    my $x5 = $points[$noeuds[$no13-1] - 1][0];
    my $y5 = $points[$noeuds[$no13-1] - 1][1];
    my $z5 = $points[$noeuds[$no13-1] - 1][2];
    my $vx1 = $x2 - $x1; my $vy1 = $y2 - $y1; my $vz1 = $z2 - $z1;
    my $vx2 = $x3 - $x1; my $vy2 = $y3 - $y1; my $vz2 = $z3 - $z1;
    my $vx3 = $x5 - $x1; my $vy3 = $y5 - $y1; my $vz3 = $z5 - $z1;
    my $pvx1 = ($vy1 * $vz2) - ($vz1 * $vy2);
    my $pvy1 = ($vz1 * $vx2) - ($vx1 * $vz2);
    my $pvz1 = ($vx1 * $vy2) - ($vy1 * $vx2);
    my $pv1 = ($pvx1*$vx3)+($pvy1*$vy3)+($pvz1*$vz3);
    if ($pv1 > 0.) {
        print FIS ",$no1,$no3,$no5,$no7,$no13,$no2,$no4,$no6,$no8,$no9,$no10,$no11,$no12\n";
        $corresp_num_el[$nmail1][$el1] = $num_el_unv;
    } else {
        print FIS ",$no1,$no7,$no5,$no3,$no13,$no8,$no6,$no4,$no2,$no9,$no12,$no11,$no10\n";
        $corresp_num_el[$nmail1][$el1] = -1 * $num_el_unv;
    };
    return;
}}};

#
#==========================================================================
# Ecriture des SURFACE
#==========================================================================
#
sub ab_surfac
{{{
    my($num1) = @_;
    my $nom1 = $SURFAC[$num1-1][1];
    my $nom2 = $SURFAC[$num1-1][2];
    my $nom3 = $SURFAC[$num1-1][3];
    my $val1 = 'SURF';
    my $nmail1 = $noms_mail{$nom1}-1;
    my $nmail2 = $noms_mail{$nom2}-1;
    my $typma1 = $mail_tyel[$nmail1];
    # On cherhe le nombre d'elemnt de bord à trouver
    ab_nombre($nmail2);
    if ($verb1) {print "*SURFACE DEFINITION, NAME=$nom3\n";};
    print FIS "*SURFACE DEFINITION, NAME=$nom3\n";
    if ($typma1 == 0) {
        my $nbref1 = $#{ $mail[$nmail1][1]} ;
        #print "$ELSET[$i][2] : $nbref1 types d'elements\n";
        for my $ref1 (1 .. $nbref1){
            my $nmail3 = $mail[$nmail1][1][$ref1] - 1;
            ab_sdload2($nmail3, $nmail2,$val1);
        }
    } else {
        ab_sdload2($nmail1, $nmail2,$val1);
    }
    return;
}}} ;
#
#==========================================================================
# Recherche du nombre delements bords.
#==========================================================================
#
sub ab_nombre
{{{
    my ($nmail1) = @_;
    my $typma1 = $mail_tyel[$nmail1];
    $reste = 0;
    if ($typma1 == 0) {
        my $nbref1 = $#{ $mail[$nmail1][1]} ;
        for my $ref1 (1 .. $nbref1){
            my $nmail3 = $mail[$nmail1][1][$ref1] - 1;
            $reste += $mail_nbel[$nmail3];
        }
    } else {
        $reste = $mail_nbel[$nmail1];
    }
}}};
#
#==========================================================================
# Ecriture des SDLOAD
#==========================================================================
#
sub ab_sdload   
{{{
    my($num1) = @_;
    my $nom1 = $SDLOAD[$num1-1][1];
    my $nom2 = $SDLOAD[$num1-1][2];
    my $val1 = $SDLOAD[$num1-1][3];
    my $nmail1 = $noms_mail{$nom1}-1;
    my $nmail2 = $noms_mail{$nom2}-1;
    my $typma1 = $mail_tyel[$nmail1];
    # On cherhe le nombre d'elemnt de bord à trouver
    ab_nombre($nmail2);
    #print "$num1 $nom1 $nmail1 $nom2 $nmail2\n";
    if ($verb1) {print     "*DLOAD (pression $val1 sur $nom2)\n";};
    print FIS "*DLOAD\n";
    if ($typma1 == 0) {
        my $nbref1 = $#{ $mail[$nmail1][1]} ;
        #print "$ELSET[$i][2] : $nbref1 types d'elements\n";
        for my $ref1 (1 .. $nbref1){
            my $nmail3 = $mail[$nmail1][1][$ref1] - 1;
            ab_sdload2($nmail3, $nmail2,$val1);
        }
    } else {
        ab_sdload2($nmail1, $nmail2,$val1);
    }
    return;
}}} ;
#
#==========================================================================
# Ecriture d'un SDLOAD
#==========================================================================
#
sub ab_sdload2
{{{ 
    my($nmail1,$nmail2,$val1) = @_;
    my $typma1 = $mail_tyel[$nmail1];
    my $nom_de_code = "ac_" . $typ_el_cast[$typma1]; 
    for my $el1 (0 .. ($mail_nbel[$nmail1] - 1)) {
        &$nom_de_code($nmail1,$el1,$nmail2,$val1);
        if ($reste == 0) {last};
    };
    return;
}}};
#
#
sub sortie_usage {{{
        load_usage();
        print "$help_text";
	return;
        }}};

#
#
sub load_usage {{{
        $help_text =
        "  \n".
        "========================================================  \n".
        "cast2unv.pl : convertion de maillages CAST3M vers UNV   \n".
        "Laurent CHAMPANEY                           Juillet 2003\n".
        "Franck DICOT - Roody SANSOU                             \n".
        "========================================================  \n".
        "  \n".
        "Usage :\n".
        "-----  \n".
        "  \n".
        "  Mode GUI :\n".
        "      cast2unv.pl \n".
        "  \n".
        "  Mode ligne de commande :\n".
        "      cast2unv.pl [-v][-h][-t][-s=S|P|M] nom \n".
        "  \n".
        "    lit maillage.sauv et le converti en maillage.unv, \n".
        "      en ne considerant que les maillages dont les noms\n".
        "      sont indiques dans maillage.c2a. \n".
        "    maillage.sauv est issu d'un SAUV FORMAT\n".
        "      dans castem et contient tous les maillages\n".
        "      a utiliser.\n".
        "  \n".
        "      -v donne des infos pendant l'execution\n".
        "      -t force l'utilisation du mode tridimensionnel\n".
        "      -s=... indique le type d'element utilise pour\n".
        "         les tri et quad en 3D \n".
        "          S : Thin Shell [par defaut]\n".
        "          P : Plate\n".
        "          M : Membrane\n".
        "      -h donne ces infos                    \n".
        "  \n".
        "========================================================  \n".
        "  \n".
        "Structure du fichier maillage.c2a :\n".
        "    Chaque ligne contient le nom d'un maillage à \n".
        "    transferer\n".
        "  \n".
        "========================================================  \n".
        "  \n".
        "Elements actuellement supportes :\n".
        "    - Segments 2 et 3 noeuds\n".
        "    - Triangles 3 et 6 noeuds\n".
        "    - Quadrangles 4 et 8 noeuds\n".
        "    - Tetrahèdres 4 et 10 noeuds\n".
        "    - Cubes 8 et 20 noeuds\n".
        "    - Prismes 6 et 15 noeuds\n".
        "  \n".
        "========================================================  \n".
        "  \n".
        "Regles de conversion des elements :\n".
        "  \n".
        "  Le mode de calcul est celui lu dans le fichier castem.\n".
        "  L'option -t force l'utilisation du mode tridimensionnel\n".
        "  dans la conversion des elements : les triangles et les\n".
        "  quandrangles deviennent des coques, des plaques ou\n".
        "  des membranes en fonction de l'option -s\n".
        "  \n".
        "    En axisymetrique\n".
        "          SEG2 -> Axi Linear shell\n".
        "          SEG2 -> Axi Parabolic shell\n".
        "          TRI3 -> Axi Solid Linear Triangle\n".
        "          TRI6 -> Axi Solid Parabolic Triangle\n".
        "          QUA4 -> Axi Solid Linear Quadrilateral\n".
        "          QUA8 -> Axi Solid Parabolic Quadrilateral\n".
        "    En deformations planes\n".
        "          SEG2 -> Linear Beam\n".
        "          SEG3 -> Parabolic Beam\n".
        "          TRI3 -> Plain Strain Linear Triangle\n".
        "          TRI6 -> Plain Strain Parabolic Triangle\n".
        "          QUA4 -> Plain Strain Linear Quadrilateral\n".
        "          QUA8 -> Plain Strain Parabolic Quadrilateral\n".
        "    En contraintes planes\n".
        "          SEG2 -> Linear Beam\n".
        "          SEG3 -> Parabolic Beam\n".
        "          TRI3 -> Plain Stress Linear Triangle\n".
        "          TRI6 -> Plain Stress Parabolic Triangle\n".
        "          QUA4 -> Plain Stress Linear Quadrilateral\n".
        "          QUA8 -> Plain Stress Parabolic Quadrilateral\n".
        "    en 3D\n".
        "          SEG2 -> Linear Beam\n".
        "          SEG3 -> Parabolic Beam\n".
        "          CUB8 -> Solid Linear Brick\n".
        "          CU20 -> Solid Parabolic Brick\n".
        "          PRI6 -> Solid Linear Wedge\n".
        "          PR15 -> Solid Parabolic Wedge\n".
        "          TET4 -> Solid Linear Tetrahedron\n".
        "          TE10 -> Solid Parabolic Tetrahedron\n".
        "        Option -s=S [par defaut]\n".
        "          TRI3 -> Thin Shell Linear Triangle\n".
        "          TRI6 -> Thin Shell Parabolic Triangle\n".
        "          QUA4 -> Thin Shell Linear Quadrilateral\n".
        "          QUA8 -> Thin Shell Parabolic Quadrilateral\n".
        "        Option -s=M\n".
        "          TRI3 -> Membrane Linear Triangle\n".
        "          TRI6 -> Membrane Parabolic Triangle\n".
        "          QUA4 -> Membrane Linear Quadrilateral\n".
        "          QUA8 -> Membrane Parabolic Quadrilateral\n".
        "        Option -s=P\n".
        "          TRI3 -> PLate Linear Triangle\n".
        "          TRI6 -> PLate Parabolic Triangle\n".
        "          QUA4 -> PLate Linear Quadrilateral\n".
        "          QUA8 -> PLate Parabolic Quadrilateral\n".
        "  \n".
        "========================================================  \n".
        "cast2unv.pl : convertion de maillages CAST3M vers UNV   \n".
        "Laurent CHAMPANEY                           Juillet 2003\n".
        "Franck DICOT - Roody SANSOU                             \n".
        "========================================================  \n".
        "  \n";
#
    return;
}}};
