Skip to content

Commit 570cbc8

Browse files
committed
first SDC run works
1 parent f5decfc commit 570cbc8

File tree

4 files changed

+176
-47
lines changed

4 files changed

+176
-47
lines changed
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
from petsc4py import PETSc
2+
3+
from pySDC.core.Errors import DataError
4+
5+
6+
class petsc_vec(PETSc.Vec):
7+
__array_priority__ = 1000 # otherwise rmul with float64 does not work (don't ask, won't tell)
8+
9+
def __new__(cls, init=None, val=0.0):
10+
if isinstance(init, petsc_vec) or isinstance(init, PETSc.Vec):
11+
obj = PETSc.Vec().__new__(cls)
12+
init.copy(obj)
13+
elif isinstance(init, PETSc.DMDA):
14+
tmp = init.createGlobalVector()
15+
obj = petsc_vec(tmp)
16+
objarr = init.getVecArray(obj)
17+
objarr[:] = val
18+
else:
19+
obj = PETSc.Vec().__new__(cls)
20+
return obj
21+
22+
def __abs__(self):
23+
"""
24+
Overloading the abs operator
25+
26+
Returns:
27+
float: absolute maximum of all vec values
28+
"""
29+
# take absolute values of the mesh values (INF = 3)
30+
return self.norm(3)
31+
32+
def isend(self, dest=None, tag=None, comm=None):
33+
"""
34+
Routine for sending data forward in time (non-blocking)
35+
36+
Args:
37+
dest (int): target rank
38+
tag (int): communication tag
39+
comm: communicator
40+
41+
Returns:
42+
request handle
43+
"""
44+
return comm.Issend(self[:], dest=dest, tag=tag)
45+
46+
def irecv(self, source=None, tag=None, comm=None):
47+
"""
48+
Routine for receiving in time
49+
50+
Args:
51+
source (int): source rank
52+
tag (int): communication tag
53+
comm: communicator
54+
55+
Returns:
56+
None
57+
"""
58+
return comm.Irecv(self[:], source=source, tag=tag)
59+
60+
def bcast(self, root=None, comm=None):
61+
"""
62+
Routine for broadcasting values
63+
64+
Args:
65+
root (int): process with value to broadcast
66+
comm: communicator
67+
68+
Returns:
69+
broadcasted values
70+
"""
71+
comm.Bcast(self[:], root=root)
72+
return self
73+
74+
75+
class petsc_vec_imex(object):
76+
"""
77+
RHS data type for Vec with implicit and explicit components
78+
79+
This data type can be used to have RHS with 2 components (here implicit and explicit)
80+
81+
Attributes:
82+
impl (petsc_vec): implicit part
83+
expl (petsc_vec): explicit part
84+
"""
85+
86+
def __init__(self, init, val=0.0):
87+
"""
88+
Initialization routine
89+
90+
Args:
91+
init: can either be a tuple (one int per dimension) or a number (if only one dimension is requested)
92+
or another imex_mesh object
93+
val (float): an initial number (default: 0.0)
94+
Raises:
95+
DataError: if init is none of the types above
96+
"""
97+
98+
if isinstance(init, type(self)):
99+
self.impl = petsc_vec(init.impl)
100+
self.expl = petsc_vec(init.expl)
101+
elif isinstance(init, PETSc.DMDA):
102+
self.impl = petsc_vec(init, val=val)
103+
self.expl = petsc_vec(init, val=val)
104+
# something is wrong, if none of the ones above hit
105+
else:
106+
raise DataError('something went wrong during %s initialization' % type(self))

pySDC/implementations/problem_classes/HeatEquation_2D_PETSc_forced.py

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
from pySDC.core.Errors import ParameterError, ProblemError
55
from pySDC.core.Problem import ptype
6-
from pySDC.implementations.datatype_classes.petsc_dmda_grid import petsc_data, rhs_imex_petsc_data
6+
from pySDC.implementations.datatype_classes.petsc_vec import petsc_vec, petsc_vec_imex
77

88

99
# noinspection PyUnusedLocal
@@ -20,7 +20,7 @@ class heat2d_petsc_forced(ptype):
2020
ksp: PETSc linear solver object
2121
"""
2222

23-
def __init__(self, problem_params, dtype_u=petsc_data, dtype_f=rhs_imex_petsc_data):
23+
def __init__(self, problem_params, dtype_u=petsc_vec, dtype_f=petsc_vec_imex):
2424
"""
2525
Initialization routine
2626
@@ -165,10 +165,10 @@ def eval_f(self, u, t):
165165

166166
f = self.dtype_f(self.init)
167167
# evaluate Au for implicit part
168-
self.A.mult(u.values, f.impl.values)
168+
self.A.mult(u, f.impl)
169169

170170
# evaluate forcing term for explicit part
171-
fa = self.init.getVecArray(f.expl.values)
171+
fa = self.init.getVecArray(f.expl)
172172
xv, yv = np.meshgrid(range(self.xs, self.xe), range(self.ys, self.ye), indexing='ij')
173173
fa[self.xs:self.xe, self.ys:self.ye] = -np.sin(np.pi * self.params.freq * xv * self.dx) * \
174174
np.sin(np.pi * self.params.freq * yv * self.dy) * \
@@ -192,10 +192,9 @@ def solve_system(self, rhs, factor, u0, t):
192192

193193
me = self.dtype_u(u0)
194194
self.ksp.setOperators(self.Id - factor * self.A)
195-
self.ksp.solve(rhs.values, me.values)
195+
self.ksp.solve(rhs, me)
196196
self.ksp_ncalls += 1
197197
self.ksp_itercount += int(self.ksp.getIterationNumber())
198-
199198
return me
200199

