C – Translate The Coordinates Along Any Given Axis

Disclaimer

The instructions/steps/scripts/methods given below worked for me running CentOS and various other distributions. It may very well work for you on other linux distributions, Red Hat-like or otherwise. Please note that if you decide to use these instructions on your machine, you are doing so entirely at your very own discretion and that neither this site, sgowtham.com, nor its author is responsible for any/all damage – intellectual or otherwise.


What is C?

In computing, C is a general-purpose, cross-platform, block structured, procedural, imperative computer programming language developed in 1972 by Dennis Ritchie at the Bell Telephone Laboratories for use with the Unix operating system. Although C was designed for implementing system software, it is also used for developing application software – on a great many different software platforms and computer architectures, and several popular compilers exist. C has greatly influenced many other popular programming languages, most notably C++, which originally began as an extension to C. C is an imperative (procedural) systems implementation language. It was designed to be compiled using a relatively straightforward compiler, to provide low-level access to memory, to provide language constructs that map efficiently to machine instructions, and to require minimal run-time support. C was therefore useful for many applications that had formerly been coded in assembly language. Despite its low-level capabilities, the language was designed to encourage machine-independent programming. A standards-compliant and portably written C program can be compiled for a very wide variety of computer platforms and operating systems with little or no change to its source code. The language has become available on a very wide range of platforms, from embedded microcontrollers to supercomputers.


The Program

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 
This program shifts x, y, z co-ordinates of any system based on
the value of dx, dy, dz and writes the new set of (x,y,z) in a new
file. 
 
INPUT :
 
Input file must have the name 'shift-xyz-input.xyz' and (x,y,z) 
co-ordinates must be in the following format (space or tab separated)
 
First Line   : Number of atoms, N
Next N Lines : x, y, z of each atom
 
DESCRIPTION OF VARIABLES :
 
Nbuf     First line of the input file, stored as string
Abuf     Atomic Number of the atom, stored as string
xbuf     x co-ordinate of the atom, stored as string
ybuf     y co-ordinate of the atom, stored as string
zbuf     z co-ordinate of the atom, stored as string
 
N        Nbuf converted to integer, using atoi()
         Number of atoms
 
Atom[i]  Abuf converted to integer, using atoi()
         One dimensional array for atomic number of N atoms  
 
x[i]     xbuf converted to double precision number, using atof()
         One dimensional array for storing x co-ordinate of N atoms  
 
y[i]     ybuf converted to double precision number, using atof()
         One dimensional array for storing y co-ordinate of N atoms   
 
z[i]     zbuf converted to double precision number, using atof()
         One dimensional array for storing z co-ordinate of N atoms
 
 
COMPILATION/EXECUTION PROCEDURE :
 
gcc -o shift-xyz.x shift-xyz.c -lm
./shift-xyz.x
 
OUTPUT :
 
If the compilation and execution is successful, the program writes an output 
file named in 'shift-xyz-ouput.xyz' format with shifted (x,y,z) co-ordinates
 
Thu Dec 22 21:22:51 EST 2005
 
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
 
main()
{
 
/* Defines input and output files */
  FILE *input;
  FILE *output;
 
/* Declaration and initialization of variables */
  char   Nbuf[100]={'\0'};
  char   Abuf[100]={'\0'};
  char   xbuf[100]={'\0'};
  char   ybuf[100]={'\0'};
  char   zbuf[100]={'\0'};
 
  int      Atom[100]={0};
  double   x[100]={0};
  double   y[100]={0};
  double   z[100]={0};
 
  int     i, N;
  double  dx, dy, dz;
 
  dx=0.500;  /* Change this value to indicate dx */
  dy=0.500;  /* Change this value to indicate dy */
  dz=0.500;  /* Change this value to indicate dz */
 
/* Opens the input file for reading */
  input = fopen("shift-xyz-input.xyz", "r");
 
  if (input == NULL) {
    printf("\nInput File empty or corrupted! Exiting...\n");
    exit (1);
  }
 
/* Creates the output file and opens it for writing */
  output = fopen("shift-xyz-ouput.xyz", "w");
 
/* Reads the first line of the input file and stores it as N */
  fscanf(input, "%s", Nbuf);
  N = atoi(Nbuf);
 
/* Reads and stores the (x, y, z) for each atom, first as a string (buffer) 
  and later stores it as an array element using appropriate conversion 
  mechanism */
  for(i=0; i<N; i++) {
    fscanf(input, "%s", Abuf);
    Atom[i]= atoi(Abuf);
 
    fscanf(input, "%s", xbuf);
    x[i]= atof(xbuf);
 
    fscanf(input, "%s", ybuf);
    y[i]= atof(ybuf);
 
    fscanf(input, "%s", zbuf);
    z[i]= atof(zbuf);
  }
 
/* Calculates the new x and y co-odrinates of atoms based on the value of
  dx, dy and dz */
  for(i=0; i<N; i++)  {
    x[i] = x[i] + dx;
    y[i] = y[i] + dy;
    z[i] = z[i] + dz;
  }
 
/* Final values are written in the output file */
  fprintf(output, "%d\n", N);
 
  for(i=0; i<N; i++){
    fprintf(output, "%d",       Atom[i]);
    fprintf(output, "\t%lf",    x[i]);
    fprintf(output, "\t%lf",    y[i]);
    fprintf(output, "\t%lf\n",  z[i]);
  }
 
/* Closes the input and output files */
  fclose(input);
  fclose(output);
 
/* Confirmation to the user */
  printf("Please open shift-xyz-output.xyz for results\n\n");
 
/* Program Ends */
}


The Input File Format

