some basic files

This commit is contained in:
Adam Parler 2024-01-19 15:38:35 -08:00
parent ad310f6e65
commit ec4e4388fe
31 changed files with 4618 additions and 0 deletions

15
src/basis/GNUmakefile Normal file
View file

@ -0,0 +1,15 @@
HEADERS = bas.h basP.h bas_staticP.h
OBJ = basis.o newbasis.o bas_input.o
LIBRARY = libbasis.a
LIB_TARGETS = testbasis testbasis.o
include ../config/makefile.h
include ../config/makelib.h
testbasis: testbasis.o $(LIBRARY)
$(FC) $(FFLAGS) -o $@ testbasis.o $(LIBS)
basis.o: basP.h geobasmapP.h basdeclsP.h
basP.h: bas_staticP.h
@touch basP.h

38
src/basis/bas.h Normal file
View file

@ -0,0 +1,38 @@
#ifndef _BAS_H
#define _BAS_H
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
void bas_input(FILE *rtdb);
void bas_input_body(int basis, bool osegment);
bool gbs_map_clear(int basisin);
bool bas_create();
bool bas_destroy();
bool bas_check_handle(int basisin, char *msg);
bool bas_321g_load();
bool bas_print();
bool bas_rtdb_load();
bool bas_rtdb_store();
bool bas_high_angular();
bool gbs_map_print();
bool bas_continfo();
bool bas_numcont();
bool bas_numbf();
bool bas_get_exponent();
bool bas_get_coeff();
bool bas_set_exponent();
bool bas_set_coeff();
bool bas_print_all();
bool bas_version();
void bas_add_ucnt(int, char *, int, int, int, double*, double*, int);
#ifdef __cplusplus
}
#endif
#endif // _BAS_H_

194
src/basis/basP.h Normal file
View file

@ -0,0 +1,194 @@
#ifndef _BASP_H
#define _BASP_H
/*
basis set object/api
Rick A. Kendall and Robert J. Harrison (March 1994)
What is the minimum basis set informaton?
What is a basis set? A basis set is a set of tags nominally
associated with an atomic center through a geometry specification
or geometry object. What needs to be stored is the basis set for
the unique tags ("atoms"). The concept of shell and general
contraction confuses the issue somewhat but in the limit of a
segmented basis set the "shell" concept is the same as the
"general contraction." The basis set object and its interaction
with the integral API is predicated upon this assumption.
A pseudo input deck with the minimum information is as follows.
Basis Set: Name (as on the rtdb)
ntags (number of unique tags for which basis set
information is supplied)
nucont (total number of unique contractions in basis)
nprim_t (total number of primitives in basis)
ncoef_t (total number of coeffs in basis)
foreach tag (ntags of them)
tag (character string identifier of tag)
number_of_contractions on tag
nprim_c in contractions on tag
ncoeff in contractions on tag
first contraction of tag
last contraction of tag
foreach contraction (number_of_contractions of them)
itype, nprim, ngen, iexptr, icoeff, tag_cont_is_on
foreach nprim in a contraction
ex(1), coeff(1,...) (ngen contractions)
The tag ("atomic") information pseudo-data structure is as follows:
Integer num_cont ! Number of contractions on tag
Integer nprim_tag ! Number of primitive exponents on tag
Integer ncoeff_tag ! Number of primitive coeffs on tag
Integer ifirst_cont ! first contraction on tag
Integer ilast_cont ! last contraction on tag
Integer itype(num_cont) ! type of contraction 0=s,1=p,2=d...
! later -1=sp,-2=spd etc.
Integer nprim(num_cont) ! number of primitives in each cont. on tag
Integer ngen(num_cont) ! number of general conts in each cont.
! 1= segmented basis, >1 general cont.
Integer iexpt(num_cont) ! pointer into linearized real*8 array for
! first exponent
Integer icoeffpt(num_cont) ! pointer into linearized real*8 array for
! first coefficient
Integer itag(num_cont) ! tag identifier for contraction
! (redundant for just atomic info)
double exndcf[nprim_tag+ncoeff_tag] ! linearized real*8 array of
! exponents and coefficients
The basis set information is the number of tags and the above tag
information.
unique information only!!!!!!!
The basis set information pseudo-data structure is as follows:
char bs_name[256] ! (as "mo basis")
int num_tags ! number of tags in basis
int num_cont_total ! number of conts in basis
int num_prim_total ! number of prims in basis
int num_coeff_total ! number of coefs in basis
char tags[num_tags][16] ! character string of tags
int num_cont[num_tags] ! Num of conts on tag
int nprim_tag[num_tags] ! Num of prim exponents on tag
int ncoeff_tag[num_tags] ! Num of prim coeffs on tag
int itype[num_cont] ! type of contraction 0=s,1=p,2=d...
! later -1=sp,-2=spd etc.
int nprim[num_cont] ! num of prims in each cont. on tag
int ngen[num_cont] ! num of general conts in each cont.
! on each tag
! 1= segmented basis, >1 general cont.
int iexpt[num_cont] ! pointer into linearized real*8 array
! for first exponent of each cont.
! on each tag
int icoeffpt[num_cont] ! pointer into linearized real*8
! array for first coefficient of
! each cont. on each tag
int itag[num_cont] ! tag identifier for contraction
! (redundant for just atomic info)
double exndcf[] ! linearized real*8 array of
! exponents and coefficients
Note: exndcf does not carry the num_cont label because it is a
linearized real*8 array and the added dimensionality is
handled by proper evaluation of the pointer arrays
iexpt and icoeffpt.
The above data structure is too cumbersome to efficiently store to
and read from the run-time-data-base (one call per array). The
integer and real*8 data needs to be linearized with appropriate
informaton accessable by pointers arrays.
The more appropriate "basis" data structure is as follows:
char bs_name[256] ! as "mo basis"
char tags[num_tags][16] ! character string of tags
int infbs_head[4] ! header information
! 1 = num_tags ! num of tags in basis
! 2 = num_cont_total ! num of conts in basis
! 3 = num_prim_total ! num of prims(ex) in basis
! 4 = num_coeff_total ! num of coeffs in basis
int infbs_tags[5][num_tags]
! 1 = num_cont ! Num of conts on tag
! 2 = nprim_tag ! Num of prim exponents on tag
! 3 = ncoeff_tag ! Num of prim coeffs on tag
! 4 = first cont ! first contaction on tag
! 5 = last cont ! last contaction on tag
int infbs_cont[6][num_cont]
! 1 = itype ! type of contraction 0=s,1=p,2=d...
! later -1=sp,-2=spd etc.
! 2 = nprim ! num of prims in each cont. on tag
! 3 = ngen ! num of general conts in each cont.
! on each tag
! 1= segmented basis, >1 general cont.
! 4 = iexpt ! pointer into linearized real*8 array
! for first exponent of each cont.
! on each tag
! 5 = icoeffpt ! pointer into linearized real*8
! array for first coefficient of
! each cont. on each tag
! 6 = itag ! cunique tag number
double exndcf[] ! linearized real*8 array of
! exponents and coefficients
The above data structure now must handle multiple basis sets.
The "multiple basis set" data structure is as follows:
char bs_name[nbasis][256] ! as "mo basis"
char tags[num_tags][nbasis][16] ! character string of tags
int infbs_head[4][nbasis]
! 1 = num_tags ! num of tags in basis
! 2 = num_cont_total ! num of conts in basis
! 3 = num_prim_total ! num of prims(ex) in basis
! 4 = num_coeff_total ! num of coeffs in basis
int infbs_tags[5][num_tags][nbasis]
! 1 = num_cont_tag ! Num of conts on tag
! 2 = nprim_tag ! Num of prim exponents on tag
! 3 = ncoeff_tag ! Num of prim coeffs on tag
! 4 = first cont ! first contraction on tag
! 5 = last cont ! last contraction on tag
int infbs_cont[6][num_cont_total][nbasis]
! 1 = itype ! type of contraction 0=s,1=p,2=d...
! later -1=sp,-2=spd etc.
! 2 = nprim ! num of prims in each cont. on tag
! 3 = ngen ! num of general conts in each cont.
! on each tag
! 1= segmented basis, >1 general cont.
! 4 = iexpt ! pointer into linearized real*8 array
! for first exponent of each cont.
! on each tag
! 5 = icoeffpt ! pointer into linearized real*8
! array for first coefficient of
! each cont. on each tag
! 6 = tag number ! unique center lexical index
double exndcf[][nbasis] ! linearized real*8 array of
! exponents and coefficients
actual names are set to protect name space between the geom and
basis objects
*/
#define BASIS_HANDLE_OFFSET ((0-565))
// static dimension information for common blocks
#include "bas_staticP.h"
// leading dimensions of compressed arrays
#define ndbs_tags 5
#define ndbs_ucont 6
#define ndbs_head 4
// stored structures
char bs_name[nbasis_bsmx][256];
char bs_tags[ntags_bsmx][nbasis_bsmx][16];
double exndcf[mxbs_exndcf][nbasis_bsmx];
int infbs_head[ndbs_head][nbasis_bsmx];
int infbs_tags[ndbs_tags][ntags_bsmx][nbasis_bsmx];
int infbs_cont[ndbs_ucont][nucont_bsmx][nbasis_bsmx];
// in-core structures
double bsversion;
char bs_trans[nbasis_bsmx];
char bs_names_rtdb[nbasis_rtdb_mx][256];
int len_bs_name[nbasis_bsmx];
int len_bs_trans[nbasis_bsmx];
int len_bs_rtdb[nbasis_rtdb_mx];
int nbasis_rtdb;
int angular_bs[nbasis_bsmx];
bool bsactive[nbasis_bsmx];
#endif // _BASP_H

273
src/basis/bas_input.c Normal file
View file

