Simpler required selection input from a file.
[gromacs.git] / src / gromacs / gmxpreprocess / gpp_atomtype.c
blob8478b0d550211296328bc6912fdc2ce5e9b2bf9d
1 /*
2 *
3 * This source code is part of
4 *
5 * G R O M A C S
6 *
7 * GROningen MAchine for Chemical Simulations
8 *
9 * VERSION 3.2.0
10 * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
11 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
12 * Copyright (c) 2001-2004, The GROMACS development team,
13 * check out http://www.gromacs.org for more information.
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
20 * If you want to redistribute modifications, please consider that
21 * scientific software is very special. Version control is crucial -
22 * bugs must be traceable. We will be happy to consider code for
23 * inclusion in the official distribution, but derived work must not
24 * be called official GROMACS. Details are found in the README & COPYING
25 * files - if they are missing, get the official version at www.gromacs.org.
27 * To help us fund GROMACS development, we humbly ask that you cite
28 * the papers on the package - you can find them in the top README file.
30 * For more info, check our website at http://www.gromacs.org
32 * And Hey:
33 * Gallium Rubidium Oxygen Manganese Argon Carbon Silicon
35 #ifdef HAVE_CONFIG_H
36 #include <config.h>
37 #endif
39 #include <math.h>
40 #include "smalloc.h"
41 #include "sysstuff.h"
42 #include "macros.h"
43 #include "string2.h"
44 #include "topdirs.h"
45 #include "toputil.h"
46 #include "topdirs.h"
47 #include "toputil.h"
48 #include "symtab.h"
49 #include "gmx_fatal.h"
50 #include "txtdump.h"
51 #include "gpp_atomtype.h"
53 typedef struct gpp_atomtype {
54 int nr; /* The number of atomtypes */
55 t_atom *atom; /* Array of atoms */
56 char ***atomname; /* Names of the atomtypes */
57 t_param *nb; /* Nonbonded force default params */
58 int *bondatomtype; /* The bond_atomtype for each atomtype */
59 real *radius; /* Radius for GBSA stuff */
60 real *vol; /* Effective volume for GBSA */
61 real *surftens; /* Surface tension with water, for GBSA */
62 real *gb_radius; /* Radius for Still model */
63 real *S_hct; /* Overlap factor for HCT model */
64 int *atomnumber; /* Atomic number, used for QM/MM */
65 } t_gpp_atomtype;
67 int get_atomtype_type(const char *str,gpp_atomtype_t ga)
69 int i;
71 /* Atom types are always case sensitive */
72 for (i=0; (i<ga->nr); i++)
73 if (strcmp(str,*(ga->atomname[i])) == 0)
74 return i;
76 return NOTSET;
79 int get_atomtype_ntypes(gpp_atomtype_t ga)
81 return ga->nr;
84 char *get_atomtype_name(int nt, gpp_atomtype_t ga)
86 if ((nt < 0) || (nt >= ga->nr))
87 return NULL;
89 return *(ga->atomname[nt]);
92 real get_atomtype_massA(int nt,gpp_atomtype_t ga)
94 if ((nt < 0) || (nt >= ga->nr))
95 return NOTSET;
97 return ga->atom[nt].m;
100 real get_atomtype_massB(int nt,gpp_atomtype_t ga)
102 if ((nt < 0) || (nt >= ga->nr))
103 return NOTSET;
105 return ga->atom[nt].mB;
108 real get_atomtype_qA(int nt,gpp_atomtype_t ga)
110 if ((nt < 0) || (nt >= ga->nr))
111 return NOTSET;
113 return ga->atom[nt].q;
116 real get_atomtype_qB(int nt,gpp_atomtype_t ga)
118 if ((nt < 0) || (nt >= ga->nr))
119 return NOTSET;
121 return ga->atom[nt].qB;
124 int get_atomtype_ptype(int nt,gpp_atomtype_t ga)
126 if ((nt < 0) || (nt >= ga->nr))
127 return NOTSET;
129 return ga->atom[nt].ptype;
132 int get_atomtype_batype(int nt,gpp_atomtype_t ga)
134 if ((nt < 0) || (nt >= ga->nr))
135 return NOTSET;
137 return ga->bondatomtype[nt];
140 int get_atomtype_atomnumber(int nt,gpp_atomtype_t ga)
142 if ((nt < 0) || (nt >= ga->nr))
143 return NOTSET;
145 return ga->atomnumber[nt];
148 real get_atomtype_radius(int nt,gpp_atomtype_t ga)
150 if ((nt < 0) || (nt >= ga->nr))
151 return NOTSET;
153 return ga->radius[nt];
156 real get_atomtype_vol(int nt,gpp_atomtype_t ga)
158 if ((nt < 0) || (nt >= ga->nr))
159 return NOTSET;
161 return ga->vol[nt];
164 real get_atomtype_surftens(int nt,gpp_atomtype_t ga)
166 if ((nt < 0) || (nt >= ga->nr))
167 return NOTSET;
169 return ga->surftens[nt];
172 real get_atomtype_gb_radius(int nt,gpp_atomtype_t ga)
174 if ((nt < 0) || (nt >= ga->nr))
175 return NOTSET;
177 return ga->gb_radius[nt];
180 real get_atomtype_S_hct(int nt,gpp_atomtype_t ga)
182 if ((nt < 0) || (nt >= ga->nr))
183 return NOTSET;
185 return ga->S_hct[nt];
188 real get_atomtype_nbparam(int nt,int param,gpp_atomtype_t ga)
190 if ((nt < 0) || (nt >= ga->nr))
191 return NOTSET;
192 if ((param < 0) || (param >= MAXFORCEPARAM))
193 return NOTSET;
194 return ga->nb[nt].c[param];
197 gpp_atomtype_t init_atomtype(void)
199 gpp_atomtype_t ga;
201 snew(ga,1);
203 ga->nr = 0;
204 ga->atom = NULL;
205 ga->atomname = NULL;
206 ga->nb = NULL;
207 ga->bondatomtype = NULL;
208 ga->radius = NULL;
209 ga->vol = NULL;
210 ga->surftens = NULL;
211 ga->atomnumber = NULL;
212 ga->gb_radius = NULL;
213 ga->S_hct = NULL;
215 return ga;
219 set_atomtype_gbparam(gpp_atomtype_t ga, int i,
220 real radius,real vol,real surftens,
221 real gb_radius, real S_hct)
223 if ( (i < 0) || (i>= ga->nr))
224 return NOTSET;
226 ga->radius[i] = radius;
227 ga->vol[i] = vol;
228 ga->surftens[i] = surftens;
229 ga->gb_radius[i] = gb_radius;
230 ga->S_hct[i] = S_hct;
232 return i;
236 int set_atomtype(int nt,gpp_atomtype_t ga,t_symtab *tab,
237 t_atom *a,const char *name,t_param *nb,
238 int bondatomtype,
239 real radius,real vol,real surftens,int atomnumber,
240 real gb_radius, real S_hct)
242 if ((nt < 0) || (nt >= ga->nr))
243 return NOTSET;
245 ga->atom[nt] = *a;
246 ga->atomname[nt] = put_symtab(tab,name);
247 ga->nb[nt] = *nb;
248 ga->bondatomtype[nt] = bondatomtype;
249 ga->radius[nt] = radius;
250 ga->vol[nt] = vol;
251 ga->surftens[nt] = surftens;
252 ga->atomnumber[nt] = atomnumber;
253 ga->gb_radius[nt] = gb_radius;
254 ga->S_hct[nt] = S_hct;
256 return nt;
259 int add_atomtype(gpp_atomtype_t ga,t_symtab *tab,
260 t_atom *a,const char *name,t_param *nb,
261 int bondatomtype,
262 real radius,real vol,real surftens,real atomnumber,
263 real gb_radius, real S_hct)
265 int i;
267 for(i=0; (i<ga->nr); i++) {
268 if (strcmp(*ga->atomname[i],name) == 0) {
269 if (NULL != debug)
270 fprintf(debug,"Trying to add atomtype %s again. Skipping it.\n",name);
271 break;
274 if (i == ga->nr) {
275 ga->nr++;
276 srenew(ga->atom,ga->nr);
277 srenew(ga->atomname,ga->nr);
278 srenew(ga->nb,ga->nr);
279 srenew(ga->bondatomtype,ga->nr);
280 srenew(ga->radius,ga->nr);
281 srenew(ga->vol,ga->nr);
282 srenew(ga->surftens,ga->nr);
283 srenew(ga->atomnumber,ga->nr);
284 srenew(ga->gb_radius,ga->nr);
285 srenew(ga->S_hct,ga->nr);
287 return set_atomtype(ga->nr-1,ga,tab,a,name,nb,bondatomtype,radius,
288 vol,surftens,atomnumber,gb_radius,S_hct);
290 else
291 return i;
294 void print_at (FILE * out, gpp_atomtype_t ga)
296 int i;
297 t_atom *atom = ga->atom;
298 t_param *nb = ga->nb;
300 fprintf (out,"[ %s ]\n",dir2str(d_atomtypes));
301 fprintf (out,"; %6s %8s %8s %8s %12s %12s\n",
302 "type","mass","charge","particle","c6","c12");
303 for (i=0; (i<ga->nr); i++)
304 fprintf(out,"%8s %8.3f %8.3f %8s %12e %12e\n",
305 *(ga->atomname[i]),atom[i].m,atom[i].q,"A",
306 nb[i].C0,nb[i].C1);
308 fprintf (out,"\n");
311 void done_atomtype(gpp_atomtype_t ga)
313 sfree(ga->atom);
314 sfree(ga->atomname);
315 sfree(ga->nb);
316 sfree(ga->bondatomtype);
317 sfree(ga->radius);
318 sfree(ga->vol);
319 sfree(ga->gb_radius);
320 sfree(ga->S_hct);
321 sfree(ga->surftens);
322 sfree(ga->atomnumber);
323 ga->nr = 0;
324 sfree(ga);
325 ga = NULL;
328 static int search_atomtypes(gpp_atomtype_t ga,int *n,int typelist[],
329 int thistype,
330 t_param param[],int ftype)
332 int i,nn,nrfp,j,k,ntype,tli;
333 gmx_bool bFound=FALSE;
335 nn = *n;
336 nrfp = NRFP(ftype);
337 ntype = get_atomtype_ntypes(ga);
339 for(i=0; (i<nn); i++)
341 if (typelist[i] == thistype)
343 /* This type number has already been added */
344 break;
347 /* Otherwise, check if the parameters are identical to any previously added type */
349 bFound=TRUE;
350 for(j=0;j<ntype && bFound;j++)
352 /* Check nonbonded parameters */
353 for(k=0;k<nrfp && bFound;k++)
355 bFound=(param[ntype*typelist[i]+j].c[k]==param[ntype*thistype+j].c[k]);
358 /* Check radius, volume, surftens */
359 tli = typelist[i];
360 bFound = bFound &&
361 (get_atomtype_radius(tli,ga) == get_atomtype_radius(thistype,ga)) &&
362 (get_atomtype_vol(tli,ga) == get_atomtype_vol(thistype,ga)) &&
363 (get_atomtype_surftens(tli,ga) == get_atomtype_surftens(thistype,ga)) &&
364 (get_atomtype_atomnumber(tli,ga) == get_atomtype_atomnumber(thistype,ga)) &&
365 (get_atomtype_gb_radius(tli,ga) == get_atomtype_gb_radius(thistype,ga)) &&
366 (get_atomtype_S_hct(tli,ga) == get_atomtype_S_hct(thistype,ga));
368 if (bFound)
370 break;
374 if (i == nn) {
375 if (debug)
376 fprintf(debug,"Renumbering atomtype %d to %d\n",thistype,nn);
377 if (nn == ntype)
378 gmx_fatal(FARGS,"Atomtype horror n = %d, %s, %d",nn,__FILE__,__LINE__);
379 typelist[nn]=thistype;
380 nn++;
382 *n = nn;
384 return i;
387 void renum_atype(t_params plist[],gmx_mtop_t *mtop,
388 int *wall_atomtype,
389 gpp_atomtype_t ga,gmx_bool bVerbose)
391 int i,j,k,l,molt,mi,mj,nat,nrfp,ftype,ntype;
392 t_atoms *atoms;
393 t_param *nbsnew;
394 int *typelist;
395 real *new_radius;
396 real *new_vol;
397 real *new_surftens;
398 real *new_gb_radius;
399 real *new_S_hct;
400 int *new_atomnumber;
401 char ***new_atomname;
403 ntype = get_atomtype_ntypes(ga);
404 snew(typelist,ntype);
406 if (bVerbose)
407 fprintf(stderr,"renumbering atomtypes...\n");
409 /* Since the bonded interactions have been assigned now,
410 * we want to reduce the number of atom types by merging
411 * ones with identical nonbonded interactions, in addition
412 * to removing unused ones.
414 * With Generalized-Born electrostatics, or implicit solvent
415 * we also check that the atomtype radius, effective_volume
416 * and surface tension match.
418 * With QM/MM we also check that the atom numbers match
421 /* Get nonbonded interaction type */
422 if (plist[F_LJ].nr > 0)
423 ftype=F_LJ;
424 else
425 ftype=F_BHAM;
427 /* Renumber atomtypes by first making a list of which ones are actually used.
428 * We provide the list of nonbonded parameters so search_atomtypes
429 * can determine if two types should be merged.
431 nat=0;
432 for(molt=0; molt<mtop->nmoltype; molt++) {
433 atoms = &mtop->moltype[molt].atoms;
434 for(i=0; (i<atoms->nr); i++) {
435 atoms->atom[i].type =
436 search_atomtypes(ga,&nat,typelist,atoms->atom[i].type,
437 plist[ftype].param,ftype);
438 atoms->atom[i].typeB=
439 search_atomtypes(ga,&nat,typelist,atoms->atom[i].typeB,
440 plist[ftype].param,ftype);
444 for(i=0; i<2; i++) {
445 if (wall_atomtype[i] >= 0)
446 wall_atomtype[i] = search_atomtypes(ga,&nat,typelist,wall_atomtype[i],
447 plist[ftype].param,ftype);
450 snew(new_radius,nat);
451 snew(new_vol,nat);
452 snew(new_surftens,nat);
453 snew(new_atomnumber,nat);
454 snew(new_gb_radius,nat);
455 snew(new_S_hct,nat);
456 snew(new_atomname,nat);
458 /* We now have a list of unique atomtypes in typelist */
460 if (debug)
461 pr_ivec(debug,0,"typelist",typelist,nat,TRUE);
463 /* Renumber nlist */
464 nbsnew = NULL;
465 snew(nbsnew,plist[ftype].nr);
467 nrfp = NRFP(ftype);
469 for(i=k=0; (i<nat); i++)
471 mi=typelist[i];
472 for(j=0; (j<nat); j++,k++)
474 mj=typelist[j];
475 for(l=0; (l<nrfp); l++)
477 nbsnew[k].c[l]=plist[ftype].param[ntype*mi+mj].c[l];
480 new_radius[i] = get_atomtype_radius(mi,ga);
481 new_vol[i] = get_atomtype_vol(mi,ga);
482 new_surftens[i] = get_atomtype_surftens(mi,ga);
483 new_atomnumber[i] = get_atomtype_atomnumber(mi,ga);
484 new_gb_radius[i] = get_atomtype_gb_radius(mi,ga);
485 new_S_hct[i] = get_atomtype_S_hct(mi,ga);
486 new_atomname[i] = ga->atomname[mi];
489 for(i=0; (i<nat*nat); i++) {
490 for(l=0; (l<nrfp); l++)
491 plist[ftype].param[i].c[l]=nbsnew[i].c[l];
493 plist[ftype].nr=i;
494 mtop->ffparams.atnr = nat;
496 sfree(ga->radius);
497 sfree(ga->vol);
498 sfree(ga->surftens);
499 sfree(ga->atomnumber);
500 sfree(ga->gb_radius);
501 sfree(ga->S_hct);
502 /* Dangling atomname pointers ? */
503 sfree(ga->atomname);
505 ga->radius = new_radius;
506 ga->vol = new_vol;
507 ga->surftens = new_surftens;
508 ga->atomnumber = new_atomnumber;
509 ga->gb_radius = new_gb_radius;
510 ga->S_hct = new_S_hct;
511 ga->atomname = new_atomname;
513 ga->nr=nat;
515 sfree(nbsnew);
516 sfree(typelist);
519 void copy_atomtype_atomtypes(gpp_atomtype_t ga,t_atomtypes *atomtypes)
521 int i,ntype;
523 /* Copy the atomtype data to the topology atomtype list */
524 ntype = get_atomtype_ntypes(ga);
525 atomtypes->nr=ntype;
526 snew(atomtypes->radius,ntype);
527 snew(atomtypes->vol,ntype);
528 snew(atomtypes->surftens,ntype);
529 snew(atomtypes->atomnumber,ntype);
530 snew(atomtypes->gb_radius,ntype);
531 snew(atomtypes->S_hct,ntype);
533 for(i=0; i<ntype; i++) {
534 atomtypes->radius[i] = ga->radius[i];
535 atomtypes->vol[i] = ga->vol[i];
536 atomtypes->surftens[i] = ga->surftens[i];
537 atomtypes->atomnumber[i] = ga->atomnumber[i];
538 atomtypes->gb_radius[i] = ga->gb_radius[i];
539 atomtypes->S_hct[i] = ga->S_hct[i];