Skip to content

clean ups #32

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

Merged
merged 1 commit into from
Dec 15, 2023
Merged
Show file tree
Hide file tree
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
3 changes: 3 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,6 @@ ENV OMPI_MCA_hwloc_base_binding_policy=hwthread \
OMPI_ALLOW_RUN_AS_ROOT_CONFIRM=1

RUN python -m ipykernel install --name=PyNucleus

COPY README.container.rst /README.container.rst
RUN echo '[ ! -z "$TERM" -a -r /README.container.rst ] && cat /README.container.rst' >> /etc/bash.bashrc
56 changes: 44 additions & 12 deletions PyNucleus/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,51 @@
# If you want to use this code, please refer to the README.rst and LICENSE files. #
###################################################################################

import importlib
import pkgutil
import sys

subpackages = {}
__all__ = []
for finder, name, ispkg in pkgutil.iter_modules():
if ispkg and name.find('PyNucleus_') == 0:
importName = name[len('PyNucleus_'):]
module = importlib.import_module(name, 'PyNucleus')
sys.modules['PyNucleus.'+importName] = module
subpackages[importName] = module
names = [name for name in module.__dict__ if not name.startswith('_')]
locals().update({name: getattr(module, name) for name in names})
if hasattr(module, '__all__'):
__all__ += module.__all__

from PyNucleus_packageTools import *
import PyNucleus_packageTools as packageTools

sys.modules['PyNucleus.packageTools'] = packageTools
subpackages['packageTools'] = packageTools

from PyNucleus_base import *
import PyNucleus_base as base

sys.modules['PyNucleus.base'] = base
subpackages['base'] = base
__all__ += base.__all__

from PyNucleus_metisCy import *
import PyNucleus_metisCy as metisCy

sys.modules['PyNucleus.metisCy'] = metisCy
subpackages['metisCy'] = metisCy
__all__ += metisCy.__all__

from PyNucleus_fem import *
import PyNucleus_fem as fem

sys.modules['PyNucleus.fem'] = fem
subpackages['fem'] = fem
__all__ += fem.__all__

from PyNucleus_multilevelSolver import *
import PyNucleus_multilevelSolver as multilevelSolver

sys.modules['PyNucleus.multilevelSolver'] = multilevelSolver
subpackages['multilevelSolver'] = multilevelSolver
__all__ += multilevelSolver.__all__

try:
from PyNucleus_nl import *
import PyNucleus_nl as nl

sys.modules['PyNucleus.nl'] = nl
subpackages['nl'] = nl
__all__ += nl.__all__
except ImportError:
pass
6 changes: 6 additions & 0 deletions README.container.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

This is a container image for PyNucleus.

The drivers and examples for PyNucleus can be found in /pynucleus/drivers and /pynucleus/examples

The directory from which the container was launched on the host system is mapped to /user
4 changes: 3 additions & 1 deletion base/PyNucleus_base/utilsFem.py
Original file line number Diff line number Diff line change
Expand Up @@ -1822,7 +1822,9 @@ def setDriverArgs(self):

@property
def timer(self):
return self.driver.getTimer()
if self._timer is None:
self._timer = self.driver.getTimer()
return self._timer

def processCmdline(self, params):
pass
Expand Down
9 changes: 5 additions & 4 deletions compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ version: 3
services:

# Launch with:
# docker compose run --profile interactive pynucleus
# docker compose run pynucleus
pynucleus:
image: ghcr.io/sandialabs/pynucleus:latest
build: .
Expand All @@ -22,23 +22,24 @@ services:
- /tmp/.X11-unix:/tmp/.X11-unix
- $XAUTHORITY:/root/.Xauthority
network_mode: host
hostname: pynucleus-container

