diff --git a/PuReMD/src/control.c b/PuReMD/src/control.c index f0f6ea0cb9780311237da174b07a743f6b29ca9b..e0e0e86d2999e7bdb1350b0c59921584b2655533 100644 --- a/PuReMD/src/control.c +++ b/PuReMD/src/control.c @@ -20,12 +20,13 @@ ----------------------------------------------------------------------*/ #include "reax_types.h" + #if defined(PURE_REAX) -#include "control.h" -#include "tool_box.h" + #include "control.h" + #include "tool_box.h" #elif defined(LAMMPS_REAX) -#include "reax_control.h" -#include "reax_tool_box.h" + #include "reax_control.h" + #include "reax_tool_box.h" #endif @@ -34,51 +35,58 @@ char Read_Control_File( char *control_file, control_params* control, { FILE *fp; char *s, **tmp; - int c, i, ival; - real val; + int c, i, ival; + real val; - /* open control file */ - if ( (fp = fopen( control_file, "r" ) ) == NULL ) - { - fprintf( stderr, "error opening the control file! terminating...\n" ); - MPI_Abort( MPI_COMM_WORLD, FILE_NOT_FOUND ); - } + fp = sfopen( control_file, "r", "Read_Control_File::fp" ); /* assign default values */ - strcpy( control->sim_name, "simulate" ); - control->ensemble = NVE; - control->nsteps = 0; - control->dt = 0.25; - control->nprocs = 1; + strcpy( control->sim_name, "default.sim" ); + control->ensemble = NVE; + control->nsteps = 0; + control->dt = 0.25; + control->nprocs = 1; control->procs_by_dim[0] = 1; control->procs_by_dim[1] = 1; control->procs_by_dim[2] = 1; control->geo_format = 1; - control->restart = 0; + control->random_vel = 0; + control->restart = 0; out_control->restart_format = WRITE_BINARY; out_control->restart_freq = 0; control->reposition_atoms = 0; - control->restrict_bonds = 0; - control->remove_CoM_vel = 25; - out_control->debug_level = 0; + control->restrict_bonds = 0; + control->remove_CoM_vel = 25; + out_control->debug_level = 0; out_control->energy_update_freq = 0; control->reneighbor = 1; - control->vlist_cut = control->nonb_cut; control->bond_cut = 5.0; + control->vlist_cut = control->nonb_cut; control->bg_cut = 0.3; control->thb_cut = 0.001; control->hbond_cut = 0.0; control->tabulate = 0; - control->qeq_freq = 1; + control->charge_method = QEQ_CM; + control->charge_freq = 1; + control->cm_q_net = 0.0; + control->cm_solver_type = GMRES_S; control->cm_solver_max_iters = 100; - control->q_err = 1e-6; - control->sai_thres = 0.1; - control->refactor = 100; - control->droptol = 1e-2;; + control->cm_solver_restart = 50; + control->cm_solver_q_err = 0.000001; + control->cm_domain_sparsify_enabled = FALSE; + control->cm_init_guess_extrap1 = 3; + control->cm_init_guess_extrap2 = 2; + control->cm_domain_sparsity = 1.0; + control->cm_solver_pre_comp_type = JACOBI_PC; + control->cm_solver_pre_comp_sweeps = 3; + control->cm_solver_pre_comp_refactor = 100; + control->cm_solver_pre_comp_droptol = 0.01; + control->cm_solver_pre_app_type = TRI_SOLVE_PA; + control->cm_solver_pre_app_jacobi_iters = 50; control->T_init = 0.; control->T_final = 300.; @@ -110,355 +118,435 @@ char Read_Control_File( char *control_file, control_params* control, control->restrict_type = 0; /* memory allocations */ - s = (char*) malloc(sizeof(char) * MAX_LINE); - tmp = (char**) malloc(sizeof(char*)*MAX_TOKENS); + s = (char*) smalloc( sizeof(char) * MAX_LINE, "Read_Control_File::s", MPI_COMM_WORLD ); + tmp = (char**) smalloc( sizeof(char*) * MAX_TOKENS, "Read_Control_File::tmp", MPI_COMM_WORLD ); for (i = 0; i < MAX_TOKENS; i++) - tmp[i] = (char*) malloc(sizeof(char) * MAX_LINE); + { + tmp[i] = (char*) smalloc( sizeof(char) * MAX_LINE, "Read_Control_File::tmp[i]", MPI_COMM_WORLD ); + } /* read control parameters file */ while ( fgets( s, MAX_LINE, fp ) ) { c = Tokenize( s, &tmp ); - //fprintf( stderr, "%s\n", s ); - if ( strcmp(tmp[0], "simulation_name") == 0 ) - { - strcpy( control->sim_name, tmp[1] ); - } - else if ( strcmp(tmp[0], "ensemble_type") == 0 ) - { - ival = atoi(tmp[1]); - control->ensemble = ival; - if ( ival == iNPT || ival == sNPT || ival == NPT ) - control->virial = 1; - } - else if ( strcmp(tmp[0], "nsteps") == 0 ) - { - ival = atoi(tmp[1]); - control->nsteps = ival; - } - else if ( strcmp(tmp[0], "dt") == 0) - { - val = atof(tmp[1]); - control->dt = val * 1.e-3; // convert dt from fs to ps! - } - else if ( strcmp(tmp[0], "proc_by_dim") == 0 ) + if ( c > 0 ) { - ival = atoi(tmp[1]); - control->procs_by_dim[0] = ival; - ival = atoi(tmp[2]); - control->procs_by_dim[1] = ival; - ival = atoi(tmp[3]); - control->procs_by_dim[2] = ival; + if ( strcmp(tmp[0], "simulation_name") == 0 ) + { + strcpy( control->sim_name, tmp[1] ); + } + else if ( strcmp(tmp[0], "ensemble_type") == 0 ) + { + ival = atoi(tmp[1]); + control->ensemble = ival; + } + else if ( strcmp(tmp[0], "nsteps") == 0 ) + { + ival = atoi(tmp[1]); + control->nsteps = ival; + } + else if ( strcmp(tmp[0], "dt") == 0) + { + val = atof(tmp[1]); + control->dt = val * 1.e-3; // convert dt from fs to ps! + } + else if ( strcmp(tmp[0], "proc_by_dim") == 0 ) + { + if ( c < 4 ) + { + fprintf( stderr, "[ERROR] invalid number of control file parameters (procs_by_dim). terminating!\n" ); + MPI_Abort( MPI_COMM_WORLD, INVALID_INPUT ); + } - control->nprocs = control->procs_by_dim[0] * control->procs_by_dim[1] * - control->procs_by_dim[2]; - } - //else if( strcmp(tmp[0], "restart") == 0 ) { - // ival = atoi(tmp[1]); - // control->restart = ival; - //} - //else if( strcmp(tmp[0], "restart_from") == 0 ) { - // strcpy( control->restart_from, tmp[1] ); - //} - else if ( strcmp(tmp[0], "random_vel") == 0 ) - { - ival = atoi(tmp[1]); - control->random_vel = ival; - } - else if ( strcmp(tmp[0], "restart_format") == 0 ) - { - ival = atoi(tmp[1]); - out_control->restart_format = ival; - } - else if ( strcmp(tmp[0], "restart_freq") == 0 ) - { - ival = atoi(tmp[1]); - out_control->restart_freq = ival; - } - else if ( strcmp(tmp[0], "reposition_atoms") == 0 ) - { - ival = atoi(tmp[1]); - control->reposition_atoms = ival; - } - else if ( strcmp(tmp[0], "restrict_bonds") == 0 ) - { - ival = atoi( tmp[1] ); - control->restrict_bonds = ival; - } - else if ( strcmp(tmp[0], "remove_CoM_vel") == 0 ) - { - ival = atoi(tmp[1]); - control->remove_CoM_vel = ival; - } - else if ( strcmp(tmp[0], "debug_level") == 0 ) - { - ival = atoi(tmp[1]); - out_control->debug_level = ival; - } - else if ( strcmp(tmp[0], "energy_update_freq") == 0 ) - { - ival = atoi(tmp[1]); - out_control->energy_update_freq = ival; - } - else if ( strcmp(tmp[0], "reneighbor") == 0 ) - { - ival = atoi( tmp[1] ); - control->reneighbor = ival; - control->refactor = ival; - } - else if ( strcmp(tmp[0], "vlist_buffer") == 0 ) - { - val = atof(tmp[1]); - control->vlist_cut = val + control->nonb_cut; - } - else if ( strcmp(tmp[0], "nbrhood_cutoff") == 0 ) - { - val = atof(tmp[1]); - control->bond_cut = val; - } - else if ( strcmp(tmp[0], "bond_graph_cutoff") == 0 ) - { - val = atof(tmp[1]); - control->bg_cut = val; - } - else if ( strcmp(tmp[0], "thb_cutoff") == 0 ) - { - val = atof(tmp[1]); - control->thb_cut = val; - } - else if ( strcmp(tmp[0], "hbond_cutoff") == 0 ) - { - val = atof( tmp[1] ); - control->hbond_cut = val; - } - else if ( strcmp(tmp[0], "ghost_cutoff") == 0 ) - { - val = atof(tmp[1]); - control->user_ghost_cut = val; - } - else if ( strcmp(tmp[0], "tabulate_long_range") == 0 ) - { - ival = atoi( tmp[1] ); - control->tabulate = ival; - } - else if ( strcmp(tmp[0], "qeq_freq") == 0 ) - { - ival = atoi( tmp[1] ); - control->qeq_freq = ival; - } - else if ( strcmp(tmp[0], "cm_solver_max_iters") == 0 ) - { - ival = atoi( tmp[1] ); - control->cm_solver_max_iters = ival; - } - else if ( strcmp(tmp[0], "q_err") == 0 ) - { - val = atof( tmp[1] ); - control->q_err = val; - } - else if ( strcmp(tmp[0], "cm_solver_pre_comp_type") == 0 ) - { - val = atoi( tmp[1] ); - control->cm_solver_pre_comp_type = val; - } - else if ( strcmp(tmp[0], "sai_thres") == 0 ) - { - val = atof( tmp[1] ); - control->sai_thres = val; - } - else if ( strcmp(tmp[0], "ilu_refactor") == 0 ) - { - ival = atoi( tmp[1] ); - control->refactor = ival; - } - else if ( strcmp(tmp[0], "ilu_droptol") == 0 ) - { - val = atof( tmp[1] ); - control->droptol = val; - } - else if ( strcmp(tmp[0], "temp_init") == 0 ) - { - val = atof(tmp[1]); - control->T_init = val; + ival = atoi(tmp[1]); + control->procs_by_dim[0] = ival; + ival = atoi(tmp[2]); + control->procs_by_dim[1] = ival; + ival = atoi(tmp[3]); + control->procs_by_dim[2] = ival; - if ( control->T_init < 0.1 ) - control->T_init = 0.1; - } - else if ( strcmp(tmp[0], "temp_final") == 0 ) - { - val = atof(tmp[1]); - control->T_final = val; + control->nprocs = control->procs_by_dim[0] * control->procs_by_dim[1] * + control->procs_by_dim[2]; + } + //else if( strcmp(tmp[0], "restart") == 0 ) { + // ival = atoi(tmp[1]); + // control->restart = ival; + //} + //else if( strcmp(tmp[0], "restart_from") == 0 ) { + // strcpy( control->restart_from, tmp[1] ); + //} + else if ( strcmp(tmp[0], "random_vel") == 0 ) + { + ival = atoi(tmp[1]); + control->random_vel = ival; + } + else if ( strcmp(tmp[0], "restart_format") == 0 ) + { + ival = atoi(tmp[1]); + out_control->restart_format = ival; + } + else if ( strcmp(tmp[0], "restart_freq") == 0 ) + { + ival = atoi(tmp[1]); + out_control->restart_freq = ival; + } + else if ( strcmp(tmp[0], "reposition_atoms") == 0 ) + { + ival = atoi(tmp[1]); + control->reposition_atoms = ival; + } + else if ( strcmp(tmp[0], "restrict_bonds") == 0 ) + { + ival = atoi( tmp[1] ); + control->restrict_bonds = ival; + } + else if ( strcmp(tmp[0], "remove_CoM_vel") == 0 ) + { + ival = atoi(tmp[1]); + control->remove_CoM_vel = ival; + } + else if ( strcmp(tmp[0], "debug_level") == 0 ) + { + ival = atoi(tmp[1]); + out_control->debug_level = ival; + } + else if ( strcmp(tmp[0], "energy_update_freq") == 0 ) + { + ival = atoi(tmp[1]); + out_control->energy_update_freq = ival; + } + else if ( strcmp(tmp[0], "reneighbor") == 0 ) + { + ival = atoi( tmp[1] ); + control->reneighbor = ival; + } + else if ( strcmp(tmp[0], "vlist_buffer") == 0 ) + { + val = atof(tmp[1]); + control->vlist_cut = val + control->nonb_cut; + } + else if ( strcmp(tmp[0], "nbrhood_cutoff") == 0 ) + { + val = atof(tmp[1]); + control->bond_cut = val; + } + else if ( strcmp(tmp[0], "bond_graph_cutoff") == 0 ) + { + val = atof(tmp[1]); + control->bg_cut = val; + } + else if ( strcmp(tmp[0], "thb_cutoff") == 0 ) + { + val = atof(tmp[1]); + control->thb_cut = val; + } + else if ( strcmp(tmp[0], "hbond_cutoff") == 0 ) + { + val = atof( tmp[1] ); + control->hbond_cut = val; + } + else if ( strcmp(tmp[0], "ghost_cutoff") == 0 ) + { + val = atof(tmp[1]); + control->user_ghost_cut = val; + } + else if ( strcmp(tmp[0], "tabulate_long_range") == 0 ) + { + ival = atoi( tmp[1] ); + control->tabulate = ival; + } + else if ( strcmp(tmp[0], "charge_method") == 0 ) + { + ival = atoi( tmp[1] ); + control->charge_method = ival; + } + else if ( strcmp(tmp[0], "charge_freq") == 0 ) + { + ival = atoi( tmp[1] ); + control->charge_freq = ival; + } + else if ( strcmp(tmp[0], "cm_q_net") == 0 ) + { + val = atof( tmp[1] ); + control->cm_q_net = val; + } + else if ( strcmp(tmp[0], "cm_solver_type") == 0 ) + { + ival = atoi( tmp[1] ); + control->cm_solver_type = ival; + } + else if ( strcmp(tmp[0], "cm_solver_max_iters") == 0 ) + { + ival = atoi( tmp[1] ); + control->cm_solver_max_iters = ival; + } + else if ( strcmp(tmp[0], "cm_solver_restart") == 0 ) + { + ival = atoi( tmp[1] ); + control->cm_solver_restart = ival; + } + else if ( strcmp(tmp[0], "cm_solver_q_err") == 0 ) + { + val = atof( tmp[1] ); + control->cm_solver_q_err = val; + } + else if ( strcmp(tmp[0], "cm_domain_sparsity") == 0 ) + { + val = atof( tmp[1] ); + control->cm_domain_sparsity = val; + if ( val < 1.0 ) + { + control->cm_domain_sparsify_enabled = TRUE; + } + } + else if ( strncmp(tmp[0], "cm_init_guess_extrap1", MAX_LINE) == 0 ) + { + ival = atoi( tmp[1] ); + control->cm_init_guess_extrap1 = ival; + } + else if ( strncmp(tmp[0], "cm_init_guess_extrap2", MAX_LINE) == 0 ) + { + ival = atoi( tmp[1] ); + control->cm_init_guess_extrap2 = ival; + } + else if ( strcmp(tmp[0], "cm_solver_pre_comp_type") == 0 ) + { + ival = atoi( tmp[1] ); + control->cm_solver_pre_comp_type = ival; + } + else if ( strcmp(tmp[0], "cm_solver_pre_comp_refactor") == 0 ) + { + ival = atoi( tmp[1] ); + control->cm_solver_pre_comp_refactor = ival; + } + else if ( strcmp(tmp[0], "cm_solver_pre_comp_droptol") == 0 ) + { + val = atof( tmp[1] ); + control->cm_solver_pre_comp_droptol = val; + } + else if ( strcmp(tmp[0], "cm_solver_pre_comp_sweeps") == 0 ) + { + ival = atoi( tmp[1] ); + control->cm_solver_pre_comp_sweeps = ival; + } + else if ( strncmp(tmp[0], "cm_solver_pre_comp_sai_thres", MAX_LINE) == 0 ) + { + val = atof( tmp[1] ); + control->cm_solver_pre_comp_sai_thres = val; + } + else if ( strcmp(tmp[0], "cm_solver_pre_app_type") == 0 ) + { + ival = atoi( tmp[1] ); + control->cm_solver_pre_app_type = ival; + } + else if ( strcmp(tmp[0], "cm_solver_pre_app_jacobi_iters") == 0 ) + { + ival = atoi( tmp[1] ); + control->cm_solver_pre_app_jacobi_iters = ival; + } + else if ( strcmp(tmp[0], "temp_init") == 0 ) + { + val = atof(tmp[1]); + control->T_init = val; - if ( control->T_final < 0.1 ) - control->T_final = 0.1; - } - else if ( strcmp(tmp[0], "t_mass") == 0 ) - { - val = atof(tmp[1]); - control->Tau_T = val * 1.e-3; // convert t_mass from fs to ps - } - else if ( strcmp(tmp[0], "t_mode") == 0 ) - { - ival = atoi(tmp[1]); - control->T_mode = ival; - } - else if ( strcmp(tmp[0], "t_rate") == 0 ) - { - val = atof(tmp[1]); - control->T_rate = val; - } - else if ( strcmp(tmp[0], "t_freq") == 0 ) - { - val = atof(tmp[1]); - control->T_freq = val; - } - else if ( strcmp(tmp[0], "pressure") == 0 ) - { - if ( control->ensemble == iNPT ) + if ( control->T_init < 0.1 ) + { + control->T_init = 0.1; + } + } + else if ( strcmp(tmp[0], "temp_final") == 0 ) { - control->P[0] = control->P[1] = control->P[2] = atof(tmp[1]); + val = atof(tmp[1]); + control->T_final = val; + + if ( control->T_final < 0.1 ) + { + control->T_final = 0.1; + } } - else if ( control->ensemble == sNPT ) + else if ( strcmp(tmp[0], "t_mass") == 0 ) { - control->P[0] = atof(tmp[1]); - control->P[1] = atof(tmp[2]); - control->P[2] = atof(tmp[3]); + val = atof(tmp[1]); + control->Tau_T = val * 1.e-3; // convert t_mass from fs to ps } - } - else if ( strcmp(tmp[0], "p_mass") == 0 ) - { - // convert p_mass from fs to ps - if ( control->ensemble == iNPT ) + else if ( strcmp(tmp[0], "t_mode") == 0 ) { - control->Tau_P[0] = control->Tau_P[1] = control->Tau_P[2] = - atof(tmp[1]) * 1.e-3; + ival = atoi(tmp[1]); + control->T_mode = ival; } - else if ( control->ensemble == sNPT ) + else if ( strcmp(tmp[0], "t_rate") == 0 ) { - control->Tau_P[0] = atof(tmp[1]) * 1.e-3; - control->Tau_P[1] = atof(tmp[2]) * 1.e-3; - control->Tau_P[2] = atof(tmp[3]) * 1.e-3; + val = atof(tmp[1]); + control->T_rate = val; + } + else if ( strcmp(tmp[0], "t_freq") == 0 ) + { + val = atof(tmp[1]); + control->T_freq = val; + } + else if ( strcmp(tmp[0], "pressure") == 0 ) + { + if ( control->ensemble == iNPT ) + { + control->P[0] = control->P[1] = control->P[2] = atof(tmp[1]); + } + else if ( control->ensemble == sNPT ) + { + control->P[0] = atof(tmp[1]); + control->P[1] = atof(tmp[2]); + control->P[2] = atof(tmp[3]); + } + } + else if ( strcmp(tmp[0], "p_mass") == 0 ) + { + // convert p_mass from fs to ps + if ( control->ensemble == iNPT ) + { + control->Tau_P[0] = control->Tau_P[1] = control->Tau_P[2] = + atof(tmp[1]) * 1.e-3; + } + else if ( control->ensemble == sNPT ) + { + control->Tau_P[0] = atof(tmp[1]) * 1.e-3; + control->Tau_P[1] = atof(tmp[2]) * 1.e-3; + control->Tau_P[2] = atof(tmp[3]) * 1.e-3; + } + } + else if ( strcmp(tmp[0], "pt_mass") == 0 ) + { + val = atof(tmp[1]); + control->Tau_PT[0] = control->Tau_PT[1] = control->Tau_PT[2] = + val * 1.e-3; // convert pt_mass from fs to ps + } + else if ( strcmp(tmp[0], "compress") == 0 ) + { + val = atof(tmp[1]); + control->compressibility = val; + } + else if ( strcmp(tmp[0], "press_mode") == 0 ) + { + ival = atoi(tmp[1]); + control->press_mode = ival; + } + else if ( strcmp(tmp[0], "geo_format") == 0 ) + { + ival = atoi( tmp[1] ); + control->geo_format = ival; + } + else if ( strcmp(tmp[0], "write_freq") == 0 ) + { + ival = atoi(tmp[1]); + out_control->write_steps = ival; + } + else if ( strcmp(tmp[0], "traj_compress") == 0 ) + { + ival = atoi(tmp[1]); + out_control->traj_compress = ival; + } + else if ( strcmp(tmp[0], "traj_method") == 0 ) + { + ival = atoi(tmp[1]); + out_control->traj_method = ival; + } + else if ( strcmp(tmp[0], "traj_title") == 0 ) + { + strcpy( out_control->traj_title, tmp[1] ); + } + else if ( strcmp(tmp[0], "atom_info") == 0 ) + { + ival = atoi(tmp[1]); + out_control->atom_info += ival * 4; + } + else if ( strcmp(tmp[0], "atom_velocities") == 0 ) + { + ival = atoi(tmp[1]); + out_control->atom_info += ival * 2; + } + else if ( strcmp(tmp[0], "atom_forces") == 0 ) + { + ival = atoi(tmp[1]); + out_control->atom_info += ival * 1; + } + else if ( strcmp(tmp[0], "bond_info") == 0 ) + { + ival = atoi(tmp[1]); + out_control->bond_info = ival; + } + else if ( strcmp(tmp[0], "angle_info") == 0 ) + { + ival = atoi(tmp[1]); + out_control->angle_info = ival; + } + else if ( strcmp(tmp[0], "molecular_analysis") == 0 ) + { + ival = atoi(tmp[1]); + control->molecular_analysis = ival; + } + else if ( strcmp(tmp[0], "ignore") == 0 ) + { + control->num_ignored = atoi(tmp[1]); + for ( i = 0; i < control->num_ignored; ++i ) + { + control->ignore[atoi(tmp[i + 2])] = 1; + } + } + else if ( strcmp(tmp[0], "dipole_anal") == 0 ) + { + ival = atoi(tmp[1]); + control->dipole_anal = ival; + } + else if ( strcmp(tmp[0], "freq_dipole_anal") == 0 ) + { + ival = atoi(tmp[1]); + control->freq_dipole_anal = ival; + } + else if ( strcmp(tmp[0], "diffusion_coef") == 0 ) + { + ival = atoi(tmp[1]); + control->diffusion_coef = ival; + } + else if ( strcmp(tmp[0], "freq_diffusion_coef") == 0 ) + { + ival = atoi(tmp[1]); + control->freq_diffusion_coef = ival; + } + else if ( strcmp(tmp[0], "restrict_type") == 0 ) + { + ival = atoi(tmp[1]); + control->restrict_type = ival; + } + else + { + fprintf( stderr, "[ERROR] unknown control file parameter (%s)\n", tmp[0] ); + MPI_Abort( MPI_COMM_WORLD, INVALID_INPUT ); } - } - else if ( strcmp(tmp[0], "pt_mass") == 0 ) - { - val = atof(tmp[1]); - control->Tau_PT[0] = control->Tau_PT[1] = control->Tau_PT[2] = - val * 1.e-3; // convert pt_mass from fs to ps - } - else if ( strcmp(tmp[0], "compress") == 0 ) - { - val = atof(tmp[1]); - control->compressibility = val; - } - else if ( strcmp(tmp[0], "press_mode") == 0 ) - { - ival = atoi(tmp[1]); - control->press_mode = ival; - } - else if ( strcmp(tmp[0], "geo_format") == 0 ) - { - ival = atoi( tmp[1] ); - control->geo_format = ival; - } - else if ( strcmp(tmp[0], "write_freq") == 0 ) - { - ival = atoi(tmp[1]); - out_control->write_steps = ival; - } - else if ( strcmp(tmp[0], "traj_compress") == 0 ) - { - ival = atoi(tmp[1]); - out_control->traj_compress = ival; - } - else if ( strcmp(tmp[0], "traj_method") == 0 ) - { - ival = atoi(tmp[1]); - out_control->traj_method = ival; - } - else if ( strcmp(tmp[0], "traj_title") == 0 ) - { - strcpy( out_control->traj_title, tmp[1] ); - } - else if ( strcmp(tmp[0], "atom_info") == 0 ) - { - ival = atoi(tmp[1]); - out_control->atom_info += ival * 4; - } - else if ( strcmp(tmp[0], "atom_velocities") == 0 ) - { - ival = atoi(tmp[1]); - out_control->atom_info += ival * 2; - } - else if ( strcmp(tmp[0], "atom_forces") == 0 ) - { - ival = atoi(tmp[1]); - out_control->atom_info += ival * 1; - } - else if ( strcmp(tmp[0], "bond_info") == 0 ) - { - ival = atoi(tmp[1]); - out_control->bond_info = ival; - } - else if ( strcmp(tmp[0], "angle_info") == 0 ) - { - ival = atoi(tmp[1]); - out_control->angle_info = ival; - } - else if ( strcmp(tmp[0], "molecular_analysis") == 0 ) - { - ival = atoi(tmp[1]); - control->molecular_analysis = ival; - } - else if ( strcmp(tmp[0], "ignore") == 0 ) - { - control->num_ignored = atoi(tmp[1]); - for ( i = 0; i < control->num_ignored; ++i ) - control->ignore[atoi(tmp[i + 2])] = 1; - } - else if ( strcmp(tmp[0], "dipole_anal") == 0 ) - { - ival = atoi(tmp[1]); - control->dipole_anal = ival; - } - else if ( strcmp(tmp[0], "freq_dipole_anal") == 0 ) - { - ival = atoi(tmp[1]); - control->freq_dipole_anal = ival; - } - else if ( strcmp(tmp[0], "diffusion_coef") == 0 ) - { - ival = atoi(tmp[1]); - control->diffusion_coef = ival; - } - else if ( strcmp(tmp[0], "freq_diffusion_coef") == 0 ) - { - ival = atoi(tmp[1]); - control->freq_diffusion_coef = ival; - } - else if ( strcmp(tmp[0], "restrict_type") == 0 ) - { - ival = atoi(tmp[1]); - control->restrict_type = ival; - } - else - { - fprintf( stderr, "WARNING: unknown parameter %s\n", tmp[0] ); - MPI_Abort( MPI_COMM_WORLD, 15 ); } } + if ( ferror( fp ) ) + { + fprintf( stderr, "[ERROR] parsing control file failed (I/O error). TERMINATING...\n" ); + MPI_Abort( MPI_COMM_WORLD, INVALID_INPUT ); + } + /* determine target T */ if ( control->T_mode == 0 ) + { control->T = control->T_final; - else control->T = control->T_init; + } + else + { + control->T = control->T_init; + } /* free memory allocations at the top */ for ( i = 0; i < MAX_TOKENS; i++ ) - sfree( tmp[i], "tmp[i]" ); - sfree( tmp, "tmp" ); - sfree( s, "s" ); + { + sfree( tmp[i], "Read_Control_File::tmp[i]" ); + } + sfree( tmp, "Read_Control_File::tmp" ); + sfree( s, "Read_Control_File::s" ); // fprintf( stderr,"%d %d %10.5f %d %10.5f %10.5f\n", // control->ensemble, control->nsteps, control->dt, diff --git a/PuReMD/src/forces.c b/PuReMD/src/forces.c index bbbf110adf7a3bd5be7d24c236f968612a8aa3bd..49e747a4c92042a1b2eba168a9c05417450b9332 100644 --- a/PuReMD/src/forces.c +++ b/PuReMD/src/forces.c @@ -978,7 +978,7 @@ void Compute_Forces( reax_system *system, control_params *control, comm = mpi_data->world; /********* init forces ************/ #if defined(PURE_REAX) - if ( control->qeq_freq && (data->step - data->prev_steps) % control->qeq_freq == 0 ) + if ( control->charge_freq && (data->step - data->prev_steps) % control->charge_freq == 0 ) qeq_flag = 1; else qeq_flag = 0; #elif defined(LAMMPS_REAX) diff --git a/PuReMD/src/linear_solvers.c b/PuReMD/src/linear_solvers.c index bcb0432798fc5d4a3aff91c0848d025985eea50a..34b3f8e9b38157abd5797d9b33beace90a6df492 100644 --- a/PuReMD/src/linear_solvers.c +++ b/PuReMD/src/linear_solvers.c @@ -1227,7 +1227,7 @@ int CG( reax_system *system, control_params *control, simulation_data *data, t_pa += Get_Timing_Info( t_start ); } - else if ( control->cm_solver_pre_comp_type == DIAG_PC) + else if ( control->cm_solver_pre_comp_type == JACOBI_PC) { t_start = Get_Time( ); for ( j = 0; j < system->n; ++j ) @@ -1277,7 +1277,7 @@ int CG( reax_system *system, control_params *control, simulation_data *data, t_pa += Get_Timing_Info( t_start ); } - else if ( control->cm_solver_pre_comp_type == DIAG_PC) + else if ( control->cm_solver_pre_comp_type == JACOBI_PC) { t_start = Get_Time( ); for ( j = 0; j < system->n; ++j ) diff --git a/PuReMD/src/qEq.c b/PuReMD/src/qEq.c index 969171981070ac646122b9e42844159c7f70cc02..3ec05786996bae3f0a25e0301c344c5111670d46 100644 --- a/PuReMD/src/qEq.c +++ b/PuReMD/src/qEq.c @@ -237,12 +237,12 @@ void Init_MatVec( reax_system *system, simulation_data *data, int i; //, fillin; reax_atom *atom; - /*if( (data->step - data->prev_steps) % control->refactor == 0 || + /*if( (data->step - data->prev_steps) % control->cm_solver_pre_comp_refactor == 0 || workspace->L == NULL ) { //Print_Linear_System( system, control, workspace, data->step ); Sort_Matrix_Rows( workspace->H ); fprintf( stderr, "H matrix sorted\n" ); - Calculate_Droptol( workspace->H, workspace->droptol, control->droptol ); + Calculate_Droptol( workspace->H, workspace->droptol, control->cm_solver_pre_comp_droptol ); fprintf( stderr, "drop tolerances calculated\n" ); if( workspace->L == NULL ) { fillin = Estimate_LU_Fill( workspace->H, workspace->droptol ); @@ -376,7 +376,7 @@ static void Setup_Preconditioner_QEq( reax_system *system, control_params *contr t_sort = Get_Timing_Info( time ); t_pc = setup_sparse_approx_inverse( system, data, workspace, mpi_data, workspace->H, &workspace->H_spar_patt, - control->nprocs, control->sai_thres ); + control->nprocs, control->cm_solver_pre_comp_sai_thres ); MPI_Reduce(&t_sort, &total_sort, 1, MPI_DOUBLE, MPI_SUM, MASTER_NODE, mpi_data->world); @@ -424,7 +424,7 @@ void QEq( reax_system *system, control_params *control, simulation_data *data, if( control->cm_solver_pre_comp_type == SAI_PC ) { - if( control->refactor > 0 && ((data->step - data->prev_steps) % control->refactor == 0)) + if( control->cm_solver_pre_comp_refactor > 0 && ((data->step - data->prev_steps) % control->cm_solver_pre_comp_refactor == 0)) { Setup_Preconditioner_QEq( system, control, data, workspace, mpi_data ); @@ -436,7 +436,7 @@ void QEq( reax_system *system, control_params *control, simulation_data *data, for ( j = 0; j < system->n; ++j ) workspace->s[j] = workspace->x[j][0]; iters = CG(system, control, data, workspace, workspace->H, workspace->b_s, - control->q_err, workspace->s, mpi_data, out_control->log , control->nprocs ); + control->cm_solver_q_err, workspace->s, mpi_data, out_control->log , control->nprocs ); for ( j = 0; j < system->n; ++j ) workspace->x[j][0] = workspace->s[j]; @@ -447,7 +447,7 @@ void QEq( reax_system *system, control_params *control, simulation_data *data, for ( j = 0; j < system->n; ++j ) workspace->t[j] = workspace->x[j][1]; iters += CG(system, control, data, workspace, workspace->H, workspace->b_t,//newQEq sCG - control->q_err, workspace->t, mpi_data, out_control->log, control->nprocs ); + control->cm_solver_q_err, workspace->t, mpi_data, out_control->log, control->nprocs ); for ( j = 0; j < system->n; ++j ) workspace->x[j][1] = workspace->t[j]; diff --git a/PuReMD/src/reax_types.h b/PuReMD/src/reax_types.h index 4335d66cb3e14ca6c0e4d6f2c566f8bb445795bf..f9933ffe9b3181c2555dd6708af2614a1608e506 100644 --- a/PuReMD/src/reax_types.h +++ b/PuReMD/src/reax_types.h @@ -70,18 +70,46 @@ #endif +/* method for computing atomic charges */ +enum charge_method +{ + QEQ_CM = 0, + EE_CM = 1, + ACKS2_CM = 2, +}; + +/* linear solver type used in charge method */ +enum solver +{ + GMRES_S = 0, + GMRES_H_S = 1, + CG_S = 2, + SDM_S = 3, + BiCGStab_S = 4, +}; + /* preconditioner computation type for charge method linear solver */ enum pre_comp { NONE_PC = 0, - DIAG_PC = 1, + JACOBI_PC = 1, ICHOLT_PC = 2, - ILU_PAR_PC = 3, - ILUT_PAR_PC = 4, - ILU_SUPERLU_MT_PC = 5, + ILUT__PC = 3, + ILUTP_PC = 4, + FG_ILUT_PC = 5, SAI_PC = 6, }; +/* preconditioner application type for ICHOL/ILU preconditioners, + * used for charge method linear solver */ +enum pre_app +{ + TRI_SOLVE_PA = 0, + TRI_SOLVE_LEVEL_SCHED_PA = 1, + TRI_SOLVE_GC_PA = 2, + JACOBI_ITER_PA = 3, +}; + /********************** TYPE DEFINITIONS ********************/ typedef int ivec[3]; @@ -513,67 +541,161 @@ typedef struct /* system control parameters */ typedef struct { + /* simulation name, as supplied via control file */ char sim_name[REAX_MAX_STR]; - int nprocs; + /* number of MPI processors, as supplied via control file */ + int nprocs; + /* MPI processors per each simulation dimension (cartesian topology), + * as supplied via control file */ ivec procs_by_dim; - /* ensemble values: - 0 : NVE - 1 : bNVT (Berendsen) - 2 : nhNVT (Nose-Hoover) - 3 : sNPT (Parrinello-Rehman-Nose-Hoover) semiisotropic - 4 : iNPT (Parrinello-Rehman-Nose-Hoover) isotropic - 5 : NPT (Parrinello-Rehman-Nose-Hoover) Anisotropic*/ - int ensemble; - int nsteps; + /* ensemble type for simulation, values: + * 0 : NVE + * 1 : bNVT (Berendsen) + * 2 : nhNVT (Nose-Hoover) + * 3 : sNPT (Parrinello-Rehman-Nose-Hoover) semiisotropic + * 4 : iNPT (Parrinello-Rehman-Nose-Hoover) isotropic + * 5 : NPT (Parrinello-Rehman-Nose-Hoover) Anisotropic */ + int ensemble; + /* num. of simulation time steps */ + int nsteps; + /* length of time step, in femtoseconds */ real dt; - int geo_format; - int restart; - - int restrict_bonds; - int remove_CoM_vel; - int random_vel; - int reposition_atoms; + /* format of geometry input file */ + int geo_format; + /* format of restart file */ + int restart; - int reneighbor; + /**/ + int restrict_bonds; + /* flag to control if center of mass velocity is removed */ + int remove_CoM_vel; + /* flag to control if atomic initial velocity is randomly assigned */ + int random_vel; + /* flag to control how atom repositioning is performed, values: + * 0: fit to periodic box + * 1: put center of mass to box center + * 2: put center of mass to box origin */ + int reposition_atoms; + + /* flag to control the frequency (in terms of simulation time stesp) + * at which atom reneighboring is performed */ + int reneighbor; + /* far neighbor (Verlet list) interaction cutoff, in Angstroms */ real vlist_cut; + /* bond interaction cutoff, in Angstroms */ real bond_cut; - real nonb_cut, nonb_low; + /* non-bonded interaction cutoff, in Angstroms */ + real nonb_cut; + /* ???, as supplied by force field parameters, in Angstroms */ + real nonb_low; + /* hydrogen bond interaction cutoff, in Angstroms */ real hbond_cut; + /* ghost region cutoff (user-supplied via control file), in Angstroms */ real user_ghost_cut; + /* bond graph cutoff, as supplied by control file, in Angstroms */ real bg_cut; + /* bond order cutoff, as supplied by force field parameters, in Angstroms */ real bo_cut; + /* three body interaction cutoff, as supplied by control file, in Angstroms */ real thb_cut; + /* flag to control if force computations are tablulated */ int tabulate; - int qeq_freq; - int cm_solver_max_iters; - real q_err; - int cm_solver_pre_comp_type; - real sai_thres; - int refactor; - real droptol; - - real T_init, T_final, T; + /* method for computing atomic charges */ + unsigned int charge_method; + /* frequency (in terms of simulation time steps) at which to + * re-compute atomic charge distribution */ + int charge_freq; + /* iterative linear solver type */ + unsigned int cm_solver_type; + /* system net charge */ + real cm_q_net; + /* max. iterations for linear solver */ + unsigned int cm_solver_max_iters; + /* max. iterations before restarting in specific solvers, e.g., GMRES(k) */ + unsigned int cm_solver_restart; + /* error tolerance of solution produced by charge distribution + * sparse iterative linear solver */ + real cm_solver_q_err; + /* ratio used in computing sparser charge matrix, + * between 0.0 and 1.0 */ + real cm_domain_sparsity; + /* TRUE if enabled, FALSE otherwise */ + unsigned int cm_domain_sparsify_enabled; + /* order of spline extrapolation used for computing initial guess + * to linear solver */ + unsigned int cm_init_guess_extrap1; + /* order of spline extrapolation used for computing initial guess + * to linear solver */ + unsigned int cm_init_guess_extrap2; + /* preconditioner type for linear solver */ + unsigned int cm_solver_pre_comp_type; + /* frequency (in terms of simulation time steps) at which to recompute + * incomplete factorizations */ + unsigned int cm_solver_pre_comp_refactor; + /* drop tolerance of incomplete factorization schemes (ILUT, ICHOLT, etc.) + * used for preconditioning the iterative linear solver used in charge distribution */ + real cm_solver_pre_comp_droptol; + /* num. of sweeps for computing preconditioner factors + * in fine-grained iterative methods (FG-ICHOL, FG-ILU) */ + unsigned int cm_solver_pre_comp_sweeps; + /* relative num. of non-zeros to charge matrix used to + * compute the sparse approximate inverse preconditioner, + * between 0.0 and 1.0 */ + real cm_solver_pre_comp_sai_thres; + /* preconditioner application type */ + unsigned int cm_solver_pre_app_type; + /* num. of iterations used to apply preconditioner via + * Jacobi relaxation scheme (truncated Neumann series) */ + unsigned int cm_solver_pre_app_jacobi_iters; + + /* initial temperature of simulation, in Kelvin */ + real T_init; + /* final temperature of simulation, in Kelvin */ + real T_final; + /* current temperature of simulation, in Kelvin */ + real T; + /**/ real Tau_T; + /**/ int T_mode; - real T_rate, T_freq; + /**/ + real T_rate; + /**/ + real T_freq; + /**/ int virial; - rvec P, Tau_P, Tau_PT; - int press_mode; + /**/ + rvec P; + /**/ + rvec Tau_P; + /**/ + rvec Tau_PT; + /**/ + int press_mode; + /**/ real compressibility; - int molecular_analysis; - int num_ignored; + /**/ + int molecular_analysis; + /**/ + int num_ignored; + /**/ int ignore[REAX_MAX_ATOM_TYPES]; - int dipole_anal; - int freq_dipole_anal; - int diffusion_coef; - int freq_diffusion_coef; - int restrict_type; + /**/ + int dipole_anal; + /**/ + int freq_dipole_anal; + /**/ + int diffusion_coef; + /**/ + int freq_diffusion_coef; + /**/ + int restrict_type; } control_params; diff --git a/PuReMD/src/tool_box.c b/PuReMD/src/tool_box.c index a089287001279e198fccbb9bbfd0aa660863c2d3..d898f2190d72de1424eea2730ed506e9e04ec610 100644 --- a/PuReMD/src/tool_box.c +++ b/PuReMD/src/tool_box.c @@ -486,3 +486,65 @@ void sfree( void *ptr, char *name ) free( ptr ); ptr = NULL; } + + +/* Safe wrapper around libc fopen + * + * fname: name of file to be opened + * mode: mode in which to open file + * msg: message to be printed in case of error + * */ +FILE * sfopen( const char * fname, const char * mode, const char * msg ) +{ + FILE * ptr; + + if ( fname == NULL ) + { + fprintf( stderr, "[ERROR] trying to open file: NULL file name (%s). Terminating...\n", + msg ); + exit( INVALID_INPUT ); + } + if ( mode == NULL ) + { + fprintf( stderr, "[ERROR] trying to open file: NULL mode (%s). Terminating...\n", + msg ); + exit( INVALID_INPUT ); + } + + ptr = fopen( fname, mode ); + + if ( ptr == NULL ) + { + fprintf( stderr, "[ERROR] failed to open file %s with mode %s (%s)\n", + fname, mode, msg ); + exit( INVALID_INPUT ); + } + + return ptr; +} + + +/* Safe wrapper around libc fclose + * + * fname: name of file to be opened + * mode: mode in which to open file + * msg: message to be printed in case of error + * */ +void sfclose( FILE * fp, const char * msg ) +{ + int ret; + + if ( fp == NULL ) + { + fprintf( stderr, "[WARNING] trying to close NULL file pointer (%s). Returning...\n", msg ); + return; + } + + ret = fclose( fp ); + + if ( ret != 0 ) + { + fprintf( stderr, "[ERROR] error detected when closing file (%s). Terminating...\n", msg ); + exit( INVALID_INPUT ); + } +} diff --git a/PuReMD/src/tool_box.h b/PuReMD/src/tool_box.h index bf25c64fc658e46d4762da484bd1fa7cbfac605c..22cbc1954e03cc7892a7c341e392dbb3603f51d7 100644 --- a/PuReMD/src/tool_box.h +++ b/PuReMD/src/tool_box.h @@ -66,4 +66,8 @@ void *smalloc( long, char*, MPI_Comm ); void *scalloc( int, int, char*, MPI_Comm ); void sfree( void*, char* ); +FILE * sfopen( const char *, const char *, const char * ); + +void sfclose( FILE *, const char * ); + #endif diff --git a/PuReMD/src/traj.c b/PuReMD/src/traj.c index 40df8bbd1860eff00141ed97013e596430daf69c..d03a8289f22639477db5c9c7b3af919d37adba9e 100644 --- a/PuReMD/src/traj.c +++ b/PuReMD/src/traj.c @@ -261,7 +261,7 @@ int Write_Header( reax_system *system, control_params *control, control->thb_cut ); strncat( out_control->buffer, out_control->line, HEADER_LINE_LEN + 1 ); - sprintf( out_control->line, SCI_LINE, "QEq_tolerance:", control->q_err ); + sprintf( out_control->line, SCI_LINE, "QEq_tolerance:", control->cm_solver_q_err ); strncat( out_control->buffer, out_control->line, HEADER_LINE_LEN + 1 ); /* temperature controls */