1
2
3
4
5
6
7
6
6   1.000000    0.000000        0.000000
6   2.000000  0.000000  0.000000
1   3.000000  0.000000  0.000000
1   4.000000  0.000000  0.000000
8   5.000000  0.000000  0.000000
8   6.000000  0.000000  0.000000

VASP, MPICH, Intel Compilers and Rocks

Much of the weekend was spent in some relaxation, shoveling snow (I have come to realize that this is a very good exercise – it can make one sweat even when it’s +10F outside!) and trying to debug the errors associated with execution of parallel version of VASP 4.6.28. However, same errors persisted and I didn’t go too far ahead with it.

I got in touch with few of Intel’s authorized resellers (one in Bloomington, MN – who transferred the call to someone else in Boston, MA) to see if I can get a copy of version 8.x of FORTRAN and C compilers. Though the latter person promised to get back to me with some favorable information soon, I got directly in touch with an Intel Support Technician – hoping that he/she wouldn’t be from a call center in some other country. Fortunately, it was somebody in California and unfortunately, he redirected me back to their re-sellers. Last call, pretty much out of desperation, did what I needed: I just had to register the non-commercially downloaded products for Premier Support and I would be entitled for previous versions too. If only Intel explicitly mentioned what Premier Support actually is, my worries would have ended a long time ago. By the way, if you are now wondering what the error message was (running on 2 processors), here it is:


1
2
3
4
5
6
7
8
9
10
11
12
13
running on    2 nodes
distr:  one band on    1 nodes,    2 groups
vasp.4.6.28 25Jul05 complex
POSCAR found :  4 types and   18 ions
LDA part: xc-table for Ceperly-Alder, standard interpolation
found WAVECAR, reading the header
POSCAR, INCAR and KPOINTS ok, starting setup
WARNING: wrap around errors must be expected
FFT: planning ...           1
reading WAVECAR
the WAVECAR file was read sucessfully
LAPACK: Routine ZPOTRF failed!           8
LAPACK: Routine ZPOTRF failed!           8

Having managed to get version 8.x and 7.x of Intel compilers, situation only got worse as the error message remained the same. At this point, I must thank the help offered by VASP Tech Support and Andri Arnaldsson (from University of Washington) – they have been pretty quick in their responses, sent their copies of Makefiles along with several tips and tricks. Changing compiler versions, using a previous version of MPICH (1.2.7p1 to be precise), repeating compilation many times with different BLAS, LAPACK libraries — nothing helped.

Taking a break for an hour and watching an episode of South Park seemed to have helped. A modification in the key words used for Google! search and reading some discussion forum a lot more carefully, I found that adding three lines at the end of VASP Makefile (what this does is to reduce the level of optimization for mpi.F), the error vanished and the calculations started running smoothly.

I repeated the same calculation using 2, 4, 6 and 8 processors and noticed a slightly strange behavior – when the number of processors was 2, 4 or 8, energy optimization is exactly same as in a serial calculation but when the number of processors is 2*N (N=3 in this case), energy optimization route is different – final result is still exactly the same. Though I have to do more trials (say 3, 5, 7, 9, 10 processors) to completely convince myself, it appears to me that using 2N processors does the trick. Like Dave Kraus mentioned once before – knowing what trick works is certainly important, but knowing why that trick works is even more important.

300+ compilation attempts spanning over six (yes, SIX) months of day in and day out, 14+ hour days to get (the Makefile with necessary flags and libraries for) one software suite compiled and tested successfully. The timing of this successful attempt can’t be just a coincidence — I sure do believe in Santa Claus and Christmas miracles, and am forever grateful to my advisor’s endless patience throughout these six months.

BASH – Login Counter

Disclaimer

The instructions/steps/scripts/methods given below worked for me running CentOS. It may very well work for you on other linux distributions, Red Hat-like or otherwise. Please note that if you decide to use these instructions on your machine, you are doing so entirely at your very own discretion and that neither this site, sgowtham.com, nor its author is responsible for any/all damage – intellectual or otherwise.


What is BASH and AWK?

BASH is a free software Unix shell written for the GNU Project. Its name is an acronym which stands for Bourne-again shell. The name is a pun on the name of the Bourne shell (sh), an early and important UNIX shell written by Stephen Bourne and distributed with Version 7 UNIX circa 1978, and the concept of being born again. BASH was created in 1987 by Brian Fox. In 1990 Chet Ramey became the primary maintainer. BASH is the default shell on most GNU/Linux systems as well as on Mac OS X and it can be run on most UNIX-like operating systems. It has also been ported to Microsoft Windows using the POSIX emulation provided by Cygwin, to MS-DOS by the DJGPP project and to Novell NetWare.

AWK is a general purpose programming language that is designed for processing text-based data, either in files or data streams, and was created at Bell Labs in the 1970s. The name AWK is derived from the family names of its authors — Alfred Aho, Peter Weinberger, and Brian Kernighan; however, it is not commonly pronounced as a string of separate letters but rather to sound the same as the name of the bird, auk. awk, when written in all lowercase letters, refers to the UNIX or Plan 9 program that runs other programs written in the AWK programming language. AWK is an example of a programming language that extensively uses the string data type, associative arrays (that is, arrays indexed by key strings), and regular expressions. The power, terseness, and limitations of AWK programs and sed scripts inspired Larry Wall to write PERL. Because of their dense notation, all these languages are often used for writing one-liner programs. AWK is one of the early tools to appear in Version 7 UNIX and gained popularity as a way to add computational features to a UNIX pipeline. A version of the AWK language is a standard feature of nearly every modern UNIX-like operating system.


The Script

1
2
3
4
5
6
7
8
9
#! /bin/bash
# 
# Displays the number of login attempts by users
# Gowtham, 2005.09.23
 
echo
echo " `hostname` login attempts by users in this month"
echo
last | awk '{print $1}' | sort | uniq -c | sort -nr