예제 #1
0
파일: IBI.py 프로젝트: uschille/FabSim
def basic_test_suite():
  """ Simple testing of various functions in the script."""
  print "read_lammps_data_file"
  lattice, type_list = lmp_io.read_lammps_data_file("CG_first_interaction.lammps05")
  print "read_lammps_rdf"
  rdf_average = lmp_io.read_lammps_rdf("tmp.1.rdf", 3, 1)
  print "read_CG_log_file"
  final_pressure = read_CG_log_file("new_CG.prod1.log")
  print "smooth_data"
  smoothed = dm.smooth_data(rdf_average[1][1])
  print "read_in_rdf_file"
  rdf_array, numofbins, cutoff = read_in_rdf_file("rdf", 3, [[1,1],[1,2],[1,3],[2,2],[2,3],[3,3]])
  print "read_in_interaction_files"
  distance, potential, derivative, pot_file_list, cutoff = lmp_io.read_in_interaction_files("./pot", 3, [[1,1],[1,2],[1,3],[2,2],[2,3],[3,3]], 1)
예제 #2
0
파일: IBI.py 프로젝트: UCL-CCS/FabMD
def basic_test_suite():
    """ Simple testing of various functions in the script."""
    print "read_lammps_data_file"
    lattice, type_list = lmp_io.read_lammps_data_file(
        "CG_first_interaction.lammps05")
    print "read_lammps_rdf"
    rdf_average = lmp_io.read_lammps_rdf("tmp.1.rdf", 3, 1)
    print "read_CG_log_file"
    final_pressure = read_CG_log_file("new_CG.prod1.log")
    print "smooth_data"
    smoothed = dm.smooth_data(rdf_average[1][1])
    print "read_in_rdf_file"
    rdf_array, numofbins, cutoff = read_in_rdf_file(
        "rdf", 3, [[1, 1], [1, 2], [1, 3], [2, 2], [2, 3], [3, 3]])
    print "read_in_interaction_files"
    distance, potential, derivative, pot_file_list, cutoff = lmp_io.read_in_interaction_files(
        "./pot", 3, [[1, 1], [1, 2], [1, 3], [2, 2], [2, 3], [3, 3]], 1)
