Beispiel #1
0
def test_dihedral_scanner_range_masks():
    """
    Test dihedral scanner range limit implemented as masks
    """
    # setup a scanner
    m = Molecule()
    m.elem = ['H'] * 5
    m.xyzs = [
        np.array([[0, 0, 0], [0, 1, 0], [0, 0, 1], [1, 1, 1], [1, 0, 0]],
                 dtype=float) * 0.5
    ]
    m.build_topology()
    engine = EngineBlank()
    dihedrals = [[0, 1, 2, 3], [1, 2, 3, 4]]
    # two ranges are tested, one is normal, one is "split" crossing boundaries
    dihedral_ranges = [[-120, 120], [150, 240]]
    scanner = DihedralScanner(engine,
                              dihedrals=dihedrals,
                              grid_spacing=[30, 30],
                              init_coords_M=m,
                              dihedral_ranges=dihedral_ranges)
    # check dihedral masks
    assert scanner.dihedral_ranges == dihedral_ranges
    assert scanner.dihedral_mask[0] == {
        -120, -90, -60, -30, 0, 30, 60, 90, 120
    }
    assert scanner.dihedral_mask[1] == {-150, -120, 150, 180}
    # test validate_task() function
    task1 = (m, (-120, 120), (-120, 150))
    assert scanner.validate_task(task1) == True
    task2 = (m, (-120, 60), (-120, 90))
    assert scanner.validate_task(task2) == False
Beispiel #2
0
def test_dihedral_scanner_methods():
    """
    Testing methods of DihedralScanner
    """
    # setup a scanner
    m = Molecule()
    m.elem = ['H'] * 5
    m.xyzs = [
        np.array([[0, 0, 0], [0, 1, 0], [0, 0, 1], [1, 1, 1], [1, 0, 0]],
                 dtype=float) * 0.5
    ]
    m.build_topology()
    engine = EngineBlank()
    dihedrals = [[0, 1, 2, 3], [1, 2, 3, 4]]
    scanner = DihedralScanner(engine,
                              dihedrals=dihedrals,
                              grid_spacing=[30, 30],
                              init_coords_M=m)
    # test methods
    gid = (120, -60)
    assert scanner.get_dihedral_id(m) == gid
    assert scanner.get_dihedral_id(m, check_grid_id=(120, -90)) == None
    assert set(scanner.grid_neighbors(gid)) == {(90, -60), (150, -60),
                                                (120, -90), (120, -30)}
    assert set(scanner.grid_full_neighbors(gid)) == {(90, -90), (90, -30),
                                                     (150, -90), (150, -30)}
    scanner.push_initial_opt_tasks()
    assert len(scanner.opt_queue) == 1
    geo, start_gid, end_gid = scanner.opt_queue.pop()
    assert start_gid == end_gid
Beispiel #3
0
def test_dihedral_scanner_energy_upper_limit_filter():
    """
    Test dihedral scanner energy_upper_limit as task filters
    """
    # setup a scanner
    m = Molecule()
    m.elem = ['H'] * 5
    m.xyzs = [
        np.array([[0, 0, 0], [0, 1, 0], [0, 0, 1], [1, 1, 1], [1, 0, 0]],
                 dtype=float) * 0.5
    ]
    m.build_topology()
    engine = EngineBlank()
    dihedrals = [[0, 1, 2, 3], [1, 2, 3, 4]]
    # two ranges are tested, one is normal, one is "split" crossing boundaries
    dihedral_ranges = [[-120, 120], [150, 240]]
    scanner = DihedralScanner(engine,
                              dihedrals=dihedrals,
                              grid_spacing=[30, 30],
                              init_coords_M=m,
                              dihedral_ranges=dihedral_ranges,
                              energy_upper_limit=0.001)
    # check dihedral masks
    assert scanner.energy_upper_limit == 0.001
    # test validate_task() function
    scanner.global_minimum_energy = 0.0
    m.qm_energies = [0.0]
    task1 = (m, (-120, 120), (-120, 150))
    assert scanner.validate_task(task1) == True
    m.qm_energies = [0.0015]
    task2 = (m, (-120, 120), (-120, 150))
    assert scanner.validate_task(task2) == False
