10
1
mirror of https://gitlab.com/scemama/QCaml.git synced 2024-11-19 12:32:21 +01:00
QCaml/particles/nuclei.org
2021-01-01 11:52:08 +01:00

10 KiB

Nuclei

Type

open Common

type t = (Element.t * Coordinate.t) array

xyz file lexer/parser

Lexer

nuclei_lexer.mll contains the description of the lexemes used in an xyz file.

{
open Xyz_parser
}

let eol = ['\n']
let white = [' ' '\t']+
let word = [^' ' '\t' '\n']+
let letter = ['A'-'Z' 'a'-'z']
let integer = ['0'-'9']+
let real = '-'? (integer '.' integer | integer '.' | '.' integer) (['e' 'E'] ('+'|'-')? integer)?


rule read_all = parse
| eof            { EOF }
| eol            { EOL }
| white   as w   { SPACE w }
| integer as i   { INTEGER (int_of_string i) }
| real    as f   { FLOAT (float_of_string f) }
| word    as w   { WORD w }


{
(* DEBUG
let () =
let ic = open_in "h2o.xyz" in
let lexbuf = Lexing.from_channel ic in
while true do
 let s =
  match read_all lexbuf with
  | EOL -> "EOL"
  | SPACE w -> "SPACE("^w^")"
  | INTEGER i -> "INTEGER("^(string_of_int i)^")"
  | FLOAT f -> "FLOAT("^(string_of_float f)^")"
  | WORD w -> "WORD("^w^")"
  | EOF -> "EOF"
 in
 print_endline s
done;
*)
}

Parser

xyz_parser.mly parses nuclear coordinates in xyz format.

%{
open Common

let make_angstrom x y z =
Coordinate.(make_angstrom {
x ; y ; z
})

let output_of f x y z =
let a = make_angstrom x y z in
fun e ->
{
Xyz_ast.
element = f e;
coord = a ;
}

let output_of_string = output_of Element.of_string
let output_of_int    = output_of Element.of_int

%}

%token EOL
%token <string> SPACE
%token <string> WORD
%token <int> INTEGER
%token <float> FLOAT
%token EOF

%start input
%type <Xyz_ast.xyz_file> input

%% /* Grammar rules and actions follow */

input:
| integer title atoms_xyz {
  {
    number_of_atoms = $1;
    file_title = $2;
    nuclei = $3;
  }
}
;


integer:
| INTEGER EOL { $1 }
| INTEGER SPACE EOL { $1 }
| SPACE INTEGER EOL { $2 }
| SPACE INTEGER SPACE EOL { $2 }
;

title:
| title_list EOL { $1 }
;

text:
| WORD    { $1 }
| SPACE   { $1 }
| FLOAT   { (string_of_float $1)}
| INTEGER { (string_of_int $1)}
;

title_list:
| { "" }
| title_list text { ($1 ^ $2) }
;

atoms_xyz:
| atoms_list EOL { List.rev $1 }
| atoms_list EOF { List.rev $1 }
;

atoms_list:
| { [] }
| atoms_list WORD    SPACE FLOAT SPACE FLOAT SPACE FLOAT       EOL { output_of_string $4 $6 $8 $2 :: $1 }
| atoms_list WORD    SPACE FLOAT SPACE FLOAT SPACE FLOAT SPACE EOL { output_of_string $4 $6 $8 $2 :: $1 }
| atoms_list INTEGER SPACE FLOAT SPACE FLOAT SPACE FLOAT       EOL { output_of_int    $4 $6 $8 $2 :: $1 }
| atoms_list INTEGER SPACE FLOAT SPACE FLOAT SPACE FLOAT SPACE EOL { output_of_int    $4 $6 $8 $2 :: $1 }
| atoms_list SPACE WORD    SPACE FLOAT SPACE FLOAT SPACE FLOAT       EOL { output_of_string $5 $7 $9 $3 :: $1 }
| atoms_list SPACE WORD    SPACE FLOAT SPACE FLOAT SPACE FLOAT SPACE EOL { output_of_string $5 $7 $9 $3 :: $1 }
| atoms_list SPACE INTEGER SPACE FLOAT SPACE FLOAT SPACE FLOAT       EOL { output_of_int    $5 $7 $9 $3 :: $1 }
| atoms_list SPACE INTEGER SPACE FLOAT SPACE FLOAT SPACE FLOAT SPACE EOL { output_of_int    $5 $7 $9 $3 :: $1 }
;

When an xyz file is read by xyz_parser.mly, it is converted into an xyz_file data structure.

open Common

type nucleus =
{
element: Element.t ;
coord  : Coordinate.angstrom Coordinate.point;
}

type xyz_file =
{
number_of_atoms : int ;
file_title      : string ;
nuclei          : nucleus list ;
}

Conversion

val of_xyz_string : string -> t
val to_xyz_string  : t -> string
val of_xyz_file   : string -> t

val of_zmt_string : string -> t
val of_zmt_file   : string -> t

val to_string      : t -> string

val of_filename : string -> t
of_xyz_string Create from a string, in xyz format
of_xyz_file Create from a file, in xyz format
of_zmt_string Create from a string, in z-matrix format
of_zmt_file Create from a file, in z-matrix format
to_string Transform to a string, for printing
of_filename Detects the type of file (xyz, z-matrix) and reads the file

TODO Query

val formula    : t -> string
val repulsion  : t -> float
val charge     : t -> Charge.t
val small_core : t -> int
val large_core : t -> int
formula Returns the chemical formula
repulsion Nuclear repulsion energy, in atomic units
charge Sum of the charges of the nuclei
small_core Number of core electrons in the small core model
large_core Number of core electrons in the large core model

Printers

val pp : Format.formatter -> t -> unit

Tests