# Launch with:
# docker compose up
# Then open localhost:8889 in your browser
pynucleus-jupyter:
image: ghcr.io/sandialabs/pynucleus:latest
build: .
command: jupyter notebook --port=8888 --no-browser --ip=0.0.0.0 --allow-root --NotebookApp.token='' --NotebookApp.password='' --notebook-dir=/pynucleus/user --KernelSpecManager.ensure_native_kernel=False --KernelSpecManager.allowed_kernelspecs=pynucleus
command: jupyter notebook --port=8888 --no-browser --ip=0.0.0.0 --allow-root --NotebookApp.token='' --NotebookApp.password='' --notebook-dir=/notebooks --KernelSpecManager.ensure_native_kernel=False --KernelSpecManager.allowed_kernelspecs=pynucleus
environment:
# expose host proxies
- http_proxy=${http_proxy}
- https_proxy=${https_proxy}
- HTTP_PROXY=${HTTP_PROXY}
- HTTPS_PROXY=${HTTPS_PROXY}
volumes:
# The current directory on host gets mapped to /pynucleus/user in the container
- $PWD/notebooks:/pynucleus/user
# The notebook subdirectory on host gets mapped to /notebooks in the container
- $PWD/notebooks:/notebooks
ports:
# Expose a Jupyter notebook server from the container
- 8889:8888
4 changes: 2 additions & 2 deletions drivers/runNonlocalInterface.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,9 +92,9 @@
with d.timer('assemble matrices'):
buildDense = True

A1 = getFracLapl(domain1Mesh, dm1, nIP.kernel1, boundaryCondition=HOMOGENEOUS_NEUMANN, dense=buildDense,
A1 = getFracLapl(dm1, nIP.kernel1, boundaryCondition=HOMOGENEOUS_NEUMANN, dense=buildDense,
forceRebuild=d.forceRebuild, genKernel=d.genKernel, trySparsification=True, doSave=True)
A2 = getFracLapl(domain2Mesh, dm2, nIP.kernel2, boundaryCondition=HOMOGENEOUS_NEUMANN, dense=buildDense,
A2 = getFracLapl(dm2, nIP.kernel2, boundaryCondition=HOMOGENEOUS_NEUMANN, dense=buildDense,
forceRebuild=d.forceRebuild, genKernel=d.genKernel, trySparsification=True, doSave=True)

# domain-domain interaction
Expand Down
16 changes: 12 additions & 4 deletions fem/PyNucleus_fem/DoFMaps.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -805,11 +805,19 @@ cdef class DoFMap:
return assembleRHSgrad(fun, self, coeff, qr)

def assembleNonlocal(self, kernel, str matrixFormat='DENSE', DoFMap dm2=None, BOOL_t returnNearField=False, **kwargs):
"""Assemble a nonlocal operator of the form
"""Assemble a nonlocal operator.

For finite horizon kernels

.. math::

\\iint_{D \\times D} (u(x)-u(y)) (v(x) \\gamma(x, y) - v(y) \\gamma(y, x)) dy dx

and for infinite horizon kernels

.. math::

\\int_D (u(x)-u(y)) \\gamma(x, y) dy
\\iint_{D \\times D} (u(x)-u(y)) (v(x) \\gamma(x, y) - v(y) \\gamma(y, x)) dy dx + 2\\int_{D} u(x) v(x) \\int_{D^c} \\gamma(x, y) dy dx

:param kernel: The kernel function :math:`\\gamma`

Expand Down Expand Up @@ -861,11 +869,11 @@ cdef class DoFMap:
if isinstance(kernel, ComplexKernel):
from PyNucleus_nl.nonlocalAssembly import ComplexnonlocalBuilder

builder = ComplexnonlocalBuilder(self.mesh, self, kernel, dm2=dm2, **kwargs)
builder = ComplexnonlocalBuilder(self, kernel, dm2=dm2, **kwargs)
else:
from PyNucleus_nl.nonlocalAssembly import nonlocalBuilder

builder = nonlocalBuilder(self.mesh, self, kernel, dm2=dm2, **kwargs)
builder = nonlocalBuilder(self, kernel, dm2=dm2, **kwargs)
if matrixFormat.upper() == 'DENSE':
return builder.getDense()
elif matrixFormat.upper() == 'DIAGONAL':
Expand Down
8 changes: 7 additions & 1 deletion fem/PyNucleus_fem/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,10 @@
from . factories import functionFactory, dofmapFactory, meshFactory
from . pdeProblems import diffusionProblem, helmholtzProblem
__all__ = ['functionFactory', 'dofmapFactory', 'meshFactory',
'diffusionProblem', 'helmholtzProblem']
'diffusionProblem', 'helmholtzProblem',
'PHYSICAL', 'INTERIOR_NONOVERLAPPING', 'INTERIOR', 'NO_BOUNDARY',
'DIRICHLET', 'HOMOGENEOUS_DIRICHLET',
'NEUMANN', 'HOMOGENEOUS_NEUMANN',
'NORM', 'boundaryConditions',
'P0_DoFMap', 'P1_DoFMap', 'P2_DoFMap', 'P3_DoFMap',
'str2DoFMap', 'str2DoFMapOrder', 'getAvailableDoFMaps']
1 change: 1 addition & 0 deletions metisCy/PyNucleus_metisCy/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,4 @@
from . metisCy import (OBJTYPE_CUT,
OBJTYPE_NODE,
OBJTYPE_VOL)
__all__ = []
1 change: 1 addition & 0 deletions multilevelSolver/PyNucleus_multilevelSolver/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@

solverFactory.register('mg', multigrid, isMultilevelSolver=True)
solverFactory.register('complex_mg', Complexmultigrid, isMultilevelSolver=True)
__all__ = []
6 changes: 3 additions & 3 deletions nl/PyNucleus_nl/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,6 @@
nonlocalMeshFactory)
from . discretizedProblems import (discretizedNonlocalProblem,
discretizedTransientProblem)
__all__ = [twoPointFunctionFactory, fractionalOrderFactory, interactionFactory, kernelFactory, nonlocalMeshFactory,
fractionalLaplacianProblem, nonlocalPoissonProblem, transientFractionalProblem,
discretizedNonlocalProblem, discretizedTransientProblem]
__all__ = ['twoPointFunctionFactory', 'fractionalOrderFactory', 'interactionFactory', 'kernelFactory', 'nonlocalMeshFactory',
'fractionalLaplacianProblem', 'nonlocalPoissonProblem', 'transientFractionalProblem',
'discretizedNonlocalProblem', 'discretizedTransientProblem']
8 changes: 6 additions & 2 deletions nl/PyNucleus_nl/discretizedProblems.py
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,7 @@ def __init__(self, driver, continuumProblem):
super().__init__(driver)
self.continuumProblem = continuumProblem
self.addRemote(self.continuumProblem)
driver.addToProcessHook(self.setTimerManager)

