download the original source code.
1 """Example of using hypre through the Babel-Python interface"""
2
3 # To build, do the following
4 # 1. Install Python 2.4 or later.
5 # 2. Install a version of Numeric Python as required by Babel.
6 # 3. Install pyMPI. Probably this could be made to work with other MPI extensions of Python
7 # with minor changes in this example; but I haven't tried anything else.
8 # 4. configure --enable-shared --with-babel --enable-python=pyMPI
9 # If you have trouble with missing stdc++ functions, also use --without-fei
10 # 5. make
11 # 6. Make sure you have the following environment variables:
12 # SIDL_DLL_PATH={your top-level hypre directory}/babel/bHYPREClient-P/libbHYPRE.scl
13 # LD_LIBRARY_PATH={your top-level hypre directory}/hypre/lib
14
15 import mpi,sys
16 import bHYPRE
17 import bHYPRE.MPICommunicator
18 # It is important to import bHYPRE.MPICommunicator first. The other classes
19 # require it, so the build system assumes you will have loaded it first.
20 import bHYPRE.IJParCSRMatrix
21 import bHYPRE.IJParCSRVector
22 import bHYPRE.BoomerAMG
23 import bHYPRE.PCG
24 import bHYPRE.IdentitySolver
25 from array import *
26 from struct import *
27 from Numeric import *
28
29 def solver( solver_id=0 ):
30 # solver_id values : 0(default, AMG), 1 (PCG-AMG), 8 (ParaSails), 50 (PCG)
31 #
32 myid = mpi.COMM_WORLD.rank
33 num_procs = mpi.COMM_WORLD.size
34 #>>>> doesn't work, but should ...mpi_comm = bHYPRE.MPICommunicator.CreateC( mpi.COMM_WORLD )
35 #>>>> temporary substitute>>>
36 mpi_comm = bHYPRE.MPICommunicator.Create_MPICommWorld()
37 #
38 # for now, don't bother to read any inputs
39 #
40 n = 33
41 print_solution = 0
42 #
43 # Preliminaries: want at least one processor per row
44 if n*n < num_procs :
45 n = int( num_procs**0.5 ) + 1
46 N = n*n # global number of rows
47 h = 1.0/(n+1) # mesh size
48 h2 = h*h
49 #
50 # Each processor knows only of its own rows - the range is denoted by ilower
51 # and upper. Here we partition the rows. We account for the fact that
52 # N may not divide evenly by the number of processors.
53 local_size = N/num_procs
54 extra = N - local_size*num_procs
55 #
56 ilower = local_size*myid
57 ilower += min(myid, extra)
58 #
59 iupper = local_size*(myid+1)
60 iupper += min(myid+1, extra)
61 iupper = iupper - 1
62 #
63 # How many rows do I have?
64 local_size = iupper - ilower + 1
65 #
66 # Create the matrix.
67 # Note that this is a square matrix, so we indicate the row partition
68 # size twice (since number of rows = number of cols)
69 parcsr_A = bHYPRE.IJParCSRMatrix.Create( mpi_comm, ilower, iupper, ilower, iupper )
70 #
71 # Choose a parallel csr format storage (see the User's Manual)
72 # Note: Here the HYPRE interface requires a SetObjectType call.
73 # I am using the bHYPRE interface in a way which does not because
74 # the object type is already specified through the class name.
75 #
76 # Initialize before setting coefficients
77 parcsr_A.Initialize()
78 #
79 # Now go through my local rows and set the matrix entries.
80 # Each row has at most 5 entries. For example, if n=3:
81 #
82 # A = [M -I 0; -I M -I; 0 -I M]
83 # M = [4 -1 0; -1 4 -1; 0 -1 4]
84 #
85 # Note that here we are setting one row at a time, though
86 # one could set all the rows together (see the User's Manual).
87 values = zeros(5)
88 cols = zeros(5)
89 i = ilower
90 while i<=iupper:
91 nnz = 0
92 # The left identity block: position i-n
93 if (i-n) >= 0 :
94 cols[nnz] = i-n
95 values[nnz] = -1.0
96 nnz = nnz + 1
97 # The left -1: position i-1
98 if (i%n):
99 cols[nnz] = i-1
100 values[nnz] = -1.0
101 nnz = nnz + 1
102 # Set the diagonal: position i
103 cols[nnz] = i
104 values[nnz] = 4.0
105 nnz = nnz + 1
106 # The right -1: position i+1
107 if ((i+1)%n):
108 cols[nnz] = i+1
109 values[nnz] = -1.0
110 nnz = nnz + 1
111 # The right identity block:position i+n
112 if (i+n) < N:
113 cols[nnz] = i+n
114 values[nnz] = -1.0
115 nnz = nnz + 1
116 # Set the values for row i
117 parcsr_A.SetValues( array([nnz]), array([i]), cols, values )
118 i = i + 1
119 #
120 # Assemble after setting the coefficients
121 parcsr_A.Assemble()
122 #
123 # Create the rhs and solution
124 par_b = bHYPRE.IJParCSRVector.Create( mpi_comm, ilower, iupper )
125 par_b.Initialize()
126 par_x = bHYPRE.IJParCSRVector.Create( mpi_comm, ilower, iupper )
127 par_x.Initialize()
128 #
129 # Set the rhs values to h^2 and the solution to zero
130 rhs_values = zeros(local_size)*1.1
131 x_values = zeros(local_size)*1.1
132 rows = zeros(local_size)
133 i = 0
134 while i<local_size:
135 rhs_values[i] = h2
136 rows[i] = ilower + i
137 i = i + 1
138 par_b.SetValues( rows, rhs_values )
139 par_x.SetValues( rows, x_values )
140 #
141 par_b.Assemble()
142 par_x.Assemble()
143 #
144 # Choose a solver and solve the system
145 #
146 # AMG
147 if solver_id == 0:
148 # Create solver
149 solver = bHYPRE.BoomerAMG.Create( mpi_comm, parcsr_A )
150 # Set some parameters (See Reference Manual for more parameters)
151 solver.SetIntParameter( "PrintLevel", 3 ) # print solve info + parameters
152 solver.SetIntParameter( "CoarsenType", 6 ) # Falgout coarsening
153 solver.SetIntParameter( "RelaxType", 3 ) # G-S/Jacobi hybrid relaxation
154 solver.SetIntParameter( "NumSweeps", 1 ) # Sweeeps on each level
155 solver.SetIntParameter( "MaxLevels", 20 ) # maximum number of levels
156 solver.SetDoubleParameter( "Tolerance", 1e-7 ) # conv. tolerance
157 #
158 # Now setup and solve!
159 solver.Setup( par_b, par_x )
160 solver.Apply( par_b, par_x )
161 #
162 # Run info - needed logging turned on
163 # The 0-th return value of Get*Value is the error flag.
164 num_iterations = solver.GetIntValue( "NumIterations" )[1]
165 final_res_norm = solver.GetDoubleValue( "RelResidualNorm" )[1]
166 #
167 if myid == 0:
168 print "Iterations = ", num_iterations
169 print "Final Relative Residual Norm = ", final_res_norm
170 elif solver_id == 50:
171 # Create solver
172 solver = bHYPRE.PCG.Create( mpi_comm, parcsr_A )
173 # Set some parameters (See Reference Manual for more parameters)
174 solver.SetIntParameter( "MaxIter", 1000 ) # max iterations
175 solver.SetDoubleParameter( "Tolerance", 1e-7 ) # conv. tolerance
176 solver.SetIntParameter( "TwoNorm", 1 ) # use the two norm as the stopping criteria
177 solver.SetIntParameter( "PrintLevel", 2 ) # prints out the iteration info
178 solver.SetIntParameter( "Logging", 1 ) # needed to get run info later
179 #
180 precond = bHYPRE.IdentitySolver.Create( mpi_comm )
181 solver.SetPreconditioner( precond )
182 #
183 # Now setup and solve!
184 solver.Setup( par_b, par_x )
185 solver.Apply( par_b, par_x )
186 #
187 # Run info - needed logging turned on
188 # The 0-th return value of Get*Value is the error flag.
189 num_iterations = solver.GetIntValue( "NumIterations" )[1]
190 final_res_norm = solver.GetDoubleValue( "RelResidualNorm" )[1]
191 #
192 if myid == 0:
193 print "Iterations = ", num_iterations
194 print "Final Relative Residual Norm =", final_res_norm
195 else:
196 print "Solver ", solver_id, " is not supported."
197 #
198 if __name__ == "__main__":
199 solver(0)
syntax highlighted by Code2HTML, v. 0.9.1