2015-03-27 19:03:15 +01:00
|
|
|
#!/usr/bin/env python
|
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
import unittest
|
|
|
|
import subprocess
|
|
|
|
import os
|
2015-03-30 10:15:35 +02:00
|
|
|
import sys
|
2015-03-27 19:03:15 +01:00
|
|
|
|
2015-06-08 14:49:10 +02:00
|
|
|
qpackage_root = os.environ['QP_ROOT']
|
2015-03-27 19:03:15 +01:00
|
|
|
|
2015-06-08 14:49:10 +02:00
|
|
|
EZFIO = "{0}/install/EZFIO".format(qpackage_root)
|
2015-03-27 19:03:15 +01:00
|
|
|
sys.path = [EZFIO + "/Python"] + sys.path
|
|
|
|
|
|
|
|
from ezfio import ezfio
|
2015-03-30 10:15:35 +02:00
|
|
|
from collections import defaultdict
|
2015-05-05 10:28:04 +02:00
|
|
|
from collections import namedtuple
|
|
|
|
|
|
|
|
Energy = namedtuple('Energy', ['without_pseudo', 'with_pseudo'])
|
2015-03-30 10:15:35 +02:00
|
|
|
|
|
|
|
# ~#~#~ #
|
|
|
|
# O p t #
|
|
|
|
# ~#~#~ #
|
2015-03-27 19:03:15 +01:00
|
|
|
|
2015-05-28 14:05:13 +02:00
|
|
|
precision = 5.e-7
|
2015-03-27 19:03:15 +01:00
|
|
|
|
2015-03-30 10:15:35 +02:00
|
|
|
# A test get a geo file and a basis file.
|
|
|
|
# A global dict containt the result for this test
|
|
|
|
# A test return True or Raise a error !
|
|
|
|
# More ezfio condition you set, beter it is
|
2015-03-27 19:03:15 +01:00
|
|
|
|
|
|
|
|
2015-03-30 10:37:11 +02:00
|
|
|
# You cannot order the test flow.
|
|
|
|
# So if you dont whant to remarque on test (for example the HF), set
|
|
|
|
# a global variable and check for it
|
|
|
|
global has_hf_alredy
|
|
|
|
has_hf_alredy = False
|
|
|
|
|
2015-04-01 14:26:42 +02:00
|
|
|
global filename_check
|
2015-03-31 13:31:43 +02:00
|
|
|
|
2015-04-01 14:26:42 +02:00
|
|
|
|
2015-05-05 10:28:04 +02:00
|
|
|
def init_folder(geo, basis, mult=1, pseudo=False, ezfio_name=None):
|
2015-03-30 10:15:35 +02:00
|
|
|
'''
|
|
|
|
Take a geo in arg (aka a existing geo.xyz in test/)
|
|
|
|
And create the geo.ezfio with the adeguate basis and multipliciti
|
|
|
|
DO NOT CHECK IS THE EZFIO FOLDER ALREADY EXIST
|
|
|
|
'''
|
2015-03-27 19:03:15 +01:00
|
|
|
|
2015-04-01 14:26:42 +02:00
|
|
|
if not ezfio_name:
|
|
|
|
ezfio_name = geo
|
|
|
|
|
2015-05-05 10:28:04 +02:00
|
|
|
if pseudo:
|
|
|
|
cmd = "qp_create_ezfio_from_xyz -b {0} -m {1} {2}.xyz -p -o {3}.ezfio"
|
|
|
|
else:
|
|
|
|
cmd = "qp_create_ezfio_from_xyz -b {0} -m {1} {2}.xyz -o {3}.ezfio"
|
|
|
|
|
2015-04-01 14:26:42 +02:00
|
|
|
subprocess.check_call([cmd.format(basis, mult, geo, ezfio_name)],
|
|
|
|
shell=True)
|
2015-03-27 19:03:15 +01:00
|
|
|
|
2015-03-30 10:15:35 +02:00
|
|
|
def get_error_message(l_exepected, l_cur):
|
2015-03-31 13:31:43 +02:00
|
|
|
l_msg = ["Need {0} get {1} error is {2}".format(i, j, abs(i - j))
|
|
|
|
for i, j in zip(l_exepected, l_cur)]
|
2015-05-05 10:28:04 +02:00
|
|
|
return "\n" + "\n".join(l_msg)
|
2015-03-30 10:15:35 +02:00
|
|
|
|
|
|
|
|
2015-04-01 14:26:42 +02:00
|
|
|
# _
|
|
|
|
# / |_ _ _ | o ._ ._ _|_
|
|
|
|
# \_ | | (/_ (_ |< | | | |_) |_| |_
|
|
|
|
# |
|
|
|
|
def check_disk_acess(geo, basis, mult=1):
|
2015-04-01 12:02:02 +02:00
|
|
|
|
2015-04-01 14:26:42 +02:00
|
|
|
import uuid
|
|
|
|
filename = str(uuid.uuid4())
|
|
|
|
|
|
|
|
# ~#~#~#~ #
|
|
|
|
# I n i t #
|
|
|
|
# ~#~#~#~ #
|
|
|
|
|
|
|
|
init_folder(geo, basis, mult, ezfio_name=filename)
|
|
|
|
ezfio.set_file("{0}.ezfio".format(filename))
|
|
|
|
|
|
|
|
# ~#~#~#~#~#~#~#~#~#~#~#~#~ #
|
|
|
|
# S e t _ p a r a m e t e r #
|
|
|
|
# ~#~#~#~#~#~#~#~#~#~#~#~#~ #
|
|
|
|
|
|
|
|
# Test 1
|
2015-05-12 12:08:18 +02:00
|
|
|
ezfio.integrals_bielec_disk_access_ao_integrals = "Write"
|
2015-04-01 14:26:42 +02:00
|
|
|
cmd = "qp_edit -c {0}.ezfio".format(filename)
|
|
|
|
subprocess.check_call([cmd], shell=True)
|
|
|
|
|
|
|
|
# Test 2
|
2015-05-12 12:08:18 +02:00
|
|
|
ezfio.integrals_bielec_disk_access_ao_integrals = "IculeAcess"
|
2015-04-01 14:26:42 +02:00
|
|
|
cmd = "qp_edit -c {0}.ezfio".format(filename)
|
|
|
|
|
|
|
|
try:
|
|
|
|
subprocess.check_call([cmd], shell=True)
|
|
|
|
return_code = False
|
|
|
|
except subprocess.CalledProcessError:
|
|
|
|
return_code = True
|
|
|
|
|
|
|
|
# ~#~#~#~#~#~#~#~ #
|
|
|
|
# F i n a l i z e #
|
|
|
|
# ~#~#~#~#~#~#~#~ #
|
|
|
|
|
|
|
|
if return_code:
|
|
|
|
subprocess.call(["rm -R {0}.ezfio".format(filename)], shell=True)
|
|
|
|
return return_code
|
|
|
|
|
|
|
|
|
|
|
|
def check_mo_guess(geo, basis, mult=1):
|
|
|
|
|
|
|
|
import uuid
|
|
|
|
filename = str(uuid.uuid4())
|
|
|
|
|
|
|
|
# ~#~#~#~ #
|
|
|
|
# I n i t #
|
|
|
|
# ~#~#~#~ #
|
|
|
|
|
|
|
|
init_folder(geo, basis, mult, ezfio_name=filename)
|
|
|
|
ezfio.set_file("{0}.ezfio".format(filename))
|
|
|
|
|
|
|
|
# ~#~#~#~#~#~#~#~#~#~#~#~#~ #
|
|
|
|
# S e t _ p a r a m e t e r #
|
|
|
|
# ~#~#~#~#~#~#~#~#~#~#~#~#~ #
|
|
|
|
|
|
|
|
# Test 1
|
|
|
|
ezfio.hartree_fock_mo_guess_type = "Huckel"
|
|
|
|
cmd = "qp_edit -c {0}.ezfio".format(filename)
|
|
|
|
subprocess.check_call([cmd], shell=True)
|
|
|
|
|
|
|
|
# Test 2
|
|
|
|
ezfio.hartree_fock_mo_guess_type = "IculeGuess"
|
|
|
|
cmd = "qp_edit -c {0}.ezfio".format(filename)
|
|
|
|
|
|
|
|
try:
|
|
|
|
subprocess.check_call([cmd], shell=True)
|
|
|
|
return_code = False
|
|
|
|
except subprocess.CalledProcessError:
|
|
|
|
return_code = True
|
|
|
|
|
|
|
|
# ~#~#~#~#~#~#~#~ #
|
|
|
|
# F i n a l i z e #
|
|
|
|
# ~#~#~#~#~#~#~#~ #
|
|
|
|
|
|
|
|
if return_code:
|
|
|
|
subprocess.call(["rm -R {0}.ezfio".format(filename)], shell=True)
|
|
|
|
return return_code
|
|
|
|
|
|
|
|
|
|
|
|
# _
|
|
|
|
# / |_ _ _ | _. | _ _
|
|
|
|
# \_ | | (/_ (_ |< \/ (_| | |_| (/_ _>
|
|
|
|
#
|
2015-05-05 10:28:04 +02:00
|
|
|
def run_hf(geo, basis, mult=1, pseudo=False, remove_after_sucess=True):
|
2015-03-30 10:15:35 +02:00
|
|
|
"""
|
|
|
|
Run a simle by default hf
|
|
|
|
EZFIO path = geo.ezfio
|
|
|
|
"""
|
2015-05-05 10:28:04 +02:00
|
|
|
|
2015-03-30 11:57:42 +02:00
|
|
|
# ~#~#~#~#~#~#~#~#~#~ #
|
|
|
|
# R e f _ e n e r g y #
|
|
|
|
# ~#~#~#~#~#~#~#~#~#~ #
|
2015-03-27 19:03:15 +01:00
|
|
|
|
2015-05-05 10:28:04 +02:00
|
|
|
ref_energy = defaultdict(defaultdict)
|
2015-03-27 19:03:15 +01:00
|
|
|
|
2015-05-05 10:28:04 +02:00
|
|
|
ref_energy["sto-3g"]["methane"] = Energy(-39.7267433402, None)
|
|
|
|
ref_energy["vdz"]["SO2"] = Energy(None, -41.48912297776174)
|
2015-06-03 18:55:29 +02:00
|
|
|
ref_energy["vdz"]["HBO"] = Energy(None, -19.1198254041)
|
2015-03-27 19:03:15 +01:00
|
|
|
|
2015-03-30 11:57:42 +02:00
|
|
|
# ~#~#~#~#~#~#~#~#~#~#~#~#~#~#~ #
|
|
|
|
# G l o b a l _ v a r i a b l e #
|
|
|
|
# ~#~#~#~#~#~#~#~#~#~#~#~#~#~#~ #
|
2015-03-27 19:03:15 +01:00
|
|
|
|
2015-03-30 11:57:42 +02:00
|
|
|
global has_hf_alredy
|
|
|
|
has_hf_alredy = True
|
|
|
|
|
|
|
|
# ~#~#~#~ #
|
|
|
|
# I n i t #
|
|
|
|
# ~#~#~#~ #
|
|
|
|
|
2015-05-05 10:28:04 +02:00
|
|
|
init_folder(geo, basis, mult, pseudo)
|
2015-03-30 11:47:56 +02:00
|
|
|
ezfio.set_file("{0}.ezfio".format(geo))
|
2015-03-30 11:57:42 +02:00
|
|
|
|
|
|
|
# ~#~#~#~#~#~#~#~#~#~#~#~#~ #
|
|
|
|
# S e t _ p a r a m e t e r #
|
|
|
|
# ~#~#~#~#~#~#~#~#~#~#~#~#~ #
|
2015-03-31 09:58:25 +02:00
|
|
|
ezfio.bielec_integrals_direct = False
|
|
|
|
ezfio.bielec_integrals_threshold_ao = 1.e-15
|
2015-04-01 12:02:02 +02:00
|
|
|
ezfio.bielec_integrals_disk_access_ao_integrals = "None"
|
2015-03-31 09:58:25 +02:00
|
|
|
|
|
|
|
ezfio.bielec_integrals_threshold_mo = 1.e-15
|
2015-04-01 12:02:02 +02:00
|
|
|
ezfio.bielec_integrals_disk_access_mo_integrals = "None"
|
2015-03-30 11:57:42 +02:00
|
|
|
|
|
|
|
ezfio.hartree_fock_mo_guess_type = "Huckel"
|
|
|
|
ezfio.hartree_fock_thresh_scf = 1.e-10
|
|
|
|
ezfio.hartree_fock_n_it_scf_max = 100
|
|
|
|
|
2015-05-11 19:41:56 +02:00
|
|
|
ezfio.pseudo_do_pseudo = pseudo
|
2015-05-02 13:29:57 +02:00
|
|
|
|
2015-03-30 11:57:42 +02:00
|
|
|
# ~#~#~ #
|
|
|
|
# R u n #
|
|
|
|
# ~#~#~ #
|
2015-03-30 11:47:56 +02:00
|
|
|
|
2015-03-30 10:15:35 +02:00
|
|
|
cmd = "qp_run SCF {0}.ezfio/".format(geo)
|
2015-03-27 19:03:15 +01:00
|
|
|
subprocess.check_call([cmd], shell=True)
|
|
|
|
|
2015-03-30 11:57:42 +02:00
|
|
|
# ~#~#~#~#~ #
|
|
|
|
# C h e c k #
|
|
|
|
# ~#~#~#~#~ #
|
|
|
|
|
2015-03-27 19:03:15 +01:00
|
|
|
cur_e = ezfio.get_hartree_fock_energy()
|
2015-05-05 10:28:04 +02:00
|
|
|
|
2015-03-30 10:15:35 +02:00
|
|
|
ref_e = ref_energy[basis][geo]
|
2015-05-05 10:28:04 +02:00
|
|
|
if pseudo:
|
|
|
|
ref_e = ref_e.with_pseudo
|
|
|
|
else:
|
|
|
|
ref_e = ref_e.without_pseudo
|
2015-03-27 19:03:15 +01:00
|
|
|
|
2015-03-30 10:15:35 +02:00
|
|
|
if abs(cur_e - ref_e) <= precision:
|
2015-05-05 10:28:04 +02:00
|
|
|
|
|
|
|
if remove_after_sucess:
|
|
|
|
subprocess.call(["rm -R {0}.ezfio".format(geo)], shell=True)
|
|
|
|
|
2015-03-30 10:15:35 +02:00
|
|
|
return True
|
2015-05-05 10:28:04 +02:00
|
|
|
|
2015-03-30 10:15:35 +02:00
|
|
|
else:
|
|
|
|
raise ValueError(get_error_message([ref_e], [cur_e]))
|
2015-03-27 19:03:15 +01:00
|
|
|
|
|
|
|
|
2015-05-05 10:28:04 +02:00
|
|
|
def run_full_ci_10k_pt2_end(geo, basis, pseudo):
|
2015-03-30 10:15:35 +02:00
|
|
|
"""
|
|
|
|
Run a Full_ci with 10k with the TruePT2
|
|
|
|
EZFIO path = geo.ezfio
|
|
|
|
"""
|
2015-03-27 19:03:15 +01:00
|
|
|
|
2015-03-30 11:57:42 +02:00
|
|
|
# ~#~#~#~#~#~#~#~#~#~ #
|
|
|
|
# R e f _ e n e r g y #
|
|
|
|
# ~#~#~#~#~#~#~#~#~#~ #
|
|
|
|
|
2015-03-27 19:03:15 +01:00
|
|
|
ref_energy_var = defaultdict(dict)
|
|
|
|
ref_energy_pt2 = defaultdict(dict)
|
|
|
|
|
2015-05-12 15:14:54 +02:00
|
|
|
ref_energy_var["sto-3g"]["methane"] = Energy(-39.8058687211, None)
|
|
|
|
ref_energy_pt2["sto-3g"]["methane"] = Energy(-39.8059180427, None)
|
2015-03-27 19:03:15 +01:00
|
|
|
|
2015-03-30 11:57:42 +02:00
|
|
|
# ~#~#~#~ #
|
|
|
|
# I n i t #
|
|
|
|
# ~#~#~#~ #
|
|
|
|
|
2015-03-30 10:15:35 +02:00
|
|
|
ezfio.set_file("{0}.ezfio".format(geo))
|
2015-03-27 19:03:15 +01:00
|
|
|
|
2015-03-30 11:57:42 +02:00
|
|
|
# ~#~#~#~#~#~#~#~#~#~#~#~#~ #
|
|
|
|
# S e t _ p a r a m e t e r #
|
|
|
|
# ~#~#~#~#~#~#~#~#~#~#~#~#~ #
|
|
|
|
|
2015-03-27 19:03:15 +01:00
|
|
|
ezfio.full_ci_do_pt2_end = True
|
|
|
|
ezfio.full_ci_n_det_max_fci = 10000
|
|
|
|
ezfio.full_ci_pt2_max = 1.e-8
|
|
|
|
|
2015-03-30 11:57:42 +02:00
|
|
|
# ~#~#~ #
|
|
|
|
# R u n #
|
|
|
|
# ~#~#~ #
|
|
|
|
|
2015-03-30 10:15:35 +02:00
|
|
|
cmd = "qp_run full_ci {0}.ezfio/".format(geo)
|
2015-03-27 19:03:15 +01:00
|
|
|
subprocess.check_call([cmd], shell=True)
|
|
|
|
|
2015-03-30 11:57:42 +02:00
|
|
|
# ~#~#~#~#~ #
|
|
|
|
# C h e c k #
|
|
|
|
# ~#~#~#~#~ #
|
|
|
|
|
2015-03-27 19:03:15 +01:00
|
|
|
cur_var = ezfio.get_full_ci_energy()
|
|
|
|
cur_pt2 = ezfio.get_full_ci_energy_pt2()
|
|
|
|
|
2015-03-30 10:15:35 +02:00
|
|
|
ref_var = ref_energy_var[basis][geo]
|
|
|
|
ref_pt2 = ref_energy_pt2[basis][geo]
|
2015-03-27 19:03:15 +01:00
|
|
|
|
2015-05-05 10:28:04 +02:00
|
|
|
if pseudo:
|
|
|
|
ref_var = ref_var.with_pseudo
|
|
|
|
ref_pt2 = ref_pt2.with_pseudo
|
|
|
|
else:
|
|
|
|
ref_var = ref_var.without_pseudo
|
|
|
|
ref_pt2 = ref_pt2.without_pseudo
|
|
|
|
|
2015-03-30 10:15:35 +02:00
|
|
|
t = [abs(cur_var - ref_var) <= precision,
|
|
|
|
abs(cur_pt2 - ref_pt2) <= precision]
|
2015-03-27 19:03:15 +01:00
|
|
|
|
2015-03-30 10:15:35 +02:00
|
|
|
if all(t):
|
|
|
|
return True
|
2015-03-27 19:03:15 +01:00
|
|
|
else:
|
2015-03-30 10:15:35 +02:00
|
|
|
raise ValueError(get_error_message([ref_var, ref_pt2],
|
|
|
|
[cur_var, cur_pt2]))
|
|
|
|
|
|
|
|
|
2015-05-05 10:28:04 +02:00
|
|
|
def hf_then_10k_test(geo, basis, mult=1, pseudo=False):
|
|
|
|
|
|
|
|
run_hf(geo, basis, mult, pseudo, remove_after_sucess=False)
|
2015-03-30 10:15:35 +02:00
|
|
|
|
2015-04-01 14:26:42 +02:00
|
|
|
try:
|
2015-05-05 10:28:04 +02:00
|
|
|
run_full_ci_10k_pt2_end(geo, basis, pseudo)
|
2015-04-01 14:26:42 +02:00
|
|
|
except:
|
2015-05-05 10:28:04 +02:00
|
|
|
raise
|
|
|
|
else:
|
|
|
|
return_code = True
|
2015-04-01 14:26:42 +02:00
|
|
|
|
|
|
|
# ~#~#~#~#~#~#~#~ #
|
|
|
|
# F i n a l i z e #
|
|
|
|
# ~#~#~#~#~#~#~#~ #
|
2015-03-27 19:03:15 +01:00
|
|
|
|
2015-04-01 14:26:42 +02:00
|
|
|
if return_code:
|
|
|
|
subprocess.call(["rm -R {0}.ezfio".format(geo)], shell=True)
|
|
|
|
return return_code
|
2015-03-27 19:03:15 +01:00
|
|
|
|
2015-04-01 14:26:42 +02:00
|
|
|
|
2015-04-16 11:34:26 +02:00
|
|
|
# _
|
|
|
|
# / |_ _ _ | _. ._ _ _ ._ _ ._ _|_
|
|
|
|
# \_ | | (/_ (_ |< (_| |_) (_ (_) | | \/ (/_ | |_
|
|
|
|
# | | __
|
|
|
|
def check_convert(path_out):
|
|
|
|
'''
|
|
|
|
Path_out is the out_file
|
|
|
|
'''
|
|
|
|
|
|
|
|
# ~#~#~#~#~#~#~#~#~#~ #
|
|
|
|
# R e f _ e n e r g y #
|
|
|
|
# ~#~#~#~#~#~#~#~#~#~ #
|
|
|
|
|
|
|
|
ref_energy = defaultdict(dict)
|
|
|
|
|
|
|
|
ref_energy["HBO.out"] = -100.0185822589
|
|
|
|
|
|
|
|
# ~#~#~#~#~#~#~#~#~#~#~#~#~ #
|
|
|
|
# S e t _ p a r a m e t e r #
|
|
|
|
# ~#~#~#~#~#~#~#~#~#~#~#~#~ #
|
|
|
|
cmd = "qp_convert_output_to_ezfio.py {0}".format(path_out)
|
|
|
|
subprocess.check_call([cmd], shell=True)
|
|
|
|
|
|
|
|
# Test 2
|
|
|
|
cmd = "qp_edit -c {0}.ezfio".format(path_out)
|
|
|
|
subprocess.check_call([cmd], shell=True)
|
|
|
|
|
|
|
|
cmd = "qp_run SCF {0}.ezfio".format(path_out)
|
|
|
|
subprocess.check_call([cmd], shell=True)
|
|
|
|
|
|
|
|
# ~#~#~#~#~ #
|
|
|
|
# C h e c k #
|
|
|
|
# ~#~#~#~#~ #
|
|
|
|
|
|
|
|
ezfio.set_file("{0}.ezfio".format(path_out))
|
|
|
|
|
|
|
|
cur_e = ezfio.get_hartree_fock_energy()
|
|
|
|
ref_e = ref_energy[path_out]
|
|
|
|
|
|
|
|
if abs(cur_e - ref_e) <= precision:
|
|
|
|
subprocess.call(["rm -R {0}.ezfio".format(path_out)], shell=True)
|
|
|
|
return True
|
|
|
|
else:
|
|
|
|
raise ValueError(get_error_message([ref_e], [cur_e]))
|
|
|
|
|
2015-05-05 10:28:04 +02:00
|
|
|
|
2015-04-01 14:26:42 +02:00
|
|
|
# ___
|
|
|
|
# | _ _ _|_
|
|
|
|
# | (/_ _> |_
|
|
|
|
#
|
|
|
|
class ValueTest(unittest.TestCase):
|
2015-03-27 19:03:15 +01:00
|
|
|
|
2015-05-05 15:41:10 +02:00
|
|
|
def test_hf_then_full_ci_10k_pt2_end(self):
|
|
|
|
self.assertTrue(hf_then_10k_test(geo="methane",
|
|
|
|
basis="sto-3g",
|
|
|
|
mult=1,
|
|
|
|
pseudo=False))
|
2015-05-05 10:28:04 +02:00
|
|
|
|
|
|
|
def test_hf(self):
|
2015-05-05 10:33:22 +02:00
|
|
|
self.assertTrue(run_hf(geo="HBO",
|
2015-05-05 10:28:04 +02:00
|
|
|
basis="vdz",
|
|
|
|
mult=1,
|
|
|
|
pseudo=True))
|
2015-04-01 14:26:42 +02:00
|
|
|
|
2015-05-05 10:28:04 +02:00
|
|
|
|
2015-05-05 15:41:10 +02:00
|
|
|
class ConvertTest(unittest.TestCase):
|
|
|
|
def test_check_convert_hf_energy(self):
|
|
|
|
self.assertTrue(check_convert("HBO.out"))
|
|
|
|
|
|
|
|
|
|
|
|
class InputTest(unittest.TestCase):
|
|
|
|
|
|
|
|
def test_check_disk_acess(self):
|
|
|
|
self.assertTrue(check_disk_acess(geo="methane",
|
|
|
|
basis="un-ccemd-ref"))
|
|
|
|
|
|
|
|
def test_check_mo_guess(self):
|
|
|
|
self.assertTrue(check_mo_guess(geo="methane",
|
|
|
|
basis="maug-cc-pVDZ"))
|
2015-03-27 19:03:15 +01:00
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
unittest.main()
|