cefa9692b740d41c73ac9ec8cc440102aa342065
[alexxy/gromacs.git] / src / gromacs / gmxana / edittop.c
1 /*
2  * This file is part of the GROMACS molecular simulation package.
3  *
4  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
5  * Copyright (c) 2001-2004, The GROMACS development team.
6  * Copyright (c) 2013,2014, by the GROMACS development team, led by
7  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
8  * and including many others, as listed in the AUTHORS file in the
9  * top-level source directory and at http://www.gromacs.org.
10  *
11  * GROMACS is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Lesser General Public License
13  * as published by the Free Software Foundation; either version 2.1
14  * of the License, or (at your option) any later version.
15  *
16  * GROMACS is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19  * Lesser General Public License for more details.
20  *
21  * You should have received a copy of the GNU Lesser General Public
22  * License along with GROMACS; if not, see
23  * http://www.gnu.org/licenses, or write to the Free Software Foundation,
24  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
25  *
26  * If you want to redistribute modifications to GROMACS, please
27  * consider that scientific software is very special. Version
28  * control is crucial - bugs must be traceable. We will be happy to
29  * consider code for inclusion in the official distribution, but
30  * derived work must not be called official GROMACS. Details are found
31  * in the README & COPYING files - if they are missing, get the
32  * official version at http://www.gromacs.org.
33  *
34  * To help us fund GROMACS development, we humbly ask that you cite
35  * the research papers on the package. Check out http://www.gromacs.org.
36  */
37 #include "gmxpre.h"
38
39 #include "config.h"
40
41 #include "gromacs/legacyheaders/typedefs.h"
42 #include "gromacs/topology/symtab.h"
43 #include "gromacs/utility/smalloc.h"
44 #include "gromacs/utility/fatalerror.h"
45
46 void replace_atom(t_topology *top, int inr, char *anm, char *resnm,
47                   real q, real m, int type)
48 {
49     t_atoms *atoms;
50
51     atoms = &(top->atoms);
52
53     /* Replace important properties of an atom by other properties */
54     if ((inr < 0) || (inr > atoms->nr))
55     {
56         gmx_fatal(FARGS, "Replace_atom: inr (%d) not in %d .. %d", inr, 0, atoms->nr);
57     }
58     if (debug)
59     {
60         fprintf(debug, "Replacing atom %d ... ", inr);
61     }
62     /* Charge, mass and type */
63     atoms->atom[inr].q    = atoms->atom[inr].qB    = q;
64     atoms->atom[inr].m    = atoms->atom[inr].mB    = m;
65     atoms->atom[inr].type = atoms->atom[inr].typeB = type;
66
67     /* Residue name */
68     atoms->resinfo[atoms->atom[inr].resind].name = put_symtab(&top->symtab, resnm);
69     /* Atom name */
70     atoms->atomname[inr] = put_symtab(&top->symtab, anm);
71     if (debug)
72     {
73         fprintf(debug, " done\n");
74     }
75 }
76
77 static void delete_from_interactions(t_idef *idef, int inr)
78 {
79     int      i, j, k, nra, nnr;
80     t_iatom *niatoms;
81     gmx_bool bDel;
82
83     /* Delete interactions including atom inr from lists */
84     for (i = 0; (i < F_NRE); i++)
85     {
86         nra = interaction_function[i].nratoms;
87         nnr = 0;
88         snew(niatoms, idef->il[i].nr);
89         for (j = 0; (j < idef->il[i].nr); j += nra+1)
90         {
91             bDel = FALSE;
92             for (k = 0; (k < nra); k++)
93             {
94                 if (idef->il[i].iatoms[j+k+1] == inr)
95                 {
96                     bDel = TRUE;
97                 }
98             }
99             if (!bDel)
100             {
101                 /* If this does not need to be deleted, then copy it to temp array */
102                 for (k = 0; (k < nra+1); k++)
103                 {
104                     niatoms[nnr+k] = idef->il[i].iatoms[j+k];
105                 }
106                 nnr += nra+1;
107             }
108         }
109         /* Copy temp array back */
110         for (j = 0; (j < nnr); j++)
111         {
112             idef->il[i].iatoms[j] = niatoms[j];
113         }
114         idef->il[i].nr = nnr;
115         /* cppcheck-suppress uninitvar Fixed in cppcheck 1.65 */
116         sfree(niatoms);
117     }
118 }
119
120 static void delete_from_block(t_block *block, int inr)
121 {
122     /* Update block data structure */
123     int i, i1, j1, j, k;
124
125     for (i = 0; (i < block->nr); i++)
126     {
127         for (j = block->index[i]; (j < block->index[i+1]); j++)
128         {
129             if (j == inr)
130             {
131                 /* This atom has to go */
132                 /* Change indices too */
133                 for (i1 = i+1; (i1 <= block->nr); i1++)
134                 {
135                     block->index[i1]--;
136                 }
137             }
138         }
139     }
140 }
141
142 static void delete_from_blocka(t_blocka *block, int inr)
143 {
144     /* Update block data structure */
145     int i, i1, j1, j, k;
146
147     for (i = 0; (i < block->nr); i++)
148     {
149         for (j = block->index[i]; (j < block->index[i+1]); j++)
150         {
151             k = block->a[j];
152             if (k == inr)
153             {
154                 /* This atom has to go */
155                 for (j1 = j; (j1 < block->nra-1); j1++)
156                 {
157                     block->a[j1] = block->a[j1+1];
158                 }
159                 block->nra--;
160                 /* Change indices too */
161                 for (i1 = i+1; (i1 <= block->nr); i1++)
162                 {
163                     block->index[i1]--;
164                 }
165             }
166         }
167     }
168 }
169
170 static void delete_from_atoms(t_atoms *atoms, int inr)
171 {
172     int i;
173
174     /* Shift the atomnames down */
175     for (i = inr; (i < atoms->nr-1); i++)
176     {
177         atoms->atomname[i] = atoms->atomname[i+1];
178     }
179
180     /* Shift the atom struct down */
181     for (i = inr; (i < atoms->nr-1); i++)
182     {
183         atoms->atom[i] = atoms->atom[i+1];
184     }
185
186     if (atoms->pdbinfo)
187     {
188         /* Shift the pdbatom struct down */
189         for (i = inr; (i < atoms->nr-1); i++)
190         {
191             atoms->pdbinfo[i] = atoms->pdbinfo[i+1];
192         }
193     }
194     atoms->nr--;
195 }
196
197 void delete_atom(t_topology *top, int inr)
198 {
199     int k;
200
201     if ((inr < 0) || (inr >= top->atoms.nr))
202     {
203         gmx_fatal(FARGS, "Delete_atom: inr (%d) not in %d .. %d", inr, 0,
204                   top->atoms.nr);
205     }
206     if (debug)
207     {
208         fprintf(debug, "Deleting atom %d ...", inr);
209     }
210
211     /* First remove bonds etc. */
212     delete_from_interactions(&top->idef, inr);
213     /* Now charge groups etc. */
214     delete_from_block(&(top->cgs), inr);
215     delete_from_block(&(top->mols), inr);
216     delete_from_blocka(&(top->excls), inr);
217     /* Now from the atoms struct */
218     delete_from_atoms(&top->atoms, inr);
219     if (debug)
220     {
221         fprintf(debug, " done\n");
222     }
223 }