source: CIVL/examples/omp/c_md.c@ d4a23c3

1.23 2.0 acw/focus-triggers main test-branch
Last change on this file since d4a23c3 was feadd65, checked in by Matthew B. Dwyer <matthewbdwyer@…>, 11 years ago

git-svn-id: svn://vsl.cis.udel.edu/civl/trunk@1929 fb995dde-84ed-4084-dfe6-e5aef3e2452c

  • Property mode set to 100644
File size: 9.2 KB
Line 
1/* ***********************************************************************
2 This program is part of the
3 OpenMP Source Code Repository
4
5 http://www.pcg.ull.es/ompscr/
6 e-mail: ompscr@etsii.ull.es
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 (LICENSE file) along with this program; if not, write to
20 the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
21 Boston, MA 02111-1307 USA
22
23 FILE: c_md.c
24 VERSION: 1.0
25 DATE: May 2004
26 AUTHOR: Bill Magro, Kuck and Associates, Inc. (KAI), 1998
27 COMMENTS TO: sande@csi.ull.es
28 DESCRIPTION: This program implements a simple molecular dynamics simulation,
29 using the velocity Verlet time integration scheme.
30 The particles interact with a central pair potential.
31 COMMENTS:
32 REFERENCES: W. C. Swope and H. C. Andersen and P. H. Berens and K. R. Wilson
33 A Computer Simulation Method for the Calculation of
34 Equilibrium Constants for the Formation of Physical
35 Clusters of Molecules: Application to Small Water Clusters
36 Journal of Chemical Physics, 1982 vol. 76 pg 637-649
37 BASIC PRAGMAS: parallel for
38 USAGE: ./c_md.par 8192 10
39 INPUT: Number of particles
40 Number of simulation steps
41 OUTPUT: -
42 FILE FORMATS: -
43 RESTRICTIONS: -
44 REVISION HISTORY:
45**************************************************************************/
46//#include "OmpSCR.h"
47#include <math.h>
48#include <omp.h>
49#ifndef RAND_MAX
50#define RAND_MAX 0x7fff
51#endif
52
53#ifndef M_PI_2
54#define M_PI_2 1.57079632679489661923 /* pi/2 */
55#endif
56
57#define NUM_ARGS 2
58#define NUM_TIMERS 1
59#define DEFAULT_NPARTS 8192
60#define DEFAULT_NSTEPS 10
61#define USAGE_STR "NPARTS NSTEPS"
62#define NDIM 3
63
64#define NPARTSINIT 10
65#define NSTEPSINIT 4
66
67int NPARTS; /* No. of particles */
68int NSTEPS; /* No. of simulation steps */
69
70typedef double vnd_t[NDIM];
71
72/* -----------------------------------------------------------------------
73 PROTOTYPES
74 * ----------------------------------------------------------------------- */
75
76double v(double x);
77double dv(double x);
78void initialize(int np, int nd, vnd_t box, vnd_t *pos, vnd_t *vel, vnd_t *acc);
79double dist(int nd, vnd_t r1, vnd_t r2, vnd_t dr);
80double dot_prod(int n, vnd_t x,vnd_t y);
81void compute(int np, int nd, vnd_t *pos, vnd_t *vel, double mass, vnd_t *f, double *pot_p, double *kin_p);
82void update(int np, int nd, vnd_t *pos, vnd_t *vel, vnd_t *f, vnd_t *a, double mass, double dt);
83int main (int argc, char **argv);
84
85/* -----------------------------------------------------------------------
86 IMPLEMENTATION
87 * ----------------------------------------------------------------------- */
88/* -----------------------------------------------------------------------
89 statement function for the pair potential.
90 This potential is a harmonic well which smoothly saturates to a
91 maximum value at PI/2.
92 * ----------------------------------------------------------------------- */
93double v(double x) {
94 if (x < M_PI_2)
95 return pow(sin(x), 2.0);
96 else
97 return 1.0;
98}
99/* -----------------------------------------------------------------------
100 statement function for the derivative of the pair potential
101 * ----------------------------------------------------------------------- */
102double dv(double x) {
103 if (x < M_PI_2)
104 return 2.0 * sin(x) * cos(x);
105 else
106 return 0.0;
107}
108/* -----------------------------------------------------------------------
109 Initialize the positions, velocities, and accelerations.
110 * ----------------------------------------------------------------------- */
111void initialize(int np, int nd, vnd_t box, vnd_t *pos, vnd_t *vel, vnd_t *acc) {
112 int i, j;
113 double x;
114
115 //srand(4711L);
116 int r = 42; // REPLACE RANDOM NUMBER GENERATION
117 for (i = 0; i < np; i++) {
118 for (j = 0; j < nd; j++) {
119 x = (r++) % 10000 / (double)10000.0;
120 pos[i][j] = box[j] * x;
121 vel[i][j] = 0.0;
122 acc[i][j] = 0.0;
123 }
124 }
125}
126/* -----------------------------------------------------------------------
127 Compute the displacement vector (and its norm) between two particles.
128 * ----------------------------------------------------------------------- */
129double dist(int nd, vnd_t r1, vnd_t r2, vnd_t dr) {
130 int i;
131 double d;
132
133 d = 0.0;
134 for (i = 0; i < nd; i++) {
135 dr[i] = r1[i] - r2[i];
136 d += dr[i] * dr[i];
137 }
138 return sqrt(d);
139}
140/* -----------------------------------------------------------------------
141 Return the dot product between two vectors of type double and length n
142 * ----------------------------------------------------------------------- */
143double dot_prod(int n, vnd_t x, vnd_t y) {
144 int i;
145 double t = 0.0;
146
147 for (i = 0; i < n; i++) {
148 t += x[i] * y[i];
149 }
150 return t;
151}
152/* -----------------------------------------------------------------------
153 Compute the forces and energies, given positions, masses,
154 and velocities
155 * ----------------------------------------------------------------------- */
156void compute(int np, int nd, vnd_t *pos, vnd_t *vel,
157 double mass, vnd_t *f, double *pot_p, double *kin_p) {
158 int i, j, k;
159 vnd_t rij;
160 double d;
161 double pot, kin;
162
163 pot = 0.0;
164 kin = 0.0;
165 /* The computation of forces and energies is fully parallel. */
166#pragma omp parallel for default(shared) private(i, j, k, rij, d) reduction(+ : pot, kin)
167 for (i = 0; i < np; i++) {
168 /* compute potential energy and forces */
169 for (j = 0; j < nd; j++)
170 f[i][j] = 0.0;
171 for (j = 0; j < np; j++) {
172 if (i != j) {
173 d = dist(nd, pos[i], pos[j], rij);
174 /* attribute half of the potential energy to particle 'j' */
175 pot = pot + 0.5 * v(d);
176 for (k = 0; k < nd; k++) {
177 f[i][k] = f[i][k] - rij[k]* dv(d) /d;
178 }
179 }
180 }
181 /* compute kinetic energy */
182 kin = kin + dot_prod(nd, vel[i], vel[j]);
183 }
184 kin = kin * 0.5 * mass;
185 *pot_p = pot;
186 *kin_p = kin;
187}
188/* -----------------------------------------------------------------------
189 Perform the time integration, using a velocity Verlet algorithm
190 * ----------------------------------------------------------------------- */
191void update(int np, int nd, vnd_t *pos, vnd_t *vel, vnd_t *f, vnd_t *a, double mass, double dt) {
192 int i, j;
193 double rmass;
194
195 rmass = 1.0/mass;
196 /* The time integration is fully parallel */
197#pragma omp parallel for default(shared) private(i, j) firstprivate(rmass, dt)
198 for (i = 0; i < np; i++) {
199 for (j = 0; j < nd; j++) {
200 pos[i][j] = pos[i][j] + vel[i][j]*dt + 0.5*dt*dt*a[i][j];
201 vel[i][j] = vel[i][j] + 0.5*dt*(f[i][j]*rmass + a[i][j]);
202 a[i][j] = f[i][j]*rmass;
203 }
204 }
205}
206/* ----------------------------------------------------------------------- */
207int main (int argc, char **argv) {
208 /* simulation parameters */
209 double mass = 1.0;
210 double dt = 1.0e-4;
211 vnd_t box;
212 vnd_t *position;
213 vnd_t *velocity;
214 vnd_t *force;
215 vnd_t *accel;
216 double potential, kinetic, E0;
217 int i;
218 int NUMTHREADS;
219 double total_time;
220 char *PARAM_NAMES[NUM_ARGS] = {"Nparts", "Nsteps"};
221 char *TIMERS_NAMES[NUM_TIMERS] = {"Total_time" };
222 char *DEFAULT_VALUES[NUM_ARGS] = {"8192", "10"};
223
224
225 NUMTHREADS = omp_get_num_threads();
226 //OSCR_init (NUMTHREADS, "Molecular dynamic simulation", "Use md <Nparts> <Nsteps>", NUM_ARGS,
227 // PARAM_NAMES, DEFAULT_VALUES , NUM_TIMERS, NUM_TIMERS, TIMERS_NAMES,
228 //argc, argv);
229
230
231 NPARTS = NPARTSINIT; //OSCR_getarg_int(1);
232 NSTEPS = NSTEPSINIT; //OSCR_getarg_int(2);
233 /* Default: DEFAULT_NPARTS, DEFAULT_NSTEPS */
234
235 /* Memory allocation */
236 position = calloc(NPARTS, sizeof(vnd_t));
237 velocity = calloc(NPARTS, sizeof(vnd_t));
238 force = calloc(NPARTS, sizeof(vnd_t));
239 accel = calloc(NPARTS, sizeof(vnd_t));
240
241 NUMTHREADS = omp_get_num_threads();
242 for (i = 0; i < NDIM; i++)
243 box[i] = 10.0;
244 /* set initial positions, velocities, and accelerations */
245 initialize(NPARTS, NDIM, box, position, velocity, accel);
246 //OSCR_timer_start(0);
247 /* compute the forces and energies */
248 compute(NPARTS, NDIM, position, velocity, mass, force, &potential, &kinetic);
249 E0 = potential + kinetic;
250 /* This is the main time stepping loop */
251 for (i = 0; i < NSTEPS; i++) {
252 compute(NPARTS, NDIM, position, velocity, mass, force, &potential, &kinetic);
253#if 0
254 printf("%17.9e %17.9e %17.9e\n", potential, kinetic, (potential + kinetic - E0) / E0);
255#endif
256 update(NPARTS, NDIM, position, velocity, force, accel, mass, dt);
257 }
258 //OSCR_timer_stop(0);
259 total_time = 1; //OSCR_timer_read(0);
260 //OSCR_report(1, TIMERS_NAMES);
261 printf("\n \t# THREADS \tTIME (secs.) \n");
262 printf("\t %d \t\t%14.6lf\n", NUMTHREADS, total_time);
263
264 return 0;
265}
266
267
268/*
269 * vim:ts=2:sw=2:
270 */
Note: See TracBrowser for help on using the repository browser.