Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix sub-packages #43

Merged
merged 1 commit into from
Mar 9, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -177,7 +177,7 @@ flake8:
rm flake8.txt

cython-lint:
- cython-lint --max-line-length=160 drivers examples packageTools base metisCy fem multilevelSolver nl tests > cython-lint.txt 2>&1
- cython-lint --max-line-length=160 --ignore="E741" drivers examples packageTools base metisCy fem multilevelSolver nl tests > cython-lint.txt 2>&1
flake8_junit cython-lint.txt cython-lint.xml
rm cython-lint.txt
sed 's/name="flake8"/name="cython-lint"/g' cython-lint.xml > cython-lint2.xml
10 changes: 0 additions & 10 deletions base/PyNucleus_base/factory.py
Original file line number Diff line number Diff line change
@@ -51,13 +51,6 @@ def numRegistered(self, countAliases=False):
return len(self.classes) + len(self.aliases)

def __str__(self):
s = ''
for canonical_name in self.classes:
a = [self.aliases[canonical_alias][0] for canonical_alias in self.aliases if self.aliases[canonical_alias][1] == canonical_name]
s += '{} {} {}\n'.format(canonical_name, a, self.classes[canonical_name])
return s

def __repr__(self):
s = 'Available:\n'
for canonical_name in self.classes:
name = self.classes[canonical_name][0]
@@ -77,6 +70,3 @@ def __repr__(self):
else:
s += '\'{}\', signature: \'{}\'\n'.format(name, sig)
return s

def print(self):
print(repr(self))
6 changes: 3 additions & 3 deletions base/PyNucleus_base/solver_factory.py
Original file line number Diff line number Diff line change
@@ -95,12 +95,12 @@ def build(self, name, **kwargs):
solvers[k].setPreconditioner(solvers[k+1].asPreconditioner())
return solvers[0]

def __repr__(self):
def __str__(self):
s = ''
if self.singleLevelSolverFactory.numRegistered() > 0:
s += 'Single level solvers:\n'
s += repr(self.singleLevelSolverFactory)
s += str(self.singleLevelSolverFactory)
if self.multiLevelSolverFactory.numRegistered() > 0:
s += 'Multi level solvers:\n'
s += repr(self.multiLevelSolverFactory)
s += str(self.multiLevelSolverFactory)
return s
61 changes: 33 additions & 28 deletions base/PyNucleus_base/timestepping.py
Original file line number Diff line number Diff line change
@@ -15,11 +15,13 @@ class Stepper:
"""
Solve

f(t, u, u_t) = A(t, u_t) + B(t, u) - g(t) = 0
f(t, u, u_t) = A(t, u_t) + B(t, u) - g(t) = 0.

mass: t, u -> A(t, u)
explicit: t, u -> B(t, u)
forcing: t -> g(t)
We assume that A is linear in its second argument. Let

mass: t, u -> A(t, u)
explicit: t, u -> B(t, u)
forcing: t -> g(t)
implicitSolverBuilder: t, alpha, beta -> solver for alpha*A(t, u)+beta*B(t, u) = g

"""
@@ -51,9 +53,12 @@ def apply_jacobian(self, t, dt, ut, ut_plus_dt, residual, alpha=1., beta=1.):


class CrankNicolson(Stepper):
"""
1/dt*A(t+dt, u_{k+1}) + theta*B(t+dt, u_{k+1}) = (1-theta)*g(t_{k}) + theta*g(t_{k+1}) + 1/dt*A(t_{k}, u_{k}) - (1-theta)*B(t_{k}, u_{k})
"""
def __init__(self, dm, mass, solverBuilder, forcing, explicit=None, theta=0.5, dt=None,
solverIsTimeDependent=False, explicitIslinearAndTimeIndependent=False):
assert theta > 0 and theta <= 1.
assert theta >= 0 and theta <= 1.
self.theta = theta
super(CrankNicolson, self).__init__(dm, mass, solverBuilder, forcing, explicit, dt, solverIsTimeDependent, explicitIslinearAndTimeIndependent)
if self.theta < 1.:
@@ -73,12 +78,16 @@ def getSolver(self, t, dt):
return self.solverBuilder(t+dt, 1./dt, self.theta)

def setRHS(self, t, dt, rhs):
self.forcing(t+dt, rhs)
if self.theta < 1.:
if self.theta > 0. and self.theta < 1.:
self.forcing(t+dt, rhs)
rhs *= self.theta
self.forcing(t, self.rhs2)
self.rhs2 *= (1.-self.theta)
rhs += self.rhs2
elif self.theta == 0.:
self.forcing(t, rhs)
elif self.theta == 1.:
self.forcing(t+dt, rhs)

def step(self, t, dt, u, forcingVector=None):
if dt is None:
@@ -105,6 +114,9 @@ def step(self, t, dt, u, forcingVector=None):
return t+dt

