diff --git a/common/README.org b/common/README.org index 79df007..523426b 100644 --- a/common/README.org +++ b/common/README.org @@ -48,6 +48,7 @@ with open(dunetest,'w') as f: (synopsis "Test for {name} library") (libraries alcotest + unix qcaml.{name} ) ) @@ -61,6 +62,7 @@ with open(dunetest,'w') as f: str zarith getopt + unix ) #+end_src diff --git a/common/lib/dune b/common/lib/dune index 0885a04..36e3236 100644 --- a/common/lib/dune +++ b/common/lib/dune @@ -2,7 +2,7 @@ (library (name common) (public_name qcaml.common) - (synopsis + (synopsis "Utility functions used by all the other directories." ) (libraries @@ -10,8 +10,9 @@ zarith getopt camlp-streams + unix ) - + (c_names util ) diff --git a/common/lib/qcaml.ml b/common/lib/qcaml.ml index 65fda79..945977c 100644 --- a/common/lib/qcaml.ml +++ b/common/lib/qcaml.ml @@ -1,7 +1,8 @@ -(* | ~root~ | Path to the QCaml source directory | - * | ~name~ | ~"QCaml"~ | *) +(* | ~root~ | Path to the QCaml source directory | + * | ~name~ | ~"QCaml"~ | + * | ~num_domains~ | Number of threads in parallel computations | *) (* [[file:~/QCaml/common/qcaml.org::*QCaml][QCaml:2]] *) @@ -18,4 +19,14 @@ let root = |> chop |> List.rev |> String.concat Filename.dir_sep + + +let num_domains = + let result = + try + Unix.getenv "OMP_NUM_THREADS" + |> int_of_string + with Not_found -> 1 + in + result - 1 (* QCaml:2 ends here *) diff --git a/common/lib/qcaml.mli b/common/lib/qcaml.mli index 0ffcba3..0d21c3c 100644 --- a/common/lib/qcaml.mli +++ b/common/lib/qcaml.mli @@ -9,4 +9,5 @@ (* [[file:~/QCaml/common/qcaml.org::*QCaml][QCaml:1]] *) val root : string val name : string +val num_domains : int (* QCaml:1 ends here *) diff --git a/common/qcaml.org b/common/qcaml.org index 373ade3..a6a29a3 100644 --- a/common/qcaml.org +++ b/common/qcaml.org @@ -19,10 +19,12 @@ #+begin_src ocaml :tangle (eval mli) val root : string val name : string +val num_domains : int #+end_src - | ~root~ | Path to the QCaml source directory | - | ~name~ | ~"QCaml"~ | + | ~root~ | Path to the QCaml source directory | + | ~name~ | ~"QCaml"~ | + | ~num_domains~ | Number of threads in parallel computations | #+begin_src ocaml :tangle (eval ml) :exports none let name = "QCaml" @@ -40,5 +42,14 @@ let root = |> String.concat Filename.dir_sep +let num_domains = + let result = + try + Unix.getenv "OMP_NUM_THREADS" + |> int_of_string + with Not_found -> 1 + in + result - 1 + #+end_src diff --git a/docs/common.html b/docs/common.html index 880cc2f..dc6281b 100644 --- a/docs/common.html +++ b/docs/common.html @@ -3,7 +3,7 @@ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> - + Common @@ -272,143 +272,143 @@ org_html_manager.setup(); // activate after the parameters are set

Table of Contents

-
-

1 Summary

+
+

1 Summary

-
-

2 Angular Momentum

+
+

2 Angular Momentum

Azimuthal quantum number, repsesented as \( s,p,d,\dots \) .

-
-

2.1 Type

+
+

2.1 Type

-Angular_momentum.t +Angular_momentum.t

-
type t =
+
type t =
   | S | P | D | F | G | H | I | J | K | L | M | N | O
   | Int of int
 
@@ -424,7 +424,7 @@ Azimuthal quantum number, repsesented as \( s,p,d,\dots \) .
 

-An exception is raised when the Angular_momentum.t element can't +An exception is raised when the Angular_momentum.t element can't be created.

@@ -435,8 +435,8 @@ quartets, use in the two-electron operators.
-
-

2.2 Conversions

+
+

2.2 Conversions

val of_char : char -> t
@@ -460,7 +460,7 @@ quartets, use in the two-electron operators.
 
 
 of_char
-Returns an Angular_momentum.t when a shell is given as  a character (case insensitive)
+Returns an Angular_momentum.t when a shell is given as  a character (case insensitive)
 
 
 
@@ -488,7 +488,7 @@ quartets, use in the two-electron operators.
 

Example:

-
+
 Angular_momentum.of_char 'p';;
 - : Angular_momentum.t = P
 
@@ -507,8 +507,8 @@ Angular_momentum.(to_string D);;
 
-
-

2.3 Shell functions

+
+

2.3 Shell functions

val n_functions : t -> int
@@ -532,7 +532,7 @@ Angular_momentum.(to_string D);;
 
 
 zkey_array
-Array of Zkey.t, where each element is a a key associated with the the powers of \(x,y,z\).
+Array of Zkey.t, where each element is a a key associated with the the powers of \(x,y,z\).
 
 
 
@@ -540,7 +540,7 @@ Angular_momentum.(to_string D);;
 

Example:

-
+
 Angular_momentum.(n_functions D) ;;
 - : int = 6
 
@@ -553,8 +553,8 @@ Angular_momentum.( zkey_array (Doublet (P,S)) );;
 
-
-

2.4 Arithmetic

+
+

2.4 Arithmetic

val ( + ) : t -> t -> t
@@ -565,7 +565,7 @@ Angular_momentum.( zkey_array (Doublet (P,S)) );;
 

Example:

-
+
 Angular_momentum.(D + P);;
 - : Angular_momentum.t = F
 
@@ -575,8 +575,8 @@ Angular_momentum.(F - P);;
 
-
-

2.5 Printers

+
+

2.5 Printers

Printers can print as a string (default) or as an integer. @@ -591,12 +591,12 @@ Printers can print as a string (default) or as an integer.

-
-

2.6 TODO Tests

+
+

2.6 TODO Tests

-
-

3 Bit string

+
+

3 Bit string

We define here a data type to handle bit strings efficiently. When @@ -608,11 +608,11 @@ bit string as a multi-precision integer.

-
-

3.1 Type

+
+

3.1 Type