201200
def u_exact(self, t):
@@ -210,7 +209,7 @@ def u_exact(self, t):
210209
"""
211210

212211
me = self.dtype_u(self.init)
213-
xa = self.init.getVecArray(me.values)
212+
xa = self.init.getVecArray(me)
214213
for i in range(self.xs, self.xe):
215214
for j in range(self.ys, self.ye):
216215
xa[i, j] = np.sin(np.pi * self.params.freq * i * self.dx) * \

pySDC/playgrounds/other/petsc_datatype.py

Lines changed: 63 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,39 @@
11
from petsc4py import PETSc
2-
2+
import numpy as np
33

44
class mymesh(PETSc.Vec):
5-
5+
__array_priority__ = 1000
66
def __new__(cls, init=None, val=0.0):
7-
if isinstance(init, mymesh):
7+
if isinstance(init, mymesh) or isinstance(init, PETSc.Vec):
88
obj = PETSc.Vec().__new__(cls)
99
init.copy(obj)
10-
# obj.
11-
# obj[:] = init[:]
12-
# obj.part1 = obj[0, :]
13-
# obj.part2 = obj[1, :]
14-
elif isinstance(init, tuple):
15-
obj = PETSc.Vec().__new__(cls)
16-
obj.createMPI(size=init[0], comm=init[1])
17-
objarr = obj.getArray()
10+
elif isinstance(init, PETSc.DMDA):
11+
tmp = init.createGlobalVector()
12+
obj = mymesh(tmp)
13+
objarr = init.getVecArray(obj)
1814
objarr[:] = val
1915
else:
2016
obj = PETSc.Vec().__new__(cls)
2117
return obj
2218

19+
# def __rmul__(self, other):
20+
# print('here')
21+
# tmp = self.getArray()
22+
# tmp[:] *= other
23+
# return self
24+
25+
def __abs__(self):
26+
"""
27+
Overloading the abs operator
28+
29+
Returns:
30+
float: absolute maximum of all mesh values
31+
"""
32+
# take absolute values of the mesh values
33+
# print(self.norm(3))
34+
return self.norm(3)
35+
36+
2337
# def __array_finalize__(self, obj):
2438
# """
2539
# Finalizing the datatype. Without this, new datatypes do not 'inherit' the communicator.
@@ -29,39 +43,49 @@ def __new__(cls, init=None, val=0.0):
2943
# self.part1 = getattr(obj, 'part1', None)
3044
# self.part2 = getattr(obj, 'part2', None)
3145

32-
u = mymesh((10, PETSc.COMM_WORLD), val=9)
33-
uarr = u.getArray()
34-
# uarr[:] = 1
35-
print(uarr, u.getOwnershipRange())
46+
47+
# u = mymesh((16, PETSc.COMM_WORLD), val=9)
48+
# uarr = u.getArray()
49+
# # uarr[:] = np.random.rand(4,4)
50+
# print(uarr, u.getOwnershipRanges())
51+
# v = mymesh(u)
52+
# varr = v.getArray()
53+
# print(varr, v.getOwnershipRange() )
54+
# if v.comm.getRank() == 0:
55+
# uarr[0] = 7
56+
#
57+
# print(uarr)
58+
# print(varr)
59+
#
60+
# w = u + v
61+
# warr = w.getArray()
62+
# print(warr, w.getOwnershipRange())
63+
64+
da = PETSc.DMDA().create([4, 4], stencil_width=1)
65+
66+
u = mymesh(da, val=9.0)
67+
uarr = da.getVecArray(u)
68+
3669
v = mymesh(u)
37-
varr = v.getArray()
38-
print(varr, v.getOwnershipRange() )
70+
varr = da.getVecArray(v)
3971
if v.comm.getRank() == 0:
40-
uarr[0] = 7
72+
uarr[0, 0] = 7
73+
print(uarr[:], uarr.shape, type(u))
74+
print(varr[:], v.getOwnershipRange(), type(v))
4175

42-
print(uarr)
43-
print(varr)
76+
w = np.float(1.0) * (u + v)
77+
warr = da.getVecArray(w)
78+
print(warr[:], da.getRanges(), type(w))
4479

45-
w = u + v
46-
warr = w.getArray()
47-
print(warr, w.getOwnershipRange())
48-
exit()
80+
print(w.norm(3))
81+
print(abs(w))
4982

83+
# v = PETSc.Vec().createMPI(16)
84+
# varr = v.getArray()
85+
# varr[:] = 9.0
86+
# a = np.float64(1.0) * v
87+
# print(type(a))
5088

51-
m = mymesh((10, np.dtype('float64')))
52-
m.part1[:] = 1
53-
m.part2[:] = 2
54-
print(m.part1, m.part2)
55-
print(m)
56-
print()
5789

58-
n = mymesh(m)
59-
n.part1[0] = 10
60-
print(n.part1, n.part2)
61-
print(n)
62-
print()
90+
exit()
6391

64-
print(o.part1, o.part2)
65-
print(o)
66-
print()
67-
# print(n + m)

pySDC/tutorial/step_7/C_pySDC_with_PETSc.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ def main():
5656
problem_params['nu'] = 1.0 # diffusion coefficient
5757
problem_params['freq'] = 2 # frequency for the test value
5858
problem_params['cnvars'] = [(65, 65)] # number of degrees of freedom for the coarsest level
59-
problem_params['refine'] = [1, 0] # number of refinements
59+
problem_params['refine'] = [1] # number of refinements
6060
problem_params['comm'] = space_comm # pass space-communicator to problem class
6161
problem_params['sol_tol'] = 1E-12 # set tolerance to PETSc' linear solver
6262

0 commit comments

Comments
 (0)