@ -0,0 +1,273 @@
#include <stdio.h>
#include <stdbool.h>
#include "rtdb.h"
#include "context.h"
#include "geom.h"
#include "bas.h"
#include "inp.h"
void bas_input(FILE *rtdb) {
/*
basis [<name>] [library <standard set>] [file <filename>] \
[spherical|cartesian] [segment] [print]
tag library <standard set> [file <filename>]
tag <shell type>
<exponent> <contraction coefficients>
...
end basis
parse the main directive
*/
int nopt = 6;
char opts[6][10] = {"spherical", "cartesian", "segment", "library", "file", "print"};
char test[255], name[255], filename[255], standard[255];
bool status, ospherical, osegment, oprint;
int ind, basis;
for (int i = 0; i < nopt; i++) {
opts[i][9] = '\0';
}
// Check is a basis directive and read in name of the basis
inp_set_field(0);
status = inp_a(test);
if ((!status) || (!inp_compare(false, test, "basis"))) {
goto L10000;
}
// Parse rest of basis directive line
name[0] = '\0';
filename[0] = '\0';
test[0] = '\0';
standard[0] = '\0';
ospherical = false;
osegment = false;
oprint = false;
L10:
if (inp_a(test)) {
if (!inp_match(nopt, false, test, opts, ind)) {
// Not a recognized option ... the name of the basis or an error
if ((name[0] != '\0') || (inp_cur_field() != 2)) {
printf(" bas_input: basis name must be first option\n");
goto L10000;
}
strcpy(name, test);
goto L10;
}
switch (ind) {
case 0: // spherical
ospherical = true;
goto L10;
case 1: // cartesian
ospherical = false;
goto L10;
case 2: // segment
osegment = true;
goto L10;
case 3: // library
if (!inp_a(standard)) {
goto L10000;
}
goto L10;
case 4: // file
if (!inp_a(filename)) {
goto L10000;
}
goto L10;
case 5: // print
oprint = true;
goto L10;
}
}
// Now check reality against input
if (standard[0] != '\0') {
printf(" Standard basis %s\n", standard);
errquit("bas_input: standard basis set not yet", 0);
}
if (ospherical) {
errquit("bas_input: spherical harmonics not yet", 0);
}
// Open a new basis set to receive the new data
if (name[0] == '\0') {
strcpy(name, "mo basis");
}
if (!bas_create(basis, name)) {
errquit("bas_input: failed to create basis", 0);
}
// Here will soon process reading standard basis sets
// Now left with reading in from the input additional specifications
// for basis functions or standard sets on specific tags
bas_input_body(basis, osegment);
// Now have processed the entire basis directive. Print out
// info if desired, write it to the data base, tidy up and go home
if (oprint) {
if (!bas_print(basis)) {
errquit("bas_input: print failed", 0);
}
}
if (!bas_rtdb_store(rtdb, name, basis)) {
errquit("bas_input: failed to store basis", 0);
}
if (!bas_destroy(basis)) {
errquit("bas_input: bas_destroy failed", 0);
}
return;
L10000:
printf(" basis [<name>] [library <standard set>] \\\n");
printf(" [file <filename>] [spherical|cartesian] [segment]\n");
errquit("bas_input: invalid format for basis directive", 0);
}
void bas_input_body(int basis, bool osegment) {
/*
c Read the body of a basis directive that describes the
c tags/exponents/contraction coefficients
c
c
c tag library <standard set> [file <filename>]
c tag <contraction type>
c <exponent> <contraction coefficients>
c ...
c end basis
*/
char tag[16], cont_type[16];
int nltypes = 7, nsptypes = 2, nopts = 2;
int cont_max = 20, prim_max = 20;
double expnt[20], coeff[20][20];
char ltypes[7] = {'s', 'p', 'd', 'f', 'g', 'h', 'i'};
char sptypes[2] = {'sp', 'l'};
int spvalues[2] = {-1, -1};
char opts[2][8] = {"library", "file"};
int spvalues[2] = {-1, -1};
int l_value, ngen, iprim, nprim, i, ind;
// Input a new line
L10:
if (!inp_read()) {
errquit("bas_input_body: premature EOF", 0);
}
// Start parsing current line
L20:
inp_set_field(0);
if (!inp_a(tag)) {
goto L10000;
}
if (inp_compare(false, "end", tag)) {
goto L9000; // End of basis directive
}
if (!inp_a(cont_type)) {
goto L10000;
}
if (inp_match(nltypes, false, cont_type, ltypes, ind)) {
// The contraction is a simple shell
l_value = ind - 1;
} else if (inp_match(nsptypes, false, cont_type, sptypes, ind)) {
// The contraction is an sp-type shell
l_value = spvalues[ind];
} else if (inp_match(nopts, false, cont_type, opts, ind)) {
/*
It is actually an option to input a standard basis
Don't bother parsing this yet
*/
errquit("bas_input_body: no standard basis sets yet", 0);
goto L10; // Process the next input line
} else {
// Only god and the user knows what was intended
goto L10000;
}
// Fall thru to here to read in a set of contraction coefficients
if (!inp_read()) {
goto L10000;
}
ngen = inp_n_field() - 1;
if (ngen < 1) {
goto L10000;
}
if (ngen > cont_max) {
errquit("bas_input_body: too many contractions - increase cont_max", cont_max);
}
for (iprim = 0; iprim < prim_max; iprim++) {
if (!inp_f(expnt[iprim])) {
// If cannot read the first field as an exponent then
// it is the end of this contraction
goto L30;
} else {
if ((inp_n_field() - 1) != ngen) {
printf(" bas_input_body: no. of coefficients?\n");
goto L10000;
}
for (i = 0; i < ngen; i++) {
if (!inp_f(coeff[iprim][i])) {
printf(" bas_input_body: failed reading coefficient\n");
goto L10000;
}
}
if (!inp_read()) {
goto L10000;
}
}
}
errquit("bas_input_body: too many primitives in contraction", prim_max);
L30:
nprim = iprim - 1;
if (nprim <= 0) {
errquit("bas_input_body: no primitives?", nprim);
}
// Now have tag, contraction type, no. of contractions, no. of prims,
// exponents, coeffs. Shove this lot into the basis set.
// bas_add_ucnt -> adds a new general contraction on the specified tag.
// If the tag is not present it will also add that.
if (osegment) {
// Add contractions one-at-a-time to force segmentation
for (i = 0; i < ngen; i++) {
if (!bas_add_ucnt(basis, tag, l_value, 1, nprim, expnt, coeff[0][i], prim_max)) {
errquit("bas_input_body: bas_add_ucnt failed!!", 0);
}
}
} else {
// Add as a single general contraction
if (!bas_add_ucnt(basis, tag, l_value, ngen, nprim, expnt, coeff, prim_max)) {
errquit("bas_input_body: bas_add_ucnt failed!!", 0);
}
}
// Have already read in the next line ... parse it
goto L20;
// Have read in all of the basis set info.
L9000:
return;
L10000:
printf(" basis directive body format is:\n");
printf(" tag library <standard set> [file <filename>]\n");
printf(" tag <contraction type>\n");
printf(" <exponent> <contraction coefficients>\n");
printf(" ... \n");
printf(" end basis\n");
errquit("bas_input_body: format error in the input", 0);
}

14
src/basis/bas_staticP.h Normal file
View file

@ -0,0 +1,14 @@
#ifndef _BAS_STATICP_H
#define _BAS_STATICP_H
// Maximum parameter definitions for static "in-core" data structure
const int nbasis_bsmx = 5;
const int nbasis_rtdb_mx = 10 * nbasis_bsmx;
const int ntags_bsmx = 10;
const int nucont_bsmx = 150;
const int mxbs_exndcf = ((300 + 500) * ntags_bsmx);
const int nat_mx = 1000;
const int ncont_mx = (nucont_bsmx * 4);
#endif // _BAS_STATICP_H

39
src/basis/basdeclsP.h Normal file
View file

@ -0,0 +1,39 @@
#ifndef _BASDECLSP_H
#define _BASDECLSP_H
// declarations for substitution by cpp for compressed array count meanings
// only for capitalized versions
// define HEAD_NTAGS 1
// define HEAD_NCONT 2
// define HEAD_NPRIM 3
// define HEAD_NCOEF 4
// define TAG_NCONT 1
// define TAG_NPRIM 2
// define TAG_NCOEF 3
// define TAG_FCONT 4
// define TAG_LCONT 5
// define CONT_TYPE 1
// define CONT_NPRIM 2
// define CONT_NGEN 3
// define CONT_IEXP 4
// define CONT_ICFP 5
// define CONT_TAG 6
#define HEAD_NTAGS 1
#define HEAD_NCONT 2
#define HEAD_NPRIM 3
#define HEAD_NCOEF 4
#define TAG_NCONT 1
#define TAG_NPRIM 2
#define TAG_NCOEF 3
#define TAG_FCONT 4
#define TAG_LCONT 5
#define CONT_TYPE 1
#define CONT_NPRIM 2
#define CONT_NGEN 3
#define CONT_IEXP 4
#define CONT_ICFP 5
#define CONT_TAG 6
#endif

1410
src/basis/basis.c Normal file

File diff suppressed because it is too large Load diff

138
src/basis/doc/api Normal file
View file

@ -0,0 +1,138 @@
Program main
----------------------
fix rtdb for arrays of characters
----------------------
context management
----------------------
get/set coords,charges,tags,masses,zmat(?),ncenters,
map 'geometry' -> name of geometry
logical geom_load(rtdb, 'geometry', geom)
logical geom_store(rtdb, 'geometry', geom)
ncent = geom_ncenter(geom)
call geom_tag(geom, icent, tag)
call geom_cent_coords(geom, icent, coords)
call geom_cent_charge(geom, icent, charge)
...
call geom_cent_info(geom, icent, tag, coords, charge, mass, ...)
logical geom_zmat_defined()
nvariables = geom_zmat_nvars(geom)
nconstants ....
call geom_cart_get(geom, all info)
call geom_cart_set(geom, all info)
call geom_zmat_get
call geom_zmat_set
print
Also on the DB
- list of known geometry names
----------------------
map 'mo basis' -> name of basis descriptor
----------------------
logical basis_load(name_of_basis_descriptor, geom, basis)
nbasis_func = basis_nfunc(basis)
nbasis_shell = basis_nshell(basis)
natoms / basis_centers =
map atom/center<->shell<->bf
get/set exponents/contraction coeffs
shell info (angular, gcontract, spherical/cart)
highest ang. mom.
print
load/store
On the data-base is
- list of known basis set names
-
----------------------
Cannot tweak geometry or basis between init/term calls
... control
int_initialize(geom, num_basis, basis_array) : generate internal int structures
.................................................................................
# not needed if batmol writes to rtdb properly
int_initialize_tape10 () : generate internal int structures (batmol?)
.................................................................................
int_terminate() : throw away internal int structures
int_print_known_basis()
int_set_eri_timing()
int_report_eri_timings()
int_mem(max1e, maxg, mscratch_1e, mscratch_2e)
int_mem_one(max1e, mscratch_1e)
int_mem_4(maxg, mscratch_2e)
int_mem_3(max3, mscratch_3_2e)
int_mem_2(max2, mscratch_2_2e)
int_mem_3ov(max3ov, mscratch_3ov)
... two electron
. 4 center 2e integrals
eri = <bra_g(ish).bra_g(jsh) | ket_g(ksh).ket_g(lsh)>
int_two_4(bra_basis, ket_basis, ish, jsh, ksh, lsh, lscr,
scr, eri)
lab_two_4(bra_basis, ket_basis, ish, jsh, ksh, lsh, zerotol,
canonicalize, eri, nints, ilab, jlab, klab, llab)
. 3 center 2e integrals
eri = <bra_g(ish).bra_g(jsh) | ket_g(ksh)>
int_two_3 (bra_basis, ket_basis, ish, jsh, ksh, lscr, scr, eri)
lab_two_3 (bra_basis, ket_basis, canonical_bra, canonical_both, ish, jsh, ksh, zerotol,
eri, nints, ilab, jlab, klab)
. 2 center 2e integrals
eri = <bra_g(ish)|ket_g(jsh)>
int_two_2 (bra_basis, ket_basis, ish, jsh, lscr, scr, eri)
lab_two_2 (bra_basis, ket_basis, canonical_both, ish, jsh, zerotol, lscr, scr, eri,
nints, ilab, jlab)
... one electron integrals
int_one_ke_basic (i_basis, j_basis, ish, jsh, lscr, scr, T)
int_one_pe_basic (i_basis, j_basis, ish, jsh, lscr, scr, V)
int_one_ov_basic (i_basis, j_basis, ish, jsh, lscr, scr, S)
int_one_h1_basic (i_basis, j_basis, ish, jsh, lscr, scr, H1)
int_one_all_basic(i_basis, j_basis, ish, jsh, lscr, scr, S, T, V)
lab_one_ke (i_basis, j_basis, ish, jsh, zerotol, ilab, jlab, T, numt)
lab_one_pe (i_basis, j_basis, ish, jsh, zerotol, ilab, jlab, V, numv)
lab_one_ov (i_basis, j_basis, ish, jsh, zerotol, ilab, jlab, S, nums)
lab_one_h1 (i_basis, j_basis, ish, jsh, zerotol, ilab, jlab, H1, numh1)
lab_one_all(i_basis, j_basis, ish, jsh, zerotol, ilab, jlab, S, T, V, numstv)
one_3c_int = <i_g(ish).j_g(jsh).k_g(ksh)>
int_one_3ov(i_basis, j_basis, k_basis, ish, jsh, ksh, lscr,
scr, OV3)
lab_one_3ov(i_basis, j_basis, k_basis, ish, jsh, ksh, zerotol,
OV3, ilab, jlab, klab, numov3)
int_mpole(i_basis, j_basis, Lvalue, ish, jsh, lscr, scr, MPINTS)
lab_mpole(i_basis, j_basis, Lvalue, ish, jsh, MPINTS, ilab, jlab, zerotol)
+ periodic versions (with k vector)
----------------------

149
src/basis/doc/basis.doc Normal file
View file