-Bitstring.t +Bitstring.t

type t
@@ -621,8 +621,8 @@ bit string as a multi-precision integer.
 
-
-

3.2 General implementation

+
+

3.2 General implementation

val of_int : int -> t
@@ -774,7 +774,7 @@ bit string as a multi-precision integer.
 

Example:

-
+
 Bitstring.of_int 15;;
 - : Bitstring.t =
 ++++------------------------------------------------------------
@@ -783,7 +783,7 @@ Bitstring.of_int 15;;
 

Example:

-
+
 Bitstring.(shift_left (of_int 15) 2);;
 - : Bitstring.t =
 --++++----------------------------------------------------------
@@ -806,7 +806,7 @@ Bitstring.(testbit (of_int 15) 4);;
 

Example:

-
+
 Bitstring.(logor (of_int 15) (of_int 73));;
 - : Bitstring.t =
 ++++--+---------------------------------------------------------
@@ -824,7 +824,7 @@ Bitstring.(logxor (of_int 15) (of_int 73));;
 

Example:

-
+
 Bitstring.(plus_one (of_int 15));;
 - : Bitstring.t =
 ----+-----------------------------------------------------------
@@ -838,7 +838,7 @@ Bitstring.(minus_one (of_int 15));;
 

Example:

-
+
 Bitstring.(trailing_zeros (of_int 12));;
 - : int = 2
 
@@ -852,7 +852,7 @@ Bitstring.(popcount (of_int 15));;
 

Example:

-
+
 Bitstring.(to_list (of_int 45));;
 - : int list = [1; 3; 4; 6]
 
@@ -860,7 +860,7 @@ Bitstring.(to_list (of_int 45));;

Example:

