Beispiel #1
0
def write_requench_data(lmpdat_a, dcd_ab, index,
                        lmpdat_b=None,
                        output_lmpdat_a="output_name_a.lmpdat",
                        output_lmpdat_b="output_name_b.lmpdat"):
    """
    Write a new data file with the coordinates from a dcd file given by the index.

    Writes a new lammps data file, which has the same topology but different
    coordinates than the lmpdat that is given.

    Parameters
    ----------
    lmpdat_a : str
        lammps data file with the topology e.g. for the solvate

    lmpdat_b : None or str
        lammps data file with the topology e.g. for the solvent

    dcd_ab : str
        dcd file with frames to read from the solvate-solvent system

    index : int
        index to extract the frame from (i.e. index of energetically best frame)

    """
    sys_lmpdat_a = aglmp.read_lmpdat(lmpdat_a)
    sys_lmpdat_a_natoms = len(sys_lmpdat_a.atoms)

    sys_dcd_ab = aglmp.LmpStuff()
    sys_dcd_ab.import_dcd(dcd_ab)

    # read only the best frame which will be appended to the existing ones
    sys_dcd_ab.read_frames(frame=index, to_frame=index + 1)

    # apply box from dcd, since we are dealing with coordinates considering
    # that box (not doing this leads to errors during wrapping)
    sys_lmpdat_a.ts_boxes = sys_dcd_ab.ts_boxes

    # write only relevant coordinates for system a
    sys_lmpdat_a.ts_coords.append(sys_dcd_ab.ts_coords[-1][:sys_lmpdat_a_natoms])

    # wrap coordinates outside the box back inside (may happen when a molecule
    # flies of and reconnects with the aggregate)
    sys_lmpdat_a.wrap_cell(frame_id=-1, same_molecule=True)

    sys_lmpdat_a.change_indices()
    sys_lmpdat_a.write_lmpdat(output_lmpdat_a, -1, title="Best frame of {} with index {}".format(os.path.basename(dcd_ab), index), cgcmm=True)

    # write only relevant coordinates for system b
    if lmpdat_b is not None:
        sys_lmpdat_b = aglmp.read_lmpdat(lmpdat_b)
        sys_lmpdat_b.ts_coords.append(sys_dcd_ab.ts_coords[sys_lmpdat_a_natoms + 1:])
        sys_lmpdat_b.change_indices()
        sys_lmpdat_b.write_lmpdat(output_lmpdat_b, -1, title="Best frame of {} with index {}".format(os.path.basename(dcd_ab), index), cgcmm=True)
Beispiel #2
0
    def _check_success():
        """
        Check aggregation state and close lammps instance properly.
        """
        if rank == 0:
            quench_sys = aglmp.read_lmpdat(lmpcuts.input_lmpdat, dcd=lmpcuts.output_dcd)
            succeeded = quench_sys.check_aggregate()

            # send data to the other ranks
            for other_rank in other_ranks:
                comm.send(succeeded, dest=other_rank)

        else:
            succeeded = comm.recv(source=0)

        #print(succeeded)
        #succeeded = comm.bcast(succeeded, 0)

        # stop trying if it was
        if succeeded is True:
            # write restart file
            lmpcuts.unfix_undump(pylmp, lmp)
            lmp.command("reset_timestep 0")
            lmp.command("write_restart {}".format(lmpcuts.output_lmprst))
            lmp.command("clear")
            lmp.close()

        return succeeded
Beispiel #3
0
def requench(lmpcuts, minstyle="cg"):
    """[summary]

    [description]

    Parameters
    ----------
    lmpcuts : {[type]}
        [description]
    minstyle : {str}, optional
        [description] (the default is "cg", which [default_description])

    Returns
    -------
    [type]
        [description]
    """
    lmp = lammps()
    pylmp = PyLammps(ptr=lmp)
    lmp.command("log {} append".format(lmpcuts.output_lmplog))

    lmp.file(lmpcuts.settings_file)

    # change dielectric
    if lmpcuts.dielectric is not None:
        lmp.command("dielectric {}".format(lmpcuts.dielectric))

    # read restart file from previous run
    lmpcuts.load_system(lmp)
    lmpcuts.thermo(lmp)
    lmp.command("fix ic_prevention all momentum 100 linear 1 1 1 angular rescale")
    lmp.command("fix integrator all nvt temp {0} {1} 0.1".format(lmpcuts.tstart, lmpcuts.tstop))
    lmpcuts.dump(lmp, unwrap=True)

    if lmpcuts.pc_file is not None:
        lmp.file(lmpcuts.pc_file)

    lmp.command("reset_timestep 0")
    lmp.command("run {}".format(lmpcuts.runsteps))
    lmpcuts.minimize(lmp, style=minstyle)
    lmpcuts.unfix_undump(pylmp, lmp)
    lmp.command("write_restart {}".format(lmpcuts.output_lmprst))
    lmp.command("clear")
    lmp.close()

    # check if aggregate is intact after requenching
    md_sys = aglmp.read_lmpdat(lmpcuts.input_lmpdat, lmpcuts.output_dcd)
    aggregate_ok = md_sys.check_aggregate(frame_id=-1)
    return aggregate_ok
