int tclcommand_reaction(ClientData data, Tcl_Interp * interp, int argc, char ** argv){ #ifdef CATALYTIC_REACTIONS /* Determine the currently set types, to block the user from trying to set up multiple reactions */ int react_type, prdct_type, catal_type; react_type = reaction.reactant_type; prdct_type = reaction.product_type; catal_type = reaction.catalyzer_type; if (argc == 1 ) return tcl_command_reaction_print_usage(interp); if (argc == 2 ) { if (ARG1_IS_S("off")) { /* We only need to set ct_rate to zero and we do not enter the reaction integration loop */ reaction.ct_rate=0.0; mpi_setup_reaction(); return TCL_OK; } if (ARG1_IS_S("print")) { return tcl_command_reaction_print(interp); } } if( argc!=11 && argc!=13 && argc!=15 && argc!=17 && argc!=3) { return tcl_command_reaction_print_usage(interp); } if(time_step < 0.0) { Tcl_AppendResult(interp, "Time step needs to be set before setting up a reaction!", (char *) NULL); return (TCL_ERROR); } argc--; argv++; while (argc>0){ if (ARG_IS_S(0,"product_type")) { if (!ARG_IS_I(1,reaction.product_type)) return tcl_command_reaction_print_usage(interp); argc-=2; argv+=2; } else if (ARG_IS_S(0,"reactant_type")) { if (!ARG_IS_I(1,reaction.reactant_type)) return tcl_command_reaction_print_usage(interp); argc-=2; argv+=2; } else if (ARG_IS_S(0,"catalyzer_type")) { if (!ARG_IS_I(1,reaction.catalyzer_type)) return tcl_command_reaction_print_usage(interp); argc-=2; argv+=2; } else if (ARG_IS_S_EXACT(0,"range")) { if (!ARG_IS_D(1,reaction.range)) return tcl_command_reaction_print_usage(interp); argc-=2; argv+=2; } else if (ARG_IS_S_EXACT(0,"ct_rate")) { if (!ARG_IS_D(1,reaction.ct_rate)) return tcl_command_reaction_print_usage(interp); argc-=2; argv+=2; } else if (ARG_IS_S_EXACT(0,"eq_rate")) { if (!ARG_IS_D(1,reaction.eq_rate)) return tcl_command_reaction_print_usage(interp); argc-=2; argv+=2; } else if (ARG_IS_S_EXACT(0,"react_once")) { if (!ARG_IS_S(1,"on")&&!ARG_IS_S(1,"off")) { return tcl_command_reaction_print_usage(interp);} if (ARG_IS_S(1,"on")) reaction.sing_mult = 1; if (ARG_IS_S(1,"off")) reaction.sing_mult = 0; argc-=2; argv+=2; } else if (ARG_IS_S_EXACT(0,"swap")) { #ifndef ROTATION char buffer[80]; sprintf(buffer, "WARNING: Parameter \"swap\" has no effect when ROTATION is not compiled in."); Tcl_AppendResult(interp, buffer, (char *)NULL); #endif if (ARG_IS_S(1,"on")) reaction.swap = 1; else if (ARG_IS_S(1,"off")) reaction.swap = 0; else return tcl_command_reaction_print_usage(interp); argc-=2; argv+=2; } else { return tcl_command_reaction_print_usage(interp); } } if( reaction.ct_rate < 0.0 ) { Tcl_AppendResult(interp, "Negative catalytic reaction rate constant is not allowed!", (char *) NULL); return (TCL_ERROR); } if( reaction.eq_rate < 0.0 && fabs(reaction.eq_rate + 1.0) > 0.001 ) { Tcl_AppendResult(interp, "Negative equilibrium reaction rate contstant is not allowed!", (char *) NULL); return (TCL_ERROR); } if( (reaction.product_type == reaction.reactant_type) || (reaction.product_type == reaction.catalyzer_type) || (reaction.catalyzer_type == reaction.reactant_type) ) { Tcl_AppendResult(interp, "One particle type cannot be a part more than one reaction species!", (char *) NULL); return (TCL_ERROR); } if ( ((react_type != reaction.reactant_type) || (prdct_type != reaction.product_type) || (catal_type != reaction.catalyzer_type)) && (react_type != prdct_type) ) { Tcl_AppendResult(interp, "A simulation can only contain a single reaction!", (char *) NULL); return (TCL_ERROR); } mpi_setup_reaction(); return TCL_OK; #else Tcl_AppendResult(interp, "CATALYTIC_REACTIONS not compiled in!" ,(char *) NULL); return (TCL_ERROR); #endif }
/** Parse integrate npt_isotropic command */ int tclcommand_integrate_set_npt_isotropic(Tcl_Interp *interp, int argc, char **argv) { int xdir, ydir, zdir; xdir = ydir = zdir = nptiso.cubic_box = 0; if (argc < 4) { Tcl_AppendResult(interp, "wrong # args: \n", (char *)NULL); return tclcommand_integrate_print_usage(interp); } /* set parameters p_ext and piston */ if ( !ARG_IS_D(3, nptiso.p_ext) ) return tclcommand_integrate_print_usage(interp); tclcallback_p_ext(interp, &nptiso.p_ext); if ( argc > 4 ) { if(!ARG_IS_D(4, nptiso.piston) ) return tclcommand_integrate_print_usage(interp); tclcallback_npt_piston(interp, &nptiso.piston); } else if ( nptiso.piston <= 0.0 ) { Tcl_AppendResult(interp, "You must set <piston> as well before you can use this integrator! \n", (char *)NULL); return tclcommand_integrate_print_usage(interp); } if ( argc > 5 ) { if (!ARG_IS_I(5,xdir) || !ARG_IS_I(6,ydir) || !ARG_IS_I(7,zdir) ) { return tclcommand_integrate_print_usage(interp);} else { /* set the geometry to include rescaling specified directions only*/ nptiso.geometry = 0; nptiso.dimension = 0; nptiso.non_const_dim = -1; if ( xdir ) { nptiso.geometry = ( nptiso.geometry | NPTGEOM_XDIR ); nptiso.dimension += 1; nptiso.non_const_dim = 0; } if ( ydir ) { nptiso.geometry = ( nptiso.geometry | NPTGEOM_YDIR ); nptiso.dimension += 1; nptiso.non_const_dim = 1; } if ( zdir ) { nptiso.geometry = ( nptiso.geometry | NPTGEOM_ZDIR ); nptiso.dimension += 1; nptiso.non_const_dim = 2; } } } else { /* set the geometry to include rescaling in all directions; the default*/ nptiso.geometry = 0; nptiso.geometry = ( nptiso.geometry | NPTGEOM_XDIR ); nptiso.geometry = ( nptiso.geometry | NPTGEOM_YDIR ); nptiso.geometry = ( nptiso.geometry | NPTGEOM_ZDIR ); nptiso.dimension = 3; nptiso.non_const_dim = 2; } if ( argc > 8 ) { /* enable if the volume fluctuations should also apply to dimensions which are switched off by the above flags and which do not contribute to the pressure (3D) / tension (2D, 1D) */ if (!ARG_IS_S(8,"-cubic_box")) { return tclcommand_integrate_print_usage(interp); } else { nptiso.cubic_box = 1; } } /* Sanity Checks */ #ifdef ELECTROSTATICS if ( nptiso.dimension < 3 && !nptiso.cubic_box && coulomb.bjerrum > 0 ){ fprintf(stderr,"WARNING: If electrostatics is being used you must use the -cubic_box option!\n"); fprintf(stderr,"Automatically reverting to a cubic box for npt integration.\n"); fprintf(stderr,"Be aware though that all of the coulombic pressure is added to the x-direction only!\n"); nptiso.cubic_box = 1; } #endif #ifdef DIPOLES if ( nptiso.dimension < 3 && !nptiso.cubic_box && coulomb.Dbjerrum > 0 ){ fprintf(stderr,"WARNING: If magnetostatics is being used you must use the -cubic_box option!\n"); fprintf(stderr,"Automatically reverting to a cubic box for npt integration.\n"); fprintf(stderr,"Be aware though that all of the magnetostatic pressure is added to the x-direction only!\n"); nptiso.cubic_box = 1; } #endif if( nptiso.dimension == 0 || nptiso.non_const_dim == -1) { Tcl_AppendResult(interp, "You must enable at least one of the x y z components as fluctuating dimension(s) for box length motion!", (char *)NULL); Tcl_AppendResult(interp, "Cannot proceed with npt_isotropic, reverting to nvt integration... \n", (char *)NULL); integ_switch = INTEG_METHOD_NVT; mpi_bcast_parameter(FIELD_INTEG_SWITCH); return (TCL_ERROR); } /* set integrator switch */ integ_switch = INTEG_METHOD_NPT_ISO; mpi_bcast_parameter(FIELD_INTEG_SWITCH); /* broadcast npt geometry information to all nodes */ mpi_bcast_nptiso_geom(); return (TCL_OK); }
int tclcommand_observable(ClientData data, Tcl_Interp *interp, int argc, char **argv){ // file_data_source* fds; char buffer[TCL_INTEGER_SPACE]; int n; int id; int temp; //int no; if (argc<2) { Tcl_AppendResult(interp, "Usage!!!\n", (char *)NULL); return TCL_ERROR; } if (argc > 1 && ARG_IS_S(1, "n_observables")) { sprintf(buffer, "%d", n_observables); Tcl_AppendResult(interp, buffer, (char *)NULL ); return TCL_OK; } // if (argc > 1 && ARG1_IS_I(no)) { // } if (argc > 2 && ARG1_IS_S("new") ) { // find the next free observable id for (id=0;id<n_observables;id++) if ( observables+id == 0 ) break; if (id==n_observables) observables=(observable**) realloc(observables, (n_observables+1)*sizeof(observable*)); REGISTER_OBSERVABLE(particle_velocities, tclcommand_observable_particle_velocities,id); REGISTER_OBSERVABLE(particle_angular_momentum, tclcommand_observable_particle_angular_momentum,id); REGISTER_OBSERVABLE(particle_forces, tclcommand_observable_particle_forces,id); REGISTER_OBSERVABLE(com_velocity, tclcommand_observable_com_velocity,id); REGISTER_OBSERVABLE(com_position, tclcommand_observable_com_position,id); REGISTER_OBSERVABLE(com_force, tclcommand_observable_com_force,id); REGISTER_OBSERVABLE(particle_positions, tclcommand_observable_particle_positions,id); REGISTER_OBSERVABLE(stress_tensor, tclcommand_observable_stress_tensor,id); REGISTER_OBSERVABLE(stress_tensor_acf_obs, tclcommand_observable_stress_tensor_acf_obs,id); REGISTER_OBSERVABLE(particle_currents, tclcommand_observable_particle_currents,id); REGISTER_OBSERVABLE(currents, tclcommand_observable_currents,id); REGISTER_OBSERVABLE(dipole_moment, tclcommand_observable_dipole_moment,id); // REGISTER_OBSERVABLE(structure_factor, tclcommand_observable_structure_factor,id); REGISTER_OBSERVABLE(interacts_with, tclcommand_observable_interacts_with,id); // REGISTER_OBSERVABLE(obs_nothing, tclcommand_observable_obs_nothing,id); // REGISTER_OBSERVABLE(flux_profile, tclcommand_observable_flux_profile,id); REGISTER_OBSERVABLE(density_profile, tclcommand_observable_density_profile,id); REGISTER_OBSERVABLE(lb_velocity_profile, tclcommand_observable_lb_velocity_profile,id); REGISTER_OBSERVABLE(radial_density_profile, tclcommand_observable_radial_density_profile,id); REGISTER_OBSERVABLE(radial_flux_density_profile, tclcommand_observable_radial_flux_density_profile,id); REGISTER_OBSERVABLE(flux_density_profile, tclcommand_observable_flux_density_profile,id); REGISTER_OBSERVABLE(lb_radial_velocity_profile, tclcommand_observable_lb_radial_velocity_profile,id); REGISTER_OBSERVABLE(tclcommand, tclcommand_observable_tclcommand,id); Tcl_AppendResult(interp, "Unknown observable ", argv[2] ,"\n", (char *)NULL); return TCL_ERROR; } if (ARG1_IS_I(n)) { if (n>=n_observables || observables+n == NULL ) { sprintf(buffer,"%d \n",n); Tcl_AppendResult(interp, "Observable with id ", buffer, (char *)NULL); Tcl_AppendResult(interp, "is not defined\n", (char *)NULL); return TCL_ERROR; } if (argc > 2 && ARG_IS_S(2,"print")) { return tclcommand_observable_print(interp, argc-3, argv+3, &temp, observables[n]); } } Tcl_AppendResult(interp, "Unknown observable ", argv[1] ,"\n", (char *)NULL); return TCL_ERROR; }
/************************************************************* * Functions * * --------- * *************************************************************/ int tclcommand_polymer (ClientData data, Tcl_Interp *interp, int argc, char **argv) { int N_P, MPC; double bond_length; int part_id = 0; double *posed = NULL; double *posed2 = NULL; /* mode==0 equals "SAW", mode==1 equals "RW", mode==2 equals "PSAW" */ int mode = 1; double shield = 1.0; int tmp_try,max_try = 30000; double val_cM = 0.0; int cM_dist = 1, type_nM = 0, type_cM = 1, type_bond = 0; double angle = -1.0, angle2 = -1.0; int constr = 0; char buffer[128 + TCL_DOUBLE_SPACE + TCL_INTEGER_SPACE]; int i; #ifdef CONSTRAINTS int j; #endif if (argc < 4) { Tcl_AppendResult(interp, "Wrong # of args! Usage: polymer <N_P> <MPC> <bond_length> [start <n> | pos <x> <y> <z> | mode | charge | distance | types | bond | angle | constraints]", (char *)NULL); return (TCL_ERROR); } if (!ARG_IS_I(1, N_P)) { Tcl_ResetResult(interp); Tcl_AppendResult(interp, "Number of polymers must be integer (got: ", argv[1],")!", (char *)NULL); return (TCL_ERROR); } else { if(N_P < 0) { Tcl_AppendResult(interp, "Number of polymers must be positive (got: ", argv[1],")!", (char *)NULL); return (TCL_ERROR); } } if (!ARG_IS_I(2, MPC)) { Tcl_ResetResult(interp); Tcl_AppendResult(interp, "Number of monomers must be integer (got: ", argv[2],")!", (char *)NULL); return (TCL_ERROR); } else { if(MPC < 2) { Tcl_AppendResult(interp, "Number of monomers must be greater than 1 (got: ", argv[2],")!", (char *)NULL); return (TCL_ERROR); } } if (!ARG_IS_D(3, bond_length)) { Tcl_ResetResult(interp); Tcl_AppendResult(interp, "Bondlength must be double (got: ", argv[3],")!", (char *)NULL); return (TCL_ERROR); } else { if(bond_length < 0.0) { Tcl_AppendResult(interp, "Bondlength must be positive (got: ", argv[3],")!", (char *)NULL); return (TCL_ERROR); } } for (i=4; i < argc; i++) { /* [start <part_id>] */ if (ARG_IS_S(i, "start")) { if(i+1 < argc) { if (!ARG_IS_I(i+1, part_id)) { Tcl_ResetResult(interp); Tcl_AppendResult(interp, "Index of polymer chain's first monomer must be integer (got: ",argv[i+1],")!", (char *)NULL); return (TCL_ERROR); } else { if (part_id < 0) { Tcl_AppendResult(interp, "Index of polymer chain's first monomer must be positive (got: ",argv[i+1],")!", (char *)NULL); return (TCL_ERROR); } } i++; } else { Tcl_AppendResult(interp, "Not enough arguments for start", (char *)NULL); return (TCL_ERROR); } } /* [pos <x> <y> <z>] */ else if (ARG_IS_S(i, "pos")) { if (i+3 < argc) { posed = malloc(3*sizeof(double)); if (!(ARG_IS_D(i+1, posed[0]) && ARG_IS_D(i+2, posed[1]) && ARG_IS_D(i+3, posed[2]))) { Tcl_ResetResult(interp); Tcl_AppendResult(interp, "The first start monomers position must be double (got: ",argv[i+1],",",argv[i+2],",",argv[i+3],")!", (char *)NULL); return (TCL_ERROR); } else { i+=3; } } else { Tcl_AppendResult(interp, "The first start monomers position must be 3D!", (char *)NULL); return (TCL_ERROR); } } /* [mode { SAW | RW | PSAW } [<shield> [max_try]]] */ else if (ARG_IS_S(i, "mode")) { if (i+1 < argc) { if (ARG_IS_S(i+1, "SAW") || ARG_IS_S(i+1, "PSAW")) { if (ARG_IS_S(i+1, "SAW")) mode = 0; else mode = 2; if ((i+2 >= argc) || !ARG_IS_D(i+2, shield)) { Tcl_ResetResult(interp); i++; } else { if (shield < 0) { Tcl_AppendResult(interp, "The SAW-shield must be positive (got: ",argv[i+2],")!", (char *)NULL); return (TCL_ERROR); } if ((i+3 >= argc) || !ARG_IS_I(i+3, max_try)) { Tcl_ResetResult(interp); i+=2; } else { i+=3; } } } else if (ARG_IS_S(i+1, "RW")) { mode = 1; if ((i+2 >= argc) || !ARG_IS_D(i+2, shield)) { Tcl_ResetResult(interp); i++; } else if ((i+3 >= argc) || !ARG_IS_I(i+3, max_try)) { Tcl_ResetResult(interp); i+=2; } else { i+=3; } } else { Tcl_AppendResult(interp, "The mode you specified does not exist (got: ",argv[i+1],")!", (char *)NULL); return (TCL_ERROR); } } else {Tcl_AppendResult(interp, "Not enough arguments for mode", (char *)NULL); return (TCL_ERROR); } } /* [charge <val_cM>] */ else if (ARG_IS_S(i, "charge")) { if(i+1 < argc) { if (!ARG_IS_D(i+1, val_cM)) { Tcl_ResetResult(interp); Tcl_AppendResult(interp, "The charge of the chain's monomers must be double (got: ",argv[i+1],")!", (char *)NULL); return (TCL_ERROR); } else { i++; } } else { Tcl_AppendResult(interp, "Not enough arguments for charge", (char *)NULL); return (TCL_ERROR); } } /* [distance <cM_dist>] */ else if (ARG_IS_S(i, "distance")) { if(i+1 <argc) { if (!ARG_IS_I(i+1, cM_dist)) { Tcl_ResetResult(interp); Tcl_AppendResult(interp, "The distance between two charged monomers' indices must be integer (got: ",argv[i+1],")!", (char *)NULL); return (TCL_ERROR); } else { if(cM_dist < 0) { Tcl_AppendResult(interp, "The charge of the chain's monomers must be positive (got: ",argv[i+2],")!", (char *)NULL); return (TCL_ERROR); } else { i++; } } } else { Tcl_AppendResult(interp, "Not enough arguments for distance", (char *)NULL); return (TCL_ERROR); } } /* [types <type_nM> [<type_cM>]] */ else if (ARG_IS_S(i, "types")) { if(i+1 < argc) { if (!ARG_IS_I(i+1, type_nM)) { Tcl_ResetResult(interp); Tcl_AppendResult(interp, "The type-# of neutral monomers must be integer (got: ",argv[i+1],")!", (char *)NULL); return (TCL_ERROR); } else { if ((i+2 >= argc) || !ARG_IS_I(i+2, type_cM)) { Tcl_ResetResult(interp); i++; } else { i+=2; } } } else {Tcl_AppendResult(interp, "Not enough arguments for types", (char *)NULL); return (TCL_ERROR); } } /* [bond <type_bond>] */ else if (ARG_IS_S(i, "bond") || ARG_IS_S(i, "FENE")) { if (i+1 < argc) { if (!ARG_IS_I(i+1, type_bond)) { Tcl_ResetResult(interp); Tcl_AppendResult(interp, "The type-# of the bond-interaction must be integer (got: ", argv[i+1],")!", (char *)NULL); return (TCL_ERROR); } else { i++; } } else { Tcl_AppendResult(interp, "Not enough arguments for bond", (char *)NULL); return (TCL_ERROR); } } /* [angle <angle> [\<angle2\>]] */ else if (ARG_IS_S(i, "angle")) { Tcl_AppendResult(interp, "Warning: The angle definition has been changed. See RELEASE-NOTES.\n", (char *)NULL); if (i+1 < argc) { if (ARG_IS_D(i+1, angle)) { if (angle < 0.0) { Tcl_ResetResult(interp); Tcl_AppendResult(interp, "The angle phi must be positive (got: ",argv[i+1],")!", (char *)NULL); return (TCL_ERROR); } while (angle >= 2.0*PI) angle -= 2.0*PI; i++; if (i+1 < argc) { if (ARG_IS_D(i+1, angle2)) { if (angle2 < 0.0) { Tcl_ResetResult(interp); Tcl_AppendResult(interp, "The angle theta must be positive (got: ",argv[i+1],")!", (char *)NULL); return (TCL_ERROR); } while(angle2 >= 2.0*PI) angle2 -= 2.0*PI; i++; if (i+3 < argc) { posed2=malloc(3*sizeof(double)); if (ARG_IS_D(i+1, posed2[0]) && ARG_IS_D(i+2, posed2[1]) && ARG_IS_D(i+3, posed2[2])) { i+=3; } else { free(posed2); } } } } } } else {Tcl_AppendResult(interp, "Not enough arguments for angle", (char *)NULL); return (TCL_ERROR); } } /* [constraints] */ else if (ARG_IS_S(i, "constraints")) { #ifndef CONSTRAINTS Tcl_AppendResult(interp, "Constraints are not compiled in!", (char *)NULL); return (TCL_ERROR); } #else constr=1; tmp_try=0; for(j=0;j<n_constraints;j++){ if(constraints[j].type==CONSTRAINT_MAZE || constraints[j].type==CONSTRAINT_PORE || constraints[j].type==CONSTRAINT_PLATE || constraints[j].type==CONSTRAINT_RHOMBOID) tmp_try++; } if (tmp_try>0) { Tcl_ResetResult(interp); Tcl_AppendResult(interp, "Warning: Only constraints of type WALL/SPHERE/CYLINDER are respected!", (char *)NULL); return (TCL_ERROR); } else { i++; } } #endif /* Default */ else { Tcl_AppendResult(interp, "The parameters you supplied do not seem to be valid (stuck at: ",argv[i],")!", (char *)NULL); return (TCL_ERROR); }
int tclcommand_integrate(ClientData data, Tcl_Interp *interp, int argc, char **argv) { int n_steps, reuse_forces = 0; INTEG_TRACE(fprintf(stderr,"%d: integrate:\n",this_node)); if (argc < 1) { Tcl_AppendResult(interp, "wrong # args: \n\"", (char *) NULL); return tclcommand_integrate_print_usage(interp); } else if (argc < 2) { return tclcommand_integrate_print_status(interp); } if (ARG1_IS_S("set")) { if (argc < 3) return tclcommand_integrate_print_status(interp); if (ARG_IS_S(2,"nvt")) return tclcommand_integrate_set_nvt(interp, argc, argv); #ifdef NPT else if (ARG_IS_S(2,"npt_isotropic")) return tclcommand_integrate_set_npt_isotropic(interp, argc, argv); #endif else { Tcl_AppendResult(interp, "unknown integrator method:\n", (char *)NULL); return tclcommand_integrate_print_usage(interp); } } else { if ( !ARG_IS_I(1,n_steps) ) return tclcommand_integrate_print_usage(interp); // actual integration if ((argc == 3) && ARG_IS_S(2, "reuse_forces")) { reuse_forces = 1; } else if ((argc == 3) && ARG_IS_S(2, "recalc_forces")) { reuse_forces = -1; } else if (argc != 2) return tclcommand_integrate_print_usage(interp); } /* go on with integrate <n_steps> */ if(n_steps < 0) { Tcl_AppendResult(interp, "illegal number of steps (must be >0) \n", (char *) NULL); return tclcommand_integrate_print_usage(interp);; } /* if skin wasn't set, do an educated guess now */ if (!skin_set) { if (max_cut == 0.0) { Tcl_AppendResult(interp, "cannot automatically determine skin, please set it manually via \"setmd skin\"\n", (char *) NULL); return TCL_ERROR; } skin = 0.4*max_cut; mpi_bcast_parameter(FIELD_SKIN); } /* perform integration */ if (!correlations_autoupdate && !observables_autoupdate) { if (mpi_integrate(n_steps, reuse_forces)) return gather_runtime_errors(interp, TCL_OK); } else { for (int i=0; i<n_steps; i++) { if (mpi_integrate(1, reuse_forces)) return gather_runtime_errors(interp, TCL_OK); reuse_forces=1; autoupdate_observables(); autoupdate_correlations(); } if (n_steps == 0){ if (mpi_integrate(0, reuse_forces)) return gather_runtime_errors(interp, TCL_OK); } } return TCL_OK; }
/** Parses the ICCP3M command. */ int tclcommand_iccp3m(ClientData data, Tcl_Interp *interp, int argc, char **argv) { int last_ind_id,num_iteration,normal_args,area_args; char buffer[TCL_DOUBLE_SPACE]; double e1,convergence,relax; Tcl_AppendResult(interp, "The ICCP3M algorithm is still experimental. Function can not be guaranteed, therefore it is still disabled.\n", (char *)NULL); return (TCL_ERROR); if(iccp3m_initialized==0){ iccp3m_init(); iccp3m_initialized=1; } if(argc != 9 && argc != 2 && argc != 10) { Tcl_AppendResult(interp, "Wrong # of args! Usage: iccp3m { iterate | <last_ind_id> <e1> <num_iteration> <convergence> <relaxation> <area> <normal_components> <e_in/e_out> [<ext_field>] }", (char *)NULL); return (TCL_ERROR); } if (argc == 2 ){ if(ARG_IS_S(1,"iterate")) { if (iccp3m_cfg.set_flag==0) { Tcl_AppendResult(interp, "iccp3m parameters not set!", (char *)NULL); return (TCL_ERROR); } else{ Tcl_PrintDouble(interp,mpi_iccp3m_iteration(0),buffer); Tcl_AppendResult(interp, buffer, (char *) NULL); return TCL_OK; } } } else { if(!ARG_IS_I(1, last_ind_id)) { Tcl_ResetResult(interp); Tcl_AppendResult(interp, "Last induced id must be integer (got: ", argv[1],")!", (char *)NULL); return (TCL_ERROR); } else if(last_ind_id < 2) { Tcl_ResetResult(interp); Tcl_AppendResult(interp, "Last induced id can not be smaller then 2 (got: ", argv[1],")!", (char *)NULL); return (TCL_ERROR); } if(!ARG_IS_D(2, e1)) { Tcl_ResetResult(interp); Tcl_AppendResult(interp, "Dielectric constant e1(inner) must be double(got: ", argv[2],")!", (char *)NULL); return (TCL_ERROR); } if(!ARG_IS_I(3, num_iteration)) { Tcl_ResetResult(interp); Tcl_AppendResult(interp, "Number of maximum iterations must be integer (got: ", argv[4],")!", (char *)NULL); return (TCL_ERROR); } if(!ARG_IS_D(4, convergence)) { Tcl_ResetResult(interp); Tcl_AppendResult(interp, "Convergence criterion must be double (got: ", argv[5],")!", (char *)NULL); return (TCL_ERROR); } else if( (convergence < 1e-10) || (convergence > 1e-1) ) { Tcl_ResetResult(interp); Tcl_AppendResult(interp, "Convergence criterion can not be smaller then 1e-10 and greater then 1e-2(got: ", argv[5],")!", (char *)NULL); return (TCL_ERROR); } if(!ARG_IS_D(5, relax)) { Tcl_ResetResult(interp); Tcl_AppendResult(interp, "Relaxation parameter must be double (got: ", argv[6],")!", (char *)NULL); return (TCL_ERROR); } iccp3m_cfg.last_ind_id = last_ind_id; /* Assign needed options */ iccp3m_cfg.num_iteration = num_iteration; /* maximum number of iterations to go */ iccp3m_cfg.eout = e1; iccp3m_cfg.convergence = convergence; iccp3m_cfg.relax = relax; iccp3m_cfg.update = 0; iccp3m_cfg.set_flag = 1; normal_args = (iccp3m_cfg.last_ind_id+1)*3; /* Now get Normal Vectors components consecutively */ if( tclcommand_iccp3m_parse_params(interp,normal_args,argv[7],ICCP3M_NORMAL) == 1) { Tcl_ResetResult(interp); Tcl_AppendResult(interp, "ICCP3M: Error in following normal vectors\n", argv[7],"\nICCP3M: Error in previous normal vectors\n", (char *)NULL); return (TCL_ERROR); } area_args=(iccp3m_cfg.last_ind_id+1); /* Now get area of the boundary elements */ if ( tclcommand_iccp3m_parse_params(interp,area_args,argv[6],ICCP3M_AREA) == 1 ){ Tcl_ResetResult(interp); Tcl_AppendResult(interp, "ICCP3M: Error in following areas\n", argv[6],"\nICCP3M: Error in previous areas\n", (char *)NULL); return (TCL_ERROR); } /* Now get the ration ein/eout for each element. It's the user's duty to make sure that only disconnected regions have different ratios */ if ( tclcommand_iccp3m_parse_params(interp,area_args,argv[8],ICCP3M_EPSILON) == 1 ) { Tcl_ResetResult(interp); Tcl_AppendResult(interp, "ICCP3M: Error in following dielectric constants\n", argv[8],"\nICCP3M: Error in previous dielectric constants\n", (char *)NULL); return (TCL_ERROR); } if( argc == 10 ) { if( tclcommand_iccp3m_parse_params(interp,normal_args,argv[9],ICCP3M_EXTFIELD) == 1) { Tcl_ResetResult(interp); Tcl_AppendResult(interp, "ICCP3M: Error in following external field vectors\n", argv[9],"\nICCP3M: Error in previous external field vectors\n", (char *)NULL); return (TCL_ERROR); } } else { printf("allocating zeroes for external field \n"); iccp3m_cfg.extx = (double*)calloc((last_ind_id +1), sizeof(double)); iccp3m_cfg.exty = (double*)calloc((last_ind_id +1), sizeof(double)); iccp3m_cfg.extz = (double*)calloc((last_ind_id +1), sizeof(double)); } mpi_iccp3m_init(0); Tcl_PrintDouble(interp,mpi_iccp3m_iteration(0),buffer); Tcl_AppendResult(interp, buffer, (char *) NULL); return TCL_OK; } /* else (argc==10) */ return TCL_OK; }
int tclcommand_inter_parse_lj(Tcl_Interp * interp, int part_type_a, int part_type_b, int argc, char ** argv) { /* parameters needed for LJ */ double eps, sig, cut, shift, offset, cap_radius, min; #ifdef SHANCHEN double *affinity=NULL; #endif int compute_auto_shift, change; /* get lennard-jones interaction type */ if (argc < 4) { Tcl_AppendResult(interp, "lennard-jones needs at least 3 parameters: " "<lj_eps> <lj_sig> <lj_cut> [<lj_shift> [<lj_offset> [<lj_cap> [<lj_min>]]]]", (char *) NULL); return 0; } change = 1; /* PARSE LENNARD-JONES COMMAND LINE */ /* epsilon */ if (! ARG_IS_D(1, eps)) { Tcl_AppendResult(interp, "<lj_eps> should be a double", (char *) NULL); return 0; } change++; /* sigma */ if (! ARG_IS_D(2, sig)) { Tcl_AppendResult(interp, "<lj_sig> should be a double", (char *) NULL); return 0; } change++; /* cutoff */ if (! ARG_IS_D(3, cut)) { Tcl_AppendResult(interp, "<lj_cut> should be a double", (char *) NULL); return 0; } change++; /* shift */ if (argc > 4) { if (ARG_IS_D(4, shift)) { /* if a shift is given, use that one */ compute_auto_shift = 0; change++; } else if (ARG_IS_S(4, "auto")) { Tcl_ResetResult(interp); compute_auto_shift = 1; /* if shift is "auto", autocompute the shift */ change++; } else { Tcl_AppendResult(interp, "<lj_shift> should be a double or \"auto\"", (char *) NULL); return 0; } } else { /* by default, compute the shift automatically */ compute_auto_shift = 1; } /* the shift can be computed automatically only when the other parameters have been determined, see below */ /* offset */ if (argc > 5) { if (!ARG_IS_D(5, offset)) { Tcl_AppendResult(interp, "<lj_off> should be a double", (char *) NULL); return 0; } change++; } else { offset = 0.0; } /* cap_radius */ if (argc > 6) { if (!ARG_IS_D(6, cap_radius)) { Tcl_AppendResult(interp, "<lj_cap> should be a double", (char *) NULL); return 0; } change++; } else { cap_radius = -1.0; } /* minimal radius */ if (argc > 7) { if (!ARG_IS_D(7, min)) { Tcl_AppendResult(interp, "<lj_rmin> should be a double", (char *) NULL); return 0; } change ++; } else { min = 0.0; } /* automatically compute the shift */ if (compute_auto_shift) shift = -(pow(sig/cut, 12) - pow(sig/cut, 6)); /* now set the parameters */ if (lennard_jones_set_params(part_type_a, part_type_b, eps, sig, cut, shift, offset, cap_radius, min) == ES_ERROR) { Tcl_AppendResult(interp, "particle types must be non-negative", (char *) NULL); return 0; } return change; }