morse_r0 = 1.4322 angle_k = 10.0 angle_a0 = np.deg2rad(120.0) dihedral_k = 0.346 vdw_epsilonij = 0.0115 vdw_rminij = 3.4681 neighbor_list = [[] for _ in range(len(a))] vdw_list = np.ones((len(a), len(a)), dtype=bool) morses = [] angles = [] dihedrals = [] vdws = [] # create neighbor list i_list, j_list, d_list, fixed_atoms = get_neighbours(atoms=a, r_cut=cutoff) for i, j in zip(i_list, j_list): neighbor_list[i].append(j) for i in range(len(neighbor_list)): neighbor_list[i].sort() # create lists of morse, bending and torsion interactions for i in range(len(a)): for jj in range(len(neighbor_list[i])): j = neighbor_list[i][jj] if j > i: morses.append( Morse(atomi=i, atomj=j, D=morse_D, alpha=morse_alpha,
def forcefield_params(atoms0): # force field parameters for fulleren, Z. Berkai at al. # Energy Procedia, 74, 2015, 59-64 a = atoms0 cutoff = 1.5 morse_D = 6.1322 morse_alpha = 1.8502 morse_r0 = 1.4322 angle_k = 10.0 angle_a0 = np.deg2rad(120.0) dihedral_k = 0.346 vdw_epsilonij = 0.0115 vdw_rminij = 3.4681 neighbor_list = [[] for _ in range(len(a))] vdw_list = np.ones((len(a), len(a)), dtype=bool) morses = [] angles = [] dihedrals = [] vdws = [] # create neighbor list i_list, j_list, d_list, fixed_atoms = get_neighbours(atoms=a, r_cut=cutoff) for i, j in zip(i_list, j_list): neighbor_list[i].append(j) for i in range(len(neighbor_list)): neighbor_list[i].sort() # create lists of morse, bending and torsion interactions for i in range(len(a)): for jj in range(len(neighbor_list[i])): j = neighbor_list[i][jj] if j > i: morses.append( Morse(atomi=i, atomj=j, D=morse_D, alpha=morse_alpha, r0=morse_r0)) vdw_list[i, j] = vdw_list[j, i] = False for kk in range(jj + 1, len(neighbor_list[i])): k = neighbor_list[i][kk] angles.append( Angle(atomi=j, atomj=i, atomk=k, k=angle_k, a0=angle_a0, cos=True)) vdw_list[j, k] = vdw_list[k, j] = False for ll in range(kk + 1, len(neighbor_list[i])): l = neighbor_list[i][ll] dihedrals.append( Dihedral(atomi=j, atomj=i, atomk=k, atoml=l, k=dihedral_k)) # create list of van der Waals interactions for i in range(len(a)): for j in range(i + 1, len(a)): if vdw_list[i, j]: vdws.append( VdW(atomi=i, atomj=j, epsilonij=vdw_epsilonij, rminij=vdw_rminij)) return dict(morses=morses, angles=angles, dihedrals=dihedrals, vdws=vdws)
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): """Create a sparse preconditioner matrix based on the passed atoms. Creates a general-purpose preconditioner for use with optimization algorithms, based on examining distances between pairs of atoms in the lattice. The matrix will be stored in the attribute self.P and returned. Note that this function will use self.mu, whatever it is. 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) diag_i = np.arange(N, dtype=int) #start_time = time.time() if self.apply_positions: # compute neighbour list i, j, rij, fixed_atoms = get_neighbours(atoms, self.r_cut) #print('--- neighbour list created in %s s ---' % # ((time.time() - start_time))) # compute entries in triplet format: without the constraints #start_time = time.time() coeff = self.get_coeff(rij) diag_coeff = np.bincount(i, -coeff, minlength=N).astype(np.float64) if force_stab or len(fixed_atoms) == 0: #print('adding stabilisation to preconditioner') diag_coeff += self.mu * self.c_stab else: diag_coeff = np.ones(N) # precon is mu_c*identity for cell DoF if isinstance(atoms, Filter): if self.apply_cell: diag_coeff[-3] = self.mu_c diag_coeff[-2] = self.mu_c diag_coeff[-1] = self.mu_c else: diag_coeff[-3] = 1.0 diag_coeff[-2] = 1.0 diag_coeff[-1] = 1.0 #print('--- computed triplet format in %s s ---' % # (time.time() - start_time)) if self.apply_positions and not initial_assembly: # apply the constraints #start_time = time.time() mask = np.ones(N) mask[fixed_atoms] = 0.0 coeff *= mask[i] * mask[j] diag_coeff[fixed_atoms] = 1.0 #print('--- applied fixed_atoms in %s s ---' % # (time.time() - start_time)) if self.apply_positions: # remove zeros #start_time = time.time() inz = np.nonzero(coeff) i = np.hstack((i[inz], diag_i)) j = np.hstack((j[inz], diag_i)) coeff = np.hstack((coeff[inz], diag_coeff)) #print('--- remove zeros in %s s ---' % # (time.time() - start_time)) else: i = diag_i j = diag_i coeff = diag_coeff # create the matrix #start_time = time.time() csc_P = sparse.csc_matrix((coeff, (i, j)), shape=(N, N)) #print('--- created CSC matrix in %s s ---' % # (time.time() - start_time)) self.csc_P = csc_P #start_time = time.time() if self.dim == 1: self.P = csc_P elif self.array_convention == 'F': csc_P = csc_P.tocsr() self.P = csc_P for i in range(self.dim - 1): self.P = sparse.block_diag((self.P, csc_P)).tocsr() else: # convert back to triplet and read the arrays csc_P = csc_P.tocoo() i = csc_P.row * self.dim j = csc_P.col * self.dim z = csc_P.data # N-dimensionalise, interlaced coordinates I = np.hstack([i + d for d in range(self.dim)]) J = np.hstack([j + d for d in range(self.dim)]) Z = np.hstack([z for d in range(self.dim)]) self.P = sparse.csc_matrix((Z, (I, J)), shape=(self.dim * N, self.dim * N)) self.P = self.P.tocsr() #print('--- 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') #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): """Create a sparse preconditioner matrix based on the passed atoms. Creates a general-purpose preconditioner for use with optimization algorithms, based on examining distances between pairs of atoms in the lattice. The matrix will be stored in the attribute self.P and returned. Note that this function will use self.mu, whatever it is. 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) diag_i = np.arange(N, dtype=int) start_time = time.time() if self.apply_positions: # compute neighbour list i, j, rij, fixed_atoms = get_neighbours(atoms, self.r_cut) logger.info('--- neighbour list created in %s s ---' % (time.time() - start_time)) # compute entries in triplet format: without the constraints start_time = time.time() coeff = self.get_coeff(rij) diag_coeff = np.bincount(i, -coeff, minlength=N).astype(np.float64) if force_stab or len(fixed_atoms) == 0: logger.info('adding stabilisation to preconditioner') diag_coeff += self.mu * self.c_stab else: diag_coeff = np.ones(N) # precon is mu_c*identity for cell DoF if isinstance(atoms, Filter): if self.apply_cell: diag_coeff[-3] = self.mu_c diag_coeff[-2] = self.mu_c diag_coeff[-1] = self.mu_c else: diag_coeff[-3] = 1.0 diag_coeff[-2] = 1.0 diag_coeff[-1] = 1.0 logger.info('--- computed triplet format in %s s ---' % (time.time() - start_time)) if self.apply_positions and not initial_assembly: # apply the constraints start_time = time.time() mask = np.ones(N) mask[fixed_atoms] = 0.0 coeff *= mask[i] * mask[j] diag_coeff[fixed_atoms] = 1.0 logger.info('--- applied fixed_atoms in %s s ---' % (time.time() - start_time)) if self.apply_positions: # remove zeros start_time = time.time() inz = np.nonzero(coeff) i = np.hstack((i[inz], diag_i)) j = np.hstack((j[inz], diag_i)) coeff = np.hstack((coeff[inz], diag_coeff)) logger.info('--- remove zeros in %s s ---' % (time.time() - start_time)) else: i = diag_i j = diag_i coeff = diag_coeff # create the matrix start_time = time.time() csc_P = sparse.csc_matrix((coeff, (i, j)), shape=(N, N)) logger.info('--- created CSC matrix in %s s ---' % (time.time() - start_time)) self.csc_P = csc_P start_time = time.time() if self.dim == 1: self.P = csc_P elif self.array_convention == 'F': csc_P = csc_P.tocsr() self.P = csc_P for i in range(self.dim - 1): self.P = sparse.block_diag((self.P, csc_P)).tocsr() else: # convert back to triplet and read the arrays csc_P = csc_P.tocoo() i = csc_P.row * self.dim j = csc_P.col * self.dim z = csc_P.data # N-dimensionalise, interlaced coordinates I = np.hstack([i + d for d in range(self.dim)]) J = np.hstack([j + d for d in range(self.dim)]) Z = np.hstack([z for d in range(self.dim)]) self.P = sparse.csc_matrix((Z, (I, J)), shape=(self.dim * N, self.dim * N)) 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
morse_r0 = 1.4322 angle_k = 10.0 angle_a0 = np.deg2rad(120.0) dihedral_k = 0.346 vdw_epsilonij = 0.0115 vdw_rminij = 3.4681 neighbor_list = [[] for _ in range(len(a))] vdw_list = np.ones((len(a), len(a)), dtype=bool) morses = [] angles = [] dihedrals = [] vdws = [] # create neighbor list i_list, j_list, d_list, fixed_atoms = get_neighbours(atoms=a, r_cut=cutoff) for i, j in zip(i_list, j_list): neighbor_list[i].append(j) for i in range(len(neighbor_list)): neighbor_list[i].sort() # create lists of morse, bending and torsion interactions for i in range(len(a)): for jj in range(len(neighbor_list[i])): j = neighbor_list[i][jj] if j > i: morses.append(Morse(atomi=i, atomj=j, D=morse_D, alpha=morse_alpha, r0=morse_r0)) vdw_list[i, j] = vdw_list[j, i] = False for kk in range(jj + 1, len(neighbor_list[i])): k = neighbor_list[i][kk]