Source code for WaveBlocksND.ParameterProvider
"""The WaveBlocks Project
A special container data structure to store simulation parameters.
The structure is similar to a python dict but provides some more
features like fetching undefined values from a global configuration.
@author: R. Bourquin
@copyright: Copyright (C) 2010, 2011, 2016 R. Bourquin
@license: Modified BSD License
"""
from copy import deepcopy
from WaveBlocksND import GlobalDefaults
from WaveBlocksND.BlockFactory import BlockFactory
from WaveBlocksND.TimeManager import TimeManager
__all__ = ["ParameterProvider"]
[docs]class ParameterProvider(object):
def __init__(self):
#: Dict for storing the configuration parameters.
self._params = {}
def __getattr__(self, key):
print(" Depreceated __getattr__ for key '{}' at ParameterProvider instance!".format(key))
return self._params[key]
def __getitem__(self, key):
# See if we have a parameter with specified name
if key in self._params:
return self._params[key]
else:
# If not, try to find a global default value for it and copy over this value
print("Warning: parameter '{}' not found, now trying global defaults!".format(key))
if key in GlobalDefaults.__dict__:
self.__setitem__(key, deepcopy(GlobalDefaults.__dict__[key]))
return self._params[key]
else:
raise KeyError("Could not find a default value for parameter {}!".format(key))
def __setitem__(self, key, value):
self._params[key] = deepcopy(value)
def __contains__(self, key):
return key in self._params
def __iter__(self):
# For iteration over the parameter key-value pairs
for item in self._params.items():
yield item
def __repr__(self):
return "A ParameterProvider instance."
def has_key(self, key):
return key in self._params
def get(self, key, default):
return self._params.get(key, default)
[docs] def compute_parameters(self):
"""Compute some further parameters from the given ones.
"""
# Perform the computation only if the basic values are available.
# This is necessary to add flexibility and essentially read in *any*
# parameter file with heavily incomplete value sets. (F.e. spawn configs)
try:
# The number of time steps we will perform.
tm = TimeManager(self)
self._params["nsteps"] = tm.compute_number_timesteps()
except:
pass
if "potential" in self._params:
# Ugly hack. Should improve handling of potential libraries
Potential = BlockFactory().create_potential(self)
# Number of components of $\Psi$
self._params["ncomponents"] = Potential.get_number_components()
[docs] def set_parameters(self, params):
r"""Overwrite the dict containing all parameters with a
newly provided dict with (possibly) changed parameters.
:param params: A :py:class:`ParameterProvider` instance or a dict
with new parameters. The values will be deep-copied.
No old values will remain.
"""
if not isinstance(params, dict):
try:
params = params.get_parameters()
except:
raise TypeError("Wrong data type for set_parameters.")
assert type(params) == dict
self._params = deepcopy(params)
# Compute some values on top of the given input parameters
self.compute_parameters()
[docs] def update_parameters(self, params):
r"""Overwrite the dict containing all parameters with a
newly provided dict with (possibly) changed parameters.
:param params: A :py:class:`ParameterProvider` instance or a dict
with new parameters. The values will be deep-copied.
Old values are only overwritten if we have got new values.
"""
if not isinstance(params, dict):
try:
params = params.get_parameters()
except:
raise TypeError("Wrong data type for update_parameters.")
for key, value in params.items():
self.__setitem__(key, value)
# Compute some values on top of the given input parameters
self.compute_parameters()
[docs] def get_timemanager(self):
r"""Return the embedded :py:class:`TimeManager` instance.
"""
return TimeManager(self._params)
[docs] def get_parameters(self):
"""Return a copy of the dict containing all parameters.
:return: A copy of the dict containing all parameters. The dict will be copied.
"""
return deepcopy(self._params)
def __str__(self):
try:
s = "====================================\n"
s += "Parameters of the current simulation\n"
s += "------------------------------------\n"
s += " Propagation algorithm: " + str(self._params["algorithm"]) + "\n"
s += " scheme: " + str(self._params["propagator"]) + "\n"
s += " Potential: " + str(self._params["potential"]) + "\n"
s += " Number components: " + str(self._params["ncomponents"]) + "\n"
s += "\n"
s += " Timestepping:\n"
s += " Final simulation time: " + str(self._params["T"]) + "\n"
s += " Time step size: " + str(self._params["dt"]) + "\n"
s += " Number of timesteps: " + str(self._params["nsteps"]) + "\n"
s += "\n"
s += " I/O related:\n"
s += " Write results every step (0 = never): " + str(self._params["write_nth"]) + "\n"
s += " Write results at time/timesteps (additionally): " + str(self._params["save_at"]) + "\n"
except KeyError:
pass
s += "------------------------------------\n"
s += "All parameters provided\n"
s += "------------------------------------\n"
keys = list(self._params.keys())
keys.sort()
for key in keys:
s += " " + str(key) + ": " + str(self._params[key]) + "\n"
s += "====================================\n"
return s