@ -0,0 +1,149 @@
/* The basis set objects are written in C.
Proposal for basis set objects (rjh/rak)
1) Currently have only general and segmented contractions of
primitive gaussians but other basis sets should be anticipated
2) The whole GTO basis is either cartesian or spherical harmonic
3) Basis functions are associated with atomic tags, not coordinates,
the tags providing the connection to a geometry
4) All basis functions associated with an 'atomic' center will be
numbered consecutively
5) General Basis Set Class:
**** Attributes:
Basis_type: Contracted Gaussian
or pseudo-potentails
or plane wave
or .?.?.?.?.
if (Basis_type.eq.1) (sub class definition)
number_of_tags: number of tags with information to be given/retrieved.
(NOTE: generally equal to the number of centers to be
defined by the geometry object.)
cartesian: is it cartesian or spherical (transformed).
nprim_tot:: total number of primitive gaussians.
ncoeff_tot:: total number of contractraction coeffs
nshell_tot:: total number of shells (in the normal sense).
nbf_tot:: total number of basis functions (in the normal sense).
for each (tag (1 .. number_of_tags) (a.k.a. center))
tag: name of atomic center (o, bond_function, ghost center)
contraction_type: Segmented or General?
(note: basis sets may have mixed segmented and
general contracted centers)
ngen: =1 (segmented) >1 (general).
nshell: number of shells for this tag (in normal sense).
:nGshell: number of generally contracted shells.
(what is the limit?? tradeoff memory vs cpu)
nbf_on_tag: number of basis functions for this tag.
:nbf_cart: number of cartesian basis functions
(note: evaluation most likely always in cartesians)
:nbf_sph: number of spherical basis functions.
nprim: number of primitives in contraction.
for each (contraction set) [general or segmented]
type basis function type = GTO (redundant??)
L angular momentum s,p,d = 0, 1, 2
Ltype =0 use only angular momentum L
=1 implies use of all angular momenta up to L
e.g., sp shells (like gaussian) or
spd shells (Rydberg, bond functions)
num_cnt number of contractions coefs (always=1 for segmented)
nbf number of basis functions in contraction (external view)
:nbf_cart: number of cartesian basis functions in contraction
:nbf_sph: number of spherical basis functions in contraction
nprim number of primitives in contraction set
coef(nprim,num_cnt) contraction coefs
ex(nprim) exponents
proposal: (some of what we need to decide!!)
. above atributes that are :attribute: are to be used only by the api
and integral routines.
. attributes that are atribute:: are derived some how.
other pointer arrays etc can be defined/derived from this information
and the goemetry object and thus are application dependent. There is
no requirement that these pointer arrays match across applications/
modules/libraries. Mappings to the final integral code could be
supplied by the api. The major hash will be to determine what is
defined a priori and what is derived information. e.g., the total
number of basis functions for a basis:<tag> is fixed but for a
molecular or periodic system it is unknown until the geometry object
defines the scope.
else
it ain't been defined yet.
endif
**** Operations: (lean and mean)
query_on: scope_set, number_of_tags, cartesian, nprim_tot, ncoeff_tot, nbf_tot etc.
open:
close:
define: (later not now).
set_scope:
6) For compact and portable representation in the database this is
compacted into five entries.
a) dimension information
b) character information
c) pointer information
d) integer information
e) real information
7) All basis set info is named as if components of a basis module
so all names are of the form
basis:<basis name>:<basis component> ...
8) A data base entry basis:list contains a list of the names
of all basis sets in the database so that it is easy to
examine what is in the database
9) a mixed basis set can be a sum of two basis sets object subclasses??
e.g., planewave + contracted gaussian
pseudo-potential + contracted gaussian.
objects:
basis set --> name --> on rtdb
operations:
----------------------
map 'mo basis' -> name of basis descriptor
----------------------
logical basis_load(name_of_basis_descriptor, geom, basis)
nbasis_func = basis_nfunc(basis)
nbasis_shell = basis_nshell(basis)
natoms / basis_centers =
map atom/center<->shell<->bf
get/set exponents/contraction coeffs
shell info (angular, gcontract, spherical/cart)
highest ang. mom.
print
load/store
On the data-base is
- list of known basis set names
-
*/

139
src/basis/doc/basis.output Executable file
View file

@ -0,0 +1,139 @@
SI 0
S 20 1.00
3948000.00000000 0.00000204
591100.00000000 0.00001584
134500.00000000 0.00008336
38120.00000000 0.00035136
12460.00000000 0.00127660
4504.00000000 0.00415191
1758.00000000 0.01230300
729.10000000 0.03331020
318.00000000 0.08098450
144.60000000 0.17029000
67.97000000 0.28687900
32.82000000 0.33034000
16.03000000 0.19660200
7.39600000 0.03545350
3.66100000 -0.00053520
1.82300000 0.00161465
0.91470000 -0.00037274
0.33930000 0.00014623
0.15000000 -0.00007894
0.06438000 0.00001928
S 20 1.00
3948000.00000000 -0.00000054
591100.00000000 -0.00000422
134500.00000000 -0.00002218
38120.00000000 -0.00009360
12460.00000000 -0.00034012
4504.00000000 -0.00111061
1758.00000000 -0.00330878
729.10000000 -0.00911602
318.00000000 -0.02287900
144.60000000 -0.05171190
67.97000000 -0.09990910
32.82000000 -0.15274700
16.03000000 -0.12750800
7.39600000 0.09469630
3.66100000 0.41403600
1.82300000 0.46793400
0.91470000 0.17392700
0.33930000 0.00843895
0.15000000 -0.00099807
0.06438000 0.00036210
S 20 1.00
3948000.00000000 0.00000014
591100.00000000 0.00000108
134500.00000000 0.00000569
38120.00000000 0.00002395
12460.00000000 0.00008724
4504.00000000 0.00028416
1758.00000000 0.00084984
729.10000000 0.00233527
318.00000000 0.00590466
144.60000000 0.01334610
67.97000000 0.02628890
32.82000000 0.04074260
16.03000000 0.03614760
7.39600000 -0.03039230
3.66100000 -0.13596100
1.82300000 -0.25014400
0.91470000 -0.15805000
0.33930000 0.36965500
0.15000000 0.61771800
0.06438000 0.22251400
S 1 1.00
0.91470000 1.00000000
S 1 1.00
0.33930000 1.00000000
S 1 1.00
0.15000000 1.00000000
S 1 1.00
0.06438000 1.00000000
P 12 1.00
1780.00000000 0.00020121
421.80000000 0.00174937
136.70000000 0.00948141
51.81000000 0.03723130
21.60000000 0.11076300
9.56300000 0.23793300
4.35000000 0.35369100
2.00600000 0.32883900
0.92050000 0.13237300
0.35000000 0.01033000
0.13810000 -0.00015031
0.05338000 0.00026581
P 12 1.00
1780.00000000 -0.00004272
421.80000000 -0.00037704
136.70000000 -0.00202240
51.81000000 -0.00812833
21.60000000 -0.02422720
9.56300000 -0.05438250
4.35000000 -0.07990510
2.00600000 -0.08889580
0.92050000 0.01839970
0.35000000 0.33509600
0.13810000 0.53228800
0.05338000 0.25437400
P 1 1.00
0.92050000 1.00000000
P 1 1.00
0.35000000 1.00000000
P 1 1.00
0.13810000 1.00000000
P 1 1.00
0.05338000 1.00000000
D 1 1.00
0.12600000 1.00000000
D 1 1.00
0.32100000 1.00000000
D 1 1.00
0.81700000 1.00000000
D 1 1.00
2.08200000 1.00000000
F 1 1.00
0.16900000 1.00000000
F 1 1.00
0.34100000 1.00000000
F 1 1.00
0.68800000 1.00000000
G 1 1.00
0.32000000 1.00000000
G 1 1.00
0.70500000 1.00000000
H 1 1.00
0.58300000 1.00000000
S 1 1.00
0.02600000 1.00000000
P 1 1.00
0.01920000 1.00000000
D 1 1.00
0.04680000 1.00000000
F 1 1.00
0.07350000 1.00000000
G 1 1.00
0.15100000 1.00000000
H 1 1.00
0.32300000 1.00000000
****

218
src/basis/doc/robert.doc Normal file
View file

@ -0,0 +1,218 @@
1) Minimize implementation effort
2) Simplify data structures so that are flattened
more readily
3) Enable local integral routines to work directly
from API interface and/or internal data structures
4) Store info in the database to avoid having a
zillion small files floating around
In the database we store just the basis set description
(i.e., the atomic basis sets for the unique atom tags)
in as simple a format as possible
In core, we have in addition mapping arrays that build
the basis set from the geometry and the basis set description
How to store the atomic basis set compactly, but so that
it is readily stored and efficiently used?
The integral routines will be given basis set handles and
shell indices. These will be used to lookup
the shell info (l-value, ngen, nprim) and find pointers
to the contraction info. Since Fortran cannot have pointers
returned to it from a C interface we have to either store
the stuff both on the C and Fortran sides, or do it
all in Fortran (I know, double ugh). I see no point
in doing things twice.
Since we are stuck with F77 we have no structures and
are back using simple offsets etc. This actually makes
storing the info externally easier since the internal
representation is flat.
Detailed data structures ... derive from their usage by your
integral routines.
int_2e_4c(ibasis, jbasis, ish, jsh, ksh, lsh, ...)
check basis handles
get info (type, nprim, ngen, coords) on each shell
find pointers to coeffs/exponents for each shell
(this implies that they are stored packed into a
single array and we have offsets stored)
branch to the fastest routine depending on if generally contracted,
the angular momentum, if it is an sp shell, ...
in your API
call the primitive evaluation routine with explicit
coord/coeff/exponents
So it seems that we have very similar data structures to the
present int.h, except that the basis info is only stored for
unique atom types
Now do the mapping in detail
if (ibasis .le.0 .or. ibasis .gt. nbasis) call errquit(...)
if (ish .le. 0 .or. ish .gt. nshell(ibasis)) call errquit(...)
iuniq = shell_uniq(ish, ibasis) ... map shell to no. of the shell info
for unique tags only
itype = shell_type(iuniq, ibasis) (1, 2, 3 for s, p, d
-1, -2, ... for sp, spd, ... shells)
iprim = shell_nprim(iuniq, ibasis)
igen = shell_nprim(iuniq, ibasis)
iexpnt= shell_expt(iuniq, ibasis) ... offset in exp(1, ibasis) where
this shells exponents start
icoeff= shell_cofpt(iuniq, ibasis) ... offset in coeff(1, ibasis) ....
icent= shell_cent(ish, ibasis) ... center no. for this shell to get coords
(for efficiency should grab the
coords from the geometry)
Should be rolling at this point.
Also need the following arrays to support the other basis set
routines
cent_to_sh(1:2, icent, ibasis) (contains hi-lo)
cent_to_bf(1:2, icent, ibasis)
sh_to_bf(1:2, ish, ibasis)
The info about each shell is simply
integer type, nprim, ngen
real coeff(nprim,ngen), expnt(nprim)
Thus, the atomic basis set is just
integer nshell, nprim_tag, ncoeff_tag
integer type(nshell), nprim(nshell), ngen(nshell),
cofpt(nshell), expt(nsehll)
real coeff(ncoeff_tag), expnt(nprim_tag)
For external storage this can be compactly represented as
... and there is no reason why the data cannot be also used
this way (so that coefpt and expt provide offsets into rdata)
integer dim_info(3)
integer idata(5*nshell)
real rdata(ncoeff_tag+nprim_tag)
(the rtdb can automatically allocate the MA arrays and read into them)
These could be stored on the rtdb as
basis:basis_name:tag:dim_info
basis:basis_name:tag:idata
basis:basis_name:tag:rdata
along with a summary of all unique tag info
integer nshell_total, nprim_total, idata_total, rdata_total
basis:basis_name:dim_info -> integer dim_info(4)
However, we can make things even easier by storing the whole
damn lot in one data structure since it will always be possible
to store info on the unqiue atom centers (even if the whole
periodic table is in there!). Thus, my recomendation is that
the data base contain the following
basis:basis_name:dim_info integer
basis:basis_name:tags character
basis:basis_name:tdata integer
basis:basis_name:idata integer
basis:basis_name:rdata double precision
Where
dim_info(1) -> nshell_uniq_total = total no. of shells on the unique tags
dim_info(2) -> nprim_uniq_total = total no. of prims on the unique tags
dim_info(3) -> idata_uniq_total = total length of idata
dim_info(4) -> idata_uniq_total = total length of rdata
dim_info(5) -> ntags_uniq = no. of unique tags
tags(1:ntags_uniq) = character array of tags (cannot be allocated
using MA !!)
tdata(1, itag_uniq) = first unique shell on this tag
tdata(2, itag_uniq) = last last shell on this tag
idata(1, ish_uniq) = type of shell
idata(2, ish_uniq) = nprim in shell
idata(3, ish_uniq) = ngen of shell
idata(4, ish_uniq) = offset into rdata for coeffs
idata(5, ish_uniq) = offset into rdata for exponents
idata(6, ish_uniq) = no. of bf in this shell
To load this lot into core and build the data structures
on the fly :
logical function basis_load(rtdb, name, igeom, ibasis)
0) look for translations of name within the current or higher
context using context_rtdb_match(). With the name or available
translation look for basis:basis_name:dim_info ... if this is there
then the basis set is defined. Can adopt a default at this
point if desired. Check that have statically allocated enuf
space to read in the unique tags.
rtdb_cget( tags )
rtdb_ma_get (tdata, rdata, idata)
1) Get tags/coords info from the geometry (note .. only one geometry
being used by the integrals at a time ... I would suggest that
the geometry handle be removed from the int_init() call and
be stored internal to each basis sets structure ... this then
gives us a mechanism to compute integrals between different
geometries (this sounds worth thinking about more)).
2) Loop thru centers checking that have a basis defined for that
tag and accumulate the no. of shells and basis functions.
At same time build map from atoms to shells and bf and
map from shells to unique shell no.
Done.
How this info gets onto the database is another problem. I would
suggest that the input program provides the info in nearly this form
to a basis set routine for output to the database. Since the input
routines want to be very general it's best to let them worry about
the details and live with a very simple basis set interface. We also
need to consider how to handle plane waves, giaos etc ... let's talk
about this and also to Jeff about giaos before casting this in
FORTRAN. I think that the above will suffice for the GTO basis
sets and we can add additional RTDB entries for the plane waves etc.
Robert

