Merge origin/release-4-6 into master
[alexxy/gromacs.git] / src / gromacs / gmxpreprocess / hackblock.c
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.
14
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.
19  * 
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.
26  * 
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.
29  * 
30  * For more info, check our website at http://www.gromacs.org
31  * 
32  * And Hey:
33  * Gallium Rubidium Oxygen Manganese Argon Carbon Silicon
34  */
35 /* This file is completely threadsafe - keep it that way! */
36 #ifdef HAVE_CONFIG_H
37 #include <config.h>
38 #endif
39
40 #include <string.h>
41 #include "hackblock.h"
42 #include "smalloc.h"
43 #include "vec.h"
44 #include "string2.h"
45 #include "macros.h"
46
47 /* these MUST correspond to the enum in hackblock.h */
48 const char *btsNames[ebtsNR] = { "bonds", "angles", "dihedrals", "impropers", "exclusions", "cmap" };
49 const int btsNiatoms[ebtsNR] = { 2,       3,        4,           4,           2,             5 };
50
51 static void free_t_bonded(t_rbonded *rb)
52 {
53   int i;
54   
55   for (i=0; i<MAXATOMLIST; i++)
56     sfree(rb->a[i]);
57   sfree(rb->s);
58 }
59
60 static void free_t_bondeds(t_rbondeds *rbs)
61 {
62   int i;
63   
64   for(i=0; i<rbs->nb; i++)
65     free_t_bonded(&rbs->b[i]);
66   sfree(rbs->b);
67   rbs->b=NULL;
68   rbs->nb=0;
69 }
70
71 void free_t_restp(int nrtp, t_restp **rtp)
72 {
73   int i,j;
74   
75   for(i=0; i<nrtp; i++) {
76     sfree((*rtp)[i].resname);
77     sfree((*rtp)[i].atom);
78     for(j=0; j<(*rtp)[i].natom; j++) {
79       sfree(*(*rtp)[i].atomname[j]);
80       sfree((*rtp)[i].atomname[j]);
81     }
82     sfree((*rtp)[i].atomname);
83     sfree((*rtp)[i].cgnr);
84     for(j=0; j<ebtsNR; j++)
85       free_t_bondeds(&(*rtp)[i].rb[j]);
86   }
87   free(*rtp);
88 }
89
90 void free_t_hack(int nh, t_hack **h)
91 {
92   int i, j;
93   
94   for(i=0; i<nh; i++) {
95     sfree((*h)[i].oname);
96     sfree((*h)[i].nname);
97     sfree((*h)[i].atom);
98     for(j=0; j<4; j++)
99       sfree((*h)[i].a[j]);
100   }
101   sfree(*h);
102   *h=NULL;
103 }
104
105 void free_t_hackblock(int nhb, t_hackblock **hb)
106 {
107   int i, j;
108   
109   for(i=0; i<nhb; i++) {
110     sfree((*hb)[i].name);
111     free_t_hack((*hb)[i].nhack, &(*hb)[i].hack);
112     for(j=0; j<ebtsNR; j++)
113       free_t_bondeds(&(*hb)[i].rb[j]);
114   }
115   sfree(*hb);
116 }
117
118 void clear_t_hackblock(t_hackblock *hb)
119 {
120   int i;
121   
122   hb->name   = NULL;
123   hb->nhack  = 0;
124   hb->maxhack= 0;
125   hb->hack   = NULL;
126   for(i=0; i<ebtsNR; i++) {
127     hb->rb[i].nb=0;
128     hb->rb[i].b=NULL;
129   }
130 }
131
132 void clear_t_hack(t_hack *hack)
133 {
134   int i;
135   
136   hack->nr    = 0;
137   hack->oname = NULL;
138   hack->nname = NULL;
139   hack->atom  = NULL;
140   hack->cgnr  = NOTSET;
141   hack->tp    = 0;
142   hack->nctl  = 0;
143   for(i=0; i<4; i++)
144     hack->a[i]  = NULL;
145   for(i=0; i<DIM; i++)
146     hack->newx[i] = NOTSET;
147 }
148
149 #define safe_strdup(str) ((str != NULL) ? strdup(str) : NULL)
150
151 static void copy_t_rbonded(t_rbonded *s, t_rbonded *d)
152 {
153   int i;
154   
155   for(i=0; i<MAXATOMLIST; i++)
156     d->a[i] = safe_strdup(s->a[i]);
157   d->s = safe_strdup(s->s);
158 }
159
160 static gmx_bool contains_char(t_rbonded *s,char c)
161 {
162   int i;
163   gmx_bool bRet;
164   
165   bRet = FALSE;
166   for(i=0; i<MAXATOMLIST; i++)
167     if (s->a[i] && s->a[i][0]==c)
168       bRet = TRUE;
169   
170   return bRet;
171 }
172
173 gmx_bool merge_t_bondeds(t_rbondeds s[], t_rbondeds d[],gmx_bool bMin,gmx_bool bPlus)
174 {
175   int i, j;
176   gmx_bool bBondsRemoved;
177   
178   bBondsRemoved = FALSE;
179   for(i=0; i < ebtsNR; i++) {
180     if ( s[i].nb > 0 ) {
181       /* make space */
182       srenew(d[i].b, d[i].nb + s[i].nb);
183       for(j=0; j < s[i].nb; j++)
184         if (!(bMin && contains_char(&s[i].b[j],'-'))
185             && !(bPlus && contains_char(&s[i].b[j],'+'))) {
186           copy_t_rbonded(&s[i].b[j], &d[i].b[ d[i].nb ]);
187           d[i].nb ++;
188         } else if (i == ebtsBONDS) {
189           bBondsRemoved = TRUE;
190         }
191     }
192   }
193
194   return bBondsRemoved;
195 }
196
197 void copy_t_restp(t_restp *s, t_restp *d)
198 {
199   int i;
200   
201   *d = *s;
202   d->resname = safe_strdup(s->resname);
203   snew(d->atom, s->natom);
204   for(i=0; i < s->natom; i++)
205     d->atom[i] = s->atom[i];
206   snew(d->atomname, s->natom);
207   for(i=0; i < s->natom; i++) {
208     snew(d->atomname[i],1);
209     *d->atomname[i] = safe_strdup(*s->atomname[i]);
210   }
211   snew(d->cgnr, s->natom);
212   for(i=0; i < s->natom; i++)
213     d->cgnr[i] = s->cgnr[i];
214   for(i=0; i < ebtsNR; i++) {
215     d->rb[i].type = s->rb[i].type;
216     d->rb[i].nb = 0;
217     d->rb[i].b = NULL;
218   }
219   merge_t_bondeds(s->rb, d->rb,FALSE,FALSE);
220 }
221
222 void copy_t_hack(t_hack *s, t_hack *d)
223 {
224   int i;
225   
226   *d = *s;
227   d->oname = safe_strdup(s->oname);
228   d->nname = safe_strdup(s->nname);
229   if (s->atom) {
230     snew(d->atom, 1);
231     *(d->atom) = *(s->atom);
232   } else
233     d->atom = NULL;
234   for(i=0; i<4; i++)
235     d->a[i] = safe_strdup(s->a[i]);
236   copy_rvec(s->newx, d->newx);
237 }
238
239 void merge_hacks_lo(int ns, t_hack *s, int *nd, t_hack **d)
240 {
241   int i;
242   
243   if (ns) {
244     srenew(*d, *nd + ns);
245     for(i=0; i < ns; i++)
246       copy_t_hack(&s[i], &(*d)[*nd + i]);
247     (*nd) += ns;
248   }
249 }
250
251 void merge_hacks(t_hackblock *s, t_hackblock *d)
252 {
253   merge_hacks_lo(s->nhack, s->hack, &d->nhack, &d->hack);
254 }
255
256 void merge_t_hackblock(t_hackblock *s, t_hackblock *d)
257 {
258   merge_hacks(s, d);
259   merge_t_bondeds(s->rb, d->rb,FALSE,FALSE);
260 }
261
262 void copy_t_hackblock(t_hackblock *s, t_hackblock *d)
263 {
264   int i;
265   
266   *d       = *s;
267   d->name  = safe_strdup(s->name);
268   d->nhack = 0;
269   d->hack  = NULL;
270   for(i=0; i<ebtsNR; i++) {
271     d->rb[i].nb=0;
272     d->rb[i].b=NULL;
273   }
274   merge_t_hackblock(s, d);
275 }
276
277 #undef safe_strdup
278
279 void dump_hb(FILE *out, int nres, t_hackblock hb[])
280 {
281   int i,j,k,l;
282   
283 #define SS(s) (s) ? (s) : "-"
284 #define SA(s) (s) ? "+" : ""
285   fprintf(out,"t_hackblock\n");
286   for(i=0; i<nres; i++) {
287     fprintf(out, "%3d %4s %2d %2d\n",
288             i, SS(hb[i].name), hb[i].nhack, hb[i].maxhack);
289     if (hb[i].nhack)
290       for(j=0; j<hb[i].nhack; j++) {
291         fprintf(out, "%d: %d %4s %4s %1s %2d %d %4s %4s %4s %4s\n", 
292                 j, hb[i].hack[j].nr, 
293                 SS(hb[i].hack[j].oname), SS(hb[i].hack[j].nname),
294                 SA(hb[i].hack[j].atom), hb[i].hack[j].tp, hb[i].hack[j].cgnr,
295                 SS(hb[i].hack[j].AI), SS(hb[i].hack[j].AJ),
296                 SS(hb[i].hack[j].AK), SS(hb[i].hack[j].AL) );
297       }
298     for(j=0; j<ebtsNR; j++)
299       if (hb[i].rb[j].nb) {
300         fprintf(out, " %c %d:", btsNames[j][0], hb[i].rb[j].nb);
301         for(k=0; k<hb[i].rb[j].nb; k++) {
302           fprintf(out, " [");
303           for(l=0; l<btsNiatoms[j]; l++)
304             fprintf(out, " %s",hb[i].rb[j].b[k].a[l]);
305           fprintf(out, " %s]",SS(hb[i].rb[j].b[k].s));
306         }
307         fprintf(out,"\n");
308       }
309     fprintf(out,"\n");
310   }
311 #undef SS
312 #undef SA
313 }
314
315 void init_t_protonate(t_protonate *protonate)
316 {
317   protonate->bInit=FALSE;
318 }