def residual(self, t, dt, ut, ut_plus_dt, residual, alpha=1., beta=1., forcingVector=None):
# alpha/dt*[A(t+dt, ut_plus_dt) - A(t, ut)]
# + beta*[(1-theta)*B(t, ut) + theta*B(t+dt, ut_plus_dt)]
# - (1-theta)*g(t) - theta*g(t+dt)
if abs(alpha/dt) > 0:
self.mass(t, ut, self.rhs)
self.mass(t+dt, ut_plus_dt, self.rhs2)
@@ -134,6 +146,8 @@ def residual(self, t, dt, ut, ut_plus_dt, residual, alpha=1., beta=1., forcingVe
residual -= self.rhs

def apply_jacobian(self, t, dt, ut, ut_plus_dt, residual, alpha=1., beta=1.):
# alpha/dt*[A(t+dt, ut_plus_dt) - A(t, ut)]
# + beta*[(1-theta)*B(t, ut) + theta*B(t+dt, ut_plus_dt)]
if abs(alpha/dt) > 0:
self.mass(t, ut, self.rhs)
self.mass(t+dt, ut_plus_dt, self.rhs2)
@@ -157,30 +171,21 @@ def apply_jacobian(self, t, dt, ut, ut_plus_dt, residual, alpha=1., beta=1.):
residual += self.rhs2


class ExplicitEuler(Stepper):
def __init__(self, dm, mass, solverBuilder, forcing, explicit, solverIsTimeDependent=False):
assert explicit is not None
super(ExplicitEuler, self).__init__(dm, mass, solverBuilder, forcing, explicit, 0., solverIsTimeDependent)
self.rhs = self.dm.zeros()
self.rhs2 = self.dm.zeros()

def step(self, t, dt, u):
self.forcing(t+dt, self.rhs)
self.rhs *= dt
self.explicit(t, u, self.rhs2)
self.rhs2 *= -dt
self.rhs += self.rhs2
if not self.solverIsTimeDependent:
solver = self.solver
else:
solver = self.solverBuilder(t+dt, 0.)
if isinstance(solver, iterative_solver):
solver.setInitialGuess(u)
solver(self.rhs, u)
return t+dt
class ExplicitEuler(CrankNicolson):
"""
1/dt*A(t+dt, u_{k+1}) = g(t_{k}) + 1/dt*A(t_{k}, u_{k}) - B(t_{k}, u_{k})
"""
def __init__(self, dm, mass, solverBuilder, forcing, explicit=None, dt=None, solverIsTimeDependent=False):
super(ExplicitEuler, self).__init__(dm, mass, solverBuilder, forcing, explicit,
dt=dt,
theta=0.,
solverIsTimeDependent=solverIsTimeDependent)


class ImplicitEuler(CrankNicolson):
"""
1/dt*A(t+dt, u_{k+1}) + B(t+dt, u_{k+1}) = g(t_{k+1}) + 1/dt*A(t_{k}, u_{k})
"""
def __init__(self, dm, mass, solverBuilder, forcing, explicit=None, dt=None, solverIsTimeDependent=False):
super(ImplicitEuler, self).__init__(dm, mass, solverBuilder, forcing, explicit,
dt=dt,
39 changes: 24 additions & 15 deletions base/PyNucleus_base/utilsFem.py
Original file line number Diff line number Diff line change
@@ -310,7 +310,7 @@ def saveDictToHDF5(params, f, ignore=set()):
def loadDictFromHDF5(f):
import h5py
from . linear_operators import LinearOperator
from PyNucleus.fem.DoFMaps import DoFMap
from PyNucleus_fem.DoFMaps import DoFMap
params = {}
for key in f.attrs:
if isinstance(f.attrs[key], h5py.Empty):
@@ -352,7 +352,7 @@ def loadDictFromHDF5(f):
else:
params[key] = LinearOperator.HDF5read(f[key])
elif 'vertices' in f[key] and 'cells' in f[key]:
from PyNucleus.fem.mesh import meshNd
from PyNucleus_fem.mesh import meshNd
params[key] = meshNd.HDF5read(f[key])
else:
params[key] = loadDictFromHDF5(f[key])
@@ -369,7 +369,7 @@ def loadDictFromHDF5(f):


def processDictForYaml(params):
from PyNucleus.fem.functions import function
from PyNucleus_fem.functions import function
paramsNew = {}
for key in params:
if isinstance(params[key], dict):
@@ -411,7 +411,7 @@ def updateFromDefaults(params, defaults):
updateFromDefaults(params[key], defaults[key])


def getMPIinfo(grp):
def getMPIinfo(grp, verbose=False):
from sys import modules
if 'mpi4py.MPI' in modules:
import mpi4py
@@ -427,13 +427,15 @@ def getMPIinfo(grp):
if MPI.COMM_WORLD.rank == 0:
hosts = ','.join(set(hosts))
grp.add('MPI library', '{}'.format(MPI.Get_library_version()[:-1]))
for label, value in [('MPI standard supported', MPI.Get_version()),
('Vendor', MPI.get_vendor()),
('Level of thread support', t[MPI.Query_thread()]),
('Is threaded', MPI.Is_thread_main()),
('Threads requested', mpi4py.rc.threads),
('Thread level requested', mpi4py.rc.thread_level),
('Hosts', hosts),
if verbose:
for label, value in [('MPI standard supported', MPI.Get_version()),
('Vendor', MPI.get_vendor()),
('Level of thread support', t[MPI.Query_thread()]),
('Is threaded', MPI.Is_thread_main()),
('Threads requested', mpi4py.rc.threads),
('Thread level requested', mpi4py.rc.thread_level)]:
grp.add(label, value)
for label, value in [('Hosts', hosts),
('Communicator size', MPI.COMM_WORLD.size)]:
grp.add(label, value)

@@ -487,8 +489,8 @@ def getSystemInfo(grp, argv=None, envVars=[('OMP_NUM_THREADS', True)]):
versions[(version, sha)].append(pkg)
except KeyError:
versions[(version, sha)] = [pkg]
for version in versions:
grp.add('PyNucleus_'+(','.join(versions[version])), version)
for version, sha in versions:
grp.add('PyNucleus_'+(','.join(versions[(version, sha)])), '{}, {}'.format(version, sha))


class MPIFileHandler(logging.Handler):
@@ -1382,6 +1384,7 @@ def runDriver(path, py, python=None, timeout=600, ranks=None, cacheDir='',
py += ['--overwriteCache']
else:
py += ['--test']
py += ['--disableFileLog']
if extra is not None:
plotDir.mkdir(exist_ok=True, parents=True)
py += ['--plotFolder={}'.format(plotDir), '--plotFormat=png']
@@ -1444,7 +1447,7 @@ def __init__(self, name, params=[]):
fields.append('True|False')
else:
raise NotImplementedError()
self.regexp = re.compile(name+'\('+','.join(['\s*(' + f + ')\s*' for f in fields])+'\)')
self.regexp = re.compile(name+'\(?'+','.join(['\s*(' + f + ')\s*' for f in fields])+'\)?')

def match(self, s):
return self.regexp.match(s) is not None
@@ -1841,7 +1844,13 @@ def processCmdline(self, params):
pass

def getIdentifier(self, params):
return ''
from sys import argv
identifier = '-'.join(argv)
pos = identifier.rfind('/')
if pos >= 0:
return identifier[pos+1:]
else:
return identifier

def process(self, params):
self.processCmdline(params)
38 changes: 19 additions & 19 deletions docs/PyNucleus_base.rst
Original file line number Diff line number Diff line change
@@ -1,111 +1,111 @@

PyNucleus.base package
PyNucleus_base package
=======================

.. automodule:: PyNucleus_base


PyNucleus.base.blas module
PyNucleus_base.blas module
---------------------------

.. automodule:: PyNucleus_base.blas


PyNucleus.base.convergence module
PyNucleus_base.convergence module
----------------------------------

.. automodule:: PyNucleus_base.convergence


PyNucleus.base.factory module
PyNucleus_base.factory module
------------------------------

.. automodule:: PyNucleus_base.factory


PyNucleus.base.intTuple module
PyNucleus_base.intTuple module
-------------------------------

.. automodule:: PyNucleus_base.intTuple


PyNucleus.base.ip.norm module
PyNucleus_base.ip.norm module
-------------------------------

.. automodule:: PyNucleus_base.ip_norm


PyNucleus.base.linalg module
PyNucleus_base.linalg module
-----------------------------

.. automodule:: PyNucleus_base.linalg


PyNucleus.base.linear.operators module
PyNucleus_base.linear.operators module
----------------------------------------

.. automodule:: PyNucleus_base.linear_operators


PyNucleus.base.memProfile module
PyNucleus_base.memProfile module
---------------------------------

.. automodule:: PyNucleus_base.memProfile


PyNucleus.base.myTypes module
PyNucleus_base.myTypes module
------------------------------

.. automodule:: PyNucleus_base.myTypes


PyNucleus.base.performanceLogger module
PyNucleus_base.performanceLogger module
----------------------------------------

.. automodule:: PyNucleus_base.performanceLogger


PyNucleus.base.plot.utils module
PyNucleus_base.plot.utils module
----------------------------------

.. automodule:: PyNucleus_base.plot_utils


PyNucleus.base.solver.factory module
PyNucleus_base.solver.factory module
--------------------------------------

.. automodule:: PyNucleus_base.solver_factory


PyNucleus.base.solvers module
PyNucleus_base.solvers module
------------------------------

.. automodule:: PyNucleus_base.solvers

PyNucleus.base.sparseGraph module
PyNucleus_base.sparseGraph module
----------------------------------

.. automodule:: PyNucleus_base.sparseGraph

PyNucleus.base.sparsityPattern module
PyNucleus_base.sparsityPattern module
--------------------------------------

.. automodule:: PyNucleus_base.sparsityPattern


PyNucleus.base.tupleDict module
PyNucleus_base.tupleDict module
--------------------------------

.. automodule:: PyNucleus_base.tupleDict


PyNucleus.base.utilsCy module
PyNucleus_base.utilsCy module
------------------------------

.. automodule:: PyNucleus_base.utilsCy


PyNucleus.base.utilsFem module
PyNucleus_base.utilsFem module
-------------------------------

.. automodule:: PyNucleus_base.utilsFem
Loading