def setDriverArgs(self):
p = self.driver.addGroup('solver')
Expand All @@ -367,6 +368,9 @@ def setDriverArgs(self):
self.setDriverFlag('matrixFormat', acceptedValues=['H2', 'sparse', 'sparsified', 'dense'], help='matrix format', group=p)
self.setDriverFlag('debugAssemblyTimes', False, group=p)

def setTimerManager(self, params):
self._timer = self.driver.getTimer().getSubManager(logging.getLogger(__name__))

@generates(['meshHierarchy', 'finalMesh',
'dm', 'dmBC', 'dmInterior',
'R_interior', 'P_interior',
Expand Down Expand Up @@ -518,7 +522,7 @@ def buildBCoperator(self, dmInterior, dmBC,
assemblyParams['dense'] = matrixFormat == 'dense'
assemblyParams['matrixFormat'] = matrixFormat
assemblyParams['tag'] = tag
self.A_BC = getFracLapl(dmInterior.mesh, dmInterior, dm2=dmBC, **assemblyParams)
self.A_BC = getFracLapl(dmInterior, dm2=dmBC, **assemblyParams)
else:
self.A_BC = None

Expand Down Expand Up @@ -638,7 +642,7 @@ def solve(self, b, dm, dmInterior, dmBC, P_interior, P_bc, solver, boundaryCondi
@generates('adjointModelSolution')
def adjointSolve(self, b, dm, dmInterior, P_interior, adjointSolver, tol, maxiter):
uInterior = dmInterior.zeros()
with self.timer('solve {}'.format(self.__class__.__name__)):
with self.timer('solve adjoint {}'.format(self.__class__.__name__)):
its = adjointSolver(b, uInterior)

resError = (b-adjointSolver.A*uInterior).norm(False)
Expand Down
16 changes: 8 additions & 8 deletions nl/PyNucleus_nl/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,9 @@ def processBC(tag, boundaryCondition, kernel):
return tag, zeroExterior


def getFracLapl(mesh, DoFMap, kernel=None, rangedOpParams={}, **kwargs):
def getFracLapl(DoFMap, kernel=None, rangedOpParams={}, **kwargs):

mesh = DoFMap.mesh
if kernel is None and len(rangedOpParams) == 0:
return DoFMap.assembleStiffness(dm2=kwargs.get('dm2', None))
assert kernel is not None or 's' in rangedOpParams, (kernel, rangedOpParams)
Expand Down Expand Up @@ -188,7 +189,7 @@ def getFracLapl(mesh, DoFMap, kernel=None, rangedOpParams={}, **kwargs):
intervalOps = []
for s in n:
kernel = getFractionalKernel(mesh.dim, constFractionalOrder(s), horizon, scaling=scaling, normalized=normalized)
intervalOps.append(delayedFractionalLaplacianOp(mesh, DoFMap, kernel, **kwargs))
intervalOps.append(delayedFractionalLaplacianOp(DoFMap, kernel, **kwargs))
ops.append(intervalOps)
A = multiIntervalInterpolationOperator(intervals, nodes, ops)
return A
Expand Down Expand Up @@ -263,10 +264,10 @@ def getFracLapl(mesh, DoFMap, kernel=None, rangedOpParams={}, **kwargs):
if dm2 is not None and matrixFormat.upper() in ('H2', 'SPARSE', 'SPARSIFIED') and DoFMap.num_boundary_dofs > 0:
# currently not implemented
dm, R_interior, R_bc = DoFMap.getFullDoFMap(dm2)
A = getFracLapl(mesh, dm, kernel, rangedOpParams={}, **kwargs)
A = getFracLapl(dm, kernel, rangedOpParams={}, **kwargs)
A = R_interior*A*R_bc.transpose()
return A
builder = nonlocalBuilder(mesh, DoFMap, kernel, params, zeroExterior=zeroExterior, comm=comm, logging=logging, PLogger=PLogger, dm2=dm2)
builder = nonlocalBuilder(DoFMap, kernel, params, zeroExterior=zeroExterior, comm=comm, logging=logging, PLogger=PLogger, dm2=dm2)
if diagonal:
with timer('Assemble diagonal matrix {}, zeroExterior={}'.format(kernel, zeroExterior)):
A = builder.getDiagonal()
Expand Down Expand Up @@ -343,7 +344,7 @@ def build(self, buildType):
self.params['assemblyComm'] = self.comm
self.params['assembleOnRoot'] = False
self.params['forceUnsymmetric'] = True
self.S = getFracLapl(mesh, DoFMap, **self.params)
self.S = getFracLapl(DoFMap, **self.params)
self.A = self.S
# if not s.symmetric:
# from PyNucleus_base.linear_operators import Dense_LinearOperator
Expand Down Expand Up @@ -650,10 +651,9 @@ def construct(self):


class delayedFractionalLaplacianOp(delayedConstructionOperator):
def __init__(self, mesh, dm, kernel, **kwargs):
def __init__(self, dm, kernel, **kwargs):
super().__init__(dm.num_dofs,
dm.num_dofs)
self.mesh = mesh
self.dm = dm
self.kernel = kernel
self.kwargs = kwargs
Expand All @@ -662,7 +662,7 @@ def construct(self):
from copy import copy
d = copy(self.kwargs)
d.update(self.params)
A = getFracLapl(self.mesh, self.dm, self.kernel, **d)
A = getFracLapl(self.dm, self.kernel, **d)
return A


8 changes: 4 additions & 4 deletions nl/PyNucleus_nl/nonlocalAssembly.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ cdef class horizonCorrected(TimeStepperLinearOperator):
if Ainf is None:
scaling = constantTwoPoint(0.5)
infiniteKernel = kernel.getModifiedKernel(horizon=constant(np.inf), scaling=scaling)
infBuilder = nonlocalBuilder(self.mesh, self.dm, infiniteKernel, zeroExterior=True, comm=self.comm, logging=self.logging)
infBuilder = nonlocalBuilder(self.dm, infiniteKernel, zeroExterior=True, comm=self.comm, logging=self.logging)
self.Ainf = infBuilder.getH2()
else:
self.Ainf = Ainf
Expand Down Expand Up @@ -233,7 +233,7 @@ cdef class horizonCorrected(TimeStepperLinearOperator):
self.kernel = kernel

complementKernel = kernel.getComplementKernel()
builder = nonlocalBuilder(self.mesh, self.dm, complementKernel, zeroExterior=True, comm=self.comm, logging=self.logging)
builder = nonlocalBuilder(self.dm, complementKernel, zeroExterior=True, comm=self.comm, logging=self.logging)
correction = builder.getH2()

self.S = self.Ainf
Expand Down Expand Up @@ -363,7 +363,7 @@ def assembleNonlocalOperator(meshBase mesh,
MPI.Comm comm=None,
**kwargs):
kernel = getFractionalKernel(mesh.dim, s, horizon)
builder = nonlocalBuilder(mesh, dm, kernel, params, zeroExterior, comm, **kwargs)
builder = nonlocalBuilder(dm, kernel, params, zeroExterior, comm, **kwargs)
return builder.getDense()


Expand Down Expand Up @@ -487,7 +487,7 @@ def assembleNearField(list Pnear,
comm=None,
**kwargs):
kernel = getFractionalKernel(mesh.dim, s, horizon)
builder = nonlocalBuilder(mesh, dm, kernel, params, zeroExterior, comm, logging=True, **kwargs)
builder = nonlocalBuilder(dm, kernel, params, zeroExterior, comm, logging=True, **kwargs)
A = builder.assembleClusters(Pnear)
return A

Expand Down
3 changes: 0 additions & 3 deletions nl/PyNucleus_nl/nonlocalAssembly_{SCALAR}.pxi
Original file line number Diff line number Diff line change
Expand Up @@ -858,7 +858,6 @@ cdef class {SCALAR_label}IndexManagerMixed({SCALAR_label}IndexManager):

cdef class {SCALAR_label}nonlocalBuilder:
def __init__(self,
meshBase mesh,
DoFMap dm,
{SCALAR_label}Kernel kernel,
dict params={},
Expand All @@ -875,7 +874,6 @@ cdef class {SCALAR_label}nonlocalBuilder:

self.dm = dm
self.mesh = self.dm.mesh
assert self.dm.mesh == mesh
if dm2 is not None:
self.dm2 = dm2
assert type(self.dm) == type(self.dm2)
Expand All @@ -889,7 +887,6 @@ cdef class {SCALAR_label}nonlocalBuilder:
self.params = params

assert isinstance(self.kernel.horizon, constant), "Need horizon to be constant."
assert kernel.dim == mesh.dim, "Kernel dimension must match mesh dimension"
assert kernel.dim == dm.mesh.dim, "Kernel dimension must match dm.mesh dimension"

# volume integral
Expand Down
6 changes: 3 additions & 3 deletions tests/test_fracLapl.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,8 @@ def scaling(dim, s, horizon, refinements):
kernel2 = getFractionalKernel(mesh.dim, s, horizon, scaling=scaling)
print(kernel1, kernel2)
zeroExterior = not np.isfinite(horizon.value)
builder1 = nonlocalBuilder(mesh, dm, kernel1, zeroExterior=zeroExterior)
builder2 = nonlocalBuilder(mesh, dm, kernel2, zeroExterior=zeroExterior)
builder1 = nonlocalBuilder(dm, kernel1, zeroExterior=zeroExterior)
builder2 = nonlocalBuilder(dm, kernel2, zeroExterior=zeroExterior)
A = builder1.getDense().toarray()
B = builder2.getDense().toarray()
assert np.allclose(A, B)
Expand Down Expand Up @@ -160,7 +160,7 @@ def h2(dim, s, refinements, element, errBnd, genKernel=False):
params['eta'] = eta
params['maxLevels'] = maxLevels
kernel = getFractionalKernel(mesh.dim, s, constant(np.inf))
builder = nonlocalBuilder(mesh, DoFMap_fine, kernel, params=params, zeroExterior=True)
builder = nonlocalBuilder(DoFMap_fine, kernel, params=params, zeroExterior=True)

A_d = np.array(builder.getDense().data)
A_h2 = builder.getH2()
Expand Down
Loading