ESPResSo 3.2.0-11-g9950804-git
Extensible Simulation Package for Soft Matter Research
interaction_data_tcl.c
Go to the documentation of this file.
00001 /*
00002   Copyright (C) 2010,2011,2012,2013 The ESPResSo project
00003   Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 
00004     Max-Planck-Institute for Polymer Research, Theory Group
00005   
00006   This file is part of ESPResSo.
00007   
00008   ESPResSo is free software: you can redistribute it and/or modify
00009   it under the terms of the GNU General Public License as published by
00010   the Free Software Foundation, either version 3 of the License, or
00011   (at your option) any later version.
00012   
00013   ESPResSo is distributed in the hope that it will be useful,
00014   but WITHOUT ANY WARRANTY; without even the implied warranty of
00015   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016   GNU General Public License for more details.
00017   
00018   You should have received a copy of the GNU General Public License
00019   along with this program.  If not, see <http://www.gnu.org/licenses/>. 
00020 */
00021 /** \file interaction_data.c
00022     Implementation of interaction_data.h
00023  */
00024 #include <string.h>
00025 #include <stdlib.h>
00026 #include "interaction_data_tcl.h"
00027 #include "interaction_data.h"
00028 #include "communication.h"
00029 
00030 #include "comforce_tcl.h"
00031 #include "comfixed_tcl.h"
00032 #include "rattle_tcl.h"
00033 #include "mol_cut_tcl.h"
00034 
00035 // for the force caps
00036 #include "lj.h"
00037 #include "ljangle.h"
00038 #include "morse.h"
00039 #include "tab.h"
00040 #include "buckingham.h"
00041 
00042 // nonbonded
00043 #include "bmhtf-nacl_tcl.h"
00044 #include "buckingham_tcl.h"
00045 #include "gb_tcl.h"
00046 #include "gaussian_tcl.h"
00047 #include "hat_tcl.h"
00048 #include "lj_tcl.h"
00049 #include "ljangle_tcl.h"
00050 #include "ljcos_tcl.h"
00051 #include "ljcos2_tcl.h"
00052 #include "ljgen_tcl.h"
00053 #include "hertzian_tcl.h"
00054 #include "morse_tcl.h"
00055 #include "dpd_tcl.h"
00056 #include "soft_sphere_tcl.h"
00057 #include "steppot_tcl.h"
00058 #include "tab_tcl.h"
00059 #include "tunable_slip_tcl.h"
00060 
00061 // Coulomb
00062 #include "debye_hueckel_tcl.h"
00063 #include "elc_tcl.h"
00064 #include "maggs_tcl.h"
00065 #include "mmm1d_tcl.h"
00066 #include "mmm2d_tcl.h"
00067 #include "p3m_tcl.h"
00068 #include "reaction_field_tcl.h"
00069 
00070 // Magnetostatics
00071 #include "mdlc_correction_tcl.h"
00072 #include "p3m-dipolar_tcl.h"
00073 #include "magnetic_non_p3m_methods_tcl.h"
00074 
00075 // bonded
00076 #include "angle_tcl.h"
00077 #include "angle_harmonic_tcl.h"
00078 #include "angle_cosine_tcl.h"
00079 #include "angle_cossquare_tcl.h"
00080 #include "angledist_tcl.h"
00081 #include "dihedral_tcl.h"
00082 #include "endangledist_tcl.h"
00083 #include "fene_tcl.h"
00084 #include "overlap_tcl.h"
00085 #include "harmonic_tcl.h"
00086 #include "subt_lj_tcl.h"
00087 #include "tcl/object-in-fluid/area_force_local_tcl.h"
00088 #include "tcl/object-in-fluid/area_force_global_tcl.h"
00089 #include "tcl/object-in-fluid/volume_force_tcl.h"
00090 #include "tcl/object-in-fluid/stretching_force_tcl.h"
00091 #include "tcl/object-in-fluid/bending_force_tcl.h"
00092 
00093 ///
00094 int tclprint_to_result_CoulombIA(Tcl_Interp *interp);
00095 
00096 #ifdef DIPOLES
00097 int tclprint_to_result_DipolarIA(Tcl_Interp *interp);
00098 #endif
00099 
00100 #ifdef ELECTROSTATICS
00101 
00102 /********************************************************************************/
00103 /*                                 electrostatics                               */
00104 /********************************************************************************/
00105 
00106 int tclcommand_inter_parse_coulomb(Tcl_Interp * interp, int argc, char ** argv)
00107 {
00108   double d1;
00109 
00110   Tcl_ResetResult(interp);
00111 
00112   if(argc == 0) {
00113     tclprint_to_result_CoulombIA(interp);
00114     return TCL_OK;
00115   }
00116   
00117   if (! ARG0_IS_D(d1)) {
00118 #ifdef P3M
00119     Tcl_ResetResult(interp);
00120     if (ARG0_IS_S("elc") && ((coulomb.method == COULOMB_P3M) || (coulomb.method == COULOMB_ELC_P3M)))
00121       return tclcommand_inter_coulomb_parse_elc_params(interp, argc - 1, argv + 1);
00122     if (coulomb.method == COULOMB_P3M)
00123       return tclcommand_inter_coulomb_parse_p3m_opt_params(interp, argc, argv);
00124     else {
00125       Tcl_AppendResult(interp, "expect: inter coulomb <bjerrum>",
00126                        (char *) NULL);
00127       return TCL_ERROR;
00128     }
00129 #else
00130     return TCL_ERROR;
00131 #endif
00132   }
00133 
00134   if (coulomb_set_bjerrum(d1) == TCL_ERROR) {
00135     Tcl_AppendResult(interp, argv[0], "bjerrum length must be positive",
00136                      (char *) NULL);
00137     return TCL_ERROR;
00138   }
00139     
00140   argc -= 1;
00141   argv += 1;
00142 
00143   if (d1 == 0.0 && argc == 0) {
00144     mpi_bcast_coulomb_params();
00145     return TCL_OK;
00146   }
00147 
00148   if(argc < 1) {
00149     Tcl_AppendResult(interp, "wrong # args for inter coulomb.",
00150                      (char *) NULL);
00151     mpi_bcast_coulomb_params();
00152     return TCL_ERROR;
00153   }
00154 
00155   /* check method */
00156 
00157 #define REGISTER_COULOMB(name, parser)                  \
00158   if(ARG0_IS_S(name))                                   \
00159     return parser(interp, argc-1, argv+1);
00160 
00161 #ifdef P3M
00162   REGISTER_COULOMB("p3m", tclcommand_inter_coulomb_parse_p3m);
00163 #endif
00164 
00165   REGISTER_COULOMB("dh", tclcommand_inter_coulomb_parse_dh);    
00166 
00167   if(ARG0_IS_S("rf")) return tclcommand_inter_coulomb_parse_rf(interp, argc-1, argv+1,COULOMB_RF);
00168 
00169   if(ARG0_IS_S("inter_rf")) return tclcommand_inter_coulomb_parse_rf(interp, argc-1, argv+1,COULOMB_INTER_RF);
00170 
00171   REGISTER_COULOMB("mmm1d", tclcommand_inter_coulomb_parse_mmm1d);
00172 
00173   REGISTER_COULOMB("mmm2d", tclcommand_inter_coulomb_parse_mmm2d);
00174 
00175   REGISTER_COULOMB("maggs", tclcommand_inter_coulomb_parse_maggs);
00176 
00177   REGISTER_COULOMB("memd", tclcommand_inter_coulomb_parse_maggs);
00178 
00179   /* fallback */
00180   coulomb.method  = COULOMB_NONE;
00181   coulomb.bjerrum = 0.0;
00182 
00183   mpi_bcast_coulomb_params();
00184 
00185   Tcl_AppendResult(interp, "do not know coulomb method \"",argv[0],
00186                    "\": coulomb switched off", (char *) NULL);
00187   
00188   return TCL_ERROR;
00189 }
00190 
00191 /* =========================================================
00192    ========================================================= */
00193 #endif /*ifdef ELECTROSTATICS */
00194 
00195 
00196 #ifdef DIPOLES
00197 int tclcommand_inter_parse_magnetic(Tcl_Interp * interp, int argc, char ** argv)
00198 {
00199   double d1;
00200 
00201   Tcl_ResetResult(interp);
00202 
00203   if(argc == 0) {
00204     tclprint_to_result_DipolarIA(interp);
00205     return TCL_OK;
00206   }
00207   
00208   if (! ARG0_IS_D(d1)) {
00209     Tcl_ResetResult(interp);
00210     
00211     if (ARG0_IS_S("mdlc") && ((coulomb.Dmethod == DIPOLAR_DS) || (coulomb.Dmethod == DIPOLAR_MDLC_DS)))
00212       return tclcommand_inter_magnetic_parse_mdlc_params(interp, argc - 1, argv + 1);
00213 
00214 #ifdef DP3M
00215     if (ARG0_IS_S("mdlc") && ((coulomb.Dmethod == DIPOLAR_P3M) || (coulomb.Dmethod == DIPOLAR_MDLC_P3M)))
00216       return tclcommand_inter_magnetic_parse_mdlc_params(interp, argc - 1, argv + 1);
00217     
00218     if (coulomb.Dmethod == DIPOLAR_P3M)
00219       return tclcommand_inter_magnetic_parse_dp3m_opt_params(interp, argc, argv);
00220     else {
00221       Tcl_AppendResult(interp, "expect: inter magnetic <Dbjerrum>",
00222                        (char *) NULL);
00223       return TCL_ERROR;
00224     }
00225 #else
00226     return TCL_ERROR;
00227 #endif
00228   }
00229 
00230 
00231   if (dipolar_set_Dbjerrum(d1) == TCL_ERROR) {
00232     Tcl_AppendResult(interp, argv[0], "Dbjerrum length must be positive",
00233                      (char *) NULL);
00234     return TCL_ERROR;
00235   }
00236     
00237   argc -= 1;
00238   argv += 1;
00239 
00240   if (d1 == 0.0 && argc == 0) {
00241     mpi_bcast_coulomb_params();
00242     return TCL_OK;
00243   }
00244 
00245   if(argc < 1) {
00246     Tcl_AppendResult(interp, "wrong # args for inter magnetic.",
00247                      (char *) NULL);
00248     mpi_bcast_coulomb_params();
00249     return TCL_ERROR;
00250   }
00251 
00252   /* check method */
00253 
00254 #define REGISTER_DIPOLAR(name, parser)                  \
00255   if(ARG0_IS_S(name))                                   \
00256     return parser(interp, argc-1, argv+1);
00257 
00258 #ifdef DP3M
00259   REGISTER_DIPOLAR("p3m", tclcommand_inter_magnetic_parse_dp3m);
00260 #endif
00261 
00262   REGISTER_DIPOLAR("dawaanr", tclcommand_inter_magnetic_parse_dawaanr);
00263 
00264   REGISTER_DIPOLAR("mdds", tclcommand_inter_magnetic_parse_mdds);
00265 
00266 
00267   /* fallback */
00268   coulomb.Dmethod  = DIPOLAR_NONE;
00269   coulomb.Dbjerrum = 0.0;
00270 
00271   mpi_bcast_coulomb_params();
00272 
00273   Tcl_AppendResult(interp, "do not know magnetic method \"",argv[0],
00274                    "\": magnetic switched off", (char *) NULL);
00275   
00276   return TCL_ERROR;
00277 }
00278 #endif   /* ifdef  DIPOLES */
00279 
00280 
00281 /********************************************************************************/
00282 /*                                       printing                               */
00283 /********************************************************************************/
00284 
00285 int tclprint_to_result_BondedIA(Tcl_Interp *interp, int i)
00286 {
00287   Bonded_ia_parameters *params = &bonded_ia_params[i];
00288   char buffer[TCL_INTEGER_SPACE];
00289 
00290   sprintf(buffer, "%d ", i);
00291   Tcl_AppendResult(interp, buffer, (char *)NULL);
00292   
00293   switch (params->type) {
00294   case BONDED_IA_FENE:
00295     return tclprint_to_result_feneIA(interp, params);
00296   case BONDED_IA_STRETCHING_FORCE:                                              
00297     return tclprint_to_result_stretchingforceIA(interp, params);
00298   case BONDED_IA_AREA_FORCE_LOCAL:                                      
00299         return tclprint_to_result_areaforcelocalIA(interp, params);
00300   case BONDED_IA_BENDING_FORCE:                                         
00301         return tclprint_to_result_bendingforceIA(interp, params);
00302 #ifdef AREA_FORCE_GLOBAL
00303   case BONDED_IA_AREA_FORCE_GLOBAL:                                             
00304         return tclprint_to_result_areaforceglobalIA(interp, params);
00305 #endif
00306 #ifdef VOLUME_FORCE
00307   case BONDED_IA_VOLUME_FORCE:                                          
00308         return tclprint_to_result_volumeforceIA(interp, params);
00309 #endif
00310   case BONDED_IA_HARMONIC:
00311     return tclprint_to_result_harmonicIA(interp, params);
00312 #ifdef BOND_ANGLE_OLD
00313   case BONDED_IA_ANGLE_OLD:
00314     return tclprint_to_result_angleIA(interp, params);
00315 #endif
00316 #ifdef BOND_ANGLE
00317   case BONDED_IA_ANGLE_HARMONIC:
00318     return tclprint_to_result_angle_harmonicIA(interp, params);
00319   case BONDED_IA_ANGLE_COSINE:
00320     return tclprint_to_result_angle_cosineIA(interp, params);
00321   case BONDED_IA_ANGLE_COSSQUARE:
00322     return tclprint_to_result_angle_cossquareIA(interp, params);
00323 #endif
00324 #ifdef BOND_ANGLEDIST
00325   case BONDED_IA_ANGLEDIST:
00326     return tclprint_to_result_angledistIA(interp, params);
00327 #endif
00328   case BONDED_IA_DIHEDRAL:
00329     return tclprint_to_result_dihedralIA(interp, params);
00330 #ifdef BOND_ENDANGLEDIST
00331   case BONDED_IA_ENDANGLEDIST:
00332     return tclprint_to_result_endangledistIA(interp, params);
00333 #endif
00334 #ifdef TABULATED
00335   case BONDED_IA_TABULATED:
00336     return tclprint_to_result_tabulated_bondedIA(interp, params);
00337 #endif
00338 #ifdef OVERLAPPED
00339   case BONDED_IA_OVERLAPPED:
00340     return tclprint_to_result_overlapIA(interp, params);
00341 #endif
00342 #ifdef BOND_CONSTRAINT
00343   case BONDED_IA_RIGID_BOND:
00344     return tclprint_to_result_rigid_bond(interp, params);
00345 #endif
00346 #ifdef LENNARD_JONES
00347   case BONDED_IA_SUBT_LJ:
00348     return tclprint_to_result_subt_ljIA(interp, params);
00349 #endif
00350 #ifdef BOND_VIRTUAL
00351   case BONDED_IA_VIRTUAL_BOND:
00352     Tcl_AppendResult(interp, "VIRTUAL_BOND ", (char *) NULL);
00353     return (TCL_OK);
00354 #endif
00355   case BONDED_IA_NONE:
00356     Tcl_ResetResult(interp);
00357     Tcl_AppendResult(interp, "unknown bonded interaction number ",buffer,
00358                      (char *) NULL);
00359     return (TCL_ERROR);
00360   }
00361   /* if none of the above */
00362   Tcl_ResetResult(interp);
00363   Tcl_AppendResult(interp, "unknown bonded interaction type",(char *) NULL);
00364   return (TCL_ERROR);
00365 }
00366 
00367 #ifdef ADRESS
00368 /* #ifdef THERMODYNAMIC_FORCE */
00369 int tclprint_to_result_TF(Tcl_Interp *interp, int i)
00370 {
00371   char buffer[TCL_DOUBLE_SPACE + 2*TCL_INTEGER_SPACE];
00372   TF_parameters *data = get_tf_param(i);
00373   
00374   if (!data) {
00375     Tcl_ResetResult(interp);
00376     Tcl_AppendResult(interp, "thermodynamic force does not exist",
00377                      (char *) NULL);
00378     return (TCL_ERROR);
00379   }
00380   sprintf(buffer, "%d ", i);
00381   Tcl_AppendResult(interp, buffer, (char *) NULL);
00382   
00383   if(data->TF_TAB_maxval !=0)
00384     Tcl_AppendResult(interp, "thermodynamic_force \"", data->TF_TAB_filename,"\"", (char *) NULL);
00385   
00386   return(TCL_OK);
00387 }
00388 /* #endif */
00389 #endif
00390 
00391 int tclprint_to_result_NonbondedIA(Tcl_Interp *interp, int i, int j)
00392 {
00393   char buffer[TCL_DOUBLE_SPACE + 2*TCL_INTEGER_SPACE];
00394   IA_parameters *data = get_ia_param(i, j);
00395 
00396   if (!data) {
00397     Tcl_ResetResult(interp);
00398     Tcl_AppendResult(interp, "interaction does not exist",
00399                      (char *) NULL);
00400     return (TCL_ERROR);
00401   }
00402 
00403   sprintf(buffer, "%d %d ", i, j);
00404   Tcl_AppendResult(interp, buffer, (char *) NULL);
00405 
00406 #ifdef LENNARD_JONES
00407   if (data->LJ_cut > 0.0) tclprint_to_result_ljIA(interp,i,j);
00408 #endif
00409 
00410 #ifdef LENNARD_JONES_GENERIC
00411   if (data->LJGEN_cut > 0.0) tclprint_to_result_ljgenIA(interp,i,j);
00412 #endif
00413 
00414 #ifdef LJ_ANGLE
00415   if (data->LJANGLE_cut > 0.0) tclprint_to_result_ljangleIA(interp,i,j);
00416 #endif
00417 
00418 #ifdef SMOOTH_STEP
00419   if (data->SmSt_cut > 0.0) tclprint_to_result_SmStIA(interp,i,j);
00420 #endif
00421 
00422 #ifdef HERTZIAN
00423   if (data->Hertzian_sig > 0.0) tclprint_to_result_HertzianIA(interp,i,j);
00424 #endif
00425 
00426 #ifdef GAUSSIAN
00427   if (data->Gaussian_cut > 0.0) tclprint_to_result_GaussianIA(interp,i,j);
00428 #endif
00429 
00430 #ifdef BMHTF_NACL
00431   if (data->BMHTF_cut > 0.0) tclprint_to_result_BMHTFIA(interp,i,j);
00432 #endif
00433 
00434 #ifdef MORSE
00435   if (data->MORSE_cut > 0.0) tclprint_to_result_morseIA(interp,i,j);
00436 #endif
00437 
00438 #ifdef LJCOS
00439   if (data->LJCOS_cut > 0.0) tclprint_to_result_ljcosIA(interp,i,j);
00440 #endif
00441 
00442 #ifdef BUCKINGHAM
00443   if (data->BUCK_cut > 0.0) tclprint_to_result_buckIA(interp,i,j);
00444 #endif
00445 
00446 #ifdef SOFT_SPHERE
00447   if (data->soft_cut > 0.0) tclprint_to_result_softIA(interp,i,j);
00448 #endif
00449 
00450 #ifdef HAT
00451   if (data->HAT_r > 0.0) tclprint_to_result_hatIA(interp,i,j);
00452 #endif
00453 
00454 #ifdef LJCOS2
00455   if (data->LJCOS2_cut > 0.0) tclprint_to_result_ljcos2IA(interp,i,j);
00456 #endif
00457 
00458 #ifdef GAY_BERNE
00459   if (data->GB_cut > 0.0) tclprint_to_result_gbIA(interp,i,j);
00460 #endif
00461 
00462 #ifdef TABULATED
00463   if (data->TAB_maxval > 0.0)
00464     Tcl_AppendResult(interp, "tabulated \"", data->TAB_filename,"\"", (char *) NULL);
00465 #endif
00466 
00467 #if defined(ADRESS) && defined(INTERFACE_CORRECTION)
00468   if(data->ADRESS_TAB_maxval > 0.0)
00469     Tcl_AppendResult(interp, "adress \"", data->ADRESS_TAB_filename,"\"", (char *) NULL);
00470 #endif
00471 
00472 #ifdef COMFORCE
00473   if (data->COMFORCE_flag > 0.0) tclprint_to_result_comforceIA(interp,i,j);
00474 #endif
00475 
00476 #ifdef COMFIXED
00477   if (data->COMFIXED_flag > 0.0) tclprint_to_result_comfixedIA(interp,i,j);
00478 #endif
00479 
00480 #ifdef INTER_DPD
00481   if ((data->dpd_r_cut > 0.0)||(data->dpd_tr_cut > 0.0)) tclprint_to_result_inter_dpdIA(interp,i,j);
00482 #endif
00483 
00484 #ifdef INTER_RF
00485   if (data->rf_on == 1) tclprint_to_result_interrfIA(interp,i,j);
00486 #endif
00487   
00488 #ifdef MOL_CUT
00489   if (data->mol_cut_type > 0.0) tclprint_to_result_molcutIA(interp,i,j);
00490 #endif
00491 
00492 #ifdef TUNABLE_SLIP
00493   if (data->TUNABLE_SLIP_r_cut > 0.0) tclprint_to_result_tunable_slipIA(interp,i,j);
00494 #endif
00495 
00496   return (TCL_OK);
00497 }
00498 
00499 int tclprint_to_result_CoulombIA(Tcl_Interp *interp) 
00500 {
00501 #ifdef ELECTROSTATICS
00502   char buffer[TCL_DOUBLE_SPACE + 2*TCL_INTEGER_SPACE];
00503   if (coulomb.method == COULOMB_NONE) {
00504     Tcl_AppendResult(interp, "coulomb 0.0", (char *) NULL);
00505     return (TCL_OK);
00506   }
00507   Tcl_PrintDouble(interp, coulomb.bjerrum, buffer);
00508   Tcl_AppendResult(interp, "{coulomb ", buffer, " ", (char *) NULL);
00509   switch (coulomb.method) {
00510 #ifdef P3M
00511   case COULOMB_ELC_P3M:
00512     tclprint_to_result_p3m(interp);
00513     tclprint_to_result_ELC(interp);
00514     break;
00515   case COULOMB_P3M: tclprint_to_result_p3m(interp); break;
00516 #endif
00517   case COULOMB_DH: tclprint_to_result_dh(interp); break;
00518   case COULOMB_RF: tclprint_to_result_rf(interp,"rf"); break;
00519   case COULOMB_INTER_RF: tclprint_to_result_rf(interp,"inter_rf"); break;
00520   case COULOMB_MMM1D: tclprint_to_result_MMM1D(interp); break;
00521   case COULOMB_MMM2D: tclprint_to_result_MMM2D(interp); break;
00522   case COULOMB_MAGGS: tclprint_to_result_Maggs(interp); break;
00523   default: break;
00524   }
00525   Tcl_AppendResult(interp, "}",(char *) NULL);
00526 
00527 #else
00528   Tcl_AppendResult(interp, "ELECTROSTATICS not compiled (see config.h)",(char *) NULL);
00529 #endif
00530   return (TCL_OK);
00531 }
00532 
00533 #ifdef DIPOLES
00534 int tclprint_to_result_DipolarIA(Tcl_Interp *interp) 
00535 {
00536   char buffer[TCL_DOUBLE_SPACE + 2*TCL_INTEGER_SPACE];
00537   if (coulomb.Dmethod == DIPOLAR_NONE) {
00538             Tcl_AppendResult(interp, "magnetic 0.0", (char *) NULL);
00539     return (TCL_OK);
00540   }
00541  
00542   Tcl_PrintDouble(interp, coulomb.Dbjerrum, buffer);
00543   Tcl_AppendResult(interp, "{magnetic ", buffer, " ", (char *) NULL);
00544   switch (coulomb.Dmethod) {
00545 #ifdef DP3M
00546   case DIPOLAR_MDLC_P3M:
00547     tclprint_to_result_dp3m(interp);   
00548     tclprint_to_result_MDLC(interp);
00549     break;
00550   case DIPOLAR_P3M: tclprint_to_result_dp3m(interp); break;
00551 #endif
00552   case DIPOLAR_MDLC_DS:
00553     tclprint_to_result_Magnetic_dipolar_direct_sum_(interp);
00554     tclprint_to_result_MDLC(interp);
00555     break;
00556   case DIPOLAR_ALL_WITH_ALL_AND_NO_REPLICA: tclprint_to_result_DAWAANR(interp); break;
00557   case DIPOLAR_DS: tclprint_to_result_Magnetic_dipolar_direct_sum_(interp); break;
00558   default: break;
00559   }
00560   Tcl_AppendResult(interp, "}",(char *) NULL);
00561 
00562   return (TCL_OK);
00563 }
00564 #endif
00565 
00566 int tclcommand_inter_print_all(Tcl_Interp *interp)
00567 {
00568   int i, j, start = 1;
00569 
00570   for (i = 0; i < n_bonded_ia; i++) {
00571     if (bonded_ia_params[i].type != BONDED_IA_NONE) {
00572       if (start) {
00573         Tcl_AppendResult(interp, "{", (char *)NULL);
00574         start = 0;
00575       }
00576       else
00577         Tcl_AppendResult(interp, " {", (char *)NULL);
00578 
00579       if (tclprint_to_result_BondedIA(interp, i) == TCL_ERROR) {
00580         return TCL_ERROR;
00581       }
00582       Tcl_AppendResult(interp, "}", (char *)NULL);
00583     }
00584   }
00585   for (i = 0; i < n_particle_types; i++)
00586     for (j = i; j < n_particle_types; j++) {
00587       if (checkIfParticlesInteract(i, j)) {
00588         if (start) {
00589           Tcl_AppendResult(interp, "{", (char *)NULL);
00590           start = 0;
00591         }
00592         else
00593           Tcl_AppendResult(interp, " {", (char *)NULL);
00594         if (tclprint_to_result_NonbondedIA(interp, i, j) == TCL_ERROR) {
00595           return TCL_ERROR;
00596         }
00597         Tcl_AppendResult(interp, "}", (char *)NULL);
00598       }
00599     }
00600 #ifdef ELECTROSTATICS
00601   if(coulomb.method != COULOMB_NONE) {
00602     if (start) 
00603       start = 0;
00604     else
00605       Tcl_AppendResult(interp, " ", (char *)NULL);
00606     /* here the curled braces will be set inside \ref tclprint_to_result_CoulombIA
00607        because electrostatics might be using several lists */
00608     tclprint_to_result_CoulombIA(interp);
00609   }
00610 #endif
00611 
00612 #ifdef DIPOLES
00613   if(coulomb.Dmethod != DIPOLAR_NONE) {
00614     if (start) 
00615       start = 0;
00616     else
00617       Tcl_AppendResult(interp, " ", (char *)NULL);
00618     /* here the curled braces will be set inside \ref tclprint_to_result_DipolarIA
00619        because magnetostatics might be using several lists */
00620     tclprint_to_result_DipolarIA(interp);
00621   }
00622 #endif
00623 
00624   if(force_cap != 0.0) {
00625     char buffer[TCL_DOUBLE_SPACE];
00626     
00627     if (start) {
00628       Tcl_AppendResult(interp, "{", (char *)NULL);
00629       start = 0;
00630     }
00631     else
00632       Tcl_AppendResult(interp, " {", (char *)NULL);
00633     if (force_cap == -1.0)
00634       Tcl_AppendResult(interp, "forcecap individual", (char *)NULL);
00635     else {
00636       Tcl_PrintDouble(interp, force_cap, buffer);
00637       Tcl_AppendResult(interp, "forcecap ", buffer, (char *) NULL);
00638     }
00639     Tcl_AppendResult(interp, "}", (char *)NULL);
00640   }
00641 
00642   return (TCL_OK);
00643 }
00644 
00645 int tclcommand_inter_print_bonded(Tcl_Interp *interp, int i)
00646 {
00647   char buffer[TCL_INTEGER_SPACE];
00648 
00649   Tcl_ResetResult(interp);
00650 
00651   if(i < 0) {
00652     Tcl_AppendResult(interp, "interaction type must be nonnegative",
00653                      (char *) NULL);
00654     return (TCL_ERROR);
00655   }
00656   
00657   /* print specific interaction information */
00658   if(i<n_bonded_ia) {
00659     tclprint_to_result_BondedIA(interp, i);
00660     return TCL_OK;
00661   }
00662 
00663   sprintf(buffer, "%d", i);
00664   Tcl_AppendResult(interp, "unknown bonded interaction number ", buffer,
00665                    (char *) NULL);
00666   return TCL_ERROR;
00667 }
00668 
00669 int tclcommand_inter_print_non_bonded(Tcl_Interp * interp,
00670                            int part_type_a, int part_type_b)
00671 {
00672   IA_parameters *data, *data_sym;
00673 
00674   Tcl_ResetResult(interp);
00675   make_particle_type_exist(part_type_a);
00676   make_particle_type_exist(part_type_b);
00677     
00678   data     = get_ia_param(part_type_a, part_type_b);
00679   data_sym = get_ia_param(part_type_b, part_type_a);
00680 
00681   if (!data || !data_sym) {
00682     Tcl_AppendResult(interp, "particle types must be nonnegative",
00683                      (char *) NULL);
00684     return TCL_ERROR;
00685   }
00686 
00687   return tclprint_to_result_NonbondedIA(interp, part_type_a, part_type_b);
00688 }
00689 
00690 #ifdef ADRESS
00691 /* #ifdef THERMODYNAMIC_FORCE */
00692 /* TODO: This function is not used anywhere. To be removed?  */
00693 int tf_print(Tcl_Interp * interp, int part_type)
00694 {
00695   //TF_parameters *data;
00696   Tcl_ResetResult(interp);
00697     
00698     make_particle_type_exist(part_type);
00699     
00700     //data = get_tf_param(part_type);
00701     
00702     return tclprint_to_result_TF(interp, part_type);
00703 }
00704 /* #endif */
00705 #endif
00706 
00707 
00708 int tclcommand_inter_parse_non_bonded(Tcl_Interp * interp,
00709                            int part_type_a, int part_type_b,
00710                            int argc, char ** argv)
00711 {
00712   int change;
00713   
00714   Tcl_ResetResult(interp);
00715 
00716   if (argc <= 0) {
00717     Tcl_AppendResult(interp, "wrong # args:  should be \"",
00718                      "inter <type 1> <type 2> ?interaction? ?values?\"",
00719                      (char *) NULL);
00720     return TCL_ERROR;
00721   }
00722 
00723   /* get interaction parameters */
00724 
00725   while (argc > 0) {
00726     /* The various parsers return the number of parsed parameters.
00727        If an error occured, 0 should be returned, since none of the parameters were
00728        understood */
00729 
00730     /* that's just for the else below... */
00731     if (0);
00732 
00733 #define REGISTER_NONBONDED(name, parser)                                \
00734     else if (ARG0_IS_S(name))                                           \
00735       change = parser(interp, part_type_a, part_type_b, argc, argv)
00736 
00737 #ifdef LENNARD_JONES
00738     REGISTER_NONBONDED("lennard-jones", tclcommand_inter_parse_lj);
00739 #endif
00740 
00741 #ifdef LENNARD_JONES_GENERIC
00742     REGISTER_NONBONDED("lj-gen", tclcommand_inter_parse_ljgen);
00743 #endif
00744 
00745 #ifdef LJ_ANGLE
00746     REGISTER_NONBONDED("lj-angle", tclcommand_inter_parse_ljangle);
00747 #endif
00748 
00749 #ifdef SMOOTH_STEP
00750     REGISTER_NONBONDED("smooth-step", tclcommand_inter_parse_SmSt);
00751 #endif
00752 
00753 #ifdef HERTZIAN
00754     REGISTER_NONBONDED("hertzian", tclcommand_inter_parse_hertzian);
00755 #endif
00756 
00757 #ifdef GAUSSIAN
00758     REGISTER_NONBONDED("gaussian", tclcommand_inter_parse_gaussian);
00759 #endif
00760 
00761 #ifdef BMHTF_NACL
00762     REGISTER_NONBONDED("bmhtf-nacl", tclcommand_inter_parse_BMHTF);
00763 #endif
00764 
00765 #ifdef MORSE
00766     REGISTER_NONBONDED("morse", tclcommand_inter_parse_morse);
00767 #endif
00768 
00769 #ifdef LJCOS
00770     REGISTER_NONBONDED("lj-cos", tclcommand_inter_parse_ljcos);
00771 #endif
00772 
00773 #ifdef BUCKINGHAM
00774     REGISTER_NONBONDED("buckingham", tclcommand_inter_parse_buckingham);
00775 #endif
00776 
00777 #ifdef SOFT_SPHERE
00778     REGISTER_NONBONDED("soft-sphere", tclcommand_inter_parse_soft);
00779 #endif
00780 
00781 #ifdef HAT
00782     REGISTER_NONBONDED("hat", tclcommand_inter_parse_hat);
00783 #endif
00784 
00785 #ifdef COMFORCE
00786     REGISTER_NONBONDED("comforce", tclcommand_inter_parse_comforce);
00787 #endif
00788 
00789 #ifdef LJCOS2
00790     REGISTER_NONBONDED("lj-cos2", tclcommand_inter_parse_ljcos2);
00791 #endif
00792 
00793 #ifdef COMFIXED
00794     REGISTER_NONBONDED("comfixed", tclcommand_inter_parse_comfixed);
00795 #endif
00796 
00797 #ifdef GAY_BERNE
00798     REGISTER_NONBONDED("gay-berne", tclcommand_inter_parse_gb);
00799 #endif
00800 
00801 #ifdef TABULATED
00802     REGISTER_NONBONDED("tabulated", tclcommand_inter_parse_tab);
00803 #endif
00804 #ifdef INTER_DPD
00805     REGISTER_NONBONDED("inter_dpd", tclcommand_inter_parse_inter_dpd);
00806 #endif
00807 #ifdef INTER_RF
00808     REGISTER_NONBONDED("inter_rf", tclcommand_inter_parse_interrf);
00809 #endif
00810 #ifdef TUNABLE_SLIP
00811     REGISTER_NONBONDED("tunable_slip", tclcommand_inter_parse_tunable_slip);
00812 #endif
00813 #ifdef MOL_CUT
00814     REGISTER_NONBONDED("molcut", tclcommand_inter_parse_molcut);
00815 #endif
00816     
00817 #ifdef ADRESS
00818 #ifdef INTERFACE_CORRECTION
00819     REGISTER_NONBONDED("adress_tab_ic", tclcommand_inter_parse_adress_tab);
00820 #endif
00821 #endif
00822     else {
00823       Tcl_AppendResult(interp, "excessive parameter/unknown interaction type \"", argv[0],
00824                        "\" in parsing non bonded interaction",
00825                        (char *) NULL);
00826       return TCL_ERROR;
00827     }
00828 
00829     if (change <= 0)
00830       return TCL_ERROR;
00831 
00832     argc -= change;
00833     argv += change;
00834   }
00835   return TCL_OK;
00836 }
00837 
00838 int tclcommand_inter_print_partner_num(Tcl_Interp *interp, int bond_type)
00839 {
00840   Bonded_ia_parameters * params;
00841   char buffer[TCL_INTEGER_SPACE];
00842 
00843   if(bond_type < 0) {
00844     Tcl_AppendResult(interp, "interaction type must be nonnegative",
00845                      (char *) NULL);
00846     return TCL_ERROR;
00847   }
00848 
00849   if(bond_type < n_bonded_ia) {
00850     params = &bonded_ia_params[bond_type];
00851     sprintf(buffer, "%d", params->num);
00852     Tcl_AppendResult(interp, buffer, (char *) NULL);
00853     return TCL_OK;
00854   }
00855  
00856   sprintf(buffer, "%d", bond_type);
00857   Tcl_AppendResult(interp, "unknown bonded interaction number ", buffer,
00858                    (char *) NULL);
00859   return TCL_ERROR;
00860 }
00861 
00862 /********************************************************************************/
00863 /*                                       parsing                                */
00864 /********************************************************************************/
00865 
00866 #ifdef BOND_VIRTUAL
00867 int tclcommand_inter_parse_virtual_bonds(Tcl_Interp *interp, int bond_type, int argc, char **argv)
00868 {
00869   CHECK_VALUE(virtual_set_params(bond_type), "bond type must be nonnegative");
00870 }
00871 #endif
00872 
00873 int tclcommand_inter_parse_bonded(Tcl_Interp *interp,
00874                        int bond_type,
00875                        int argc, char ** argv)
00876 {
00877   if (ARG0_IS_S("num")) {
00878     if (argc == 1)
00879       return tclcommand_inter_print_partner_num(interp, bond_type);
00880     else {
00881         Tcl_AppendResult(interp, "too many parameters",
00882                          (char *) NULL);
00883         return TCL_ERROR;
00884     }
00885   }
00886 
00887 #define REGISTER_BONDED(name,parser)                    \
00888   if (ARG0_IS_S(name)) return parser(interp, bond_type, argc, argv);
00889   
00890   REGISTER_BONDED("fene", tclcommand_inter_parse_fene);
00891   REGISTER_BONDED("stretching_force", tclcommand_inter_parse_stretching_force);
00892   REGISTER_BONDED("area_force_local", tclcommand_inter_parse_area_force_local);
00893   REGISTER_BONDED("bending_force", tclcommand_inter_parse_bending_force);
00894 #ifdef AREA_FORCE_GLOBAL
00895   REGISTER_BONDED("area_force_global", tclcommand_inter_parse_area_force_global);
00896 #endif
00897 #ifdef VOLUME_FORCE
00898   REGISTER_BONDED("volume_force", tclcommand_inter_parse_volume_force);
00899 #endif
00900   REGISTER_BONDED("harmonic", tclcommand_inter_parse_harmonic);
00901 #ifdef LENNARD_JONES  
00902   REGISTER_BONDED("subt_lj", tclcommand_inter_parse_subt_lj);
00903 #endif
00904 #ifdef BOND_ANGLE_OLD
00905   REGISTER_BONDED("angle", tclcommand_inter_parse_angle);
00906 #endif
00907 #ifdef BOND_ANGLE
00908   REGISTER_BONDED("angle_harmonic", tclcommand_inter_parse_angle_harmonic);
00909   REGISTER_BONDED("angle_cosine", tclcommand_inter_parse_angle_cosine);
00910   REGISTER_BONDED("angle_cossquare", tclcommand_inter_parse_angle_cossquare);
00911 #endif
00912 #ifdef BOND_ANGLEDIST
00913   REGISTER_BONDED("angledist", tclcommand_inter_parse_angledist);
00914 #endif
00915   REGISTER_BONDED("dihedral", tclcommand_inter_parse_dihedral);
00916 #ifdef BOND_ENDANGLEDIST
00917   REGISTER_BONDED("endangledist", tclcommand_inter_parse_endangledist);
00918 #endif
00919 #ifdef TABULATED
00920   REGISTER_BONDED("tabulated", tclcommand_inter_parse_tabulated_bonded);
00921 #endif
00922 #ifdef OVERLAPPED
00923   REGISTER_BONDED("overlapped", tclcommand_inter_parse_overlapped_bonded);
00924 #endif
00925 #ifdef BOND_CONSTRAINT
00926   REGISTER_BONDED("rigid_bond", tclcommand_inter_parse_rigid_bond);
00927 #endif
00928 #ifdef BOND_VIRTUAL
00929   REGISTER_BONDED("virtual_bond", tclcommand_inter_parse_virtual_bonds);
00930 #endif
00931   Tcl_AppendResult(interp, "unknown bonded interaction type \"", argv[0],
00932                    "\"", (char *) NULL);
00933   return TCL_ERROR;
00934 }
00935 
00936 int tclcommand_inter_parse_rest(Tcl_Interp * interp, int argc, char ** argv)
00937 {
00938   if(ARG0_IS_S("forcecap"))
00939     return tclcommand_inter_parse_forcecap(interp,argc-1, argv+1);
00940 
00941 #if defined(LENNARD_JONES) || defined(LENNARD_JONES_GENERIC)
00942   if(ARG0_IS_S("ljforcecap"))
00943     return tclcommand_inter_parse_ljforcecap(interp, argc-1, argv+1);
00944 #endif
00945 
00946 #ifdef LJ_ANGLE
00947   if(ARG0_IS_S("ljangleforcecap"))
00948     return tclcommand_inter_parse_ljangleforcecap(interp, argc-1, argv+1);
00949 #endif
00950 
00951   
00952 #ifdef MORSE
00953   if(ARG0_IS_S("morseforcecap"))
00954     return tclcommand_inter_parse_morseforcecap(interp, argc-1, argv+1);
00955 #endif
00956 
00957 #ifdef BUCKINGHAM
00958   if(ARG0_IS_S("buckforcecap"))
00959     return tclcommand_inter_parse_buckforcecap(interp, argc-1, argv+1);
00960 #endif
00961 
00962 #ifdef TABULATED
00963   if(ARG0_IS_S("tabforcecap"))
00964     return tclcommand_inter_parse_tabforcecap(interp, argc-1, argv+1);
00965 #endif
00966 
00967   if(ARG0_IS_S("coulomb")) {
00968     #ifdef ELECTROSTATICS
00969       return tclcommand_inter_parse_coulomb(interp, argc-1, argv+1);
00970    #else
00971        Tcl_AppendResult(interp, "ELECTROSTATICS not compiled (see config.h)", (char *) NULL);
00972     #endif
00973   }
00974   
00975   if(ARG0_IS_S("magnetic")) {
00976    #ifdef DIPOLES
00977       return tclcommand_inter_parse_magnetic(interp, argc-1, argv+1);
00978     #else
00979       Tcl_AppendResult(interp, "DIPOLES not compiled (see config.h)", (char *) NULL);
00980     #endif
00981   }
00982   
00983   
00984   Tcl_AppendResult(interp, "unknown interaction type \"", argv[0],
00985                    "\"", (char *) NULL);
00986 
00987   return TCL_ERROR;
00988 }
00989 
00990 int tclcommand_inter(ClientData _data, Tcl_Interp *interp,
00991           int argc, char **argv)
00992 {
00993   int i, j, err_code = TCL_OK, is_i1, is_i2;
00994 
00995   Tcl_ResetResult(interp);
00996 
00997   /* first we handle the special cases
00998 
00999      1. no parameters
01000      2. one parameter
01001      3. two parameters
01002 
01003      then the bonded interactions
01004      then the non bonded interactions
01005      then the rest
01006    */
01007 
01008   if (argc == 1) {
01009     /* no argument -> print all interaction informations. */
01010     err_code = tclcommand_inter_print_all(interp);
01011   }
01012   else if (argc == 2) {
01013     /* There is only 1 parameter, bonded ia printing or force caps */
01014 
01015     if (ARG1_IS_I(i))
01016       err_code = tclcommand_inter_print_bonded(interp, i);
01017     else {
01018       Tcl_ResetResult(interp);
01019       err_code = tclcommand_inter_parse_rest(interp, argc-1, argv+1);
01020     }
01021   }
01022   else if (argc == 3) {
01023     /* There are only 2 parameters, non_bonded printing */
01024     
01025     is_i1 = ARG_IS_I(1, i);
01026     is_i2 = ARG_IS_I(2, j);
01027 
01028     Tcl_ResetResult(interp);
01029 
01030     if (is_i1 && is_i2)
01031       err_code = tclcommand_inter_print_non_bonded(interp, i, j);
01032     else if (is_i1)
01033       err_code = tclcommand_inter_parse_bonded(interp, i, argc-2, argv+2);
01034     else
01035       err_code = tclcommand_inter_parse_rest(interp, argc-1, argv+1);
01036   }
01037   else {
01038     /****************************************************
01039      * Here we have more than 2 parameters
01040      ****************************************************/
01041 
01042     is_i1 = ARG_IS_I(1, i);
01043     is_i2 = ARG_IS_I(2, j);
01044 
01045     Tcl_ResetResult(interp);
01046 
01047     // non bonded interactions
01048     if (is_i1 && is_i2)
01049       err_code = tclcommand_inter_parse_non_bonded(interp, i, j, argc-3, argv+3);
01050     else if (is_i1)
01051       // bonded interactions
01052       err_code = tclcommand_inter_parse_bonded(interp, i, argc-2, argv+2);
01053     else
01054       // named interactions
01055       err_code = tclcommand_inter_parse_rest(interp, argc-1, argv+1);
01056   }
01057   /* check for background errors which have not been handled so far */
01058   return gather_runtime_errors(interp, err_code);
01059 }
01060 
01061 int tclcallback_min_global_cut(Tcl_Interp *interp, void *_data)
01062 {
01063   min_global_cut = *((double *)_data);
01064   mpi_bcast_parameter(FIELD_MIN_GLOBAL_CUT);
01065   return TCL_OK;
01066 }