Page MenuHomec4science

system.cpp
No OneTemporary

File Metadata

Created
Wed, Sep 11, 05:39

system.cpp

/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
www.cs.sandia.gov/~sjplimp/lammps.html
Steve Plimpton, sjplimp@sandia.gov, Sandia National Laboratories
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#include "mpi.h"
#include "string.h"
#include "system.h"
#include "memory.h"
#include "error.h"
#include "universe.h"
#include "input.h"
#include "atom.h"
#include "update.h"
#include "neighbor.h"
#include "comm.h"
#include "domain.h"
#include "force.h"
#include "modify.h"
#include "group.h"
#include "output.h"
#include "timer.h"
/* ----------------------------------------------------------------------
allocate fundamental classes (memory, error, universe, input)
parse input switches
initialize communicators, screen & logfile output
input is allocated at end after MPI info is setup
------------------------------------------------------------------------- */
void System::open(int narg, char **arg, MPI_Comm communicator)
{
memory = new Memory;
error = new Error;
universe = new Universe(communicator);
// parse input switches
int inflag = 0;
int screenflag = 0;
int logflag = 0;
int iarg = 1;
while (iarg < narg) {
if (strcmp(arg[iarg],"-partition") == 0) {
if (iarg+1 > narg)
error->universe_all("Invalid command-line argument");
iarg++;
while (iarg < narg && arg[iarg][0] != '-') {
universe->add_world(arg[iarg]);
iarg++;
}
} else if (strcmp(arg[iarg],"-in") == 0) {
if (iarg+2 > narg)
error->universe_all("Invalid command-line argument");
inflag = iarg + 1;
iarg += 2;
} else if (strcmp(arg[iarg],"-screen") == 0) {
if (iarg+2 > narg)
error->universe_all("Invalid command-line argument");
screenflag = iarg + 1;
iarg += 2;
} else if (strcmp(arg[iarg],"-log") == 0) {
if (iarg+2 > narg)
error->universe_all("Invalid command-line argument");
logflag = iarg + 1;
iarg += 2;
} else if (strcmp(arg[iarg],"-var") == 0) {
if (iarg+3 > narg)
error->universe_all("Invalid command-line argument");
iarg += 3;
} else if (strcmp(arg[iarg],"-echo") == 0) {
if (iarg+2 > narg)
error->universe_all("Invalid command-line argument");
iarg += 2;
} else error->universe_all("Invalid command-line argument");
}
// if procs was not a command-line switch, universe is one world w/ all procs
if (universe->nworlds == 0) universe->add_world(NULL);
// sum of procs in all worlds must equal total # of procs
if (!universe->consistent())
error->universe_all("Processor partitions are inconsistent");
// multiple-world universe must define input file
if (universe->nworlds > 1 && inflag == 0)
error->universe_all("Must use -in switch with multiple partitions");
// set universe screen and logfile
if (universe->me == 0) {
if (screenflag == 0)
universe->uscreen = stdout;
else if (strcmp(arg[screenflag],"none") == 0)
universe->uscreen = NULL;
else {
universe->uscreen = fopen(arg[screenflag],"w");
if (universe->uscreen == NULL)
error->universe_one("Cannot open universe screen file");
}
if (logflag == 0) {
universe->ulogfile = fopen("log.lammps","w");
if (universe->ulogfile == NULL)
error->universe_one("Cannot open log.lammps");
} else if (strcmp(arg[logflag],"none") == 0)
universe->ulogfile = NULL;
else {
universe->ulogfile = fopen(arg[logflag],"w");
if (universe->ulogfile == NULL)
error->universe_one("Cannot open universe log file");
}
}
if (universe->me > 0) {
if (screenflag == 0) universe->uscreen = stdout;
else universe->uscreen = NULL;
universe->ulogfile = NULL;
}
// universe is single world
// inherit settings from universe
// set world screen, logfile, communicator, infile
// open input script if from file
if (universe->nworlds == 1) {
screen = universe->uscreen;
logfile = universe->ulogfile;
world = universe->uworld;
infile = NULL;
if (universe->me == 0) {
if (inflag == 0) infile = stdin;
else infile = fopen(arg[inflag],"r");
if (infile == NULL) {
char str[128];
sprintf(str,"Cannot open input script %s",arg[inflag]);
error->one(str);
}
}
if (universe->me == 0) {
if (screen) fprintf(screen,"LAMMPS (%s)\n",universe->version);
if (logfile) fprintf(logfile,"LAMMPS (%s)\n",universe->version);
}
// universe is multiple worlds
// split into separate communicators
// set world screen, logfile, communicator, infile
// open input script
} else {
int me;
MPI_Comm_split(universe->uworld,universe->iworld,0,&world);
MPI_Comm_rank(world,&me);
if (me == 0) {
if (screenflag == 0) {
char str[32];
sprintf(str,"screen.%d",universe->iworld);
screen = fopen(str,"w");
if (screen == NULL) error->one("Cannot open screen file");
} else if (strcmp(arg[screenflag],"none") == 0)
screen = NULL;
else {
char str[128];
sprintf(str,"%s.%d",arg[screenflag],universe->iworld);
screen = fopen(str,"w");
if (screen == NULL) error->one("Cannot open screen file");
}
} else screen = NULL;
if (me == 0) {
if (logflag == 0) {
char str[32];
sprintf(str,"log.lammps.%d",universe->iworld);
logfile = fopen(str,"w");
if (logfile == NULL) error->one("Cannot open logfile");
} else if (strcmp(arg[logflag],"none") == 0)
logfile = NULL;
else {
char str[128];
sprintf(str,"%s.%d",arg[logflag],universe->iworld);
logfile = fopen(str,"w");
if (logfile == NULL) error->one("Cannot open logfile");
}
} else logfile = NULL;
if (me == 0) {
infile = fopen(arg[inflag],"r");
if (infile == NULL) {
char str[128];
sprintf(str,"Cannot open input script %s",arg[inflag]);
error->one(str);
}
} else infile = NULL;
// screen and logfile messages for universe and world
if (universe->me == 0) {
if (universe->uscreen) {
fprintf(universe->uscreen,"LAMMPS (%s)\n",universe->version);
fprintf(universe->uscreen,"Running on %d partitions of processors\n",
universe->nworlds);
}
if (universe->ulogfile) {
fprintf(universe->ulogfile,"LAMMPS (%s)\n",universe->version);
fprintf(universe->ulogfile,"Running on %d partitions of processors\n",
universe->nworlds);
}
}
if (me == 0) {
if (screen) {
fprintf(screen,"LAMMPS (%s)\n",universe->version);
fprintf(screen,"Processor partition = %d\n",universe->iworld);
}
if (logfile) {
fprintf(logfile,"LAMMPS (%s)\n",universe->version);
fprintf(logfile,"Processor partition = %d\n",universe->iworld);
}
}
}
// allocate input class now that MPI is fully setup
input = new Input(narg,arg);
}
/* ----------------------------------------------------------------------
allocate single instance of top-level classes
fundamental classes are allocated in open()
atom is allocated via input script
------------------------------------------------------------------------- */
void System::create()
{
neighbor = new Neighbor;
comm = new Comm;
domain = new Domain;
group = new Group;
force = new Force; // must be after group, to create temperature
modify = new Modify;
output = new Output; // must be after group, so "all" exists
update = new Update; // must be after output, force, neighbor
timer = new Timer;
}
/* ----------------------------------------------------------------------
init top-level classes
------------------------------------------------------------------------- */
void System::init()
{
update->init();
force->init();
domain->init();
atom->init(); // atom must come after force:
// atom deletes extra array
// used by fix shear_history::unpack_restart()
// when force->pair->gran_history creates fix ??
modify->init(); // modify must come after update, force, atom
neighbor->init(); // neighbor must come after force, modify (due to min)
output->init(); // output must come after domain, force, modify
comm->init(); // comm must come after force, modify
timer->init();
}
/* ----------------------------------------------------------------------
delete single instance of top-level classes
fundamental classes are deleted in close()
------------------------------------------------------------------------- */
void System::destroy()
{
if (atom) delete atom;
atom = NULL;
delete update;
delete neighbor;
delete comm;
delete domain;
delete force;
delete group;
delete output;
delete modify; // modify must come after output, force, update
delete timer;
}
/* ----------------------------------------------------------------------
shutdown system
close screen and log files in world and universe
output files were already closed in system::destroy()
delete fundamental classes
------------------------------------------------------------------------- */
void System::close()
{
if (universe->nworlds == 1) {
if (logfile) fclose(logfile);
} else {
if (screen && screen != stdout) fclose(screen);
if (logfile) fclose(logfile);
if (universe->ulogfile) fclose(universe->ulogfile);
}
if (world != universe->uworld) MPI_Comm_free(&world);
delete input;
delete universe;
delete error;
delete memory;
}

Event Timeline