ESPResSo 3.2.0-167-g2c9ead1-git
Extensible Simulation Package for Soft Matter Research
particle_data.h
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 #ifndef _PARTICLE_DATA_H
00022 #define _PARTICLE_DATA_H
00023 /** \file particle_data.h
00024     For more information on particle_data,
00025     see \ref particle_data.c "particle_data.c"
00026 */
00027 
00028 
00029 #include "utils.h"
00030 #include "global.h"
00031 
00032 /************************************************
00033  * defines
00034  ************************************************/
00035 
00036 /// ok code for \ref place_particle
00037 #define ES_PART_OK 0
00038 /// error code for \ref place_particle
00039 #define ES_PART_ERROR -1
00040 /// ok code for \ref place_particle, particle is new
00041 #define ES_PART_CREATED 1
00042 
00043 /**  bonds_flag "bonds_flag" value for updating particle config without bonding information */
00044 #define WITHOUT_BONDS 0
00045 /**  bonds_flag "bonds_flag" value for updating particle config with bonding information */
00046 #define WITH_BONDS 1
00047 
00048 #ifdef EXTERNAL_FORCES
00049 /** \ref ParticleLocal::ext_flag "ext_flag" value for particle subject to an external force. */
00050 #define PARTICLE_EXT_FORCE 1
00051 /** \ref ParticleLocal::ext_flag "ext_flag" value for fixed coordinate coord. */
00052 #define COORD_FIXED(coord) (2L << coord)
00053 /** \ref ParticleLocal::ext_flag "ext_flag" mask to check wether any of the coordinates is fixed. */
00054 #define COORDS_FIX_MASK     (COORD_FIXED(0) | COORD_FIXED(1) | COORD_FIXED(2))
00055 
00056 #ifdef ROTATION
00057 /** \ref ParticleLocal::ext_flag "ext_flag" value for particle subject to an external torque. */
00058 #define PARTICLE_EXT_TORQUE 16
00059 #endif
00060 
00061 #endif
00062 
00063 
00064 /************************************************
00065  * data types
00066  ************************************************/
00067 
00068 /** Properties of a particle which are not supposed to
00069     change during the integration, but have to be known
00070     for all ghosts. Ghosts are particles which are
00071     needed in the interaction calculation, but are just copies of
00072     particles stored on different nodes.
00073 */
00074 typedef struct {
00075   /** unique identifier for the particle. */
00076   int    identity;
00077   /** Molecule identifier. */
00078   int    mol_id;
00079   /** particle type, used for non bonded interactions. */
00080   int    type;
00081 
00082 #ifdef MASS
00083   /** particle mass */
00084   double mass;
00085 #endif
00086 
00087 #ifdef SHANCHEN
00088   double solvation[2*LB_COMPONENTS];
00089 #endif
00090 
00091 #ifdef ROTATIONAL_INERTIA
00092   /** rotational inertia */
00093   double rinertia[3];
00094 #endif
00095 
00096 #ifdef ROTATION_PER_PARTICLE
00097   // Determines, wether a particle's rotational degrees of freedom are
00098   // integrated
00099   int rotation;
00100 #endif
00101 
00102 #ifdef ELECTROSTATICS
00103   /** charge. */
00104   double q;
00105 #endif
00106 
00107 #ifdef LB_ELECTROHYDRODYNAMICS
00108   /** electrophoretic mobility times E-field: mu_0 * E */
00109   double mu_E[3];
00110 #endif
00111 
00112 #ifdef DIPOLES
00113   /** dipole moment (absolute value)*/
00114   double dipm;
00115 #endif
00116 
00117 #ifdef VIRTUAL_SITES
00118   /** is particle virual
00119       0 = real particle
00120       else = virual particle */
00121   int isVirtual;
00122   #ifdef VIRTUAL_SITES_RELATIVE
00123   /** In case, the "relative" implementation of virtual sites is enabled, the 
00124   following properties define, with respect to which real particle a virtual
00125   site is placed and in what distance. The relative orientation of the vector
00126   pointing from real particle to virtual site with respect to the orientation
00127   of the real particle is stored in the virtual site's quaternion attribute.
00128   */
00129   int vs_relative_to_particle_id;
00130   double vs_relative_distance;
00131   #endif
00132 #endif
00133 
00134 #ifdef ADRESS
00135   /** particles adress weight */
00136   double adress_weight;
00137 #endif
00138 
00139 #ifdef LANGEVIN_PER_PARTICLE
00140   double T;
00141   double gamma;
00142 #endif
00143 
00144 #ifdef CATALYTIC_REACTIONS
00145   int catalyzer_count;
00146 #endif
00147 } ParticleProperties;
00148 
00149 /** Positional information on a particle. Information that is
00150     communicated to calculate interactions with ghost particles. */
00151 typedef struct {
00152   /** periodically folded position. */
00153   double p[3];
00154 
00155 #ifdef ROTATION
00156   /** quaternions to define particle orientation */
00157   double quat[4];
00158   /** unit director calculated from the quaternions */
00159   double quatu[3];
00160 #endif
00161 
00162 #ifdef DIPOLES
00163   /** dipol moment. This is synchronized with quatu and quat. */
00164   double dip[3];
00165 #endif
00166 
00167 #ifdef BOND_CONSTRAINT
00168   /**stores the particle position at the previous time step*/
00169   double p_old[3];
00170 #endif
00171 
00172 } ParticlePosition;
00173 
00174 /** Force information on a particle. Forces of ghost particles are
00175     collected and added up to the force of the original particle. */
00176 typedef struct {
00177   /** force. */
00178   double f[3];
00179 
00180 #ifdef ROTATION
00181   /** torque */
00182   double torque[3];
00183 #endif
00184 
00185 } ParticleForce;
00186 
00187 /** Momentum information on a particle. Information not contained in
00188     communication of ghost particles so far, but a communication would
00189     be necessary for velocity dependend potentials. */
00190 typedef struct {
00191   /** velocity. */
00192   double v[3];
00193 
00194 #ifdef ROTATION
00195   /** angular velocity  
00196       ALWAYS IN PARTICLE FIXEXD, I.E., CO-ROTATING COORDINATE SYSTEM */
00197   double omega[3];
00198 #endif
00199 } ParticleMomentum;
00200 
00201 /** Information on a particle that is needed only on the
00202     node the particle belongs to */
00203 typedef struct {
00204   /** position in the last time step befor last Verlet list update. */
00205   double p_old[3];
00206   /** index of the simulation box image where the particle really sits. */
00207   int    i[3];
00208 
00209 #ifdef EXTERNAL_FORCES
00210   /** flag whether to fix a particle in space.
00211       Values:
00212       <ul> <li> 0 no external influence
00213            <li> 1 apply external force \ref ParticleLocal::ext_force
00214            <li> 2,3,4 fix particle coordinate 0,1,2
00215            <li> 5 apply external torque \ref ParticleLocal::ext_torque
00216       </ul>
00217   */
00218   int ext_flag;
00219   /** External force, apply if \ref ParticleLocal::ext_flag == 1. */
00220   double ext_force[3];
00221 
00222   #ifdef ROTATION
00223   /** External torque, apply if \ref ParticleLocal::ext_flag == 16. */
00224   double ext_torque[3];
00225   #endif
00226 
00227 #endif
00228 
00229 #ifdef GHOST_FLAG
00230   /** check whether a particle is a ghost or not */
00231   int ghost;
00232 #endif
00233 
00234 #ifdef GHMC
00235   /** Data for the ghmc thermostat, last saved 
00236       position and monentum of particle */
00237   ParticlePosition r_ls;
00238   ParticleMomentum m_ls;
00239 #endif
00240 } ParticleLocal;
00241 
00242 #ifdef LB
00243 /** Data related to the Lattice Boltzmann hydrodynamic coupling */
00244 typedef struct {
00245   /** fluctuating part of the coupling force */
00246   double f_random[3];
00247 } ParticleLatticeCoupling;
00248 #endif
00249 
00250 /** Struct holding all information for one particle. */
00251 typedef struct {
00252   ///
00253   ParticleProperties p;
00254   ///
00255   ParticlePosition r;
00256   ///
00257   ParticleMomentum m;
00258   ///
00259   ParticleForce f;
00260   ///
00261   ParticleLocal l;
00262   ///
00263 #ifdef LB
00264   ParticleLatticeCoupling lc;
00265 #endif
00266   /** bonded interactions list. The format is pretty simple:
00267       Just the bond type, and then the particle ids. The number of particle ids can be determined
00268       easily from the bonded_ia_params entry for the type. */
00269   IntList bl;
00270 
00271 #ifdef EXCLUSIONS
00272   /** list of particles, with which this particle has no nonbonded interactions */
00273   IntList el;
00274 #endif
00275 
00276 } Particle;
00277 
00278 /** List of particles. The particle array is resized using a sophisticated
00279     (we hope) algorithm to avoid unnecessary resizes.
00280     Access using \ref realloc_particlelist, \ref got_particle,...
00281 */
00282 typedef struct {
00283   /** The particles payload */
00284   Particle *part;
00285   /** Number of particles contained */
00286   int n;
00287   /** Number of particles that fit in until a resize is needed */
00288   int max;
00289 } ParticleList;
00290 
00291 /************************************************
00292  * exported variables
00293  ************************************************/
00294 
00295 /** Highest particle number seen so far. If you leave out some
00296     particle numbers, this number might be higher than the
00297     true number of particles. On the other hand, if you start
00298     your particle numbers at 0, the total number of particles
00299     is larger by 1.
00300 */
00301 extern int max_seen_particle;
00302 /** total number of particles on all nodes. */
00303 extern int  n_total_particles;
00304 
00305 /** Capacity of the \ref particle_node / \ref local_particles. */
00306 extern int  max_particle_node;
00307 /** Used only on master node: particle->node mapping. */
00308 extern int  *particle_node;
00309 /** id->particle mapping on all nodes. This is used to find partners
00310     of bonded interactions. */
00311 extern Particle   **local_particles;
00312 
00313 /** Particles' current configuration. Before using that
00314     call \ref updatePartCfg or \ref sortPartCfg to allocate
00315     the data if necessary (which is decided by \ref updatePartCfg). */
00316 extern Particle *partCfg;
00317 
00318 /** if non zero, \ref partCfg is sorted by particle order, and
00319     the particles are stored consecutively starting with 0. */
00320 extern int partCfgSorted;
00321 
00322 /** Particles' current bond partners. \ref partBondPartners is
00323     sorted by particle order, and the particles are stored
00324     consecutively starting with 0. This array is global to all nodes*/
00325 extern int *partBondPartners;
00326 
00327 
00328 /************************************************
00329  * Functions
00330  ************************************************/
00331 
00332 
00333 /*       Functions acting on Particles          */
00334 /************************************************/
00335 
00336 /** Initialize a particle.
00337     This function just sets all values to the defaults (mostly zeros)!
00338     Do NOT use this without setting the values of the
00339     \ref ParticleProperties::identity "identity" and \ref ParticlePosition::p "position" to
00340     reasonable values. Also make sure that you update \ref local_particles.
00341 
00342     Add here all initializations you need to be done !!!
00343     If dynamic memory allocation is involved, also look at \ref free_particle.
00344 */
00345 void init_particle(Particle *part);
00346 
00347 /** Deallocate the dynamic storage of a particle. */
00348 void free_particle(Particle *part);
00349 
00350 /*    Functions acting on Particle Lists        */
00351 /************************************************/
00352 
00353 /** Initialize a particle list.
00354  *  Use with care and ONLY for initialization! */
00355 void init_particlelist(ParticleList *pList);
00356 
00357 /** Allocate storage for local particles and ghosts. This version
00358     does \em not care for the bond information to be freed if necessary.
00359     \param plist the list on which to operate
00360     \param size the size to provide at least. It is rounded
00361     up to multiples of \ref PART_INCREMENT.
00362     \return true iff particle adresses have changed */
00363 int realloc_particlelist(ParticleList *plist, int size);
00364 
00365 /** Search for a specific particle.
00366     \param plist the list on which to operate
00367     \param id the identity of the particle to search
00368     \return a pointer to the particle structure or NULL if particle is
00369     not in this list */
00370 Particle *got_particle(ParticleList *plist, int id);
00371 
00372 /** Append a particle at the end of a particle List.
00373     reallocates particles if necessary!
00374     This procedure does not care for \ref local_particles.
00375     \param plist List to append the particle to.
00376     \param part  Particle to append.
00377     \return Pointer to new location of the particle. */
00378 Particle *append_unindexed_particle(ParticleList *plist, Particle *part);
00379 
00380 /** Append a particle at the end of a particle List.
00381     reallocates particles if necessary!
00382     This procedure cares for \ref local_particles.
00383     \param plist List to append the particle to.
00384     \param part  Particle to append.
00385     \return Pointer to new location of the particle. */
00386 Particle *append_indexed_particle(ParticleList *plist, Particle *part);
00387 
00388 /** Remove a particle from one particle List and append it to another.
00389     Refill the sourceList with last particle and update its entry in
00390     local_particles. reallocates particles if necessary.  This
00391     procedure does not care for \ref local_particles.
00392     NOT IN USE AT THE MOMENT.
00393     \param destList   List where the particle is appended.
00394     \param sourceList List where the particle will be removed.
00395     \param ind        Index of the particle in the sourceList.
00396     \return Pointer to new location of the particle.
00397  */
00398 Particle *move_unindexed_particle(ParticleList *destList, ParticleList *sourceList, int ind);
00399 
00400 /** Remove a particle from one particle List and append it to another.
00401     Refill the sourceList with last particle and update its entry in
00402     local_particles. Reallocates particles if necessary.  This
00403     procedure cares for \ref local_particles.
00404     \param destList   List where the particle is appended.
00405     \param sourceList List where the particle will be removed.
00406     \param ind        Index of the particle in the sourceList.
00407     \return Pointer to new location of the particle.
00408  */
00409 Particle *move_indexed_particle(ParticleList *destList, ParticleList *sourceList, int ind);
00410 
00411 /*    Other Functions                           */
00412 /************************************************/
00413 
00414 /** Update the entries in \ref local_particles for all particles in the list pl.
00415     @param pl the list to put in.
00416 */
00417 void update_local_particles(ParticleList *pl);
00418 
00419 /** Rebuild \ref particle_node from scratch.
00420     After a simulation step \ref particle_node has to be rebuild
00421     since the particles might have gone to a different node.
00422 */
00423 void build_particle_node();
00424 
00425 /** Invalidate \ref particle_node. This has to be done
00426     at the beginning of the integration.
00427 */
00428 void particle_invalidate_part_node();
00429 
00430 /** Realloc \ref local_particles. */
00431 void realloc_local_particles();
00432 
00433 /** Get particle data. Note that the bond intlist is
00434     allocated so that you are responsible to free it later.
00435     @param part the identity of the particle to fetch
00436     @param data where to store its contents.
00437     @return ES_OK if particle existed
00438 */
00439 int get_particle_data(int part, Particle *data);
00440 
00441 /** Call only on the master node.
00442     Move a particle to a new position.
00443     If it does not exist, it is created.
00444     @param part the identity of the particle to move
00445     @param p    its new position
00446     @return ES_PART_OK if particle existed, ES_PART_CREATED
00447     if created and ES_PART_ERROR if id is illegal
00448 */
00449 int place_particle(int part, double p[3]);
00450 
00451 /** Call only on the master node: set particle velocity.
00452     @param part the particle.
00453     @param v its new velocity.
00454     @return ES_OK if particle existed
00455 */
00456 int set_particle_v(int part, double v[3]);
00457 
00458 /** Call only on the master node: set particle force.
00459     @param part the particle.
00460     @param F its new force.
00461     @return ES_OK if particle existed
00462 */
00463 int set_particle_f(int part, double F[3]);
00464 
00465 /** Call only on the master node: set particle mass.
00466     @param part the particle.
00467     @param mass its new mass.
00468     @return ES_OK if particle existed
00469 */
00470 int set_particle_mass(int part, double mass);
00471 
00472 /** Call only on the master node: set particle solvation free energy.
00473     @param part the particle.
00474     @param solvation its new solvation free energy.
00475     @return ES_OK if particle existed
00476 */
00477 int set_particle_solvation(int part, double* solvation);
00478 
00479 
00480 #ifdef ROTATIONAL_INERTIA
00481 /** Call only on the master node: set particle rotational inertia.
00482     @param part the particle.
00483     @param rinertia its new inertia.
00484     @return ES_OK if particle existed
00485 */
00486 int set_particle_rotational_inertia(int part, double rinertia[3]);
00487 #endif
00488 
00489 #ifdef ROTATION_PER_PARTICLE
00490 /** Call only on the master node: Specifies whether a particle's rotational
00491     degrees of freedom are integrated or not. If set to zero, the content of
00492     the torque and omega variables are meaningless
00493     @param part the particle.
00494     @param rot the degrees of freedom flag.
00495     @return ES_OK if particle existed
00496 */
00497 int set_particle_rotation(int part, int rot);
00498 #endif
00499 
00500 
00501 /** Call only on the master node: set particle charge.
00502     @param part the particle.
00503     @param q its new charge.
00504     @return ES_OK if particle existed
00505 */
00506 int set_particle_q(int part, double q);
00507 
00508 /** Call only on the master node: set particle electrophoretic mobility.
00509     @param part the particle.
00510     @param mu_E its new mobility.
00511     @return ES_OK if particle existed
00512 */
00513 int set_particle_mu_E(int part, double mu_E[3]);
00514 
00515 /** Call only on the master node: set particle type.
00516     @param part the particle.
00517     @param type its new type.
00518     @return ES_OK if particle existed
00519 */
00520 int set_particle_type(int part, int type);
00521 
00522 /** Call only on the master node: set particle's molecule id.
00523     @param part the particle.
00524     @param mid  its new mol id.
00525     @return ES_OK if particle existed
00526 */
00527 int set_particle_mol_id(int part, int mid);
00528 
00529 #ifdef ROTATION
00530 /** Call only on the master node: set particle orientation using quaternions.
00531     @param part the particle.
00532     @param quat its new value for quaternions.
00533     @return ES_OK if particle existed
00534 */
00535 int set_particle_quat(int part, double quat[4]);
00536 
00537 /** Call only on the master node: set particle angular velocity from lab frame.
00538     @param part the particle.
00539     @param omega its new angular velocity.
00540     @return ES_OK if particle existed
00541 */
00542 int set_particle_omega_lab(int part, double omega[3]);
00543 
00544 /** Call only on the master node: set particle angular velocity in body frame.
00545     @param part the particle.
00546     @param omega its new angular velocity.
00547     @return ES_OK if particle existed
00548 */
00549 int set_particle_omega_body(int part, double omega[3]);
00550 
00551 /** Call only on the master node: set particle torque from lab frame.
00552     @param part the particle.
00553     @param torque its new torque.
00554     @return ES_OK if particle existed
00555 */
00556 int set_particle_torque_lab(int part, double torque[3]);
00557 
00558 /** Call only on the master node: set particle torque in body frame.
00559     @param part the particle.
00560     @param torque its new torque.
00561     @return ES_OK if particle existed
00562 */
00563 int set_particle_torque_body(int part, double torque[3]);
00564 #endif
00565 
00566 #ifdef DIPOLES
00567 /** Call only on the master node: set particle dipole orientation.
00568     @param part the particle.
00569     @param dip its new dipole orientation.
00570     @return ES_OK if particle existed
00571 */
00572 int set_particle_dip(int part, double dip[3]);
00573 
00574 /** Call only on the master node: set particle dipole moment (absolut value).
00575     @param part the particle.
00576     @param dipm its new dipole moment.
00577     @return ES_OK if particle existed
00578 */
00579 int set_particle_dipm(int part, double dipm);
00580 #endif
00581 
00582 #ifdef VIRTUAL_SITES
00583 /** Call only on the master node: set particle dipole moment (absolut value).
00584     @param part the particle.
00585     @param isVirtual its new dipole moment.
00586     @return ES_OK if particle existed
00587 */
00588 int set_particle_virtual(int part,int isVirtual);
00589 #endif
00590 
00591 #ifdef LANGEVIN_PER_PARTICLE
00592 /** Call only on the master node: set particle temperature.
00593     @param part the particle.
00594     @param T its new temperature.
00595     @return ES_OK if particle existed
00596 */
00597 int set_particle_temperature(int part, double T);
00598 
00599 /** Call only on the master node: set particle frictional coefficient.
00600     @param part the particle.
00601     @param gamma its new frictional coefficient.
00602     @return ES_OK if particle existed
00603 */
00604 int set_particle_gamma(int part, double gamma);
00605 #endif
00606 
00607 #ifdef EXTERNAL_FORCES
00608   #ifdef ROTATION
00609     /** Call only on the master node: set particle external torque.
00610         @param part  the particle.
00611         @param flag  new value for ext_flag.
00612         @param torque new value for ext_torque.
00613         @return ES_OK if particle existed
00614     */
00615     int set_particle_ext_torque(int part, int flag, double torque[3]);
00616   #endif
00617 /** Call only on the master node: set particle external force.
00618     @param part  the particle.
00619     @param flag  new value for ext_flag.
00620     @param force new value for ext_force.
00621     @return ES_OK if particle existed
00622 */
00623 int set_particle_ext_force(int part, int flag, double force[3]);
00624 /** Call only on the master node: set coordinate axes for which the particles motion is fixed.
00625     @param part  the particle.
00626     @param flag new value for flagged coordinate axes to be fixed
00627     @return ES_OK if particle existed
00628 */
00629 int set_particle_fix(int part,  int flag);
00630 #endif
00631 
00632 /** Call only on the master node: change particle bond.
00633     @param part     identity of principal atom of the bond.
00634     @param bond     field containing the bond type number and the
00635     identity of all bond partners (secundary atoms of the bond). If NULL, delete all bonds.
00636     @param _delete   if true, do not add the bond, rather delete it if found
00637     @return ES_OK on success or ES_ERROR if no success
00638     (e. g. particle or bond to delete does not exist)
00639 */
00640 int change_particle_bond(int part, int *bond, int _delete);
00641 
00642 #ifdef EXCLUSIONS
00643 /** Call only on the master node: change particle constraints.
00644     @param part     identity of particle for which the exclusion is set.
00645     @param part2    identity of particle for which the exclusion is set. If -1, delete all exclusions.
00646     @param _delete   if true, do not add the exclusion, rather delete it if found
00647     @return ES_OK on success or ES_ERROR if no success
00648     (e. g. particles do not exist / did not have exclusion set)
00649 */
00650 int change_exclusion(int part, int part2, int _delete);
00651 
00652 /** remove all exclusions. */
00653 void remove_all_exclusions();
00654 #endif
00655 
00656 /** remove particle with a given identity. Also removes all bonds to the particle.
00657     @param part     identity of the particle to remove
00658     @return ES_OK on success or ES_ERROR if particle does not exist
00659 */
00660 int remove_particle(int part);
00661 
00662 /** remove all particles.
00663  */
00664 void remove_all_particles();
00665 
00666 /** for all local particles, remove bonds incorporating the specified
00667     particle.
00668     @param part     identity of the particle to free from bonds
00669 */
00670 void remove_all_bonds_to(int part);
00671 
00672 /** Get the complete unsorted informations on all particles into \ref
00673     partCfg if something's changed. This is a severe performance
00674     drawback and might even fail for lack of memory for large systems.
00675     If you need the particle info sorted, call \ref sortPartCfg
00676     instead.  This function is lazy. If you would like the bonding
00677     information in \ref partCfg to be valid you should set the value
00678     of  to \ref WITH_BONDS.
00679 */
00680 void updatePartCfg(int bonds_flag );
00681 
00682 /** release the partCfg array. Use this function, since it also frees the
00683     bonds, if they are used.
00684 */
00685 void freePartCfg();
00686 
00687 /** sorts the \ref partCfg array. This is indicated by setting
00688     \ref partCfgSorted to 1. Note that for this to work the particles
00689     have to be stored consecutively starting with 0.
00690     This function is lazy.
00691     @return 1 iff sorting was possible, i. e. the particles were stored
00692     consecutively.
00693 */
00694 int sortPartCfg();
00695 
00696 /** Used by \ref mpi_place_particle, should not be used elsewhere.
00697     Move a particle to a new position.
00698     If it does not exist, it is created. the position must
00699     be on the local node!
00700     @param part the identity of the particle to move
00701     @param p    its new position
00702     @param _new  if true, the particle is allocated, else has to exists already
00703 */
00704 void local_place_particle(int part, double p[3], int _new);
00705 
00706 /** Used by \ref mpi_place_particle, should not be used elsewhere.
00707     Called if on a different node a new particle was added.
00708     @param part the identity of the particle added
00709 */
00710 void added_particle(int part);
00711 
00712 /** Used by \ref mpi_send_bond, should not be used elsewhere.
00713     Modify a bond.
00714     @param part the identity of the particle to change
00715     @param bond the bond to do
00716     @param _delete if true, delete the bond instead of add
00717     @return ES_OK for add or successful delete, ES_ERROR else
00718 */
00719 int local_change_bond(int part, int *bond, int _delete);
00720 
00721 /** Used for example by \ref mpi_send_exclusion.
00722     Locally add a exclusion to a particle.
00723     @param part1 the identity of the first exclusion partner
00724     @param part2 the identity of the second exclusion partner
00725     @param _delete if true, delete the exclusion instead of add
00726 */
00727 void local_change_exclusion(int part1, int part2, int _delete);
00728 
00729 /** Used by \ref mpi_remove_particle, should not be used elsewhere.
00730     Remove a particle on this node.
00731     @param part the identity of the particle to remove
00732 */
00733 void local_remove_particle(int part);
00734 
00735 /** Used by \ref mpi_remove_particle, should not be used elsewhere.
00736     Locally remove all particles.
00737  */
00738 void local_remove_all_particles();
00739 
00740 /** Used by \ref mpi_rescale_particles, should not be used elsewhere.
00741     Locally rescale all particles on current node.
00742     @param dir   direction to scale (0/1/2 = x/y/z, 3 = x+y+z isotropically)
00743     @param scale factor by which to rescale (>1: stretch, <1: contract)
00744 */
00745 void local_rescale_particles(int dir, double scale);
00746 
00747 /** Synchronous send of a particle buffer to another node. The other node
00748     MUST call \ref recv_particles when this is called. The particles data
00749     is freed. */
00750 void send_particles(ParticleList *particles, int node);
00751 
00752 /** Synchronous receive of a particle buffer from another node. The other node
00753     MUST call \ref send_particles when this is called. The particles are
00754     APPENDED to the list, so it has to be a valid one */
00755 void recv_particles(ParticleList *particles, int node);
00756 
00757 #ifdef EXCLUSIONS
00758 /** Determines if the non bonded interactions between p1 and p2 should be calculated */
00759 MDINLINE int do_nonbonded(Particle *p1, Particle *p2)
00760 {
00761   int i, i2;
00762   /* check for particle 2 in particle 1's exclusion list. The exclusion list is
00763      symmetric, so this is sufficient. */
00764   i2  = p2->p.identity;
00765   for (i = 0; i < p1->el.n; i++)
00766     if (i2 == p1->el.e[i]) return 0;
00767   return 1;
00768 }
00769 #endif
00770 
00771 /** Remove bond from particle if possible */
00772 int try_delete_bond(Particle *part, int *bond);
00773 
00774 /** Remove exclusion from particle if possible */
00775 void try_delete_exclusion(Particle *part, int part2);
00776 
00777 /** Insert an exclusion if not already set */
00778 void try_add_exclusion(Particle *part, int part2);
00779 
00780 /** Automatically add the next <distance> neighbors in each molecule to the exclusion list.
00781  This uses the bond topology obtained directly from the particles, since only this contains
00782  the full topology, in contrast to \ref topology::topology. To easily setup the bonds, all data
00783  should be on a single node, therefore the \ref partCfg array is used. With large amounts
00784  of particles, you should avoid this function and setup exclusions manually. */
00785 void auto_exclusion(int distance);
00786 
00787 /* keep a unique list for particle i. Particle j is only added if it is not i
00788  and not already in the list. */
00789 void add_partner(IntList *il, int i, int j, int distance);
00790 
00791 #ifdef GRANDCANONICAL
00792 //value that is returned in the case there was no error, but the type was not yet indexed
00793 #define NOT_INDEXED -3
00794 //struct that associates the index used for the type_list and the real particle type
00795 typedef struct {
00796         int max_entry;
00797         int * type;
00798 } IndexOfType;
00799 
00800 //and the other way round
00801 typedef struct {
00802         int max_entry;
00803         int * index;
00804 } TypeOfIndex;
00805 
00806 TypeOfIndex Type; 
00807 //index.max_entry=0;
00808 //index->type = (int *) 0;
00809 
00810 IndexOfType Index; 
00811 //tindex.max_entry=0;
00812 //tindex->type = (int *) 0;
00813 
00814 
00815 typedef struct {
00816         int max_entry;
00817         int cur_size;
00818         int *id_list;
00819 } TypeList;
00820 
00821 //undefined array size
00822 TypeList *type_array;
00823 int number_of_type_lists;
00824 
00825 // flag indicating init_gc was called 
00826 int GC_init;
00827 
00828 // flag that indicates that the function init_type_array was called already
00829 int Type_array_init;
00830 
00831 /** linked list for particles of a given type */
00832 //typedef struct {
00833 //      int identifier;
00834 //      struct type_list_item *next;
00835 //} type_list item;
00836 //
00837 //typedef struct {
00838 //      struct type_list_item *list;
00839 //      int type;
00840 //      int max;
00841 //} type_list
00842 
00843 /** vars and fields */
00844 
00845 int init_gc(void);
00846 
00847 /** init particle lists         */
00848 int init_type_array(int type);
00849 
00850 /** resize the array for the list of ids for a certain type */
00851 int reallocate_type_array(int type);
00852 
00853 /** make more type_arrays available */
00854 int reallocate_global_type_list(int size);
00855 
00856 /** free particle lists         */
00857 int free_particle_lists(void);
00858 
00859 //update particle list
00860 int update_particle_array(int type);
00861 
00862 /* find a particle of given type and return its id */
00863 int find_particle_type(int type, int *id);
00864 /** return an array with real particle id and the corresponding index of typelist */
00865 //static int *find_particle_type(int type);
00866 
00867 int find_particle_type_id(int type, int *id, int *in_id );
00868 
00869 /** delete one randomly chosen particle of given type 
00870  * returns ES_OK if succesful or else ES_ERROR          */
00871 int delete_particle_of_type(int type);
00872 
00873 int remove_id_type_array(int part_id, int type);
00874 int add_particle_to_list(int part_id, int type);
00875 // print out a list of currently indexed ids
00876 int gc_status(int type);
00877 int number_of_particles_with_type(int type, int *number);
00878 #endif
00879 
00880 #endif