def _make_sparse_precon(self, atoms, initial_assembly=False, force_stab=False): """Create a sparse preconditioner matrix based on the passed atoms. Args: atoms: the Atoms object used to create the preconditioner. Returns: A scipy.sparse.csr_matrix object, representing a d*N by d*N matrix (where N is the number of atoms, and d is the value of self.dim). BE AWARE that using numpy.dot() with this object will result in errors/incorrect results - use the .dot method directly on the sparse matrix instead. """ #print('creating sparse precon: initial_assembly=%r, ' # 'force_stab=%r, apply_positions=%r, apply_cell=%r' % # (initial_assembly, force_stab, self.apply_positions, # self.apply_cell)) N = len(atoms) #start_time = time.time() if self.apply_positions: # compute neighbour list i_list, j_list, rij_list, fixed_atoms = get_neighbours( atoms, self.r_cut) #print('--- neighbour list created in %s s ---' % # (time.time() - start_time)) row = [] col = [] data = [] # precon is mu_c*identity for cell DoF if isinstance(atoms, Filter): i = N - 3 j = N - 2 k = N - 1 x = [3 * i, 3 * i + 1, 3 * i + 2, 3 * j, 3 * j + 1, 3 * j + 2, 3 * k, 3 * k + 1, 3 * k + 2] row.extend(x) col.extend(x) if self.apply_cell: data.extend(np.repeat(self.mu_c, 9)) else: data.extend(np.repeat(self.mu_c, 9)) #print('--- computed triplet format in %s s ---' % # (time.time() - start_time)) conn = sparse.lil_matrix((N, N), dtype=bool) if self.apply_positions and not initial_assembly: if self.morses is not None: for n in range(len(self.morses)): if self.hessian == 'reduced': i, j, Hx = ff.get_morse_potential_reduced_hessian( atoms, self.morses[n]) elif self.hessian == 'spectral': i, j, Hx = ff.get_morse_potential_hessian( atoms, self.morses[n], spectral=True) else: raise NotImplementedError('Not implemented hessian') x = [3 * i, 3 * i + 1, 3 * i + 2, 3 * j, 3 * j + 1, 3 * j + 2] row.extend(np.repeat(x, 6)) col.extend(np.tile(x, 6)) data.extend(Hx.flatten()) conn[i, j] = True conn[j, i] = True if self.bonds is not None: for n in range(len(self.bonds)): if self.hessian == 'reduced': i, j, Hx = ff.get_bond_potential_reduced_hessian( atoms, self.bonds[n], self.morses) elif self.hessian == 'spectral': i, j, Hx = ff.get_bond_potential_hessian( atoms, self.bonds[n], self.morses, spectral=True) else: raise NotImplementedError('Not implemented hessian') x = [3 * i, 3 * i + 1, 3 * i + 2, 3 * j, 3 * j + 1, 3 * j + 2] row.extend(np.repeat(x, 6)) col.extend(np.tile(x, 6)) data.extend(Hx.flatten()) conn[i, j] = True conn[j, i] = True if self.angles is not None: for n in range(len(self.angles)): if self.hessian == 'reduced': i, j, k, Hx = ff.get_angle_potential_reduced_hessian( atoms, self.angles[n], self.morses) elif self.hessian == 'spectral': i, j, k, Hx = ff.get_angle_potential_hessian( atoms, self.angles[n], self.morses, spectral=True) else: raise NotImplementedError('Not implemented hessian') x = [3 * i, 3 * i + 1, 3 * i + 2, 3 * j, 3 * j + 1, 3 * j + 2, 3 * k, 3 * k + 1, 3 * k + 2] row.extend(np.repeat(x, 9)) col.extend(np.tile(x, 9)) data.extend(Hx.flatten()) conn[i, j] = conn[i, k] = conn[j, k] = True conn[j, i] = conn[k, i] = conn[k, j] = True if self.dihedrals is not None: for n in range(len(self.dihedrals)): if self.hessian == 'reduced': i, j, k, l, Hx = \ ff.get_dihedral_potential_reduced_hessian( atoms, self.dihedrals[n], self.morses) elif self.hessian == 'spectral': i, j, k, l, Hx = ff.get_dihedral_potential_hessian( atoms, self.dihedrals[n], self.morses, spectral=True) else: raise NotImplementedError('Not implemented hessian') x = [3 * i, 3 * i + 1, 3 * i + 2, 3 * j, 3 * j + 1, 3 * j + 2, 3 * k, 3 * k + 1, 3 * k + 2, 3 * l, 3 * l + 1, 3 * l + 2] row.extend(np.repeat(x, 12)) col.extend(np.tile(x, 12)) data.extend(Hx.flatten()) conn[i, j] = conn[i, k] = conn[i, l] = conn[ j, k] = conn[j, l] = conn[k, l] = True conn[j, i] = conn[k, i] = conn[l, i] = conn[ k, j] = conn[l, j] = conn[l, k] = True if self.apply_positions: for i, j, rij in zip(i_list, j_list, rij_list): if not conn[i, j]: coeff = self.get_coeff(rij) x = [3 * i, 3 * i + 1, 3 * i + 2] y = [3 * j, 3 * j + 1, 3 * j + 2] row.extend(x + x) col.extend(x + y) data.extend(3 * [-coeff] + 3 * [coeff]) row.extend(range(self.dim * N)) col.extend(range(self.dim * N)) if initial_assembly: data.extend([self.mu * self.c_stab] * self.dim * N) else: data.extend([self.c_stab] * self.dim * N) # create the matrix #start_time = time.time() self.P = sparse.csc_matrix( (data, (row, col)), shape=(self.dim * N, self.dim * N)) #print('--- created CSC matrix in %s s ---' % # (time.time() - start_time)) if not initial_assembly: if len(fixed_atoms) != 0: self.P.tolil() for i in fixed_atoms: self.P[i, :] = 0.0 self.P[:, i] = 0.0 self.P[i, i] = 1.0 self.P = self.P.tocsr() # Create solver if self.use_pyamg: #start_time = time.time() self.ml = smoothed_aggregation_solver( self.P, B=None, strength=('symmetric', {'theta': 0.0}), smooth=( 'jacobi', {'filter': True, 'weighting': 'local'}), improve_candidates=[('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None], aggregate='standard', presmoother=('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}), postsmoother=('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}), max_levels=15, max_coarse=300, coarse_solver='pinv') #print('--- multi grid solver created in %s s ---' % # (time.time() - start_time)) return self.P
def _make_sparse_precon(self, atoms, initial_assembly=False, force_stab=False): """ """ #start_time = time.time() N = len(atoms) row = [] col = [] data = [] if self.morses is not None: for n in range(len(self.morses)): if self.hessian == 'reduced': i, j, Hx = ff.get_morse_potential_reduced_hessian( atoms, self.morses[n]) elif self.hessian == 'spectral': i, j, Hx = ff.get_morse_potential_hessian( atoms, self.morses[n], spectral=True) else: raise NotImplementedError('Not implemented hessian') x = [3 * i, 3 * i + 1, 3 * i + 2, 3 * j, 3 * j + 1, 3 * j + 2] row.extend(np.repeat(x, 6)) col.extend(np.tile(x, 6)) data.extend(Hx.flatten()) if self.bonds is not None: for n in range(len(self.bonds)): if self.hessian == 'reduced': i, j, Hx = ff.get_bond_potential_reduced_hessian( atoms, self.bonds[n], self.morses) elif self.hessian == 'spectral': i, j, Hx = ff.get_bond_potential_hessian( atoms, self.bonds[n], self.morses, spectral=True) else: raise NotImplementedError('Not implemented hessian') x = [3 * i, 3 * i + 1, 3 * i + 2, 3 * j, 3 * j + 1, 3 * j + 2] row.extend(np.repeat(x, 6)) col.extend(np.tile(x, 6)) data.extend(Hx.flatten()) if self.angles is not None: for n in range(len(self.angles)): if self.hessian == 'reduced': i, j, k, Hx = ff.get_angle_potential_reduced_hessian( atoms, self.angles[n], self.morses) elif self.hessian == 'spectral': i, j, k, Hx = ff.get_angle_potential_hessian( atoms, self.angles[n], self.morses, spectral=True) else: raise NotImplementedError('Not implemented hessian') x = [3 * i, 3 * i + 1, 3 * i + 2, 3 * j, 3 * j + 1, 3 * j + 2, 3 * k, 3 * k + 1, 3 * k + 2] row.extend(np.repeat(x, 9)) col.extend(np.tile(x, 9)) data.extend(Hx.flatten()) if self.dihedrals is not None: for n in range(len(self.dihedrals)): if self.hessian == 'reduced': i, j, k, l, Hx = \ ff.get_dihedral_potential_reduced_hessian( atoms, self.dihedrals[n], self.morses) elif self.hessian == 'spectral': i, j, k, l, Hx = ff.get_dihedral_potential_hessian( atoms, self.dihedrals[n], self.morses, spectral=True) else: raise NotImplementedError('Not implemented hessian') x = [3 * i, 3 * i + 1, 3 * i + 2, 3 * j, 3 * j + 1, 3 * j + 2, 3 * k, 3 * k + 1, 3 * k + 2, 3 * l, 3 * l + 1, 3 * l + 2] row.extend(np.repeat(x, 12)) col.extend(np.tile(x, 12)) data.extend(Hx.flatten()) row.extend(range(self.dim * N)) col.extend(range(self.dim * N)) data.extend([self.c_stab] * self.dim * N) # create the matrix #start_time = time.time() self.P = sparse.csc_matrix( (data, (row, col)), shape=(self.dim * N, self.dim * N)) #print('--- created CSC matrix in %s s ---' % # (time.time() - start_time)) fixed_atoms = [] for constraint in atoms.constraints: if isinstance(constraint, FixAtoms): fixed_atoms.extend(list(constraint.index)) else: raise TypeError( 'only FixAtoms constraints are supported by Precon class') if len(fixed_atoms) != 0: self.P.tolil() for i in fixed_atoms: self.P[i, :] = 0.0 self.P[:, i] = 0.0 self.P[i, i] = 1.0 self.P = self.P.tocsr() #print('--- N-dim precon created in %s s ---' % # (time.time() - start_time)) # Create solver if self.use_pyamg: #start_time = time.time() self.ml = smoothed_aggregation_solver( self.P, B=None, strength=('symmetric', {'theta': 0.0}), smooth=( 'jacobi', {'filter': True, 'weighting': 'local'}), improve_candidates=[('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None], aggregate='standard', presmoother=('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}), postsmoother=('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}), max_levels=15, max_coarse=300, coarse_solver='pinv') #print('--- multi grid solver created in %s s ---' % # (time.time() - start_time)) return self.P
def _make_sparse_precon(self, atoms, initial_assembly=False, force_stab=False): """Create a sparse preconditioner matrix based on the passed atoms. Args: atoms: the Atoms object used to create the preconditioner. Returns: A scipy.sparse.csr_matrix object, representing a d*N by d*N matrix (where N is the number of atoms, and d is the value of self.dim). BE AWARE that using numpy.dot() with this object will result in errors/incorrect results - use the .dot method directly on the sparse matrix instead. """ logger.info('creating sparse precon: initial_assembly=%r, ' 'force_stab=%r, apply_positions=%r, apply_cell=%r', initial_assembly, force_stab, self.apply_positions, self.apply_cell) N = len(atoms) start_time = time.time() if self.apply_positions: # compute neighbour list i_list, j_list, rij_list, fixed_atoms = get_neighbours( atoms, self.r_cut) logger.info('--- neighbour list created in %s s ---' % (time.time() - start_time)) row = [] col = [] data = [] # precon is mu_c*identity for cell DoF if isinstance(atoms, Filter): i = N - 3 j = N - 2 k = N - 1 x = [3 * i, 3 * i + 1, 3 * i + 2, 3 * j, 3 * j + 1, 3 * j + 2, 3 * k, 3 * k + 1, 3 * k + 2] row.extend(x) col.extend(x) if self.apply_cell: data.extend(np.repeat(self.mu_c, 9)) else: data.extend(np.repeat(self.mu_c, 9)) logger.info('--- computed triplet format in %s s ---' % (time.time() - start_time)) conn = sparse.lil_matrix((N, N), dtype=bool) if self.apply_positions and not initial_assembly: if self.morses is not None: for n in range(len(self.morses)): if self.hessian == 'reduced': i, j, Hx = ff.get_morse_potential_reduced_hessian( atoms, self.morses[n]) elif self.hessian == 'spectral': i, j, Hx = ff.get_morse_potential_hessian( atoms, self.morses[n], spectral=True) else: raise NotImplementedError('Not implemented hessian') x = [3 * i, 3 * i + 1, 3 * i + 2, 3 * j, 3 * j + 1, 3 * j + 2] row.extend(np.repeat(x, 6)) col.extend(np.tile(x, 6)) data.extend(Hx.flatten()) conn[i, j] = True conn[j, i] = True if self.bonds is not None: for n in range(len(self.bonds)): if self.hessian == 'reduced': i, j, Hx = ff.get_bond_potential_reduced_hessian( atoms, self.bonds[n], self.morses) elif self.hessian == 'spectral': i, j, Hx = ff.get_bond_potential_hessian( atoms, self.bonds[n], self.morses, spectral=True) else: raise NotImplementedError('Not implemented hessian') x = [3 * i, 3 * i + 1, 3 * i + 2, 3 * j, 3 * j + 1, 3 * j + 2] row.extend(np.repeat(x, 6)) col.extend(np.tile(x, 6)) data.extend(Hx.flatten()) conn[i, j] = True conn[j, i] = True if self.angles is not None: for n in range(len(self.angles)): if self.hessian == 'reduced': i, j, k, Hx = ff.get_angle_potential_reduced_hessian( atoms, self.angles[n], self.morses) elif self.hessian == 'spectral': i, j, k, Hx = ff.get_angle_potential_hessian( atoms, self.angles[n], self.morses, spectral=True) else: raise NotImplementedError('Not implemented hessian') x = [3 * i, 3 * i + 1, 3 * i + 2, 3 * j, 3 * j + 1, 3 * j + 2, 3 * k, 3 * k + 1, 3 * k + 2] row.extend(np.repeat(x, 9)) col.extend(np.tile(x, 9)) data.extend(Hx.flatten()) conn[i, j] = conn[i, k] = conn[j, k] = True conn[j, i] = conn[k, i] = conn[k, j] = True if self.dihedrals is not None: for n in range(len(self.dihedrals)): if self.hessian == 'reduced': i, j, k, l, Hx = \ ff.get_dihedral_potential_reduced_hessian( atoms, self.dihedrals[n], self.morses) elif self.hessian == 'spectral': i, j, k, l, Hx = ff.get_dihedral_potential_hessian( atoms, self.dihedrals[n], self.morses, spectral=True) else: raise NotImplementedError('Not implemented hessian') x = [3 * i, 3 * i + 1, 3 * i + 2, 3 * j, 3 * j + 1, 3 * j + 2, 3 * k, 3 * k + 1, 3 * k + 2, 3 * l, 3 * l + 1, 3 * l + 2] row.extend(np.repeat(x, 12)) col.extend(np.tile(x, 12)) data.extend(Hx.flatten()) conn[i, j] = conn[i, k] = conn[i, l] = conn[ j, k] = conn[j, l] = conn[k, l] = True conn[j, i] = conn[k, i] = conn[l, i] = conn[ k, j] = conn[l, j] = conn[l, k] = True if self.apply_positions: for i, j, rij in zip(i_list, j_list, rij_list): if not conn[i, j]: coeff = self.get_coeff(rij) x = [3 * i, 3 * i + 1, 3 * i + 2] y = [3 * j, 3 * j + 1, 3 * j + 2] row.extend(x + x) col.extend(x + y) data.extend(3 * [-coeff] + 3 * [coeff]) row.extend(range(self.dim * N)) col.extend(range(self.dim * N)) if initial_assembly: data.extend([self.mu * self.c_stab] * self.dim * N) else: data.extend([self.c_stab] * self.dim * N) # create the matrix start_time = time.time() self.P = sparse.csc_matrix( (data, (row, col)), shape=(self.dim * N, self.dim * N)) logger.info('--- created CSC matrix in %s s ---' % (time.time() - start_time)) if not initial_assembly: if len(fixed_atoms) != 0: self.P.tolil() for i in fixed_atoms: self.P[i, :] = 0.0 self.P[:, i] = 0.0 self.P[i, i] = 1.0 self.P = self.P.tocsr() # Create solver if self.use_pyamg and have_pyamg: start_time = time.time() self.ml = smoothed_aggregation_solver( self.P, B=None, strength=('symmetric', {'theta': 0.0}), smooth=( 'jacobi', {'filter': True, 'weighting': 'local'}), improve_candidates=[('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None], aggregate='standard', presmoother=('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}), postsmoother=('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}), max_levels=15, max_coarse=300, coarse_solver='pinv') logger.info('--- multi grid solver created in %s s ---' % (time.time() - start_time)) return self.P
def _make_sparse_precon(self, atoms, initial_assembly=False, force_stab=False): """ """ start_time = time.time() N = len(atoms) row = [] col = [] data = [] if self.morses is not None: for n in range(len(self.morses)): if self.hessian == 'reduced': i, j, Hx = ff.get_morse_potential_reduced_hessian( atoms, self.morses[n]) elif self.hessian == 'spectral': i, j, Hx = ff.get_morse_potential_hessian( atoms, self.morses[n], spectral=True) else: raise NotImplementedError('Not implemented hessian') x = [3 * i, 3 * i + 1, 3 * i + 2, 3 * j, 3 * j + 1, 3 * j + 2] row.extend(np.repeat(x, 6)) col.extend(np.tile(x, 6)) data.extend(Hx.flatten()) if self.bonds is not None: for n in range(len(self.bonds)): if self.hessian == 'reduced': i, j, Hx = ff.get_bond_potential_reduced_hessian( atoms, self.bonds[n], self.morses) elif self.hessian == 'spectral': i, j, Hx = ff.get_bond_potential_hessian( atoms, self.bonds[n], self.morses, spectral=True) else: raise NotImplementedError('Not implemented hessian') x = [3 * i, 3 * i + 1, 3 * i + 2, 3 * j, 3 * j + 1, 3 * j + 2] row.extend(np.repeat(x, 6)) col.extend(np.tile(x, 6)) data.extend(Hx.flatten()) if self.angles is not None: for n in range(len(self.angles)): if self.hessian == 'reduced': i, j, k, Hx = ff.get_angle_potential_reduced_hessian( atoms, self.angles[n], self.morses) elif self.hessian == 'spectral': i, j, k, Hx = ff.get_angle_potential_hessian( atoms, self.angles[n], self.morses, spectral=True) else: raise NotImplementedError('Not implemented hessian') x = [3 * i, 3 * i + 1, 3 * i + 2, 3 * j, 3 * j + 1, 3 * j + 2, 3 * k, 3 * k + 1, 3 * k + 2] row.extend(np.repeat(x, 9)) col.extend(np.tile(x, 9)) data.extend(Hx.flatten()) if self.dihedrals is not None: for n in range(len(self.dihedrals)): if self.hessian == 'reduced': i, j, k, l, Hx = \ ff.get_dihedral_potential_reduced_hessian( atoms, self.dihedrals[n], self.morses) elif self.hessian == 'spectral': i, j, k, l, Hx = ff.get_dihedral_potential_hessian( atoms, self.dihedrals[n], self.morses, spectral=True) else: raise NotImplementedError('Not implemented hessian') x = [3 * i, 3 * i + 1, 3 * i + 2, 3 * j, 3 * j + 1, 3 * j + 2, 3 * k, 3 * k + 1, 3 * k + 2, 3 * l, 3 * l + 1, 3 * l + 2] row.extend(np.repeat(x, 12)) col.extend(np.tile(x, 12)) data.extend(Hx.flatten()) row.extend(range(self.dim * N)) col.extend(range(self.dim * N)) data.extend([self.c_stab] * self.dim * N) # create the matrix start_time = time.time() self.P = sparse.csc_matrix( (data, (row, col)), shape=(self.dim * N, self.dim * N)) logger.info('--- created CSC matrix in %s s ---' % (time.time() - start_time)) fixed_atoms = [] for constraint in atoms.constraints: if isinstance(constraint, FixAtoms): fixed_atoms.extend(list(constraint.index)) else: raise TypeError( 'only FixAtoms constraints are supported by Precon class') if len(fixed_atoms) != 0: self.P.tolil() for i in fixed_atoms: self.P[i, :] = 0.0 self.P[:, i] = 0.0 self.P[i, i] = 1.0 self.P = self.P.tocsr() logger.info('--- N-dim precon created in %s s ---' % (time.time() - start_time)) # Create solver if self.use_pyamg and have_pyamg: start_time = time.time() self.ml = smoothed_aggregation_solver( self.P, B=None, strength=('symmetric', {'theta': 0.0}), smooth=( 'jacobi', {'filter': True, 'weighting': 'local'}), improve_candidates=[('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 4}), None, None, None, None, None, None, None, None, None, None, None, None, None, None], aggregate='standard', presmoother=('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}), postsmoother=('block_gauss_seidel', {'sweep': 'symmetric', 'iterations': 1}), max_levels=15, max_coarse=300, coarse_solver='pinv') logger.info('--- multi grid solver created in %s s ---' % (time.time() - start_time)) return self.P
def calculate(self, atoms, properties, system_changes): Calculator.calculate(self, atoms, properties, system_changes) if system_changes: for name in ['energy', 'forces', 'hessian']: self.results.pop(name, None) if 'energy' not in self.results: energy = 0.0 for morse in self.morses: i, j, e = ff.get_morse_potential_value(atoms, morse) energy += e for bond in self.bonds: i, j, e = ff.get_bond_potential_value(atoms, bond) energy += e for angle in self.angles: i, j, k, e = ff.get_angle_potential_value(atoms, angle) energy += e for dihedral in self.dihedrals: i, j, k, l, e = ff.get_dihedral_potential_value( atoms, dihedral) energy += e for vdw in self.vdws: i, j, e = ff.get_vdw_potential_value(atoms, vdw) energy += e for coulomb in self.coulombs: i, j, e = ff.get_coulomb_potential_value(atoms, coulomb) energy += e self.results['energy'] = energy if 'forces' not in self.results: forces = np.zeros(3 * len(atoms)) for morse in self.morses: i, j, g = ff.get_morse_potential_gradient(atoms, morse) limits = get_limits([i, j]) for gb, ge, lb, le in limits: forces[gb:ge] -= g[lb:le] for bond in self.bonds: i, j, g = ff.get_bond_potential_gradient(atoms, bond) limits = get_limits([i, j]) for gb, ge, lb, le in limits: forces[gb:ge] -= g[lb:le] for angle in self.angles: i, j, k, g = ff.get_angle_potential_gradient(atoms, angle) limits = get_limits([i, j, k]) for gb, ge, lb, le in limits: forces[gb:ge] -= g[lb:le] for dihedral in self.dihedrals: i, j, k, l, g = ff.get_dihedral_potential_gradient( atoms, dihedral) limits = get_limits([i, j, k, l]) for gb, ge, lb, le in limits: forces[gb:ge] -= g[lb:le] for vdw in self.vdws: i, j, g = ff.get_vdw_potential_gradient(atoms, vdw) limits = get_limits([i, j]) for gb, ge, lb, le in limits: forces[gb:ge] -= g[lb:le] for coulomb in self.coulombs: i, j, g = ff.get_coulomb_potential_gradient(atoms, coulomb) limits = get_limits([i, j]) for gb, ge, lb, le in limits: forces[gb:ge] -= g[lb:le] self.results['forces'] = np.reshape(forces, (len(atoms), 3)) if 'hessian' not in self.results: hessian = np.zeros((3 * len(atoms), 3 * len(atoms))) for morse in self.morses: i, j, h = ff.get_morse_potential_hessian(atoms, morse) limits = get_limits([i, j]) for gb1, ge1, lb1, le1 in limits: for gb2, ge2, lb2, le2 in limits: hessian[gb1:ge1, gb2:ge2] += h[lb1:le1, lb2:le2] for bond in self.bonds: i, j, h = ff.get_bond_potential_hessian(atoms, bond) limits = get_limits([i, j]) for gb1, ge1, lb1, le1 in limits: for gb2, ge2, lb2, le2 in limits: hessian[gb1:ge1, gb2:ge2] += h[lb1:le1, lb2:le2] for angle in self.angles: i, j, k, h = ff.get_angle_potential_hessian(atoms, angle) limits = get_limits([i, j, k]) for gb1, ge1, lb1, le1 in limits: for gb2, ge2, lb2, le2 in limits: hessian[gb1:ge1, gb2:ge2] += h[lb1:le1, lb2:le2] for dihedral in self.dihedrals: i, j, k, l, h = ff.get_dihedral_potential_hessian( atoms, dihedral) limits = get_limits([i, j, k, l]) for gb1, ge1, lb1, le1 in limits: for gb2, ge2, lb2, le2 in limits: hessian[gb1:ge1, gb2:ge2] += h[lb1:le1, lb2:le2] for vdw in self.vdws: i, j, h = ff.get_vdw_potential_hessian(atoms, vdw) limits = get_limits([i, j]) for gb1, ge1, lb1, le1 in limits: for gb2, ge2, lb2, le2 in limits: hessian[gb1:ge1, gb2:ge2] += h[lb1:le1, lb2:le2] for coulomb in self.coulombs: i, j, h = ff.get_coulomb_potential_hessian(atoms, coulomb) limits = get_limits([i, j]) for gb1, ge1, lb1, le1 in limits: for gb2, ge2, lb2, le2 in limits: hessian[gb1:ge1, gb2:ge2] += h[lb1:le1, lb2:le2] self.results['hessian'] = hessian