Exemplo n.º 1
0
 def __init__(self, atoms=None):
     """
     Parameters:
         atoms: ASE Atoms
             The full system. You can later on define it with set_atoms, or
             provide it directly in get_potential_energy()/get_forces().
     """
     self.total_timer = Timer(["total"])
     self.total_timer.start("total")
     self.subsystem_energies = {}
     self.subsystems = {}
     self.subsystem_interactions = {}
     self.subsystem_info = {}
     self.interaction_info = {}
     self.forces = None
     self.stress = None
     self.potential_energy = None
     self.system_initialized = False
     if atoms is not None:
         self.atoms = atoms.copy()
     else:
         self.atoms = None
Exemplo n.º 2
0
    def __init__(
            self,
            full_system,
            primary_subsystem,
            secondary_subsystem,
            info):
        """
        Parameters:
            full_system: ASE Atoms
            primary_subsystem: :class:`~pysic.subsystem.SubSystem`
            secondary_subsystem: :class:`~pysic.subsystem.SubSystem`
            info: :class:`~pysic.interaction.Interaction`
        """
        self.info = info
        self.full_system = full_system
        self.primary_subsystem = primary_subsystem
        self.secondary_subsystem = secondary_subsystem

        self.uncorrected_interaction_energy = None
        self.uncorrected_interaction_forces = None
        self.link_atom_correction_energy = None
        self.link_atom_correction_forces = None
        self.interaction_energy = None
        self.interaction_forces = None

        # Determine if any potentials have been set
        self.has_interaction_potentials = False
        if self.info.comb_potential_enabled:
            self.has_interaction_potentials = True
        if self.info.coulomb_potential_enabled:
            self.has_interaction_potentials = True
        if len(self.info.potentials) != 0:
            self.has_interaction_potentials = True

        self.calculator = Pysic()
        self.pbc_calculator = Pysic()

        self.timer = Timer([
            "Interaction",
            "Interaction (PBC)",
            "Forces",
            "Forces (PBC)",
            "Link atom correction energy",
            "Link atom correction forces"])

        # The interaction needs to know if PBC:s are on
        pbc = primary_subsystem.atoms_for_interaction.get_pbc()
        if pbc[0] or pbc[1] or pbc[2]:
            self.has_pbc = True
        else:
            self.has_pbc = False

        # Initialize hydrogen links
        self.link_atoms = None
        self.setup_hydrogen_links(info.links)

        # Store the number of atoms in different systems
        self.n_primary = len(primary_subsystem.atoms_for_interaction)
        self.n_secondary = len(secondary_subsystem.atoms_for_interaction)
        self.n_full = self.n_primary + self.n_secondary
        if self.link_atoms is not None:
            self.n_links = len(self.link_atoms)
        else:
            self.n_links = 0

        # Initialize the COMB potential first (set_potentials(COMB) is used,
        # because it isn' the same as add_potential(COMB))
        if info.comb_potential_enabled:
            self.setup_comb_potential()

        # Initialize the coulomb interaction
        if info.electrostatic_parameters is not None:
            self.setup_coulomb_potential()

        # Add the other potentials
        self.setup_potentials()

        # Can't enable link atom correction on system without link atoms
        if len(info.links) == 0:
            self.info.link_atom_correction_enabled = False
Exemplo n.º 3
0
    def __init__(self, atoms, info, index_map, reverse_index_map, n_atoms):
        """
        Parameters:
            atoms: ASE Atoms
                The subsystem atoms.
            info: SubSystem object
                Contains all the information about the subsystem
            index_map: dictionary of int to int
                The keys are the atom indices in the full system, values are
                indices in the subssystem.
            reverse_index_map: dicitonary of int to int
                The keys are the atom indices in the subsystem, values are the
                keys in the full system.
            n_atoms: int
                Number of atoms in the full system.
        """
        # Extract data from info
        self.name = info.name
        self.calculator = copy.copy(info.calculator)
        self.cell_size_optimization_enabled = info.cell_size_optimization_enabled
        self.cell_padding = info.cell_padding
        self.charge_calculation_enabled = info.charge_calculation_enabled
        self.charge_source = info.charge_source
        self.division = info.division
        self.gridrefinement = info.gridrefinement

        self.n_atoms = n_atoms
        self.atoms_for_interaction = atoms.copy()
        self.atoms_for_subsystem = atoms.copy()
        self.index_map = index_map
        self.reverse_index_map = reverse_index_map
        self.potential_energy = None
        self.forces = None
        self.density_grid = None
        self.pseudo_density = None
        self.link_atom_indices = []
        self.timer = Timer([
            "Bader charge calculation", "van Der Waals charge calculation",
            "Energy", "Forces", "Density grid update", "Cell minimization"
        ])

        # The older ASE versions do not support get_initial_charges()
        try:
            charges = np.array(atoms.get_initial_charges())
        except:
            charges = np.array(atoms.get_charges())
        self.initial_charges = charges

        ## Can't enable charge calculation on non-DFT calculator
        self.dft_system = hasattr(self.calculator, "get_pseudo_density")
        if self.charge_calculation_enabled is True and not self.dft_system:
            error("Can't enable charge calculation on non-DFT calculator!")

        # If the cell size minimization flag has been enabled, then try to reduce the
        # cell size
        if self.cell_size_optimization_enabled:
            pbc = atoms.get_pbc()
            if pbc[0] or pbc[1] or pbc[2]:
                warn(("Cannot optimize cell size when periodic boundary"
                      "condition have been enabled, disabling optimization."),
                     2)
                self.cell_size_optimization_enabled = False
            else:
                self.optimize_cell()