def __init__( self, n_radial=43, n_ap=21, cutoff_radius=8.0, cutoff_react=None, cutoff_prod=None, sym_start=0.8, sym_cut=5.5, width_adjust=(0.5)**(0.5), width_adjust_ap=(2)**(0.5), elements=frozenset((1, 6, 7, 8, 9)), centered=False, sharez=True, trainz=False, mode="Behler", cutoff=snn.CosineCutoff, len_embedding=1, atom_t=None, atom_react=None, atom_prod=None, morse_beta=10.0, ): super(APNet_mod, self).__init__() # Determine mode. if mode == "weighted": initz = "weighted" pairwise_elements = False elif mode == "Behler": initz = "onehot" pairwise_elements = True else: raise NotImplementedError("Unrecognized symmetry function %s" % mode) self.n_radial = n_radial self.n_ap = n_ap self.len_embedding = len_embedding self.n_elements = None self.cutoff_radius = cutoff_radius self.cutoff = cutoff(cutoff=self.cutoff_radius) if atom_t is not None: self.atom_t = torch.tensor(atom_t).reshape(-1) if isinstance(atom_react, int): if atom_react < self.atom_t: self.atom_react = torch.tensor(atom_react).reshape(-1) else: self.atom_react = torch.tensor(atom_react - 1).reshape(-1) #self.atom_react = torch.tensor(atom_react).reshape(-1) else: atom_react = torch.tensor(atom_react).reshape(-1) inc = -torch.ones_like(atom_react) zero = torch.zeros_like(atom_react) zero[atom_react > self.atom_t] = inc[atom_react > self.atom_t] self.atom_react = atom_react + zero if isinstance(atom_prod, int): if atom_prod < self.atom_t: self.atom_prod = torch.tensor(atom_prod).reshape(-1) else: self.atom_prod = torch.tensor(atom_prod - 1).reshape(-1) #self.atom_prod = torch.tensor(atom_prod).reshape(-1) else: atom_prod = torch.tensor(atom_prod).reshape(-1) inc = -torch.ones_like(atom_prod) zero = torch.zeros_like(atom_prod) zero[atom_prod > self.atom_t] = inc[atom_prod > self.atom_t] self.atom_prod = atom_prod + zero self.fd_react = FermiDirac(mu=cutoff_react, beta=morse_beta) self.fd_prod = FermiDirac(mu=cutoff_prod, beta=morse_beta) else: self.cutoff2 = None self.sym_cut = sym_cut # Check for general stupidity: if self.n_ap < 1 and self.n_radial < 1: raise ValueError("At least one type of SF required") if self.n_radial > 0: # Get basic filters (if centered Gaussians are requested, start is set to 0.5 if centered: radial_start = 1.0 else: radial_start = 0.5 self.radial_filter = snn.GaussianSmearing( start=sym_start, stop=self.sym_cut - 0.5, n_gaussians=n_radial, centered=centered, width_adjust=width_adjust) self.RDF = snn.RadialDistribution(self.radial_filter, cutoff_function=self.cutoff) else: self.RDF = None if self.n_ap > 0: self.radial_filter_ap = snn.GaussianSmearing( start=-1.0, stop=1.0, n_gaussians=n_ap, centered=centered, width_adjust=width_adjust_ap) self.APF = snn.APDistribution_Mod(self.radial_filter_ap, cutoff_functions=self.cutoff) else: self.APF = None self.radial_Z = self.initz(initz, elements) # check whether angular functions should use the same embedding if sharez: self.ap_Z = self.radial_Z else: self.ap_Z = self.initz(initz, elements) # Turn of training of embeddings unless requested explicitly if not trainz: # Turn off gradients self.radial_Z.weight.requires_grad = False self.ap_Z.weight.requires_grad = False # Compute total number of symmetry functions self.n_symfuncs = (self.n_radial + self.n_ap) * self.n_elements
def __init__( self, n_radial=22, n_angular=5, zetas={1}, cutoff=snn.CosineCutoff, cutoff_radius=5.0, centered=False, crossterms=False, elements=frozenset((1, 6, 7, 8, 9)), sharez=True, trainz=False, initz="weighted", len_embedding=5, pairwise_elements=False, ): super(SymmetryFunctions, self).__init__() self.n_radial = n_radial self.n_angular = n_angular self.len_embedding = len_embedding self.n_elements = None self.n_theta = 2 * len(zetas) # Initialize cutoff function self.cutoff_radius = cutoff_radius self.cutoff = cutoff(cutoff=self.cutoff_radius) # Check for general stupidity: if self.n_angular < 1 and self.n_radial < 1: raise ValueError("At least one type of SF required") if self.n_angular > 0: # Get basic filters self.theta_filter = snn.BehlerAngular(zetas=zetas) self.angular_filter = snn.GaussianSmearing( start=1.0, stop=self.cutoff_radius - 0.5, n_gaussians=n_angular, centered=True, ) self.ADF = snn.AngularDistribution( self.angular_filter, self.theta_filter, cutoff_functions=self.cutoff, crossterms=crossterms, pairwise_elements=pairwise_elements, ) else: self.ADF = None if self.n_radial > 0: # Get basic filters (if centered Gaussians are requested, start is set to 0.5 if centered: radial_start = 1.0 else: radial_start = 0.5 self.radial_filter = snn.GaussianSmearing( start=radial_start, stop=self.cutoff_radius - 0.5, n_gaussians=n_radial, centered=centered, ) self.RDF = snn.RadialDistribution(self.radial_filter, cutoff_function=self.cutoff) else: self.RDF = None # Initialize the atomtype embeddings self.radial_Z = self.initz(initz, elements) # check whether angular functions should use the same embedding if sharez: self.angular_Z = self.radial_Z else: self.angular_Z = self.initz(initz, elements) # Turn of training of embeddings unless requested explicitly if not trainz: # Turn off gradients self.radial_Z.weight.requires_grad = False self.angular_Z.weight.requires_grad = False # Compute total number of symmetry functions if not pairwise_elements: self.n_symfuncs = (self.n_radial + self.n_angular * self.n_theta) * self.n_elements else: # if the outer product is used, all unique pairs of elements are considered, leading to the factor of # (N+1)/2 self.n_symfuncs = (self.n_radial + self.n_angular * self.n_theta * (self.n_elements + 1) // 2) * self.n_elements
def __init__( self, n_radial=43, n_ap=21, cutoff_radius=8.0, cutoff_radius2=None, sym_start=0.8, sym_cut=5.5, width_adjust=(0.5)**(0.5), width_adjust_ap=(2)**(0.5), elements=frozenset((1, 6, 7, 8, 9)), centered=False, sharez=True, trainz=False, mode="Behler", cutoff=snn.CosineCutoff, len_embedding=1, morse_bond=None, morse_mu=None, morse_res=None, morse_beta=10.0, ): super(APNet, self).__init__() # Determine mode. if mode == "weighted": initz = "weighted" pairwise_elements = False elif mode == "Behler": initz = "onehot" pairwise_elements = True else: raise NotImplementedError("Unrecognized symmetry function %s" % mode) self.n_radial = n_radial self.n_ap = n_ap self.len_embedding = len_embedding self.n_elements = None self.cutoff_radius = cutoff_radius self.cutoff_radius2 = cutoff_radius2 self.cutoff = cutoff(cutoff=self.cutoff_radius) if self.cutoff_radius2 is not None: self.cutoff2 = cutoff(cutoff=self.cutoff_radius2) else: self.cutoff2 = None self.sym_cut = sym_cut if morse_bond is not None: g1 = [i for i in morse_bond if isinstance(i, int)] if len(g1) < len(morse_bond): g2 = [i for i in morse_bond if isinstance(i, list)][0] self.morse1 = torch.tensor(g1).reshape(-1) self.morse2 = torch.tensor(g2) inc = -torch.ones_like(self.morse2) zero = torch.zeros_like(self.morse2) zero[self.morse2 > self.morse1] = inc[ self.morse2 > self.morse1] self.morse2 = self.morse2 + zero self.morse1 += morse_res[0] else: morse1 = g1[0] morse2 = g1[1] if morse2 > morse1: morse2 -= 1 self.morse1 = torch.tensor(morse1 + morse_res[0]).reshape(-1) self.morse2 = torch.tensor(morse2).reshape(-1) self.fermi_dirac = FermiDirac(mu=morse_mu, beta=morse_beta) # Check for general stupidity: if self.n_ap < 1 and self.n_radial < 1: raise ValueError("At least one type of SF required") if self.n_radial > 0: # Get basic filters (if centered Gaussians are requested, start is set to 0.5 if centered: radial_start = 1.0 else: radial_start = 0.5 self.radial_filter = snn.GaussianSmearing( start=sym_start, stop=self.sym_cut - 0.5, n_gaussians=n_radial, centered=centered, width_adjust=width_adjust) self.RDF = snn.RadialDistribution(self.radial_filter, cutoff_function=self.cutoff) else: self.RDF = None if self.n_ap > 0: self.radial_filter_ap = snn.GaussianSmearing( start=-1.0, stop=1.0, n_gaussians=n_ap, centered=centered, width_adjust=width_adjust_ap) self.APF = snn.APDistribution(self.radial_filter_ap, cutoff_functions=self.cutoff) else: self.APF = None self.radial_Z = self.initz(initz, elements) # check whether angular functions should use the same embedding if sharez: self.ap_Z = self.radial_Z else: self.ap_Z = self.initz(initz, elements) # Turn of training of embeddings unless requested explicitly if not trainz: # Turn off gradients self.radial_Z.weight.requires_grad = False self.ap_Z.weight.requires_grad = False # Compute total number of symmetry functions self.n_symfuncs = (self.n_radial + self.n_ap) * self.n_elements