29
src/basis/geobasmapP.h Normal file
View file

@ -0,0 +1,29 @@
#ifndef _GEOBASMAPP_H
#define _GEOBASMAPP_H
/*
NOTE: this MUST follow basP.fh in the include order
these are all in core
mapping arrays atoms <-> contr <-> bfn (maybe add shells later)
contraction -> unique_contr :: ibs_cn2ucn(ncont,nbasis)
contraction -> center_number :: ibs_cn2ce (ncont,nbasis)
center -> unique_center :: ibs_ce2uce(nat,nbasis)
contraction -> basis function range :: ibs_cn2bfr(2,ncont,nbasis)
centers -> contraction range :: ibs_ce2cnr(2,nat,nbasis)
*/
#ifdef __cplusplus
extern "C" {
#endif
int ibs_cn2ucn(int ncont, int nbasis);
int ibs_cn2ce(int ncont, int nbasis);
int ibs_ce2uce(int nat, int nbasis);
int ibs_cn2bfr(int ncont, int nbasis);
int ibs_ce2cnr(int nat, int nbasis);
int ncont_tot_gb, nprim_tot_gb, nbf_tot_gb, ibs_geom;
#ifdef __cplusplus
}
#endif
#endif // _GEOBASMAPP_H

11
src/basis/newbasis.c Normal file
View file

@ -0,0 +1,11 @@
#include <stdio.h>
void bas_dummmmmm() {
int i;
i = 0;
}
int bas_print_known(FILE *rtdb) {
return 0;
}

170
src/basis/testbasis.c Normal file
View file

@ -0,0 +1,170 @@
#include "bas.h"
#include "rtdb.h"
#include "geom.h"
#include <stdio.h>
#include <stdbool.h>
int main() {
FILE *rtdb, *geom, *basis;
int ngen, nprim, iang;
int ncenters, sphcart, i, j;
char drivtags[20][16];
double coords[3][20], charge[20];
double exp[400], coeff[400];
bool status;
double expnt_new[3] = {1.0, 2.0, 3.0};
double coeff_new[4][3] = {
{-1.0, -2.0, -3.0},
{0.0, -4.0, -5.0},
{-6.0, 0.0, -7.0},
{-8.0, -9.0, 0.0}
};
if (!ma_init(MT_DBL, -1, -1)) {
printf("Error initializing ma_init\n");
return 99;
}
status = rtdb_par_open("shit.rtdb", "unknown", &rtdb);
printf("rtdb handle %d\n", rtdb);
status = bas_321g_load(&rtdb);
if (!geom_create(&geom, "321g:1-20")) {
printf("Error getting geometry handle\n");
return 1;
}
ncenters = 3;
// oxygen
strcpy(drivtags[0], "O");
coords[0][0] = 0.0;
coords[1][0] = 0.0;
coords[2][0] = 0.0;
charge[0] = 8.0;
// hydrogen 1
strcpy(drivtags[1], "H");
coords[0][1] = 1.0;
coords[1][1] = 1.0;
coords[2][1] = 1.0;
charge[1] = 1.0;
// hydrogen 2
strcpy(drivtags[2], "H");
coords[0][2] = -1.0;
coords[1][2] = -1.0;
coords[2][2] = -1.0;
charge[2] = 1.0;
if (!geom_cart_set(&geom, ncenters, drivtags, coords, charge)) {
printf("geom_cart_set fail\n");
return 1;
} else {
status = geom_print(&geom);
}
basis = 0;
if (!bas_create(&basis, "3211-20")) {
printf("Error getting basis handle\n");
return 1;
}
basis = 0;
if (!bas_create(&basis, "321g1-20")) {
printf("Error getting second basis handle\n");
return 1;
}
basis = 0;
if (!bas_create(&basis, "321g:1-20")) {
printf("Error getting third basis handle\n");
return 1;
}
status = bas_rtdb_load(&rtdb, &geom, &basis, "321g:1-20");
status = bas_print(&basis);
status = gbs_map_print(&basis);
status = bas_continfo(&basis, 1, false, &nprim, &ngen, &sphcart);
printf("f:query: nprim cont 1 %d\n", nprim);
printf("f:query: ngen cont 1 %d\n", ngen);
printf("f:query: sphcart cont 1 %d\n", sphcart);
status = bas_get_exponent(&basis, 1, false, exp);
status = bas_get_coeff(&basis, 1, false, coeff);
printf("exponents and coefficients\n");
for (i = 0; i < nprim; i++) {
for (j = 0; j < ngen; j++) {
printf("%lf ", coeff[i + j * nprim]);
}
printf("\n");
}
status = bas_continfo(&basis, 1, true, &nprim, &ngen, &sphcart);
printf("t:query: nprim cont 1 %d\n", nprim);
printf("t:query: ngen cont 1 %d\n", ngen);
printf("t:query: sphcart cont 1 %d\n", sphcart);
status = bas_get_exponent(&basis, 1, true, exp);
status = bas_get_coeff(&basis, 1, true, coeff);
printf("exponents and coefficients\n");
for (i = 0; i < nprim; i++) {
for (j = 0; j < ngen; j++) {
printf("%lf ", coeff[i + j * nprim]);
}
printf("\n");
}
exp[0] = 565.6589;
coeff[0] = 6.021023;
status = bas_set_exponent(&basis, 1, true, exp, nprim + 1);
status = bas_set_coeff(&basis, 1, true, coeff, nprim * ngen + 1);
status = bas_set_exponent(&basis, 1, true, exp, nprim);
status = bas_set_coeff(&basis, 1, true, coeff, nprim * ngen);
status = bas_continfo(&basis, 1, true, &nprim, &ngen, &sphcart);
printf("modified\n");
printf("t:query: nprim cont 1 %d\n", nprim);
printf("t:query: ngen cont 1 %d\n", ngen);
printf("t:query: sphcart cont 1 %d\n", sphcart);
status = bas_get_exponent(&basis, 1, true, exp);
status = bas_get_coeff(&basis, 1, true, coeff);
printf("exponents and coefficients\n");
for (i = 0; i < nprim; i++) {
for (j = 0; j < ngen; j++) {
printf("%lf ", coeff[i + j * nprim]);
}
printf("\n");
}
// Try adding new contractions on an existing center
printf("adding 3*3 d function on H\n");
if (!bas_add_ucnt(basis, "H", 2, 3, 3, expnt_new, coeff_new, 4)) {
printf(" basis_add_ucnt failed");
}
if (!bas_print(&basis)) {
printf(" print ???");
}
// Try adding new contractions on a new center
printf("adding 2*3 g function on Cl\n");
if (!bas_add_ucnt(basis, "Cl", 4, 2, 3, expnt_new, coeff_new, 4)) {
printf(" basis_add_ucnt failed");
}
if (!bas_print(&basis)) {
printf(" print ???");
}
printf("bas_print_all\n");
status = bas_print_all();
bas_err_info("who who who");
status = bas_high_angular(&basis, &iang);
printf("high angular momentum %d\n", iang);
status = bas_version();
printf("testbasis done\n");
return 0;
}

176
src/config/makefile.h Normal file
View file

@ -0,0 +1,176 @@
# $Id: makefile.h,v 1.1.1.1 1994-03-29 06:44:24 d3g681 Exp $
# Common definitions for all makefiles ... these can be overridden
# either in each makefile by putting additional definitions below the
# include statement, or on the command line
#
# Set TOPDIR to point to your top-level directory that contains
# src, lib, config, ... (SRCDIR, etc., are derived from TOPDIR)
#
TOPDIR = /msrc/home/d3g681/allnew
SRCDIR = $(TOPDIR)/src
LIBDIR = $(TOPDIR)/lib
BINDIR = $(TOPDIR)/bin
INCDIR = $(TOPDIR)/src/include
#
# Define TARGET to be the machine you wish to build for
# (one of SUN, IPSC, KSR)
#
TARGET = SUN
#
# Define SUBDIRS to be list of subdirectories of SRC to be made
#
# The include directory should be first so that the include
# files are all present and correct before any compilation
#
SUBDIRS = include global db rtdb basis inp util geom input ma tcgmsg
#
# Define LIBPATH to be paths for libraries that you are linking in
# from precompiled sources and are not building now. These libraries
# will be searched AFTER anything you are building now.
# e.g. LIBPATH = -L/msrc/proj/mss/lib
#
LIBPATH =
#
# Define INCPATH to be directories to get includes for
# libraries that you are not building now. These directories
# will be searched AFTER anything you are building now.
#
INCPATH =
##########################################################
# #
# Should NOT need to modify below here unless porting to #
# a new machine or changing compiler options #
# #
##########################################################
# !!!! Only the SUN version is up to date !!!!!
ifeq ($(TARGET),SUN)
#
# Sun running SunOS
#
FC = f77
CC = gcc
AR = ar
RANLIB = ranlib
SHELL = /bin/sh
MAKE = make
MAKEFLAGS = -j 2
INSTALL = echo $@ is built
FOPT = -g -u -Nl99
FOPT_REN = $(FOPT)
COPT = -g
FLDOPT = $(FOPT)
CLDOPT = $(COPT)
INCLUDES = -I. $(LIB_INCLUDES) -I$(INCDIR) $(INCPATH)
WARNINGS = -Wall
#-Wshadow -Wcast-qual -Wwrite-strings -Wpointer-arith
DEFINES = -DSUN $(LIB_DEFINES)
FFLAGS = $(FOPT) $(INCLUDES) $(DEFINES)
CFLAGS = $(COPT) $(INCLUDES) $(DEFINES) $(WARNINGS)
ARFLAGS = rcv
LIBS = -L$(LIBDIR) $(LIBPATH) \
-linput -lgeom -lbasis -lutil -lglobal -lrtdb -ldb -linp \
-lutil -lma -ltcgmsg
EXPLICITF = FALSE
endif
ifeq ($(TARGET),IPSC)
#
# DELTA/IPSC running NX
#
FC = if77
CC = icc
CPP = /usr/lib/cpp
AR = ar860
RANLIB = echo
SHELL = /bin/sh
INSTALL = rcp $@ delta2:
FOPT = -O2 -Knoieee -Mquad -node -Minline=100
FOPT_REN = -O2 -Knoieee -Mquad -Mreentrant -Mrecursive -node
COPT = -O2 -Knoieee -Mreentrant -node
INCLUDES = -I. -I$(SRCDIR)/rtdb -I$(SRCDIR)/global -I$(SRCDIR)/tcgmsg -I$(SRCDIR)/ints \
-I$(SRCDIR)/util -I$(SRCDIR)/ma -I$(SRCDIR)/db -I$(SRCDIR)/tcgmsg/ipcv4.0
DEFINES = -DNX -DIPSC -DNO_BCOPY $(LIB_DEFINES)
# -DGA_TRACE
FFLAGS = $(FOPT)
CFLAGS = $(COPT) $(INCLUDES) $(DEFINES)
MAKEFLAGS = -j 2
FLDOPT = $(FOPT) -node
CLDOPT = $(COPT) -node
ARFLAGS = rcv
LIBS = $(SRCDIR)/input/libinput.a \
$(SRCDIR)/ddscf/libddscf.a \
$(SRCDIR)/ints/libints.a \
$(SRCDIR)/rtdb/librtdb.a \
$(SRCDIR)/db/libdb.a \
$(SRCDIR)/global/libglobal.a \
$(SRCDIR)/trace/libtrace.a \
$(SRCDIR)/tcgmsg/ipcv4.0/libtcgmsg.a \
$(SRCDIR)/util/libutil.a \
$(SRCDIR)/ma/libma.a \
$(SRCDIR)/peigs1.0/libpeigs.a \
$(SRCDIR)/peigs1.0/liblapack.a \
-lkmath
EXPLICITF = TRUE
endif
ifeq ($(TARGET),IBM)
#
# IBM AIX .... NOT YET TESTED !!!!!
#
# FC = xlf
# CC = xlc
# AR = ar
# RANLIB = ranlib
# INSTALL = echo
# SHELL = /bin/sh
# FOPT = -g
# COPT = -g
# INCLUDES = -I. -I../ma
# DEFINES = -DTCGMSG
# FFLAGS = -qEXTNAME $(FOPT)
# FLDOPT = $(FOPT) -b rename:.exit_,.exit
# CFLAGS = $(COPT) $(INCLUDES) $(DEFINES)
# CLDOPT = $(COPT)
# ARFLAGS = rcv
# LIBS = ../tcgmsg/ipcv4.0/libtcgmsg.a ../ma/libma.a -lc
# EXPLICITF = TRUE
#
endif
ifeq ($(EXPLICITF),TRUE)
#
# Needed on machines where FCC does not preprocess .F files
# with CPP to get .f files
#
.SUFFIXES:
.SUFFIXES: .o .s .F .f .c
.F.o:
$(MAKE) $*.f
$(FC) -c $(FFLAGS) $*.f
/bin/rm -f $*.f
.F.f:
$(CPP) $(INCLUDES) $(DEFINES) < $*.F | sed '/^#/D' > $*.f
.c.o:
$(CC) $(CFLAGS) -c $*.c
endif

