1from petsc4py import PETSc 2import unittest 3 4# -------------------------------------------------------------------- 5 6 7class BaseTestVec: 8 COMM = None 9 TYPE = None 10 11 def setUp(self): 12 v = PETSc.Vec() 13 v.create(self.COMM) 14 v.setSizes(100) 15 v.setType(self.TYPE) 16 self.vec = v 17 18 def tearDown(self): 19 self.vec.destroy() 20 self.vec = None 21 PETSc.garbage_cleanup() 22 23 def testDuplicate(self): 24 self.vec.set(1) 25 vec = self.vec.duplicate() 26 self.assertFalse(self.vec.equal(vec)) 27 self.assertEqual(self.vec.sizes, vec.sizes) 28 del vec 29 30 def testCopy(self): 31 self.vec.set(1) 32 vec = self.vec.duplicate() 33 self.vec.copy(vec) 34 self.assertTrue(self.vec.equal(vec)) 35 del vec 36 37 def testDot(self): 38 self.vec.set(1) 39 d = self.vec.dot(self.vec) 40 self.assertAlmostEqual(abs(d), self.vec.getSize()) 41 self.vec.dotBegin(self.vec) 42 d = self.vec.dotEnd(self.vec) 43 self.assertAlmostEqual(abs(d), self.vec.getSize()) 44 45 def testNorm(self): 46 from math import sqrt 47 48 self.vec.set(1) 49 n1 = self.vec.norm(PETSc.NormType.NORM_1) 50 n2 = self.vec.norm(PETSc.NormType.NORM_2) 51 ni = self.vec.norm(PETSc.NormType.NORM_INFINITY) 52 self.assertAlmostEqual(n1, self.vec.getSize()) 53 self.assertAlmostEqual(n2, sqrt(self.vec.getSize())) 54 self.assertAlmostEqual(n2, self.vec.norm()) 55 self.assertAlmostEqual(ni, 1.0) 56 self.vec.normBegin(PETSc.NormType.NORM_1) 57 nn1 = self.vec.normEnd(PETSc.NormType.NORM_1) 58 self.assertAlmostEqual(nn1, n1) 59 self.vec.normBegin() 60 nn2 = self.vec.normEnd() 61 self.assertAlmostEqual(nn2, n2) 62 self.vec.normBegin(PETSc.NormType.NORM_INFINITY) 63 nni = self.vec.normEnd(PETSc.NormType.NORM_INFINITY) 64 self.assertAlmostEqual(nni, ni) 65 66 def testNormalize(self): 67 from math import sqrt 68 69 self.vec.set(1) 70 n2 = self.vec.normalize() 71 self.assertAlmostEqual(n2, sqrt(self.vec.getSize())) 72 self.assertAlmostEqual(1, self.vec.norm()) 73 74 def testSumMinMax(self): 75 self.vec.set(1) 76 self.assertEqual(self.vec.sum(), self.vec.getSize()) 77 self.vec.set(-7) 78 self.assertEqual(self.vec.min()[1], -7) 79 self.vec.set(10) 80 self.assertEqual(self.vec.max()[1], 10) 81 82 def testSwap(self): 83 v1 = self.vec 84 v2 = v1.duplicate() 85 v1.set(1) 86 v2.set(2) 87 v1.swap(v2) 88 idx, _ = self.vec.getOwnershipRange() 89 self.assertEqual(v1[idx], 2) 90 self.assertEqual(v2[idx], 1) 91 92 def testBsize(self): 93 self.vec.setBlockSize(1) 94 self.assertEqual(self.vec.getBlockSize(), 1) 95 self.vec.setBlockSize(1) 96 97 def testGetSetVals(self): 98 start, end = self.vec.getOwnershipRange() 99 self.vec[start] = -7 100 self.vec[end - 1] = -7 101 self.vec.assemble() 102 self.assertEqual(self.vec[start], -7) 103 self.assertEqual(self.vec[end - 1], -7) 104 for i in range(start, end): 105 self.vec[i] = i 106 self.vec.assemble() 107 values = [self.vec[i] for i in range(start, end)] 108 self.assertEqual(values, list(range(start, end))) 109 sz = self.vec.getSize() 110 self.assertEqual(self.vec.sum(), (sz - 1) / 2.0 * sz) 111 112 def testGetSetValsBlocked(self): 113 return 114 lsize, gsize = self.vec.getSizes() 115 start, end = self.vec.getOwnershipRange() 116 bsizes = list(range(1, lsize + 1)) 117 nblocks = list(range(1, lsize + 1)) 118 compat = [ 119 (bs, nb) 120 for bs in bsizes 121 if not (gsize % bs or lsize % bs) 122 for nb in nblocks 123 if bs * nb <= lsize 124 ] 125 for bsize, nblock in compat: 126 self.vec.setBlockSize(bsize) 127 bindex = [start // bsize + i for i in range(nblock)] 128 bvalue = [float(i) for i in range(nblock * bsize)] 129 self.vec.setValuesBlocked(bindex, bvalue) 130 self.vec.assemble() 131 index = [start + i for i in range(nblock * bsize)] 132 value = self.vec.getValues(index) 133 self.assertEqual(bvalue, list(value)) 134 135 def testGetSetArray(self): 136 self.vec.set(1) 137 arr0 = self.vec.getArray().copy() 138 self.assertEqual(arr0.sum(), self.vec.getLocalSize()) 139 arr0 = self.vec.getArray().copy() 140 self.vec.setRandom() 141 arr1 = self.vec.getArray().copy() 142 self.vec.setArray(arr1) 143 arr1 = self.vec.getArray().copy() 144 arr2 = self.vec.getArray().copy() 145 self.assertTrue((arr1 == arr2).all()) 146 import numpy 147 148 refs = self.vec.getRefCount() 149 arr3 = numpy.asarray(self.vec) 150 self.assertEqual(self.vec.getRefCount(), refs + 1) 151 self.assertTrue((arr1 == arr3).all()) 152 arr3[:] = 0 153 self.assertAlmostEqual(abs(self.vec.sum()), 0) 154 self.assertEqual(self.vec.max()[1], 0) 155 self.assertEqual(self.vec.min()[1], 0) 156 self.vec.set(1) 157 self.assertAlmostEqual(abs(arr3.sum()), self.vec.getLocalSize()) 158 self.assertEqual(arr3.min(), 1) 159 self.assertEqual(arr3.max(), 1) 160 del arr3 161 self.assertEqual(self.vec.getRefCount(), refs) 162 163 def testPlaceArray(self): 164 self.vec.set(1) 165 array = self.vec.getArray().copy() 166 self.vec.placeArray(array) 167 array[:] = 2 168 self.assertAlmostEqual(abs(self.vec.sum()), 2 * self.vec.getSize()) 169 self.vec.resetArray() 170 self.assertAlmostEqual(abs(self.vec.sum()), self.vec.getSize()) 171 172 def testLocalVector(self): 173 rank = self.vec.getComm().Get_rank() 174 self.vec.getArray()[:] = rank + 1 175 ln = self.vec.getLocalSize() 176 lvec = self.vec.createLocalVector() 177 self.vec.getLocalVector(lvec) 178 self.assertEqual(abs(lvec.sum()), (rank + 1) * ln) 179 self.vec.restoreLocalVector(lvec) 180 self.vec.getLocalVector(lvec, readonly=True) 181 self.assertEqual(abs(lvec.sum()), (rank + 1) * ln) 182 self.vec.restoreLocalVector(lvec, readonly=True) 183 lvec.destroy() 184 185 def testSetOption(self): 186 opt1 = PETSc.Vec.Option.IGNORE_OFF_PROC_ENTRIES 187 opt2 = PETSc.Vec.Option.IGNORE_NEGATIVE_INDICES 188 for opt in [opt1, opt2] * 2: 189 for flag in [True, False] * 2: 190 self.vec.setOption(opt, flag) 191 192 def testGetSetItem(self): 193 v = self.vec 194 w = v.duplicate() 195 # 196 v[...] = 7 197 self.assertEqual(v.max()[1], 7) 198 self.assertEqual(v.min()[1], 7) 199 # 200 v.setRandom() 201 w[...] = v 202 self.assertTrue(w.equal(v)) 203 # 204 v.setRandom() 205 w[...] = v.getArray() 206 self.assertTrue(w.equal(v)) 207 # 208 s, e = v.getOwnershipRange() 209 v.setRandom() 210 w[s:e] = v.getArray().copy() 211 w.assemble() 212 self.assertTrue(w.equal(v)) 213 w1, v1 = w[s], v[s] 214 w2, v2 = w[e - 1], v[e - 1] 215 self.assertEqual(w1, v1) 216 self.assertEqual(w2, v2) 217 218 def testMAXPY(self): 219 y = self.vec 220 y.set(1) 221 x = [y.copy() for _ in range(3)] 222 a = [1] * len(x) 223 y.maxpy(a, x) 224 z = y.duplicate() 225 z.set(len(x) + 1) 226 self.assertTrue(y.equal(z)) 227 228 def testBinOp(self): 229 x = self.vec 230 x.set(1) 231 n = x.getSize() 232 y = 2 + 2 * x + 1 - x * 3 - 1 233 self.assertEqual(y.min()[1], 1) 234 self.assertEqual(y.max()[1], 1) 235 z = (4 * x) / (2 * y) 236 self.assertEqual(z.min()[1], 2) 237 self.assertEqual(z.max()[1], 2) 238 z = z / 2 239 self.assertEqual(z.min()[1], 1) 240 self.assertEqual(z.max()[1], 1) 241 s = (+x) @ (-y) 242 self.assertEqual(s, -n) 243 # 244 M, N = n, 2 * n 245 A = PETSc.Mat().createDense((M, N), comm=self.COMM) 246 A.setUp() 247 rs, re = A.getOwnershipRange() 248 cs, ce = A.getOwnershipRangeColumn() 249 a, b = 3, 5 250 for i in range(rs, re): 251 for j in range(N): 252 A[i, j] = a * i + b * j 253 A.assemble() 254 y = x @ A 255 self.assertEqual(y.getSize(), N) 256 for i in range(cs, ce): 257 self.assertEqual(y[i], a * M * (M - 1) / 2 + b * i * M) 258 y.set(1) 259 z = A @ y 260 self.assertEqual(z.getSize(), M) 261 for i in range(rs, re): 262 self.assertEqual(z[i], b * N * (N - 1) / 2 + a * i * N) 263 264 265# -------------------------------------------------------------------- 266 267 268class TestVecSeq(BaseTestVec, unittest.TestCase): 269 COMM = PETSc.COMM_SELF 270 TYPE = PETSc.Vec.Type.SEQ 271 272 273class TestVecMPI(BaseTestVec, unittest.TestCase): 274 COMM = PETSc.COMM_WORLD 275 TYPE = PETSc.Vec.Type.MPI 276 277 278class TestVecShared(BaseTestVec, unittest.TestCase): 279 if PETSc.COMM_WORLD.getSize() == 1: 280 TYPE = PETSc.Vec.Type.SHARED 281 else: 282 TYPE = PETSc.Vec.Type.MPI 283 COMM = PETSc.COMM_WORLD 284 285 286# class TestVecSieve(BaseTestVec, unittest.TestCase): 287# CLASS = PETSc.VecSieve 288# TARGS = ([],) 289 290# class TestVecGhost(BaseTestVec, unittest.TestCase): 291# CLASS = PETSc.VecGhost 292# TARGS = ([],) 293 294# -------------------------------------------------------------------- 295 296 297class TestVecWithArray(unittest.TestCase): 298 def testCreateSeq(self): 299 import numpy 300 301 a = numpy.zeros(5, dtype=PETSc.ScalarType) 302 303 v1 = PETSc.Vec().createWithArray(a, comm=PETSc.COMM_SELF) 304 v2 = PETSc.Vec().createWithArray(a, size=5, comm=PETSc.COMM_SELF) 305 v3 = PETSc.Vec().createWithArray(a, size=3, comm=PETSc.COMM_SELF) 306 307 self.assertTrue(v1.size == 5) 308 self.assertTrue(v2.size == 5) 309 self.assertTrue(v3.size == 3) 310 311 a1 = v1.getDict()['__array__'] 312 self.assertTrue(a is a1) 313 a2 = v2.getDict()['__array__'] 314 self.assertTrue(a is a2) 315 a3 = v3.getDict()['__array__'] 316 self.assertTrue(a is a3) 317 318 def testCreateMPI(self): 319 import numpy 320 321 a = numpy.zeros(5, dtype=PETSc.ScalarType) 322 323 v1 = PETSc.Vec().createWithArray(a, comm=PETSc.COMM_WORLD) 324 v2 = PETSc.Vec().createWithArray(a, size=(5, None), comm=PETSc.COMM_WORLD) 325 v3 = PETSc.Vec().createWithArray(a, size=(3, None), comm=PETSc.COMM_WORLD) 326 327 self.assertTrue(v1.local_size == 5) 328 self.assertTrue(v2.local_size == 5) 329 self.assertTrue(v3.local_size == 3) 330 331 a1 = v1.getDict()['__array__'] 332 self.assertTrue(a is a1) 333 a2 = v2.getDict()['__array__'] 334 self.assertTrue(a is a2) 335 a3 = v3.getDict()['__array__'] 336 self.assertTrue(a is a3) 337 338 def testSetMPIGhost(self): 339 import numpy 340 341 v = PETSc.Vec().create() 342 v.setType(PETSc.Vec.Type.MPI) 343 v.setSizes((5, None)) 344 ghosts = [i % v.size for i in range(v.owner_range[1], v.owner_range[1] + 3)] 345 v.setMPIGhost(ghosts) 346 v.setArray(numpy.array(range(*v.owner_range), dtype=PETSc.ScalarType)) 347 v.ghostUpdate() 348 with v.localForm() as loc: 349 self.assertTrue((loc[0 : v.local_size] == range(*v.owner_range)).all()) 350 self.assertTrue((loc[v.local_size :] == ghosts).all()) 351 352 353# -------------------------------------------------------------------- 354 355if __name__ == '__main__': 356 unittest.main() 357 358# -------------------------------------------------------------------- 359