Source code for WaveBlocksND.BlockFactory


"""The WaveBlocks Project

This file contains a the block factory.

@author: R. Bourquin
@copyright: Copyright (C) 2012, 2013, 2014, 2016 R. Bourquin
@license: Modified BSD License
"""

from copy import deepcopy

__all__ = ["BlockFactory"]


[docs]class BlockFactory(object): """A factory to create instances of various classes based on a simple description ``dict``. """ def __init__(self): # Load different factory methods from WaveBlocksND import GridFactory self.__dict__["create_grid"] = GridFactory.create_grid from WaveBlocksND import PotentialFactory self.__dict__["create_potential"] = PotentialFactory.create_potential from WaveBlocksND import MatrixExponentialFactory self.__dict__["create_matrixexponential"] = MatrixExponentialFactory.create_matrixexponential # TODO: Consider "local" vs "global" description dicts # TODO: Consider putting defaults into "GlobalDefaults" def create_basis_shape(self, description): try: bs_type = description["type"] except: # Default setting bs_type = "HyperCubicShape" if bs_type == "HyperCubicShape": from WaveBlocksND.HyperCubicShape import HyperCubicShape limits = description["limits"] BS = HyperCubicShape(limits) elif bs_type == "SimplexShape": from WaveBlocksND.SimplexShape import SimplexShape K = description["K"] D = description["dimension"] BS = SimplexShape(D, K) elif bs_type == "HyperbolicCutShape": from WaveBlocksND.HyperbolicCutShape import HyperbolicCutShape K = description["K"] D = description["dimension"] BS = HyperbolicCutShape(D, K) else: raise ValueError("Unknown basis shape type {}".format(bs_type)) return BS def create_wavepacket(self, description): wp_type = description["type"] if wp_type == "HagedornWavepacket": from WaveBlocksND.HagedornWavepacket import HagedornWavepacket # Initialize a packet WP = HagedornWavepacket(description["dimension"], description["ncomponents"], description["eps"]) # Set parameters if "Pi" in description: Pi = description["Pi"] WP.set_parameters(Pi) # Configure basis shapes if "basis_shapes" in description: for component, shapedescr in enumerate(description["basis_shapes"]): BS = self.create_basis_shape(shapedescr) WP.set_basis_shapes(BS, component=component) # Set coefficients if "coefficients" in description: for component, data in enumerate(description["coefficients"]): BS = WP.get_basis_shapes(component=component) for index, value in data: if BS.contains(index): WP.set_coefficient(component, index, value) else: print("Warning: dropped coefficient with index {}".format(index)) # And the inner product if "innerproduct" in description: IP = self.create_inner_product(description["innerproduct"]) WP.set_innerproduct(IP) else: print("Warning: no inner product specified!") elif wp_type == "HagedornWavepacketInhomogeneous": from WaveBlocksND.HagedornWavepacketInhomogeneous import HagedornWavepacketInhomogeneous # Initialize a packet WP = HagedornWavepacketInhomogeneous(description["dimension"], description["ncomponents"], description["eps"]) # Set parameters if "Pi" in description: Pi = description["Pi"] WP.set_parameters(Pi) # Configure basis shapes if "basis_shapes" in description: for component, shapedescr in enumerate(description["basis_shapes"]): BS = self.create_basis_shape(shapedescr) WP.set_basis_shapes(BS, component=component) # Set coefficients if "coefficients" in description: for component, data in enumerate(description["coefficients"]): for index, value in data: WP.set_coefficient(component, index, value) # And the quadrature if "innerproduct" in description: IP = self.create_inner_product(description["innerproduct"]) WP.set_innerproduct(IP) else: print("Warning: no inner product specified!") else: raise ValueError("Unknown wavepacket type {}".format(wp_type)) return WP def create_inner_product(self, description): # try: ip_type = description["type"] except: # Default setting print("Warning: Using fall-back inner product of type 'InhomogeneousInnerProduct'!") # TODO: Maybe change to homogeneous one? ip_type = "InhomogeneousInnerProduct" if ip_type == "HomogeneousInnerProduct": from WaveBlocksND.HomogeneousInnerProduct import HomogeneousInnerProduct QE = self.create_quadrature(description["delegate"]) IP = HomogeneousInnerProduct(QE) elif ip_type == "InhomogeneousInnerProduct": from WaveBlocksND.InhomogeneousInnerProduct import InhomogeneousInnerProduct QE = self.create_quadrature(description["delegate"]) IP = InhomogeneousInnerProduct(QE) else: raise ValueError("Unknown inner product type {}".format(ip_type)) return IP def create_quadrature(self, description): # NOTE: The difference between Quadrature and InnerProduct here # is for backward compatibility but will be removed soon. try: qe_type = description["type"] except: # Default setting qe_type = "DirectInhomogeneousQuadrature" # TODO: Maybe denest QR initialization? if qe_type == "DirectHomogeneousQuadrature": from WaveBlocksND.DirectHomogeneousQuadrature import DirectHomogeneousQuadrature QR = self.create_quadrature_rule(description["qr"]) QE = DirectHomogeneousQuadrature(QR) elif qe_type == "DirectInhomogeneousQuadrature": from WaveBlocksND.DirectInhomogeneousQuadrature import DirectInhomogeneousQuadrature QR = self.create_quadrature_rule(description["qr"]) QE = DirectInhomogeneousQuadrature(QR) elif qe_type == "NSDInhomogeneous": from WaveBlocksND.NSDInhomogeneous import NSDInhomogeneous QR = self.create_quadrature_rule(description["qr"]) QE = NSDInhomogeneous(QR) elif qe_type == "SymbolicIntegral": from WaveBlocksND.SymbolicIntegral import SymbolicIntegral QE = SymbolicIntegral() else: raise ValueError("Unknown quadrature type {}".format(qe_type)) return QE def create_quadrature_rule(self, description): qr_type = description["type"] if "options" in description: op = deepcopy(description["options"]) else: # Per default, adapt qr to follow dynamics op = {"transform": True} if qr_type == "GaussHermiteQR": from WaveBlocksND.GaussHermiteQR import GaussHermiteQR order = description["order"] assert type(order) == int QR = GaussHermiteQR(order, options=op) elif qr_type == "GaussHermiteOriginalQR": from WaveBlocksND.GaussHermiteOriginalQR import GaussHermiteOriginalQR order = description["order"] assert type(order) == int QR = GaussHermiteOriginalQR(order, options=op) elif qr_type == "TrapezoidalQR": from WaveBlocksND.TrapezoidalQR import TrapezoidalQR left = description["left"] right = description["right"] order = description["order"] assert type(order) == int QR = TrapezoidalQR(left, right, order, options=op) elif qr_type == "GaussLaguerreQR": from WaveBlocksND.GaussLaguerreQR import GaussLaguerreQR order = description["order"] a = description["a"] assert type(order) == int QR = GaussLaguerreQR(order, a=a, options=op) elif qr_type == "TensorProductQR": from WaveBlocksND.TensorProductQR import TensorProductQR # Iteratively create all quadrature rules necessary qrs = [self.create_quadrature_rule(desc) for desc in description["qr_rules"]] QR = TensorProductQR(qrs, options=op) else: raise ValueError("Unknown quadrature rule type {}".format(qr_type)) return QR def create_propagator(self, description, *args, **kwargs): prop_type = description["propagator"] if prop_type == "fourier": from WaveBlocksND.FourierPropagator import FourierPropagator propagator = FourierPropagator(description, *args, **kwargs) elif prop_type == "chinchen": from WaveBlocksND.ChinChenPropagator import ChinChenPropagator propagator = ChinChenPropagator(description, *args, **kwargs) elif prop_type == "hagedorn": from WaveBlocksND.HagedornPropagator import HagedornPropagator propagator = HagedornPropagator(description, *args, **kwargs) elif prop_type == "semiclassical": from WaveBlocksND.SemiclassicalPropagator import SemiclassicalPropagator propagator = SemiclassicalPropagator(description, *args, **kwargs) elif prop_type == "magnus_split": from WaveBlocksND.MagnusPropagator import MagnusPropagator propagator = MagnusPropagator(description, *args, **kwargs) elif prop_type == "McL42sc": from WaveBlocksND.McL42scPropagator import McL42scPropagator propagator = McL42scPropagator(description, *args, **kwargs) elif prop_type == "McL84sc": from WaveBlocksND.McL84scPropagator import McL84scPropagator propagator = McL84scPropagator(description, *args, **kwargs) elif prop_type == "Pre764sc": from WaveBlocksND.Pre764scPropagator import Pre764scPropagator propagator = Pre764scPropagator(description, *args, **kwargs) elif prop_type == "hagedorn_inhomog": from WaveBlocksND.HagedornPropagatorInhomogeneous import HagedornPropagatorInhomogeneous propagator = HagedornPropagatorInhomogeneous(description, *args, **kwargs) elif prop_type == "hagedorn_psi": from WaveBlocksND.HagedornPropagatorPsi import HagedornPropagatorPsi propagator = HagedornPropagatorPsi(description, *args, **kwargs) else: raise ValueError("Unknown propagator type {}".format(prop_type)) return propagator