59
src/config/makelib.h Normal file
View file

@ -0,0 +1,59 @@
# $Id: makelib.h,v 1.1.1.1 1994-03-29 06:44:24 d3g681 Exp $
#
# A makefile for a library should
#
# 1) include ../config/makefile.h ... amoung other things this will
# define TARGET from which any machine dependent actions are driven
# 2) define LIBRARY as the name of the library to be made
# 3) define OBJ as the list of object files to be made
# 4) define HEADERS as the list of header/include files to be exported
# into the common include directory
# 5) optionally define LIB_TARGETS as any additional files made in
# this subdirectory that may need cleaning up
# 6) optionally define LIB_DEFINES as any additional defines for
# the C preprocessor
# 7) optionally define LIB_INCLUDES as any additional includes
# 8) include ../config/makelib.h
# 9) define any additional targets (e.g., test programs)
#
# E.g.
#
# include ../config/makefile.h
#
# OBJ = a.o b.o c.o
# LIBRARY = libsimple.a
# HEADERS = simple.h
# LIB_TARGETS = test.o test.x
# LIB_DEFINES = -DGOODBYE="\"Have a nice day\""
# LIB_INCLUDES = -I../testdir
#
# include ../config/makelib.h
#
# test: test.o $(LIBRARY)
# $(CC) -o $@ $^
#
# a.o b.o c.o test.o: simple.h
#
$(LIBRARY): $(OBJ)
/bin/rm -f $@
$(AR) $(ARFLAGS) $@ $(OBJ)
$(RANLIB) $@
cp -p $(LIBRARY) $(LIBDIR)
ifdef HEADERS
include_stamp: $(HEADERS)
cp -p $(HEADERS) $(INCDIR)
touch include_stamp
else
include_stamp:
touch include_stamp
endif
clean:
/bin/rm -f $(LIBRARY) $(OBJ) core include_stamp $(LIB_TARGETS)
realclean: clean
/bin/rm -f *~ \#*\#

9
src/geom/GNUmakefile Normal file
View file

@ -0,0 +1,9 @@
OBJ = geom.o geom_input.o
LIBRARY = libgeom.a
HEADERS = geom.h geomP.h
include ../config/makefile.h
include ../config/makelib.h
geom_input.o geom.o: geomP.h

683
src/geom/geom.c Normal file
View file

