Example #1
0
    def __init__(self,
                 nn=3,
                 relax='J',
                 eps=1e-24,
                 classical_material=None,
                 cell=None,
                 qm_spacing=0.30,
                 cl_spacing=1.20,
                 remove_moments=(1, 1),
                 potential_coupler='Refiner',
                 communicator=serial_comm):

        self.rank = mpi.rank

        self.messages = []

        assert (potential_coupler in ['Multipoles', 'Refiner'])
        self.potential_coupling_scheme = potential_coupler

        if classical_material is None:
            self.classical_material = PolarizableMaterial()
        else:
            self.classical_material = classical_material

        self.set_calculation_mode('solve')

        self.has_subsystems = False
        self.remove_moment_cl = remove_moments[0]
        self.remove_moment_qm = remove_moments[1]
        self.time = 0.0
        self.time_step = 0.0
        self.kick = np.array([0.0, 0.0, 0.0], dtype=float)
        self.maxiter = 2000
        self.eps = eps
        self.relax = relax
        self.nn = nn

        # Only handle the quantities via self.qm or self.cl
        self.cl = PoissonOrganizer()
        self.cl.spacing_def = cl_spacing * np.ones(3) / Bohr
        self.cl.extrapolated_qm_phi = None
        self.cl.dcomm = communicator
        self.cl.dparsize = None
        self.qm = PoissonOrganizer(FDPoissonSolver)  # Default solver
        self.qm.spacing_def = qm_spacing * np.ones(3) / Bohr
        self.qm.cell = np.array(cell) / Bohr

        # Classical spacing and simulation cell
        _cell = np.array(cell) / Bohr
        self.cl.spacing = self.cl.spacing_def
        if np.size(_cell) == 3:
            self.cl.cell = np.diag(_cell)
        else:
            self.cl.cell = _cell

        # Generate classical grid descriptor
        self.initialize_clgd()
Example #2
0
# Whole simulation cell (Angstroms)
large_cell = np.array([3 * radius, 3 * radius, 3 * radius])

# Permittivity of Gold
# J. Chem. Phys. 135, 084121 (2011); http://dx.doi.org/10.1063/1.3626549
gold = [[0.2350, 0.1551, 95.62],
        [0.4411, 0.1480, -12.55],
        [0.7603, 1.946, -40.89],
        [1.161, 1.396, 17.22],
        [2.946, 1.183, 15.76],
        [4.161, 1.964, 36.63],
        [5.747, 1.958, 22.55],
        [7.912, 1.361, 81.04]]

# Initialize classical material
classical_material = PolarizableMaterial()

# Classical nanosphere
classical_material.add_component(
    PolarizableSphere(center=0.5 * large_cell,
                      radius=radius,
                      permittivity=PermittivityPlus(data=gold)))

# Quasistatic FDTD
qsfdtd = QSFDTD(classical_material=classical_material,
                atoms=None,
                cells=large_cell,
                spacings=[8.0, 1.0],
                communicator=world,
                remove_moments=(4, 1))
Example #3
0
    def read(self, reader):
        r = reader.hamiltonian.poisson

        # FDTDPoissonSolver related data
        self.description = r.description
        self.time = r.time
        self.time_step = r.time_step

        # Try to read time-dependent information
        self.kick = r.kick
        self.maxiter = r.maxiter

        # PoissonOrganizer: classical
        self.cl = PoissonOrganizer()
        self.cl.spacing_def = r.cl_spacing_def
        self.cl.spacing = r.cl_spacing
        self.cl.cell = np.diag(r.cl_cell)
        self.cl.dparsize = None

        # TODO: it should be possible to use different
        #       communicator after restart
        if r.cl_world_comm:
            self.cl.dcomm = world
        else:
            self.cl.dcomm = mpi.serial_comm

        # Generate classical grid descriptor
        self.initialize_clgd()

        # Classical materials data
        self.classical_material = PolarizableMaterial()
        self.classical_material.read(r)
        self.classical_material.initialize(self.cl.gd)

        # PoissonOrganizer: quantum
        self.qm = PoissonOrganizer()
        self.qm.corner1 = r.qm_corner1
        self.qm.corner2 = r.qm_corner2
        self.given_corner_v1 = r.given_corner_1
        self.given_corner_v2 = r.given_corner_2
        self.given_cell = np.diag(r.given_cell)
        self.hratios = r.hratios
        self.shift_indices_1 = r.shift_indices_1.astype(int)
        self.shift_indices_2 = r.shift_indices_2.astype(int)
        self.num_indices = r.num_indices.astype(int)
        self.num_refinements = int(r.num_refinements)

        # Redefine atoms to suit the cut_cell routine
        newatoms = read_atoms(reader.atoms)
        newatoms.positions = newatoms.positions + self.qm.corner1 * Bohr
        newatoms.set_cell(np.diag(self.given_cell))
        self.create_subsystems(newatoms)

        # Read self.classical_material.charge_density
        if self.cl.gd.comm.rank == 0:
            big_charge_density = \
                np.array(r.get('classical_material_rho'), dtype=float)
        else:
            big_charge_density = None
        self.cl.gd.distribute(big_charge_density,
                              self.classical_material.charge_density)

        # Read self.classical_material.polarization_total
        if self.cl.gd.comm.rank == 0:
            big_polarization_total = \
                np.array(r.get('polarization_total'), dtype=float)
        else:
            big_polarization_total = None
        self.cl.gd.distribute(big_polarization_total,
                              self.classical_material.polarization_total)

        # Read self.classical_material.polarizations
        if self.cl.gd.comm.rank == 0:
            big_polarizations = np.array(r.get('polarizations'), dtype=float)
        else:
            big_polarizations = None
        self.cl.gd.distribute(big_polarizations,
                              self.classical_material.polarizations)

        # Read self.classical_material.currents
        if self.cl.gd.comm.rank == 0:
            big_currents = np.array(r.get('currents'), dtype=float)
        else:
            big_currents = None
        self.cl.gd.distribute(big_currents, self.classical_material.currents)
