Page MenuHomec4science

FenicsHSEngine.py
No OneTemporary

File Metadata

Created
Thu, Oct 31, 21:16

FenicsHSEngine.py

#!/usr/bin/python
import numpy as np
import utilities
from matplotlib import pyplot as plt
import fenics as fen
class FenicsHSEngine:
"""
Fenics-based Hilbert space engine.
"""
def __init__(self, V:"Fenics FE space"):
self.V = V
def name(self) -> str:
"""Class label."""
return self.__class__.__name__
def norm(self, u:"numpy 1D array",
normType : "numpy 2D array, number or str" = "H10") -> float:
"""
Compute general norm of complex-valued function with given dofs.
Args:
u: numpy complex array with function dofs.
normType(optional): Target norm identifier. If matrix, target norm
is one induced by normType. If number, target norm is weighted
H^1 norm with given weight. If string, must be recognizable by
Fenics norm command. Defaults to 'H10'.
Returns:
Norm of the function (non-negative).
"""
if type(normType).__name__[-6:] == "matrix":
return np.abs(u.dot(normType.dot(u).conj())) ** .5
if isinstance(normType, (int, float)):
return (FenicsHSEngine.norm(self, u, "H10")**2
+ (normType * FenicsHSEngine.norm(self, u, "L2"))**2)**.5
uRe = fen.Function(self.V)
uIm = fen.Function(self.V)
uRe.vector()[:] = np.array(np.real(u), dtype = float)
uIm.vector()[:] = np.array(np.imag(u), dtype = float)
return (fen.norm(uRe, normType)**2 + fen.norm(uIm, normType)**2)**.5
def plot(self, u:"numpy 1D array", name : str = "u",
what : "str or list" = 'all', **figspecs):
"""
Do some nice plots of the complex-valued function with given dofs.
Args:
u: numpy complex array with function dofs.
name(optional): Name to be shown as title of the plots. Defaults to
'u'.
what(optional): Which plots to do. If list, can contain 'ABS',
'PHASE', 'REAL', 'IMAG'. If str, same plus wildcard 'ALL'.
Defaults to 'ALL'.
figspecs(optional key args): Optional arguments for matplotlib
figure creation.
"""
if isinstance(what, (str,)):
if what.upper() == 'ALL':
what = ['ABS', 'PHASE', 'REAL', 'IMAG']
else:
what = [what]
what = utilities.purgeList(what, ['ABS', 'PHASE', 'REAL', 'IMAG'],
listname = self.name() + ".what")
if len(what) == 0: return
if 'figsize' not in figspecs.keys():
figspecs['figsize'] = (13. * len(what) / 4, 3)
subplotcode = 100 + len(what) * 10
if not what == ['IMAG']:
uRe = fen.Function(self.V)
uRe.vector()[:] = np.array(np.real(u), dtype = float)
if not what == ['REAL']:
uIm = fen.Function(self.V)
uIm.vector()[:] = np.array(np.imag(u), dtype = float)
if 'REAL' in what and 'IMAG' in what:
combined_data_ReIm = np.concatenate([np.real(u), np.imag(u)])
_min = np.amin(combined_data_ReIm)
_max = np.amax(combined_data_ReIm)
pars = {'vmin' : _min, 'vmax' : _max}
else:
pars = {}
plt.figure(**figspecs)
plt.jet()
if 'ABS' in what:
uAbs = fen.project(np.power(np.power(uRe, 2) + np.power(uIm, 2),
.5), self.V)
subplotcode = subplotcode + 1
plt.subplot(subplotcode)
p = fen.plot(uAbs, title = "|{0}|".format(name))
plt.colorbar(p)
if 'PHASE' in what:
uPhase = fen.project(fen.atan(np.divide(uIm, uRe)), self.V)
subplotcode = subplotcode + 1
plt.subplot(subplotcode)
p = fen.plot(uPhase, title = "phase({0})".format(name))
plt.colorbar(p)
if 'REAL' in what:
subplotcode = subplotcode + 1
plt.subplot(subplotcode)
p = fen.plot(uRe, title = "Re({0})".format(name), **pars)
plt.colorbar(p)
if 'IMAG' in what:
subplotcode = subplotcode + 1
plt.subplot(subplotcode)
p = fen.plot(uIm, title = "Im({0})".format(name), **pars)
plt.colorbar(p)
class FenicsHSAugmentedEngine(FenicsHSEngine):
"""
Fenics-based Hilbert space engine for augmented spaces.
"""
def __init__(self, V:"Fenics FE space", d : int = 2):
self.d = d
FenicsHSEngine.__init__(self, V)
def norm(self, u:"numpy 1D array or list",
normType : "numpy 2D array, number or str" = "H10")\
-> "numpy 1D array":
"""
Compute general norm of complex-valued function with given dofs.
Args:
u: numpy complex array with function dofs.
normType(optional): Target norm identifier. If matrix, target norm
is one induced by normType. If number, target norm is weighted
H^1 norm with given weight. If string, must be recognizable by
Fenics norm command. Defaults to 'H10'.
Returns:
Norms of the function (non-negative).
"""
if isinstance(normType, (int, float)):
u = utilities.listify(u, self.d)
norms = [None] * self.d
for j in range(self.d):
norms[j] = FenicsHSEngine.norm(self, u[j], normType)
return norms
elif type(normType).__name__[-6:] == "matrix":
u = utilities.vectorify(u, self.d)
if normType.shape[0] % u[0] == 0:
N = int(normType.shape[0] / u[0])
else:
raise Exception("Energy matrix dimension mismatch.")
return FenicsHSEngine.norm(self, np.concatenate(u[: N]), normType)
raise Exception("Norm type not recognized.")
def plot(self, u:"numpy 1D array", name : str = "u",
what : "str or list" = 'all', **figspecs) -> list:
"""
Do some nice plots of the complex-valued function with given dofs.
Args:
u: numpy complex array with function dofs.
name(optional): Name to be shown as title of the plots. Defaults to
'u'.
what(optional): Which plots to do. If list, can contain 'ABS',
'PHASE', 'REAL', 'IMAG'. If str, same plus wildcard 'ALL'.
Defaults to 'ALL'.
figspecs(optional key args): Optional arguments for matplotlib
figure creation.
Returns:
List of pyplot figure handles.
"""
u = utilities.listify(u, self.d)
for j in range(self.d):
FenicsHSEngine.plot(self, u[j], what = what,
name = "{0}, comp. {1}".format(name, j),
**figspecs)

Event Timeline