@ -0,0 +1,683 @@
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include "inp.h"
#include "rtdb.h"
#include "util.h"
#include "geomP.h"
#include "tcgmsg.h"
#include "context.h"
int ngeom_rtdb = 0;
bool active[max_geom] = {false};
char *symbols = {
"H ", "He", "Li", "Be", "B ", "C ", "N ", "O ", "F ", "Ne",
"Na", "Mg", "Al", "Si", "P ", "S ", "Cl", "Ar", "K ", "Ca",
"Sc", "Ti", "V ", "Cr", "Mn", "Fe", "Co", "Ni", "Cu", "Zn",
"Ga", "Ge", "As", "Se", "Br", "Kr", "Rb", "Sr", "Y ", "Zr",
"Nb", "Mo", "Tc", "Ru", "Rh", "Pd", "Ag", "Cd", "In", "Sn",
"Sb", "Te", "I ", "Xe", "Cs", "Ba", "La", "Ce", "Pr", "Nd",
"Pm", "Sm", "Eu", "Gd", "Tb", "Dy", "Ho", "Er", "Tm", "Yb",
"Lu", "Hf", "Ta", "W ", "Re", "Os", "Ir", "Pt", "Au", "Hg",
"Tl", "Pb", "Bi", "Po", "At", "Rn", "Fr", "Ra", "Ac", "Th",
"Pa", "U ", "Np", "Pu", "Am", "Cm", "Bk", "Cf", "Es", "Fm",
"Md", "No", "Lr"
};
char *elements = {
"Hydrogen", "Helium", "Lithium", "Beryllium", "Boron",
"Carbon", "Nitrogen", "Oxygen", "Fluorine", "Neon", "Sodium",
"Magnesium", "Aluminium", "Silicon", "Phosphorous",
"Sulphur", "Chlorine", "Argon", "Potassium", "Calcium",
"Scandium", "Titanium", "Vanadium", "Chromium", "Manganese",
"Iron", "Cobalt", "Nickel", "Copper", "Zinc", "Gallium",
"Germanium", "Arsenic", "Selenium", "Bromine", "Krypton",
"Rubidium", "Strontium", "Yttrium", "Zirconium", "Niobium",
"Molybdenum", "Technetium", "Ruthenium", "Rhodium",
"Palladium", "Silver", "Cadmium", "Indium", "Tin",
"Antinomy", "Tellurium", "Iodine", "Xenon", "Caesium",
"Barium", "Lanthanum", "Cerium", "Praseodymium", "Neodymium",
"Promethium", "Samarium", "Europium", "Gadolinium",
"Terbium", "Dysprosium", "Holmium", "Erbium", "Thulium",
"Ytterbium", "Lutetium", "Hafnium", "Tantalum", "Tungsten",
"Rhenium", "Osmium", "Iridium", "Platinum", "Gold",
"Mercury", "Thallium", "Lead", "Bismuth", "Polonium",
"Astatine", "Radon", "Francium", "Radium", "Actinium",
"Thorium", "Protoactinium", "Uranium", "Neptunium",
"Plutonium", "Americium", "Curium", "Berkelium",
"Californium", "Einsteinium", "Fermium", "Mendelevium",
"Nobelium", "Lawrencium"
};
bool geom_check_handle(FILE *geom, char *msg) {
bool ret_val;
ret_val = geom > 0 && geom < max_geom;
if (ret_val) ret_val = ret_val && active[geom];
if (!ret_val) {
printf("%s: geometry handle invalid %d", msg, geom);
geom_err_info(msg);
}
return ret_val;
}
bool geom_check_cent(FILE *geom, char *msg, int icent) {
bool ret_val;
ret_val = icent > 0 && icent <= ncenter[geom];
if (!ret_val) {
printf("%s: icent invalid %d %s\n", msg, icent, names[geom]);
geom_err_info(msg);
geom_print(geom);
}
return ret_val;
}
bool geom_rtdb_in(FILE *rtdb) {
/*
load in info about known geometries ... this is more
for diagnostic and debugging purposes
*/
FILE *geom;
bool ret_val = false;
int ngeom_rtdb = 0;
if (rtdb_par_get(rtdb, "geometry:ngeom", MT_INT, 1, &ngeom_rtdb)) {
if (!rtdb_par_cget(rtdb, "geometry:names", max_geom, names_rtdb)) {
printf("geom_rtdb_in: rtdb corrupt\n");
} else {
for (geom = 0; geom < ngeom_rtdb; geom++) {
lenr[geom] = inp_strlen(names_rtdb[geom]);
}
ret_val = true;
}
}
return ret_val;
}
bool geom_rtdb_out(FILE *rtdb) {
bool ret_val;
// output to rtdb info about known geometries
ret_val = rtdb_par_put(rtdb, 'geometry:ngeom', MT_INT, 1, ngeom_rtdb)
&& rtdb_par_cput(rtdb, 'geometry:names', max_geom, names_rtdb);
if (!ret_val) printf(" geom_rtdb_out: rtdb is corrupt ");
}
bool geom_rtdb_add(FILE *rtdb, char *name) {
FILE *geom;
bool status, ret_val;
int ln;
// See if name is on the rtdb already
ln = strlen(name);
status = geom_rtdb_in(rtdb);
ret_val = true;
for (geom = 0; geom < ngeom_rtdb; geom++) {
if (strncmp(name, names_rtdb[geom], ln) == 0) {
return true;
}
}
// Name is not present ... add and rewrite info
if (ngeom_rtdb == max_geom_rtdb) {
printf(" geom_rtdb_add: too many geometries on rtdb %s\n", name);
return false;
}
ngeom_rtdb++;
strncpy(names_rtdb[ngeom_rtdb], name, ln);
lenr[ngeom_rtdb] = ln;
if (!geom_rtdb_out(rtdb)) {
printf(" geom_rtdb_add: rtdb error adding %.*s\n", ln, name);
return false;
}
return true;
}
bool geom_err_info(char *info) {
FILE *geom;
int ngeom = 0;
/*
For internal use of the geom routines only: print out
info of known geometries to aid in diagnosing a problem
*/
for (geom = 0; geom < max_geom; geom++) {
if (active[geom]) {
ngeom++;
}
}
printf(" %s: open geometries: %d\n", info, ngeom);
ngeom = 0;
for (geom = 0; geom < max_geom; geom++) {
if (active[geom]) {
printf(" %d %s: \"%s\" -> \"%s\"\n", ngeom, info, names[geom], trans[geom]);
}
}
if (ngeom_rtdb > 0) {
printf(" %s: geometries in last accessed data base: %d\n", info, ngeom_rtdb);
for (geom = 0; geom < ngeom_rtdb; geom++) {
printf(" %s\n", names_rtdb[geom]);
}
}
return true;
}
bool geom_rtdb_load(FILE *rtdb, FILE *geom, char *name) {
char tmp[256];
int k;
bool status, ret_val;
ret_val = geom_check_handle(geom, "geom_rtdb_load");
if (!ret_val) return false;
status = geom_rtdb_in(rtdb);
// Translate the provided name
strcpy(names[geom], name);
lenn[geom] = strlen(name);
strcpy(trans[geom], "junk");
if (!context_rtdb_match(rtdb, name, trans[geom]))
strcpy(trans[geom], name);
lent[geom] = strlen(trans[geom]);
// Now get the info from the data base
strcpy(tmp, "geometry:");
strncat(tmp, trans[geom], lent[geom]);
k = strlen(tmp) + 1;
status = true;
strcpy(tmp + k, ":ncenter");
status = status && rtdb_par_get(rtdb, tmp, MT_INT, 1, &ncenter[geom]);
strcpy(tmp + k, ":coords");
status = status && rtdb_par_get(rtdb, tmp, MT_DBL, max_cent * 3, &coords[1][1][geom]);
strcpy(tmp + k, ":charges");
status = status && rtdb_par_get(rtdb, tmp, MT_DBL, max_cent, &charge[1][geom]);
strcpy(tmp + k, ":efield");
status = status && rtdb_par_get(rtdb, tmp, MT_DBL, 3, &efield[1][geom]);
strcpy(tmp + k, ":latvec");
status = status && rtdb_par_get(rtdb, tmp, MT_DBL, 9, &latvec[1][1][geom]);
strcpy(tmp + k, ":tags");
status = status && rtdb_par_cget(rtdb, tmp, max_cent, &tags[1][geom]);
if (!status) {
printf(" geom_rtdb_load: not found or rtdb corrupt: %.*s -> %.*s\n", lenn[geom], names[geom], lent[geom], trans[geom]);
geom_err_info("geom_rtdb_load");
return false;
}
// Determine if system is periodic or if external fields are applied
oefield[geom] = ddot(3, efield[1][geom], 1, efield[1][geom], 1) > 0.0;
operiodic[geom] = ddot(9, latvec[1][1][geom], 1, latvec[1][1][geom], 1) > 0.0;
// Compute effective nuclear repulsion energy, dipole and interaction with external fields
geom_compute_values(geom);
active[geom] = true;
return true;
}
double geom_compute_values(FILE *geom) {
/*
compute effective nuclear repulsion energy, dipole and
interaction with external fields
*/
double e, r;
int i, j;
e = 0.0;
ndipole[0][geom] = 0.0;
ndipole[1][geom] = 0.0;
ndipole[2][geom] = 0.0;
// compute nuclear dipole moment and usual nuclear repulsion energy
for (i = 0; i < ncenter[geom]; i++) {
for (j = 0; j < 3; j++) {
ndipole[j][geom] += charge[i][geom] * coords[j][i][geom];
}
for (j = i + 1; j < ncenter[geom]; j++) {
r = sqrt(pow(coords[0][i][geom] - coords[0][j][geom], 2) +
pow(coords[1][i][geom] - coords[1][j][geom], 2) +
pow(coords[2][i][geom] - coords[2][j][geom], 2));
e += charge[i][geom] * charge[j][geom] / r;
}
}
// add in interaction of nuclear dipole with external field
e += ddot(3, ndipole[0][geom], 1, efield[0][geom], 1);
erep[geom] = e;
}
bool geom_rtdb_store(FILE *rtdb, char *name, FILE *geom) {
bool status, ret_val;
char tmp[256];
ret_val = geom_check_handle(geom, "geom_rtdb_store");
if (!ret_val) {
return false;
}
// Update the name if provided
if (name != NULL && strcmp(name, "") != 0) {
strcpy(names[geom], name);
lenn[geom] = strlen(name);
}
// If not process 0 return ... this is so that input routines can be completely single threaded
if (nodeid() != 0) {
return true;
}
// Try to translate the name
strcpy(trans[geom], "junk");
if (!context_rtdb_match(rtdb, name, trans[geom])) {
strcpy(trans[geom], name);
}
lent[geom] = strlen(trans[geom]);
// Now put the info into the data base
strcpy(tmp, "geometry:");
k = strlen(tmp);
status = true;
strcpy(tmp[k], ":ncenter\0");
status = status && rtdb_par_put(rtdb, tmp, MT_INT, 1, &ncenter[geom]);
strcpy(tmp[k], ":coords\0");
status = status && rtdb_par_put(rtdb, tmp, MT_DBL, ncenter[geom] * 3, &coords[1][1][geom]);
strcpy(tmp[k], ":charges\0");
status = status && rtdb_par_put(rtdb, tmp, MT_DBL, ncenter[geom], &charge[1][geom]);
strcpy(tmp[k], ":efield\0");
status = status && rtdb_par_put(rtdb, tmp, MT_DBL, 3, &efield[1][geom]);
strcpy(tmp[k], ":latvec\0");
status = status && rtdb_par_put(rtdb, tmp, MT_DBL, 9, &latvec[1][1][geom]);
strcpy(tmp[k], ":tags\0");
status = status && rtdb_par_cput(rtdb, tmp, ncenter[geom], &tags[1][geom]);
// Insert translated name into list of known geometries
status = status && geom_rtdb_add(rtdb, name);
// Check that all rtdb operations were successful
if (!status) {
printf(" geom_rtdb_store: write to rtdb failed: %.*s -> %.*s\n", lenn[geom], names[geom], lent[geom], trans[geom]);
geom_err_info("geom_rtdb_store");
return false;
}
return true;
}
bool geom_rtdb_delete(FILE *rtdb, char *name) {
char translation[256], tmp[256];
int lt, geom, geom2, k;
bool status, set_true = false;
// try to translate the provided name
if (rtdb_par_cget(rtdb, name, 1, translation) != 0) {
strcpy(translation, name);
}
lt = strlen(translation);
// locate name in list and remove
status = geom_rtdb_in(rtdb);
for (geom = 1; geom <= ngeom_rtdb; geom++) {
if (strncmp(names_rtdb[geom], translation, lt) == 0) {
set_true = true;
break;
}
}
if (!set_true) {
printf(" geom_rtdb_delete: no such geometry %.*s -> %.*s\n", strlen(name), name, lt, translation);
}
for (geom2 = geom + 1; geom2 <= ngeom_rtdb; geom2++) {
strcpy(names_rtdb[geom2 - 1], names_rtdb[geom2]);
}
ngeom_rtdb--;
status = geom_rtdb_out(rtdb);
// delete each entry associated with a geometry in the database
strcpy(tmp, "geometry:");
k = strlen(tmp);
strcpy(tmp[k], ":ncenter");
status = status && rtdb_par_delete(rtdb, tmp);
strcpy(tmp[k], ":coords");
status = status && rtdb_par_delete(rtdb, tmp);
strcpy(tmp[k], ":charges");
status = status && rtdb_par_delete(rtdb, tmp);
strcpy(tmp[k], ":efield");
status = status && rtdb_par_delete(rtdb, tmp);
strcpy(tmp[k], ":latvec");
status = status && rtdb_par_delete(rtdb, tmp);
strcpy(tmp[k], ":tags");
status = status && rtdb_par_delete(rtdb, tmp);
// check status of all rtdb stores
if (!status) {
printf(" geom_rtdb_delete: rtdb corrupt %.*s\n", lt, translation);
geom_err_info("geom_rtdb_delete");
return false;
}
return true;
}
bool geom_create(FILE *geom, char *name) {
char translation[256];
int i;
// Assign the next free slot for a geometry
for (i = 0; i < max_geom; i++) {
if (!active[i]) {
break;
}
}
if (i == max_geom) {
printf("geom_create: too many geoms trying to create %s\n", name);
geom_err_info("geom_create");
return false;
}
// Store info about the geometry
strcpy(names[i], name);
strcpy(trans[i], " ");
lenn[i] = strlen(name);
ncenter[i] = 0;
active[i] = true;
return true;
}
bool geom_destroy(FILE *geom) {
bool ret_val;
bool ret_val = geom_check_handle(geom, "geom_destroy");
if (!ret_val) return false;
active[geom] = false;
return true;
}
bool geom_cart_set(FILE *geom, int ncent, char *t[], double c[3][ncent], double q[ncent]) {
int i;
bool ret_val;
if (!geom_check_handle(geom, "geom_cart_set")) {
return false;
}
if (ncent <= 0 || ncent > max_cent) {
printf("geom_cart_set: too many centers %d %s\n", ncent, names[geom]);
return false;
}
ncenter[geom] = ncent;
for (i = 0; i < ncent; i++) {
strcpy(tags[i][geom], t[i]);
charge[i][geom] = q[i];
coords[0][i][geom] = c[0][i];
coords[1][i][geom] = c[1][i];
coords[2][i][geom] = c[2][i];
}
/*
compute effective nuclear repulsion energy, dipole and
interaction with external fields
*/
geom_compute_values(geom);
return true;
}
bool geom_cart_get(FILE *geom, int *ncent, char *t[], double c[][ncent], double q[]) {
int i;
if (!geom_check_handle(geom, "geom_cart_get")) {
return false;
}
*ncent = ncenter[geom];
for (i = 0; i < *ncent; i++) {
strcpy(t[i], tags[i][geom]);
q[i] = charge[i][geom];
c[0][i] = coords[0][i][geom];
c[1][i] = coords[1][i][geom];
c[2][i] = coords[2][i][geom];
}
return true;
}
bool geom_cent_get(FILE *geom, int icent, char *t, double c[3], double *q) {
bool ret_val;
ret_val = geom_check_handle(geom, "geom_cent_get");
if (!ret_val) return false;
ret_val = geom_check_cent(geom, "geom_cent_get", icent);
if (!ret_val) return false;
strcpy(t, tags[icent][geom]);
c[0] = coords[0][icent][geom];
c[1] = coords[1][icent][geom];
c[2] = coords[2][icent][geom];
q = charge[icent][geom];
return true;
}
bool geom_cent_set(FILE *geom, int icent, char *t, double c[3], double q) {
if (!geom_check_handle(geom, "geom_cent_set")) {
return false;
}
if (!geom_check_cent(geom, "geom_cent_set", icent)) {
return false;
}
strcpy(tags[icent][geom], t);
coords[0][icent][geom] = c[0];
coords[1][icent][geom] = c[1];
coords[2][icent][geom] = c[2];
charge[icent][geom] = q;
geom_compute_values(geom);
return true;
}
bool geom_ncent(FILE *geom, int ncent) {
bool ret_val;
ret_val = geom_check_handle(geom, "geom_ncent");
if (!ret_val) return false;
ncent = ncenter[geom];
return true;
}
bool geom_cent_tag(FILE *geom, int icent, char *tag) {
if (!geom_check_handle(geom, "geom_cent_tag")) {
return false;
}
if (!geom_check_cent(geom, "geom_cent_tag", icent)) {
return false;
}
strcpy(tag, tags[icent][geom]);
return true;
}
bool geom_latvec_set(FILE *geom, double vectors[3][3]) {
errquit("geom_latvec_set: not yet!", 0);
return false;
}
bool geom_latvec_get(FILE *geom, double vectors[3][3]) {
errquit("geom_latvec_get: not yet!", 0);
return false;
}
bool geom_efield_set(FILE *geom, double efield[3]) {
errquit("geom_efield_set: not yet!", 0);
geom_set_values(geom);
return false;
}
bool geom_efield_get(FILE *geom, double efield) {
errquit("geom_efield_get: not yet!", 0);
return false;
}
bool geom_print(FILE *geom) {
/*
Basic printing of cartesian geometry ... needs support for
user defined units, internal coords, different formats, ...
*/
int icent, ivec, i;
bool ret_val;
if (!geom_check_handle(geom, "geom_print")) {
return false;
}
printf(" Geometry (au) \"%s\" -> \"%s\"\n", names[geom], trans[geom]);
printf(" -------------\n");
printf(" No. Tag Charge X Y Z\n");
printf(" ---- ---------------- ---------- -------------- -------------- --------------\n");
for (icent = 0; icent < ncenter[geom]; icent++) {
printf("%4d %16s %10.6f %14.8f %14.8f %14.8f\n", icent, tags[icent][geom], charge[icent][geom], coords[0][icent][geom], coords[1][icent][geom], coords[2][icent][geom]);
}
printf("Effective nucler repulsion charge (au) %18.10f", erep[geom]);
if (operiodic[geom]) {
printf("Periodic lattice vectors (au)\n");
printf(" -----------------------------\n");
printf(" X Y Z\n");
printf(" ---------------- ---------------- ----------------\n");
for (ivec = 0; ivec < 3; ivec++) {
printf(" %17.10f %17.10f %17.10f\n", latvec[ivec][0][geom], latvec[ivec][1][geom], latvec[ivec][2][geom]);
}
}
if (oefield[geom]) {
printf("Electric Field (au)\n");
printf(" -------------------\n");
printf(" X Y Z\n");
printf(" ---------------- ---------------- ----------------\n");
printf(" %17.10f %17.10f %17.10f\n", efield[0][geom], efield[1][geom], efield[2][geom]);
}
return true;
}
bool geom_tag_to_element(char *tag, char *symbol, char *element, int *atn) {
/*
attempt to figure out which element a tag refers to
and return the symbol, name and atomic no.
*/
bool ret_val;
int lbuf, ind;
char buf[17];
char sym1[15] = {'h', 'b', 'c', 'n', 'o', 'f', 'p', 's', 'k', 'v', 'y', 'i', 'w', 'u'};
int atn1[14] = {1, 5, 6, 7, 8, 9, 15, 16, 19, 23, 39, 53, 74, 92};
ret_val = false;
/*
eliminate conventions that refer to centers used for
computation purposes .. just bq for now
*/
lbuf = strlen(buf);
if (lbuf == 0) return false;
for (int i = 0; i < lbuf; i++) {
buf[i] = tolower(buf[i]);
}
if (strncmp(buf, "bq", 2) == 0) {
strcpy(element, "point charge");
strcpy(symbol, "bq");
atn = 0;
return false;
}
/*
Attempt to match the first 4 characters of the
full names of the elements
*/
atn = 0;
if (lbuf >= 4) {
for (int i = 0; i < nelements; i++) {
if (strncmp(buf, elements[i], 4) == 0) {
strcpy(symbol, symbols[i]);
strcpy(element, elements[i]);
atn = i;
ret_val = true;
return true;
}
}
}
/*
Failed ... attempt to match the first two characters
against two character element names
*/
if (buf[1] != ' ') {
for (int i = 0; i < nelements; i++) {
if (strncmp(buf, symbols[i], 2) == 0) {
strcpy(symbol, symbols[i]);
strcpy(element, elements[i]);
atn = i;
ret_val = true;
return true;
}
}
}
// Last ditch attempt ... match against 1 character symbols
for (int i = 0; i < 14; i++) {
if (buf[0] == sym1[i]) {
ind = atn1[i];
strcpy(symbol, symbols[ind]);
strcpy(element, elements[ind]);
atn = ind;
ret_val = true;
return true;
}
}
// Nothing matched
strcpy(symbol, " ");
strcpy(element, " ");
atn = 0;
return false;
}

113
src/geom/geom.doc Normal file
View file