Beispiel #4
0
def add_dummy_to_lmpdat(lmpdat, indices_and_values, key_index=0):
    """
    Read and write a new data file with dummy bond-/angle- or dihedral-coeffs.

    Compile a bond-/angle-/dihedral-coeff string for lammps and alter the lammps instance.

    The 'coeff-string' has only values of 0 which means it gets omitted.
    Needed to switch off the energy contribution of a given dihedral in the
    system.

    Parameters
    ----------
    lmp : lammps.lammps instance
        the instance of lammps which will be altered
    lmpdat : str
        lammps data file that is to be read
    indices_and_values : dict
        atom ids and according entity values, e.g. {"1 2 3 4": 120, ...}
    key_index : int
        index of indices_and_values to be processed

    """
    lmp_sys = aglmp.read_lmpdat(lmpdat)
    num_geom_types = None
    key = list(indices_and_values.keys())[key_index]
    cur_geometry = get_geometry_by_key(key)
    null_coeff = None

    if cur_geometry == "bond":
        # geometry types start with 0
        num_geom_types = len(lmp_sys.bnd_types) - 1
        null_coeff_id = num_geom_types + 1
    elif cur_geometry == "angle":
        # geometry types start with 0
        num_geom_types = len(lmp_sys.ang_types) - 1
        null_coeff_id = num_geom_types + 1
    elif cur_geometry == "dihedral":
        # geometry types start with 0
        num_geom_types = len(lmp_sys.dih_types) - 1
        null_coeff_id = num_geom_types + 1
    # impropers are not supported by fix restrain
    else:
        raise Warning("***Warning: Something went wrong!")
    return (cur_geometry, null_coeff_id)
Beispiel #5
0
def add_dummy_entry(lmpdat):
    """
    Add dummy entries to the lammps data file.

    Parameters
    ----------
    lmpdat : str
        name of the lammps data file

    """
    md_sys = aglmp.read_lmpdat(lmpdat)
    if md_sys.bnd_types != {}:
        ntypes = len(md_sys.bnd_types)
        if md_sys.bnd_types[ntypes - 1].prm1 > 0:
            md_sys.bnd_types[ntypes] = mds.Bond(
                bnd_key=ntypes,
                prm1=0.0,
                prm2=0.0,
                comment=" dummy bond for force field fitting")

    if md_sys.ang_types != {}:
        ntypes = len(md_sys.ang_types)
        if md_sys.ang_types[ntypes - 1].prm1 > 0:
            md_sys.ang_types[ntypes] = mds.Angle(
                ang_key=ntypes,
                prm1=0.0,
                prm2=0.0,
                comment=" dummy bond for force field fitting")

    if md_sys.dih_types != {}:
        ntypes = len(md_sys.dih_types)
        if md_sys.dih_types[ntypes - 1].prm_k > 0:
            md_sys.dih_types[ntypes] = mds.Dihedral(
                dih_key=ntypes,
                prm_k=0.0,
                prm_n=1,
                prm_d=0,
                weigh_factor=0,
                comment=" dummy angle for force field fitting")

    md_sys.change_indices(incr=1, mode="increase")
    md_sys.write_lmpdat(lmpdat, frame_id=-1, title="Default Title", cgcmm=True)
    return True
