def forceDistrRecord(self, coord_x, coord_y, updated_Fsys, d): if self.ndims == 1: self.colvars_force[getIndices(coord_x, self.bins)] += updated_Fsys if self.ndims == 2: self.colvars_force[d][getIndices(coord_x, self.bins)][getIndices(coord_y, self.bins)] += updated_Fsys
def histDistrRecord(self, coord_x, coord_y, d): if self.ndims == 1: self.colvars_count[getIndices(coord_x, self.bins)] += 1 if self.ndims == 2: self.colvars_count[d][getIndices(coord_x, self.bins)][getIndices(coord_y, self.bins)] += 1
def histDistrRecord(self, coord_x, coord_y, d=None): # TODO better strucuture if self.ndims == 1: self.colvars_count[getIndices(coord_x, self.bins)] += 1 if self.ndims == 2: self.colvars_count[d][getIndices(coord_x, self.bins)][getIndices( coord_y, self.bins)] += 1
def getLocalForce(self, coord_x, coord_y, vel, d=None): coord_x = truncateFloat(coord_x) coord_y = truncateFloat(coord_y) # Regular MD if self.abfCheckFlag == "no" and self.nnCheckFlag == "no": Fu = self.PotentialForce(coord_x, coord_y, d) Fsys = self.PotentialForce( coord_x, coord_y, d) + self.visForce(vel) + self.randForce() self.forceDistrRecord(coord_x, coord_y, Fsys, d) return Fu / self.mass # Regular MD with ABF if self.abfCheckFlag == "yes" and self.nnCheckFlag == "no": Fu = self.PotentialForce(coord_x, coord_y, d) Fsys = self.PotentialForce( coord_x, coord_y, d) + self.visForce(vel) + self.randForce() self.forceDistrRecord(coord_x, coord_y, Fsys, d) Fabf = self.appliedBiasForce(coord_x, coord_y, d) return (Fu + Fabf) / self.mass # Regular MD with ABF and ANN (I) if self.abfCheckFlag == "yes" and self.nnCheckFlag == "yes": Fu = self.PotentialForce(coord_x, coord_y, d) Fsys = self.PotentialForce( coord_x, coord_y, d) + self.visForce(vel) + self.randForce() self.forceDistrRecord(coord_x, coord_y, Fsys, d) if self.frame % self.Frequency == 0 and self.frame != 0: output = trainingNN("loss.dat", "hyperparam.dat", self.ndims, len(self.bins)) self.colvars_force = (self.colvars_force / self.colvars_count) self.colvars_force[np.isnan( self.colvars_force)] = 0 # 0/0 = nan n/0 = inf self.colvars_force_NN = \ output.training(self.colvars_coord, self.colvars_force, self.learning_rate, self.regularCoeff, self.epoch, self.NNoutputFreq) self.colvars_force = (self.colvars_force * self.colvars_count) self.forceDistrRecord(coord_x, coord_y, self.colvars_force_NN, d) Fabf = -self.colvars_force_NN[getIndices(coord_x, self.bins)] return (Fu + Fabf) / self.mass else: if self.frame < self.Frequency: Fabf = self.appliedBiasForce(coord_x, coord_y, d) return (Fu + Fabf) / self.mass else: Fabf = -self.colvars_force_NN[getIndices( coord_x, self.bins)] return (Fu + Fabf) / self.mass
def forceDistrRecord(self, coord_x, coord_y, updated_Fsys, d=None): # TODO better strucuture if self.ndims == 1: self.colvars_force[getIndices(coord_x, self.bins)] += updated_Fsys if self.ndims == 2: self.colvars_force[d][getIndices(coord_x, self.bins)][getIndices( coord_y, self.bins)] += updated_Fsys
def getLocalForce(self, coord_x, coord_y, vel, d=None): #TODO 2D coord_x = truncateFloat(coord_x) coord_y = truncateFloat(coord_y) Fu = self.PotentialForce(coord_x, coord_y, d) Fsys = self.PotentialForce(coord_x, coord_y, d) + self.visForce(vel) + self.randForce() # Regular MD if self.abfCheckFlag == "no" and self.nnCheckFlag == "no": self.forceDistrRecord(coord_x, coord_y, Fsys, d) self.histDistrRecord(coord_x, coord_y, d) return Fu / self.mass # Regular MD with ABF and ANN (I) if self.abfCheckFlag == "yes" and self.nnCheckFlag == "yes": if self.frame < self.Frequency: Fabf = self.appliedBiasForce(coord_x, coord_y, d) self.forceDistrRecord(coord_x, coord_y, Fsys, d) self.histDistrRecord(coord_x, coord_y, d) return (Fu + Fabf) / self.mass else: # NN takes over here self.forceDistrRecord(coord_x, coord_y, Fsys, d) self.histDistrRecord(coord_x, coord_y, d) if self.ndims == 1: Fabf = self.gradient[getIndices(coord_x, self.bins)] if self.ndims == 2: pass return (Fu + Fabf) / self.mass
def checkBoltzDistr(self, fileIn, fileOut): with open(fileIn, "r") as fin: if self.ndims == 1: # use xmgrace instead prob_x = np.zeros((self.binNum), dtype = np.int32) nsamples = 0 for line in fin: line = line.split() if line[0] != "#": nsamples += 1 prob_x[getIndices(truncateFloat(float(line[2])), self.x_axis)] += 1 prob_x = np.array(prob_x) prob_x = (prob_x / nsamples) # final probability distribution with open(fileOut, "w") as fout: for i in range(len(prob_x)): # in xmgrace, one can discard the point on pi (boundary error) fout.write(str(self.x_axis[i]) + " " + str(prob_x[i]) + "\n") if self.ndims == 2: prob_xy = np.zeros((self.binNum, self.binNum), dtype = np.float64) nsamples = 0 for line in fin: line = line.split() if line[0] != "#": nsamples += 1 prob_xy[getIndices(truncateFloat(float(line[2])), self.x_axis)][getIndices(truncateFloat(float(line[4])), self.y_axis)] += 1 # 2 for cartcoord_1D, 2 4 for cartcoord_2D prob_xy = (prob_xy / nsamples) # final probability distribution with open(fileOut, "w") as fout: for i in range(self.binNum): # discard the point on the positive boundary (PBC issues) for j in range(self.binNum): # discard the point on the positive boundary (PBC issues) fout.write(str(self.x_axis[i]) + " ") fout.write(str(self.y_axis[j]) + " " + str(prob_xy[i][j]) + "\n") prob_xy = np.delete(prob_xy, -1, 0) # rendering; prevent boundary error prob_xy = np.delete(prob_xy, -1, 1) r = rendering(self.ndims, self.half_boxboundary, self.binNum, self.temperature) r.render(prob_xy, name=str(self.abfCheckFlag + "_" + self.nnCheckFlag + "_" + "boltz2D"))
def appliedBiasPotential(self, coord_x, coord_y, d=None): #TODO 2D if self.abfCheckFlag == "yes" and self.nnCheckFlag == "yes": if self.ndims == 1: if self.frame <= self.Frequency: # initial sweep return 0 # np.sin(coord_x) else: return self.biasingPotentialFromNN[getIndices( coord_x, self.bins)] if self.ndims == 2: pass
def forceDistrRecord(self, coord_x, coord_y, updated_Fsys, d): if self.ndims == 1: if isinstance(updated_Fsys, float) or isinstance( updated_Fsys, int): # conventional ABF collection, which is a float self.colvars_force[getIndices(coord_x, self.bins)] += updated_Fsys self.colvars_count[getIndices(coord_x, self.bins)] += 1 else: # refined force from NN, which is a np.ndarray self.colvars_force += updated_Fsys self.colvars_count += 1 if self.ndims == 2: if isinstance(updated_Fsys, float) or isinstance( updated_Fsys, int): self.colvars_force[d][getIndices( coord_x, self.bins)][getIndices(coord_y, self.bins)] += updated_Fsys self.colvars_count[d][getIndices(coord_x, self.bins)][getIndices( coord_y, self.bins)] += 1 else: self.colvars_force += updated_Fsys self.colvars_count += 1
def appliedBiasForce(self, coord_x, coord_y, d): if self.ndims == 1: if self.colvars_count[getIndices(coord_x, self.bins)] == 0: return 0 else: return -(self.colvars_force[getIndices(coord_x, self.bins)] / self.colvars_count[getIndices(coord_x, self.bins)]) if self.ndims == 2: if self.colvars_count[d][getIndices(coord_x, self.bins)][getIndices(coord_y, self.bins)] == 0: return 0 else: return -(self.colvars_force[d][getIndices(coord_x, self.bins)][getIndices(coord_y, self.bins)] / self.colvars_count[d][getIndices(coord_x, self.bins)][getIndices(coord_y, self.bins)])