@ -0,0 +1,113 @@
The geometry data includes
1) A description of the coordinates of all types of centers (e.g.,
atom, charge, basis function)
2) Charges (and I guess possibly other potentials) associated with
those centers
3) Tags (names) of centers
4) Masses associated with centers
5) Variables for optimization (e.g., via constrained cartesians
or zmatrix variables)
6) Any other simple scalar/vector attributed associated
specifically with a center
Operations
1) Store/retrieve from the database
logical geom_rtdb_load(rtdb, name, geom)
integer rtdb [input]
character*(*) name [input]
integer geom [output]
logical geom_rtdb_store(rtdb, 'geometry', geom)
integer rtdb [input]
character*(*) name [input]
integer geom [input]
2) Create/destroy
logical geom_create(geom)
integer geom [output]
logical geom_destroy(geom)
integer geom [input]
3) Set/get commmon values for all centers
logical geom_cart_set(geom, ncent, tags, coords, charges)
integer geom [input]
integer ncent [input]
character*(*) tags(ncent) [input]
character*(*) coords(3, ncent) [input]
character*(*) charges(ncent) [input]
logical geom_cart_get(geom, ncent, tags, coords, charges)
integer geom [input]
integer ncent [output]
character*(*) tags(ncent) [output]
character*(*) coords(3, ncent) [output]
character*(*) charges(ncent) [output]
4) Set/get common values for specific centers
logical geom_cent_set(geom, icent, tag, coord, charge)
integer geom [input]
integer ncent [input]
character*(*) tag [input]
character*(*) coords(3) [input]
character*(*) charge [input]
logical geom_cent_get(geom, icent, tag, coord, charge)
integer geom [input]
integer ncent [output]
character*(*) tag [output]
character*(*) coords(3) [output]
character*(*) charge [output]
5) Inquiry routines
integer function geom_ncent(geom)
integer geom [input]
logical function geom_cent_tag(geom, icent, tag)
integer geom [input]
integer icent [input]
character*(*) tag [output]
6) Set/get specific values for specific centers
There are two possibilities here
a) adopt an extensible definition of properties associated
with a center. This includes registering new properties
with a name and routines to set/get/load/store the values
and some general format (e.g., netcdf) for describing
and passing data.
b) adopt a static definition of the data structures and
require recompilation after the structures have been changed
and new routines provided.
Do we think that new properties will be added very regularly or
that this will become very infrequent? I tend to think the latter,
so a) is not yet worth the effort. Since b) requires very little
effort we can always change our minds and do a) later.
7) Zmatrix routines ... not yet defined
n_zmat_cent, n_zmat_vars, ...
logical geom_zmat_defined()
call geom_zmat_get
call geom_zmat_set
...
Data on the rtdb

31
src/geom/geom.h Normal file
View file

@ -0,0 +1,31 @@
#ifndef _GEOM_H
#define _GEOM_H
#include <stdio.h>
bool geom_check_handle(FILE *, char *);
bool geom_check_cent(FILE *, char *, int);
bool geom_rtdb_in(FILE *);
bool geom_rtdb_out(FILE *);
bool geom_rtdb_add(FILE *, char *);
bool geom_err_info(char *);
bool geom_rtdb_load(FILE *, FILE *, char *);
double geom_compute_values(FILE *);
bool geom_rtdb_store(FILE *, char *, FILE *);
bool geom_rtdb_delete(FILE *, char *);
bool geom_create(FILE *, char *);
bool geom_destroy(FILE *);
bool geom_cart_set(FILE *, int, char *[], double[3][], double[]);
bool geom_cart_get(FILE *, int *, char *[], double *[], double []);
bool geom_cent_get(FILE *, int, char *, double[3], double *);
bool geom_cent_set(FILE *, int, char *, double[3], double);
bool geom_ncent(FILE *, int);
bool geom_cent_tag(FILE *, int, char *);
bool geom_latvec_set(FILE *, double [3][3]);
bool geom_latvec_get(FILE *, double [3][3]);
bool geom_efield_set(FILE *, double[3]);
bool geom_efield_get(FILE *, double);
bool geom_print(FILE *);
bool geom_tag_to_element(char *, char *, char *, int *);
#endif

84
src/geom/geomP.h Normal file
View file

@ -0,0 +1,84 @@
#ifndef _GEOMP_H
#define _GEOMP_H
/*
Private fortran include file for the geometry routines
Parameters
max_geom = maximum no. of geometries
max_cent = maximum no. of centers in a geometry
max_geom_rtdb = maximum no. of geometries stored in the rtdb
nelments = no. of elements that info is stored about
[The only thing that cannot be dynamically allocated are the
character variables for the tags ... I was lazy and just statically
dimensioned everything ... just drudge work to dynamically
allocate though if necessary ... which it hopefully won't be
... since only geom.F (and maybe the basis routines) include
this header file only these need to be recompiled if the parameters
are changed]
Members of /cgeometry/
ngeom_rtdb = current no. of geometries on the rtdb
active(1:max_geom) = true if this geometry is open
ncenter(1:max_geom) = no. of centers in this geometry
coords(1:3,1:max_cent,1:max_geom) = cartesian coords of this geometry
charge(1:max_cent,1:max_geom) = charges associated with centers
dipole ... not yet
quadrupole ... not yet
pseudopotential ... not yet
efield(1:3,1:max_geom) = external electric field applied to this system
oefield = true if efield is on
latvec(1:3,1:3,1:max_geom) = vectors specifing periodicity
(null vector gives no periodicity)
operiodic = true if a lattice vector is non-null
erep(1:max_geom) = interaction energy of centers with each other
and external fields. At its simplest this is
just the nuclear repulsion energy
ndipole(1:3,1:max_geom) = nuclear dipole moment
Members of /ccgeometry/
names(1:max_geom) = names of open geometries
trans(1:max_geom) = translations of names of open geoms
names_rtdb(1:max_geom) = names of geometries in the rtdb
tag(1:max_cent,1:max_geom) = tags associated with centers
lenn(1:max_geom) = length of names(geom) minus trailing blanks
lent(1:max_geom) = length of trans(geom) ...
lenr(1:max_geom) = length of names_rtdb(geom) ...
symbols(1:nelements) = symbols for elements
elements(1:nelements) = names of elements
*/
#define MAX_GEOM 2
#define MAX_CENT 1000
#define MAX_GEOM_RTDB 100
#define NELEMENTS 103
typedef struct {
double coords[3][MAX_CENT][MAX_GEOM];
double charge[MAX_CENT][MAX_GEOM];
double efield[3][MAX_GEOM];
double latvec[3][3][MAX_GEOM];
double erep[MAX_GEOM];
double ndipole[3][MAX_GEOM];
int ncenter[MAX_GEOM];
int active[MAX_GEOM];
int lenn[MAX_GEOM];
int lent[MAX_GEOM];
int lenr[MAX_GEOM];
int operiodic[MAX_GEOM];
int oefield[MAX_GEOM];
int ngeom_rtdb;
} CGeometry;
typedef struct {
char names[MAX_GEOM][256];
char trans[MAX_GEOM][256];
char names_rtdb[MAX_GEOM_RTDB][256];
char tags[MAX_CENT][MAX_GEOM][16];
char symbols[NELEMENTS][2];
char elements[NELEMENTS][16];
} CCGeometry;
#endif // _GEOMP_H

98
src/geom/geom_input.c Normal file
View file

@ -0,0 +1,98 @@
#include <stdio.h>
#include <stdbool.h>
#include "inp.h"
#include "geom.h"
#include "tcgmsg.h"
void geom_input(FILE *rtdb, bool print) {
char field[255]; // for character input
char name[255]; // for name of geometry
char units[12]; // holds units of coordinates
int ncenter; // counts no. of centers as input
FILE *geom; // handle for geometry
bool status; // scratch for return codes
const int max_center = 1000; // parameter for local array dimension
double coords[max_center][3];
double charge[max_center];
char tags[max_center][16];
/*
read a geometry from the input deck and output it
to the rtdb.
current input line should begin 'geometry ...'
Cartesians only for now
*/
if (nodeid() != 0) return;
// Check that this is indeed a geometry line
inp_set_field(0); // goto start of line
if (!inp_a(field)) {
errquit("geom_input: no input present", 0);
}
if (!inp_compare(false, "geom", field)) {
errquit("geom_input: not geometry input", 0);
}
// geometry [<name>] [units <units>]
strcpy(units, "atomic units");
strcpy(name, " ");
while (inp_a(field)) {
if (inp_compare(false, "units", field)) {
if (!inp_a(units)) {
errquit("geom_input: geometry [<name>] [units <units>]", 0);
}
geom_check_units(units);
} else {
if (strcmp(name, " ") != 0) {
errquit("geom_input: geometry [<name>] [units <units>]", 0);
}
strcpy(name, field);
}
}
if (!geom_create(geom, name)) {
errquit("geom_input: geom_create failed !", 0);
}
// tag charge x y z
ncenter = 0;
while (inp_read()) {
status = inp_a(field);
if (inp_compare(false, "end", field)) break;
else {
if ((ncenter + 1) == max_center)
errquit("geom_input: too many centers?", ncenter);
strcpy(tags[ncenter + 1], field);
status = status && inp_f(charge[ncenter + 1]);
status = status && inp_f(coords[0][ncenter + 1]);
status = status && inp_f(coords[1][ncenter + 1]);
status = status && inp_f(coords[2][ncenter + 1]);
if (!status)
errquit("geom_input: <tag> <charge> <x> <y> <z>", 0);
ncenter++;
}
}
if (!geom_cart_set(geom, ncenter, tags, coords, charge)) {
errquit("geom_input: geom_cart_set failed", 0);
}
if (print) {
if (!geom_print(geom)){
errquit("geom_input: print failed ", 0);
}
}
if (!geom_rtdb_store(rtdb, name, geom)) {
errquit("geom_input: geom_rtdb_store failed", 0);
}
if (!geom_destroy(geom)) {
errquit("geom_input: geom_destroy failed", 0);
}
// done
}

20
src/include/GNUmakefile Normal file
View file

@ -0,0 +1,20 @@
#
# This directory is a central repository for all include
# files. The makefile in each subdirectory should contain
# a rule that keeps this directory up to date
#
include ../config/makefile.h
includes:
for dir in $(SUBDIRS); do \
echo Making include_stamp in $(SRCDIR)/$$dir ; \
(cd $(SRCDIR)/$$dir; $(MAKE) include_stamp) ; \
done
include_stamp:
echo Nothing to be done
realclean clean:
echo Header files not removed
/bin/rm -f *~ \#*\#

13
src/inp/GNUmakefile Normal file
View file

@ -0,0 +1,13 @@
# $Id: GNUmakefile,v 1.1.1.1 1994-03-29 06:44:37 d3g681 Exp $
OBJ = inp.o
LIBRARY = libinp.a
LIB_TARGETS = test.o test
HEADERS = inp.fh
include ../config/makefile.h
include ../config/makelib.h
test: test.o input.o
$(FC) $(FFLAGS) -o $@ $^ $(LIBS)

191
src/inp/inp.doc Normal file
View file