Beispiel #6
0
def get_shift_vector(lmpdat, atoms_cog1, atoms_cog2, dcd=None, frame_id=-1):
    """
    Calculate the vector for shifting both molecules.

    Parameters
    ----------
    lmpdat : str
        lammps data file

    dcd : str or None
        default: None
        dcd file from molecular dynamics run which supplies the latest
        coordinates

    atoms_cog1 : tuple or list
        atom indices that form the first center of geometry;
        if only one atom is given, it will be the center of geometry

    atoms_cog2 : tuple or list
        same as atoms_cog1 but for 2nd center of geometry

    Returns:
    --------
    vt_shift : np-array
        normalized shifting vector

    """
    dimer = read_lmpdat(lmpdat, dcd)

    if len(atoms_cog1) > 1:
        cog1 = dimer.get_cog(frame_id, *atoms_cog1)
        cog2 = dimer.get_cog(frame_id, *atoms_cog2)
    else:
        cog1 = dimer.ts_coords[frame_id][atoms_cog1[0]]
        cog2 = dimer.ts_coords[frame_id][atoms_cog2[0]]

    vt_shift = cog1 - cog2
    vt_shift /= np.linalg.norm(vt_shift)
    return vt_shift
Beispiel #7
0
def calculate_distances(lmpdat, dcd, idxs_atm1, idxs_atm2):
    """
    Calculate the distance between the center of geometry of the two benzene rings.
    """
    distances = []
    dimer_sys = read_lmpdat(lmpdat, dcd, frame_idx_start=0)
    #pdb.set_trace()

    for frame_idx in range(0, len(dimer_sys.ts_coords)):

        if len(idxs_atm1) == 1:
            cog1 = dimer_sys.ts_coords[frame_idx][idxs_atm1[0]]
        else:
            cog1 = dimer_sys.get_cog(frame_idx, *idxs_atm1)

        if len(idxs_atm2) == 1:
            cog2 = dimer_sys.ts_coords[frame_idx][idxs_atm2[0]]
        else:
            cog2 = dimer_sys.get_cog(frame_idx, *idxs_atm2)

        distance = np.linalg.norm(cog1 - cog2)
        distances.append(distance)

    return distances
Beispiel #8
0
    #-------------------------------------------------------------------------------
    inverse_help = "Selection: box (normal), negative of box (inverted)"
    shft_cut_result = "Shift the cut out coordinates by these 3 vectors (index 0, 1, 2: a; 3, 4, 5: b; 6, 7, 8: c"
    enlarge_cut_help = "Enlarge the box of the cuttings shape by this vector"
    parser.add_argument("-inverse", default=False, action="store_true", help=inverse_help)
    parser.add_argument("-shft_cut_result", nargs=3, type=float, default=(0.0, 0.0, 0.0), metavar=("sx, sy, sz"), help=shft_cut_result)
    parser.add_argument("-scale_cut", default=None, nargs=9, type=float, metavar=2.42, help=enlarge_cut_help)

    parser.add_argument("-out", default="test.lmpdat")

    args = parser.parse_args()

    #===============================================================================
    # PREPARE THE MAIN SYSTEM
    #===============================================================================
    sys_cutfrom = ag_lammps.read_lmpdat(args.lmpdat, dcd=args.dcd, frame_idx_start=args.f, frame_idx_stop=args.f)

    # replicate cell if desired
    if args.rep is not None:
        # read last frame since the frame selection was done with read_lmpdat already
        sys_cutfrom.replicate_cell(n_start=args.rep[0], n_stop=args.rep[1], direction="a", frame_id=-1, adjust_box=True)
        sys_cutfrom.replicate_cell(n_start=args.rep[2], n_stop=args.rep[3], direction="b", frame_id=-1, adjust_box=True)
        sys_cutfrom.replicate_cell(n_start=args.rep[4], n_stop=args.rep[5], direction="c", frame_id=-1, adjust_box=True)
        sys_cutfrom.fetch_molecules_by_bonds()
        sys_cutfrom.mols_to_grps()

    # shift sys_cutfrom by given vector
    if args.shft is not None:
        args.shft = np.array(args.shft)
        M_shft = cgt.translation_matrix(args.shft)
        atm_idxs = list(range(len(sys_cutfrom.atoms)))
