Files
mlpack/fastlib/trunk/contrib/jim/molecular_dynamics/simulation_driver.cc
T

239 lines
6.8 KiB
C++

/**
* @file simulation_driver.cc
*
* @author Jim Waters (jwaters6@gatech.edu)
*
* This program creates an instance of the LennardJones problem
* class, and updates the velocities using a leapfrogging scheme
* until a specified end time is reached.
*
* @see lennard_jones.h
*/
#include "multi_physics_system.h"
#include "particle_tree.h"
#include "raddist.h"
#define PI 3.14159265358979
#define K_B 8.63e-5 // In eV / Kelvin
const fx_entry_doc root_entries[] = {
{"dt", FX_PARAM, FX_DOUBLE, NULL,
"Specifies time step of dynamic simulation. \n"},
{"tf", FX_PARAM, FX_DOUBLE, NULL,
"Specifies duration of simulation \n"},
{"temp", FX_PARAM, FX_DOUBLE, NULL,
"Temperature of simulation. \n"},
{"pos", FX_REQUIRED, FX_STR, NULL,
"Kinematic Information of particles \n"},
{"two", FX_REQUIRED, FX_STR, NULL,
"Parameters of two-body potential function \n"},
{"rad", FX_PARAM, FX_STR, NULL,
"Name of radial distribution output \n"},
{"coord", FX_PARAM, FX_STR, NULL,
"Name of coordinate output file \n"},
{"stats", FX_PARAM, FX_STR, NULL,
"Name of stats output file \n"},
{"info", FX_PARAM, FX_INT, NULL,
"Toggles off output to screen \n"},
{"diff", FX_PARAM, FX_STR, NULL,
"Name of diffusion output file \n"},
{"snapshots", FX_PARAM, FX_INT, NULL,
"Number of snapshots for diffusion \n"},
{"three", FX_REQUIRED, FX_STR, NULL,
"Parameters fo three-body potential function \n"},
{"naive", FX_PARAM, FX_BOOL, NULL,
"Specifies whether to do naive or tree-based simulation \n"},
FX_ENTRY_DOC_DONE
};
const fx_submodule_doc md_submodules[] = {
{"param", &param_doc, "Parameters for MD-simulation \n"},
FX_SUBMODULE_DOC_DONE
};
const fx_module_doc root_doc = {
root_entries, md_submodules,
"Simulation Parameters \n"
};
int main(int argc, char *argv[])
{
fx_module *root = fx_init(argc, argv, &root_doc);
const char* fp_k;
const char* fp_l;
const char* fp_three;
const char* fp_athelp;
const char* fp_stats;
const char* fp_coords;
const char* fp_rad;
const char* fp_diff;
FILE *coords;
FILE *stats;
FILE *radial_distribution;
FILE *diff;
double time_step, stop_time, time;
int diff_tot = fx_param_int(0, "snapshots", 1);
// Input files
fp_k = fx_param_str_req(NULL, "pos");
fp_l = fx_param_str_req(NULL, "two");
fp_three = fx_param_str_req(NULL, "three");
fp_athelp = fx_param_str(NULL, "at", "at_helper.txt");
// Output Files
fp_stats = fx_param_str(NULL, "stats", "tree_stats.dat");
fp_rad = fx_param_str(NULL, "rad", "raddist.dat");
fp_coords = fx_param_str(NULL, "coord", "coords.dat");
fp_diff = fx_param_str(NULL, "diff", "diffusion.dat");
bool do_naive = fx_param_bool(NULL, "naive", 0);
coords = fopen(fp_coords, "w+");
stats = fopen(fp_stats, "w+");
radial_distribution = fopen(fp_rad, "w+");
diff = fopen(fp_diff, "w+");
Matrix atom_matrix, lj_matrix, at_matrix, at_params;
struct datanode* parameters = fx_submodule(root, "param");
time_step = fx_param_double(0, "dt", 0.1);
stop_time = fx_param_double(0, "tf", 1.0e3);
double set_temp = fx_param_double(0, "temp", -1.0);
set_temp = set_temp * (3.0*K_B);
int info = fx_param_int(0, "info", 0);
// Read Atom Matrix
data::Load(fp_k, &atom_matrix);
data::Load(fp_athelp, &at_params);
Vector signs_, powers_;
data::Load(fp_l, &lj_matrix);
data::Load(fp_three, &at_matrix);
int n_atoms = lj_matrix.n_cols();
Vector temp;
lj_matrix.MakeColumnVector(n_atoms-2, &temp);
powers_.Init(lj_matrix.n_rows());
powers_.CopyValues(temp);
temp.Destruct();
lj_matrix.MakeColumnVector(n_atoms-1, &temp);
signs_.Init(lj_matrix.n_rows());
signs_.CopyValues(temp);
lj_matrix.ResizeNoalias(n_atoms - 2);
Vector use_dims;
use_dims.Init(3);
use_dims[0] = 0;
use_dims[1] = 1;
use_dims[2] = 2;
ArrayList<Matrix> positions;
fx_timer_start(parameters, "Building Tree");
MultiPhysicsSystem simulation;
printf("\n------------------\nTree Simulation \n------------------ \n");
if (do_naive){
simulation.InitNaive(atom_matrix, parameters);
} else {
simulation.Init(atom_matrix, parameters);
}
simulation.InitStats(lj_matrix, signs_, powers_);
simulation.InitAxilrodTeller(at_matrix, at_params);
fx_timer_stop(parameters, "Building Tree");
printf("Finished Initialization. Updating Momentum. \n");
fx_timer_start(parameters, "Tree Based");
// simulation.UpdateMomentum(time_step);
time = 0;
double target_pct = 0.9;
int target_trips = 0;
RadDist tree_simulation;
tree_simulation.Init(450, 15.0);
tree_simulation.WriteHeader(radial_distribution);
double delta = 10.0, last_time = -2*delta;
int diff_count = 0;
positions.Init(diff_tot);
double temperature, diffusion = 0,pressure = 0;
while (time < stop_time){
if (diff_count < diff_tot & time > last_time + delta){
last_time = time;
positions[diff_count].Init(3, atom_matrix.n_cols());
simulation.RecordPositions(positions[diff_count]);
diff_count++;
}
double pct = simulation.GetPercent();
int trips = simulation.GetTrips();
if (unlikely(time < 2*time_step)){
target_pct = pct;
target_trips = trips;
}
simulation.UpdateMomentum(time_step);
simulation.UpdatePositions(time_step);
if (pct < 0.85*target_pct || trips > 1.1*target_trips){
simulation.RebuildTree();
simulation.ReinitStats(lj_matrix);
simulation.ReinitAxilrodTeller(at_matrix, at_params);
}
if ((int)(time / time_step -0.5) % 5 == 0){
tree_simulation.Reset();
simulation.RadialDistribution(&tree_simulation);
tree_simulation.Write(radial_distribution);
temperature = simulation.ComputeTemperature();
temperature = temperature / (3.0*K_B);
pressure = simulation.ComputePressure();
fprintf(diff, "%f, ", time);
fflush(diff);
for (int j = 0; j < diff_tot; j++){
if (j < diff_count){
diffusion = simulation.ComputeDiffusion(positions[j]);
fprintf(diff, "%f,", diffusion);
fflush(diff);
} else {
fprintf(diff, "%f,", 0.0);
fflush(diff);
}
}
fprintf(diff, "\n");
if (info){
printf("\n Time: %f \n", time);
printf("--------------\n");
printf("Temperature: %f \n", temperature);
printf("Pressure: %f \n", pressure);
printf("Percent Pruned: %f \n", pct);
printf("Triples Computed: %d \n \n", trips);
}
fprintf(stats, "%f %f %f \n", time, pressure, temperature);
fflush(stats);
if (set_temp > 0){
simulation.ScaleToTemperature(set_temp);
}
}
// simulation.UpdateMomentum(time_step);
pct = simulation.GetPercent();
time = time + time_step;
}
fx_timer_stop(parameters, "Tree_Based");
simulation.WriteData(coords);
fclose(coords);
fclose(stats);
fclose(radial_distribution);
fx_done(root);
}