@ -0,0 +1,191 @@
All routines are declared in the header file 'inp.h'
subroutine inp_init(ir, iw)
Initialize free format input routines to take input from
fortran unit ir and send their output to fortran unit iw.
The input file is processed from the current location.
inp_init() shuld be invoked each time the input file is
repositioned using other than inp_*() routines (e.g., rewind).
logical function inp_read()
Read a line from the input and split it into white space (blank
or tab) separated fields. White space may be incorporated into a
field by enclosing it in quotes ("). The case of input is
preserved. Blank lines are ignored, and text from a pound or
hash symbol (#) to the end of the line is treated as a comment.
A backslash(\) at the end of a line (only white space may appear
after it) may be used to concatentate physical input lines into
one logical input line. A semicolon (;) may be used to split a
physical input line into multiple logical input lines. The
special meaning of hash (#), semicolon (;) and quotation (")
characters may be avoided only by prefacing them with a backslash
(this must be done even if the character is inside a quoted
character string).
The no. of fields read is set to 0, there being a total of
inp_nfield() fields in the line.
If a non-blank line is successfully parsed then .true. is returned.
Otherwise an internal error message is set and .false. is returned.
Possible errors include detection of EOF (inp_eof() may be used
to check for this condition) or failure to parse the line (e.g.,
a character string without a terminating quote).
EOF may be indicated by end of the physical input file, or by a
physical input line that begins with either asterisk (*), period
(.) or EOF (ignoring case), and has only trailing white space.
There is a maximum input line width of 256 characters.
logical function inp_i(integer i)
Attempt to read the next field as an integer.
Upon success return .true. and advance to the next field.
Otherwise return .false., save an internal error message and do
not change the current field.
logical function inp_f(double precision d)
Attempt to read the next field as a floating point number.
Upon success return .true. and advance to the next field.
Otherwise return .false., save an internal error message and do
not change the current field.
logical function inp_a(character*(*) a)
Attempt to read the next field as a character string.
Upon success return .true. and advance to the next field.
Otherwise return .false., save an internal error message and do
not change the current field.
logical function inp_a_trunc(character*(*) a)
Attempt to read the next field as a character string, quietly
discarding any data that does not fit in the user provided buffer.
Upon success return .true. and advance to the next field.
Otherwise return .false., save an internal error message and do
not change the current field.
logical function inp_line(character*(*) z)
character*(*) z
Return in z as much of the entire input line as it will hold and
quietly discard any overflow. Upon success return .true.,
otherwise save an internal error message and return .false.
integer function inp_n_field()
Returns the no. of fields in the current input line (1, ...). A
value of 0 implies either that EOF or some other error was
detected or inp_read() has not yet been called.
integer function inp_cur_field()
Returns the no. of fields in the input line that have been
processed so far (0, ...). Thus if inp_cur_field() returns 2,
then the next field read by inp_f() etc. will be field 3.
subroutine inp_set_field(value)
integer value
Sets the current field (as returned by inp_cur_field) to be
value. 0 <= value <= inp_n_field(). An out of range value
results in error termination.
subroutine inp_prev_field()
A convenience routine that positions you to read the field (on
the current input line) that was last read. It is simply
implemented as
call inp_set_field(max(0,inp_cur_field()-1))
At the beginning of the line this is a null operation.
logical function inp_compare(ocase, a, b)
logical ocase
character*(*) a, b
Return .true. iff all the characters in A match the first
len(A) characters of B. If ocase is .true. then comparisons are
case sensitive, otherwise comparisons ignore case.
logical function inp_match(nrec, ocase, test, array, ind)
integer nrec
logical ocase
character*(*) test
character*(*) array(nrec)
integer ind
Let L be the length of the character string test ignoring
trailing blanks. Attempt to find a unique match of test(1:L)
against elements of array(*). If ocase is .true. then
comparisons are case sensitive, otherwise comparisons ignore
case.
If a unique match is made return the index of the element in ind
and return .true.
If the match is ambiguous set ind to 0, and return .false.
If no match is found set ind to -1 and return .false.
logical function inp_search(ocase, z)
character*(*) z
logical ocase
Position the input file at the next logical input line which has
a first input field that matches the leading non-blank characters
in z. If ocase is .true. then matches are case sensitive.
If such a line is found then return .true., and reset the current
input field to 0 (i.e., as if inp_read() had just been called).
If no such line is found return .false.. The file will be either
at EOF or at a line which was not successfully parsed. EOF may
be detected by inp_eof().
logical function inp_eof()
Return .true. if EOF has been detected, .false. otherwise.
subroutine inp_lcase(z)
character*(*) z
Lowercase the character string z
integer function inp_strlen(z)
character*(*) z
Return the index of the last non-blank character in z, 0 being
returned for a fully blank string.
subroutine inp_errout()
If there is an internal error message, print out its value,
the current line number and its contents. If appropriate
indicate the problematic position in the current input line.
subroutine inp_outrec()
Print out the current input line.

18
src/inp/inp.h Normal file
View file

@ -0,0 +1,18 @@
#ifndef _INP_H
#define _INP_H
int inp_i();
float inp_f();
char *inp_a();
int inp_n_field();
int inp_cur_field();
int inp_match();
int inp_read();
int inp_search();
int inp_compare();
int inp_strlen();
int inp_line();
int inp_eof();
int inp_a_trunc();
#endif

34
src/inp/inpP.h Normal file
View file

@ -0,0 +1,34 @@
#ifndef _INPP_H
#define _INPP_H
// Private header file for free format input routines
#include <stdbool.h>
#define MAX_WIDTH 256 // Maximum no. of characters in an input line
#define MAX_FIELD MAX_WIDTH/2 + 1 // Maximum no. of fields in an input line
char ja[256]; // Input buffers ... MUST match max_width
char tmp[256]; // Same size work space
char errmsg[80]; // Error message
char xcomm; // Comment character
char xsplit; // Character to split physical input lines
char xback; // Backslash for concatenation and quoting
char xquote; // Quotation marks for strings
char xblnk; // Space
char xtab; // Tab
int jrec; // No. of current field
int jump; // No. of fields in current line
int istrt[MAX_FIELD]; // Start of fields
int inumb[MAX_FIELD]; // Length of fields
int nstart[MAX_FIELD]; // Start of fields
int nend[MAX_FIELD]; // End of fields
int iwidth; // Length of current logical input line
int nline; // Current logical line inside physical line
int noline; // No. of logical lines inside physical line
int input_line; // No. of current physical input line
int nerr; // ????
bool oswit; // True if EOF has beeen detected
int ierrpos; // Input char position where error was detected
#endif // _INPP_H

36
src/inp/test.c Normal file
View file

@ -0,0 +1,36 @@
#include <stdio.h>
#include "inp.h"
void test() {
char aval[30];
int i, ival, line;
double dval;
line = 0;
inp_init(5, 6);
while (inp_read()) {
line = line + 1;
inp_outrec();
for (i = 1; i <= inp_n_field(); i++) {
if (inp_i(&ival)) {
printf("line=%d, field=%d, integer=%d\n", line, i, ival);
} else if (inp_f(&dval)) {
printf("line=%d, field=%d, double=%.2lf\n", line, i, dval);
} else if (inp_a(aval)) {
printf("line=%d, field=%d, string=%s\n", line, i, aval);
} else {
printf("line=%d, field=%d, error!\n", line, i);
inp_errout();
}
}
}
if (inp_eof()) {
printf("EOF detected at line %d\n", line);
} else {
printf("input failed at line %d\n", line);
}
inp_errout();
}

47
src/rtdb/GNUmakefile Normal file
View file

@ -0,0 +1,47 @@
# $Id: GNUmakefile,v 1.1.1.1 1994-03-29 06:44:27 d3g681 Exp $
include ../config/makefile.h
OBJ = rtdb_f2c.o rtdb.o rtdb_par.o rtdb_par_f2c.o \
context.o context_f2c.o
LIBRARY = librtdb.a
HEADERS = context.h rtdb.h rtdb.h context.h
LIB_TARGETS = test test.o rtdbtest rtdbtest.o interact context davetest \
context.o davetest.o interact.o rtdb_par_f2c.o \
cntx.o cntx
LIB_INCLUDES = -I../db
TEST_LIBS = $(LIBRARY) $(LIBS)
include ../config/makelib.h
davetest: davetest.o $(LIBRARY)
$(FC) $(FFLAGS) -o $@ davetest.o librtdb.a ../db/libdb.a ../util/libutil.a ../ma/libma.a
rtdb_par_f2c.c: rtdb_f2c.c
sed 's/rtdb_/rtdb_par_/g' rtdb_f2c.c > rtdb_par_f2c.c
cntx: cntx.o $(LIBRARY)
$(FC) $(FFLAGS) -o $@ cntx.o $(LIBS)
interact: interact.o $(LIBRARY)
$(CC) $(CFLAGS) -o $@ interact.o $(TEST_LIBS)
test: test.o $(LIBRARY)
$(FC) $(FFLAGS) -o $@ test.o $(TEST_LIBS)
rtdbtest: rtdbtest.o $(LIBRARY)
$(CC) $(CFLAGS) -o $@ rtdbtest.o $(TEST_LIBS)
rtdbpartest: rtdb_par_test.o $(LIBRARY)
$(CC) $(CFLAGS) -o $@ rtdb_par_test.o $(TEST_LIBS)
rtdb.o rtdbf2c.o rtdbtest.o: misc.h
rtdb.o rtdbf2c.o rtdbtest.o: rtdb.h
test.o: rtdb.h
context: context.o $(LIBRARY)
$(CC) $(CFLAGS) -o $@ context.o $(TEST_LIBS)

15
src/rtdb/context.h Normal file
View file

@ -0,0 +1,15 @@
#ifndef _CONTEXT_H
#define _CONTEXT_H
#include <stdbool.h>
bool context_set(const char *);
char *context_get(void);
bool context_rtdb_store(int);
bool context_rtdb_load(int);
bool context_push(const char *);
bool context_pop(const char *);
bool context_rtdb_match(int, const char *, int, char *);
bool context_prefix(const char *, char *, int);
#endif

154
src/rtdb/rtdb.h Normal file
View file

@ -0,0 +1,154 @@
#ifndef _RTDB_H
#define _RTDB_H
/*
All routines return TRUE (1) on success, FALSE (0) on failure.
int rtdb_open(const char *filename, const char *mode, int *handle)
Filename = path to file associated with the data base
mode = 'new' Open only if it does not exist already
'old', Open only if it does exist already
'unknown' Create new or open existing (preserving contents)
'empty' Create new or open existing (deleting contents)
'scratch' Create new or open existing (deleting contents)
and automatically delete upon closing. Also, items
cached in memory are not written to disk.
handle = returns handle by which all future references to the
data base are made
int rtdb_close(const int handle, const char *mode)
Close the data base
handle = handle to RTDB
mode = 'keep' Preserve the data base file to enable restart
'delete' Delete the data base file freeing all resources
mode is overridden by opening the data base with
mode='scratch' in which instance it is always deleted
upon closing
int rtdb_get_info(const int handle, const char *name, int *ma_type,
int *nelem, char date[26])
Get info about an entry from the data base
handle = handle to RTDB
name = entry name (null terminated character string)
ma_type = returns MA type of the entry
nelem = returns no. of elements of the given type
date = returns date of insertion (null terminated character string)
int rtdb_put(const int handle, const char *name, const int ma_type,
const int nelem, const void *array)
Insert an entry into the data base replacing previous entry
handle = handle to RTDB
name = entry name (null terminated character string)
ma_type = MA type of the entry
nelem = no. of elements of the given type
array = data to be inserted
int rtdb_get(const int handle, const char *name, const int ma_type,
const int nelem, void *array)
Get an entry from the data base
handle = handle to RTDB
name = entry name (null terminated character string)
ma_type = MA type of the entry which must match entry type
nelem = size of array in units of ma_type
array = user provided buffer that returns data
int rtdb_ma_get(const int handle, const char *name, int *ma_type,
int *nelem, int *ma_handle)
Get an entry from the data base returning an MA handle
handle = handle to RTDB
name = entry name (null terminated character string)
ma_type = returns MA type of the entry
nelem = returns no. of elements of type ma_type in data
ma_handle= returns MA handle to data
int rtdb_first(const int handle, const int namelen, char *name)
Return the name of the first (user inserted) entry in the data base.
The order is effectively random.
handle = handle to RTDB
namelen = size of user provided buffer name
name = name of entry is returned in this buffer
int rtdb_next(const int handle, const int namelen, char *name)
Return the name of the next (user inserted) entry in the data base.
The order is effectively random.
handle = handle to RTDB
namelen = size of user provided buffer name
name = name of entry is returned in this buffer
int rtdb_print(const int handle, const int print_values)
Print the contents of the data base to stdout
handle = handle to RTDB
print_values = boolean flag ... if true values as well as
keys are printed out.
int rtdb_delete(const int handle, const char *name)
Delete the entry from the database.
Return
1 if key was present and successfully deleted
0 if key was not present, or if an error occured
handle = handle to RTDB
name = name of entry to delete
*/
#include <stdio.h>
bool rtdb_open(const char *, const char *, FILE *);
bool rtdb_close(FILE *, const char *);
bool rtdb_put(const int, const char *, const int, const int, const void *);
bool rtdb_get(const int, const char *, const int, const int, void *);
bool rtdb_get_info(const int, const char *, int *, int *, char [26]);
bool rtdb_ma_get(const int, const char *, int *, int *, int *);
bool rtdb_first(const int, const int, char *);
bool rtdb_next(const int, const int, char *);
bool rtdb_print(const int, const int);
bool rtdb_delete(const int, const char *);
/*
Following are 'parallel' versions of the above where only
process 0 actually accesses the data base and all others
just get its output.
*/
bool rtdb_par_open(const char *, const char *, FILE *);
bool rtdb_par_close(FILE *, const char *);
bool rtdb_par_put(const int, const char *, const int, const int, const void *);
bool rtdb_par_get(const int, const char *, const int, const int, void *);
bool rtdb_par_get_info(const int, const char *, int *, int *, char [26]);
bool rtdb_par_ma_get(const int, const char *, int *, int *, int *);
bool rtdb_par_first(const int, const int, char *);
bool rtdb_par_next(const int, const int, char *);
bool rtdb_par_print(const int, const int);
bool rtdb_par_delete(const int, const char *);
#endif // _RTDB_H