Beispiel #9
0
                        else:
                            print("***Quenching-Info: Quenching done!")

                        # after 20 failed attempts, end run
                        if quench_attempts > 20 and quench_success is False:
                            exit(101)

                        #del quench_attempts

                #======================================================================#
                # 3. ANNEALING
                #======================================================================#
                if os.path.isfile(lmpsettings_anneal.output_lmprst) is False:
                    if rank == 0:
                        agk.create_folder(anneal_dir)
                        solvate_sys = aglmp.read_lmpdat(lmpsettings_quench.input_lmpdat,
                                                        dcd=lmpsettings_quench.output_dcd)
                        solvate_sys_natoms = len(solvate_sys.atoms)
                        atm_idxs_solvate = list(range(solvate_sys_natoms))

                        # change box size according to the coordinates from
                        # quenching in order to save space
                        solvate_sys.def_boxes_by_coords(addition=(20, 20, 20), boxtype="lammps")

                    else:
                        solvate_sys = None
                        atm_idxs_solvate = None
                        solvate_sys_natoms = None

                    solvate_sys = comm.bcast(solvate_sys, 0)
                    atm_idxs_solvate = comm.bcast(atm_idxs_solvate, 0)
                    solvate_sys_natoms = comm.bcast(solvate_sys_natoms, 0)
Beispiel #10
0
def create_voids(lmpcuts, lmpdat_solvate, dcd_solvate=None, dcd_solvent=None):
    """
    """
    # solvate with molecule radii and cogs
    solvate_sys = aglmp.read_lmpdat(lmpdat_solvate, dcd_solvate, frame_idx_start=-2, frame_idx_stop=-1)
    radii_mol, cogs_mol = _molecules_radii(solvate_sys)
    indent_strs = _fix_indent_ids(radii_mol, cogs_mol, "molecule", scale_start=10, scale_stop=15)

    # load solution system (last frame only)
    solvent_sys = aglmp.read_lmpdat(lmpcuts.input_lmpdat, dcd_solvent, frame_idx_start=-2, frame_idx_stop=-1)
    solution_sys = mdu.merge_systems([solvate_sys, solvent_sys])
    solution_sys.reset_cells()

    # check solvate atoms with too close contacts to solvent atoms
    close_atoms = _check_clashes(solution_sys, solvate_sys, solvent_sys)
    cogs_atoms = [solvate_sys.ts_coords[-1][i] for i in close_atoms]
    radii_atoms = [mde.elements_mass_radii[round(solvate_sys.atm_types[solvate_sys.atoms[i].atm_key].weigh, 1)] for i in close_atoms]

    # gather close atoms and remember which were close
    all_close_atoms = []
    all_radii_atoms = []
    all_cogs_atoms = []

    all_close_atoms.extend(close_atoms)
    all_radii_atoms.extend(radii_atoms)
    all_cogs_atoms.extend(cogs_atoms)

    # load lammps and lammps settings
    lmp = lammps()
    pylmp = PyLammps(ptr=lmp)
    lmp.command("log {}".format(lmpcuts.output_lmplog))

    if lmpcuts.gpu is True:
        lmpcuts.use_gpu(lmp)

    lmp.file(lmpcuts.settings_file)

    # change dielectric
    if lmpcuts.dielectric is not None:
        lmp.command("dielectric {}".format(lmpcuts.dielectric))

    lmpcuts.load_system(lmp)
    lmpcuts.thermo(lmp)
    lmp.command("fix ic_prevention all momentum 100 linear 1 1 1 angular rescale")
    lmpcuts.dump(lmp, unwrap=True)

    if lmpcuts.pc_file is not None:
        lmp.file(lmpcuts.pc_file)

    #lmpcuts.fix_berendsen(lmp, group="all", ensemble="nve", keyword="iso")
    lmpcuts.fix_berendsen(lmp, group="all", ensemble="npt", keyword="iso", integrator="nve/limit 0.2")
    #lmp.command("unfix integrator")
    #lmp.command("fix limit_movement all nve/limit 0.05")
    _lmp_indent(lmp, indent_strs, lmpcuts.runsteps, keep_last_fixes=True)

    factor_start = 10
    factor_stop = factor_start + 1

    if close_atoms != []:
        # move solvent molecules away from close solvate atoms
        for _ in range(5):
            indent_strs = _fix_indent_ids(all_radii_atoms, all_cogs_atoms, "atom", scale_start=factor_start, scale_stop=factor_stop)
            _lmp_indent(lmp, indent_strs, lmpcuts.runsteps, keep_last_fixes=False)
            close_atoms = _check_clashes(solution_sys, solvate_sys, solvent_sys, lmpcuts.output_dcd)

            # add new close atoms to present ones or stop indenting
            if close_atoms == []:
                break

            # add further close atoms to present ones
            for atm_idx in close_atoms:
                #print(close_atoms)
                if atm_idx not in all_close_atoms:
                    all_close_atoms.append(atm_idx)
                    all_radii_atoms.append(mde.elements_mass_radii[round(solvate_sys.atm_types[solvate_sys.atoms[i].atm_key].weigh, 1)])
                    all_cogs_atoms.append(solvate_sys.ts_coords[-1][atm_idx])

            # dynamically grow sphere around atoms
            factor_start += 1
            factor_stop = factor_start + 1

    lmpcuts.unfix_undump(pylmp, lmp)
    lmp.command("write_restart {}".format(lmpcuts.output_lmprst))
    lmp.command("clear")
    lmp.close()

    return close_atoms == []
