download
raw
5.17 kB
import numpy as np
class Parameters(object):
def __init__(self):
"""
Subclasses must initialize self.prm with
parameters and default values, self.type with
the corresponding types, and self.help with
the corresponding descriptions of parameters.
self.type and self.help are optional, but
self.prms must be complete and contain all parameters.
"""
pass
def ok(self):
"""Check if attr. prm, type, and help are defined."""
if hasattr(self, 'prm') and \
isinstance(self.prm, dict) and \
hasattr(self, 'type') and \
isinstance(self.type, dict) and \
hasattr(self, 'help') and \
isinstance(self.help, dict):
return True
else:
raise ValueError(
'The constructor in class %s does not '\
'initialize the\ndictionaries '\
'self.prm, self.type, self.help!' %
self.__class__.__name__)
def _illegal_parameter(self, name):
"""Raise exception about illegal parameter name."""
raise ValueError(
'parameter "%s" is not registered.\nLegal '\
'parameters are\n%s' %
(name, ' '.join(list(self.prm.keys()))))
def set(self, **parameters):
"""Set one or more parameters."""
for name in parameters:
if name in self.prm:
self.prm[name] = parameters[name]
else:
self._illegal_parameter(name)
def get(self, name):
"""Get one or more parameter values."""
if isinstance(name, (list,tuple)): # get many?
for n in name:
if n not in self.prm:
self._illegal_parameter(name)
return [self.prm[n] for n in name]
else:
if name not in self.prm:
self._illegal_parameter(name)
return self.prm[name]
def __getitem__(self, name):
"""Allow obj[name] indexing to look up a parameter."""
return self.get(name)
def __setitem__(self, name, value):
"""Allow obj[name] = valye syntax to assign a parameter's value."""
return self.set(name=value)
def define_command_line_options(self, parser=None):
self.ok()
if parser is None:
import argparse
parser = argparse.ArgumentParser()
for name in self.prm:
tp = self.type[name] if name in self.type else str
help = self.help[name] if name in self.help else None
parser.add_argument(
'--' + name, default=self.get(name), metavar=name,
type=tp, help=help)
return parser
def init_from_command_line(self, args):
for name in self.prm:
self.prm[name] = getattr(args, name)
class Problem(Parameters):
"""
Physical parameters for the problem u'=-a*u, u(0)=I,
with t in [0,T].
"""
def __init__(self):
self.prm = dict(I=1, a=1, T=10)
self.type = dict(I=float, a=float, T=float)
self.help = dict(I='initial condition, u(0)',
a='coefficient in ODE',
T='end time of simulation')
def u_exact(self, t):
I, a = self['I a'.split()]
return I*np.exp(-a*t)
class Solver(Parameters):
"""
Numerical parameters and algorithm for solving u'=-au by the
theta rule.
"""
def __init__(self, problem):
self.problem = problem
self.prm = dict(dt=0.5, theta=0.5)
self.type = dict(dt=float, theta=float)
self.help = dict(dt='time step value',
theta='time discretization parameter')
def solve(self):
from decay import solver
I, a, T = self.problem['I a T'.split()]
dt, theta = self['dt theta'.split()]
self.u, self.t = solver(I, a, T, dt, theta)
def error(self):
try:
u_e = self.problem.u_exact(self.t)
e = u_e - self.u
E = np.sqrt(self.get('dt')*np.sum(e**2))
except AttributeError:
E = None
return E
def experiment_classes():
problem = Problem()
solver = Solver(problem)
# Read input from the command line
parser = problem.define_command_line_options()
parser = solver. define_command_line_options(parser)
args = parser.parse_args()
problem.init_from_command_line(args)
solver. init_from_command_line(args)
# Solve and plot
solver.solve()
u, t = solver.u, solver.t
print 'Error norm:', solver.error()
import matplotlib.pyplot as plt
t_e = np.linspace(0, problem['T'], 1001) # very fine mesh for u_e
u_e = problem.u_exact(t_e)
plt.plot(t, u, 'r--o') # dashed red line with circles
plt.plot(t_e, u_e, 'b-') # blue line for u_e
plt.legend(['numerical, theta=%g' % solver['theta'], 'exact'])
plt.xlabel('t')
plt.ylabel('u')
plotfile = 'tmp'
plt.savefig(plotfile + '.png'); plt.savefig(plotfile + '.pdf')
plt.show()
if __name__ == '__main__':
experiment_classes()

Xet Storage Details

Size:
5.17 kB
·
Xet hash:
6a77d1d480d131df9821faefa59a4a601c7c9b1ef9fc407323d3879a0f4c65a4

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.