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

1.23 2.0 acw/focus-triggers main test-branch
Last change on this file since c5d1621 was 60ba8f2, checked in by Stephen Siegel <siegel@…>, 12 years ago

Experimental performance improvement: taking advantages of SARL's new "substituter" method to get a repeatable substituter which caches its results. Using it now to cache results of renumbering the dyscopes. This is in the state module. Could use in many other cases too. Seems to save a little bit of time.

Added missing library includes in the new example c_md.c.

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

  • Property mode set to 100644
File size: 9.3 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
50// following added by sfsiegel due to use of "calloc":
51#include <stdlib.h>
52// following added by sfsiegel due to use of "printf":
53#include <stdio.h>
54
55#ifndef RAND_MAX
56#define RAND_MAX 0x7fff
57#endif
58
59#ifndef M_PI_2
60#define M_PI_2 1.57079632679489661923 /* pi/2 */
61#endif
62
63#define NUM_ARGS 2
64#define NUM_TIMERS 1
65#define DEFAULT_NPARTS 8192
66#define DEFAULT_NSTEPS 10
67#define USAGE_STR "NPARTS NSTEPS"
68#define NDIM 3
69
70#define NPARTSINIT 10
71#define NSTEPSINIT 4
72
73int NPARTS; /* No. of particles */
74int NSTEPS; /* No. of simulation steps */
75
76typedef double vnd_t[NDIM];
77
78/* -----------------------------------------------------------------------
79 PROTOTYPES
80 * ----------------------------------------------------------------------- */
81
82double v(double x);
83double dv(double x);
84void initialize(int np, int nd, vnd_t box, vnd_t *pos, vnd_t *vel, vnd_t *acc);
85double dist(int nd, vnd_t r1, vnd_t r2, vnd_t dr);
86double dot_prod(int n, vnd_t x,vnd_t y);
87void compute(int np, int nd, vnd_t *pos, vnd_t *vel, double mass, vnd_t *f, double *pot_p, double *kin_p);
88void update(int np, int nd, vnd_t *pos, vnd_t *vel, vnd_t *f, vnd_t *a, double mass, double dt);
89int main (int argc, char **argv);
90
91/* -----------------------------------------------------------------------
92 IMPLEMENTATION
93 * ----------------------------------------------------------------------- */
94/* -----------------------------------------------------------------------
95 statement function for the pair potential.
96 This potential is a harmonic well which smoothly saturates to a
97 maximum value at PI/2.
98 * ----------------------------------------------------------------------- */
99double v(double x) {
100 if (x < M_PI_2)
101 return pow(sin(x), 2.0);
102 else
103 return 1.0;
104}
105/* -----------------------------------------------------------------------
106 statement function for the derivative of the pair potential
107 * ----------------------------------------------------------------------- */
108double dv(double x) {
109 if (x < M_PI_2)
110 return 2.0 * sin(x) * cos(x);
111 else
112 return 0.0;
113}
114/* -----------------------------------------------------------------------
115 Initialize the positions, velocities, and accelerations.
116 * ----------------------------------------------------------------------- */
117void initialize(int np, int nd, vnd_t box, vnd_t *pos, vnd_t *vel, vnd_t *acc) {
118 int i, j;
119 double x;
120
121 //srand(4711L);
122 int r = 42; // REPLACE RANDOM NUMBER GENERATION
123 for (i = 0; i < np; i++) {
124 for (j = 0; j < nd; j++) {
125 x = (r++) % 10000 / (double)10000.0;
126 pos[i][j] = box[j] * x;
127 vel[i][j] = 0.0;
128 acc[i][j] = 0.0;
129 }
130 }
131}
132/* -----------------------------------------------------------------------
133 Compute the displacement vector (and its norm) between two particles.
134 * ----------------------------------------------------------------------- */
135double dist(int nd, vnd_t r1, vnd_t r2, vnd_t dr) {
136 int i;
137 double d;
138
139 d = 0.0;
140 for (i = 0; i < nd; i++) {
141 dr[i] = r1[i] - r2[i];
142 d += dr[i] * dr[i];
143 }
144 return sqrt(d);
145}
146/* -----------------------------------------------------------------------
147 Return the dot product between two vectors of type double and length n
148 * ----------------------------------------------------------------------- */
149double dot_prod(int n, vnd_t x, vnd_t y) {
150 int i;
151 double t = 0.0;
152
153 for (i = 0; i < n; i++) {
154 t += x[i] * y[i];
155 }
156 return t;
157}
158/* -----------------------------------------------------------------------
159 Compute the forces and energies, given positions, masses,
160 and velocities
161 * ----------------------------------------------------------------------- */
162void compute(int np, int nd, vnd_t *pos, vnd_t *vel,
163 double mass, vnd_t *f, double *pot_p, double *kin_p) {
164 int i, j, k;
165 vnd_t rij;
166 double d;
167 double pot, kin;
168
169 pot = 0.0;
170 kin = 0.0;
171 /* The computation of forces and energies is fully parallel. */
172#pragma omp parallel for default(shared) private(i, j, k, rij, d) reduction(+ : pot, kin)
173 for (i = 0; i < np; i++) {
174 /* compute potential energy and forces */
175 for (j = 0; j < nd; j++)
176 f[i][j] = 0.0;
177 for (j = 0; j < np; j++) {
178 if (i != j) {
179 d = dist(nd, pos[i], pos[j], rij);
180 /* attribute half of the potential energy to particle 'j' */
181 pot = pot + 0.5 * v(d);
182 for (k = 0; k < nd; k++) {
183 f[i][k] = f[i][k] - rij[k]* dv(d) /d;
184 }
185 }
186 }
187 /* compute kinetic energy */
188 kin = kin + dot_prod(nd, vel[i], vel[j]);
189 }
190 kin = kin * 0.5 * mass;
191 *pot_p = pot;
192 *kin_p = kin;
193}
194/* -----------------------------------------------------------------------
195 Perform the time integration, using a velocity Verlet algorithm
196 * ----------------------------------------------------------------------- */
197void update(int np, int nd, vnd_t *pos, vnd_t *vel, vnd_t *f, vnd_t *a, double mass, double dt) {
198 int i, j;
199 double rmass;
200
201 rmass = 1.0/mass;
202 /* The time integration is fully parallel */
203#pragma omp parallel for default(shared) private(i, j) firstprivate(rmass, dt)
204 for (i = 0; i < np; i++) {
205 for (j = 0; j < nd; j++) {
206 pos[i][j] = pos[i][j] + vel[i][j]*dt + 0.5*dt*dt*a[i][j];
207 vel[i][j] = vel[i][j] + 0.5*dt*(f[i][j]*rmass + a[i][j]);
208 a[i][j] = f[i][j]*rmass;
209 }
210 }
211}
212/* ----------------------------------------------------------------------- */
213int main (int argc, char **argv) {
214 /* simulation parameters */
215 double mass = 1.0;
216 double dt = 1.0e-4;
217 vnd_t box;
218 vnd_t *position;
219 vnd_t *velocity;
220 vnd_t *force;
221 vnd_t *accel;
222 double potential, kinetic, E0;
223 int i;
224 int NUMTHREADS;
225 double total_time;
226 char *PARAM_NAMES[NUM_ARGS] = {"Nparts", "Nsteps"};
227 char *TIMERS_NAMES[NUM_TIMERS] = {"Total_time" };
228 char *DEFAULT_VALUES[NUM_ARGS] = {"8192", "10"};
229
230
231 NUMTHREADS = omp_get_num_threads();
232 //OSCR_init (NUMTHREADS, "Molecular dynamic simulation", "Use md <Nparts> <Nsteps>", NUM_ARGS,
233 // PARAM_NAMES, DEFAULT_VALUES , NUM_TIMERS, NUM_TIMERS, TIMERS_NAMES,
234 //argc, argv);
235
236
237 NPARTS = NPARTSINIT; //OSCR_getarg_int(1);
238 NSTEPS = NSTEPSINIT; //OSCR_getarg_int(2);
239 /* Default: DEFAULT_NPARTS, DEFAULT_NSTEPS */
240
241 /* Memory allocation */
242 position = calloc(NPARTS, sizeof(vnd_t));
243 velocity = calloc(NPARTS, sizeof(vnd_t));
244 force = calloc(NPARTS, sizeof(vnd_t));
245 accel = calloc(NPARTS, sizeof(vnd_t));
246
247 NUMTHREADS = omp_get_num_threads();
248 for (i = 0; i < NDIM; i++)
249 box[i] = 10.0;
250 /* set initial positions, velocities, and accelerations */
251 initialize(NPARTS, NDIM, box, position, velocity, accel);
252 //OSCR_timer_start(0);
253 /* compute the forces and energies */
254 compute(NPARTS, NDIM, position, velocity, mass, force, &potential, &kinetic);
255 E0 = potential + kinetic;
256 /* This is the main time stepping loop */
257 for (i = 0; i < NSTEPS; i++) {
258 compute(NPARTS, NDIM, position, velocity, mass, force, &potential, &kinetic);
259#if 0
260 printf("%17.9e %17.9e %17.9e\n", potential, kinetic, (potential + kinetic - E0) / E0);
261#endif
262 update(NPARTS, NDIM, position, velocity, force, accel, mass, dt);
263 }
264 //OSCR_timer_stop(0);
265 total_time = 1; //OSCR_timer_read(0);
266 //OSCR_report(1, TIMERS_NAMES);
267 printf("\n \t# THREADS \tTIME (secs.) \n");
268 printf("\t %d \t\t%14.6lf\n", NUMTHREADS, total_time);
269
270 return 0;
271}
272
273
274/*
275 * vim:ts=2:sw=2:
276 */
Note: See TracBrowser for help on using the repository browser.