Skip to content

Commit cc0dd93

Browse files
committed
updates
Signed-off-by: Christian Glusa <[email protected]>
1 parent f89007b commit cc0dd93

File tree

82 files changed

+1585
-756
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

82 files changed

+1585
-756
lines changed

Dockerfile

+3-2
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ RUN sed -i 's/Components: main/Components: main contrib non-free/' /etc/apt/sour
2222
libarpack2-dev \
2323
mpi-default-bin mpi-default-dev \
2424
python3 python3-dev python-is-python3 python3-pip \
25-
python3-numpy python3-scipy python3-matplotlib python3-mpi4py cython3 python3-yaml python3-h5py python3-tk jupyter-notebook \
25+
python3-numpy python3-scipy python3-matplotlib python3-mpi4py cython3 python3-yaml python3-h5py python3-tk jupyter-notebook python3-meshio python3-gmsh \
2626
--no-install-recommends \
2727
&& rm -rf /var/lib/apt/lists/*
2828

@@ -31,7 +31,8 @@ RUN sed -i 's/Components: main/Components: main contrib non-free/' /etc/apt/sour
3131
ENV OMPI_MCA_hwloc_base_binding_policy=hwthread \
3232
MPIEXEC_FLAGS=--allow-run-as-root \
3333
OMPI_ALLOW_RUN_AS_ROOT=1 \
34-
OMPI_ALLOW_RUN_AS_ROOT_CONFIRM=1
34+
OMPI_ALLOW_RUN_AS_ROOT_CONFIRM=1 \
35+
PIP_BREAK_SYSTEM_PACKAGES=1
3536

3637
COPY . /pynucleus
3738

base/PyNucleus_base/LinearOperator_{SCALAR}.pxi

+37-6
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,15 @@ cdef class {SCALAR_label}LinearOperator:
4141
BOOL_t no_overwrite=False,
4242
BOOL_t trans=False):
4343
if not trans:
44+
assert self.num_columns == x.shape[0], (self.num_columns, x.shape[0])
45+
assert self.num_rows == y.shape[0], (self.num_rows, y.shape[0])
4446
if no_overwrite:
4547
self.matvec_no_overwrite(x, y)
4648
else:
4749
self.matvec(x, y)
4850
else:
51+
assert self.num_rows == x.shape[0], (self.num_rows, x.shape[0])
52+
assert self.num_columns == y.shape[0], (self.num_columns, y.shape[0])
4953
if no_overwrite:
5054
self.matvecTrans_no_overwrite(x, y)
5155
else:
@@ -93,6 +97,9 @@ cdef class {SCALAR_label}LinearOperator:
9397
def __sub__(self, x):
9498
return self + (-1.*x)
9599

100+
def __matmul__(self, {SCALAR_label}LinearOperator x):
101+
return {SCALAR_label}Product_Linear_Operator(self, x)
102+
96103
def __mul__(self, x):
97104
cdef:
98105
np.ndarray[{SCALAR}_t, ndim=1] y
@@ -110,7 +117,7 @@ cdef class {SCALAR_label}LinearOperator:
110117
return self.dotMV(x)
111118
elif isinstance(self, {SCALAR_label}TimeStepperLinearOperator) and isinstance(x, (float, int, {SCALAR})):
112119
tsOp = self
113-
return {SCALAR_label}TimeStepperLinearOperator(self, tsOp.M, tsOp.S, tsOp.facS*x, tsOp.facM*x)
120+
return {SCALAR_label}TimeStepperLinearOperator(tsOp.M, tsOp.S, tsOp.facS*x, tsOp.facM*x)
114121
elif isinstance(self, {SCALAR_label}LinearOperator) and isinstance(x, (float, int, {SCALAR})):
115122
return {SCALAR_label}Multiply_Linear_Operator(self, x)
116123
elif isinstance(x, {SCALAR_label}LinearOperator) and isinstance(self, (float, int, {SCALAR})):
@@ -128,8 +135,14 @@ cdef class {SCALAR_label}LinearOperator:
128135
raise NotImplementedError('Cannot multiply {} with {}:\n{}'.format(self, x, e))
129136

130137
def __rmul__(self, x):
138+
cdef:
139+
{SCALAR_label}TimeStepperLinearOperator tsOp
131140
if isinstance(x, (float, int, {SCALAR})):
132-
return {SCALAR_label}Multiply_Linear_Operator(self, x)
141+
if isinstance(self, {SCALAR_label}TimeStepperLinearOperator):
142+
tsOp = self
143+
return {SCALAR_label}TimeStepperLinearOperator(tsOp.M, tsOp.S, tsOp.facS*x, tsOp.facM*x)
144+
else:
145+
return {SCALAR_label}Multiply_Linear_Operator(self, x)
133146
else:
134147
raise NotImplementedError('Cannot multiply with {}'.format(x))
135148

@@ -196,14 +209,14 @@ cdef class {SCALAR_label}LinearOperator:
196209
def toLinearOperator(self):
197210
def matvec(x):
198211
if x.ndim == 1:
199-
return self*x
212+
return self*x.astype({SCALAR})
200213
elif x.ndim == 2 and x.shape[1] == 1:
201214
if x.flags.c_contiguous:
202215
return self*x[:, 0]
203216
else:
204217
y = np.zeros((x.shape[0]), dtype=x.dtype)
205218
y[:] = x[:, 0]
206-
return self*y
219+
return self*y.astype({SCALAR})
207220
else:
208221
raise NotImplementedError()
209222

@@ -380,9 +393,27 @@ cdef class {SCALAR_label}TimeStepperLinearOperator({SCALAR_label}LinearOperator)
380393

381394
def __repr__(self):
382395
if np.real(self.facS) >= 0:
383-
return '{}*{} + {}*{}'.format(self.facM, self.M, self.facS, self.S)
396+
if self.facM != 1.0:
397+
if self.facS != 1.0:
398+
return '{}*{} + {}*{}'.format(self.facM, self.M, self.facS, self.S)
399+
else:
400+
return '{}*{} + {}'.format(self.facM, self.M, self.S)
401+
else:
402+
if self.facS != 1.0:
403+
return '{} + {}*{}'.format(self.M, self.facS, self.S)
404+
else:
405+
return '{} + {}'.format(self.M, self.S)
384406
else:
385-
return '{}*{} - {}*{}'.format(self.facM, self.M, -self.facS, self.S)
407+
if self.facM != 1.0:
408+
if self.facS != -1.0:
409+
return '{}*{} - {}*{}'.format(self.facM, self.M, -self.facS, self.S)
410+
else:
411+
return '{}*{} - {}'.format(self.facM, self.M, self.S)
412+
else:
413+
if self.facS != -1.0:
414+
return '{} - {}*{}'.format(self.M, -self.facS, self.S)
415+
else:
416+
return '{} - {}'.format(self.M, self.S)
386417

387418
def to_csr_linear_operator(self):
388419
if isinstance(self.S, {SCALAR_label}Dense_LinearOperator):

base/PyNucleus_base/plot_utils.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -217,12 +217,12 @@ def formatScientificLatex(a, useEnotation=True):
217217
exp = int(np.floor(np.log10(a)))
218218
mantissa = a/10**exp
219219
if useEnotation:
220-
return '{:.3}\mathrm{{e}}{{{}}}'.format(mantissa, exp)
220+
return '{:.3}\\mathrm{{e}}{{{}}}'.format(mantissa, exp)
221221
else:
222222
return '{:.3} \\times 10^{{{}}}'.format(mantissa, exp)
223223
elif abs(a) == 0:
224224
if useEnotation:
225-
return '0.00\mathrm{{e}}{0}'
225+
return '0.00\\mathrm{{e}}{0}'
226226
else:
227227
return '0.00 \\times 10^{0}'
228228
else:

base/PyNucleus_base/utilsFem.py

+8
Original file line numberDiff line numberDiff line change
@@ -1069,6 +1069,14 @@ def process(self, override={}):
10691069
if self.comm:
10701070
params = self.comm.bcast(params, root=0)
10711071
self.params = params
1072+
1073+
if params['test']:
1074+
import psutil
1075+
p = psutil.Process()
1076+
try:
1077+
p.cpu_affinity(list(range(psutil.cpu_count())))
1078+
except AttributeError:
1079+
pass
10721080
self._timer = TimerManager(self.logger, comm=self.comm, memoryProfiling=params['showMemory'])
10731081

10741082
for fun in self.processHook:

drivers/brusselator.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
from PyNucleus_base.linear_operators import TimeStepperLinearOperator
2828
from PyNucleus_fem.femCy import assembleNonlinearity
2929
from PyNucleus_multilevelSolver import hierarchyManager
30-
from PyNucleus_nl import paramsForFractionalHierarchy
30+
from PyNucleus_nl.helpers import paramsForFractionalHierarchy
3131
from PyNucleus_nl.nonlocalProblems import brusselatorProblem
3232
from PyNucleus_base.timestepping import EulerIMEX, ARS3, koto
3333
import h5py

drivers/brusselatorMovie.py

+11-10
Original file line numberDiff line numberDiff line change
@@ -8,42 +8,43 @@
88

99
import numpy as np
1010
import matplotlib.pyplot as plt
11-
from path import Path
11+
from pathlib import Path
1212
from shutil import rmtree
1313
import h5py
1414
from subprocess import Popen
1515
from PyNucleus_base import driver
16-
from PyNucleus_fem import meshNd
16+
from PyNucleus_fem.mesh import meshNd
1717
from PyNucleus_fem.DoFMaps import DoFMap
1818
from PyNucleus_nl.nonlocalProblems import brusselatorProblem
1919

2020
d = driver()
21-
brusselatorProblem(d)
21+
# brusselatorProblem(d)
22+
d.add('inputFile', '')
2223
d.add('zoomIn', False)
2324
d.add('shading', acceptedValues=['gouraud', 'flat'])
2425
d.process()
2526

26-
filename = d.identifier+'.hdf5'
27+
filename = d.inputFile
2728
resultFile = h5py.File(str(filename), 'r')
2829

2930
mesh = meshNd.HDF5read(resultFile['mesh'])
3031
dm = DoFMap.HDF5read(resultFile['dm'])
3132
dm.mesh = mesh
3233

33-
folder = Path('brusselatorMovie')/Path(filename).basename()
34+
folder = Path('brusselatorMovie')/Path(filename).name
3435
try:
3536
rmtree(str(folder))
3637
except:
3738
pass
38-
folder.makedirs_p()
39+
folder.mkdir(parents=True, exist_ok=True)
3940

4041
if d.zoomIn:
41-
folderZoom = Path('brusselatorMovie')/(Path(filename).basename()+'-zoomIn')
42+
folderZoom = Path('brusselatorMovie')/(Path(filename).name+'-zoomIn')
4243
try:
4344
rmtree(str(folderZoom))
4445
except:
4546
pass
46-
folderZoom.makedirs_p()
47+
folderZoom.mkdir(parents=True, exist_ok=True)
4748

4849
l = sorted([int(i) for i in resultFile['U']])
4950

@@ -74,12 +75,12 @@
7475
resultFile.close()
7576

7677
Popen(['mencoder', 'mf://*.png', '-mf', 'fps=10', '-o',
77-
'../{}.avi'.format(Path(filename).basename().stripext()), '-ovc', 'lavc',
78+
'../{}.avi'.format(Path(filename).stem), '-ovc', 'lavc',
7879
'-lavcopts', 'vcodec=msmpeg4v2:vbitrate=800'],
7980
cwd=folder).wait()
8081
if d.zoomIn:
8182
Popen(['mencoder', 'mf://*.png', '-mf', 'fps=10', '-o',
82-
'../{}-zoom.avi'.format(Path(filename).basename().stripext()), '-ovc', 'lavc',
83+
'../{}-zoom.avi'.format(Path(filename).stem), '-ovc', 'lavc',
8384
'-lavcopts', 'vcodec=msmpeg4v2:vbitrate=800'],
8485
cwd=folderZoom).wait()
8586

drivers/runParallelGMG.py

+36-14
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,13 @@
4444
solver.add('smoother', 'jacobi', acceptedValues=['gauss_seidel', 'chebyshev'])
4545
solver.add('doPCoarsen', False)
4646
solver.add('maxiter', 50)
47+
solver.add('tolerance', 0.)
4748

4849
d.declareFigure('residuals', default=False)
50+
d.declareFigure('numericalSolution')
4951
d.declareFigure('spSolve')
5052
d.declareFigure('spSolveError')
51-
d.declareFigure('spSolveExactSolution')
53+
d.declareFigure('interpolatedAnalyticSolution')
5254

5355
params = d.process()
5456

@@ -95,7 +97,7 @@
9597
else:
9698
hierarchies, connectors = paramsForMG(p.noRef,
9799
range(d.comm.size),
98-
params, p.dim, p.element)
100+
params, p.manifold_dim, p.element)
99101
connectors['input'] = {'type': inputConnector,
100102
'params': {'domain': d.domain}}
101103

@@ -111,10 +113,13 @@
111113
overlaps = hM[FINE].multilevelAlgebraicOverlapManager
112114
h = hM[FINE].meshLevels[-1].mesh.global_h(overlaps.comm)
113115
hmin = hM[FINE].meshLevels[-1].mesh.global_hmin(overlaps.comm)
114-
tol = {'P1': 0.5*h**2,
115-
'P2': 0.001*h**3,
116-
'P3': 0.001*h**4}[d.element]
117-
tol = max(tol, 2e-9)
116+
if d.tolerance <= 0.:
117+
tol = {'P1': 0.5*h**2,
118+
'P2': 0.001*h**3,
119+
'P3': 0.001*h**4}[d.element]
120+
tol = max(tol, 2e-9)
121+
else:
122+
tol = d.tolerance
118123

119124
# assemble rhs on finest grid
120125
with d.timer('Assemble rhs on finest grid'):
@@ -211,6 +216,7 @@
211216
residuals = solver.residuals
212217
A.residual_py(x, rhs, r)
213218
resNorm = r.norm(False)
219+
numIter = max(1, numIter)
214220
rate.add('Rate of convergence P'+label, (resNorm/r0)**(1/numIter), tested=False if label == 'BICGSTAB' else None)
215221
its.add('Number of iterations P'+label, numIter, aTol=2 if label == 'BICGSTAB' else None)
216222
res.add('Residual norm P'+label, resNorm)
@@ -333,11 +339,16 @@
333339
# cg(b_global, u_global)
334340
# print(cg.residuals, len(cg.residuals))
335341

342+
if p.nontrivialNullspace:
343+
const = DoFMap_fine.ones()
344+
x -= (x.inner(const)/const.inner(const))*const
345+
336346
if p.L2ex:
337347
if p.boundaryCond:
338348
d.logger.warning('L2 error is wrong for inhomogeneous BCs')
339349
with d.timer('Mass matrix'):
340350
M = DoFMap_fine.assembleMass(sss_format=d.symmetric)
351+
341352
z = DoFMap_fine.assembleRHS(p.exactSolution)
342353
L2err = np.sqrt(np.absolute(x.inner(M*x, True, False) -
343354
2*z.inner(x, False, True) +
@@ -379,17 +390,30 @@
379390
global_dm) = accumulate2global(subdomain, interfaces, DoFMap_fine, x,
380391
comm=d.comm)
381392
if d.isMaster:
382-
from scipy.sparse.linalg import spsolve
393+
394+
if d.startPlot('numericalSolution'):
395+
global_solution.plot()
396+
if p.exactSolution and d.startPlot('interpolatedAnalyticSolution'):
397+
global_dm.interpolate(p.exactSolution).plot()
398+
383399
from numpy.linalg import norm
384400
A = global_dm.assembleStiffness()
401+
if p.nontrivialNullspace:
402+
from PyNucleus_base.linear_operators import Dense_LinearOperator
403+
A = A+Dense_LinearOperator(np.ones(A.shape))
385404
rhs = global_dm.assembleRHS(p.rhsFun)
386405
if p.boundaryCond:
387406
global_boundaryDoFMap = global_dm.getComplementDoFMap()
388407
global_boundary_data = global_boundaryDoFMap.interpolate(p.boundaryCond)
389408
global_A_boundary = global_dm.assembleStiffness(dm2=global_boundaryDoFMap)
390409
rhs -= global_A_boundary*global_boundary_data
391410
with d.timer('SpSolver'):
392-
y = spsolve(A.to_csr(), rhs)
411+
directSolver = solverFactory('lu', A=A, setup=True)
412+
global_solution_spsolve = global_dm.zeros()
413+
directSolver(rhs, global_solution_spsolve)
414+
if p.nontrivialNullspace:
415+
const = global_dm.ones()
416+
global_solution_spsolve -= (global_solution_spsolve.inner(const)/const.inner(const))*const
393417
if p.boundaryCond:
394418
sol_augmented, dm_augmented = global_dm.augmentWithBoundaryData(global_solution, global_boundary_data)
395419
global_mass = dm_augmented.assembleMass()
@@ -405,14 +429,12 @@
405429
p.L2ex))
406430
errsSpSolve = d.addOutputGroup('errSpSolve')
407431
errsSpSolve.add('L2', L2err)
408-
errsSpSolve.add('2-norm', norm(global_solution-y, 2))
409-
errsSpSolve.add('max-norm', np.abs(global_solution-y).max())
432+
errsSpSolve.add('2-norm', norm(global_solution-global_solution_spsolve, 2))
433+
errsSpSolve.add('max-norm', np.abs(global_solution-global_solution_spsolve).max())
410434
d.logger.info('\n'+str(errsSpSolve))
411435
if d.startPlot('spSolve'):
412436
import matplotlib.pyplot as plt
413-
global_solution.plot()
414-
if p.exactSolution and d.startPlot('spSolveExactSolution'):
415-
global_dm.interpolate(p.exactSolution).plot()
437+
global_solution_spsolve.plot()
416438
if d.startPlot('spSolveError'):
417-
(global_solution-y).plot()
439+
(global_solution-global_solution_spsolve).plot()
418440
d.finish()

fem/PyNucleus_fem/DoFMaps.pyx

+5-3
Original file line numberDiff line numberDiff line change
@@ -722,7 +722,8 @@ cdef class DoFMap:
722722
BOOL_t reorder=False,
723723
diffusivity=None,
724724
INDEX_t[::1] cellIndices=None,
725-
DoFMap dm2=None):
725+
DoFMap dm2=None,
726+
simplexQuadratureRule qr=None):
726727
"""This function assembles the stiffness matrix for a given
727728
diffusivity function:
728729
@@ -760,7 +761,8 @@ cdef class DoFMap:
760761
reorder,
761762
diffusivity,
762763
cellIndices,
763-
dm2=dm2)
764+
dm2=dm2,
765+
qr=qr)
764766

765767
def assembleRHS(self,
766768
fun,
@@ -983,7 +985,7 @@ cdef class DoFMap:
983985
for i in range(numCoords):
984986
for k in range(dim):
985987
coords[i, k] = 0.
986-
for j in range(dim+1):
988+
for j in range(cell.shape[0]):
987989
for k in range(dim):
988990
coords[i, k] += self.nodes[i, j]*cell[j, k]
989991

0 commit comments

Comments
 (0)