Imported Upstream version 4.6.0
[debian/atlc] / tests / MPI_16a_PI.c
1 /*
2 atlc - arbitrary transmission line calculator, for the analysis of
3 transmission lines are directional couplers. 
4
5 Copyright (C) 2002. Dr. David Kirkby, PhD (G8WRB).
6
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License
9 as published by the Free Software Foundation; either package_version 2
10 of the License, or (at your option) any later package_version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
20 USA.
21
22 Dr. David Kirkby, e-mail drkirkby@ntlworld.com 
23
24 */
25
26 #include "config.h"
27
28 #ifdef ENABLE_MPI
29 #include <mpi.h>
30 #endif
31
32 #include <stdio.h>
33 #include <math.h>
34
35 #ifdef ENABLE_MPI
36 double f(double);
37
38 double f(double a)
39 {
40     return (4.0 / (1.0 + a*a));
41 }
42 #endif
43
44 int main(int argc,char *argv[])
45 {
46 #ifdef ENABLE_MPI
47     int done = 0, n, myid, numprocs, i;
48     double PI25DT = 3.141592653589793238462643;
49     double mypi, pi, h, sum, x;
50     double startwtime = 0.0, endwtime;
51     int  namelen;
52     char processor_name[MPI_MAX_PROCESSOR_NAME];
53
54     MPI_Init(&argc,&argv);
55     MPI_Comm_size(MPI_COMM_WORLD,&numprocs);
56     MPI_Comm_rank(MPI_COMM_WORLD,&myid);
57     MPI_Get_processor_name(processor_name,&namelen);
58
59
60     n = 0;
61     while (!done)
62     {
63         if (myid == 0)
64         {
65 /*
66             printf("Enter the number of intervals: (0 quits) ");
67             scanf("%d",&n);
68 */
69             if (n==0) n=10000; else n=0;
70
71             startwtime = MPI_Wtime();
72         }
73         MPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD);
74         if (n == 0)
75             done = 1;
76         else
77         {
78             h   = 1.0 / (double) n;
79             sum = 0.0;
80             /* A slightly better approach starts from large i and works back */
81             for (i = myid + 1; i <= n; i += numprocs)
82             {
83                 x = h * ((double)i - 0.5);
84                 sum += f(x);
85             }
86             mypi = h * sum;
87
88             MPI_Reduce(&mypi, &pi, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
89
90             if (myid == 0)
91             {
92                 /* printf("pi is approximately %.16f, Error is %.16f\n",
93                        pi, fabs(pi - PI25DT)); */
94                 if (fabs(pi - PI25DT) > 0.00000001 )
95                 {
96                   MPI_Finalize();
97                   return 1;
98                 }
99                 endwtime = MPI_Wtime();
100                 //printf("wall clock time = %f\n", endwtime-startwtime);               
101                 fflush( stdout );
102             }
103         }
104     }
105     MPI_Finalize();
106     return 0;
107 #endif
108     return 77;
109 }