Beispiel #11
0
def quench(lmpcuts, lmpdat_main, runs=20, split=None):
    """
    """
    # check how many cores are used, leave the list empty if it is only one
    try:
        other_ranks = list(range(lmpcuts.ncores))[1:]
    except ValueError:
        other_ranks = []

    def _check_success():
        """
        Check aggregation state and close lammps instance properly.
        """
        if rank == 0:
            quench_sys = aglmp.read_lmpdat(lmpcuts.input_lmpdat, dcd=lmpcuts.output_dcd)
            succeeded = quench_sys.check_aggregate()

            # send data to the other ranks
            for other_rank in other_ranks:
                comm.send(succeeded, dest=other_rank)

        else:
            succeeded = comm.recv(source=0)

        #print(succeeded)
        #succeeded = comm.bcast(succeeded, 0)

        # stop trying if it was
        if succeeded is True:
            # write restart file
            lmpcuts.unfix_undump(pylmp, lmp)
            lmp.command("reset_timestep 0")
            lmp.command("write_restart {}".format(lmpcuts.output_lmprst))
            lmp.command("clear")
            lmp.close()

        return succeeded

    def _run(steps):
        """
        Helper function for running and catching an exception when anything
        goes wrong.
        """
        try:
            lmp.command("run {}".format(steps))
        except:
            # prevent deadlock by not nicely ending the whole program if more
            # than one rank is used
            if size > 1:
                MPI.COMM_WORLD.Abort()

    natoms_main_sys = get_natms(lmpdat_main)

    lmp = lammps(comm=split)
    pylmp = PyLammps(ptr=lmp)
    lmp.command("log {} append".format(lmpcuts.output_lmplog))

    if lmpcuts.gpu is True:
        lmpcuts.use_gpu(lmp, neigh=False)

    lmp.file(lmpcuts.settings_file)

    # change dielectric
    if lmpcuts.dielectric is not None:
        lmp.command("dielectric {}".format(lmpcuts.dielectric))

    lmpcuts.load_system(lmp)

    #lmp.command("velocity all create {} {} mom yes rot yes dist gaussian".format(lmpcuts.tstart, np.random.randint(29847587)))
    lmp.command("fix ic_prevention all momentum 100 linear 1 1 1 angular rescale")
    lmpcuts.dump(lmp, unwrap=True)
    lmpcuts.thermo(lmp)

    if lmpcuts.pc_file is not None:
        lmp.file(lmpcuts.pc_file)

    # distribute the available cores if we have lots of vacuum in our box
    lmp.command("comm_style tiled")
    lmp.command("balance 1.0 rcb")

    # define the atoms that may move during the simulation
    lmp.command("group grp_add_sys id > {}".format(natoms_main_sys))
    #lmp.command("group grp_main_sys id <= {}".format(natoms_main_sys))
    #lmp.command("fix freeze grp_main_sys setforce {0} {0} {0}".format(0.0))

    # pre-optimization
    lmp.command("min_style cg")
    lmp.command("min_modify dmax 0.5")
    lmp.command("minimize 1.0e-5 1.0e-8 10000 100000")

    # set an additional push to the added atoms that should be docked
    # towards the origin at (0/0/0)
    # (prevents losing atoms due to being localized outside the cutoff)
    if rank == 0:
        prep_sys = aglmp.read_lmpdat(lmpcuts.input_lmpdat)
        cog = agm.get_cog(prep_sys.ts_coords[-1][natoms_main_sys + 1:])
        cog /= np.linalg.norm(cog, axis=0)  # unit vector
        # make vector show towards the center (0/0/0)
        cog_force = cog * -1

        for other_rank in other_ranks:
            comm.send(cog_force, dest=other_rank)

    else:
        cog_force = comm.recv(source=0)

    #cog_force = comm.bcast(cog_force, 0)
    # barostatting, thermostatting only for atoms that will be docked
    lmp.command("fix integrator grp_add_sys nvt temp {0} {1} 0.1".format(lmpcuts.tstart, lmpcuts.tstop))
    quench_success = False

    # runs attempts to dock the molecule
    for _ in range(runs):
        # minimize and check if that is enough for docking
        lmp.command("min_style quickmin")
        lmp.command("minimize 1.0e-5 1.0e-8 10000 100000")

        lmp.command("min_style cg")
        lmp.command("minimize 1.0e-5 1.0e-8 10000 100000")

        # check aggregate, i.e. docking was a success
        quench_success = _check_success()

        if quench_success is True:
            break

        del quench_success
        # perform a little molecular dynamics simulation with
        # half of the lmpcuts.runsteps
        _run(int(lmpcuts.runsteps))

        # check aggregate, i.e. docking was a success
        quench_success = _check_success()

        if quench_success is True:
            break

        del quench_success
        # give 'to-be-docked' molecules a little push if minimization was not
        # sufficient for aggregation
        addforce_cmd = "fix push grp_add_sys addforce {c[0]} {c[1]} {c[2]} every 1"
        addforce_cmd = addforce_cmd.format(c=cog_force)
        lmp.command(addforce_cmd)
        #import time
        #time.sleep(30)

        # set force does not work
        #lmp.command("fix push grp_add_sys setforce {0} {0} {0}".format(*cog))
        _run(1)

        # remove pushing force
        lmp.command("unfix push")

        # run the 2nd half of the simulation with push 'grp_add_sys'
        _run(int(lmpcuts.runsteps * 0.5))

        # stop to-be-docked molecules from moving
        #lmp.command("velocity grp_add_sys set 0.0 0.0 0.0")
        #lmp.command("fix freeze grp_add_sys setforce {0} {0} {0}".format(0.0))

        _run(int(lmpcuts.runsteps * 0.25))

    return quench_success
