Merge release-4-6 into master
[alexxy/gromacs.git] / src / gromacs / gmxana / edittop.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  * Green Red Orange Magenta Azure Cyan Skyblue
34  */
35 #ifdef HAVE_CONFIG_H
36 #include <config.h>
37 #endif
38
39 #include "smalloc.h"
40 #include "string2.h"
41 #include "gmx_fatal.h"
42 #include "symtab.h"
43
44 void replace_atom(t_topology *top, int inr, char *anm, char *resnm,
45                   real q, real m, int type)
46 {
47     t_atoms *atoms;
48
49     atoms = &(top->atoms);
50
51     /* Replace important properties of an atom by other properties */
52     if ((inr < 0) || (inr > atoms->nr))
53     {
54         gmx_fatal(FARGS, "Replace_atom: inr (%d) not in %d .. %d", inr, 0, atoms->nr);
55     }
56     if (debug)
57     {
58         fprintf(debug, "Replacing atom %d ... ", inr);
59     }
60     /* Charge, mass and type */
61     atoms->atom[inr].q    = atoms->atom[inr].qB    = q;
62     atoms->atom[inr].m    = atoms->atom[inr].mB    = m;
63     atoms->atom[inr].type = atoms->atom[inr].typeB = type;
64
65     /* Residue name */
66     atoms->resinfo[atoms->atom[inr].resind].name = put_symtab(&top->symtab, resnm);
67     /* Atom name */
68     atoms->atomname[inr] = put_symtab(&top->symtab, anm);
69     if (debug)
70     {
71         fprintf(debug, " done\n");
72     }
73 }
74
75 static void delete_from_interactions(t_idef *idef, int inr)
76 {
77     int      i, j, k, nra, nnr;
78     t_iatom *niatoms;
79     gmx_bool bDel;
80
81     /* Delete interactions including atom inr from lists */
82     for (i = 0; (i < F_NRE); i++)
83     {
84         nra = interaction_function[i].nratoms;
85         nnr = 0;
86         snew(niatoms, idef->il[i].nr);
87         for (j = 0; (j < idef->il[i].nr); j += nra+1)
88         {
89             bDel = FALSE;
90             for (k = 0; (k < nra); k++)
91             {
92                 if (idef->il[i].iatoms[j+k+1] == inr)
93                 {
94                     bDel = TRUE;
95                 }
96             }
97             if (!bDel)
98             {
99                 /* If this does not need to be deleted, then copy it to temp array */
100                 for (k = 0; (k < nra+1); k++)
101                 {
102                     niatoms[nnr+k] = idef->il[i].iatoms[j+k];
103                 }
104                 nnr += nra+1;
105             }
106         }
107         /* Copy temp array back */
108         for (j = 0; (j < nnr); j++)
109         {
110             idef->il[i].iatoms[j] = niatoms[j];
111         }
112         idef->il[i].nr = nnr;
113         sfree(niatoms);
114     }
115 }
116
117 static void delete_from_block(t_block *block, int inr)
118 {
119     /* Update block data structure */
120     int i, i1, j1, j, k;
121
122     for (i = 0; (i < block->nr); i++)
123     {
124         for (j = block->index[i]; (j < block->index[i+1]); j++)
125         {
126             if (j == inr)
127             {
128                 /* This atom has to go */
129                 /* Change indices too */
130                 for (i1 = i+1; (i1 <= block->nr); i1++)
131                 {
132                     block->index[i1]--;
133                 }
134             }
135         }
136     }
137 }
138
139 static void delete_from_blocka(t_blocka *block, int inr)
140 {
141     /* Update block data structure */
142     int i, i1, j1, j, k;
143
144     for (i = 0; (i < block->nr); i++)
145     {
146         for (j = block->index[i]; (j < block->index[i+1]); j++)
147         {
148             k = block->a[j];
149             if (k == inr)
150             {
151                 /* This atom has to go */
152                 for (j1 = j; (j1 < block->nra-1); j1++)
153                 {
154                     block->a[j1] = block->a[j1+1];
155                 }
156                 block->nra--;
157                 /* Change indices too */
158                 for (i1 = i+1; (i1 <= block->nr); i1++)
159                 {
160                     block->index[i1]--;
161                 }
162             }
163         }
164     }
165 }
166
167 static void delete_from_atoms(t_atoms *atoms, int inr)
168 {
169     int i;
170
171     /* Shift the atomnames down */
172     for (i = inr; (i < atoms->nr-1); i++)
173     {
174         atoms->atomname[i] = atoms->atomname[i+1];
175     }
176
177     /* Shift the atom struct down */
178     for (i = inr; (i < atoms->nr-1); i++)
179     {
180         atoms->atom[i] = atoms->atom[i+1];
181     }
182
183     if (atoms->pdbinfo)
184     {
185         /* Shift the pdbatom struct down */
186         for (i = inr; (i < atoms->nr-1); i++)
187         {
188             atoms->pdbinfo[i] = atoms->pdbinfo[i+1];
189         }
190     }
191     atoms->nr--;
192 }
193
194 void delete_atom(t_topology *top, int inr)
195 {
196     int k;
197
198     if ((inr < 0) || (inr >= top->atoms.nr))
199     {
200         gmx_fatal(FARGS, "Delete_atom: inr (%d) not in %d .. %d", inr, 0,
201                   top->atoms.nr);
202     }
203     if (debug)
204     {
205         fprintf(debug, "Deleting atom %d ...", inr);
206     }
207
208     /* First remove bonds etc. */
209     delete_from_interactions(&top->idef, inr);
210     /* Now charge groups etc. */
211     delete_from_block(&(top->cgs), inr);
212     delete_from_block(&(top->mols), inr);
213     delete_from_blocka(&(top->excls), inr);
214     /* Now from the atoms struct */
215     delete_from_atoms(&top->atoms, inr);
216     if (debug)
217     {
218         fprintf(debug, " done\n");
219     }
220 }