ESPResSo 3.2.0-11-g9950804-git
Extensible Simulation Package for Soft Matter Research
interaction_data.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 "utils.h"
00027 #include "rattle.h"
00028 #include "interaction_data.h"
00029 #include "errorhandling.h"
00030 #include "communication.h"
00031 #include "grid.h"
00032 #include "pressure.h"
00033 #include "p3m.h"
00034 #include "debye_hueckel.h"
00035 #include "reaction_field.h"
00036 #include "mmm1d.h"
00037 #include "mmm2d.h"
00038 #include "maggs.h"
00039 #include "elc.h"
00040 #include "lj.h"
00041 #include "ljgen.h"
00042 #include "ljangle.h"
00043 #include "steppot.h"
00044 #include "hertzian.h"
00045 #include "gaussian.h"
00046 #include "buckingham.h"
00047 #include "soft_sphere.h"
00048 #include "hat.h"
00049 #include "tab.h"
00050 #include "overlap.h"
00051 #include "ljcos.h"
00052 #include "ljcos2.h"
00053 #include "gb.h"
00054 #include "cells.h"
00055 #include "comforce.h"
00056 #include "comfixed.h"
00057 #include "morse.h"
00058 #include "dpd.h"
00059 #include "tunable_slip.h"
00060 #include "magnetic_non_p3m_methods.h"
00061 #include "mdlc_correction.h"
00062 #include "initialize.h"
00063 
00064 /****************************************
00065  * variables
00066  *****************************************/
00067 int n_particle_types = 0;
00068 int n_interaction_types = 0;
00069 IA_parameters *ia_params = NULL;
00070 
00071 #ifdef ADRESS
00072 /* #ifdef THERMODYNAMIC_FORCE */
00073 TF_parameters *tf_params = NULL;
00074 /* #endif */
00075 #endif
00076 
00077 #if defined(ELECTROSTATICS) || defined(DIPOLES)
00078 Coulomb_parameters coulomb = { 
00079 #ifdef ELECTROSTATICS
00080   0.0, 0.0, COULOMB_NONE,
00081 #endif
00082 #ifdef DIPOLES
00083   0.0, 0.0, DIPOLAR_NONE,
00084 #endif
00085 };
00086 #endif
00087 
00088 #ifdef ELECTROSTATICS
00089 Debye_hueckel_params dh_params = { 0.0, 0.0 };
00090 Reaction_field_params rf_params = { 0.0, 0.0 };
00091 #endif
00092 
00093 int n_bonded_ia = 0;
00094 Bonded_ia_parameters *bonded_ia_params = NULL;
00095 
00096 double min_global_cut = 0.0;
00097 
00098 double max_cut;
00099 double max_cut_nonbonded;
00100 double max_cut_bonded;
00101 /** maximal cutoff of type-independent short range ia, mainly
00102     electrostatics and DPD*/
00103 double max_cut_global;
00104 
00105 /** Array containing all tabulated forces*/
00106 DoubleList tabulated_forces;
00107 /** Corresponding array containing all tabulated energies*/
00108 DoubleList tabulated_energies;
00109 
00110 #ifdef ADRESS
00111 #ifdef INTERFACE_CORRECTION
00112 /** Array containing all adress tabulated forces*/
00113 DoubleList adress_tab_forces;
00114 /** Corresponding array containing all adress tabulated energies*/
00115 DoubleList adress_tab_energies;
00116 #endif
00117 
00118 /* #ifdef THERMODYNAMIC_FORCE */
00119 /** Array containing the thermodynamic forces **/
00120 DoubleList thermodynamic_forces;
00121 DoubleList thermodynamic_f_energies;
00122 /* #endif */
00123 #endif
00124 
00125 /*****************************************
00126  * function prototypes
00127  *****************************************/
00128 
00129 /** calculates and returns the maximal global nonbonded cutoff that is
00130     required.  Currently, this are just the cutoffs from the
00131     electrostatics method and some dpd cutoffs. */
00132 static void recalc_global_maximal_nonbonded_cutoff();
00133 /** calculate the maximal cutoff of bonded interactions, required to
00134     determine the cell size for communication. */
00135 static void recalc_maximal_cutoff_bonded();
00136 
00137 /*****************************************
00138  * general lowlevel functions
00139  *****************************************/
00140 
00141 /** Initialize force and energy tables */
00142 void force_and_energy_tables_init() {
00143   init_doublelist(&tabulated_forces);
00144   init_doublelist(&tabulated_energies);
00145 }
00146 
00147 #ifdef ADRESS
00148 #ifdef INTERFACE_CORRECTION
00149 /** Initialize adress force and energy tables */
00150 void adress_force_and_energy_tables_init() {
00151   init_doublelist(&adress_tab_forces);
00152   init_doublelist(&adress_tab_energies);
00153 }
00154 #endif
00155 
00156 /* #ifdef THERMODYNAMIC_FORCE */
00157 void tf_tables_init() {
00158   init_doublelist(&thermodynamic_forces);
00159   init_doublelist(&thermodynamic_f_energies);
00160 }
00161 /* #endif */
00162 #endif
00163 
00164 /** Initialize interaction parameters. */
00165 void initialize_ia_params(IA_parameters *params) {
00166  
00167   params->particlesInteract = 0;
00168   params->max_cut = max_cut_global;
00169 
00170 #ifdef LENNARD_JONES
00171   params->LJ_eps =
00172     params->LJ_sig =
00173     params->LJ_shift =
00174     params->LJ_offset =
00175     params->LJ_capradius =
00176     params->LJ_min = 0.0;
00177   params->LJ_cut = INACTIVE_CUTOFF;
00178 #endif
00179 
00180 #ifdef LENNARD_JONES_GENERIC
00181   params->LJGEN_eps =
00182     params->LJGEN_sig =
00183     params->LJGEN_shift =
00184     params->LJGEN_offset =
00185     params->LJGEN_capradius =
00186     params->LJGEN_a1 =
00187     params->LJGEN_a2 = 
00188     params->LJGEN_b1 =
00189     params->LJGEN_b2 = 0.0;
00190   params->LJGEN_cut = INACTIVE_CUTOFF;
00191 #endif
00192 
00193 #ifdef LJ_ANGLE
00194   params->LJANGLE_eps =
00195     params->LJANGLE_sig =
00196     params->LJANGLE_bonded1type=
00197     params->LJANGLE_bonded1pos = 
00198     params->LJANGLE_bonded1neg = 
00199     params->LJANGLE_bonded2pos = 
00200     params->LJANGLE_bonded2neg = 
00201     params->LJANGLE_capradius =
00202     params->LJANGLE_z0 =
00203     params->LJANGLE_kappa =
00204     params->LJANGLE_epsprime = 0.0;
00205   params->LJANGLE_dz = -1.0;
00206   params->LJANGLE_cut = INACTIVE_CUTOFF;
00207 #endif
00208 
00209 #ifdef SMOOTH_STEP
00210   params->SmSt_eps =
00211     params->SmSt_sig =
00212     params->SmSt_d =
00213     params->SmSt_n =
00214     params->SmSt_k0 = 0.0;
00215   params->SmSt_cut = INACTIVE_CUTOFF;
00216 #endif
00217 
00218 #ifdef HERTZIAN
00219   params->Hertzian_eps = 0.0;
00220   params->Hertzian_sig = INACTIVE_CUTOFF;
00221 #endif
00222 
00223 #ifdef GAUSSIAN
00224   params->Gaussian_eps = 0.0;
00225   params->Gaussian_sig = 1.0;
00226   params->Gaussian_cut = INACTIVE_CUTOFF;
00227 #endif
00228 
00229 #ifdef BMHTF_NACL
00230   params->BMHTF_A =
00231     params->BMHTF_B =
00232     params->BMHTF_C =
00233     params->BMHTF_D =
00234     params->BMHTF_sig =
00235     params->BMHTF_computed_shift = 0.0;
00236   params->BMHTF_cut = INACTIVE_CUTOFF;
00237 #endif
00238 
00239 #ifdef MORSE
00240   params->MORSE_eps = 
00241     params->MORSE_alpha =
00242     params->MORSE_rmin =
00243     params->MORSE_rest = 
00244     params->MORSE_capradius = 0;
00245   params->MORSE_cut = INACTIVE_CUTOFF;
00246 #endif
00247 
00248 #ifdef BUCKINGHAM
00249   params->BUCK_A =
00250     params->BUCK_B =
00251     params->BUCK_C =
00252     params->BUCK_D =
00253     params->BUCK_discont =
00254     params->BUCK_shift =
00255     params->BUCK_capradius =
00256     params->BUCK_F1 =
00257     params->BUCK_F2 = 0.0;
00258   params->BUCK_cut = INACTIVE_CUTOFF;
00259 #endif
00260 
00261 #ifdef SOFT_SPHERE
00262   params->soft_a =
00263     params->soft_n =
00264     params->soft_offset = 0.0;
00265   params->soft_cut = INACTIVE_CUTOFF;
00266 #endif
00267 
00268 #ifdef HAT
00269   params->HAT_Fmax =
00270     params->HAT_r = 0.0;
00271 #endif
00272 
00273 #ifdef LJCOS
00274   params->LJCOS_eps =
00275     params->LJCOS_sig =
00276     params->LJCOS_offset =
00277     params->LJCOS_alfa =
00278     params->LJCOS_beta =
00279     params->LJCOS_rmin = 0.0;
00280   params->LJCOS_cut = INACTIVE_CUTOFF;
00281 #endif
00282 
00283 #ifdef LJCOS2
00284   params->LJCOS2_eps =
00285     params->LJCOS2_sig =
00286     params->LJCOS2_offset =
00287     params->LJCOS2_w =
00288     params->LJCOS2_rchange = 
00289     params->LJCOS2_capradius = 0.0;
00290   params->LJCOS2_cut = INACTIVE_CUTOFF;
00291 #endif
00292 
00293 #ifdef GAY_BERNE
00294   params->GB_eps =
00295     params->GB_sig =
00296     params->GB_k1 =
00297     params->GB_k2 =
00298     params->GB_mu =
00299     params->GB_nu =
00300     params->GB_chi1 =
00301     params->GB_chi2 = 0.0;
00302   params->GB_cut = INACTIVE_CUTOFF;
00303 #endif
00304 
00305 #ifdef TABULATED
00306   params->TAB_npoints =
00307     params->TAB_startindex = 0;
00308   params->TAB_minval =
00309     params->TAB_stepsize = 0.0;
00310   strcpy(params->TAB_filename,"");
00311   params->TAB_maxval = INACTIVE_CUTOFF;
00312 #endif
00313 
00314 #ifdef INTER_DPD
00315   params->dpd_gamma = 0.0;
00316   params->dpd_wf = 0;
00317   params->dpd_pref1 = 0.0;
00318   params->dpd_pref2 = 0.0;
00319   params->dpd_tgamma = 0.0;
00320   params->dpd_tr_cut = 0.0;
00321   params->dpd_wf = 0;
00322   params->dpd_pref3 = 0;
00323   params->dpd_pref4 = 0;
00324   params->dpd_r_cut = INACTIVE_CUTOFF;
00325 #endif
00326 
00327 #ifdef TUNABLE_SLIP
00328   params->TUNABLE_SLIP_temp  = 0.0;
00329   params->TUNABLE_SLIP_gamma = 0.0;
00330   params->TUNABLE_SLIP_time  = 0.0;
00331   params->TUNABLE_SLIP_vx  = 0.0;
00332   params->TUNABLE_SLIP_vy  = 0.0;
00333   params->TUNABLE_SLIP_vz  = 0.0;
00334   params->TUNABLE_SLIP_r_cut = INACTIVE_CUTOFF;
00335 #endif
00336 
00337 #if defined(ADRESS) && defined(INTERFACE_CORRECTION)
00338   //params->ADRESS_IC_npoints = 0;
00339   params->ADRESS_TAB_npoints = 0;
00340   params->ADRESS_TAB_startindex = 0;
00341   params->ADRESS_TAB_minval = 0.0;
00342   params->ADRESS_TAB_stepsize = 0.0;
00343   strcpy(params->ADRESS_TAB_filename,"");
00344   params->ADRESS_TAB_maxval = INACTIVE_CUTOFF;
00345 #endif
00346 
00347   /* things that are not strictly speaking short-ranged interactions,
00348      and do not have a cutoff */
00349 #ifdef COMFORCE
00350   params->COMFORCE_flag = 0;
00351   params->COMFORCE_dir = 0;
00352   params->COMFORCE_force = 0.;
00353   params->COMFORCE_fratio = 0.;
00354 #endif
00355 
00356 #ifdef COMFIXED
00357   params->COMFIXED_flag = 0;
00358 #endif
00359 
00360 #ifdef INTER_RF
00361   params->rf_on = 0;
00362 #endif
00363 
00364 #ifdef MOL_CUT
00365   params->mol_cut_type = 0;
00366   params->mol_cut_cutoff = 0.0;
00367 #endif
00368 
00369 #ifdef CATALYTIC_REACTIONS
00370   params->REACTION_range = 0.0;
00371 #endif
00372 }
00373 
00374 /** Copy interaction parameters. */
00375 void copy_ia_params(IA_parameters *dst, IA_parameters *src) {
00376   memcpy(dst, src, sizeof(IA_parameters));
00377 }
00378 
00379 IA_parameters *get_ia_param_safe(int i, int j) {
00380   make_particle_type_exist(imax(i, j));
00381   return get_ia_param(i, j);
00382 }
00383 
00384 #ifdef ADRESS
00385 /* #ifdef THERMODYNAMIC_FORCE */
00386 void initialize_tf_params(TF_parameters *params){
00387   params->TF_TAB_npoints = 0;
00388   params->TF_TAB_startindex = 0;
00389   
00390   params->TF_prefactor = 0.0;
00391   params->TF_TAB_minval = 0.0;
00392   params->TF_TAB_maxval = 0.0;
00393   params->TF_TAB_stepsize = 0.0;
00394   strcpy(params->TF_TAB_filename, "");
00395 }
00396 
00397 void copy_tf_params(TF_parameters *dst, TF_parameters *src){
00398   memcpy(dst, src, sizeof(TF_parameters));
00399 }
00400 
00401 int checkIfTF(TF_parameters *data){
00402   if (data->TF_TAB_maxval !=0)
00403     return 1;
00404   return 0;
00405 }
00406 /* #endif */
00407 #endif
00408 
00409 static void recalc_maximal_cutoff_bonded()
00410 {
00411   int i;
00412   double max_cut_tmp;
00413 
00414   max_cut_bonded = 0.0;
00415 
00416   for (i = 0; i < n_bonded_ia; i++) {
00417     switch (bonded_ia_params[i].type) {
00418     case BONDED_IA_FENE:
00419       max_cut_tmp = bonded_ia_params[i].p.fene.r0+bonded_ia_params[i].p.fene.drmax;
00420       if(max_cut_bonded < max_cut_tmp)
00421         max_cut_bonded = max_cut_tmp;
00422       break;
00423     case BONDED_IA_HARMONIC:
00424       if((bonded_ia_params[i].p.harmonic.r_cut>0)&&(max_cut_bonded < bonded_ia_params[i].p.harmonic.r_cut))
00425         max_cut_bonded = bonded_ia_params[i].p.harmonic.r_cut;
00426       break;
00427     case BONDED_IA_SUBT_LJ:
00428       if(max_cut_bonded < bonded_ia_params[i].p.subt_lj.r)
00429         max_cut_bonded = bonded_ia_params[i].p.subt_lj.r;
00430       break;
00431     case BONDED_IA_RIGID_BOND:
00432       if(max_cut_bonded < sqrt(bonded_ia_params[i].p.rigid_bond.d2))
00433         max_cut_bonded = sqrt(bonded_ia_params[i].p.rigid_bond.d2);
00434        break;
00435 #ifdef TABULATED
00436     case BONDED_IA_TABULATED:
00437       if(bonded_ia_params[i].p.tab.type == TAB_BOND_LENGTH &&
00438          max_cut_bonded < bonded_ia_params[i].p.tab.maxval)
00439         max_cut_bonded = bonded_ia_params[i].p.tab.maxval;
00440       break;
00441 #endif
00442 #ifdef OVERLAPPED 
00443     case BONDED_IA_OVERLAPPED:
00444       /* in UNIT Angstrom */
00445       if(bonded_ia_params[i].p.overlap.type == OVERLAP_BOND_LENGTH &&
00446          max_cut_bonded < bonded_ia_params[i].p.overlap.maxval)
00447         max_cut_bonded = bonded_ia_params[i].p.overlap.maxval;
00448       break;
00449 #endif
00450     default:
00451      break;
00452     }
00453   }
00454 
00455   /* Bond angle and dihedral potentials do not contain a cutoff
00456      intrinsically. The cutoff for these potentials depends on the
00457      bond length potentials. For bond angle potentials nothing has to
00458      be done (it is assumed, that particles participating in a bond
00459      angle or dihedral potential are bound to each other by some bond
00460      length potential (FENE, Harmonic or tabulated)). For dihedral
00461      potentials (both normal and tabulated ones) it follows, that the
00462      cutoff is TWO TIMES the maximal cutoff! That's what the following
00463      lines assure. */
00464   max_cut_tmp = 2.0*max_cut_bonded;
00465   for (i = 0; i < n_bonded_ia; i++) {
00466     switch (bonded_ia_params[i].type) {
00467     case BONDED_IA_DIHEDRAL:
00468       max_cut_bonded = max_cut_tmp;
00469       break;
00470 #ifdef TABULATED
00471     case BONDED_IA_TABULATED:
00472       if(bonded_ia_params[i].p.tab.type == TAB_BOND_DIHEDRAL)
00473         max_cut_bonded = max_cut_tmp;
00474       break;
00475 #endif
00476 #ifdef OVERLAPPED 
00477     case BONDED_IA_OVERLAPPED:
00478       if(bonded_ia_params[i].p.overlap.type == OVERLAP_BOND_DIHEDRAL)
00479         max_cut_bonded = max_cut_tmp;
00480       break;
00481 #endif
00482     default:
00483       break;
00484     }
00485   }
00486 }
00487 
00488 static void recalc_global_maximal_nonbonded_cutoff()
00489 {
00490   /* user defined minimal global cut. This makes sure that data of
00491    pairs of particles with a distance smaller than this are always
00492    available on the same node (through ghosts). Required for example
00493    for the relative virtual sites algorithm. */
00494   max_cut_global = min_global_cut;
00495 
00496 #ifdef ELECTROSTATICS
00497   /* Cutoff for the real space electrostatics.
00498      Note that the box length may have changed,
00499      but the method not yet reinitialized.
00500    */
00501   switch (coulomb.method) {
00502 #ifdef P3M 
00503   case COULOMB_ELC_P3M:
00504     if (max_cut_global < elc_params.space_layer)
00505       max_cut_global = elc_params.space_layer;
00506     // fall through
00507   case COULOMB_P3M: {
00508     /* do not use precalculated r_cut here, might not be set yet */
00509     double r_cut = p3m.params.r_cut_iL* box_l[0];
00510     if (max_cut_global < r_cut)
00511       max_cut_global = r_cut;
00512     break;
00513   }
00514 #endif
00515   case COULOMB_DH:
00516     if (max_cut_global < dh_params.r_cut)
00517       max_cut_global = dh_params.r_cut;
00518     break;
00519   case COULOMB_RF:
00520   case COULOMB_INTER_RF:
00521     if (max_cut_global < rf_params.r_cut)
00522       max_cut_global = rf_params.r_cut;
00523     break;
00524   }
00525 #endif /*ifdef ELECTROSTATICS */
00526   
00527 #ifdef DIPOLES
00528   switch (coulomb.Dmethod) {
00529 #ifdef DP3M
00530   case DIPOLAR_MDLC_P3M:
00531     // fall through
00532   case DIPOLAR_P3M: {
00533     /* do not use precalculated r_cut here, might not be set yet */
00534     double r_cut = dp3m.params.r_cut_iL* box_l[0];
00535     if (max_cut_global < r_cut)
00536       max_cut_global = r_cut;
00537     break;
00538   }
00539 #endif /*ifdef DP3M */
00540   }       
00541 #endif
00542 
00543 #ifdef DPD
00544   if (dpd_r_cut != 0) {
00545     if(max_cut_global < dpd_r_cut)
00546       max_cut_global = dpd_r_cut;
00547   }
00548 #endif
00549   
00550 #ifdef TRANS_DPD
00551   if (dpd_tr_cut != 0) {
00552     if(max_cut_global < dpd_tr_cut)
00553       max_cut_global = dpd_tr_cut;
00554   }
00555 #endif
00556 
00557 }
00558 
00559 static void recalc_maximal_cutoff_nonbonded()
00560 {
00561   int i, j;
00562 
00563   CELL_TRACE(fprintf(stderr, "%d: recalc_maximal_cutoff_nonbonded\n", this_node));
00564 
00565   recalc_global_maximal_nonbonded_cutoff();
00566 
00567   CELL_TRACE(fprintf(stderr, "%d: recalc_maximal_cutoff_nonbonded: max_cut_global = %f\n", this_node, max_cut_global));
00568 
00569   max_cut_nonbonded = max_cut_global;
00570   
00571   for (i = 0; i < n_particle_types; i++)
00572     for (j = i; j < n_particle_types; j++) {
00573       double max_cut_current = 0;
00574 
00575       IA_parameters *data = get_ia_param(i, j);
00576 
00577 #ifdef LENNARD_JONES
00578       if(max_cut_current < (data->LJ_cut+data->LJ_offset))
00579         max_cut_current = (data->LJ_cut+data->LJ_offset);
00580 #endif
00581 
00582 #ifdef INTER_DPD
00583       {
00584         double max_cut_tmp = (data->dpd_r_cut > data->dpd_tr_cut) ?
00585           data->dpd_r_cut : data->dpd_tr_cut;
00586         if (max_cut_current <  max_cut_tmp)
00587           max_cut_current = max_cut_tmp;
00588       }
00589 #endif
00590 
00591 #ifdef LENNARD_JONES_GENERIC
00592       if (max_cut_current < (data->LJGEN_cut+data->LJGEN_offset))
00593         max_cut_current = (data->LJGEN_cut+data->LJGEN_offset);
00594 #endif
00595 
00596 #ifdef LJ_ANGLE
00597       if (max_cut_current < (data->LJANGLE_cut))
00598         max_cut_current = (data->LJANGLE_cut);
00599 #endif
00600 
00601 #ifdef SMOOTH_STEP
00602       if (max_cut_current < data->SmSt_cut)
00603         max_cut_current = data->SmSt_cut;
00604 #endif
00605 
00606 #ifdef HERTZIAN
00607       if (max_cut_current < data->Hertzian_sig)
00608         max_cut_current = data->Hertzian_sig;
00609 #endif
00610 
00611 #ifdef GAUSSIAN
00612       if (max_cut_current < data->Gaussian_cut)
00613         max_cut_current = data->Gaussian_cut;
00614 #endif
00615 
00616 #ifdef BMHTF_NACL
00617       if (max_cut_current < data->BMHTF_cut)
00618         max_cut_current = data->BMHTF_cut;
00619 #endif
00620 
00621 #ifdef MORSE
00622       if (max_cut_current < data->MORSE_cut)
00623         max_cut_current = data->MORSE_cut;
00624 #endif
00625 
00626 #ifdef BUCKINGHAM
00627       if (max_cut_current < data->BUCK_cut)
00628         max_cut_current = data->BUCK_cut;
00629 #endif
00630 
00631 #ifdef SOFT_SPHERE
00632       if (max_cut_current < data->soft_cut)
00633         max_cut_current = data->soft_cut;
00634 #endif
00635 
00636 #ifdef HAT
00637       if (max_cut_current < data->HAT_r)
00638         max_cut_current = data->HAT_r;
00639 #endif
00640 
00641 #ifdef LJCOS
00642       {
00643         double max_cut_tmp = data->LJCOS_cut + data->LJCOS_offset;
00644         if (max_cut_current < max_cut_tmp)
00645           max_cut_current = max_cut_tmp;
00646       }
00647 #endif
00648 
00649 #ifdef LJCOS2
00650       {
00651         double max_cut_tmp = data->LJCOS2_cut + data->LJCOS2_offset;
00652         if (max_cut_current < max_cut_tmp)
00653           max_cut_current = max_cut_tmp;
00654       }
00655 #endif
00656 
00657 #ifdef GAY_BERNE
00658       if (max_cut_current < data->GB_cut)
00659         max_cut_current = data->GB_cut;
00660 #endif
00661 
00662 #ifdef TABULATED
00663       if (max_cut_current < data->TAB_maxval)
00664         max_cut_current = data->TAB_maxval;
00665 #endif
00666          
00667 #if defined(ADRESS) && defined(INTERFACE_CORRECTION)
00668       if (max_cut_current < data->ADRESS_TAB_maxval)
00669         max_cut_current = data->ADRESS_TAB_maxval;
00670 #endif
00671 
00672 #ifdef TUNABLE_SLIP
00673       if (max_cut_current < data->TUNABLE_SLIP_r_cut)
00674         max_cut_current = data->TUNABLE_SLIP_r_cut;
00675 #endif
00676 
00677 #ifdef CATALYTIC_REACTIONS
00678       if (max_cut_current < data->REACTION_range)
00679         max_cut_current = data->REACTION_range;
00680 #endif
00681 
00682 #ifdef MOL_CUT
00683       if (data->mol_cut_type != 0) {
00684         if (max_cut_current < data->mol_cut_cutoff)
00685           max_cut_current = data->mol_cut_cutoff;
00686         max_cut_current += 2.0* max_cut_bonded;
00687       }
00688 #endif
00689 
00690       IA_parameters *data_sym = get_ia_param(j, i);
00691 
00692       /* no interaction ever touched it, at least no real
00693          short-ranged one (that writes to the nonbonded energy) */
00694       data_sym->particlesInteract =
00695         data->particlesInteract = (max_cut_current > 0.0);
00696       
00697       /* take into account any electrostatics */
00698       if (max_cut_global > max_cut_current)
00699         max_cut_current = max_cut_global;
00700 
00701       data_sym->max_cut =
00702         data->max_cut = max_cut_current;
00703 
00704       if (max_cut_current > max_cut_nonbonded)
00705         max_cut_nonbonded = max_cut_current;
00706 
00707       CELL_TRACE(fprintf(stderr, "%d: pair %d,%d max_cut total %f\n",
00708                          this_node, i, j, data->max_cut));
00709     }
00710 }
00711 
00712 void recalc_maximal_cutoff()
00713 {
00714   recalc_maximal_cutoff_bonded();
00715   recalc_maximal_cutoff_nonbonded();
00716 
00717   /* make max_cut the maximal cutoff of both bonded and non-bonded
00718      interactions */
00719   if (max_cut_nonbonded > max_cut_bonded)
00720     max_cut = max_cut_nonbonded;
00721   else
00722     max_cut = max_cut_bonded;
00723 }
00724 
00725 char *get_name_of_bonded_ia(int i) {
00726   switch (i) {
00727   case BONDED_IA_FENE:
00728     return "FENE";
00729   case BONDED_IA_ANGLE_OLD:
00730     return "angle";
00731   case BONDED_IA_ANGLE_HARMONIC:
00732     return "angle_harmonic";
00733   case BONDED_IA_ANGLE_COSINE:
00734     return "angle_cosine";
00735   case BONDED_IA_ANGLE_COSSQUARE:
00736     return "angle_cossquare";
00737   case BONDED_IA_ANGLEDIST:
00738     return "angledist";
00739   case BONDED_IA_DIHEDRAL:
00740     return "dihedral";
00741   case BONDED_IA_ENDANGLEDIST:
00742     return "endangledist";
00743   case BONDED_IA_HARMONIC:
00744     return "HARMONIC";
00745   case BONDED_IA_SUBT_LJ:
00746     return "SUBT_LJ";
00747   case BONDED_IA_TABULATED:
00748     return "tabulated";
00749   case BONDED_IA_OVERLAPPED:
00750     return "overlapped";
00751   case BONDED_IA_RIGID_BOND:
00752     return "RIGID_BOND";
00753   case BONDED_IA_VIRTUAL_BOND:
00754     return "VIRTUAL_BOND";
00755   case BONDED_IA_STRETCHING_FORCE:
00756     return "STRETCHING_FORCE";
00757   case BONDED_IA_AREA_FORCE_LOCAL:
00758     return "AREA_FORCE_LOCAL";
00759   case BONDED_IA_AREA_FORCE_GLOBAL:
00760     return "AREA_FORCE_GLOBAL";
00761   case BONDED_IA_BENDING_FORCE:
00762     return "BENDING_FORCE";
00763   case BONDED_IA_VOLUME_FORCE:
00764     return "VOLUME_FORCE";
00765   default:
00766     fprintf(stderr, "%d: INTERNAL ERROR: name of unknown interaction %d requested\n",
00767             this_node, i);
00768     errexit();
00769   }
00770   /* just to keep the compiler happy */
00771   return "";
00772 }
00773 
00774 /** This function increases the LOCAL ia_params field for non-bonded interactions
00775     to the given size. This function is not exported
00776     since it does not do this on all nodes. Use
00777     make_particle_type_exist for that.
00778 */
00779 void realloc_ia_params(int nsize)
00780 {
00781   int i, j;
00782   IA_parameters *new_params;
00783   if (nsize <= n_particle_types)
00784     return;
00785 
00786   new_params = (IA_parameters *) malloc(nsize*nsize*sizeof(IA_parameters));
00787   if (ia_params) {
00788     /* if there is an old field, copy entries and delete */
00789     for (i = 0; i < nsize; i++)
00790       for (j = 0; j < nsize; j++) {
00791         if ((i < n_particle_types) && (j < n_particle_types))
00792           copy_ia_params(&new_params[i*nsize + j],
00793                          &ia_params[i*n_particle_types + j]);
00794         else
00795           initialize_ia_params(&new_params[i*nsize + j]);
00796       }
00797     free(ia_params);
00798   }
00799   else {
00800     /* new field, just init */
00801     for (i = 0; i < nsize; i++)
00802       for (j = 0; j < nsize; j++)
00803         initialize_ia_params(&new_params[i*nsize + j]);
00804   }
00805 
00806   n_particle_types = nsize;
00807   ia_params = new_params;
00808 }
00809 
00810 #ifdef ADRESS
00811 /* #ifdef THERMODYNAMIC_FORCE */
00812 void realloc_tf_params(int nsize)
00813 {
00814   int i;
00815   TF_parameters *new_params;
00816 
00817   if (nsize <= n_particle_types)
00818     return;
00819 
00820   new_params = (TF_parameters *) malloc(nsize*sizeof(TF_parameters));
00821   if (tf_params) {
00822     /* if there is an old field, copy entries and delete */
00823     for (i = 0; i < nsize; i++)
00824       {
00825         if (i < n_particle_types)
00826           copy_tf_params(&new_params[i],
00827                          &tf_params[i]);
00828         else
00829           initialize_tf_params(&new_params[i]);
00830       }
00831     free(tf_params);
00832   }
00833   else {
00834     /* new field, just init */
00835     for (i = 0; i < nsize; i++)
00836       initialize_tf_params(&new_params[i]);
00837   }
00838   
00839   tf_params = new_params;
00840 }
00841 /* #endif */
00842 #endif
00843 
00844 void make_particle_type_exist(int type)
00845 {
00846   int ns = type + 1;
00847   if (ns <= n_particle_types)
00848     return;
00849   mpi_bcast_n_particle_types(ns);
00850 }
00851 
00852 void make_bond_type_exist(int type)
00853 {
00854   int i, ns = type + 1;
00855   
00856   if(ns <= n_bonded_ia) {
00857 #ifdef TABULATED
00858     if ( bonded_ia_params[type].type == BONDED_IA_TABULATED && 
00859          bonded_ia_params[type].p.tab.npoints > 0 ) {
00860       free(bonded_ia_params[type].p.tab.f);
00861       free(bonded_ia_params[type].p.tab.e);
00862     }
00863 #endif 
00864 #ifdef OVERLAPPED
00865     if ( bonded_ia_params[type].type == BONDED_IA_OVERLAPPED &&
00866          bonded_ia_params[type].p.overlap.noverlaps > 0 ) {
00867       free(bonded_ia_params[type].p.overlap.para_a);
00868       free(bonded_ia_params[type].p.overlap.para_b);
00869       free(bonded_ia_params[type].p.overlap.para_c);
00870     }
00871 #endif
00872     return;
00873   }
00874   /* else allocate new memory */
00875   bonded_ia_params = (Bonded_ia_parameters *)realloc(bonded_ia_params,
00876                                                      ns*sizeof(Bonded_ia_parameters));
00877   /* set bond types not used as undefined */
00878   for (i = n_bonded_ia; i < ns; i++)
00879     bonded_ia_params[i].type = BONDED_IA_NONE;
00880  
00881   n_bonded_ia = ns;
00882 }
00883 
00884 int check_obs_calc_initialized()
00885 {
00886   /* set to zero if initialization was not successful. */
00887   int state = 1;
00888 
00889 #ifdef ELECTROSTATICS
00890   switch (coulomb.method) {
00891   case COULOMB_MMM1D: if (MMM1D_sanity_checks()) state = 0; break;
00892   case COULOMB_MMM2D: if (MMM2D_sanity_checks()) state = 0; break;
00893 #ifdef P3M
00894   case COULOMB_ELC_P3M: if (ELC_sanity_checks()) state = 0; // fall through
00895   case COULOMB_P3M: if (p3m_sanity_checks()) state = 0; break;
00896 #endif
00897   }
00898 #endif /* ifdef ELECTROSTATICS */
00899 
00900 #ifdef DIPOLES
00901   switch (coulomb.Dmethod) {
00902 #ifdef DP3M
00903   case DIPOLAR_MDLC_P3M: if (mdlc_sanity_checks()) state = 0; // fall through
00904   case DIPOLAR_P3M: if (dp3m_sanity_checks()) state = 0; break;
00905 #endif
00906   case DIPOLAR_MDLC_DS: if (mdlc_sanity_checks()) state = 0; // fall through
00907   case DIPOLAR_DS: if (magnetic_dipolar_direct_sum_sanity_checks()) state = 0; break;
00908   }
00909 #endif /* ifdef  DIPOLES */
00910 
00911   return state;
00912 }
00913 
00914 
00915 #ifdef ELECTROSTATICS
00916 
00917 /********************************************************************************/
00918 /*                                 electrostatics                               */
00919 /********************************************************************************/
00920 
00921 int coulomb_set_bjerrum(double bjerrum)
00922 {
00923   if (bjerrum < 0.0)
00924     return ES_ERROR;
00925   
00926   coulomb.bjerrum = bjerrum;
00927 
00928   if (coulomb.bjerrum == 0.0) {
00929     switch (coulomb.method) {
00930 #ifdef P3M
00931     case COULOMB_ELC_P3M:
00932     case COULOMB_P3M:
00933       p3m_set_bjerrum();
00934       break;
00935 #endif
00936     case COULOMB_DH:
00937       dh_params.r_cut   = 0.0;
00938       dh_params.kappa   = 0.0;
00939     case COULOMB_RF:
00940     case COULOMB_INTER_RF:
00941       rf_params.kappa  = 0.0;
00942       rf_params.epsilon1   = 0.0;
00943       rf_params.epsilon2   = 0.0;
00944       rf_params.r_cut   = 0.0;
00945       rf_params.B   = 0.0;
00946     case COULOMB_MMM1D:
00947       mmm1d_params.maxPWerror = 1e40;
00948       mmm1d_params.bessel_cutoff = 0;
00949     }
00950  
00951     mpi_bcast_coulomb_params();
00952     coulomb.method = COULOMB_NONE;
00953     mpi_bcast_coulomb_params();
00954 
00955   }
00956 
00957   return ES_OK;
00958 }
00959 
00960 
00961 
00962 /* =========================================================
00963    ========================================================= */
00964 #endif /*ifdef ELECTROSTATICS */
00965 
00966 #ifdef DIPOLES
00967 
00968 int dipolar_set_Dbjerrum(double bjerrum)
00969 {
00970   if (bjerrum < 0.0)
00971     return ES_ERROR;
00972   
00973   coulomb.Dbjerrum = bjerrum;
00974 
00975   if (coulomb.Dbjerrum == 0.0) {
00976     switch (coulomb.Dmethod) {
00977 #ifdef DP3M
00978     case DIPOLAR_MDLC_P3M:
00979       // fall through
00980     case DIPOLAR_P3M:
00981       coulomb.Dbjerrum = bjerrum;
00982       dp3m_set_bjerrum();
00983       break;
00984 #endif
00985     }
00986  
00987     mpi_bcast_coulomb_params();
00988     coulomb.Dmethod = DIPOLAR_NONE;
00989     mpi_bcast_coulomb_params();
00990 
00991   }
00992 
00993   return ES_OK;
00994 }
00995 
00996 #endif   /* ifdef  DIPOLES */
00997 
00998 void recalc_coulomb_prefactor()
00999 {
01000 #ifdef ELECTROSTATICS
01001   if(temperature > 0.0)
01002     coulomb.prefactor = coulomb.bjerrum * temperature; 
01003   else
01004     coulomb.prefactor = coulomb.bjerrum;
01005 #endif
01006 
01007 #ifdef DIPOLES
01008   if(temperature > 0.0)
01009     coulomb.Dprefactor = coulomb.Dbjerrum * temperature; 
01010   else
01011     coulomb.Dprefactor = coulomb.Dbjerrum;
01012 #endif
01013 }
01014 
01015 #ifdef BOND_VIRTUAL
01016 int virtual_set_params(int bond_type)
01017 {
01018   if(bond_type < 0)
01019     return ES_ERROR;
01020 
01021   make_bond_type_exist(bond_type);
01022 
01023   bonded_ia_params[bond_type].type = BONDED_IA_VIRTUAL_BOND;
01024   bonded_ia_params[bond_type].num  = 1;
01025 
01026   /* broadcast interaction parameters */
01027   mpi_bcast_ia_params(bond_type, -1); 
01028 
01029   return ES_OK;
01030 }
01031 
01032 #endif