예제 #3
0
파일: IBI.py 프로젝트: uschille/FabSim
def production():
  """ This script will create the next interation of coarse-grained potentials using the Iterative Boltzmann Inversion to 
  match to a user-supplied radial distribution function (normally from atomistic simulation). It will also attempt a correction 
  for the pressure. The script will also extrapolate the potentials at low distance values by fitting to a soft Lennard-Jones 
  potential. Note, this fitting is somewhat unstable (CurveFit.pm) and can cause the IBI to fail. """

  print "ARGUMENTS TO THE IBI ARE: ", sys.argv 

  # user-supplied arguments to the IBI. Note, not all of these arguments are required depending on what analysis is need and files are provided. 
  lammps_input_file = "" # LAMMPS input file for the current CG iteration. 
  correct_rdf_base  = "" # User-supplied Radial Distribution Function to match to (normally derived from atomistic simulation) - distance is column 1 and the RDF is column 3.   
  potential_base    = "" # the file base-name for the potential energy files. The format is such: pot.<iteration_number>.new.<type1><type2>. In this case the base-name is "pot". 
  number = 0             # the current IBI iteration number
  lammps_data_file = ""  # LAMMPS CG data file 
  lammps_rdf_file  = ""  # the CG RDF file if calculated by LAMMPS - this is a series of snapshot values, which need to be averaged. 
  p_target = 1.0         # pressure target for the CG simulation.
  p_flag   = 0.0         # flag to indicate whether to apply pressure correction - set to one if a pressure target is set by the user. 
  CG_output_file = ""    # LAMMPS thermodynamic log file for the current CG simulation. Used to calculate the current average CG pressure. 
  p_now    = 0           # current CG pressure read from (and averaged) the CG lammps thermodynamic log file; 
  temperature = 300      # temperature the simulations are run at; default is 300K
  LJ_file_flag = 0       # if this flag is set to one, the parameters used in the extrapolation by fitting to a Lennard-Jones potential are read from a file (called LJ_parameters) rather than computed from fitting to the potential / forces.  
  num_of_bins = 0
  DeltaR = 0.0
  number_of_arguments = len(sys.argv) 
  mode = "default"
  num_of_types = 0

  for i in xrange(0, number_of_arguments):  
    if sys.argv[i].lower() == "lammps_input_file":
      lammps_input_file = sys.argv[i+1] 
      print "THE LAMMPS INPUT FILE IS ", lammps_input_file 
    elif sys.argv[i].lower() == "lammps_output_file":
      lammps_output_file = sys.argv[i+1] 
      print "THE LAMMPS OUTPUT FILE IS ", lammps_input_file 
    elif sys.argv[i].lower() == "lammps_data_file":
      lammps_data_file = sys.argv[i+1] 
      print "THE LAMMPS DATA FILE IS ", lammps_data_file
    elif ((sys.argv[i] == "potential_base") or (sys.argv[i] == "potential")):
      potential_base = sys.argv[i+1] 
    elif sys.argv[i].lower() == "lammps_rdf_file":
      lammps_rdf_file = sys.argv[i+1] 
      print "THE RDFS WILL BE READ FROM LAMMPS OUTPUT", lammps_rdf_file
    elif (sys.argv[i] == "correct_rdf_base"):
      correct_rdf_base = sys.argv[i+1] 
      print "THE RDFS TO MATCH TO HAVE THE FILE BASE ", correct_rdf_base
    elif ((sys.argv[i] == "number") or (sys.argv[i] == "current_number") or (sys.argv[i] == "iteration_number")):
      number = int(sys.argv[i+1])
      print "THE CURRENT ITERATION NUMBER IS ", number
    elif ((sys.argv[i] == "pressure_flag") or (sys.argv[i] == "p_flag")):
      p_flag = float(sys.argv[i+1])
      print "THE PRESSURE FLAG is ", p_flag
    elif ((sys.argv[i] == "pressure_target") or (sys.argv[i] == "p_target")):
      p_target = float(sys.argv[i+1])
      if abs(p_flag) < 0.00001:
        p_flag = 1 
      print "THE PRESSURE TARGET is ", p_target
    elif ((sys.argv[i] == "CG_log_file") or (sys.argv[i] == "CG_logfile")):
      CG_output_file = sys.argv[i+1] 
      p_now = read_CG_log_file(CG_output_file, label="Press")          
      #TODO: this is only a temp hack!
      print "THE CURRENT PRESSURE WILL BE CALCULATED FROM THE LOG FILE ", CG_output_file , p_now
    elif (sys.argv[i] == "temperature"):
      temperature = float(sys.argv[i+1])
    elif (sys.argv[i] == "LJ_param_file"):
      LJ_file_flag = 1
      
    elif sys.argv[i].lower() == "numofbins":
      num_of_bins = int(sys.argv[i+1]) 
      print "THE NUMBER OF BINS IS ", num_of_bins
    elif sys.argv[i].lower() == "deltar":
      DeltaR = float(sys.argv[i+1]) 
      print "DeltaR IS ", DeltaR
           
    elif sys.argv[i] == "mode":
      mode = sys.argv[i+1]
    elif sys.argv[i].lower() == "numoftypes":
      num_of_types = int(sys.argv[i+1]) 

  # read in the lammps data file to identify the number of CG types and lattice parameters. 
  lattice, type_list = lmp_io.read_lammps_data_file(lammps_data_file)

  num_of_types = len(type_list)
  print "Num of types = ", num_of_types
  #num_of_types = 4
   
  number_of_types_array = np.zeros((num_of_types+1))
  for n in xrange(1, num_of_types+1):
    number_of_types_array[n] = len(type_list["%s" % n]) 

  if mode=="pressure_correct":
    
    num_of_bins, cutoff, offset = lmp_io.get_number_of_bins_and_cutoff(potential_base, 1)
    print "Potential numofbins and cutoff:", num_of_bins, cutoff
    
    pots = (potential_base.strip()).split('.')
    atom1 = int(pots[-2])
    atom2 = int(pots[-1])
    
    print "ATOMS are:", atom1, atom2
    
    potential = np.zeros((num_of_bins+1)) 
    volume = float(lattice[0]) * float(lattice[1]) * float(lattice[2])
      
    hist_rdf = lmp_io.read_lammps_rdf(lammps_rdf_file, num_of_types, number)
   
    pressure_pot = calc_pressure_correction(hist_rdf[atom1][atom2], num_of_bins, DeltaR, number_of_types_array[atom1], number_of_types_array[atom2], abs(p_flag), p_now, p_target, volume, temperature)

    old_distance, old_potential, old_derivative = lmp_io.read_in_interaction_file(potential_base, num_of_bins)
   
    potential = apply_pressure_correction(old_potential, pressure_pot, num_of_bins+1, old_distance[1], DeltaR)
        
    potential[0]=potential[1] # TODO: change this temporary workaround into something more systematic. The workaround reduces anomalies in the derivative at the start of the potential.   
    new_derivatives = da.derivatives(np.arange(offset, cutoff, DeltaR), potential)
    print "dy lens:", num_of_bins, len(new_derivatives), len(np.arange(offset-DeltaR, cutoff, DeltaR)), len(potential)
    
    write_pot_file("%s/pot.%d.new.%d.%d" % (os.path.dirname(lammps_output_file), number+1, atom1, atom2), new_derivatives[1:] , potential[1:], num_of_bins, DeltaR, atom1, atom2, num_of_bins, offset, smoothing="no", selection="no") #note: we use an offset here!
    
    
    
  elif mode=="default":
    # Either read an interaction list from a file in the atom_dir (useful if you want to parametrize only a subset of interactions), or generate one on the fly.
    interaction_filename = os.path.dirname(correct_rdf_base) + "/interaction_list"
    if os.path.exists(interaction_filename):
      interaction_list = interaction_list_from_file(interaction_filename)
    else: 
      interaction_list = generate_interaction_list(num_of_types)
       
    first_array, num_of_bins, cutoff2 = read_in_rdf_file(correct_rdf_base, num_of_types, interaction_list) # read in the rdfs to match to. 

    print "THE CUTOFF in the RDF files is", cutoff2, ", with", len(first_array[1][1])-1, "number of bins "; 
    print "THIS IS ITERATION NUMBER", number

    deltaR = cutoff2 / num_of_bins # bin spacing from the RDF 
    previous_position, previous_potential, previous_derivative, old_pot_files, cutoff = lmp_io.read_in_interaction_files(potential_base, num_of_types,
interaction_list, number)
    num_of_bins = int(cutoff / deltaR)

    print deltaR, cutoff2, num_of_bins, correct_rdf_base
    print "THE CUTOFF in the POS FILES is", cutoff, "and number of bins are", num_of_bins 

    # read in the RDFs of the CG calculated by LAMMPS.
    hist_rdf = lmp_io.read_lammps_rdf(lammps_rdf_file, num_of_types, number)
  #  print lammps_rdf_file, len(hist_rdf[1][1])
    DeltaR = cutoff / num_of_bins
    
    # calculate the IBI 
    compute_update(os.path.dirname(lammps_output_file), first_array, hist_rdf, previous_position, previous_potential, num_of_types, number, DeltaR, num_of_bins, number_of_types_array, lattice, LJ_file_flag, p_flag, p_now, p_target, temperature, interaction_list)
    # modify the lammps input file, ready for the next iteration
    modify_lammps_in_file(lammps_input_file, lammps_output_file, number, interaction_list, num_of_types)
  else:
    print "ERROR: mode is incorrectly set in IBI.py. Should be e.g., default or pressure_correct"
    sys.exit()