Beispiel #12
0
def sysprep(lmpdat_out, lmpdat_main, lmpdat_add, dcd_main=None, dcd_add=None, frame_idx_main=-1, frame_idx_add=-1):
    """
    Prepare the system for the next docking step.

    Since the kawska-zahn approach adds an agglomerate of molecules each stage,
    the system must be prepared for lammps beforehand. Therefor a sphere with
    radius r1 is created around the main system as well as a sphere with radius
    r2 around the agglomerate to add. Both systems are combined, checked for clashes
    and eventually a new lammps data file is written which can further be
    utilized. If

    Parameters
    ----------
    lmpdat_out : str
        Name of merged lammps data file to write

    lmpdat_main : str
        Name of the lammps data file to add another system to

    lmpdat_add : str
        Name of the lammps data file which is added to the main molecular
        system

    dcd_main : str (optional, default: None)
        dcd file to load on top of lmpdat_main

    dcd_add : str (optional, default: None)
        dcd file to load on top of lmpdat_add

    frame_idx_main : int
        frame index of frame to add from dcd_main to lmpdat_main

    frame_idx_add : int
        frame index of frame to add from dcd_add to lmpdat_add

    Returns
    -------
    success : bool
        True if successful, False otherwise.

    Writes a new lammps data file called sysprep_out_index

    """
    # read and transpose the main sys to the origin
    main_sys = aglmp.read_lmpdat(lmpdat_main, dcd_main, frame_idx_main)
    main_sys.transpose_by_cog(-1, [0, 0, 0], copy=False)
    _natoms = len(main_sys.atoms)

    # read and transpose the add sys to the origin
    add_sys = aglmp.read_lmpdat(lmpdat_add, dcd_add, frame_idx_add)
    add_sys.transpose_by_cog(-1, [0, 0, 0], copy=False)

    # rotate add sys
    _rotate_sys(add_sys)

    # shift add sys to sphere around main sys
    main_sys_radius = main_sys.get_system_radius(-1)
    add_sys_radius = add_sys.get_system_radius(-1)
    kwz_radius = main_sys_radius + add_sys_radius

    _shift_sys(add_sys, kwz_radius)

    # merge both systems
    main_sys.extend_universe(add_sys, mode="merge")
    _create_new_box(main_sys)

    # group atoms by bonds
    main_sys.fetch_molecules_by_bonds()
    main_sys.mols_to_grps()

    success = _check_sys(main_sys, _natoms)

    # write an output lammps data only if everything worked out
    if success is True:
        # write new data file
        main_sys.change_indices(incr=1, mode="increase")
        main_sys.write_lmpdat(lmpdat_out, frame_id=0, title="System ready" +
                              "for docking", cgcmm=True)
    return success
