140 lines
4.4 KiB
Python
Executable File
140 lines
4.4 KiB
Python
Executable File
#!/usr/bin/python3.12
|
||
import argparse
|
||
import configparser
|
||
import math
|
||
import os
|
||
|
||
def compute_dependent(params):
|
||
model = params["model"]
|
||
|
||
# Charge neutrality
|
||
params["charge_B"] = round(params["charge"]/2, 5)
|
||
params["charge_A"] = -2 * params["charge_B"]
|
||
|
||
# Relative sigma and epsilon
|
||
params["sigma_A"] = params["sigma"]
|
||
params["epsilon_A"] = params["sigma"]
|
||
sigma_A = params["sigma"]
|
||
epsilon_A = params["epsilon"]
|
||
params["sigma_B"] = round(params["sigma_rel"] * sigma_A, 5)
|
||
params["epsilon_B"] = round(params["epsilon_rel"] * epsilon_A, 5)
|
||
params["d_AB"] = round(params["r_AB"] * sigma_A, 5)
|
||
params["d_AM"] = round(params["r_AM"] * sigma_A, 5)
|
||
|
||
# Mass: either specified or computed to give τ ≈ 0.1
|
||
if params["mass"] is None:
|
||
# Let total mass m = 2 * m_A, solve: τ = σ * sqrt(m/ε) ≈ 0.1
|
||
tau_target = 0.05 * 10
|
||
m_total = (tau_target / sigma_A)**2 * epsilon_A
|
||
m_atom = m_total / 2
|
||
params["mass"] = round(m_atom, 5)
|
||
|
||
|
||
params["d_BB"] = round(2 * params["d_AB"] * math.sin(math.radians(params["angle_ABA"]) / 2), 5)
|
||
params["dummy_ab"] = round(params["d_AM"] / (2 * math.cos(math.radians(params["angle_ABA"]) / 2)), 5)
|
||
|
||
return params
|
||
|
||
def clean_params(params):
|
||
if params["model"] != "4point":
|
||
for k in ["r_AM", "d_AM", "d_BB", "dummy_ab"]:
|
||
params.pop(k)
|
||
if params["model"] != "3point" and params["model"] != "4point":
|
||
for k in ["r_AB", "d_AB", "angle_ABA"]:
|
||
params.pop(k)
|
||
return params
|
||
|
||
def format_directory_name(params):
|
||
"""Generate a short directory name from active parameters."""
|
||
keys_order = [
|
||
("sigma", "s"),
|
||
("epsilon", "e"),
|
||
("charge", "q"),
|
||
("sigma_rel", "sr"),
|
||
("epsilon_rel", "er"),
|
||
("r_AB", "d"),
|
||
("angle_ABA", "a"),
|
||
("r_AM", "m"),
|
||
]
|
||
|
||
parts = [params["model"]]
|
||
parts.append(f"P{params['pressure']}")
|
||
|
||
for key, prefix in keys_order:
|
||
if key in params:
|
||
val = params[key]
|
||
parts.append(f"{prefix}{val:.5f}".rstrip("0").rstrip("."))
|
||
|
||
parts.append(f"v{params['version']}")
|
||
return "_".join(parts)
|
||
|
||
|
||
def main():
|
||
parser = argparse.ArgumentParser(description="Generate directory and parameter file for A-B molecular systems.")
|
||
parser.add_argument("--version", type=int, default=1, help="Version identifier for parameter sweep")
|
||
parser.add_argument("--model", choices=["atomistic", "3point", "4point"], default='atomistic')
|
||
parser.add_argument("--pressure", type=float, default=1.0)
|
||
|
||
|
||
# Independent parameters
|
||
parser.add_argument("--sigma", type=float, default=0.3)
|
||
parser.add_argument("--epsilon", type=float, default=0.8)
|
||
parser.add_argument("--q", type=float, default=1.0)
|
||
|
||
# Relative parameters
|
||
parser.add_argument("--sigma_rel", type=float, default=0.1)
|
||
parser.add_argument("--epsilon_rel", type=float, default=0.1)
|
||
|
||
# Mass (optional, will be calculated if omitted)
|
||
parser.add_argument("--mass", type=float, default=None)
|
||
|
||
# Geometry for bonded/virtual_site
|
||
parser.add_argument("--r_AB", type=float, default=0.33334)
|
||
parser.add_argument("--angle_ABA", type=float, default=109.5) # 104.52
|
||
parser.add_argument("--r_AM", type=float, default=0.4)
|
||
|
||
# Output
|
||
parser.add_argument("--output", type=str, default="params.ini")
|
||
|
||
args = parser.parse_args()
|
||
|
||
params = {
|
||
"version": args.version,
|
||
"model": args.model,
|
||
"nmol": 1000,
|
||
"pressure": args.pressure,
|
||
"sigma": args.sigma,
|
||
"sigma_rel": args.sigma_rel,
|
||
"epsilon": args.epsilon,
|
||
"epsilon_rel": args.epsilon_rel,
|
||
"charge": args.q,
|
||
"mass": args.mass,
|
||
"r_AB": args.r_AB,
|
||
"angle_ABA": args.angle_ABA,
|
||
"r_AM": args.r_AM,
|
||
}
|
||
|
||
|
||
# Compute dependent values
|
||
params = compute_dependent(params)
|
||
params = clean_params(params)
|
||
|
||
dir_name = format_directory_name(params)
|
||
if os.path.exists(dir_name):
|
||
print(f"Directory {dir_name} already exists. Aborting.")
|
||
return
|
||
os.makedirs(dir_name)
|
||
|
||
# Save to file
|
||
config_path = os.path.join(dir_name, args.output)
|
||
with open(config_path, "w") as f:
|
||
config = configparser.ConfigParser()
|
||
config["params"] = params
|
||
config.write(f)
|
||
|
||
print(f"Parameter file written to {config_path}")
|
||
|
||
if __name__ == "__main__":
|
||
main()
|
||
|