#
eval 'exec perl $0 $*'
if 0;
require Molecule;
##########################################################################
package QCParse;
$debug = 0;
sub testparse {
my $parse = new QCParse;
my $string = "x:
xval
test_basis: STO-3G 6-311G**
charge: 1
method: scf
basis: sto-3g
state: 3b1
molecule:
H 0 0.0000001 1.00000001
H 0 0 -1
gradient: yes
optimize: no
frequencies: yes
properties: NPA
y:
yval
z: zval1 zval2
zval3
h:
0 a
1
2 c";
print "string:\n--------------\n$string\n--------------\n";
$parse->parse_string($string);
$parse->doprint();
my @t = $parse->value_as_array('h');
print "-----------------\n";
for ($i = 0; $i <= $#t; $i++) {
print "$i: $t[$i]\n";
}
print "-----------------\n";
@t = $parse->value_as_lines('h');
print "-----------------\n";
for ($i = 0; $i <= $#t; $i++) {
print "$i: $t[$i]\n";
}
print "-----------------\n";
my $qcinp = new QCInput($parse);
my $test_basis = $parse->value("test_basis");
my @test_basis_a = $parse->value_as_array("test_basis");
my $state = $qcinp->state();
my $mult = $qcinp->mult();
my $method = $qcinp->method();
my $charge = $qcinp->charge();
my $basis = $qcinp->basis();
my $gradient = $qcinp->gradient();
my $frequencies = $qcinp->frequencies();
my $optimize = $qcinp->optimize();
my $natom = $qcinp->n_atom();
foreach $i (@test_basis_a) {
print "test_basis_a: $i\n";
}
print "test_basis = $test_basis\n";
print "state = $state\n";
print "mult = $mult\n";
print "method = $method\n";
print "basis = $basis\n";
print "optimize = $optimize\n";
print "gradient = $gradient\n";
print "frequencies = $frequencies\n";
print "natom = $natom\n";
for ($i = 0; $i < $natom; $i++) {
printf "%s %14.8f %14.8f %14.8f\n", $qcinp->element($i),
$qcinp->position($i,0),
$qcinp->position($i,1),
$qcinp->position($i,2);
}
printf "qcinp errors: %s\n", $qcinp->error();
my $inpwr = new MPQCInputWriter($qcinp);
printf "MPQC input:\n%s", $inpwr->input_string();
}
sub new {
my $this = shift;
my $class = ref($this) || $this;
my $self = {};
bless $self, $class;
$self->initialize();
return $self;
}
sub initialize {
my $self = shift;
$self->{'keyval'} = {};
$self->{'error'} = "";
}
sub parse_file {
my $self = shift;
my $file = shift;
if (! -f "$file") {
$self->{"ok"} = 0;
$self->error("File $file not found.");
return;
}
open(INPUT, "<$file");
my $string = "";
while () {
$string = "$string$_";
}
close(INPUT);
#print "Got file:\n$string\n";
$self->parse_string($string);
$self->{"ok"} = 1;
}
sub write_file {
my $self = shift;
my $file = shift;
my $keyval = $self->{'keyval'};
my @keys = keys(%$keyval);
open(OUTPUT, ">$file");
foreach $key (@keys) {
my $value = $keyval->{$key};
print OUTPUT "${key}:\n";
print OUTPUT "$value\n";
}
close(OUTPUT);
}
sub parse_string {
my $self = shift;
my $string = shift;
my $value = "";
my $keyword = "";
$string = "$string\n";
while ($string) {
$string =~ s/^[^\n]*\n//;
$_ = $&;
s/#.*//;
if (/^\s*(\w+)\s*:\s*(.*)\s*$/) {
$self->add($keyword, $value);
$keyword = $1;
$value = $2;
}
elsif (/^\s*$/) {
$self->add($keyword, $value);
$keyword = "";
$value = "";
}
else {
$value = "$value$_";
}
}
$self->add($keyword, $value);
}
sub add {
my $self = shift;
my $keyword = shift;
my $value = shift;
if ($keyword ne "") {
$self->{'keyval'}{$keyword} = $value;
printf("%s = %s\n", $keyword, $value) if ($debug);
}
}
# returns the value of the keyword
sub value {
my $self = shift;
my $keyword = shift;
my $keyval = $self->{'keyval'};
my $value = $keyval->{$keyword};
return $value;
}
# sets the value of the keyword
sub set_value {
my $self = shift;
my $keyword = shift;
my $value = shift;
my $keyval = $self->{'keyval'};
$keyval->{$keyword} = $value;
return $value;
}
# returns the value of the keyword
sub boolean_value {
my $self = shift;
my $keyword = shift;
my $keyval = $self->{'keyval'};
$_ = $keyval->{$keyword};
return "1" if (/^\s*(y|yes|1|true|t)\s*$/i);
return "0" if (/^\s*(n|no|0|false|f|)\s*$/i);
"";
}
# returns an array of whitespace delimited tokens
sub value_as_array {
my $self = shift;
my $keyword = shift;
my $keyval = $self->{'keyval'};
my $value = $keyval->{$keyword};
my @array = ();
$i = 0;
$value =~ s/^\s+$//;
while ($value ne '') {
$value =~ s/^\s*(\S+)\s*//s;
$array[$i] = $1;
$i++;
}
return @array;
}
# returns an array reference of whitespace delimited tokens
sub value_as_arrayref {
my $self = shift;
my $keyword = shift;
my $keyval = $self->{'keyval'};
my $value = $keyval->{$keyword};
my $array = [];
$i = 0;
$value =~ s/^\s+$//;
while ($value ne '') {
$value =~ s/^\s*(\S+)\s*//s;
$array->[$i] = $1;
$i++;
}
return $array;
}
# returns an array of lines
sub value_as_lines {
my $self = shift;
my $keyword = shift;
my $keyval = $self->{'keyval'};
my $value = $keyval->{$keyword};
my @array = ();
$i = 0;
while ($value) {
$value =~ s/^\s*(.*)\s*\n//;
$array[$i] = $1;
$i++;
}
return @array;
}
# returns 1 if the input file existed
sub ok {
my $self = shift;
$self->{"ok"};
}
sub display {
my $self = shift;
my @keys = @_ ? @_ : sort keys %$self;
foreach $key (@keys) {
print "\t$key => $self->{$key}\n";
}
}
sub doprint {
my $self = shift;
print "QCParse:\n";
my $keyval = $self->{'keyval'};
foreach $i (keys %$keyval) {
my $val = $keyval->{$i};
$val =~ s/\n/\\n/g;
print "keyword = $i, value = $val\n";
}
}
sub error {
my $self = shift;
my $msg = shift;
$self->{"error"} = "$self->{'error'}$msg";
}
##########################################################################
package QCInput;
$debug = 0;
sub new {
my $this = shift;
my $class = ref($this) || $this;
my $self = {};
bless $self, $class;
$self->initialize(@_);
return $self;
}
sub initialize {
my $self = shift;
my $parser = shift;
if ($parser eq "") {
$parser = new QCParse;
}
$self->{"parser"} = $parser;
$self->{"error"} = $parser->error();
$self->{"molecule"} = new Molecule($parser->value("molecule"));
}
sub error {
my $self = shift;
my $msg = shift;
$self->{"error"} = "$self->{'error'}$msg";
}
sub checkpoint {
my $self = shift;
my $bval = $self->{"parser"}->boolean_value("checkpoint");
my $val = $self->{"parser"}->value("checkpoint");
if ($val ne "" && $bval eq "") {
$self->error("Bad value for checkpoint: $val");
$bval = "0";
}
elsif ($val eq "") {
$bval = "1";
}
$bval;
}
sub restart {
my $self = shift;
my $bval = $self->{"parser"}->boolean_value("restart");
my $val = $self->{"parser"}->value("restart");
if ($val ne "" && $bval eq "") {
$self->error("Bad value for restart: $val");
$bval = "0";
}
elsif ($val eq "") {
$bval = "1";
}
$bval;
}
sub label {
my $self = shift;
$self->{"parser"}->value("label");
}
sub charge {
my $self = shift;
$_ = $self->{"parser"}->value("charge");
s/^\s+//;
s/\s+$//;
s/^\+//;
if (/^$/) { $_ = "0"; }
if (! /^-?\d+$/) {
$self->error("Bad charge: $_ (using 0)\n");
$_ = "0";
}
$_;
}
sub method {
my $self = shift;
$_ = $self->{"parser"}->value("method");
s/^\s+//;
s/\s+$//;
if ($_ eq "") {
$self->error("No method given (using default).\n");
$_ = "SCF";
}
tr/a-z/A-Z/;
$_;
}
sub symmetry {
my $self = shift;
$_ = $self->{"parser"}->value("symmetry");
s/^\s*//;
s/\s*$//;
uc $_;
}
sub memory {
my $self = shift;
$_ = $self->{"parser"}->value("memory");
s/^\s*//;
s/\s*$//;
if ($_ eq "") {
$_ = 32000000;
}
$_;
}
sub state {
my $self = shift;
$_ = $self->{"parser"}->value("state");
s/^\s*//;
s/\s*$//;
uc $_;
}
sub mult {
my $self = shift;
$_ = $self->state();
s/^\s*(\d+)/\1/;
if (/^\s*$/) {
$_ = 1;
}
$_;
}
sub basis {
my $self = shift;
$_ = $self->{"parser"}->value("basis");
s/^\s+//;
s/\s+$//;
if ($_ eq "") {
$self->error("No basis given (using default).\n");
$_ = "STO-3G";
}
$_;
}
sub auxbasis {
my $self = shift;
$_ = $self->{"parser"}->value("auxbasis");
s/^\s+//;
s/\s+$//;
if ($_ eq "") {
$self->error("No auxiliary basis given (using default).\n");
$_ = "STO-3G";
}
$_;
}
sub grid {
my $self = shift;
$_ = $self->{"parser"}->value("grid");
s/^\s+//;
s/\s+$//;
if ($_ eq "") {
$_ = "default";
}
$_;
}
sub gradient {
my $self = shift;
my $bval = $self->{"parser"}->boolean_value("gradient");
if ($bval eq "") {
my $val = $self->{"parser"}->value("gradient");
$self->error("Bad value for gradient: $val");
}
$bval;
}
sub fzc {
my $self = shift;
$_ = $self->{"parser"}->value("fzc");
s/^\s+//;
s/\s+$//;
if ($_ eq "") {
$_ = 0;
}
$_;
}
sub fzv {
my $self = shift;
$_ = $self->{"parser"}->value("fzv");
s/^\s+//;
s/\s+$//;
if ($_ eq "") {
$_ = 0;
}
$_;
}
sub docc {
my $self = shift;
$_ = $self->{"parser"}->value("docc");
s/^\s+//;
s/\s+$//;
if ($_ eq "" || $_ eq "-") {
$_ = "auto";
}
$_;
}
sub socc {
my $self = shift;
$_ = $self->{"parser"}->value("socc");
s/^\s+//;
s/\s+$//;
if ($_ eq "" || $_ eq "-") {
$_ = "auto";
}
$_;
}
sub optimize {
my $self = shift;
my $bval = $self->{"parser"}->boolean_value("optimize");
if ($bval eq "") {
my $val = $self->{"parser"}->value("optimize");
$self->error("Bad value for optimize: $val");
}
$bval;
}
# returns "" if orthog_method not set
sub orthog_method {
my $self = shift;
my $bval = $self->{"parser"}->value("orthog_method");
$bval;
}
# returns "" if lindep_tol not set
sub lindep_tol {
my $self = shift;
my $bval = $self->{"parser"}->value("lindep_tol");
$bval;
}
sub transition_state {
my $self = shift;
my $bval = $self->{"parser"}->boolean_value("transition_state");
if ($bval eq "") {
my $val = $self->{"parser"}->value("transition_state");
$self->error("Bad value for transtion_state: $val");
}
$bval;
}
sub frequencies {
my $self = shift;
my $bval = $self->{"parser"}->boolean_value("frequencies");
if ($bval eq "") {
my $val = $self->{"parser"}->value("frequencies");
$self->error("Bad value for frequencies: $val");
}
$bval;
}
sub axyz_lines {
my $self = shift;
$self->molecule()->string();
}
sub molecule() {
my $self = shift;
return $self->{"molecule"};
}
sub n_atom {
my $self = shift;
printf "QCInput: returning natom = %d\n", $self->{"natom"} if ($debug);
$self->molecule()->n_atom();
}
sub element {
my $self = shift;
$self->molecule()->element(@_);
}
sub position {
my $self = shift;
$self->molecule()->position(@_);
}
sub write_file {
my $self = shift;
my $file = shift;
my $parser = $self->{'parser'};
$parser->write_file($file);
}
sub mode_following() {
my $self = shift;
return scalar($self->{"parser"}->value_as_array("followed")) != 0;
}
# returns 1 if the input file existed
sub ok {
my $self = shift;
$self->{"parser"}->{"ok"};
}
##########################################################################
package InputWriter;
# Input Writer is abstract
sub new {
my $this = shift;
my $class = ref($this) || $this;
my $self = {};
bless $self, $class;
$self->initialize(@_);
return $self;
}
sub initialize() {
my $self = shift;
my $qcinput = shift;
$self->{"qcinput"} = $qcinput;
}
# this should be overridden
sub input_string() {
"";
}
sub write_input() {
my $self = shift;
my $file = shift;
my $input = $self->input_string();
open(OUTPUT,">$file");
printf OUTPUT "%s", $input;
close(OUTPUT);
}
sub write_qcinput {
my $self = shift;
my $file = shift;
my $qcinput = $self->{'qcinput'};
$qcinput->write_file($file);
}
##########################################################################
package MPQCInputWriter;
@ISA = qw( InputWriter );
%methodmap = ("MP2-R12/A" => "MBPT2_R12",
"MP2-R12/A'" => "MBPT2_R12",
"MP2" => "MBPT2",
"OPT1[2]" => "MBPT2",
"OPT2[2]" => "MBPT2",
"ZAPT2" => "MBPT2",
"MP2V1" => "MBPT2",
"OPT1[2]V1" => "MBPT2",
"OPT2[2]V1" => "MBPT2",
"ZAPT2V1" => "MBPT2",
"MP2V2" => "MBPT2",
"OPT1[2]V2" => "MBPT2",
"OPT2[2]V2" => "MBPT2",
"ZAPT2V2" => "MBPT2",
"MP2V2LB" => "MBPT2",
"OPT1[2]V2LB" => "MBPT2",
"OPT2[2]V2LB" => "MBPT2",
"ZAPT2V2LB" => "MBPT2",
"ROSCF" => "SCF",
"SCF" => "SCF",
"UHF" => "UHF",
"CLHF" => "CLHF",
"HSOSHF" => "HSOSHF",
"HF" => "SCF",
"HFK" => "DFT",
"XALPHA" => "DFT",
"HFS" => "DFT",
"HFB" => "DFT",
"HFG96" => "DFT",
"BLYP" => "DFT",
"B3LYP" => "DFT",
"KMLYP" => "DFT",
"B3PW91" => "DFT",
"PBE" => "DFT",
"PW91" => "DFT",
"SPZ81" => "DFT",
"B3P86" => "DFT",
"BP86" => "DFT",
"BPW91" => "DFT",
"CLHFK" => "DFT",
"CLXALPHA" => "DFT",
"CLHFS" => "DFT",
"CLHFB" => "DFT",
"CLHFG96" => "DFT",
"CLBLYP" => "DFT",
"CLB3LYP" => "DFT",
"CLKMLYP" => "DFT",
"CLB3PW91" => "DFT",
"CLPBE" => "DFT",
"CLPW91" => "DFT",
"SPZ81" => "DFT",
"B3P86" => "DFT",
"BP86" => "DFT",
"BPW91" => "DFT",
"HSOSHFK" => "DFT",
"HSOSXALPHA" => "DFT",
"HSOSHFS" => "DFT",
"HSOSHFB" => "DFT",
"HSOSHFG96" => "DFT",
"HSOSBLYP" => "DFT",
"HSOSB3LYP" => "DFT",
"HSOSKMLYP" => "DFT",
"HSOSB3PW91" => "DFT",
"HSOSPBE" => "DFT",
"HSOSPW91" => "DFT",
"HSOSSPZ81" => "DFT",
"HSOSB3P86" => "DFT",
"HSOSBP86" => "DFT",
"HSOSBPW91" => "DFT",
"UHFK" => "DFT",
"UXALPHA" => "DFT",
"UHFS" => "DFT",
"UHFB" => "DFT",
"UHFG96" => "DFT",
"UBLYP" => "DFT",
"UB3LYP" => "DFT",
"UKMLYP" => "DFT",
"UB3PW91" => "DFT",
"UPBE" => "DFT",
"UPW91" => "DFT",
"USPZ81" => "DFT",
"UB3P86" => "DFT",
"UBP86" => "DFT",
"UBPW91" => "DFT",
);
%mbpt2r12stdapproxmap = ("MP2-R12/A" => "A",
"MP2-R12/A'" => "A'",
);
%mbpt2map = ("MP2" => "mp",
"OPT1[2]" => "opt1",
"OPT2[2]" => "opt2",
"ZAPT2" => "zapt",
"MP2V1" => "mp",
"OPT1[2]V1" => "opt1",
"OPT2[2]V1" => "opt2",
"ZAPT2V1" => "zapt",
"MP2V2" => "mp",
"OPT1[2]V2" => "opt1",
"OPT2[2]V2" => "opt2",
"ZAPT2V2" => "zapt",
"MP2V2LB" => "mp",
"OPT1[2]V2LB" => "opt1",
"OPT2[2]V2LB" => "opt2",
"ZAPT2V2LB" => "zapt");
%mbpt2algmap = ("MP2" => "",
"OPT1[2]" => "",
"OPT2[2]" => "",
"ZAPT2" => "",
"MP2V1" => "v1",
"OPT1[2]V1" => "v1",
"OPT2[2]V1" => "v1",
"ZAPT2V1" => "v1",
"MP2V2" => "v2",
"OPT1[2]V2" => "v2",
"OPT2[2]V2" => "v2",
"ZAPT2V2" => "v2",
"MP2V2LB" => "v2lb",
"OPT1[2]V2LB" => "v2lb",
"OPT2[2]V2LB" => "v2lb",
"ZAPT2V2LB" => "v2lb");
$debug = 0;
sub new {
my $this = shift;
my $class = ref($this) || $this;
my $self = {};
bless $self, $class;
$self->initialize(@_);
return $self;
}
sub initialize() {
my $self = shift;
my $qcinput = shift;
$self->{"qcinput"} = $qcinput;
}
sub docc_string() {
my $self = shift;
my $qcinput = $self->{"qcinput"};
my $occs = $qcinput->docc();
if ($occs eq "auto") { return ""; }
$occs =~ s/,/ /g;
"docc = [ $occs ]";
}
sub socc_string() {
my $self = shift;
my $qcinput = $self->{"qcinput"};
my $occs = $qcinput->socc();
if ($occs eq "auto") { return ""; }
$occs =~ s/,/ /g;
"socc = [ $occs ]";
}
sub input_string() {
my $self = shift;
my $qcinput = $self->{"qcinput"};
my $qcparse = $qcinput->{"parser"};
my $use_cints = 0;
my $do_cca = $qcparse->value("do_cca");
printf "molecule = %s\n", $qcparse->value("molecule") if ($debug);
my $symmetry = $qcinput->symmetry();
my $mol = "% molecule specification";
$mol = "$mol\nmolecule: (";
$symmetry = lc $symmetry if ($symmetry eq "AUTO");
if ($qcinput->frequencies()) {
$mol = "$mol\n symmetry = C1";
}
else {
$mol = "$mol\n symmetry = $symmetry";
}
$mol = "$mol\n unit = angstrom";
$mol = "$mol\n { atoms geometry } = {";
printf "MPQCInputWriter: natom = %d\n", $qcinput->n_atom() if ($debug);
my $i;
for ($i = 0; $i < $qcinput->n_atom(); $i++) {
$mol = sprintf "%s\n %2s [ %18.12f %18.12f %18.12f ]",
$mol, $qcinput->element($i),
$qcinput->position($i,0),
$qcinput->position($i,1),
$qcinput->position($i,2);
}
$mol = "$mol\n }";
$mol = "$mol\n)\n";
my $basis = "% basis set specification";
$basis = "$basis\nbasis: (";
$basis = sprintf "%s\n name = \"%s\"", $basis, $qcinput->basis();
$basis = "$basis\n molecule = \$:molecule";
$basis = "$basis\n)\n";
my $integrals = "";
if($do_cca) {
$integrals = "% using cca integrals";
$integrals = "$integrals\nintegrals: (";
my $buffer_type = $qcparse->value("integral_buffer");
if( $buffer_type ne "opaque" && $buffer_type ne "array" ) {
$buffer_type = "opaque";
}
my $int_package = $qcparse->value("integral_package");
if( $int_package ne "intv3" && $int_package ne "cints" ) {
$int_package = "intv3";
}
$integrals = "$integrals\n integral_buffer = $buffer_type";
$integrals = "$integrals\n integral_package = $int_package";
$integrals = "$integrals\n evaluator_factory = MPQC.IntegralEvaluatorFactory";
$integrals = "$integrals\n molecule = \$:molecule";
$integrals = "$integrals\n)\n";
}
my $fixed = $qcparse->value_as_arrayref("fixed");
my $followed = $qcparse->value_as_arrayref("followed");
if (scalar(@{$fixed}) != 0) {
$fixed = $self->mpqc_fixed_coor($fixed);
}
else {
$fixed = "";
}
if (scalar(@{$followed}) != 0) {
$followed = $self->mpqc_followed_coor($followed);
}
else {
$followed = "";
}
my $coor = " % molecular coordinates for optimization";
$coor = "$coor\n coor: (";
$coor = "$coor\n molecule = \$:molecule";
$coor = "$coor\n generator: (";
$coor = "$coor\n molecule = \$:molecule";
$coor = "$coor\n )";
$coor = "$coor$followed";
$coor = "$coor$fixed";
$coor = "$coor\n )\n";
my $charge = $qcinput->charge();
my $mult = $qcinput->mult();
my $docc = $self->docc_string();
my $socc = $self->socc_string();
my $grid = $qcinput->grid();
my $memory = $qcinput->memory();
my $inputmethod = $methodmap{uc($qcinput->method())};
my $method = "$inputmethod";
$method = "SCF" if ($method eq "");
my $openmethod = substr(uc($qcinput->method()),0,4);
if (substr($openmethod,0,2) eq "CL") { $openmethod = "CL"; }
if (substr($openmethod,0,1) eq "U") { $openmethod = "U"; }
if ($method eq "SCF") {
if ($openmethod eq "U") {
$method = "UHF";
}
elsif ($openmethod eq "CL") {
$method = "CLHF";
}
elsif ($openmethod eq "HSOS") {
$method = "HSOSHF";
}
elsif ($qcinput->mult() == 1) {
$method = "CLHF";
$openmethod = "CL";
}
else {
$method = "HSOSHF";
$openmethod = "HSOS";
}
}
my $functional;
if ($method eq "DFT") {
$functional = uc($qcinput->method());
if ($openmethod eq "U") {
$method = "UKS";
$functional = substr($functional,1);
}
elsif ($openmethod eq "CL") {
$method = "CLKS";
$functional = substr($functional,2);
}
elsif ($openmethod eq "HSOS") {
$method = "HSOSKS";
$functional = substr($functional,4);
}
elsif ($qcinput->mult() == 1) {
$method = "CLKS";
$openmethod = "CL";
}
else {
$method = "UKS";
$openmethod = "U";
}
}
my $orthog_method = $qcinput->orthog_method();
my $lindep_tol = $qcinput->lindep_tol();
my $mole = " do_energy = yes";
if ($qcinput->gradient()) {
$mole = "$mole\n do_gradient = yes";
}
else {
$mole = "$mole\n do_gradient = no";
}
if($do_cca) {
$mole = "$mole\n do_cca = yes";
}
$mole = "$mole\n % method for computing the molecule's energy";
$mole = "$mole\n mole<$method>: (";
$mole = "$mole\n molecule = \$:molecule";
$mole = "$mole\n basis = \$:basis";
$mole = "$mole\n coor = \$..:coor";
$mole = "$mole\n memory = $memory";
if($do_cca) {
$mole = "$mole\n integrals = \$:integrals";
}
if ($inputmethod eq "SCF" || $inputmethod eq "UHF"
|| $method eq "CLKS" || $method eq "UKS" || $method eq "HSOSKS") {
$mole = "$mole\n total_charge = $charge";
$mole = "$mole\n multiplicity = $mult";
$mole = "$mole\n print_npa = yes";
if ($docc ne "") {$mole = "$mole\n $docc";}
if ($socc ne "") {$mole = "$mole\n $socc";}
if ($orthog_method ne "" ) {
$mole = "$mole\n orthog_method = $orthog_method";
}
if ($lindep_tol ne "" ) {
$mole = "$mole\n lindep_tol = $lindep_tol";
}
}
if ($method eq "CLKS" || $method eq "UKS" || $method eq "HSOSKS") {
$mole = "$mole\n functional: name = \"$functional\"";
}
if (($method eq "CLKS" || $method eq "UKS" || $method eq "HSOSKS")
&& $grid ne "default") {
$mole = "$mole\n integrator: (grid = $grid)";
}
if ($method eq "MBPT2_R12") {
my $stdapprox = $mbpt2r12stdapproxmap{uc($qcinput->method())};
my $auxbasis = $qcinput->auxbasis();
my $fzc = $qcinput->fzc();
$mole = sprintf "%s\n stdapprox = \"%s\"", $mole, $stdapprox;
$mole = "$mole\n integrals: ()";
$mole = "$mole\n nfzc = $fzc";
# don't write an auxbasis if the auxbasis is the same as the basis set.
# this will speed up the calculation
if ("$auxbasis" ne "" && "$auxbasis" ne $qcinput->basis()) {
$mole = "$mole\n aux_basis: (";
$mole = sprintf "%s\n name = \"%s\"", $mole, $auxbasis;
$mole = "$mole\n molecule = \$:molecule";
$mole = "$mole\n )\n";
}
$mole = append_reference($mole,"CLHF",$charge,$mult,$memory,$orthog_method,
$lindep_tol,$docc,$socc,"DZ (Dunning)");
$use_cints = 1;
}
elsif ($method eq "MBPT2") {
my $fzc = $qcinput->fzc();
my $fzv = $qcinput->fzv();
my $mbpt2method = $mbpt2map{uc($qcinput->method())};
my $mbpt2algorithm = $mbpt2algmap{uc($qcinput->method())};
$mole = "$mole\n method = $mbpt2method";
if ($mbpt2algorithm ne "") {
$mole = "$mole\n algorithm = $mbpt2algorithm";
}
$mole = "$mole\n nfzc = $fzc";
$mole = "$mole\n nfzv = $fzv";
my $refmethod = "";
if ($qcinput->mult() == 1) {
$refmethod = "CLHF";
}
else {
$refmethod = "HSOSHF";
}
$mole = append_reference($mole,$refmethod,$charge,$mult,$memory,$orthog_method,
$lindep_tol,$docc,$socc,"STO-3G");
}
elsif (! ($basis =~ /^STO/
|| $basis =~ /^MI/
|| $basis =~ /^\d-\d1G$/) && ! $do_cca ) {
my $guessmethod = "${openmethod}HF";
$mole = "$mole\n guess_wavefunction<$guessmethod>: (";
$mole = "$mole\n molecule = \$:molecule";
$mole = "$mole\n total_charge = $charge";
$mole = "$mole\n multiplicity = $mult";
if ($docc ne "") {$mole = "$mole\n $docc";}
if ($socc ne "") {$mole = "$mole\n $socc";}
$mole = "$mole\n basis: (";
$mole = "$mole\n molecule = \$:molecule";
$mole = "$mole\n name = \"STO-3G\"";
$mole = "$mole\n )";
$mole = "$mole\n memory = $memory";
if($do_cca) {
$mole = "$mole\n integrals = \$:integrals";
}
$mole = "$mole\n )";
}
if ($qcinput->frequencies()) {
$mole = "$mole\n hessian: (";
if ($symmetry ne "C1") {
$mole="$mole\n point_group: symmetry = $symmetry";
}
$mole = "$mole\n checkpoint = no";
$mole = "$mole\n restart = no";
$mole = "$mole\n )";
}
$mole = "$mole\n )\n";
my $opt;
if ($qcinput->optimize()) {
$opt = " optimize = yes";
}
else {
$opt = " optimize = no";
}
my $optclass, $updateclass;
if ($qcinput->transition_state()) {
$optclass = "EFCOpt";
$updateclass = "PowellUpdate";
}
else {
$optclass = "QNewtonOpt";
$updateclass = "BFGSUpdate";
}
$opt = "$opt\n % optimizer object for the molecular geometry";
$opt = "$opt\n opt<$optclass>: (";
$opt = "$opt\n max_iterations = 20";
$opt = "$opt\n function = \$..:mole";
if ($qcinput->transition_state()) {
$opt = "$opt\n transition_state = yes";
if ($qcinput->mode_following()) {
$opt = "$opt\n hessian = [ [ -0.1 ] ]";
$opt = "$opt\n mode_following = yes";
}
}
$opt = "$opt\n update<$updateclass>: ()";
$opt = "$opt\n convergence: (";
$opt = "$opt\n cartesian = yes";
$opt = "$opt\n energy = \$..:..:mole";
$opt = "$opt\n )";
$opt = "$opt\n )\n";
my $freq = "";
if ($qcinput->frequencies()) {
$freq = "% vibrational frequency input";
$freq = "$freq\n freq: (";
if ($symmetry ne "C1") {
$freq = "$freq\n point_group: symmetry = $symmetry";
}
$freq = "$freq\n molecule = \$:molecule";
$freq = "$freq\n )\n";
}
my $mpqcstart = sprintf ("mpqc: (\n checkpoint = %s\n",
bool_to_yesno($qcinput->checkpoint()));
$mpqcstart = sprintf ("%s savestate = %s\n",
$mpqcstart,bool_to_yesno($qcinput->checkpoint()));
$mpqcstart = sprintf ("%s restart = %s\n",
$mpqcstart,bool_to_yesno($qcinput->restart()));
if ($use_cints) {
$mpqcstart = "$mpqcstart integrals: ()\n";
}
my $mpqcstop = ")\n";
my $emacs = "% Emacs should use -*- KeyVal -*- mode\n";
my $warn = "% this file was automatically generated\n";
my $lab = $qcinput->label();
my $label = "";
if (! $lab =~ /^\s*$/) {
$label = "% label: $lab";
$label =~ s/\n/\n% label: /g;
$label = "$label\n";
}
"$emacs$warn$label$mol$basis$integrals$mpqcstart$coor$mole$opt$freq$mpqcstop";
}
sub mpqc_fixed_coor {
my $self = shift;
my $coorref = shift;
my $result = "";
$result = "\n fixed: [";
while (scalar(@{$coorref}) != 0) {
my $nextcoor = $self->mpqc_sum_coor(" ","",$coorref);
$result = "$result\n$nextcoor";
}
$result = "$result\n ]";
}
sub mpqc_followed_coor {
my $self = shift;
my $coorref = shift;
sprintf "\n%s", $self->mpqc_sum_coor(" ","followed",$coorref);
}
sub mpqc_sum_coor {
my $self = shift;
my $space = shift;
my $name = shift;
my $coor = shift;
my $result = "$space$name:(";
$result = "$result\n$space coor: [";
my @coef = ();
do {
$coef[$ncoor] = shift @{$coor};
my $simple = $self->mpqc_coor($coor);
$result = "$result\n$space $simple";
$ncoor = $ncoor + 1;
} while($coor->[0] eq "+" && shift @{$coor} eq "+");
$result = "$result\n$space ]";
$result = "$result\n$space coef = [";
my $i;
foreach $i (0..$#coef) {
$result = "$result $coef[$i]";
}
$result = "$result]";
$result = "$result\n$space)";
$result;
}
sub mpqc_coor {
my $self = shift;
my $coor = shift;
my $type = shift @{$coor};
if ($type eq "TORS") {
return sprintf ":(atoms = [%d %d %d %d])",
shift @{$coor},shift @{$coor},
shift @{$coor},shift @{$coor};
}
if ($type eq "BEND") {
return sprintf ":(atoms = [%d %d %d])",
shift @{$coor},shift @{$coor},
shift @{$coor};
}
if ($type eq "STRE") {
return sprintf ":(atoms = [%d %d])",
shift @{$coor},shift @{$coor};
}
}
sub bool_to_yesno {
if (shift) { return "yes"; }
else { return "no"; }
}
sub append_reference {
my $mole = shift;
my $refmethod = shift;
my $charge = shift;
my $mult = shift;
my $memory = shift;
my $orthog_method = shift;
my $lindep_tol = shift;
my $docc = shift;
my $socc = shift;
my $guessbasis = shift;
$mole = "$mole\n reference<$refmethod>: (";
$mole = "$mole\n molecule = \$:molecule";
$mole = "$mole\n basis = \$:basis";
$mole = "$mole\n total_charge = $charge";
$mole = "$mole\n multiplicity = $mult";
$mole = "$mole\n memory = $memory";
if ($orthog_method ne "" ) {
$mole = "$mole\n orthog_method = $orthog_method";
}
if ($lindep_tol ne "" ) {
$mole = "$mole\n lindep_tol = $lindep_tol";
}
if ($docc ne "") {$mole = "$mole\n $docc";}
if ($socc ne "") {$mole = "$mole\n $socc";}
if (! ($basis =~ /^STO/
|| $basis =~ /^MI/
|| $basis =~ /^\d-\d1G$/)) {
$mole = "$mole\n guess_wavefunction<$refmethod>: (";
$mole = "$mole\n molecule = \$:molecule";
$mole = "$mole\n total_charge = $charge";
$mole = "$mole\n multiplicity = $mult";
if ($docc ne "") {$mole = "$mole\n $docc";}
if ($socc ne "") {$mole = "$mole\n $socc";}
$mole = "$mole\n basis: (";
$mole = "$mole\n molecule = \$:molecule";
$mole = "$mole\n name = \"$guessbasis\"";
$mole = "$mole\n )";
$mole = "$mole\n memory = $memory";
$mole = "$mole\n )";
}
$mole = "$mole\n )";
return $mole;
}
1;