예제 #4
0
파일: IBI.py 프로젝트: UCL-CCS/FabMD
def production():
    """ This script will create the next interation of coarse-grained potentials using the Iterative Boltzmann Inversion to 
  match to a user-supplied radial distribution function (normally from atomistic simulation). It will also attempt a correction 
  for the pressure. The script will also extrapolate the potentials at low distance values by fitting to a soft Lennard-Jones 
  potential. Note, this fitting is somewhat unstable (CurveFit.pm) and can cause the IBI to fail. """

    print "ARGUMENTS TO THE IBI ARE: ", sys.argv

    # user-supplied arguments to the IBI. Note, not all of these arguments are required depending on what analysis is need and files are provided.
    lammps_input_file = ""  # LAMMPS input file for the current CG iteration.
    correct_rdf_base = ""  # User-supplied Radial Distribution Function to match to (normally derived from atomistic simulation) - distance is column 1 and the RDF is column 3.
    potential_base = ""  # the file base-name for the potential energy files. The format is such: pot.<iteration_number>.new.<type1><type2>. In this case the base-name is "pot".
    number = 0  # the current IBI iteration number
    lammps_data_file = ""  # LAMMPS CG data file
    lammps_rdf_file = ""  # the CG RDF file if calculated by LAMMPS - this is a series of snapshot values, which need to be averaged.
    p_target = 1.0  # pressure target for the CG simulation.
    p_flag = 0.0  # flag to indicate whether to apply pressure correction - set to one if a pressure target is set by the user.
    CG_output_file = ""  # LAMMPS thermodynamic log file for the current CG simulation. Used to calculate the current average CG pressure.
    p_now = 0  # current CG pressure read from (and averaged) the CG lammps thermodynamic log file;
    temperature = 300  # temperature the simulations are run at; default is 300K
    LJ_file_flag = 0  # if this flag is set to one, the parameters used in the extrapolation by fitting to a Lennard-Jones potential are read from a file (called LJ_parameters) rather than computed from fitting to the potential / forces.
    num_of_bins = 0
    DeltaR = 0.0
    number_of_arguments = len(sys.argv)
    mode = "default"
    num_of_types = 0

    for i in xrange(0, number_of_arguments):
        if sys.argv[i].lower() == "lammps_input_file":
            lammps_input_file = sys.argv[i + 1]
            print "THE LAMMPS INPUT FILE IS ", lammps_input_file
        elif sys.argv[i].lower() == "lammps_output_file":
            lammps_output_file = sys.argv[i + 1]
            print "THE LAMMPS OUTPUT FILE IS ", lammps_input_file
        elif sys.argv[i].lower() == "lammps_data_file":
            lammps_data_file = sys.argv[i + 1]
            print "THE LAMMPS DATA FILE IS ", lammps_data_file
        elif ((sys.argv[i] == "potential_base")
              or (sys.argv[i] == "potential")):
            potential_base = sys.argv[i + 1]
        elif sys.argv[i].lower() == "lammps_rdf_file":
            lammps_rdf_file = sys.argv[i + 1]
            print "THE RDFS WILL BE READ FROM LAMMPS OUTPUT", lammps_rdf_file
        elif (sys.argv[i] == "correct_rdf_base"):
            correct_rdf_base = sys.argv[i + 1]
            print "THE RDFS TO MATCH TO HAVE THE FILE BASE ", correct_rdf_base
        elif ((sys.argv[i] == "number") or (sys.argv[i] == "current_number")
              or (sys.argv[i] == "iteration_number")):
            number = int(sys.argv[i + 1])
            print "THE CURRENT ITERATION NUMBER IS ", number
        elif ((sys.argv[i] == "pressure_flag") or (sys.argv[i] == "p_flag")):
            p_flag = float(sys.argv[i + 1])
            print "THE PRESSURE FLAG is ", p_flag
        elif ((sys.argv[i] == "pressure_target")
              or (sys.argv[i] == "p_target")):
            p_target = float(sys.argv[i + 1])
            if abs(p_flag) < 0.00001:
                p_flag = 1
            print "THE PRESSURE TARGET is ", p_target
        elif ((sys.argv[i] == "CG_log_file") or (sys.argv[i] == "CG_logfile")):
            CG_output_file = sys.argv[i + 1]
            p_now = read_CG_log_file(CG_output_file, label="Press")
            #TODO: this is only a temp hack!
            print "THE CURRENT PRESSURE WILL BE CALCULATED FROM THE LOG FILE ", CG_output_file, p_now
        elif (sys.argv[i] == "temperature"):
            temperature = float(sys.argv[i + 1])
        elif (sys.argv[i] == "LJ_param_file"):
            LJ_file_flag = 1

        elif sys.argv[i].lower() == "numofbins":
            num_of_bins = int(sys.argv[i + 1])
            print "THE NUMBER OF BINS IS ", num_of_bins
        elif sys.argv[i].lower() == "deltar":
            DeltaR = float(sys.argv[i + 1])
            print "DeltaR IS ", DeltaR

        elif sys.argv[i] == "mode":
            mode = sys.argv[i + 1]
        elif sys.argv[i].lower() == "numoftypes":
            num_of_types = int(sys.argv[i + 1])

    # read in the lammps data file to identify the number of CG types and lattice parameters.
    lattice, type_list = lmp_io.read_lammps_data_file(lammps_data_file)

    num_of_types = len(type_list)
    print "Num of types = ", num_of_types
    #num_of_types = 4

    number_of_types_array = np.zeros((num_of_types + 1))
    for n in xrange(1, num_of_types + 1):
        number_of_types_array[n] = len(type_list["%s" % n])

    if mode == "pressure_correct":

        num_of_bins, cutoff, offset = lmp_io.get_number_of_bins_and_cutoff(
            potential_base, 1)
        print "Potential numofbins and cutoff:", num_of_bins, cutoff

        pots = (potential_base.strip()).split('.')
        atom1 = int(pots[-2])
        atom2 = int(pots[-1])

        print "ATOMS are:", atom1, atom2

        potential = np.zeros((num_of_bins + 1))
        volume = float(lattice[0]) * float(lattice[1]) * float(lattice[2])

        hist_rdf = lmp_io.read_lammps_rdf(lammps_rdf_file, num_of_types,
                                          number)

        pressure_pot = calc_pressure_correction(hist_rdf[atom1][atom2],
                                                num_of_bins, DeltaR,
                                                number_of_types_array[atom1],
                                                number_of_types_array[atom2],
                                                abs(p_flag), p_now, p_target,
                                                volume, temperature)

        old_distance, old_potential, old_derivative = lmp_io.read_in_interaction_file(
            potential_base, num_of_bins)

        potential = apply_pressure_correction(old_potential, pressure_pot,
                                              num_of_bins + 1, old_distance[1],
                                              DeltaR)

        potential[0] = potential[
            1]  # TODO: change this temporary workaround into something more systematic. The workaround reduces anomalies in the derivative at the start of the potential.
        new_derivatives = da.derivatives(np.arange(offset, cutoff, DeltaR),
                                         potential)
        print "dy lens:", num_of_bins, len(new_derivatives), len(
            np.arange(offset - DeltaR, cutoff, DeltaR)), len(potential)

        write_pot_file(
            "%s/pot.%d.new.%d.%d" %
            (os.path.dirname(lammps_output_file), number + 1, atom1, atom2),
            new_derivatives[1:],
            potential[1:],
            num_of_bins,
            DeltaR,
            atom1,
            atom2,
            num_of_bins,
            offset,
            smoothing="no",
            selection="no")  #note: we use an offset here!

    elif mode == "default":
        # Either read an interaction list from a file in the atom_dir (useful if you want to parametrize only a subset of interactions), or generate one on the fly.
        interaction_filename = os.path.dirname(
            correct_rdf_base) + "/interaction_list"
        if os.path.exists(interaction_filename):
            interaction_list = interaction_list_from_file(interaction_filename)
        else:
            interaction_list = generate_interaction_list(num_of_types)

        first_array, num_of_bins, cutoff2 = read_in_rdf_file(
            correct_rdf_base, num_of_types,
            interaction_list)  # read in the rdfs to match to.

        print "THE CUTOFF in the RDF files is", cutoff2, ", with", len(
            first_array[1][1]) - 1, "number of bins "
        print "THIS IS ITERATION NUMBER", number

        deltaR = cutoff2 / num_of_bins  # bin spacing from the RDF
        previous_position, previous_potential, previous_derivative, old_pot_files, cutoff = lmp_io.read_in_interaction_files(
            potential_base, num_of_types, interaction_list, number)
        num_of_bins = int(cutoff / deltaR)

        print deltaR, cutoff2, num_of_bins, correct_rdf_base
        print "THE CUTOFF in the POS FILES is", cutoff, "and number of bins are", num_of_bins

        # read in the RDFs of the CG calculated by LAMMPS.
        hist_rdf = lmp_io.read_lammps_rdf(lammps_rdf_file, num_of_types,
                                          number)
        #  print lammps_rdf_file, len(hist_rdf[1][1])
        DeltaR = cutoff / num_of_bins

        # calculate the IBI
        compute_update(os.path.dirname(lammps_output_file), first_array,
                       hist_rdf, previous_position, previous_potential,
                       num_of_types, number, DeltaR, num_of_bins,
                       number_of_types_array, lattice, LJ_file_flag, p_flag,
                       p_now, p_target, temperature, interaction_list)
        # modify the lammps input file, ready for the next iteration
        modify_lammps_in_file(lammps_input_file, lammps_output_file, number,
                              interaction_list, num_of_types)
    else:
        print "ERROR: mode is incorrectly set in IBI.py. Should be e.g., default or pressure_correct"
        sys.exit()