ascec 3.0.0
This code explores the potential energy surface of atomic and molecular clusters using a modified Metropolis criterion and Markov chain. This Python implementation makes the workflow easier and more efficient.
Requires Python: <4.0,>=3.10

# PyASCEC

<p style="text-align: justify"> 
PyASCEC is a Python-based program designed to perform Markov chain simulations of atomic and molecular cluster conformations using a modified Metropolis algorithm. The acceptance criterion is based on the electronic energy of the system. During the simulation, the fragments evolve within a box centered on the center of mass of the input cluster.</p>

<p style="text-align: justify">
For the PyASCEC program to work, you will need to have the Gaussian 09/16 (Default: g09), Dalton, or Dirac program installed. 
Furthermore, the PyASCEC code can likely be modified to interface with other programs.
</p>

Flux diagram for the algorithm is sketched in the following figure[[2]](#2)

<img src="ascec.svg">

If you use this code please cite: 

<p style="text-align: justify"><a id="1">[1]</a>> Pérez, J. F.; Restrepo, A. ASCEC V-01: Annealing Simulado Con Energı́a Cuántica. Property, Development and Implementation; Grupo de Quı́mica-Fı́sica Teórica, Instituto de Quı́mica, Universidad de Antioquia, AA 1226 Medellı́n, Colombia.</p>
> <p style="text-align: justify"><a id="2">[2]</a> Pérez, J. F.; Hadad, C. Z., Restrepo, A. Structural Studies of Water Tetramer. Int. J. Quantum Chem. 2008, 108, 1653.</p>

### Install
To install execute the following command  

```
pip install pyascec
```

### Example 

Motion and rotate each one fragment of cluster

```
from ascec import *

cluster = [
        ["O", 0.000000,  0.000000,  0.118997,
         "H", 0.000000,  0.753010, -0.475986,
         "H", 0.000000, -0.753010, -0.475986,
        ],
        ["O", 0.000000,  0.000000,  0.118997,
         "H", 0.000000,  0.753010, -0.475986,
         "H", 0.000000, -0.753010, -0.475986,
        ],
    ]

# ASCEC object
obj_ascec = ascec(cluster=cluster)
.
# Move each
with open("move_dimer_water.xyz", "w") as f:
    for ig in range(10):
        f.write(f" {obj_ascec.natoms} \n")
        f.write(f" Structure {ig}\n")
        motion_cluster = obj_ascec.move_cluster(obj_ascec.cluster)
        for ifrag in motion_cluster:
            nats = len(ifrag) // 4
            for ia in range(nats):
                ia0 = ia * 4
                f.write(
                    f"{ifrag[ia0]}   {ifrag[ia0+1]}  {ifrag[ia0+2]}  {ifrag[ia0+3]}\n"
                )
```

Exploration of Potential Energy Surface with Gaussian 

```
from ascec import *

cluster = [
        ["O", 0.000000,  0.000000,  0.118997,
         "H", 0.000000,  0.753010, -0.475986,
         "H", 0.000000, -0.753010, -0.475986,
        ],
        ["O", 0.000000,  0.000000,  0.118997,
         "H", 0.000000,  0.753010, -0.475986,
         "H", 0.000000, -0.753010, -0.475986,
        ],
    ]

# Minimum parameters required to run ASCEC and Gaussian.
# The default methodology is HF, and the default basis set is sto-3g.
obj_ascec = ascec(
                 cluster=cluster, 
                 ic=1, # (1:Gaussain,2:Dalton,3:Dirac)
                 alias="g09", 
                )

# More parameters
obj_ascec = ascec(
                 cluster=cluster, 
                 ic=1, # (1:Gaussain,2:Dalton,3:Dirac)
                 alias="g09",  # alias or PATH
                 meth="DFTB3LYP",
                 bas="6-311G",
                 route=2, "1:lineal,2:geometric"
                 Ti=200, 
                 nT=5, 
                 dT=10, 
                 MaxCycles=200, 
                 length=4.0,
                 nproc=2,
                 mem=4.0, # Memory in GB
		 seed=141423122025 # Default: minsecday
                 )

    print(" *** ASCEC Results (Gaussian) ***")
    
    # * Start exploration #####################
    energies, geoms = obj_ascec.pes_exp()
    # * End exploration   #######################

    ngeoms = len(energies)
    print(f"Total the geometries accepted: {ngeoms}")
    cc = obj_ascec.center_cube

    # * Save geometries in .xyz ##########################
    with open("dimer_water.xyz", "w") as f:
        for ic, en in enumerate(energies):
            f.write(f" {natoms} \n")
            f.write(f" Structure {ic} Energy {en} a.u.\n")
            for ifrag in geoms[ic]:
                nats = len(ifrag) // 4
                for ia in range(nats):
                    ia0 = ia * 4
                    f.write(
                        f"{ifrag[ia0]}   {ifrag[ia0+1]}  {ifrag[ia0+2]}  {ifrag[ia0+3]}\n"
                    )
            f.write(f"X     {cc[0] + 2.0}  {cc[0] + 2.0}  {cc[0] + 2.0}\n")
            f.write(f"X     {cc[0] + 2.0}  {cc[0] + 2.0}  {cc[0] - 2.0}\n")
            f.write(f"X     {cc[0] + 2.0}  {cc[0] - 2.0}  {cc[0] + 2.0}\n")
            f.write(f"X     {cc[0] + 2.0}  {cc[0] - 2.0}  {cc[0] - 2.0}\n")
            f.write(f"X     {cc[0] - 2.0}  {cc[0] + 2.0}  {cc[0] + 2.0}\n")
            f.write(f"X     {cc[0] - 2.0}  {cc[0] + 2.0}  {cc[0] - 2.0}\n")
            f.write(f"X     {cc[0] - 2.0}  {cc[0] - 2.0}  {cc[0] + 2.0}\n")
            f.write(f"X     {cc[0] - 2.0}  {cc[0] - 2.0}  {cc[0] - 2.0}\n")
    # * End  #########################################
```

Exploration of Potential Energy Surface with Dirac

```
from ascec import *

cluster = [
        ["O", 0.000000,  0.000000,  0.118997,
         "H", 0.000000,  0.753010, -0.475986,
         "H", 0.000000, -0.753010, -0.475986,
        ],
        ["O", 0.000000,  0.000000,  0.118997,
         "H", 0.000000,  0.753010, -0.475986,
         "H", 0.000000, -0.753010, -0.475986,
        ],
    ]

obj_ascec = ascec(
                 cluster=cluster, 
                 ic=3, # (1:Gaussain,2:Dalton,3:Dirac)
                 alias="PATH/pam",  # alias or PATH
                 scratch="PATH/scratch", # PATH
                 meth="DFTB3LYP",
                 bas="STO-3G", 
                 route=2, "1:lineal,2:geometric"
                 Ti=200, 
                 nT=5, 
                 dT=10, 
                 MaxCycles=200, 
                 length=4.0,
                 nproc=2,
                 mem=4.0 # Memory in GB
                 )

    print(" *** ASCEC Results (Dirac) ***")
    
    # * Start exploration #####################
    energies, geoms = obj_ascec.pes_exp()
    # * End exploration   #######################

    ngeoms = len(energies)
    print(f"Total the geometries accepted: {ngeoms}")
    cc = obj_ascec.center_cube

    # * Save geometries in .xyz ##########################
    with open("dimer_water.xyz", "w") as f:
        for ic, en in enumerate(energies):
            f.write(f" {natoms} \n")
            f.write(f" Structure {ic} Energy {en} a.u.\n")
            for ifrag in geoms[ic]:
                nats = len(ifrag) // 4
                for ia in range(nats):
                    ia0 = ia * 4
                    f.write(
                        f"{ifrag[ia0]}   {ifrag[ia0+1]}  {ifrag[ia0+2]}  {ifrag[ia0+3]}\n"
                    )
            f.write(f"X     {cc[0] + 2.0}  {cc[0] + 2.0}  {cc[0] + 2.0}\n")
            f.write(f"X     {cc[0] + 2.0}  {cc[0] + 2.0}  {cc[0] - 2.0}\n")
            f.write(f"X     {cc[0] + 2.0}  {cc[0] - 2.0}  {cc[0] + 2.0}\n")
            f.write(f"X     {cc[0] + 2.0}  {cc[0] - 2.0}  {cc[0] - 2.0}\n")
            f.write(f"X     {cc[0] - 2.0}  {cc[0] + 2.0}  {cc[0] + 2.0}\n")
            f.write(f"X     {cc[0] - 2.0}  {cc[0] + 2.0}  {cc[0] - 2.0}\n")
            f.write(f"X     {cc[0] - 2.0}  {cc[0] - 2.0}  {cc[0] + 2.0}\n")
            f.write(f"X     {cc[0] - 2.0}  {cc[0] - 2.0}  {cc[0] - 2.0}\n")
    # * End  #########################################
```