import java.io.*;
import java.lang.Math;

public class Graphite2jmol {
  public static void main( String[] args ) {
    int i,j,k, icoord, iatom;

    int nXcell = 4, nYcell = 4, nZcell = 2;
    double aa = 2.456, cc = 6.696;

    double x,y,z, x_cart, y_cart, z_cart;
    double [][] base, carbon, C_cart; 
    double []   vector, tempo;
                FileOutputStream out; // declare a file output object
                FileOutputStream parsec_out; // declare a file output object
                PrintStream p; // declare a print stream object

    System.out.println("This program generates the structure of graphite");
    System.out.println("Written by carrier@cs.umn.edu");
    System.out.println("Group #194; P6(_3)/mmc");

    carbon = new double [4][3];
    C_cart = new double [4][3];

    base    = new double [3][3];
    vector  = new double [3];
    tempo   = new double [3];

// The basis
   base[0][0] = 0.5; 
   base[0][1] = -Math.sqrt(3.0)/2.0; 
   base[0][2] = 0.000;

   base[1][0] = 0.5; 
   base[1][1] =  Math.sqrt(3.0)/2.0; 
   base[1][2] = 0.000;

   base[2][0] = 0.0; 
   base[2][1] = 0.0; 
   base[2][2] = cc/aa;
    

// print the basis
    System.out.println("The lattice basis");
    System.out.printf( "%2.12f %2.12f %2.12f\n",base[0][0], base[0][1], base[0][2] );
    System.out.printf( "%2.12f %2.12f %2.12f\n",base[1][0], base[1][1], base[1][2] );
    System.out.printf( "%2.12f %2.12f %2.12f\n",base[2][0], base[2][1], base[2][2] );

// prints to file out
    try
    {
      // Create a new file output stream
      // connected to "graphene.xyz"
      out = new FileOutputStream("graphene.xyz");

      // Connect print stream to the output stream
      p = new PrintStream( out );

      p.printf ("2\n\n");

      carbon[ 0][0] = (0.   ); carbon[ 0][1] = (0.   ); carbon[ 0][2] = (1./4.); 
      carbon[ 1][0] = (1./3.); carbon[ 1][1] = (2./3.); carbon[ 1][2] = (1./4.); 
      carbon[ 2][0] = (0.   ); carbon[ 2][1] = (0.   ); carbon[ 2][2] = (3./4.); 
      carbon[ 3][0] = (2./3.); carbon[ 3][1] = (1./3.); carbon[ 3][2] = (3./4.); 

//    Transform in cartesian coordinates
      for( i = 0; i<=3; i++ ) {
         C_cart[i][0] = aa*(carbon[i][0]*base[0][0] + carbon[i][1]*base[1][0] + carbon[i][2]*base[2][0]);
         C_cart[i][1] = aa*(carbon[i][0]*base[0][1] + carbon[i][1]*base[1][1] + carbon[i][2]*base[2][1]);
         C_cart[i][2] = aa*(carbon[i][0]*base[0][2] + carbon[i][1]*base[1][2] + carbon[i][2]*base[2][2]);
      }

      for( i = 0; i<=3; i++ ) {
         p.printf ("C  %2.8f  %2.8f  %2.8f\n",C_cart[i][0], C_cart[i][1], C_cart[i][2]);
      }

      p.close();
    }
    catch (Exception e)
    {
      System.err.println ("Error writing to file O2Si.xyz");
    }

// supercell generation next
    try
    { 
      // Create a new file output stream
      // connected to "supercell.xyz"
      out = new FileOutputStream("supercell.xyz");
      
      // Connect print stream to the output stream
      p = new PrintStream( out );
      
      p.println ( 4*(nXcell+1)*(nYcell+1)*(nZcell+1) );    
      p.println();
      for(iatom=0 ; iatom<=3; iatom++ ) {
        for( i=0 ; i<=nXcell; i++ ) {
          for( j=0 ; j<=nYcell; j++ ) {
            for( k=0 ; k<=nZcell; k++ ) {
              for( icoord=0; icoord <=2; icoord++) {
                 tempo[icoord] = (carbon[iatom][0] + i)*base[0][icoord] 
                               + (carbon[iatom][1] + j)*base[1][icoord]
                               + (carbon[iatom][2] + k)*base[2][icoord];
              }
              p.printf ("C   %2.8f  %2.8f  %2.8f\n",tempo[0]*aa, tempo[1]*aa, tempo[2]*aa);
            }
          }
        }
      }
      p.close();
    }
    catch (Exception e)
    {
      System.err.println ("Error writing to file");
    }

  }
}