Beispiel #4
0
def get_next_jobs(current_state, verbose=False):
    """
    Take current scan state and generate the next set of optimizations.
    This function will create a new DihedralScanRepeater object and read all information from current_state,
    then reproduce the entire scan from the beginning, finish all cached ones, until a new job is not found in the cache.
    Return a list of new jobs that needs to be finished for the current iteration

    Parameters
    ----------
    current_state: dict
        An dictionary containing information of the scan state,
        Required keys: 'dihedrals', 'grid_spacing', 'elements', 'init_coords', 'grid_status'
        Optional keys: 'dihedral_ranges', 'energy_decrease_thresh', 'energy_upper_limit'

    Returns
    -------
    next_jobs: dict
        key is the target grid_id, value is a list of new_job. Each new_job is represented by its start_geo
        * Note: the order of new_job should correspond to the finished job_info.

    Examples
    --------
    current_state = {
            'dihedrals': [[0,1,2,3], [1,2,3,4]] ,
            'grid_spacing': [30, 30],
            'elements': ['H', 'C', 'O', ...]
            'init_coords': [geo1, geo2, ..]
            'grid_status': {(30, 60): [(start_geo, end_geo, end_energy), ..], ...}
        }
    >>> get_next_jobs(current_state)
    {
        (90, 60): [start_geo1, start_geo2, ..],
        (90, 90): [start_geo3, start_geo4, ..],
    }
    """
    dihedrals = current_state['dihedrals']
    grid_spacing = current_state['grid_spacing']
    # rebuild the init_coords_M molecule object
    init_coords_M = Molecule()
    init_coords_M.elem = current_state['elements']
    init_coords_M.xyzs = current_state['init_coords']
    init_coords_M.build_topology()
    # create a new scanner object with blank engine
    engine = EngineBlank()
    dihedral_ranges = current_state.get('dihedral_ranges')
    energy_decrease_thresh = current_state.get('energy_decrease_thresh')
    energy_upper_limit = current_state.get('energy_upper_limit')
    scanner = DihedralScanRepeater(engine, dihedrals, grid_spacing, init_coords_M=init_coords_M, dihedral_ranges=dihedral_ranges, \
         energy_decrease_thresh=energy_decrease_thresh, energy_upper_limit=energy_upper_limit, verbose=verbose)
    # rebuild the task_cache for scanner
    scanner.rebuild_task_cache(current_state['grid_status'])
    # run the scanner until some calculation is not found in cache
    scanner.repeat_scan_process()
    return scanner.next_jobs
def test_dihedral_scanner_setup():
    """
    Testing DihedralScanner Setup for 1-D to 4-D Scans
    """
    engine = EngineBlank()
    for dim in range(1, 5):
        print("Testing %d-D scan setup" % dim)
        dihedrals = [list(range(d, d+4)) for d in range(dim)]
        scanner = DihedralScanner(engine, dihedrals=dihedrals, grid_spacing=[90]*dim)
        gid = scanner.grid_ids[0]
        assert len(scanner.grid_ids) == 4**dim and len(gid) == dim, "Wrong dimension of grid_ids"
        assert len(scanner.grid_neighbors(gid)) == 2*dim, "Wrong dimension of grid_neighbors"
        assert isinstance(scanner.opt_queue, PriorityQueue), "DihedralScanner.opt_queue should be an instance of PriorityQueue"
        assert len(scanner.opt_queue) == 0, "DihedralScanner.opt_queue should be empty after setup"
def test_engine_blank():
    engine = EngineBlank()
    engine.optimize_native()
    engine.optimize_geomeTRIC()
    engine.load_native_output()