Example #4
0
    def read(self, paw, reader):
        r = reader

        version = r['version']

        # Helper function
        def read_vector(v):
            return np.array([
                float(x) for x in v.replace('[', '').replace(']', '').split()
            ])

        # FDTDPoissonSolver related data
        self.eps = r['fdtd.eps']
        self.nn = r['fdtd.nn']
        self.relax = r['fdtd.relax']
        self.potential_coupling_scheme = r['fdtd.coupling_scheme']
        self.description = r['fdtd.description']
        self.remove_moment_qm = int(r['fdtd.remove_moment_qm'])
        self.remove_moment_cl = int(r['fdtd.remove_moment_cl'])
        self.time = float(r['fdtd.time'])
        self.time_step = float(r['fdtd.time_step'])

        # Try to read time-dependent information
        self.kick = read_vector(r['fdtd.kick'])
        self.maxiter = int(r['fdtd.maxiter'])

        # PoissonOrganizer: classical
        self.cl = PoissonOrganizer()
        self.cl.spacing_def = read_vector(r['fdtd.cl_spacing_def'])
        self.cl.spacing = read_vector(r['fdtd.cl_spacing'])
        self.cl.cell = np.diag(read_vector(r['fdtd.cl_cell']))
        self.cl.dparsize = None

        # TODO: it should be possible to use different
        #       communicator after restart
        if r['fdtd.cl_world_comm']:
            self.cl.dcomm = world
        else:
            self.cl.dcomm = mpi.serial_comm

        # Generate classical grid descriptor
        self.initialize_clgd()

        # Classical materials data
        self.classical_material = PolarizableMaterial()
        self.classical_material.read(r)
        self.classical_material.initialize(self.cl.gd)

        # PoissonOrganizer: quantum
        self.qm = PoissonOrganizer()
        self.qm.corner1 = read_vector(r['fdtd.qm_corner1'])
        self.qm.corner2 = read_vector(r['fdtd.qm_corner2'])
        self.given_corner_v1 = read_vector(r['fdtd.given_corner_1'])
        self.given_corner_v2 = read_vector(r['fdtd.given_corner_2'])
        self.given_cell = np.diag(read_vector(r['fdtd.given_cell']))
        self.hratios = read_vector(r['fdtd.hratios'])
        self.shift_indices_1 = read_vector(r['fdtd.shift_indices_1'])
        self.shift_indices_2 = read_vector(r['fdtd.shift_indices_2'])
        self.num_indices = read_vector(r['fdtd.num_indices'])
        self.num_refinements = int(r['fdtd.num_refinements'])

        # Redefine atoms to suit the cut_cell routine
        newatoms = paw.atoms.copy()
        newatoms.positions = newatoms.positions + self.qm.corner1 * Bohr
        newatoms.set_cell(np.diag(self.given_cell))
        self.create_subsystems(newatoms)

        # Read self.classical_material.charge_density
        if self.cl.gd.comm.rank == 0:
            big_charge_density = np.array(r.get('classical_material_rho'),
                                          dtype=float)
        else:
            big_charge_density = None
        self.cl.gd.distribute(big_charge_density,
                              self.classical_material.charge_density)

        # Read self.classical_material.polarization_total
        if self.cl.gd.comm.rank == 0:
            big_polarization_total = np.array(r.get('polarization_total'),
                                              dtype=float)
        else:
            big_polarization_total = None
        self.cl.gd.distribute(big_polarization_total,
                              self.classical_material.polarization_total)

        # Read self.classical_material.polarizations
        if self.cl.gd.comm.rank == 0:
            big_polarizations = np.array(r.get('polarizations'), dtype=float)
        else:
            big_polarizations = None
        self.cl.gd.distribute(big_polarizations,
                              self.classical_material.polarizations)

        # Read self.classical_material.currents
        if self.cl.gd.comm.rank == 0:
            big_currents = np.array(r.get('currents'), dtype=float)
        else:
            big_currents = None
        self.cl.gd.distribute(big_currents, self.classical_material.currents)