ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/mdtools/md_code/AllLong.cpp
Revision: 10
Committed: Tue Jul 9 18:40:59 2002 UTC (22 years ago) by mmeineke
Original Path: branches/mmeineke/mdtools/md_code/AllLong.cpp
File size: 8106 byte(s)
Log Message:
everything you need to make libmdtools

File Contents

# User Rev Content
1 mmeineke 10 #include <iostream>
2     #include <cstdlib>
3    
4     #include "LRI.hpp"
5    
6    
7     extern "C" {
8    
9    
10     void long_range_force_(unsigned short int &exclude_check,
11     int* pair_i, int* pair_j, int &n_pairs,
12     int &n_atoms, double *sigma, double *epslon,
13     double &r_cut, double &r_list,
14     double &box_x, double &box_y, double &box_z,
15     double *R_x, double *R_y, double *R_z,
16     double *F_x, double *F_y, double *F_z,
17     double &potential_E,
18     unsigned short int &update, int *point,
19     int *list, int &maxnab,
20     double *R_x0, double *R_y0, double *R_z0,
21     double* ux, double* uy, double* uz,
22     double* Tx, double* Ty, double* Tz,
23     double* Ex, double* Ey, double* Ez,
24     double* mu, double &rRF, double &rTaper,
25     double &dielectric,
26     unsigned short int* isDipole,
27     unsigned short int* isVDW,
28     unsigned short int* isLJ,
29     unsigned short int* isSSD,
30     double* Axx, double *Axy, double *Axz,
31     double* Ayx, double *Ayy, double *Ayz,
32     double* Azx, double *Azy, double *Azz
33     );
34    
35    
36     void long_range_check_(double &r_cut, double &r_list,
37     unsigned short int &update,
38     int &n_atoms, double *R_x, double *R_y, double *R_z,
39     double *R_x0, double *R_y0, double *R_z0);
40     }
41    
42    
43    
44     AllLong::AllLong( SimInfo* entry_plug ){
45     int i, error;
46    
47     // get what info we need from the entry plug
48    
49     nPairs = entry_plug->n_exclude;
50     nAtoms = entry_plug->n_atoms;
51     atoms = entry_plug->atoms;
52     boxX = entry_plug->box_x;
53     boxY = entry_plug->box_y;
54     boxZ = entry_plug->box_z;
55     nDipoles = entry_plug->n_dipoles;
56     ex_pair *pair_list = entry_plug->excludes;
57    
58     if( nDipoles ){
59     dielectric = entry_plug->dielectric;
60     rRF = entry_plug->rRF;
61     rTaper = 0.95 * rRF;
62     }
63     else{
64     dielectric = 0.0;
65     rRF = 0.0;
66     rTaper = 0.0;
67     }
68    
69     exclude = 0;
70     pairI = NULL;
71     pairJ = NULL;
72    
73     if ( pair_list != NULL ){
74    
75     exclude = 1;
76    
77     pairI = new int[nPairs];
78     pairJ = new int[nPairs];
79    
80     for(int i = 0; i < nPairs; i++){
81    
82     pairI[i] = pair_list[i].i;
83     pairJ[i] = pair_list[i].j;
84     }
85     }
86    
87     sigma = new double[nAtoms];
88     epslon = new double[nAtoms];
89     mu = new double[nAtoms];
90    
91    
92     Rx = new double[nAtoms];
93     Ry = new double[nAtoms];
94     Rz = new double[nAtoms];
95    
96     Rx0 = new double[nAtoms];
97     Ry0 = new double[nAtoms];
98     Rz0 = new double[nAtoms];
99    
100     Fx = new double[nAtoms];
101     Fy = new double[nAtoms];
102     Fz = new double[nAtoms];
103    
104     ux = new double[nAtoms];
105     uy = new double[nAtoms];
106     uz = new double[nAtoms];
107    
108     Tx = new double[nAtoms];
109     Ty = new double[nAtoms];
110     Tz = new double[nAtoms];
111    
112     Ex = new double[nAtoms];
113     Ey = new double[nAtoms];
114     Ez = new double[nAtoms];
115    
116     Axx = new double[nAtoms];
117     Axy = new double[nAtoms];
118     Axz = new double[nAtoms];
119    
120     Ayx = new double[nAtoms];
121     Ayy = new double[nAtoms];
122     Ayz = new double[nAtoms];
123    
124     Azx = new double[nAtoms];
125     Azy = new double[nAtoms];
126     Azz = new double[nAtoms];
127    
128     isDipole = new unsigned short int[nAtoms];
129     isVDW = new unsigned short int[nAtoms];
130     isLJ = new unsigned short int[nAtoms];
131     isSSD = new unsigned short int[nAtoms];
132    
133     // collect the array of dipole moments, mass, sigma, epsilon
134     // also set the boolean arrays
135    
136     DirectionalAtom* dAtom;
137     for( i=0; i<nAtoms; i++ ){
138    
139     isDipole[i] = 0;
140     isVDW[i] = 0;
141     isLJ[i] = 0;
142     isSSD[i] = 0;
143    
144     if( atoms[i]->hasDipole() ){
145    
146     dAtom = ( DirectionalAtom* )atoms[i];
147     mu[i] = dAtom->getMu();
148     isDipole[i] = 1;
149    
150     if( dAtom->isSSD() ) isSSD[i] = 1;
151     }
152     else mu[i] = 0.0;
153    
154     sigma[i] = atoms[i]->getSigma();
155     epslon[i] = atoms[i]->getEpslon();
156    
157     isVDW[i] = atoms[i]->isVDW();
158     isLJ[i] = atoms[i]->isLJ();
159    
160     // leech off the loop, and initialize the neighbor list initial positions
161    
162     Rx0[i] = 0.0; // these positions should force the first call to regenerate
163     Ry0[i] = 0.0; // the neighbor list.
164     Rz0[i] = 0.0;
165    
166     // leech again, and initialize the rotation matrixes
167    
168     Axx[i] = 1.0;
169     Axy[i] = 0.0;
170     Axz[i] = 0.0;
171    
172     Ayx[i] = 0.0;
173     Ayy[i] = 1.0;
174     Ayz[i] = 0.0;
175    
176     Azx[i] = 0.0;
177     Azy[i] = 0.0;
178     Azz[i] = 1.0;
179     }
180    
181     // check for force consistency
182    
183     error = 0;
184     for( i=0; i<(nAtoms-1); i++ ){
185     if( isVDW[i] && isLJ[i+1] ) error = 1;
186     if( isLJ[i] && isVDW[i+1] ) error = 1;
187    
188     if( error ){
189     std::cerr << "longRange force error: You cannot mix Lenard-Jones and"
190     << " \"Exp - r^6\" type interactions\n";
191     exit(8);
192     }
193     }
194    
195     /* a little routine to set the rCut, should not exceed half of any
196     box length */
197    
198     rCut = 0.0;
199     double test_cut;
200    
201     for(int i = 0; i < nAtoms - 1; i++){
202     for(int j = i+1; j < nAtoms; j++){
203    
204     test_cut = 2.5 * ( sigma[i] + sigma[j] ) / 2.0;
205     if( test_cut > rCut) rCut = test_cut;
206     }
207     }
208    
209     if(rCut > (boxX / 2.0)) rCut = boxX / 2.0;
210     if(rCut > (boxY / 2.0)) rCut = boxY / 2.0;
211     if(rCut > (boxZ / 2.0)) rCut = boxZ / 2.0;
212    
213     if( rCut > rRF ){
214     rList = rCut + 1.0;
215     rListSmall = rCut;
216     }
217     else{
218     rList = rRF + 1.0;
219     rListSmall = rRF;
220     }
221    
222     // the first time through, the neighbor list needs to be updated
223    
224     listUpdate = 1;
225    
226     // set the neighbor list info
227    
228     maxNab = nAtoms * 1000;
229     point = new int[nAtoms];
230     list = new int[maxNab];
231    
232     // give some love back to the entry plug
233    
234     if( entry_plug->longRange != NULL ) delete entry_plug->longRange;
235     entry_plug->longRange = this;
236     }
237    
238     AllLong::~AllLong(){
239    
240     if( pairI != NULL ) delete[] pairI;
241     if( pairJ != NULL ) delete[] pairJ;
242    
243     delete[] sigma;
244     delete[] epslon;
245     delete[] mu;
246    
247     delete[] Rx;
248     delete[] Ry;
249     delete[] Rz;
250    
251     delete[] Rx0;
252     delete[] Ry0;
253     delete[] Rz0;
254    
255     delete[] Fx;
256     delete[] Fy;
257     delete[] Fz;
258    
259     delete[] ux;
260     delete[] uy;
261     delete[] uz;
262    
263     delete[] Tx;
264     delete[] Ty;
265     delete[] Tz;
266    
267     delete[] Ex;
268     delete[] Ey;
269     delete[] Ez;
270    
271     delete[] Axx;
272     delete[] Axy;
273     delete[] Axz;
274    
275     delete[] Ayx;
276     delete[] Ayy;
277     delete[] Ayz;
278    
279     delete[] Azx;
280     delete[] Azy;
281     delete[] Azz;
282    
283     delete[] isDipole;
284     delete[] isVDW;
285     delete[] isLJ;
286     delete[] isSSD;
287    
288     delete[] point;
289     delete[] list;
290     }
291    
292    
293     void AllLong::calc_forces( void ){
294    
295     int i;
296     double u_temp[3];
297     DirectionalAtom* dAtom;
298    
299     // fill our arrays;
300    
301     for( i=0; i<nAtoms; i++ ){
302    
303     if( isDipole[i] ){
304    
305     if( !(atoms[i]->isDirectional()) ){
306     std::cerr << "Something went Horribly wrong!!!!\n"
307     << "We're all gonna die in here!!!!!!!\n"
308     << "Oh yeah, by the way, atom " << i
309     << " somehow thinks it has a dipole,\n"
310     << "but it isn't a directional atom type.\n";
311     exit(8);
312     }
313    
314     dAtom = ( DirectionalAtom* )atoms[i];
315     dAtom->getU( u_temp );
316    
317     ux[i] = u_temp[0];
318     uy[i] = u_temp[1];
319     uz[i] = u_temp[2];
320    
321     Axx[i] = dAtom->getAxx();
322     Axy[i] = dAtom->getAxy();
323     Axz[i] = dAtom->getAxz();
324    
325     Ayx[i] = dAtom->getAyx();
326     Ayy[i] = dAtom->getAyy();
327     Ayz[i] = dAtom->getAyz();
328    
329     Azx[i] = dAtom->getAzx();
330     Azy[i] = dAtom->getAzy();
331     Azz[i] = dAtom->getAzz();
332    
333     }
334    
335     Rx[i] = atoms[i]->getX();
336     Ry[i] = atoms[i]->getY();
337     Rz[i] = atoms[i]->getZ();
338     }
339    
340    
341     // call fortran for the force calcs
342    
343     long_range_check_(rListSmall, rList, listUpdate,
344     nAtoms, Rx, Ry, Rz,
345     Rx0, Ry0, Rz0);
346    
347     long_range_force_(exclude,
348     pairI, pairJ, nPairs,
349     nAtoms, sigma, epslon,
350     rCut, rList,
351     boxX, boxY, boxZ,
352     Rx, Ry, Rz,
353     Fx, Fy, Fz,
354     potentialE,
355     listUpdate, point,
356     list, maxNab,
357     Rx0, Ry0, Rz0,
358     ux, uy, uz,
359     Tx, Ty, Tz,
360     Ex, Ey, Ez,
361     mu, rRF, rTaper,
362     dielectric,
363     isDipole, isVDW, isLJ, isSSD,
364     Axx, Axy, Axz,
365     Ayx, Ayy, Ayz,
366     Azx, Azy, Azz );
367    
368     // pass info back to the atoms
369    
370     for( i=0; i<nAtoms; i++ ){
371    
372     if( isDipole[i] ){
373    
374     dAtom = ( DirectionalAtom* )atoms[i];
375    
376     dAtom->addTx( Tx[i] );
377     dAtom->addTy( Ty[i] );
378     dAtom->addTz( Tz[i] );
379     }
380    
381     atoms[i]->addFx( Fx[i] );
382     atoms[i]->addFy( Fy[i] );
383     atoms[i]->addFz( Fz[i] );
384     }
385     }