-
+
    Bitstring.permutations 2 4;;
 - : Bitstring.t list =
 [++--------------------------------------------------------------;
@@ -873,8 +873,8 @@ Example:
 
-
-

3.3 Printers

+
+

3.3 Printers

val pp : Format.formatter -> t -> unit
@@ -884,16 +884,16 @@ Example:
 
-
-

4 Charge

+
+

4 Charge

-
-

4.1 Type

+
+

4.1 Type

-Charge.t +Charge.t

type t
@@ -906,8 +906,8 @@ This type should be used for all charges in the program (electrons, nuclei, 
 
-
-

4.2 Conversions

+
+

4.2 Conversions

val of_float : float -> t
@@ -923,8 +923,8 @@ This type should be used for all charges in the program (electrons, nuclei, 
 
-
-

4.3 Simple operations

+
+

4.3 Simple operations

val ( + ) : t -> t -> t
@@ -937,8 +937,8 @@ This type should be used for all charges in the program (electrons, nuclei, 
 
-
-

4.4 Printers

+
+

4.4 Printers

val pp : Format.formatter -> t -> unit
@@ -948,8 +948,8 @@ This type should be used for all charges in the program (electrons, nuclei, 
 
-
-

5 Command line

+
+

5 Command line

This module is a wrapper around the Getopt library and helps to @@ -1005,11 +1005,11 @@ Then, define what to do with the arguments:

-
-

5.1 Types

+
+

5.1 Types

-
type short_opt     = char
+
type short_opt     = char
 type long_opt      = string
 type optional      = Mandatory | Optional
 type documentation = string
@@ -1029,9 +1029,9 @@ Then, define what to do with the arguments:
 
    -
  • Short option: in the command line, a dash with a single character +
  • Short option: in the command line, a dash with a single character (ex: ls -l)
  • -
  • Long option: in the command line, two dashes with a word +
  • Long option: in the command line, two dashes with a word (ex: ls --directory)
  • Command-line options can be Mandatory or Optional
  • Documentation of the option is used in the help function
  • @@ -1042,12 +1042,12 @@ don't (ls -l) and for some arguments the argument is optional
-
-

5.2 Mutable attributes

+
+

5.2 Mutable attributes

All the options are stored in the hash table dict where the key -is the long option and the value is a value of type description. +is the long option and the value is a value of type description.

@@ -1073,8 +1073,8 @@ Function to create an anonymous argument.
-
-

5.3 Query functions

+
+

5.3 Query functions

val get       : long_opt -> string option
@@ -1094,7 +1094,7 @@ Function to create an anonymous argument.
 
 
 get
-Returns the argument associated with a long option
+Returns the argument associated with a long option
 
 
 
@@ -1112,8 +1112,8 @@ Function to create an anonymous argument.
 
-
-

5.4 Specification

+
+

5.4 Specification

val set_specs : description list -> unit
@@ -1128,16 +1128,16 @@ Sets the specifications of the current program from a list of
 
-
-

6 Constants

+
+

6 Constants

All constants used in the program.

-
-

6.1 Thresholds

+
+

6.1 Thresholds

val epsilon          : float
@@ -1168,8 +1168,8 @@ All constants used in the program.
 
-
-

6.2 Mathematical constants

+
+

6.2 Mathematical constants

val pi             : float
@@ -1224,8 +1224,8 @@ All constants used in the program.
 
-
-

6.3 Physical constants

+
+

6.3 Physical constants

val a0       : float
@@ -1269,8 +1269,8 @@ All constants used in the program.
 
-
-

7 Coordinate

+
+

7 Coordinate

Coordinates in 3D space. @@ -1283,14 +1283,14 @@ module.

-
-

7.1 Type

+
+

7.1 Type

-Coordinate.t +Coordinate.t

-
type bohr 
+
type bohr 
 type angstrom 
 
 type xyz = {
@@ -1309,8 +1309,8 @@ module.
 
-
-

7.2 Creation

+
+

7.2 Creation

val make          : 'a point -> t
@@ -1347,8 +1347,8 @@ module.
 
-
-

7.3 Conversion

+
+

7.3 Conversion

val bohr_to_angstrom : bohr point -> angstrom point
@@ -1379,8 +1379,8 @@ module.
 
-
-

7.4 Vector operations

+
+

7.4 Vector operations

val neg    : t -> t
@@ -1442,7 +1442,7 @@ module.
 

Example:

-
+
 Coordinate.neg { x=1. ; y=2. ; z=3. } ;;
 - : Coordinate.t =  -1.0000  -2.0000  -3.0000
 
@@ -1468,8 +1468,8 @@ Coordinate.(
 
-
-

7.5 Printers

+
+

7.5 Printers

val pp : Format.formatter -> t -> unit
@@ -1485,16 +1485,16 @@ Coordinates can be printed in bohr or angstrom.
 
-
-

8 Non-negative float

+
+

8 Non-negative float

-
-

8.1 Type

+
+

8.1 Type

-< +<

type t = private float
@@ -1503,8 +1503,8 @@ Coordinates can be printed in bohr or angstrom.
 
-
-

8.2 Conversions

+
+

8.2 Conversions

val of_float        : float -> t
@@ -1524,19 +1524,19 @@ The unsafe variant doesn't do this check.
 
-
-

9 Powers

+
+

9 Powers

Contains powers of \(x\), \(y\) and \(z\) describing the polynomials in atomic basis sets.

-
-

9.1 Type

+
+

9.1 Type

-Powers.t +Powers.t

type t = private {
@@ -1554,8 +1554,8 @@ Contains powers of \(x\), \(y\) and \(z\) describing the polynomials in atomic b
 
-
-

9.2 Conversions

+
+

9.2 Conversions

val of_int_tuple : int * int * int -> t
@@ -1566,7 +1566,7 @@ Contains powers of \(x\), \(y\) and \(z\) describing the polynomials in atomic b
 

Example:

-
+
 Powers.of_int_tuple (2,3,1);;
 - : Powers.t = x^2 + y^3 + z^1
 
@@ -1576,8 +1576,8 @@ Powers.(to_int_tuple (of_int_tuple (2,3,1)));;
 
-
-

9.3 Operations

+
+

9.3 Operations

val get  : Coordinate.axis -> t -> int
@@ -1602,12 +1602,12 @@ Powers.(to_int_tuple (of_int_tuple (2,3,1)));;
 
 
 incr
-Returns a new Powers.t with the power on the given axis incremented
+Returns a new Powers.t with the power on the given axis incremented
 
 
 
 decr
-Returns a new Powers.t with the power on the given axis decremented. As opposed to of_int_tuple, the values may become negative
+Returns a new Powers.t with the power on the given axis decremented. As opposed to of_int_tuple, the values may become negative
 
 
 
@@ -1615,7 +1615,7 @@ Powers.(to_int_tuple (of_int_tuple (2,3,1)));;
 

Example:

-
+
 Powers.get Coordinate.Y (Powers.of_int_tuple (2,3,1));;
 - : int = 3
 
@@ -1629,8 +1629,8 @@ Powers.decr Coordinate.Y (Powers.of_int_tuple (2,3,1));;
 
-
-

9.4 Printers

+
+

9.4 Printers

val pp : Format.formatter -> t -> unit
@@ -1640,8 +1640,8 @@ Powers.decr Coordinate.Y (Powers.of_int_tuple (2,3,1));;
 
-
-

10 QCaml

+
+

10 QCaml

QCaml-specific parameters @@ -1650,6 +1650,7 @@ QCaml-specific parameters

val root : string
 val name : string
+val num_domains : int
 
@@ -1671,13 +1672,18 @@ QCaml-specific parameters name "QCaml" + + +num_domains +Number of threads in parallel computations +
-
-

11 Range

+
+

11 Range

A range is a sorted list of integers in an interval. @@ -1692,11 +1698,11 @@ A range is a sorted list of integers in an interval.

-
-

11.1 Type

+
+

11.1 Type

-Range.t +Range.t

type t
@@ -1705,8 +1711,8 @@ A range is a sorted list of integers in an interval.
 
-
-

11.2 Conversion

+
+

11.2 Conversion

val of_string   : string -> t
@@ -1717,8 +1723,8 @@ A range is a sorted list of integers in an interval.
 
-
-

11.3 Printers

+
+

11.3 Printers

val pp : Format.formatter -> t -> unit
@@ -1728,19 +1734,19 @@ A range is a sorted list of integers in an interval.
 
-
-

12 Spin

+
+

12 Spin

Electron spin

-
-

12.1 Type

+
+

12.1 Type

-Spin.t +Spin.t

type t = Alfa | Beta
@@ -1755,8 +1761,8 @@ letters as Beta, so the alignment of the code is nicer.
 
-
-

12.2 Functions

+
+

12.2 Functions

val other : t -> t
@@ -1769,8 +1775,8 @@ Returns the opposite spin
 
-
-

12.3 Printers

+
+

12.3 Printers

val pp : Format.formatter -> t -> unit
@@ -1780,8 +1786,8 @@ Returns the opposite spin
 
-
-

13 Util

+
+

13 Util

Utility functions. @@ -1789,8 +1795,8 @@ Utility functions.

-
-

13.1 External C functions

+
+

13.1 External C functions

@@ -1834,8 +1840,8 @@ Utility functions.
-
-

13.1.1 Erf

+
+

13.1.1 Erf

external erf_float : float -> float
@@ -1845,8 +1851,8 @@ Utility functions.
 
-
-

13.1.2 Erfc

+
+

13.1.2 Erfc

external erfc_float : float -> float
@@ -1856,8 +1862,8 @@ Utility functions.
 
-
-

13.1.3 Gamma

+
+

13.1.3 Gamma

external gamma_float : float -> float
@@ -1867,8 +1873,8 @@ Utility functions.
 
-
-

13.1.4 Popcnt

+
+

13.1.4 Popcnt

val popcnt : int64 -> int
@@ -1877,8 +1883,8 @@ Utility functions.
 
-
-

13.1.5 Trailz

+
+

13.1.5 Trailz

val trailz : int64 -> int
@@ -1887,8 +1893,8 @@ Utility functions.
 
-
-

13.1.6 Leadz

+
+

13.1.6 Leadz

val leadz : int64 -> int
@@ -1897,13 +1903,13 @@ Utility functions.
 
-
-

13.1.7 Test

+
+

13.1.7 Test

-
-

13.2 General functions

+
+

13.2 General functions

val fact : int -> float
@@ -1976,8 +1982,8 @@ Utility functions.
 
-
-

13.3 Functions related to the Boys function

+
+

13.3 Functions related to the Boys function

val incomplete_gamma : alpha:float -> float -> float
@@ -2034,8 +2040,8 @@ where \(\gamma\) is the incomplete gamma function.
 
-
-

13.4 List functions

+
+

13.4 List functions

val list_some  : 'a option list -> 'a list
@@ -2072,8 +2078,8 @@ where \(\gamma\) is the incomplete gamma function.
 
-
-

13.5 Array functions

+
+

13.5 Array functions

val array_range   : int -> int -> int array
@@ -2110,8 +2116,8 @@ where \(\gamma\) is the incomplete gamma function.
 
-
-

13.6 Seq functions

+
+

13.6 Seq functions

val seq_range   : int -> int -> int Seq.t
@@ -2148,8 +2154,8 @@ where \(\gamma\) is the incomplete gamma function.
 
-
-

13.7 Printers

+
+

13.7 Printers

val pp_float_array_size   : Format.formatter -> float array -> unit
@@ -2199,7 +2205,7 @@ where \(\gamma\) is the incomplete gamma function.
 

Example:

-
+
 pp_float_array_size:
 [ 6:   1.000000   1.732051   1.732051   1.000000   1.732051   1.000000 ]
 
@@ -2222,8 +2228,8 @@ pp_bitstring 14:
 
-
-

14 Zkey

+
+

14 Zkey

Encodes the powers of x, y, z in a compact form, suitable for being @@ -2231,7 +2237,7 @@ used as keys in a hash table.

-Internally, the Zkey.t is made of two integers, left and right. +Internally, the Zkey.t is made of two integers, left and right. The small integers x, y and z are stored compactly in this 126-bits space:

@@ -2239,7 +2245,7 @@ space:

Example:

-
+
                                 Left                                                                Right
  3 [--------------------------------------------------------------]       [------------------|---------------|---------------|---------------]
                                                                                                      x               y               z        
@@ -2260,11 +2266,11 @@ The values of x,y,z should be positive and should not exceed 32767 for
 

-
-

14.1 Types

+
+

14.1 Types

-Zkey.t +Zkey.t

type t 
@@ -2280,8 +2286,8 @@ The values of x,y,z should be positive and should not exceed 32767 for
 
-
-

14.2 Conversions

+
+

14.2 Conversions

val of_powers_three  : Powers.t -> t
@@ -2308,22 +2314,22 @@ The values of x,y,z should be positive and should not exceed 32767 for
 
 
 of_powers_three
-Create from a Powers.t
+Create from a Powers.t
 
 
 
 of_powers_six
-Create from two Powers.t
+Create from two Powers.t
 
 
 
 of_powers_nine
-Create from three Powers.t
+Create from three Powers.t
 
 
 
 of_powers_twelve
-Create from four Powers.t
+Create from four Powers.t
 
 
 
@@ -2348,7 +2354,7 @@ The values of x,y,z should be positive and should not exceed 32767 for
 
 
 to_powers
-Convert to an Powers.t array
+Convert to an Powers.t array
 
 
 
@@ -2360,8 +2366,8 @@ The values of x,y,z should be positive and should not exceed 32767 for
 
-
-

14.3 Functions for hash tables

+
+

14.3 Functions for hash tables

val hash    : t -> int
@@ -2398,8 +2404,8 @@ The values of x,y,z should be positive and should not exceed 32767 for
 
-
-

14.4 Printers

+
+

14.4 Printers

val pp : Format.formatter -> t -> unit
@@ -2409,19 +2415,19 @@ The values of x,y,z should be positive and should not exceed 32767 for
 
-
-

15 Zmap

+
+

15 Zmap

A hash table where the keys are Zkey

-
-

15.1 Type

+
+

15.1 Type

-Zmap.t +Zmap.t

include module type of Hashtbl.Make(Zkey)
@@ -2433,7 +2439,7 @@ A hash table where the keys are Zkey
 

Author: Anthony Scemama

-

Created: 2023-04-20 Thu 11:51

+

Created: 2023-06-16 Fri 18:16

Validate

diff --git a/docs/gaussian.html b/docs/gaussian.html index 350d18b..0164554 100644 --- a/docs/gaussian.html +++ b/docs/gaussian.html @@ -3,7 +3,7 @@ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> - + Gaussian @@ -272,41 +272,41 @@ org_html_manager.setup(); // activate after the parameters are set

Table of Contents

-
-

1 Summary

+
+

1 Summary

-
-

2 Atomic shell

+
+

2 Atomic shell

Set of contracted Gaussians differing only by the powers of \(x\), \(y\) and \(z\), with a @@ -339,8 +339,8 @@ particular powers of \(x,y,z\) (PrimitiveShell.norm_coef_scale) -

-

2.1 Type

+
+

2.1 Type

type t
@@ -351,8 +351,8 @@ particular powers of \(x,y,z\) (PrimitiveShell.norm_coef_scale)
 
-
-

2.2 Access

+
+

2.2 Access

val ang_mom           : t -> Angular_momentum.t
@@ -429,14 +429,14 @@ particular powers of \(x,y,z\) (PrimitiveShell.norm_coef_scale)
 
 
-
+
 
 
-
-

2.3 Creation

+
+

2.3 Creation

val make : ?index:int -> Contracted_shell.t array -> t 
@@ -468,8 +468,8 @@ particular powers of \(x,y,z\) (PrimitiveShell.norm_coef_scale)
 
-
-

2.4 Printers

+
+

2.4 Printers

val pp : Format.formatter -> t -> unit
@@ -479,8 +479,8 @@ particular powers of \(x,y,z\) (PrimitiveShell.norm_coef_scale)
 
-
-

3 Atomic shell pair couple

+
+

3 Atomic shell pair couple

An atomic shell pair couple is the cartesian product between two sets of functions, one @@ -496,8 +496,8 @@ acting on different electrons, since they will be coupled by a two-electron oper

-
-

3.1 Type

+
+

3.1 Type

type t
@@ -508,8 +508,8 @@ acting on different electrons, since they will be coupled by a two-electron oper
 
-
-

3.2 Access

+
+

3.2 Access

val ang_mom                       : t -> Angular_momentum.t
@@ -594,8 +594,8 @@ acting on different electrons, since they will be coupled by a two-electron oper
 
-
-

3.3 Creation

+
+

3.3 Creation

val make : ?cutoff:float -> Atomic_shell_pair.t -> Atomic_shell_pair.t -> t option
@@ -621,14 +621,14 @@ Default cutoff is \(\epsilon\).
 
 
 
-
+
 
 
-
-

3.4 Printers

+
+

3.4 Printers

val pp : Format.formatter -> t -> unit
@@ -638,8 +638,8 @@ Default cutoff is \(\epsilon\).
 
-
-

4 Atomic shell pair

+
+

4 Atomic shell pair

Data structure to represent pairs of atomic shells. The products of @@ -651,8 +651,8 @@ An atomic shell pair is an array of pairs of contracted shells.

-
-

4.1 Type

+
+

4.1 Type

type t
@@ -663,8 +663,8 @@ An atomic shell pair is an array of pairs of contracted shells.
 
-
-

4.2 Access

+
+

4.2 Access

val atomic_shell_a         : t -> Atomic_shell.t
@@ -731,8 +731,8 @@ An atomic shell pair is an array of pairs of contracted shells.
 
-
-

4.3 Creation

+
+

4.3 Creation

val make : ?cutoff:float -> Atomic_shell.t -> Atomic_shell.t -> t option
@@ -765,8 +765,8 @@ If an atomic shell pair is not significant, sets the value to None.
 
-
-

4.4 Printers

+
+

4.4 Printers

val pp : Format.formatter -> t -> unit
@@ -778,7 +778,7 @@ If an atomic shell pair is not significant, sets the value to None.
 

Author: Anthony Scemama

-

Created: 2023-04-24 Mon 19:28

+

Created: 2023-06-16 Fri 09:49

Validate

diff --git a/docs/gaussian_integrals.html b/docs/gaussian_integrals.html index d518fd2..f6f56eb 100644 --- a/docs/gaussian_integrals.html +++ b/docs/gaussian_integrals.html @@ -3,7 +3,7 @@ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> - + Gaussian integrals @@ -250,18 +250,18 @@ org_html_manager.setup(); // activate after the parameters are set

Table of Contents

-
-

1 Summary

+
+

1 Summary

Author: Anthony Scemama

-

Created: 2023-04-24 Mon 13:50

+

Created: 2023-06-16 Fri 18:25

Validate

diff --git a/docs/linear_algebra.html b/docs/linear_algebra.html index 55b780a..bae5831 100644 --- a/docs/linear_algebra.html +++ b/docs/linear_algebra.html @@ -3,7 +3,7 @@ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> - + Linear Algebra @@ -250,18 +250,18 @@ org_html_manager.setup(); // activate after the parameters are set

Table of Contents

-
-

1 Summary

+
+

1 Summary

Author: Anthony Scemama

-

Created: 2022-12-13 Tue 10:55

+

Created: 2023-05-26 Fri 15:34

Validate

diff --git a/docs/top.html b/docs/top.html index bdfa85a..ffc3359 100644 --- a/docs/top.html +++ b/docs/top.html @@ -3,7 +3,7 @@ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> - + Top-level @@ -250,18 +250,18 @@ org_html_manager.setup(); // activate after the parameters are set

Table of Contents

-
-

1 Summary

+
+

1 Summary

Author: Anthony Scemama

-

Created: 2023-04-24 Mon 19:28

+

Created: 2023-06-16 Fri 18:25

Validate

diff --git a/dune-project b/dune-project index 87191c8..d33f31a 100644 --- a/dune-project +++ b/dune-project @@ -25,7 +25,7 @@ QCaml provides a programming framewrok work wave function methods in quantum chemistry.") (depends - (ocaml (>= 4.10)) + (ocaml (>= 5.0)) (dune (>= 1.10)) (camlp-streams (>= 5.0)) trexio @@ -33,6 +33,7 @@ in quantum chemistry.") getopt zarith alcotest + domainslib ) ) diff --git a/examples/ex_hartree_fock.ml b/examples/ex_hartree_fock.ml index 4156e41..ad4088f 100644 --- a/examples/ex_hartree_fock.ml +++ b/examples/ex_hartree_fock.ml @@ -1,11 +1,11 @@ -(* [[file:~/QCaml/examples/ex_hartree_fock.org::*Header][Header:1]] *) +(* [[file:ex_hartree_fock.org::*Header][Header:1]] *) module Command_line = Qcaml.Common.Command_line module Util = Qcaml.Common.Util let () = (* Header:1 ends here *) -(* [[file:~/QCaml/examples/ex_hartree_fock.org::*Definition][Definition:1]] *) +(* [[file:ex_hartree_fock.org::*Definition][Definition:1]] *) let open Command_line in begin set_header_doc (Sys.argv.(0)); @@ -31,7 +31,7 @@ begin end; (* Definition:1 ends here *) -(* [[file:~/QCaml/examples/ex_hartree_fock.org::*Interpretation][Interpretation:1]] *) +(* [[file:ex_hartree_fock.org::*Interpretation][Interpretation:1]] *) let basis_file = Util.of_some @@ Command_line.get "basis" in let nuclei_file = Util.of_some @@ Command_line.get "xyz" in @@ -51,26 +51,26 @@ let multiplicity = in (* Interpretation:1 ends here *) -(* [[file:~/QCaml/examples/ex_hartree_fock.org::*Computation][Computation:1]] *) +(* [[file:ex_hartree_fock.org::*Computation][Computation:1]] *) let nuclei = Qcaml.Particles.Nuclei.of_xyz_file nuclei_file in (* Computation:1 ends here *) -(* [[file:~/QCaml/examples/ex_hartree_fock.org::*Computation][Computation:2]] *) +(* [[file:ex_hartree_fock.org::*Computation][Computation:2]] *) let ao_basis = Qcaml.Ao.Basis.of_nuclei_and_basis_filename ~nuclei basis_file in (* Computation:2 ends here *) -(* [[file:~/QCaml/examples/ex_hartree_fock.org::*Computation][Computation:3]] *) -let simulation = Qcaml.Simulation.make ~charge ~multiplicity ~nuclei ao_basis in +(* [[file:ex_hartree_fock.org::*Computation][Computation:3]] *) +let simulation = Qcaml.Simulation.make ~multiplicity ~charge ~nuclei ao_basis in (* Computation:3 ends here *) -(* [[file:~/QCaml/examples/ex_hartree_fock.org::*Computation][Computation:4]] *) +(* [[file:ex_hartree_fock.org::*Computation][Computation:4]] *) let hf = Qcaml.Mo.Hartree_fock.make ~guess:`Huckel simulation in (* Computation:4 ends here *) -(* [[file:~/QCaml/examples/ex_hartree_fock.org::*Output][Output:1]] *) +(* [[file:ex_hartree_fock.org::*Output][Output:1]] *) Format.printf "@[%a@]" (Mo.Hartree_fock.pp) hf (* Output:1 ends here *) diff --git a/examples/ex_hartree_fock.org b/examples/ex_hartree_fock.org index d6fea84..4aae18c 100644 --- a/examples/ex_hartree_fock.org +++ b/examples/ex_hartree_fock.org @@ -75,14 +75,16 @@ in #+END_SRC * Computation + We first read the =xyz= file to create a molecule: + #+BEGIN_SRC ocaml :comments link :exports code :tangle ex_hartree_fock.ml let nuclei = Qcaml.Particles.Nuclei.of_xyz_file nuclei_file in #+END_SRC - Then we create an Gaussian AO basis using the atomic coordinates: + Then we create a Gaussian AO basis using the atomic coordinates: #+BEGIN_SRC ocaml :comments link :exports code :tangle ex_hartree_fock.ml let ao_basis = Qcaml.Ao.Basis.of_nuclei_and_basis_filename ~nuclei basis_file @@ -91,7 +93,7 @@ in We create a simulation from the nuclei and the basis set: #+BEGIN_SRC ocaml :comments link :exports code :tangle ex_hartree_fock.ml -let simulation = Qcaml.Simulation.make ~nuclei ao_basis in +let simulation = Qcaml.Simulation.make ~multiplicity ~charge ~nuclei ao_basis in #+END_SRC and we can make the Hartree-Fock computation: diff --git a/gaussian/lib/basis.ml b/gaussian/lib/basis.ml index 9df7650..f5265fd 100644 --- a/gaussian/lib/basis.ml +++ b/gaussian/lib/basis.ml @@ -107,13 +107,6 @@ let of_nuclei_and_basis_filenames ~nuclei filenames = let of_trexio f = let nuclei = Particles.Nuclei.of_trexio f in - (* - let nucl_num = Array.length nuclei in - let prim_num = Trexio.read_basis_prim_num f in - let shell_num = Trexio.read_basis_shell_num f in - let shell_factor = Trexio.read_basis_shell_factor f in - let prim_factor = Trexio.read_basis_prim_factor f in - *) let shell_ang_mom = Trexio.read_basis_shell_ang_mom f |> Array.map Common.Angular_momentum.of_int in @@ -137,7 +130,7 @@ let of_trexio f = | Some x -> x | None -> assert false) in - + let index_ = ref 0 in let contracted_shells = Array.mapi (fun i (_,center) -> @@ -180,9 +173,24 @@ let of_trexio f = { contracted_shells ; atomic_shells ; size = !index_; general_basis = []; } - -let to_trexio _ _ = + +let to_trexio _f _t = + failwith "Not implemented" + (* + Trexio.write_basis_type f "Gaussian" ; + Trexio.write_basis_shell_num f t.size; + let prim_num = + Array.fold_left (fun accu i -> accu + Array.length i) 0 t.contracted_shells + in + Trexio.read_basis_prim_num f prim_num; + let nucleus_index = + Array.map + in + let shell_factor = Trexio.read_basis_shell_factor f in + let prim_factor = + Trexio.read_basis_prim_factor f in () + *) let pp ppf t = Format.fprintf ppf "@[%s@]" (to_string t) diff --git a/gaussian_integrals/README.org b/gaussian_integrals/README.org index 68f2d74..49fdcc8 100644 --- a/gaussian_integrals/README.org +++ b/gaussian_integrals/README.org @@ -50,6 +50,7 @@ with open(dunetest,'w') as f: alcotest unix trexio + domainslib qcaml.{name} ) ) diff --git a/gaussian_integrals/lib/dune b/gaussian_integrals/lib/dune index 9306193..b1b65b5 100644 --- a/gaussian_integrals/lib/dune +++ b/gaussian_integrals/lib/dune @@ -2,7 +2,7 @@ (library (name gaussian_integrals) (public_name qcaml.gaussian_integrals) - (synopsis + (synopsis "Integrals on the Gaussian basis sets" ) (libraries @@ -11,8 +11,9 @@ qcaml.gaussian qcaml.operators unix + domainslib ) (modules_without_implementation matrix_on_basis) - + ) diff --git a/gaussian_integrals/lib/two_electron_integrals.ml b/gaussian_integrals/lib/two_electron_integrals.ml index 6551d47..f4f563c 100644 --- a/gaussian_integrals/lib/two_electron_integrals.ml +++ b/gaussian_integrals/lib/two_electron_integrals.ml @@ -1,6 +1,7 @@ (** Two electron integrals *) + open Common open Linear_algebra open Gaussian @@ -9,11 +10,12 @@ open Operators open Constants let cutoff = integrals_cutoff -module Bs = Basis -module Cs = Contracted_shell -module Csp = Contracted_shell_pair +module Bs = Basis +module Cs = Contracted_shell +module Csp = Contracted_shell_pair module Cspc = Contracted_shell_pair_couple -module Fis = Four_idx_storage +module Fis = Four_idx_storage + module type Two_ei_structure = sig @@ -23,15 +25,16 @@ module type Two_ei_structure = end + module Make(T : Two_ei_structure) = struct include Four_idx_storage type t = Basis.t Four_idx_storage.t - let class_of_contracted_shell_pair_couple = T.class_of_contracted_shell_pair_couple + let class_of_contracted_shell_pair_couple = T.class_of_contracted_shell_pair_couple - let store_class ?(cutoff=integrals_cutoff) data contracted_shell_pair_couple cls = - let to_powers x = + let store_class ?(cutoff=integrals_cutoff) data contracted_shell_pair_couple cls = + let to_powers x = let open Zkey in match to_powers x with | Three x -> x @@ -49,7 +52,7 @@ module Make(T : Two_ei_structure) = struct let j_c = Cs.index (Csp.shell_b shell_p) + j_c + 1 in let xj = to_powers powers_j in Array.iteri (fun k_c powers_k -> - let k_c = Cs.index (Csp.shell_a shell_q) + k_c + 1 in + let k_c = Cs.index (Csp.shell_a shell_q) + k_c + 1 in let xk = to_powers powers_k in Array.iteri (fun l_c powers_l -> let l_c = Cs.index (Csp.shell_b shell_q) + l_c + 1 in @@ -69,13 +72,13 @@ module Make(T : Two_ei_structure) = struct - let of_basis ?operator basis = + let of_basis ?operator basis = let n = Bs.size basis and shell = Bs.contracted_shells basis in - let eri_array = + let eri_array = Fis.create ~size:n `Dense (* Fis.create ~size:n `Sparse @@ -92,19 +95,11 @@ module Make(T : Two_ei_structure) = struct Printf.printf "%d significant shell pairs computed in %f seconds\n" (List.length shell_pairs) (Unix.gettimeofday () -. t0); - let ishell = ref max_int in - - - let t0 = Unix.gettimeofday () in let f shell_p = - let () = -(* - if Parallel.rank < 2 && Cs.index (Csp.shell_a shell_p) < !ishell then -*) - if Cs.index (Csp.shell_a shell_p) < !ishell then - (ishell := Cs.index (Csp.shell_a shell_p) ; print_int !ishell ; print_newline ()) + let () = + Printf.printf "%3d %3d\n%!" (Cs.index (Csp.shell_a shell_p)) (Cs.index (Csp.shell_b shell_p)) in let sp = @@ -113,13 +108,13 @@ module Make(T : Two_ei_structure) = struct try List.iter (fun shell_q -> - let () = + let () = if Cs.index (Csp.shell_a shell_q) > Cs.index (Csp.shell_a shell_p) then raise Exit in let sq = Csp.shell_pairs shell_q in - let cspc = + let cspc = if Array.length sp < Array.length sq then Cspc.make ~cutoff shell_p shell_q else @@ -137,15 +132,19 @@ module Make(T : Two_ei_structure) = struct with Exit -> () in - (* - List.rev shell_pairs - *) - shell_pairs - (* - |> Parallel.list_iter f ; - *) - |> List.iter f; - Printf.printf "Computed %s Integrals in parallel in %f seconds\n%!" + + + let pool = Domainslib.Task.setup_pool ~num_domains:Qcaml.num_domains () in + let _ = + Domainslib.Task.run pool (fun _ -> + shell_pairs + |> List.map (fun sp -> + Domainslib.Task.async pool (fun _ -> f sp) ) + |> List.iter (fun task -> ignore (Domainslib.Task.await pool task) ) ; + ) + in + Domainslib.Task.teardown_pool pool; + Printf.printf "Computed %s Integrals in %f seconds\n%!" T.name (Unix.gettimeofday () -. t0); eri_array diff --git a/linear_algebra/lib/cholesky.ml b/linear_algebra/lib/cholesky.ml new file mode 100644 index 0000000..565c54a --- /dev/null +++ b/linear_algebra/lib/cholesky.ml @@ -0,0 +1,229 @@ +open Lacaml.D + +let full_ldl m_A = + + let n = Mat.dim1 m_A in + assert (Mat.dim2 m_A = n); + + let v_D = Vec.make0 n in + let m_Lt = Mat.identity n in + + let v_D_inv = Vec.make0 n in + + let compute_d j = + let l_jk = + Mat.col m_Lt j + in + let l_jk__d_k = + Vec.mul ~n:(j-1) l_jk v_D + in + m_A.{j,j} -. dot ~n:(j-1) l_jk l_jk__d_k + in + + let compute_l i = + let l_ik__d_k = + Mat.col m_Lt i + |> Vec.mul ~n:(i-1) v_D + in + fun j -> + assert (i > j); + let l_jk = + Mat.col m_Lt j + in + v_D_inv.{j} *. ( m_A.{j,i} -. dot ~n:(j-1) l_ik__d_k l_jk ) + in + + for i=1 to n do + for j=1 to (i-1) do + m_Lt.{j,i} <- compute_l i j; + done; + let d_i = compute_d i in + v_D.{i} <- d_i; + v_D_inv.{i} <- 1. /. d_i; + done; + m_Lt, v_D + + + + +let pivoted_ldl threshold m_A = +(* {% $P A P^\dagger = L D L^\dagger$. %} + Input : Matrix $A$ + Output : Matrices $L, D, P$. +*) + + let n = Mat.dim1 m_A in + assert (Mat.dim2 m_A = n); + + let pi = Array.init (n+1) (fun i -> i) in + + let v_D = Vec.init n (fun i -> abs_float m_A.{i,i}) in + let m_Lt = Mat.identity n in + + let v_D_inv = Vec.make0 n in + + let compute_d i = + let l_ik = + Mat.col m_Lt i + in + let l_ik__d_k = + Vec.mul ~n:(i-1) l_ik v_D + in + m_A.{pi.(i),pi.(i)} -. dot ~n:(i-1) l_ik l_ik__d_k + in + + let compute_l i = + let l_ik__d_k = + Mat.col m_Lt i + |> Vec.mul ~n:(i-1) v_D + in + fun j -> + assert (i > j); + let l_jk = + Mat.col m_Lt j + in + v_D_inv.{j} *. ( m_A.{pi.(j),pi.(i)} -. dot ~n:(j-1) l_ik__d_k l_jk ) + in + + let maxloc v i = + let rec aux pos value i = + if i > n then + pos + else if v_D.{i} > value then + aux i v_D.{i} (i+1) + else + aux pos value (i+1) + in + aux i v.{i} (i+1) + in + + + let pivot i = + let j = maxloc v_D i in + let p_i, p_j = pi.(i), pi.(j) in + pi.(i) <- p_j; + pi.(j) <- p_i; + in + + + let () = + try + for i=1 to n do + pivot i; + for j=1 to (i-1) do + m_Lt.{j,i} <- compute_l i j; + done; + let d_i = compute_d i in + if abs_float d_i < threshold then + raise Exit; + v_D.{i} <- d_i; + v_D_inv.{i} <- 1. /. d_i; + done + with Exit -> () + in + m_Lt, v_D, pi + + + + + + + + + +(* +let test_case () = + + let matrix_diff m_A m_B = + Mat.syrk_trace (Mat.sub m_A m_B) + in + + let vector_diff v_A v_B = + let v = Vec.sub v_A v_B in + dot v v + in + + let m_A = Mat.random 1000 1000 in + let m_A = Mat.add m_A (Mat.transpose_copy m_A) in + + let test_full_small () = + let m_A = + Mat.of_array [| [| 4. ; 12. ; -16. |] ; + [| 12. ; 37. ; -43. |] ; + [| -16. ; -43. ; 98. |] |] + in + + let m_L_ref = + Mat.of_array [| [| 1. ; 0. ; 0. |] ; + [| 3. ; 1. ; 0. |] ; + [| -4. ; 5. ; 1. |] |] + in + + let m_Lt_ref = + Mat.transpose_copy m_L_ref + in + + let v_D_ref = + Vec.of_array [| 4. ; 1. ; 9. |] + in + + let m_Lt, v_D = full_ldl m_A in + Alcotest.(check (float 1.e-15)) "full L" 0. (matrix_diff m_Lt m_Lt_ref); + Alcotest.(check (float 1.e-15)) "full D" 0. (vector_diff v_D v_D_ref); + let m_D = Mat.of_diag v_D in + let m_B = gemm ~transa:`T m_Lt @@ gemm m_D m_Lt in + Alcotest.(check (float 1.e-15)) "full L" 0. (matrix_diff m_A m_B); + () + in + + let test_full () = + let m_Lt, v_D = full_ldl m_A in + let m_D = Mat.of_diag v_D in + let m_B = gemm ~transa:`T m_Lt @@ gemm m_D m_Lt in + Alcotest.(check (float 1.e-15)) "full D" 0. (matrix_diff m_A m_B); + () + in + + let test_pivoted () = + let m_Lt, v_D, pi = pivoted_ldl 0. m_A in + let n = Mat.dim1 m_A in + let m_P = Mat.make0 n n in + for i=1 to n do + m_P.{i,pi.(i)} <- 1. + done; + let m_D = Mat.of_diag v_D in + let m_B = + gemm ~transa:`T m_P @@ + gemm ~transa:`T m_Lt @@ + gemm m_D @@ + gemm m_Lt m_P + in + Alcotest.(check (float 1.e-14)) "pivoted D" 0. (matrix_diff m_A m_B); + () + in + + let test_truncated () = + let m_Lt, v_D, pi = pivoted_ldl 0.001 m_A in + let n = Mat.dim1 m_Lt in + let m_P = Mat.make0 n n in + for i=1 to n do + m_P.{i,pi.(i)} <- 1. + done; + let m_D = Mat.of_diag v_D in + let m_B = + gemm ~transa:`T m_P @@ + gemm ~transa:`T m_Lt @@ + gemm m_D @@ + gemm m_Lt m_P + in + Alcotest.(check (float 1.e-3)) "full D" 0. (matrix_diff m_A m_B); + () + in + [ + "Small", `Quick, test_full_small; + "Full", `Quick, test_full; + "Pivoted", `Quick, test_pivoted ; + "Truncated", `Quick, test_truncated ; + ] + +*) diff --git a/qcaml.opam b/qcaml.opam index e7db983..3d594eb 100644 --- a/qcaml.opam +++ b/qcaml.opam @@ -18,7 +18,7 @@ description: """ QCaml provides a programming framewrok work wave function methods in quantum chemistry.""" depends: [ - "ocaml" {>= "4.10"} + "ocaml" {>= "5.0"} "dune" {>= "1.10"} "camlp-streams" {>= "5.0"} "trexio" @@ -26,4 +26,5 @@ depends: [ "getopt" "zarith" "alcotest" + "domainslib" ] diff --git a/simulation/lib/simulation.ml b/simulation/lib/simulation.ml index 4dcc150..c15e245 100644 --- a/simulation/lib/simulation.ml +++ b/simulation/lib/simulation.ml @@ -1,10 +1,10 @@ -(* [[file:~/QCaml/simulation/simulation.org::*Simulation][Simulation:2]] *) +(* [[file:../simulation.org::*Simulation][Simulation:2]] *) open Common open Particles open Operators (* Simulation:2 ends here *) -(* [[file:~/QCaml/simulation/simulation.org::*Type][Type:2]] *) +(* [[file:../simulation.org::*Type][Type:2]] *) type t = { charge : Charge.t; electrons : Electrons.t; @@ -24,7 +24,7 @@ type t = { * | ~operators~ | List of extra operators (range-separation, f12, etc) | *) -(* [[file:~/QCaml/simulation/simulation.org::*Access][Access:2]] *) +(* [[file:../simulation.org::*Access][Access:2]] *) let nuclei t = t.nuclei let charge t = t.charge let electrons t = t.electrons @@ -41,7 +41,7 @@ let operators t = t.operators * - operators : ~[]~ *) -(* [[file:~/QCaml/simulation/simulation.org::*Creation][Creation:2]] *) +(* [[file:../simulation.org::*Creation][Creation:2]] *) let make ?(multiplicity=1) ?(charge=0) @@ -65,7 +65,7 @@ let make { charge ; nuclei ; electrons ; ao_basis ; operators} (* Creation:2 ends here *) -(* [[file:~/QCaml/simulation/simulation.org::*Printers][Printers:2]] *) +(* [[file:../simulation.org::*Printers][Printers:2]] *) let pp ppf t = let formula = Nuclei.formula t.nuclei in let n_aos = Ao.Basis.size t.ao_basis in diff --git a/simulation/lib/simulation.mli b/simulation/lib/simulation.mli index 74d51ff..6c55e95 100644 --- a/simulation/lib/simulation.mli +++ b/simulation/lib/simulation.mli @@ -7,7 +7,7 @@ * * #+NAME: open *) -(* [[file:~/QCaml/simulation/simulation.org::open][open]] *) +(* [[file:../simulation.org::open][open]] *) open Common open Particles open Operators @@ -17,14 +17,14 @@ open Operators * * #+NAME: types *) -(* [[file:~/QCaml/simulation/simulation.org::types][types]] *) +(* [[file:../simulation.org::types][types]] *) type t (* types ends here *) (* Access *) -(* [[file:~/QCaml/simulation/simulation.org::*Access][Access:1]] *) +(* [[file:../simulation.org::*Access][Access:1]] *) val nuclei : t -> Nuclei.t val charge : t -> Charge.t val electrons : t -> Electrons.t @@ -36,7 +36,7 @@ val operators : t -> Operator.t list (* Creation *) -(* [[file:~/QCaml/simulation/simulation.org::*Creation][Creation:1]] *) +(* [[file:../simulation.org::*Creation][Creation:1]] *) val make : ?multiplicity:int -> ?charge:int -> ?operators:Operator.t list-> nuclei:Nuclei.t -> Ao.Basis.t -> t @@ -45,6 +45,6 @@ val make : ?multiplicity:int -> ?charge:int -> (* Printers *) -(* [[file:~/QCaml/simulation/simulation.org::*Printers][Printers:1]] *) +(* [[file:../simulation.org::*Printers][Printers:1]] *) val pp : Format.formatter -> t -> unit (* Printers:1 ends here *)