/*
xmd - molecular dynamics for metals and ceramics
By Jonathan Rifkin <jon.rifkin@uconn.edu>
Copyright 1995-2004 Jonathan Rifkin
This program 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.
This program 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 this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*
************************************************************************
File Includes
************************************************************************
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <signal.h>
#include "iomngr.h"
#include "strsub.h"
#include "cdsubs.h"
#include "cddoc.h"
#include "cdhouse.h"
#include "cdthread.h" /* SetNumProc() */
#include "config.h" /* automake/autoconf defines */
#ifdef __TURBOC__
#include <alloc.h>
#endif
/*
************************************************************************
Defines
************************************************************************
*/
#ifdef __TURBOC__
#define SIGNUMBER 15
#else
#define SIGNUMBER SIGTERM
#endif
#define BOOLEAN int
#define FALSE 0
#define TRUE 1
/* Test ZETA calculcation in CSi calculation */
#define TEST_ZETA
#undef TEST_ZETA
/*
************************************************************************
Local Function Prototypes
************************************************************************
*/
void ihandler (int cursig);
char *newpath (char *, char *);
/*
************************************************************************
External Variables
************************************************************************
*/
/* Defined in cdsubs.c */
extern Particle_t *a,*b;
extern Simulation_t *s;
extern FILE *out;
extern LIST *inlist;
/* Signal Handler (for handling program interupts) */
int isig = 0;
/* XMD Version and Release (used to identify state files */
int XMD_Version_g = 2;
int XMD_Release_g = 5;
/* Tersoff C-Si Zeta Test */
#ifdef TEST_ZETA
double MinZeta_g;
int MinStep_g=0;
int MinI_g;
int MinJ_g;
#endif
/*
************************************************************************
Main Routine
************************************************************************
*/
int main (int argc, char *argv[])
{
/* DECLARE VARIALBES */
char instr[256];
BOOLEAN IsProgramDone;
FILE *infile;
int iopt;
int imacro;
char MacroName[2];
/* PRINT ID */
#ifdef __TURBOC__
printf ("XMD (Version %s %s) (PC)\n", VERSION, __DATE__);
#else
printf ("XMD (Version %s %s)\n",VERSION, __DATE__);
#endif
/* Thread Message */
#ifdef HAVE_LIBPTHREAD
printf ("\nUsing pthread library.\n");
#else
printf ("\nNot using pthread library.\n");
#endif
/* Patch message */
#ifdef INTEL
printf ("Using asm(\"finit\"); patch in thread routines.\n");
#endif
CheckMem_g = FALSE;
iopt = 1;
/* Read command lines options until non-option found ( '-' is non-option ) */
while (argc-iopt > 0 && argv[iopt][0]=='-' && argv[iopt][1])
{
/* Request for help */
if
(
!strcmpi("-?", argv[iopt]) ||
!strcmpi("-h", argv[iopt]) ||
!strcmpi("-help",argv[iopt])
)
{
write_doc();
return 0;
}
/* Check memory option -c */
else if (!strcmpi(argv[iopt],"-c"))
{
CheckMem_g = TRUE;
}
/* Debug option */
else if (!strcmpi(argv[iopt],"-d"))
{
Debug_g = TRUE;
}
/* Number of Thread option -pn or -p n */
else if (argv[iopt][0]=='-' && argv[iopt][1]=='p')
{
/* Number of threads is part of token */
if (argv[iopt][2]>='0' && argv[iopt][2]<='9')
{
SetNumProc (atoi(argv[iopt]+2));
}
/* Number of threads is separate token */
else
{
SetNumProc (atoi(argv[iopt+1]));
iopt++;
}
/* Print number of processors requested */
printf ("\nNumber of processors requested = %i\n", GetNumProc());
}
iopt++;
}
/* Test for incorrect input format - write messages */
if (argc-iopt==0)
{
write_usage();
return 0;
}
/* Start program timer */
StartProgramTimer();
/* Read command line macros (upto nine) */
LOOP (imacro, 9)
{
/* Don't read to many */
if (iopt+imacro+1 >= argc)
break;
/* Add Macro to list */
MacroName[0] = '1' + imacro;
MacroName[1] = '\0';
AddMacro (MacroName, argv[imacro+iopt+1]);
}
/* INITIALIZE VARIABLES */
init();
/* INSTALL SIGNAL HANDLERS */
signal (SIGINT, ihandler); /* intercepts ^C */
signal (SIGNUMBER, ihandler); /* intercepts "kill <pid>" */
/* OPEN OUTPUT FILE */
out = stdout;
/* INITIALIZE LIST OF INPUT FILES */
inlist = m_ini_list ();
/***********************/
/* READ INITIAL FILE */
/***********************/
infile = fopen ("config.xmd", "rt");
if (infile==NULL)
infile = fopen ( newpath (argv[0], "config.xmd"), "rt");
if (infile)
{
m_add_list (&inlist, infile, "f");
/* PROCESS COMMANDS */
IsProgramDone = FALSE;
while (!isig && !IsProgramDone && m_gets_list_f(instr,256,inlist)!=NULL)
{
/* ECHO STRING */
if (s->echo)
printf ("%s\n",instr);
read_command (instr, &IsProgramDone);
CHECK_HEAP
}
/* CLOSE CURRENT INPUT */
m_del_list (&inlist);
}
/*********************/
/* OPEN INPUT FILE */
/*********************/
if (!strcmp("-",argv[iopt]))
infile = stdin;
else {
infile = fopen (argv[iopt], "rt");
if (infile==NULL)
{
printf("Sorry. Cannot open %s\n",argv[iopt]);
return(1);
}
}
/* ADD TO FILE MANAGER LIST */
m_add_list (&inlist, infile, "f");
/* MOVE THROUGH FILE STACK */
while (inlist)
{
/* PROCESS COMMANDS */
IsProgramDone = FALSE;
while (!isig && !IsProgramDone && m_gets_list_f(instr,256,inlist)!=NULL)
{
/* ECHO STRING */
if (s->echo)
printf ("%s\n",instr);
/* Send command string to command function */
read_command (instr, &IsProgramDone);
CHECK_HEAP
}
/* CLOSE CURRENT INPUT */
m_del_list (&inlist);
}
/* If Termineated by External Signal save state */
if (isig==1)
CleanAfterError();
/* Call clean up routine */
CleanBeforeEnd();
#ifdef TEST_ZETA
if (Debug_g)
{
printf ("MinZeta = %le\n", MinZeta_g);
printf ("MinStep = %i\n", MinStep_g);
printf ("MinI = %i\n", MinI_g);
printf ("MinJ = %i\n", MinJ_g);
}
#endif
/* END PROGRAM */
return(0);
}
/*
************************************************************************
Local Functions
************************************************************************
*/
/*
Interupt handler (called when program recieves operating system signal
*/
void ihandler (int cursig)
{
/* SET SIGNAL FLAG */
isig = 1;
/* FLUSH BUFFERS */
fflush (stdout);
/* PRINT MESSAGE */
printf ("Interupt signal %i is caught.\n", cursig);
/* RE-INSTALL SIGNAL HANDLER */
signal (cursig, ihandler);
}
/* EXTRACT DIRECTORY PATH FROM FILE PATH */
char *newpath (char *dpath, char *fpath)
{
static char tpath[512];
char colon = ':';
#ifdef __TURBOC__
char slash = '\\';
#else
char slash = '/';
#endif
int l;
l = strlen(dpath) + strlen(fpath) + 1;
if (l==0)
return(NULL);
/* PUT DIRECTORY PATH AT FRONT */
strcpy (tpath, dpath);
l = strlen(tpath);
while (tpath[l]!=slash && tpath[l]!=colon && l>=0)
l--;
l++;
ASSERT(l>=0)
tpath[l] = 0;
/* ISOLATE FILE NAME FROM PATH */
l = strlen(fpath);
while (fpath[l]!=slash && fpath[l]!=colon && l>=0)
l--;
l++;
ASSERT(l>=0)
/* APPEND FILE NAME */
strcat (tpath, fpath+l);
/* RETURN */
return (tpath);
}