Beispiel #13
0
def anneal_productive(lmpcuts, atm_idxs_solvate, percentage_to_check, ensemble, group="all", keyword=None, attempts=500, output=None):
    """
    Carry out a productive run for the annealing step of the Kawska-Zahn approach.

    Check regularly if the simulation is equilibrated (i.e. PotEng of the system
    is normally distributed). If that criteria is fulfilled, stop and check if
    the aggregate of the last frame is still intact (what is happening in between
    is not of our concern and will be checked later when the best conformation
    of the complex is chosen).

    Parameters
    ----------
    lmpcuts : ag_lammps_sim.LmpSim
        The simulation settings.
    atm_idxs_solvate : list or tuple
        Indices of the solvate atoms.
    percentage_to_check : int or float, float will be converted to int
        The percentage of all frames (starting from the last frame to the first)
        to check the equilibration state from.
    ensemble : str
        The ensemble to run the simulation with
    group : str, optional
        The group of atoms that will be integrated. Uses lammps syntax for
        grouping. The default value is 'all'
    keyword : str, optional
        The keyword for the box relaxation. Allowed keywords are the same as
        in the lammps manual for barostatting: iso, aniso, tri. Default is 'None',
        which means no barostatting is done (i.e. nvt).
    output : str, optional
        Prefix for all files which were/are written by the run.

    Returns
    -------
    aggregate_ok : boolean
        The status of the aggregate. 'True' if aggregate did not dissolve, during
        the run, 'False' if it did.
    dcd_files : list
        A list of all DCD files that were written during the run. For each sub-
        run, an int starting from '0' is prepended to the filename until the
        whole simulation (formed by all sub-runs) shows convergence.
    log_files : list
        A list of all lammps log files that were written during the run. For each sub-
        run, an int starting from '0' is prepended to the filename until the
        whole simulation (formed by all sub-runs) shows convergence. Log-files
        are always in accordance to the current DCD file.

    """
    all_data = []
    solvate_sys_natoms = len(atm_idxs_solvate)
    dcd_files = []
    log_files = []

    # renaming the current found files independently of their original name automatically
    # sorts them in the right order
    for run_idx in range(attempts):
        # get just the base name of the files
        dcd_path, dcd_filename = os.path.split(lmpcuts.output_dcd)
        log_path, log_filename = os.path.split(lmpcuts.output_lmplog)

        # create a filename having 'run_idx' and check if this file already exists
        run_idx_pattern = re.compile(r'^[0-9]+')

        # check if filename starts with an integer
        if run_idx_pattern.match(dcd_filename) is not None:
            # split dcd-file by '_'
            split_dcd_filename = dcd_filename.split("_")
            dcd_filename = "{}_{}_{}".format(run_idx, split_dcd_filename[1], split_dcd_filename[2])
            del split_dcd_filename
        else:
            dcd_filename = str(run_idx) + "_" + dcd_filename

        if run_idx_pattern.match(log_filename) is not None:
            split_log_filename = log_filename.split("_")
            log_filename = "{}_{}_{}".format(run_idx, split_log_filename[1], split_log_filename[2])
            del split_log_filename
        else:
            log_filename = str(run_idx) + "_" + log_filename

        lmpcuts.output_dcd = "{}/{}".format(dcd_path, dcd_filename)
        lmpcuts.output_lmplog = "{}/{}".format(log_path, log_filename)

        # read previous log- and dcd-files if they exist already
        if os.path.isfile(lmpcuts.output_dcd) and os.path.isfile(lmpcuts.output_lmplog):
            dcd_files.append(lmpcuts.output_dcd)
            log_files.append(lmpcuts.output_lmplog)

            # read potential energy of all coordinates
            if rank == 0:

                # if this fails, then a lmplog was written but no simulation
                # was carried out
                try:
                    _append_data(all_data, lmpcuts.output_lmplog)
                except IndexError:
                    os.remove(lmpcuts.output_dcd)
                    os.remove(lmpcuts.output_lmplog)
                    dcd_files.pop(-1)
                    log_files.pop(-1)

            # skip the rest as often as there is no new file
            continue

        else:
            # carry out annealing run
            _anneal(lmpcuts, atm_idxs_solvate, ensemble, group, keyword)
            dcd_files.append(lmpcuts.output_dcd)
            log_files.append(lmpcuts.output_lmplog)

            # append data of last run
            if rank == 0:
                _append_data(all_data, lmpcuts.output_lmplog)

        # test given data so far (test applies to each newly carried out run)
        if rank == 0:
            # caveat:   each first frame of output_lmplog is omitted since
            #           it is not part of the dcd file
            # check last N % of all frames
            num_frames_to_check = int(percentage_to_check / 100 * len(all_data))

            # last X % of all frames (from end to start)
            normally_dstributed = _test_anneal_equil(all_data[-num_frames_to_check:], xlabel="Potential Energy / eV", output=output)

            # check if aggregate is still fine after the last run (only if we have a normal distribution)
            solution_sys = aglmp.read_lmpdat(lmpcuts.input_lmpdat, lmpcuts.output_dcd)
            solution_sys_atoms_idxs = list(range(len(solution_sys.atoms)))
            aggregate_ok = solution_sys.check_aggregate(frame_id=-1, excluded_atm_idxs=solution_sys_atoms_idxs[solvate_sys_natoms:])
            del (num_frames_to_check, solution_sys, solution_sys_atoms_idxs)
        else:
            aggregate_ok = False
            normally_dstributed = False

        aggregate_ok = comm.bcast(aggregate_ok)
        normally_dstributed = comm.bcast(normally_dstributed)

        # stop further runs if the aggregate is not ok or if the aggregate
        # is ok and the run is equilibrated (i.e. normal distribution of the
        # potential energy of the whole system)
        if (aggregate_ok is True and normally_dstributed is True) or aggregate_ok is False:
            break

        # the following prevents the 'else' condition (from for loop above) to execute
        #if run_idx == (attempts - 1):
        #    break

    # this only applies if all attempts already exist, but the
    # 'lmpcuts.output_lmprst' file was never written (e.g. due to aborted runs)
    else:
        aggregate_ok = False

        if rank == 0:
            num_frames_to_check = int(percentage_to_check / 100 * len(all_data))
            normally_dstributed = _test_anneal_equil(all_data[-num_frames_to_check:], xlabel="Potential Energy / eV", output=output)

            if normally_dstributed is True:
                solution_sys = aglmp.read_lmpdat(lmpcuts.input_lmpdat, lmpcuts.output_dcd)
                solution_sys_atoms_idxs = list(range(len(solution_sys.atoms)))
                aggregate_ok = solution_sys.check_aggregate(frame_id=-1, excluded_atm_idxs=solution_sys_atoms_idxs[solvate_sys_natoms:])
        else:
            normally_dstributed = False
            aggregate_ok = False

        aggregate_ok = comm.bcast(aggregate_ok, root=0)
        normally_dstributed = comm.bcast(normally_dstributed, root=0)

        #if aggregate_ok is True and normally_dstributed is True:
        #    sl.copy(lmpcuts.inter_lmprst, lmpcuts.output_lmprst)

    # if everything worked, name intermediate restart file as final output file
    if aggregate_ok is True and normally_dstributed is True:
        sl.copy(lmpcuts.inter_lmprst, lmpcuts.output_lmprst)

    return aggregate_ok and normally_dstributed
Beispiel #14
0
)
args = parser.parse_args()

# Modeling ---------------------------------------------------------------------
sys_all = []

for idx, lmpdat in enumerate(args.lmpdats):

    try:
        curdcd = args.dcds[idx]
    except (TypeError, IndexError):
        # args.dcds is None or list is too short
        curdcd = None

    cursys = ag_lammps.read_lmpdat(lmpdat,
                                   dcd=curdcd,
                                   frame_idx_start=-1,
                                   frame_idx_stop=-1)

    # resetting the pair types
    cursys.pair_types = []

    cursys.fetch_molecules_by_bonds()
    cursys.mols_to_grps()
    sys_all.append(cursys)

    # show all cell vectors of each loaded system in lattice form
    if args.show_lattice_cells is True:
        cursys.ts_boxes[-1].box_lmp2lat()
        print("System {}".format(idx))
        print(cursys.ts_boxes[-1].ltc_a)
        print(cursys.ts_boxes[-1].ltc_b)