Suppression notebook anciens/ mise à jour/ ajout nouveaux
This commit is contained in:
parent
ed290c7f44
commit
6f1e3cea5d
|
@ -1,754 +0,0 @@
|
|||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"hidden": true
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"(* Algorithme de localisation des orbitales : Méthode de Boys ou Edminston-Ruedenberg *)\n",
|
||||
"\n",
|
||||
"(*I : Position et base atomique*)\n",
|
||||
" (* 1. Fonction création chaîne linéaire de n H *)\n",
|
||||
" (* 2. Base atomique *)\n",
|
||||
"\n",
|
||||
"(* II : Hartree-Fock *)\n",
|
||||
" (* 1. Def pour HF *)\n",
|
||||
" (* 2. Calcul de Hartree-Fock*)\n",
|
||||
" \n",
|
||||
"(* III : Définition des fonctions pour la localisation *)\n",
|
||||
" (* 1. Définitions de base nécessaire pour la suite *) \n",
|
||||
" (* 2. Fonction de calcul de tous les alpha ER *)\n",
|
||||
" (* 3. Fonction de calcul de tous les alpha Boys *)\n",
|
||||
" (* 4. Pattern matching : calcul de alpha et de D *)\n",
|
||||
" (* 5. Norme de alpha *)\n",
|
||||
" (* 6. Détermination alpha_max et ses indices i et j *) \n",
|
||||
" (* 7. Matrice de rotation 2 par 2 *)\n",
|
||||
" (* 8. Fonction : i,j -> matrice Ksi (n par 2) *)\n",
|
||||
" (* 9. Fonction : i~,j~ -> matrice Ksi~ (n par 2) *)\n",
|
||||
" (* 10. Matrice intermédiaire pour supprimer i j et ajouter i~ et j~ *)\n",
|
||||
" (* 11. Matrice intérmédiaire où les orbitales i et j ont été supprimées et remplacées par des 0*)\n",
|
||||
" \n",
|
||||
"(* IV : Boucle de localisation des OMs *) \n",
|
||||
"\n",
|
||||
"(* V : Fonctions pour la séparation et le rassemblement des matrices *)\n",
|
||||
" (* 1. Fonction de création d'une list d'entier à partir d'un vecteur de float*)\n",
|
||||
" (* 2. Fonction créant une liste à partir des éléments manquant d'une autre liste, dans l'intervalle [1 ; n_mo] *)\n",
|
||||
" (* 3. Fonction de séparation d'une matrice en 2 sous matrice *)\n",
|
||||
" (* 4. Liste des OMs occupées *)\n",
|
||||
" (* 5. Fonction de rassemblement de 2 matrices *) \n",
|
||||
" (* 6. Séparation des OMs -> m_occ : OMs occupées; m_vir : OMs vacantes *)\n",
|
||||
" \n",
|
||||
"(* VI : Calcul et assemblage des OMs occupées/virtuels *) \n",
|
||||
" \n",
|
||||
"(* VII : Calcul Coef CI *)\n",
|
||||
" (* 1. Def de la mo_basis pour le HF pre CI *)\n",
|
||||
" (* 2. HF pour CI *)\n",
|
||||
" (* 3. Calcul de coef CI *)\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"open Lacaml.D\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"(*I : Position et base atomique*)\n",
|
||||
"\n",
|
||||
"(* 1. Fonction création chaîne linéaire de n H *)\n",
|
||||
"\n",
|
||||
"let xyz d n = \n",
|
||||
" let accu = \"\"\n",
|
||||
" in\n",
|
||||
" let rec toto accu d n =\n",
|
||||
" let accu = \n",
|
||||
" if n=0 \n",
|
||||
" then accu ^ \"\"\n",
|
||||
" else\n",
|
||||
" match n with \n",
|
||||
" | 1 -> \"H 0. 0. 0.\\n\" ^ accu\n",
|
||||
" | x -> toto (\"H\" ^ \" \" ^ string_of_float( d *. float_of_int(n-1)) ^ \" 0. 0.\\n\" ^ accu ) d (n-1)\n",
|
||||
" in\n",
|
||||
" accu\n",
|
||||
" in string_of_int(n) ^ \"\\nH\" ^ string_of_int(n) ^ \"\\n\" ^ toto accu d n;;\n",
|
||||
" \n",
|
||||
"let xyz_string = xyz 1.8 20;;\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"hidden": true
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"(* 2. Base atomique *)\n",
|
||||
"\n",
|
||||
"let basis_string = \n",
|
||||
"\"\n",
|
||||
"HYDROGEN\n",
|
||||
"S 6\n",
|
||||
"1 0.3552322122E+02 0.9163596281E-02\n",
|
||||
"2 0.6513143725E+01 0.4936149294E-01\n",
|
||||
"3 0.1822142904E+01 0.1685383049E+00\n",
|
||||
"4 0.6259552659E+00 0.3705627997E+00\n",
|
||||
"5 0.2430767471E+00 0.4164915298E+00\n",
|
||||
"6 0.1001124280E+00 0.1303340841E+00\n",
|
||||
"\"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"hidden": true
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"(* II : Hartree-Fock *)\n",
|
||||
"\n",
|
||||
"(* 1. Def pour HF *)\n",
|
||||
"\n",
|
||||
"let nuclei =\n",
|
||||
" Nuclei.of_xyz_string xyz_string\n",
|
||||
" \n",
|
||||
"let basis = \n",
|
||||
" Basis.of_nuclei_and_basis_string nuclei basis_string\n",
|
||||
" \n",
|
||||
"let simulation = \n",
|
||||
" Simulation.make ~charge:0 ~multiplicity:1 ~nuclei basis\n",
|
||||
" \n",
|
||||
"let ao_basis = \n",
|
||||
" Simulation.ao_basis simulation\n",
|
||||
" \n",
|
||||
"let nocc =\n",
|
||||
" let elec = Simulation.electrons simulation in\n",
|
||||
" Electrons.n_alfa elec\n",
|
||||
" "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"hidden": true
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"(* 2. Calcul de Hartree-Fock*)\n",
|
||||
"\n",
|
||||
"let hf = HartreeFock.make simulation\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"hidden": true
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"let mo_basis = MOBasis.of_hartree_fock hf\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"hidden": true
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"let mo_coef = MOBasis.mo_coef mo_basis\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"(* III : Définition des fonctions pour la localisation *)\n",
|
||||
"\n",
|
||||
"(* 1. Définitions de base nécessaire pour la suite *)\n",
|
||||
"let ee_ints = AOBasis.ee_ints ao_basis;;\n",
|
||||
"let m_C = MOBasis.mo_coef mo_basis;;\n",
|
||||
"let n_ao = Mat.dim1 m_C ;;\n",
|
||||
"let n_mo = Mat.dim2 m_C ;;\n",
|
||||
"let multipoles = \n",
|
||||
" AOBasis.multipole ao_basis;;\n",
|
||||
" \n",
|
||||
"let sum a = \n",
|
||||
" Array.fold_left (fun accu x -> accu +. x) 0. a\n",
|
||||
" \n",
|
||||
"let pi = 3.14159265358979323846264338;;\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"(* 2. Fonction de calcul de tous les alpha ER *)\n",
|
||||
"let f_alpha m_C =\n",
|
||||
"\n",
|
||||
" let n_mo = Mat.dim2 m_C in\n",
|
||||
" (*let t0 = Sys.time () in*)\n",
|
||||
" \n",
|
||||
" let m_b12 = Mat.init_cols n_mo n_mo (fun i j -> 0.) in\n",
|
||||
" let m_a12 = Mat.init_cols n_mo n_mo (fun i j -> 0.) in\n",
|
||||
" let v_d = Vec.init n_mo (fun i -> 0.) in\n",
|
||||
" \n",
|
||||
" (* Tableaux temporaires *)\n",
|
||||
" let m_pqr =\n",
|
||||
" Bigarray.(Array3.create Float64 fortran_layout n_ao n_ao n_ao)\n",
|
||||
" in\n",
|
||||
" let m_qr_i = Mat.create (n_ao*n_ao) n_mo in\n",
|
||||
" let m_ri_j = Mat.create (n_ao*n_mo) n_mo in\n",
|
||||
" let m_ij_k = Mat.create (n_mo*n_mo) n_mo in\n",
|
||||
" \n",
|
||||
" Array.iter (fun s ->\n",
|
||||
" (* Grosse boucle externe sur s *)\n",
|
||||
" Array.iter (fun r ->\n",
|
||||
" Array.iter (fun q ->\n",
|
||||
" Array.iter (fun p ->\n",
|
||||
" m_pqr.{p,q,r} <- ERI.get_phys ee_ints p q r s\n",
|
||||
" ) (Util.array_range 1 n_ao)\n",
|
||||
" ) (Util.array_range 1 n_ao)\n",
|
||||
" ) (Util.array_range 1 n_ao);\n",
|
||||
" \n",
|
||||
" (* Conversion d'un tableau a 3 indices en une matrice nao x nao^2 *)\n",
|
||||
" let m_p_qr =\n",
|
||||
" Bigarray.reshape (Bigarray.genarray_of_array3 m_pqr) [| n_ao ; n_ao*n_ao |]\n",
|
||||
" |> Bigarray.array2_of_genarray\n",
|
||||
" in\n",
|
||||
" \n",
|
||||
" let m_qr_i =\n",
|
||||
" (* (qr,i) = <i r|q s> = \\sum_p <p r | q s> C_{pi} *)\n",
|
||||
" gemm ~transa:`T ~c:m_qr_i m_p_qr m_C\n",
|
||||
" in\n",
|
||||
" \n",
|
||||
" let m_q_ri =\n",
|
||||
" (* Transformation de la matrice (qr,i) en (q,ri) *)\n",
|
||||
" Bigarray.reshape_2 (Bigarray.genarray_of_array2 m_qr_i) n_ao (n_ao*n_mo)\n",
|
||||
" in\n",
|
||||
" \n",
|
||||
" let m_ri_j =\n",
|
||||
" (* (ri,j) = <i r | j s> = \\sum_q <i r | q s> C_{bj} *)\n",
|
||||
" gemm ~transa:`T ~c:m_ri_j m_q_ri m_C\n",
|
||||
" in\n",
|
||||
" \n",
|
||||
" let m_r_ij =\n",
|
||||
" (* Transformation de la matrice (ri,j) en (r,ij) *)\n",
|
||||
" Bigarray.reshape_2 (Bigarray.genarray_of_array2 m_ri_j) n_ao (n_mo*n_mo)\n",
|
||||
" in\n",
|
||||
" \n",
|
||||
" let m_ij_k =\n",
|
||||
" (* (ij,k) = <i k | j s> = \\sum_r <i r | j s> C_{rk} *)\n",
|
||||
" gemm ~transa:`T ~c:m_ij_k m_r_ij m_C\n",
|
||||
" in\n",
|
||||
" \n",
|
||||
" let m_ijk =\n",
|
||||
" (* Transformation de la matrice (ei,j) en (e,ij) *)\n",
|
||||
" Bigarray.reshape (Bigarray.genarray_of_array2 m_ij_k) [| n_mo ; n_mo ; n_mo |]\n",
|
||||
" |> Bigarray.array3_of_genarray\n",
|
||||
" in\n",
|
||||
" \n",
|
||||
" Array.iter (fun j ->\n",
|
||||
" Array.iter (fun i ->\n",
|
||||
" m_b12.{i,j} <- m_b12.{i,j} +. m_C.{s,j} *. (m_ijk.{i,i,i} -. m_ijk.{j,i,j});\n",
|
||||
" m_a12.{i,j} <- m_a12.{i,j} +. m_ijk.{i,i,j} *. m_C.{s,j} -.\n",
|
||||
" 0.25 *. ( (m_ijk.{i,i,i} -. m_ijk.{j,i,j}) *. m_C.{s,i} +.\n",
|
||||
" (m_ijk.{j,j,j} -. m_ijk.{i,j,i}) *. m_C.{s,j})\n",
|
||||
" ) (Util.array_range 1 n_mo);\n",
|
||||
" v_d.{j} <- v_d.{j} +. m_ijk.{j,j,j} *. m_C.{s,j}\n",
|
||||
" ) (Util.array_range 1 n_mo)\n",
|
||||
" ) (Util.array_range 1 n_ao);\n",
|
||||
" \n",
|
||||
" (*let t1 = Sys.time () in\n",
|
||||
" Printf.printf \"t = %f s\\n%!\" (t1 -. t0);*)\n",
|
||||
" \n",
|
||||
" (Mat.init_cols n_mo n_mo ( fun i j ->\n",
|
||||
" if i= j then 0.\n",
|
||||
" else 0.25 *. (acos(-. m_a12.{i,j} /. sqrt((m_a12.{i,j}**2.) +. (m_b12.{i,j}**2. ))))\n",
|
||||
" ),Vec.sum v_d);;\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"(* 3. Fonction de calcul de tous les alpha Boys *)\n",
|
||||
"let f_alpha_boys m_C = \n",
|
||||
" let n_mo = Mat.dim2 m_C\n",
|
||||
" in\n",
|
||||
" let phi_x_phi =\n",
|
||||
" Multipole.matrix_x multipoles \n",
|
||||
" |> MOBasis.mo_matrix_of_ao_matrix ~mo_coef:m_C\n",
|
||||
" in \n",
|
||||
" let phi_y_phi =\n",
|
||||
" Multipole.matrix_y multipoles \n",
|
||||
" |> MOBasis.mo_matrix_of_ao_matrix ~mo_coef:m_C\n",
|
||||
" in\n",
|
||||
" let phi_z_phi =\n",
|
||||
" Multipole.matrix_z multipoles \n",
|
||||
" |> MOBasis.mo_matrix_of_ao_matrix ~mo_coef:m_C\n",
|
||||
" in \n",
|
||||
"\n",
|
||||
" let m_b12= \n",
|
||||
" let b12 g = Mat.init_cols n_mo n_mo ( fun i j ->\n",
|
||||
" (g.{i,i} -. g.{j,j}) *. g.{i,j})\n",
|
||||
"\n",
|
||||
" in \n",
|
||||
" Mat.add (b12 phi_x_phi) ( Mat.add (b12 phi_y_phi) (b12 phi_z_phi))\n",
|
||||
" in \n",
|
||||
" let m_a12 =\n",
|
||||
" let a12 g = Mat.init_cols n_mo n_mo ( fun i j -> \n",
|
||||
" g.{i,j} *. g.{i,j} -. 0.25 *. ((g.{i,i} -. g.{j,j}) *. (g.{i,i} -. g.{j,j})))\n",
|
||||
" in\n",
|
||||
" Mat.add (a12 phi_x_phi) ( Mat.add (a12 phi_y_phi) (a12 phi_z_phi))\n",
|
||||
" in\n",
|
||||
" (Mat.init_cols n_mo n_mo ( fun i j -> \n",
|
||||
" if i=j \n",
|
||||
" then 0.\n",
|
||||
" else 0.25 *. acos(-. m_a12.{i,j} /. sqrt((m_a12.{i,j}**2.) +. (m_b12.{i,j}**2.) ))),\n",
|
||||
" Vec.sum(Vec.init n_mo ( fun i -> (phi_x_phi.{i,i})**2. +. (phi_y_phi.{i,i})**2. +. (phi_z_phi.{i,i})**2.)));;\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"(* 4. Pattern matching : calcul de alpha et de D *)\n",
|
||||
"type alphad = {\n",
|
||||
"m_alpha : Mat.t;\n",
|
||||
"d : float;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"let m_alpha_d methode m_C = \n",
|
||||
" let alpha methode =\n",
|
||||
" \n",
|
||||
" match methode with \n",
|
||||
" | \"Boys\"\n",
|
||||
" | \"boys\" -> let alpha_boys , d_boys = f_alpha_boys m_C in {m_alpha = alpha_boys; d = d_boys}\n",
|
||||
" | \"ER\"\n",
|
||||
" | \"er\" -> let alpha_er , d_er = f_alpha m_C in {m_alpha = alpha_er; d = d_er}\n",
|
||||
" | _ -> invalid_arg \"Unknown method, please enter Boys or ER\"\n",
|
||||
"\n",
|
||||
"in \n",
|
||||
"alpha methode;;\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"(* 5. Norme de alpha *)\n",
|
||||
"\n",
|
||||
"let norme m = \n",
|
||||
" let vec_m = Mat.as_vec m\n",
|
||||
" in\n",
|
||||
" let vec2 = Vec.sqr vec_m\n",
|
||||
"in sqrt(Vec.sum vec2);;\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"(* 6. Détermination alpha_max et ses indices i et j.\n",
|
||||
"Si alpha max > pi/2 on soustrait pi/2 à la matrice des alphas de manière récursive *)\n",
|
||||
"type alphaij = {\n",
|
||||
" alpha_max : float;\n",
|
||||
" indice_ii : int;\n",
|
||||
" indice_jj : int;};;\n",
|
||||
"\n",
|
||||
"let rec new_m_alpha m_alpha m_C n_rec_alpha=\n",
|
||||
"\n",
|
||||
" let n_mo = Mat.dim2 m_C\n",
|
||||
" in\n",
|
||||
" let alpha_m =\n",
|
||||
" \n",
|
||||
" (*Printf.printf \"%i\\n%!\" n_rec_alpha;*)\n",
|
||||
" \n",
|
||||
" if n_rec_alpha == 0 \n",
|
||||
" then m_alpha \n",
|
||||
" else Mat.init_cols n_mo n_mo (fun i j -> \n",
|
||||
" if (m_alpha.{i,j}) > (pi /. 2.) \n",
|
||||
" then (m_alpha.{i,j} -. ( pi /. 2.))\n",
|
||||
" else if m_alpha.{i,j} < -. pi /. 2.\n",
|
||||
" then (m_alpha.{i,j} +. ( pi /. 2.))\n",
|
||||
" else if m_alpha.{i,j} < 0. \n",
|
||||
" then -. m_alpha.{i,j}\n",
|
||||
" else m_alpha.{i,j} )\n",
|
||||
" in \n",
|
||||
" \n",
|
||||
" (*Util.debug_matrix \"alpha_m\" alpha_m;*)\n",
|
||||
" \n",
|
||||
" (* Détermination de l'emplacement du alpha max *)\n",
|
||||
" let max_element3 alpha_m = \n",
|
||||
" Mat.as_vec alpha_m\n",
|
||||
" |> iamax\n",
|
||||
" in\n",
|
||||
" \n",
|
||||
" (* indice i et j du alpha max *)\n",
|
||||
" let indice_ii, indice_jj = \n",
|
||||
" let max = max_element3 alpha_m \n",
|
||||
" in\n",
|
||||
" (max - 1) mod n_mo +1, (max - 1) / n_mo +1\n",
|
||||
" in\n",
|
||||
" \n",
|
||||
" (* Valeur du alpha max*)\n",
|
||||
" let alpha alpha_m = \n",
|
||||
" let i = indice_ii \n",
|
||||
" in\n",
|
||||
" let j = indice_jj \n",
|
||||
" in\n",
|
||||
" alpha_m.{i,j}\n",
|
||||
" \n",
|
||||
" (*Printf.printf \"%i %i\\n%!\" i j;*)\n",
|
||||
" \n",
|
||||
" in\n",
|
||||
" let alpha_max = alpha alpha_m \n",
|
||||
" in\n",
|
||||
" \n",
|
||||
" (*Printf.printf \"%f\\n%!\" alpha_max;*)\n",
|
||||
" \n",
|
||||
" if alpha_max < pi /. 2.\n",
|
||||
" then {alpha_max; indice_ii; indice_jj}\n",
|
||||
" else new_m_alpha alpha_m m_C (n_rec_alpha-1);;\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"(* 7. Matrice de rotation 2 par 2 *)\n",
|
||||
"let f_R alpha =\n",
|
||||
" Mat.init_cols 2 2 (fun i j -> \n",
|
||||
" if i=j \n",
|
||||
" then cos alpha\n",
|
||||
" else if i>j \n",
|
||||
" then sin alpha \n",
|
||||
" else -. sin alpha )\n",
|
||||
";;\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"(* 8. Fonction d'extraction des 2 vecteurs propres i et j de la matrice des OMs pour les mettres dans la matrice Ksi (n par 2)\n",
|
||||
"pour appliquer R afin d'effectuer la rotation des orbitales *) (* {1,2} -> 1ere ligne, 2e colonne *)\n",
|
||||
"let f_Ksi indice_i indice_j m_C =\n",
|
||||
" let n_ao = Mat.dim1 m_C\n",
|
||||
"in\n",
|
||||
"Mat.init_cols n_ao 2 (fun i j -> if j=1 then m_C.{i,indice_i} else m_C.{i,indice_j} );;\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"(* 9. Fonction de calcul de ksi~ (matrice n par 2), nouvelle matrice par application de la matrice de rotation dans laquelle\n",
|
||||
"on obtient les deux orbitales que l'on va réinjecter dans la matrice Phi*)\n",
|
||||
"let f_Ksi_tilde m_R m_Ksi m_C = gemm m_Ksi m_R;;\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"(* 10. Fonction pour la création de matrice intermédiaire pour supprimer i j et ajouter i~ et j~ *)\n",
|
||||
"let f_k mat indice_i indice_j m_C = \n",
|
||||
"let n_mo = Mat.dim2 m_C\n",
|
||||
" in\n",
|
||||
" let n_ao = Mat.dim1 m_C\n",
|
||||
"in\n",
|
||||
"Mat.init_cols n_ao n_mo (fun i j -> \n",
|
||||
" if j=indice_i \n",
|
||||
" then mat.{i,1}\n",
|
||||
" else if j=indice_j \n",
|
||||
" then mat.{i,2}\n",
|
||||
" else 0.)\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"(* 11. Matrice intérmédiaire où les orbitales i et j ont été supprimées et remplacées par des 0, par soustraction de la matrice\n",
|
||||
"des coefs par la matrice *)\n",
|
||||
"let f_interm m_C m_Psi = Mat.sub m_C m_Psi;;\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"(* Fonction de calcul de la nouvelle matrice de coef après rotation d'un angle alpha *)\n",
|
||||
"let new_m_C m_C methode m_alpha epsilon =\n",
|
||||
" \n",
|
||||
" (* alphaij contient le alpha max ainsi que ses indices i et j *)\n",
|
||||
" let n_rec_alpha = 10 (* Nombre ditération max pour réduire les valeurs de alpha *)\n",
|
||||
" in\n",
|
||||
" let alphaij = new_m_alpha m_alpha m_C n_rec_alpha \n",
|
||||
" in\n",
|
||||
"\n",
|
||||
" (* Valeur de alpha max après calcul *) (* Epsilon = Pas <1. , 1. -> normal, sinon Pas plus petit *)\n",
|
||||
" let alpha = (alphaij.alpha_max) *. epsilon \n",
|
||||
" in\n",
|
||||
"\n",
|
||||
" (*Printf.printf \"%f\\n%!\" alpha;*)\n",
|
||||
" \n",
|
||||
" (* Indice i et j du alpha max après calcul *)\n",
|
||||
" let indice_i = alphaij.indice_ii \n",
|
||||
" in\n",
|
||||
" let indice_j = alphaij.indice_jj \n",
|
||||
" in\n",
|
||||
"\n",
|
||||
" (*Printf.printf \"%i %i\\n%!\" indice_i indice_j;*)\n",
|
||||
" \n",
|
||||
" (* Matrice de rotation *)\n",
|
||||
" let m_R = f_R alpha \n",
|
||||
" in\n",
|
||||
"\n",
|
||||
" (*Util.debug_matrix \"m_R\" m_R;*)\n",
|
||||
"\n",
|
||||
" (* Matrice qui va subir la rotation *)\n",
|
||||
" let m_Ksi = f_Ksi indice_i indice_j m_C \n",
|
||||
" in\n",
|
||||
"\n",
|
||||
" (*Util.debug_matrix \"m_Ksi\" m_Ksi;*)\n",
|
||||
"\n",
|
||||
" (* Matrice ayant subit la rotation *)\n",
|
||||
" let m_Ksi_tilde = f_Ksi_tilde m_R m_Ksi m_C \n",
|
||||
" in\n",
|
||||
"\n",
|
||||
" (*Util.debug_matrix \"m_Ksi_tilde\" m_Ksi_tilde;*)\n",
|
||||
"\n",
|
||||
" (* Matrice pour supprimerles coef des orbitales i et j dans la matrice des coef *)\n",
|
||||
" let m_Psi = f_k m_Ksi indice_i indice_j m_C\n",
|
||||
" in\n",
|
||||
"\n",
|
||||
" (*Util.debug_matrix \"m_Psi\" m_Psi;*)\n",
|
||||
"\n",
|
||||
" (* Matrice pour ajouter les coef des orbitales i~ et j~ dans la matrice des coef *)\n",
|
||||
" let m_Psi_tilde = f_k m_Ksi_tilde indice_i indice_j m_C \n",
|
||||
" in\n",
|
||||
"\n",
|
||||
" (*Util.debug_matrix \"m_Psi_tilde\" m_Psi_tilde;*)\n",
|
||||
"\n",
|
||||
" (* Matrice avec les coef des orbitales i et j remplacés par 0 *)\n",
|
||||
" let m_interm = f_interm m_C m_Psi \n",
|
||||
" in\n",
|
||||
" \n",
|
||||
" (*Util.debug_matrix \"m_interm\" m_interm;*)\n",
|
||||
" \n",
|
||||
"(* Matrice après rotation *)\n",
|
||||
"Mat.add m_Psi_tilde m_interm"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"\n",
|
||||
"(* Localisation de Edminstion ou de Boys *)\n",
|
||||
"\n",
|
||||
"(* Calcul de la nouvelle matrice des coefficient après n rotation d'orbitales *)\n",
|
||||
"let rec localisation m_C methode epsilon n prev_critere_D prev_m_alpha cc max_D=\n",
|
||||
"\n",
|
||||
" (*Printf.printf \"%i\\n%!\" n;\n",
|
||||
" Printf.printf \"%f\\n%!\" epsilon;*)\n",
|
||||
"\n",
|
||||
" (*Util.debug_matrix \"m_C\" m_C;*)\n",
|
||||
"\n",
|
||||
" (*Util.debug_matrix \"new_alpha_m\" prev_m_alpha;*)\n",
|
||||
"\n",
|
||||
"if n == 0 \n",
|
||||
" then m_C\n",
|
||||
" else\n",
|
||||
"\n",
|
||||
" let m_new_m_C = new_m_C m_C methode prev_m_alpha epsilon\n",
|
||||
" in\n",
|
||||
" (* Fonction de pattern matching en fonction de la méthode *)\n",
|
||||
" let alphad = m_alpha_d methode m_new_m_C\n",
|
||||
" in\n",
|
||||
" \n",
|
||||
" (* D critère à maximiser *)\n",
|
||||
" let critere_D = alphad.d \n",
|
||||
" in\n",
|
||||
" let diff = max_D -. critere_D \n",
|
||||
" in\n",
|
||||
" let max_D =\n",
|
||||
" if diff > 0.\n",
|
||||
" then max_D\n",
|
||||
" else critere_D\n",
|
||||
" in\n",
|
||||
" (*Printf.printf \"%f\\n%!\" max_D;*)\n",
|
||||
" Printf.printf \"%e\\n%!\" critere_D;\n",
|
||||
" (*Printf.printf \"%f\\n%!\" diff;*)\n",
|
||||
" \n",
|
||||
" (* Matrice des alphas *)\n",
|
||||
" let m_alpha = alphad.m_alpha\n",
|
||||
" in\n",
|
||||
" (*let norme_alpha = norme m_alpha\n",
|
||||
" in \n",
|
||||
" Printf.printf \"%f\\n%!\" norme_alpha;*)\n",
|
||||
"if diff > 0. && epsilon >= 0.1\n",
|
||||
" then localisation m_C methode (epsilon /. 2.) (n-1) critere_D prev_m_alpha cc max_D\n",
|
||||
" else\n",
|
||||
" let epsilon = 1.\n",
|
||||
" in\n",
|
||||
" \n",
|
||||
"(*Util.debug_matrix \"new_alpha_m\" m_alpha;*)\n",
|
||||
"(*Util.debug_matrix \"m_new_m_C\" m_new_m_C;*)\n",
|
||||
"\n",
|
||||
"if diff**2. < cc**2.\n",
|
||||
" then m_new_m_C\n",
|
||||
" else\n",
|
||||
"localisation m_new_m_C methode epsilon (n-1) critere_D m_alpha cc max_D;;\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"let localise localisation m_C methode epsilon n cc=\n",
|
||||
" let alphad = m_alpha_d methode m_C \n",
|
||||
" in\n",
|
||||
" let prev_m_alpha = alphad.m_alpha\n",
|
||||
" in \n",
|
||||
" let prev_critere_D = 0.\n",
|
||||
" in\n",
|
||||
" let max_D = 0.\n",
|
||||
"in\n",
|
||||
"localisation m_C methode epsilon n prev_critere_D prev_m_alpha cc max_D;;\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"(* V : Fonctions pour la séparation et le rassemblement des matrices *)\n",
|
||||
"\n",
|
||||
"(* 1. Fonction de création d'une list d'entier à partir d'un vecteur de float*)\n",
|
||||
"let int_list vec = \n",
|
||||
" let float_list = Vec.to_list vec\n",
|
||||
" in\n",
|
||||
" let g a = int_of_float(a)\n",
|
||||
"in List.map g float_list;;\n",
|
||||
"\n",
|
||||
"(* 2. Fonction créant une liste à partir des éléments manquant d'une autre liste, dans l'intervalle [1 ; n_mo] *)\n",
|
||||
"let miss_elem mat list = \n",
|
||||
" let n_mo = Mat.dim2 mat\n",
|
||||
" in\n",
|
||||
" let vec = Vec.init (n_mo) (fun i ->\n",
|
||||
" if List.mem i list\n",
|
||||
" then 0.\n",
|
||||
" else float_of_int(i))\n",
|
||||
" in\n",
|
||||
" let list_int = int_list vec \n",
|
||||
"in\n",
|
||||
"List.filter (fun x -> x > 0) list_int;;\n",
|
||||
"\n",
|
||||
"(* 3. Fonction de séparation d'une matrice en 2 sous matrice, la première matrice correspondant aux colonnes de la matrice dont le numéro est présent\n",
|
||||
"dans la liste et la seconde à celles dont le numéro de colonne n'est pas présent dans la liste *)\n",
|
||||
"let split_mat mat list =\n",
|
||||
" let vec_of_mat = Mat.to_col_vecs mat\n",
|
||||
" in\n",
|
||||
" let f a = vec_of_mat.(a-1)\n",
|
||||
" in\n",
|
||||
" let vec_list_1 = List.map f list\n",
|
||||
" in\n",
|
||||
" let list_2 = miss_elem mat list\n",
|
||||
" in\n",
|
||||
" let vec_list_2 = List.map f list_2\n",
|
||||
"in (Mat.of_col_vecs_list vec_list_1,Mat.of_col_vecs_list vec_list_2);;\n",
|
||||
"\n",
|
||||
"(* 4. Liste des OMs occupées *)\n",
|
||||
"let list_occ = \n",
|
||||
" let vec_occ = Vec.init (nocc) (fun i -> float_of_int(i))\n",
|
||||
"in int_list vec_occ;;\n",
|
||||
"\n",
|
||||
"(* 5. Fonction de rassemblement de 2 matrices *)\n",
|
||||
"let assemble m_occ m_vir = Mat.init_cols n_ao n_mo ( fun i j ->\n",
|
||||
" if j > nocc \n",
|
||||
" then m_vir.{i,j-(n_mo - nocc)}\n",
|
||||
" else m_occ.{i,j});;\n",
|
||||
" \n",
|
||||
"(* 6. Séparation des OMs -> m_occ : OMs occupées; m_vir : OMs vacantes *)\n",
|
||||
"let m_occ , m_vir = split_mat m_C list_occ;;\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"localise localisation m_occ \"Boys\" 1. 1000 10e-5;;"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "OCaml 4.10.0",
|
||||
"language": "OCaml",
|
||||
"name": "ocaml-jupyter"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": "text/x-ocaml",
|
||||
"file_extension": ".ml",
|
||||
"mimetype": "text/x-ocaml",
|
||||
"name": "OCaml",
|
||||
"nbconverter_exporter": null,
|
||||
"pygments_lexer": "OCaml",
|
||||
"version": "4.10.0"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
|
@ -0,0 +1,800 @@
|
|||
(* Algorithme de localisation des orbitales *)
|
||||
|
||||
(* SOMMAIRE *)
|
||||
|
||||
(* I. Définition des types *)
|
||||
|
||||
(* II : Définition des fonctions pour la localisation *)
|
||||
|
||||
(* 1. Définitions de base nécessaire pour la suite *)
|
||||
(* 2. Fonction de calcul de la matrice des angles selon la méthode de Edminston *)
|
||||
(* 3. Fonction calcul de la matrice des angles selon la méthode de Boys façon Edminston *)
|
||||
(* 4. Fonction de calcul de la matrice des angles selon la méthode de Boys *)
|
||||
(* 5. Pattern matching : calcul de alpha et du critere D *)
|
||||
(* 6. Norme d'une matrice *)
|
||||
(* 7. Détermination de alpha_max et ses indices i et j.
|
||||
Si alpha max > pi/2 on soustrait pi/2 à la matrice des alphas de manière récursive
|
||||
Si alpha max < pi/2 on ajoute pi/2 à la matrice des alphas de manière récursive *)
|
||||
(* 8. Matrice de rotation 2 par 2 *)
|
||||
(* 9. Matrice de rotation n par n avec un angle fixe *)
|
||||
(* 10. Fonction d'extraction des 2 vecteurs propres i et j de la matrice des OMs pour les mettres dans la matrice Ksi (n par 2)
|
||||
pour appliquer R afin d'effectuer la rotation des orbitales *) (* {1,2} -> 1ere ligne, 2e colonne *)
|
||||
(* 11. Fonction de calcul de ksi~ (matrice n par 2), nouvelle matrice par application de la matrice de rotation dans laquelle
|
||||
on obtient les deux orbitales que l'on va réinjecter dans la matrice Phi*)
|
||||
(* 12. Fonction pour la création de matrice intermédiaire pour supprimer i j et ajouter i~ et j~ *)
|
||||
(* 13. Matrice intérmédiaire où les orbitales i et j ont été supprimées et remplacées par des 0, par soustraction de la matrice Phi
|
||||
par la matrice *)
|
||||
|
||||
(* III. Localisation des OMs *)
|
||||
|
||||
(* 1. Boucle de calcul de la nouvelle matrice des coefficient après n rotation d'orbitales *)
|
||||
(* 2. Fonction de localisation *)
|
||||
|
||||
(* IV : Fonctions pour la séparation et le rassemblement des matrices *)
|
||||
|
||||
(* 1. Fonction de création d'une liste d'entier à partir d'un vecteur de float*)
|
||||
(* 2. Fonction créant une liste à partir des éléments manquant d'une autre liste, dans l'intervalle [1 ; n_mo] *)
|
||||
(* 3. Fonction de séparation d'une matrice en 2 sous matrice, la première matrice correspondant aux colonnes de la matrice dont le numéro est présent
|
||||
dans la liste et la seconde à celles dont le numéro de colonne n'est pas présent dans la liste *)
|
||||
(* 4. Liste des OMs occupées *)
|
||||
(* 5. Liste des OMs de coeur *)
|
||||
(* 6. Liste des OMs pi au sein des OMs virtuelles *)
|
||||
(* 7. Fonction de rassemblement de 2 matrices *)
|
||||
|
||||
(* V. Calcul *)
|
||||
|
||||
(* 1. Séparation des OMs -> m_occ : OMs occupées; m_vir : OMs vacantes *)
|
||||
(* 2. Application d'une légère rotation d'un angle fixé aux OMs pour améliorer la convergence *) (* !!! Réglage de l'angle de rotation !!! *)
|
||||
(* 3. Légende *)
|
||||
(* 4. Rotation des orbitales : localise localisation new_X / "methode" / epsilon = 1. si <1 diminue l'angle des rotations / nb itération / critère de convergence *) (* !!! Paramètres du calcul !!! *)
|
||||
(* 5. Rassemblement des occupées et des virtuelles *)
|
||||
|
||||
let methode = "BOYS";;
|
||||
let iteration = 100000;;
|
||||
let cc = 10e-3;;
|
||||
let epsilon = 1.;;
|
||||
(*let list_split_vir2 = [];;*)
|
||||
|
||||
open Lacaml.D
|
||||
|
||||
(* I. Définition des types *)
|
||||
|
||||
type alphaij = {
|
||||
alpha_max : float;
|
||||
indice_ii : int;
|
||||
indice_jj : int;
|
||||
}
|
||||
|
||||
type alphad = {
|
||||
m_alpha : Mat.t;
|
||||
d : float;
|
||||
}
|
||||
|
||||
let localize mo_basis =
|
||||
|
||||
let simulation = MOBasis.simulation mo_basis in
|
||||
let nocc =
|
||||
let elec = Simulation.electrons simulation
|
||||
in
|
||||
Electrons.n_alfa elec
|
||||
in
|
||||
let ao_basis = MOBasis.ao_basis mo_basis in
|
||||
let n_core =
|
||||
(Nuclei.small_core @@ Simulation.nuclei @@ MOBasis.simulation mo_basis) / 2
|
||||
in
|
||||
(* II : Définition des fonctions pour la localisation *)
|
||||
|
||||
(* 1. Définitions de base nécessaire pour la suite *)
|
||||
let m_C = MOBasis.mo_coef mo_basis in
|
||||
let n_ao = Mat.dim1 m_C in
|
||||
let pi = acos(-1.) in
|
||||
|
||||
(* 2. Fonction de calcul de la matrice des angles selon la méthode de Edminston *)
|
||||
let f_alpha m_C =
|
||||
|
||||
let ee_ints = AOBasis.ee_ints ao_basis in
|
||||
let n_mo = Mat.dim2 m_C in
|
||||
(*let t0 = Sys.time () in*)
|
||||
|
||||
let m_b12 = Mat.init_cols n_mo n_mo (fun i j -> 0.) in
|
||||
let m_a12 = Mat.init_cols n_mo n_mo (fun i j -> 0.) in
|
||||
let v_d = Vec.init n_mo (fun i -> 0.) in
|
||||
|
||||
(* Tableaux temporaires *)
|
||||
let m_pqr =
|
||||
Bigarray.(Array3.create Float64 fortran_layout n_ao n_ao n_ao)
|
||||
in
|
||||
let m_qr_i = Mat.create (n_ao*n_ao) n_mo in
|
||||
let m_ri_j = Mat.create (n_ao*n_mo) n_mo in
|
||||
let m_ij_k = Mat.create (n_mo*n_mo) n_mo in
|
||||
|
||||
Array.iter (fun s ->
|
||||
(* Grosse boucle externe sur s *)
|
||||
Array.iter (fun r ->
|
||||
Array.iter (fun q ->
|
||||
Array.iter (fun p ->
|
||||
m_pqr.{p,q,r} <- ERI.get_phys ee_ints p q r s
|
||||
) (Util.array_range 1 n_ao)
|
||||
) (Util.array_range 1 n_ao)
|
||||
) (Util.array_range 1 n_ao);
|
||||
|
||||
(* Conversion d'un tableau a 3 indices en une matrice nao x nao^2 *)
|
||||
let m_p_qr =
|
||||
Bigarray.reshape (Bigarray.genarray_of_array3 m_pqr) [| n_ao ; n_ao*n_ao |]
|
||||
|> Bigarray.array2_of_genarray
|
||||
in
|
||||
|
||||
let m_qr_i =
|
||||
(* (qr,i) = <i r|q s> = \sum_p <p r | q s> C_{pi} *)
|
||||
gemm ~transa:`T ~c:m_qr_i m_p_qr m_C
|
||||
in
|
||||
|
||||
let m_q_ri =
|
||||
(* Transformation de la matrice (qr,i) en (q,ri) *)
|
||||
Bigarray.reshape_2 (Bigarray.genarray_of_array2 m_qr_i) n_ao (n_ao*n_mo)
|
||||
in
|
||||
|
||||
let m_ri_j =
|
||||
(* (ri,j) = <i r | j s> = \sum_q <i r | q s> C_{bj} *)
|
||||
gemm ~transa:`T ~c:m_ri_j m_q_ri m_C
|
||||
in
|
||||
|
||||
let m_r_ij =
|
||||
(* Transformation de la matrice (ri,j) en (r,ij) *)
|
||||
Bigarray.reshape_2 (Bigarray.genarray_of_array2 m_ri_j) n_ao (n_mo*n_mo)
|
||||
in
|
||||
|
||||
let m_ij_k =
|
||||
(* (ij,k) = <i k | j s> = \sum_r <i r | j s> C_{rk} *)
|
||||
gemm ~transa:`T ~c:m_ij_k m_r_ij m_C
|
||||
in
|
||||
|
||||
let m_ijk =
|
||||
(* Transformation de la matrice (ei,j) en (e,ij) *)
|
||||
Bigarray.reshape (Bigarray.genarray_of_array2 m_ij_k) [| n_mo ; n_mo ; n_mo |]
|
||||
|> Bigarray.array3_of_genarray
|
||||
in
|
||||
|
||||
Array.iter (fun j ->
|
||||
Array.iter (fun i ->
|
||||
m_b12.{i,j} <- m_b12.{i,j} +. m_C.{s,j} *. (m_ijk.{i,i,i} -. m_ijk.{j,i,j});
|
||||
m_a12.{i,j} <- m_a12.{i,j} +. m_ijk.{i,i,j} *. m_C.{s,j} -.
|
||||
0.25 *. ( (m_ijk.{i,i,i} -. m_ijk.{j,i,j}) *. m_C.{s,i} +.
|
||||
(m_ijk.{j,j,j} -. m_ijk.{i,j,i}) *. m_C.{s,j})
|
||||
) (Util.array_range 1 n_mo);
|
||||
v_d.{j} <- v_d.{j} +. m_ijk.{j,j,j} *. m_C.{s,j}
|
||||
) (Util.array_range 1 n_mo)
|
||||
) (Util.array_range 1 n_ao);
|
||||
|
||||
(*let t1 = Sys.time () in
|
||||
Printf.printf "t = %f s\n%!" (t1 -. t0);*)
|
||||
|
||||
(Mat.init_cols n_mo n_mo ( fun i j ->
|
||||
if i= j
|
||||
then 0.
|
||||
else if +. 0.25 *. atan2 m_b12.{i,j} m_a12.{i,j} <= 0.
|
||||
then pi /. 4. +. 0.25 *. atan2 m_b12.{i,j} m_a12.{i,j}
|
||||
else -. pi /. 4. +. 0.25 *. atan2 m_b12.{i,j} m_a12.{i,j})
|
||||
,Vec.sum v_d)
|
||||
in
|
||||
(* 3. Fonction calcul de la matrice des angles selon la méthode de Boys façon Edminston *)
|
||||
let f_alpha_boys m_C =
|
||||
|
||||
let multipoles = AOBasis.multipole ao_basis in
|
||||
let n_mo = Mat.dim2 m_C
|
||||
in
|
||||
let phi_x_phi =
|
||||
Multipole.matrix_x multipoles
|
||||
|> MOBasis.mo_matrix_of_ao_matrix ~mo_coef:m_C
|
||||
in
|
||||
let phi_y_phi =
|
||||
Multipole.matrix_y multipoles
|
||||
|> MOBasis.mo_matrix_of_ao_matrix ~mo_coef:m_C
|
||||
in
|
||||
let phi_z_phi =
|
||||
Multipole.matrix_z multipoles
|
||||
|> MOBasis.mo_matrix_of_ao_matrix ~mo_coef:m_C
|
||||
in
|
||||
|
||||
let m_b12=
|
||||
let b12 g = Mat.init_cols n_mo n_mo ( fun i j ->
|
||||
(g.{i,i} -. g.{j,j}) *. g.{i,j})
|
||||
|
||||
in
|
||||
Mat.add (b12 phi_x_phi) ( Mat.add (b12 phi_y_phi) (b12 phi_z_phi))
|
||||
in
|
||||
let m_a12 =
|
||||
let a12 g = Mat.init_cols n_mo n_mo ( fun i j ->
|
||||
g.{i,j} *. g.{i,j} -. 0.25 *. ((g.{i,i} -. g.{j,j}) *. (g.{i,i} -. g.{j,j})))
|
||||
in
|
||||
Mat.add (a12 phi_x_phi) ( Mat.add (a12 phi_y_phi) (a12 phi_z_phi))
|
||||
in
|
||||
(Mat.init_cols n_mo n_mo ( fun i j ->
|
||||
if i=j
|
||||
then 0.
|
||||
else if +. 0.25 *. atan2 m_b12.{i,j} m_a12.{i,j} >= 0.
|
||||
then pi /. 4. -. 0.25 *. atan2 m_b12.{i,j} m_a12.{i,j}
|
||||
else -. pi /. 4. -. 0.25 *. atan2 m_b12.{i,j} m_a12.{i,j})
|
||||
,Vec.sum(Vec.init n_mo ( fun i -> (phi_x_phi.{i,i})**2. +. (phi_y_phi.{i,i})**2. +. (phi_z_phi.{i,i})**2.)))
|
||||
in
|
||||
(* 4. Fonction de calcul de la matrice des angles selon la méthode de Boys *)
|
||||
|
||||
let f_theta m_C =
|
||||
let multipoles = AOBasis.multipole ao_basis in
|
||||
let n_mo = Mat.dim2 m_C
|
||||
in
|
||||
let phi_x_phi =
|
||||
Multipole.matrix_x multipoles
|
||||
|> MOBasis.mo_matrix_of_ao_matrix ~mo_coef:m_C
|
||||
in
|
||||
let phi_y_phi =
|
||||
Multipole.matrix_y multipoles
|
||||
|> MOBasis.mo_matrix_of_ao_matrix ~mo_coef:m_C
|
||||
in
|
||||
let phi_z_phi =
|
||||
Multipole.matrix_z multipoles
|
||||
|> MOBasis.mo_matrix_of_ao_matrix ~mo_coef:m_C
|
||||
in
|
||||
let phi_x2_phi =
|
||||
Multipole.matrix_x2 multipoles
|
||||
|> MOBasis.mo_matrix_of_ao_matrix ~mo_coef:m_C
|
||||
in
|
||||
let phi_y2_phi =
|
||||
Multipole.matrix_y2 multipoles
|
||||
|> MOBasis.mo_matrix_of_ao_matrix ~mo_coef:m_C
|
||||
in
|
||||
let phi_z2_phi =
|
||||
Multipole.matrix_z2 multipoles
|
||||
|> MOBasis.mo_matrix_of_ao_matrix ~mo_coef:m_C
|
||||
in
|
||||
let m_b_0 =
|
||||
let b_0 g h = Mat.init_cols n_mo n_mo (fun i j ->
|
||||
h.{i,i} +. h.{j,j} -. (g.{i,i}**2. +. g.{j,j}**2.))
|
||||
in
|
||||
Mat.add (b_0 phi_x_phi phi_x2_phi) (Mat.add (b_0 phi_y_phi phi_y2_phi) (b_0 phi_z_phi phi_z2_phi))
|
||||
in
|
||||
let m_beta =
|
||||
let beta g = Mat.init_cols n_mo n_mo (fun i j ->
|
||||
(g.{i,i} -. g.{j,j})**2. -. 4. *. g.{i,j}**2.)
|
||||
in
|
||||
Mat.add (beta phi_x_phi) (Mat.add (beta phi_y_phi) (beta phi_z_phi))
|
||||
in
|
||||
(*Util.debug_matrix "m_beta" m_beta;*)
|
||||
|
||||
let m_gamma =
|
||||
let gamma g = Mat.init_cols n_mo n_mo (fun i j ->
|
||||
4. *. g.{i,j} *. (g.{i,i} -. g.{j,j}) )
|
||||
in
|
||||
Mat.add (gamma phi_x_phi) (Mat.add (gamma phi_y_phi) (gamma phi_z_phi))
|
||||
in
|
||||
(*Util.debug_matrix "m_gamma" m_gamma;*)
|
||||
|
||||
let m_theta = Mat.init_cols n_mo n_mo (fun i j ->
|
||||
if i = j
|
||||
then 0.
|
||||
else +. 0.25 *. atan2 m_gamma.{i,j} m_beta.{i,j})
|
||||
in
|
||||
(*Util.debug_matrix "m_theta" m_theta;*)
|
||||
|
||||
let m_critere_B = Mat.init_cols n_mo n_mo (fun i j ->
|
||||
m_b_0.{i,j} +. 0.25 *. ((1. -. cos(4. *. m_theta.{i,j})) *. m_beta.{i,j} +. sin(4. *. m_theta.{i,j}) *. m_gamma.{i,j}))
|
||||
in
|
||||
m_theta, Vec.sum(Mat.as_vec m_critere_B)
|
||||
in
|
||||
|
||||
(* 5. Pattern matching : calcul de alpha et du critere D *)
|
||||
|
||||
let m_alpha_d methode m_C =
|
||||
|
||||
let alpha methode =
|
||||
match methode with
|
||||
| "Boys_er"
|
||||
| "BOYS_ER"
|
||||
| "boys_er" -> let alpha_boys , d_boys = f_alpha_boys m_C in {m_alpha = alpha_boys; d = d_boys}
|
||||
| "Boys"
|
||||
| "boys"
|
||||
| "BOYS" -> let theta_boys, b_boys = f_theta m_C in {m_alpha = theta_boys; d = 1. /. b_boys}
|
||||
| "ER"
|
||||
| "er" -> let alpha_er , d_er = f_alpha m_C in {m_alpha = alpha_er; d = d_er}
|
||||
| _ -> invalid_arg "Unknown method, please enter Boys or ER"
|
||||
|
||||
in
|
||||
alpha methode
|
||||
in
|
||||
(* 6. Norme d'une matrice *)
|
||||
|
||||
let norme m =
|
||||
|
||||
let vec_m = Mat.as_vec m in
|
||||
let vec2 = Vec.sqr vec_m
|
||||
in
|
||||
sqrt(Vec.sum vec2)
|
||||
in
|
||||
|
||||
(* 7. Détermination de alpha_max et ses indices i et j.
|
||||
Si alpha max > pi/2 on soustrait pi/2 à la matrice des alphas de manière récursive
|
||||
Si alpha max < pi/2 on ajoute pi/2 à la matrice des alphas de manière récursive *)
|
||||
let rec new_m_alpha m_alpha m_C n_rec_alpha=
|
||||
|
||||
let n_mo = Mat.dim2 m_C in
|
||||
let alpha_m =
|
||||
|
||||
(*Printf.printf "%i\n%!" n_rec_alpha;*)
|
||||
|
||||
if n_rec_alpha == 0
|
||||
then m_alpha
|
||||
else
|
||||
Mat.init_cols n_mo n_mo (fun i j ->
|
||||
if (m_alpha.{i,j}) >= (pi /. 2.)
|
||||
then (m_alpha.{i,j} -. ( pi /. 2.))
|
||||
else if m_alpha.{i,j} <= -. pi /. 2.
|
||||
then (m_alpha.{i,j} +. ( pi /. 2.))
|
||||
else m_alpha.{i,j} )
|
||||
in
|
||||
|
||||
(*Util.debug_matrix "alpha_m" alpha_m;*)
|
||||
|
||||
(* Détermination de l'emplacement du alpha max *)
|
||||
let max_element alpha_m =
|
||||
|
||||
Mat.as_vec alpha_m
|
||||
|> iamax
|
||||
in
|
||||
|
||||
(* indice i et j du alpha max *)
|
||||
let indice_ii, indice_jj =
|
||||
|
||||
let max = max_element alpha_m
|
||||
in
|
||||
(max - 1) mod n_mo +1, (max - 1) / n_mo +1
|
||||
in
|
||||
|
||||
(* Valeur du alpha max*)
|
||||
let alpha alpha_m =
|
||||
|
||||
let i = indice_ii in
|
||||
let j = indice_jj
|
||||
in
|
||||
|
||||
(*Printf.printf "%i %i\n%!" i j;*)
|
||||
|
||||
alpha_m.{i,j}
|
||||
|
||||
in
|
||||
let alpha_max = alpha alpha_m in
|
||||
|
||||
(*Printf.printf "%f\n%!" alpha_max;*)
|
||||
|
||||
if alpha_max < pi /. 2.
|
||||
then {alpha_max; indice_ii; indice_jj}
|
||||
else new_m_alpha alpha_m m_C (n_rec_alpha-1)
|
||||
in
|
||||
|
||||
(* 8. Matrice de rotation 2 par 2 *)
|
||||
let f_R alpha =
|
||||
|
||||
Mat.init_cols 2 2 (fun i j ->
|
||||
if i=j
|
||||
then cos alpha
|
||||
else if i>j
|
||||
then sin alpha
|
||||
else -. sin alpha )
|
||||
in
|
||||
|
||||
(* 9. Matrice de rotation n par n avec un angle fixe *)
|
||||
let rotate m_C angle=
|
||||
|
||||
let n_mo = Mat.dim2 m_C in
|
||||
|
||||
(* Antisymétrisation et 0 sur la diagonale*)
|
||||
let m_angle angle=
|
||||
|
||||
Mat.init_cols n_mo n_mo (fun i j ->
|
||||
if i = j
|
||||
then 0.
|
||||
else if i>j
|
||||
then -. angle
|
||||
else angle)
|
||||
in
|
||||
|
||||
(*Util.debug_matrix "m" m;*)
|
||||
let m = m_angle angle in
|
||||
(* Mise au carré -> X² *)
|
||||
let mm = gemm m m in
|
||||
|
||||
(*Util.debug_matrix "mm" mm;*)
|
||||
|
||||
(* Diagonalisation de X² -> diag = vecteur contenant les eigenvalues (-tau²),
|
||||
m_angle2 -> Matrice avec les eigenvectors (W) *)
|
||||
let diag = syev ~vectors:true mm in
|
||||
(* Passage de -tau² à tau² *)
|
||||
let square_tau= Vec.abs diag in
|
||||
(* Passage de tau² à tau *)
|
||||
let tau = Vec.sqrt square_tau in
|
||||
(* Calcul de cos tau à partir du vecteur tau *)
|
||||
let cos_tau = Vec.cos tau in
|
||||
(* Matrice cos tau *)
|
||||
let m_cos_tau =
|
||||
|
||||
Mat.init_cols n_mo n_mo (fun i j ->
|
||||
if i=j
|
||||
then cos_tau.{i}
|
||||
else 0.)
|
||||
in
|
||||
|
||||
(*Util.debug_matrix "m_cos_tau" m_cos_tau;*)
|
||||
|
||||
(* Calcul de sin tau à partir du vecteur tau *)
|
||||
let sin_tau = Vec.sin tau in
|
||||
(* Matrice de sin tau *)
|
||||
let m_sin_tau =
|
||||
|
||||
Mat.init_cols n_mo n_mo (fun i j ->
|
||||
if i=j
|
||||
then sin_tau.{i}
|
||||
else 0.)
|
||||
in
|
||||
|
||||
(*Util.debug_matrix "m_sin_tau" m_sin_tau;*)
|
||||
|
||||
(* Calcul de la transposée de W (m_angles2) *)
|
||||
let transpose_mm = Mat.transpose_copy mm in
|
||||
|
||||
(*Util.debug_matrix "transpose_mm" transpose_mm;*)
|
||||
|
||||
(* Calcul du vecteur tau^-1 *)
|
||||
let tau_1 =
|
||||
|
||||
Vec.init n_mo (fun i ->
|
||||
if tau.{i}<= 0.001
|
||||
then 1.
|
||||
else 1. /. tau.{i})
|
||||
in
|
||||
(* Calcul de la matrice tau^⁻1 *)
|
||||
let m_tau_1 =
|
||||
|
||||
Mat.init_cols n_mo n_mo (fun i j ->
|
||||
if i=j
|
||||
then tau_1.{i}
|
||||
else 0.)
|
||||
in
|
||||
|
||||
(*Util.debug_matrix "m_tau_1" m_tau_1;*)
|
||||
|
||||
(* gemm mm (gemm m_cos_tau transpose_mm) -> W cos(tau) Wt *)
|
||||
let a = gemm mm (gemm m_cos_tau transpose_mm) in
|
||||
|
||||
(*Util.debug_matrix "a" a;*)
|
||||
|
||||
(* gemm mm (gemm m_tau_1 ( gemm m_sin_tau (gemm transpose_mm m))) -> W tau^-1 sin(tau) Wt X *)
|
||||
let b = gemm mm (gemm m_tau_1 ( gemm m_sin_tau (gemm transpose_mm m))) in
|
||||
|
||||
(*Util.debug_matrix "b" b;*)
|
||||
|
||||
(* Somme de 2 matrices, ici -> a + b -> R *)
|
||||
let m_r = Mat.add a b (* Matrice de rotation R *)
|
||||
in
|
||||
gemm m_C m_r
|
||||
in
|
||||
|
||||
(* 10. Fonction d'extraction des 2 vecteurs propres i et j de la matrice des OMs pour les mettres dans la matrice Ksi (n par 2)
|
||||
pour appliquer R afin d'effectuer la rotation des orbitales *) (* {1,2} -> 1ere ligne, 2e colonne *)
|
||||
let f_Ksi indice_i indice_j m_C =
|
||||
|
||||
let n_ao = Mat.dim1 m_C
|
||||
in
|
||||
Mat.init_cols n_ao 2 (fun i j ->
|
||||
if j=1
|
||||
then m_C.{i,indice_i}
|
||||
else m_C.{i,indice_j} )
|
||||
in
|
||||
|
||||
(* 11. Fonction de calcul de ksi~ (matrice n par 2), nouvelle matrice par application de la matrice de rotation dans laquelle
|
||||
on obtient les deux orbitales que l'on va réinjecter dans la matrice Phi*)
|
||||
let f_Ksi_tilde m_R m_Ksi m_C =
|
||||
|
||||
gemm m_Ksi m_R
|
||||
in
|
||||
|
||||
(* 12. Fonction pour la création de matrice intermédiaire pour supprimer i j et ajouter i~ et j~ *)
|
||||
let f_k mat indice_i indice_j m_C =
|
||||
|
||||
let n_mo = Mat.dim2 m_C in
|
||||
let n_ao = Mat.dim1 m_C
|
||||
in
|
||||
Mat.init_cols n_ao n_mo (fun i j ->
|
||||
if j=indice_i
|
||||
then mat.{i,1}
|
||||
else if j=indice_j
|
||||
then mat.{i,2}
|
||||
else 0.)
|
||||
in
|
||||
|
||||
(* 13. Matrice intérmédiaire où les orbitales i et j ont été supprimées et remplacées par des 0, par soustraction de la matrice Phi
|
||||
par la matrice *)
|
||||
let f_interm m_C m_Psi =
|
||||
|
||||
Mat.sub m_C m_Psi
|
||||
in
|
||||
|
||||
(* III. Localisation des OMs *)
|
||||
|
||||
(* 1. Boucle de calcul de la nouvelle matrice des coefficient après n rotation d'orbitales *)
|
||||
let rec localisation m_C methode epsilon n prev_critere_D prev_m_alpha cc max_D=
|
||||
|
||||
(*Printf.printf "%i\n%!" n;*)
|
||||
(*Printf.printf "%f\n%!" epsilon;*)
|
||||
(*Util.debug_matrix "m_C" m_C;
|
||||
Util.debug_matrix "new_alpha_m" prev_m_alpha;*)
|
||||
|
||||
if n == 0
|
||||
then m_C
|
||||
else
|
||||
|
||||
(* Fonction de calcul de la nouvelle matrice de coef après rotation d'un angle alpha *)
|
||||
let new_m_C m_C methode m_alpha epsilon =
|
||||
|
||||
(* alphaij contient le alpha max ainsi que ses indices i et j *)
|
||||
let n_rec_alpha = 10 in (* Nombre ditération max pour réduire les valeurs de alpha *)
|
||||
let alphaij = new_m_alpha m_alpha m_C n_rec_alpha in
|
||||
|
||||
(* Valeur de alpha max après calcul *) (* Epsilon = Pas <1. , 1. -> normal, sinon Pas plus petit *)
|
||||
let alpha = (alphaij.alpha_max) *. epsilon in
|
||||
|
||||
(*Printf.printf "%f\n%!" alpha;*)
|
||||
|
||||
(* Indice i et j du alpha max après calcul *)
|
||||
let indice_i = alphaij.indice_ii in
|
||||
let indice_j = alphaij.indice_jj in
|
||||
|
||||
(*Printf.printf "%i %i\n%!" indice_i indice_j;*)
|
||||
|
||||
(* Matrice de rotation *)
|
||||
let m_R = f_R alpha in
|
||||
|
||||
(*Util.debug_matrix "m_R" m_R;*)
|
||||
|
||||
(* Matrice qui va subir la rotation *)
|
||||
let m_Ksi = f_Ksi indice_i indice_j m_C in
|
||||
|
||||
(*Util.debug_matrix "m_Ksi" m_Ksi;*)
|
||||
|
||||
(* Matrice ayant subit la rotation *)
|
||||
let m_Ksi_tilde = f_Ksi_tilde m_R m_Ksi m_C in
|
||||
|
||||
(*Util.debug_matrix "m_Ksi_tilde" m_Ksi_tilde;*)
|
||||
|
||||
(* Matrice pour supprimerles coef des orbitales i et j dans la matrice des coef *)
|
||||
let m_Psi = f_k m_Ksi indice_i indice_j m_C in
|
||||
|
||||
(*Util.debug_matrix "m_Psi" m_Psi;*)
|
||||
|
||||
(* Matrice pour ajouter les coef des orbitales i~ et j~ dans la matrice des coef *)
|
||||
let m_Psi_tilde = f_k m_Ksi_tilde indice_i indice_j m_C in
|
||||
|
||||
(*Util.debug_matrix "m_Psi_tilde" m_Psi_tilde;*)
|
||||
|
||||
(* Matrice avec les coef des orbitales i et j remplacés par 0 *)
|
||||
let m_interm = f_interm m_C m_Psi
|
||||
|
||||
(*Util.debug_matrix "m_interm" m_interm;*)
|
||||
in
|
||||
(* Matrice après rotation *)
|
||||
(Mat.add m_Psi_tilde m_interm, alpha)
|
||||
|
||||
in
|
||||
(* Extraction de la nouvelle matrice des coef et du alpha_max *)
|
||||
let m_new_m_C, alpha_max = new_m_C m_C methode prev_m_alpha epsilon in
|
||||
|
||||
(* Fonction de pattern matching en fonction de la méthode *)
|
||||
let alphad = m_alpha_d methode m_new_m_C in
|
||||
|
||||
(* Matrice des alphas *)
|
||||
let m_alpha = alphad.m_alpha in
|
||||
|
||||
(* Critères possibles de localisation -> norme_alpha, moyenne_alpha, alpha, diff *)
|
||||
|
||||
(* Norme de m_alpha, moyenne et max *)
|
||||
|
||||
let norme_alpha = norme m_alpha in
|
||||
let moyenne_alpha = norme_alpha /. (float_of_int((Mat.dim1 m_C)* (Mat.dim2 m_C))) in
|
||||
let alpha = alpha_max /. epsilon in
|
||||
|
||||
|
||||
(* D critère à maximiser *)
|
||||
let critere_D = alphad.d in
|
||||
let diff = max_D -. critere_D in
|
||||
|
||||
(*Printf.printf "%f\n%!" diff;*)
|
||||
Printf.printf "%i %f %f %f %f %f\n%!" n max_D critere_D alpha norme_alpha moyenne_alpha;
|
||||
|
||||
let max_D =
|
||||
if diff > 0.
|
||||
then max_D
|
||||
else critere_D
|
||||
in
|
||||
(*Util.debug_matrix "new_alpha_m" m_alpha;*)
|
||||
(*Util.debug_matrix "m_new_m_C" m_new_m_C;*)
|
||||
|
||||
|
||||
(* Critère de conv pour sortir *)
|
||||
if alpha_max**2. < cc**2.
|
||||
then m_new_m_C
|
||||
else localisation m_new_m_C methode epsilon (n-1) critere_D m_alpha cc max_D
|
||||
in
|
||||
|
||||
(* 2. Fonction de localisation *)
|
||||
let localise localisation m_C methode epsilon n cc =
|
||||
|
||||
let alphad = m_alpha_d methode m_C in
|
||||
let prev_m_alpha = alphad.m_alpha in
|
||||
let prev_critere_D = 0. in
|
||||
let max_D = 0.
|
||||
in
|
||||
localisation m_C methode epsilon n prev_critere_D prev_m_alpha cc max_D
|
||||
in
|
||||
|
||||
(* IV : Fonctions pour la séparation et le rassemblement des matrices *)
|
||||
|
||||
(* 1. Fonction de création d'une liste d'entier à partir d'un vecteur de float*)
|
||||
let int_list vec =
|
||||
|
||||
let float_list = Vec.to_list vec in
|
||||
let g a = int_of_float(a)
|
||||
in
|
||||
List.map g float_list
|
||||
in
|
||||
|
||||
(* 2. Fonction créant une liste à partir des éléments manquant d'une autre liste, dans l'intervalle [1 ; n_mo] *)
|
||||
let miss_elem mat list =
|
||||
|
||||
let n_mo = Mat.dim2 mat in
|
||||
let vec = Vec.init (n_mo) (fun i ->
|
||||
if List.mem i list
|
||||
then 0.
|
||||
else float_of_int(i))
|
||||
in
|
||||
let list_int = int_list vec
|
||||
in
|
||||
List.filter (fun x -> x > 0) list_int
|
||||
in
|
||||
|
||||
(* 3. Fonction de séparation d'une matrice en 2 sous matrice, la première matrice correspondant aux colonnes de la matrice dont le numéro est présent
|
||||
dans la liste et la seconde à celles dont le numéro de colonne n'est pas présent dans la liste *)
|
||||
let split_mat mat list =
|
||||
|
||||
let vec_of_mat = Mat.to_col_vecs mat in
|
||||
let f a = vec_of_mat.(a-1) in
|
||||
let vec_list_1 = List.map f list in
|
||||
let list_2 = miss_elem mat list in
|
||||
let vec_list_2 = List.map f list_2
|
||||
in
|
||||
(Mat.of_col_vecs_list vec_list_1,Mat.of_col_vecs_list vec_list_2)
|
||||
in
|
||||
|
||||
(* 4. Liste des OMs occupées *)
|
||||
let list_occ =
|
||||
|
||||
let vec_occ = Vec.init (nocc) (fun i -> float_of_int(i))
|
||||
in
|
||||
int_list vec_occ
|
||||
in
|
||||
|
||||
(* 5. Liste des OMs de coeur *)
|
||||
let list_core =
|
||||
let vec_core = Vec.init (n_core) (fun i -> float_of_int(i))
|
||||
in int_list vec_core
|
||||
in
|
||||
|
||||
(* 6. Liste des OMs pi au sein des OMs virtuelles *)
|
||||
let list_pi mat =
|
||||
let n_ao = Mat.dim1 m_C in
|
||||
let n_mo = Mat.dim2 m_C in
|
||||
let m_pi = Mat.init_cols n_ao n_mo ( fun i j ->
|
||||
if m_C.{i,j}**2. < 10e-8**2.
|
||||
then 0.
|
||||
else m_C.{i,j})
|
||||
in
|
||||
(*Printf.printf "%i\n" nocc;
|
||||
Util.debug_matrix "m_pi" m_pi;*)
|
||||
let vec = Mat.to_col_vecs m_pi in
|
||||
let vec_dot = Vec.init (n_mo-nocc) (fun i -> dot vec.(0) vec.(i-1+nocc))
|
||||
in
|
||||
let vec_pi = Vec.init (n_mo-nocc) (fun i ->
|
||||
if vec_dot.{i} = 0.
|
||||
then float_of_int(i)
|
||||
else 0.)
|
||||
in
|
||||
let list_pi = int_list vec_pi in
|
||||
let rec remove x list =
|
||||
match list with
|
||||
| [] -> []
|
||||
| var :: tail -> if var = x
|
||||
then remove x tail
|
||||
else var :: (remove x tail)
|
||||
in
|
||||
remove 0 list_pi
|
||||
in
|
||||
(* 7. Fonction de rassemblement de 2 matrices *)
|
||||
let assemble m_occ m_vir =
|
||||
|
||||
let v_occ = Mat.to_col_vecs m_occ in
|
||||
let v_vir = Mat.to_col_vecs m_vir in
|
||||
let m = Array.append v_occ v_vir
|
||||
in
|
||||
Mat.of_col_vecs m
|
||||
in
|
||||
|
||||
(* V. Calcul *)
|
||||
|
||||
(* 1. Séparation des OMs -> m_occ : OMs occupées; m_vir : OMs vacantes, puis des orbitales de coeur : m_core et occupées : m_occu *)
|
||||
let m_occ , m_vir = split_mat m_C list_occ in
|
||||
(* Util.debug_matrix "m_vir" m_vir;*)
|
||||
let m_core, m_occu = split_mat m_occ list_core in
|
||||
let dim_m_core = Mat.dim1 m_core in
|
||||
|
||||
let list_split_vir2 = list_pi m_vir in
|
||||
|
||||
let m_vir2, m_vir1 = split_mat m_vir list_split_vir2 in
|
||||
(* Util.debug_matrix "m_vir1" m_vir1;
|
||||
Util.debug_matrix "m_vir2" m_vir2;*)
|
||||
let dim_m_vir2 = Mat.dim1 m_vir2 in
|
||||
(*Util.debug_matrix "m_vir2" m_vir2;*)
|
||||
(* 2. Application d'une légère rotation d'un angle fixé aux OMs pour améliorer la convergence *)
|
||||
let new_core =
|
||||
if dim_m_core = 0
|
||||
then m_core
|
||||
else rotate m_core 0.001
|
||||
in
|
||||
let new_occu = rotate m_occu 0.001 in
|
||||
|
||||
let new_vir2 =
|
||||
if dim_m_vir2 = 0
|
||||
then m_vir2
|
||||
else rotate m_vir2 0.001
|
||||
in
|
||||
let new_vir1 = rotate m_vir1 0.001 in
|
||||
|
||||
(* 3. Légende *)
|
||||
let texte = "Methode : " ^ methode ^ "; Nombre iterarion : " ^ string_of_int(iteration) ^ "; cc : " ^ string_of_float(cc)^string_of_float(epsilon) in
|
||||
let legende = "n max_D Critere_D alpha_max norme_alpha moyenne_alpha"
|
||||
in
|
||||
Printf.printf "%s\n" "";
|
||||
Printf.printf "%s\n" "Localisation des orbitales";
|
||||
Printf.printf "%s\n" "";
|
||||
Printf.printf "%s\n" texte;
|
||||
Printf.printf "%s\n" "";
|
||||
Printf.printf "%s\n" legende;
|
||||
Printf.printf "%s\n" "";
|
||||
|
||||
(* 4. Rotation des orbitales : localise localisation new_X / "methode" / epsilon = 1. si <1 diminue l'angle des rotations / nb itération / critère de convergence *)
|
||||
Printf.printf "%s\n" "Localisation orbitales de coeurs, 1/4";
|
||||
let loc_m_core =
|
||||
if dim_m_core= 0
|
||||
then new_core
|
||||
else localise localisation new_core methode epsilon iteration cc
|
||||
in
|
||||
Printf.printf "%s\n" "";
|
||||
Printf.printf "%s\n" "Localisation orbitales occupées, 2/4";
|
||||
let loc_m_occu = localise localisation new_occu methode epsilon iteration cc
|
||||
in
|
||||
Printf.printf "%s\n" "";
|
||||
Printf.printf "%s\n" "Localisation orbitales virtuelles pi, 3/4";
|
||||
let loc_m_vir2 =
|
||||
if dim_m_vir2 = 0
|
||||
then new_vir2
|
||||
else localise localisation new_vir2 methode epsilon iteration cc
|
||||
in
|
||||
Printf.printf "%s\n" "";
|
||||
Printf.printf "%s\n" "Localisation orbitales virtuelles sigma, 4/4";
|
||||
let loc_m_vir1 = localise localisation new_vir1 methode epsilon iteration cc
|
||||
in
|
||||
|
||||
(* 5. Rassemblement des occupées et des virtuelles *)
|
||||
let m_assemble_occ = assemble loc_m_core loc_m_occu
|
||||
in
|
||||
let m_assemble_vir = assemble loc_m_vir2 loc_m_vir1
|
||||
in
|
||||
let m_assemble_loc = assemble m_assemble_occ m_assemble_vir
|
||||
in
|
||||
m_assemble_loc
|
682
Work.ipynb
682
Work.ipynb
|
@ -152,33 +152,7 @@
|
|||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## H$_2$O"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"hidden": true
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"(*\n",
|
||||
"let xyz_string = \n",
|
||||
"\"3\n",
|
||||
"Water\n",
|
||||
"O 0. 0. 0.\n",
|
||||
"H -0.756950272703377558 0. -0.585882234512562827\n",
|
||||
"H 0.756950272703377558 0. -0.585882234512562827\n",
|
||||
"\"\n",
|
||||
"*)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### H$_4$"
|
||||
"### H$_n$"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
@ -189,7 +163,7 @@
|
|||
"source": [
|
||||
"(* Fonction création chaîne linéaire de n H *)\n",
|
||||
"\n",
|
||||
"let xyz d n = \n",
|
||||
"(*let xyz d n = \n",
|
||||
" let accu = \"\"\n",
|
||||
" in\n",
|
||||
" let rec toto accu d n =\n",
|
||||
|
@ -204,7 +178,20 @@
|
|||
" accu\n",
|
||||
" in string_of_int(n) ^ \"\\nH\" ^ string_of_int(n) ^ \"\\n\" ^ toto accu d n;;\n",
|
||||
" \n",
|
||||
"let xyz_string = xyz 1.8 10;;\n"
|
||||
"let xyz_string = xyz 1.8 6;;\n",
|
||||
"*)\n",
|
||||
"let xyz_string = \n",
|
||||
"\"8 \n",
|
||||
"C1\n",
|
||||
"C 0.000000 0.000000 0.424165\n",
|
||||
"H 0.000000 0.000000 1.508704\n",
|
||||
"N 0.000000 1.158087 -0.174215\n",
|
||||
"N 0.000000 -1.158087 -0.174215\n",
|
||||
"H 0.000000 1.258360 -1.178487\n",
|
||||
"H 0.000000 2.005112 0.371143\n",
|
||||
"H 0.000000 -2.005112 0.371143\n",
|
||||
"H 0.000000 -1.258360 -1.178487\n",
|
||||
"\""
|
||||
]
|
||||
},
|
||||
{
|
||||
|
@ -235,67 +222,65 @@
|
|||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"\n",
|
||||
"let basis_string = \n",
|
||||
"\"HYDROGEN\n",
|
||||
"S 3\n",
|
||||
"1 0.1873113696E+02 0.3349460434E-01\n",
|
||||
"2 0.2825394365E+01 0.2347269535E+00\n",
|
||||
"3 0.6401216923E+00 0.8137573261E+00\n",
|
||||
"S 1\n",
|
||||
"1 0.1612777588E+00 1.0000000\n",
|
||||
"\n",
|
||||
"CARBON\n",
|
||||
"S 6\n",
|
||||
"1 0.3552322122E+02 0.9163596281E-02\n",
|
||||
"2 0.6513143725E+01 0.4936149294E-01\n",
|
||||
"3 0.1822142904E+01 0.1685383049E+00\n",
|
||||
"4 0.6259552659E+00 0.3705627997E+00\n",
|
||||
"5 0.2430767471E+00 0.4164915298E+00\n",
|
||||
"6 0.1001124280E+00 0.1303340841E+00\n",
|
||||
"\"\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"(*\n",
|
||||
"let basis_string = \n",
|
||||
"\"\n",
|
||||
"HYDROGEN\n",
|
||||
"S 4\n",
|
||||
"1 1.301000E+01 1.968500E-02\n",
|
||||
"2 1.962000E+00 1.379770E-01\n",
|
||||
"3 4.446000E-01 4.781480E-01\n",
|
||||
"4 1.220000E-01 5.012400E-01\n",
|
||||
"1 0.3047524880E+04 0.1834737132E-02\n",
|
||||
"2 0.4573695180E+03 0.1403732281E-01\n",
|
||||
"3 0.1039486850E+03 0.6884262226E-01\n",
|
||||
"4 0.2921015530E+02 0.2321844432E+00\n",
|
||||
"5 0.9286662960E+01 0.4679413484E+00\n",
|
||||
"6 0.3163926960E+01 0.3623119853E+00\n",
|
||||
"S 3\n",
|
||||
"1 0.7868272350E+01 -0.1193324198E+00\n",
|
||||
"2 0.1881288540E+01 -0.1608541517E+00\n",
|
||||
"3 0.5442492580E+00 0.1143456438E+01\n",
|
||||
"S 1\n",
|
||||
"1 1.220000E-01 1.000000E+00\n",
|
||||
"1 0.1687144782E+00 0.1000000000E+01\n",
|
||||
"P 3\n",
|
||||
"1 0.7868272350E+01 0.6899906659E-01\n",
|
||||
"2 0.1881288540E+01 0.3164239610E+00\n",
|
||||
"3 0.5442492580E+00 0.7443082909E+00\n",
|
||||
"P 1\n",
|
||||
"1 7.270000E-01 1.0000000\n",
|
||||
"1 0.1687144782E+00 0.1000000000E+01\n",
|
||||
"\n",
|
||||
"OXYGEN\n",
|
||||
"S 9\n",
|
||||
"1 1.172000E+04 7.100000E-04\n",
|
||||
"2 1.759000E+03 5.470000E-03\n",
|
||||
"3 4.008000E+02 2.783700E-02\n",
|
||||
"4 1.137000E+02 1.048000E-01\n",
|
||||
"5 3.703000E+01 2.830620E-01\n",
|
||||
"6 1.327000E+01 4.487190E-01\n",
|
||||
"7 5.025000E+00 2.709520E-01\n",
|
||||
"8 1.013000E+00 1.545800E-02\n",
|
||||
"9 3.023000E-01 -2.585000E-03\n",
|
||||
"S 9\n",
|
||||
"1 1.172000E+04 -1.600000E-04\n",
|
||||
"2 1.759000E+03 -1.263000E-03\n",
|
||||
"3 4.008000E+02 -6.267000E-03\n",
|
||||
"4 1.137000E+02 -2.571600E-02\n",
|
||||
"5 3.703000E+01 -7.092400E-02\n",
|
||||
"6 1.327000E+01 -1.654110E-01\n",
|
||||
"7 5.025000E+00 -1.169550E-01\n",
|
||||
"8 1.013000E+00 5.573680E-01\n",
|
||||
"9 3.023000E-01 5.727590E-01\n",
|
||||
"NITROGEN\n",
|
||||
"S 6\n",
|
||||
"1 0.4173511460E+04 0.1834772160E-02\n",
|
||||
"2 0.6274579110E+03 0.1399462700E-01\n",
|
||||
"3 0.1429020930E+03 0.6858655181E-01\n",
|
||||
"4 0.4023432930E+02 0.2322408730E+00\n",
|
||||
"5 0.1282021290E+02 0.4690699481E+00\n",
|
||||
"6 0.4390437010E+01 0.3604551991E+00\n",
|
||||
"S 3\n",
|
||||
"1 0.1162636186E+02 -0.1149611817E+00\n",
|
||||
"2 0.2716279807E+01 -0.1691174786E+00\n",
|
||||
"3 0.7722183966E+00 0.1145851947E+01\n",
|
||||
"S 1\n",
|
||||
"1 3.023000E-01 1.000000E+00\n",
|
||||
"P 4\n",
|
||||
"1 1.770000E+01 4.301800E-02\n",
|
||||
"2 3.854000E+00 2.289130E-01\n",
|
||||
"3 1.046000E+00 5.087280E-01\n",
|
||||
"4 2.753000E-01 4.605310E-01\n",
|
||||
"1 0.2120314975E+00 0.1000000000E+01\n",
|
||||
"P 3\n",
|
||||
"1 0.1162636186E+02 0.6757974388E-01\n",
|
||||
"2 0.2716279807E+01 0.3239072959E+00\n",
|
||||
"3 0.7722183966E+00 0.7408951398E+00\n",
|
||||
"P 1\n",
|
||||
"1 2.753000E-01 1.000000E+00\n",
|
||||
"D 1\n",
|
||||
"1 1.185000E+00 1.0000000\n",
|
||||
"1 0.2120314975E+00 0.1000000000E+01\n",
|
||||
"\"\n",
|
||||
"*)"
|
||||
"(*\"HYDROGEN\n",
|
||||
"S 3\n",
|
||||
"1 0.1873113696E+02 0.3349460434E-01\n",
|
||||
"2 0.2825394365E+01 0.2347269535E+00\n",
|
||||
"3 0.6401216923E+00 0.8137573261E+00\n",
|
||||
"S 1\n",
|
||||
"1 0.1612777588E+00 1.0000000\n",
|
||||
"\"*)\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
@ -326,14 +311,17 @@
|
|||
" Basis.of_nuclei_and_basis_string nuclei basis_string\n",
|
||||
" \n",
|
||||
"let simulation = \n",
|
||||
" Simulation.make ~charge:0 ~multiplicity:1 ~nuclei basis\n",
|
||||
" Simulation.make ~charge:1 ~multiplicity:1 ~nuclei basis\n",
|
||||
" \n",
|
||||
"let ao_basis = \n",
|
||||
" Simulation.ao_basis simulation\n",
|
||||
" \n",
|
||||
"let nocc =\n",
|
||||
" let elec = Simulation.electrons simulation in\n",
|
||||
" Electrons.n_alfa elec"
|
||||
" Electrons.n_alfa elec\n",
|
||||
" \n",
|
||||
"let n_core =\n",
|
||||
" (Nuclei.small_core @@ Simulation.nuclei @@ MOBasis.simulation mo_basis) / 2"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
@ -677,11 +665,13 @@
|
|||
" gemm m_X m_C' (* C = X.C' *)\n",
|
||||
" \n",
|
||||
" \n",
|
||||
"let m_C = \n",
|
||||
"let m_C = m_assemble_boys\n",
|
||||
"(*\n",
|
||||
" match Guess.make ~nocc ~guess:`Hcore ao_basis with\n",
|
||||
" | Hcore m_H -> c_of_h m_H\n",
|
||||
" | _ -> assert false\n",
|
||||
"*)"
|
||||
" *) \n",
|
||||
" *)"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
@ -762,12 +752,13 @@
|
|||
"outputs": [],
|
||||
"source": [
|
||||
"(*\n",
|
||||
"let m_C =\n",
|
||||
" let m_C', _ = \n",
|
||||
"let m_C = m_assemble_boys\n",
|
||||
"(* let m_C', _ = \n",
|
||||
" Util.xt_o_x m_F m_X\n",
|
||||
" |> Util.diagonalize_symm\n",
|
||||
" in\n",
|
||||
" gemm m_X m_C'\n",
|
||||
"*)\n",
|
||||
"*)"
|
||||
]
|
||||
},
|
||||
|
@ -1326,13 +1317,11 @@
|
|||
"let m_C = MOBasis.mo_coef mo_basis;;\n",
|
||||
"let n_ao = Mat.dim1 m_C ;;\n",
|
||||
"let n_mo = Mat.dim2 m_C ;;\n",
|
||||
"let multipoles = \n",
|
||||
" AOBasis.multipole ao_basis;;\n",
|
||||
" \n",
|
||||
"let sum a = \n",
|
||||
" Array.fold_left (fun accu x -> accu +. x) 0. a\n",
|
||||
" \n",
|
||||
"let pi = 3.14159265358979323846264338;;\n"
|
||||
"let pi = acos(-1.);;\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
@ -1481,14 +1470,17 @@
|
|||
" Printf.printf \"t = %f s\\n%!\" (t1 -. t0);*)\n",
|
||||
" \n",
|
||||
" (Mat.init_cols n_mo n_mo ( fun i j ->\n",
|
||||
" if i= j then 0.\n",
|
||||
" else 0.25 *. (acos(-. m_a12.{i,j} /. sqrt((m_a12.{i,j}**2.) +. (m_b12.{i,j}**2. ))))\n",
|
||||
" ),Vec.sum v_d);;\n",
|
||||
" if i= j \n",
|
||||
" then 0.\n",
|
||||
" else if +. 0.25 *. atan2 m_b12.{i,j} m_a12.{i,j} <= 0. \n",
|
||||
" then pi /. 4. +. 0.25 *. atan2 m_b12.{i,j} m_a12.{i,j}\n",
|
||||
" else -. pi /. 4. +. 0.25 *. atan2 m_b12.{i,j} m_a12.{i,j})\n",
|
||||
" ,Vec.sum v_d);;\n",
|
||||
"\n",
|
||||
"(*********************)\n",
|
||||
"\n",
|
||||
"f_alpha m_C;;\n",
|
||||
"let m_alpha , s_D = f_alpha m_C;;\n"
|
||||
"(*\n",
|
||||
"f_alpha m_C;;*)\n",
|
||||
"(*let m_alpha , s_D = f_alpha m_C;;*)\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
@ -1499,6 +1491,7 @@
|
|||
"source": [
|
||||
"(* Fonction calcul alpha Boys *)\n",
|
||||
"let f_alpha_boys m_C = \n",
|
||||
" let multipoles = AOBasis.multipole ao_basis in\n",
|
||||
" let n_mo = Mat.dim2 m_C\n",
|
||||
" in\n",
|
||||
" let phi_x_phi =\n",
|
||||
|
@ -1529,13 +1522,16 @@
|
|||
" in\n",
|
||||
" (Mat.init_cols n_mo n_mo ( fun i j -> \n",
|
||||
" if i=j \n",
|
||||
" then 0.\n",
|
||||
" else 0.25 *. acos(-. m_a12.{i,j} /. sqrt((m_a12.{i,j}**2.) +. (m_b12.{i,j}**2.) ))),\n",
|
||||
" Vec.sum(Vec.init n_mo ( fun i -> (phi_x_phi.{i,i})**2. +. (phi_y_phi.{i,i})**2. +. (phi_z_phi.{i,i})**2.)));;\n",
|
||||
" then 0.\n",
|
||||
" else if +. 0.25 *. atan2 m_b12.{i,j} m_a12.{i,j} >= 0.\n",
|
||||
" then pi /. 4. -. 0.25 *. atan2 m_b12.{i,j} m_a12.{i,j}\n",
|
||||
" else -. pi /. 4. -. 0.25 *. atan2 m_b12.{i,j} m_a12.{i,j})\n",
|
||||
" ,Vec.sum(Vec.init n_mo ( fun i -> (phi_x_phi.{i,i})**2. +. (phi_y_phi.{i,i})**2. +. (phi_z_phi.{i,i})**2.)));;\n",
|
||||
"\n",
|
||||
"(****************************)\n",
|
||||
"\n",
|
||||
"f_alpha_boys m_C;;\n"
|
||||
"(*\n",
|
||||
"f_alpha_boys m_C;;\n",
|
||||
"*)"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
@ -1546,61 +1542,64 @@
|
|||
"source": [
|
||||
"(* Test méthode de boys *)\n",
|
||||
"\n",
|
||||
"let f_theta m_C = \n",
|
||||
" let n_mo = Mat.dim2 m_C\n",
|
||||
" in\n",
|
||||
" let phi_x_phi =\n",
|
||||
" Multipole.matrix_x multipoles \n",
|
||||
" |> MOBasis.mo_matrix_of_ao_matrix ~mo_coef:m_C\n",
|
||||
" in \n",
|
||||
" let phi_y_phi =\n",
|
||||
" Multipole.matrix_y multipoles \n",
|
||||
" |> MOBasis.mo_matrix_of_ao_matrix ~mo_coef:m_C\n",
|
||||
" in\n",
|
||||
" let phi_z_phi =\n",
|
||||
" Multipole.matrix_z multipoles \n",
|
||||
" |> MOBasis.mo_matrix_of_ao_matrix ~mo_coef:m_C\n",
|
||||
" in\n",
|
||||
" let phi_x2_phi =\n",
|
||||
" Multipole.matrix_x2 multipoles \n",
|
||||
" |> MOBasis.mo_matrix_of_ao_matrix ~mo_coef:m_C\n",
|
||||
" in \n",
|
||||
" let phi_y2_phi =\n",
|
||||
" Multipole.matrix_y2 multipoles \n",
|
||||
" |> MOBasis.mo_matrix_of_ao_matrix ~mo_coef:m_C\n",
|
||||
" in\n",
|
||||
" let phi_z2_phi =\n",
|
||||
" Multipole.matrix_z2 multipoles \n",
|
||||
" |> MOBasis.mo_matrix_of_ao_matrix ~mo_coef:m_C\n",
|
||||
" in\n",
|
||||
" let m_b_0 =\n",
|
||||
" let b_0 g h = Mat.init_cols n_mo n_mo (fun i j ->\n",
|
||||
" h.{i,i} +. h.{j,j} -. (g.{i,i}**2. +. g.{j,j}**2.))\n",
|
||||
" in Mat.add (b_0 phi_x_phi phi_x2_phi) (Mat.add (b_0 phi_y_phi phi_y2_phi) (b_0 phi_z_phi phi_z2_phi)) \n",
|
||||
" in\n",
|
||||
" let m_beta = \n",
|
||||
" let beta g = Mat.init_cols n_mo n_mo (fun i j ->\n",
|
||||
" (g.{i,i} -. g.{j,j})**2. -. 4. *. g.{i,j}**2.)\n",
|
||||
" in Mat.add (beta phi_x_phi) (Mat.add (beta phi_y_phi) (beta phi_z_phi))\n",
|
||||
" (*in Util.debug_matrix \"m_beta\" m_beta;*)\n",
|
||||
" in\n",
|
||||
" let m_gamma = \n",
|
||||
" let gamma g = Mat.init_cols n_mo n_mo (fun i j ->\n",
|
||||
" 4. *. g.{i,j} *. (g.{i,i} -. g.{j,j}) )\n",
|
||||
" in Mat.add (gamma phi_x_phi) (Mat.add (gamma phi_y_phi) (gamma phi_z_phi))\n",
|
||||
" (*in Util.debug_matrix \"m_gamma\" m_gamma;*)\n",
|
||||
" \n",
|
||||
" in\n",
|
||||
" let m_theta = Mat.init_cols n_mo n_mo (fun i j ->\n",
|
||||
" -. 0.25 *. atan(m_gamma.{i,j} /. m_beta.{i,j}))\n",
|
||||
" in\n",
|
||||
" let m_critere_B = Mat.init_cols n_mo n_mo (fun i j ->\n",
|
||||
" m_b_0.{i,j} +. 0.25 *. ((1. -. cos(4. *. m_theta.{i,j})) *. m_beta.{i,j} +. sin(4. *. m_theta.{i,j}) *. m_gamma.{i,j}))\n",
|
||||
" in m_theta, Vec.sum(Mat.as_vec m_critere_B)\n",
|
||||
";;\n",
|
||||
" let f_theta m_C = \n",
|
||||
" let multipoles = AOBasis.multipole ao_basis in\n",
|
||||
" let n_mo = Mat.dim2 m_C\n",
|
||||
" in\n",
|
||||
" let phi_x_phi =\n",
|
||||
" Multipole.matrix_x multipoles \n",
|
||||
" |> MOBasis.mo_matrix_of_ao_matrix ~mo_coef:m_C\n",
|
||||
" in \n",
|
||||
" let phi_y_phi =\n",
|
||||
" Multipole.matrix_y multipoles \n",
|
||||
" |> MOBasis.mo_matrix_of_ao_matrix ~mo_coef:m_C\n",
|
||||
" in\n",
|
||||
" let phi_z_phi =\n",
|
||||
" Multipole.matrix_z multipoles \n",
|
||||
" |> MOBasis.mo_matrix_of_ao_matrix ~mo_coef:m_C\n",
|
||||
" in\n",
|
||||
" let phi_x2_phi =\n",
|
||||
" Multipole.matrix_x2 multipoles \n",
|
||||
" |> MOBasis.mo_matrix_of_ao_matrix ~mo_coef:m_C\n",
|
||||
" in \n",
|
||||
" let phi_y2_phi =\n",
|
||||
" Multipole.matrix_y2 multipoles \n",
|
||||
" |> MOBasis.mo_matrix_of_ao_matrix ~mo_coef:m_C\n",
|
||||
" in\n",
|
||||
" let phi_z2_phi =\n",
|
||||
" Multipole.matrix_z2 multipoles \n",
|
||||
" |> MOBasis.mo_matrix_of_ao_matrix ~mo_coef:m_C\n",
|
||||
" in\n",
|
||||
" let m_b_0 =\n",
|
||||
" let b_0 g h = Mat.init_cols n_mo n_mo (fun i j ->\n",
|
||||
" h.{i,i} +. h.{j,j} -. (g.{i,i}**2. +. g.{j,j}**2.))\n",
|
||||
" in Mat.add (b_0 phi_x_phi phi_x2_phi) (Mat.add (b_0 phi_y_phi phi_y2_phi) (b_0 phi_z_phi phi_z2_phi)) \n",
|
||||
" in\n",
|
||||
" let m_beta = \n",
|
||||
" let beta g = Mat.init_cols n_mo n_mo (fun i j ->\n",
|
||||
" (g.{i,i} -. g.{j,j})**2. -. 4. *. g.{i,j}**2.)\n",
|
||||
" in Mat.add (beta phi_x_phi) (Mat.add (beta phi_y_phi) (beta phi_z_phi))\n",
|
||||
" in (*Util.debug_matrix \"m_beta\" m_beta;*)\n",
|
||||
"\n",
|
||||
"f_theta m_C;;\n",
|
||||
"f_theta m_B;;"
|
||||
"\n",
|
||||
" let m_gamma = \n",
|
||||
" let gamma g = Mat.init_cols n_mo n_mo (fun i j ->\n",
|
||||
" 4. *. g.{i,j} *. (g.{i,i} -. g.{j,j}) )\n",
|
||||
" in Mat.add (gamma phi_x_phi) (Mat.add (gamma phi_y_phi) (gamma phi_z_phi))\n",
|
||||
" in (*Util.debug_matrix \"m_gamma\" m_gamma;*)\n",
|
||||
"\n",
|
||||
" let m_theta = Mat.init_cols n_mo n_mo (fun i j ->\n",
|
||||
" if i = j \n",
|
||||
" then 0.\n",
|
||||
" else +. 0.25 *. atan2 m_gamma.{i,j} m_beta.{i,j})\n",
|
||||
" in (*Util.debug_matrix \"m_theta\" m_theta;*)\n",
|
||||
"\n",
|
||||
" let m_critere_B = Mat.init_cols n_mo n_mo (fun i j ->\n",
|
||||
" m_b_0.{i,j} +. 0.25 *. ((1. -. cos(4. *. m_theta.{i,j})) *. m_beta.{i,j} +. sin(4. *. m_theta.{i,j}) *. m_gamma.{i,j}))\n",
|
||||
" in m_theta, Vec.sum(Mat.as_vec m_critere_B)\n",
|
||||
";;\n",
|
||||
"(*\n",
|
||||
"f_theta m_C;;*)"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
@ -1619,9 +1618,9 @@
|
|||
" let alpha methode =\n",
|
||||
" \n",
|
||||
" match methode with \n",
|
||||
" | \"Boys\"\n",
|
||||
" | \"boys\" -> let alpha_boys , d_boys = f_alpha_boys m_C in {m_alpha = alpha_boys; d = d_boys}\n",
|
||||
" | \"BOYS\" -> let theta_boys, b_boys = f_theta m_C in {m_alpha = theta_boys; d = b_boys}\n",
|
||||
" | \"Boys_er\"\n",
|
||||
" | \"boys_er\" -> let alpha_boys , d_boys = f_alpha_boys m_C in {m_alpha = alpha_boys; d = d_boys}\n",
|
||||
" | \"BOYS\" -> let theta_boys, b_boys = f_theta m_C in {m_alpha = theta_boys; d = 1. /. b_boys}\n",
|
||||
" | \"ER\"\n",
|
||||
" | \"er\" -> let alpha_er , d_er = f_alpha m_C in {m_alpha = alpha_er; d = d_er}\n",
|
||||
" | _ -> invalid_arg \"Unknown method, please enter Boys or ER\"\n",
|
||||
|
@ -1633,7 +1632,7 @@
|
|||
"(*\n",
|
||||
"m_alpha_d \"ER\" ;;\n",
|
||||
"m_alpha_d \"Boys\" ;;\n",
|
||||
"let methode = \"ER\";;\n",
|
||||
"let methode = \"BOYS\"\n",
|
||||
"let alphad = m_alpha_d methode m_C;;\n",
|
||||
"let m_alpha = alphad.m_alpha;;\n",
|
||||
"let d = alphad.d;;\n",
|
||||
|
@ -1688,8 +1687,6 @@
|
|||
" then (m_alpha.{i,j} -. ( pi /. 2.))\n",
|
||||
" else if m_alpha.{i,j} <= -. pi /. 2.\n",
|
||||
" then (m_alpha.{i,j} +. ( pi /. 2.))\n",
|
||||
" else if m_alpha.{i,j} < 0. \n",
|
||||
" then -. m_alpha.{i,j}\n",
|
||||
" else m_alpha.{i,j} )\n",
|
||||
" in \n",
|
||||
" \n",
|
||||
|
@ -1731,7 +1728,7 @@
|
|||
"\n",
|
||||
"(*************************)\n",
|
||||
"(*\n",
|
||||
"let m_alpha,d = f_alpha m_C\n",
|
||||
"let m_alpha,d = f_theta m_C\n",
|
||||
"let alphaij = new_m_alpha m_alpha m_C 3;;\n",
|
||||
"alphaij.alpha_max;;\n",
|
||||
"*)"
|
||||
|
@ -1759,6 +1756,182 @@
|
|||
"*)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"(* Matrice de rotation n par n *)\n",
|
||||
" let new_c m_C angle= \n",
|
||||
" let n_mo = Mat.dim2 m_C in\n",
|
||||
"\n",
|
||||
" (* Antisymétrisation et 0 sur la diagonale*)\n",
|
||||
" let m_angle angle= Mat.init_cols n_mo n_mo (fun i j ->\n",
|
||||
" if i = j \n",
|
||||
" then 0.\n",
|
||||
" else if i>j \n",
|
||||
" then -. angle\n",
|
||||
" else angle) in\n",
|
||||
"\n",
|
||||
" (*Util.debug_matrix \"m\" m;*)\n",
|
||||
" let m = m_angle angle in\n",
|
||||
" (* Mise au carré -> X² *)\n",
|
||||
" let mm = gemm m m in\n",
|
||||
"\n",
|
||||
" (*Util.debug_matrix \"mm\" mm;*)\n",
|
||||
"\n",
|
||||
" (* Diagonalisation de X² -> diag = vecteur contenant les eigenvalues (-tau²),\n",
|
||||
" m_angle2 -> Matrice avec les eigenvectors (W) *)\n",
|
||||
" let diag = syev ~vectors:true mm in\n",
|
||||
" (* Passage de -tau² à tau² *)\n",
|
||||
" let square_tau= Vec.abs diag in\n",
|
||||
" (* Passage de tau² à tau *)\n",
|
||||
" let tau = Vec.sqrt square_tau in \n",
|
||||
" (* Calcul de cos tau à partir du vecteur tau *)\n",
|
||||
" let cos_tau = Vec.cos tau in\n",
|
||||
" (* Matrice cos tau *)\n",
|
||||
" let m_cos_tau = Mat.init_cols n_mo n_mo (fun i j -> if i=j then cos_tau.{i} else 0.) in\n",
|
||||
"\n",
|
||||
" (*Util.debug_matrix \"m_cos_tau\" m_cos_tau;*)\n",
|
||||
"\n",
|
||||
" (* Calcul de sin tau à partir du vecteur tau *)\n",
|
||||
" let sin_tau = Vec.sin tau in \n",
|
||||
" (* Matrice de sin tau *)\n",
|
||||
" let m_sin_tau = Mat.init_cols n_mo n_mo (fun i j -> if i=j then sin_tau.{i} else 0.) in\n",
|
||||
"\n",
|
||||
" (*Util.debug_matrix \"m_sin_tau\" m_sin_tau;*)\n",
|
||||
"\n",
|
||||
" (* Calcul de la transposée de W (m_angles2) *)\n",
|
||||
" let transpose_mm = Mat.transpose_copy mm in\n",
|
||||
"\n",
|
||||
" (*Util.debug_matrix \"transpose_mm\" transpose_mm;*)\n",
|
||||
"\n",
|
||||
" (* Calcul du vecteur tau^-1 *)\n",
|
||||
" let tau_1 = Vec.init n_mo (fun i -> if tau.{i}<= 0.001 then 1.\n",
|
||||
" else 1. /. tau.{i}) in\n",
|
||||
" (* Calcul de la matrice tau^⁻1 *)\n",
|
||||
" let m_tau_1 = Mat.init_cols n_mo n_mo (fun i j -> if i=j then tau_1.{i} else 0.) in\n",
|
||||
"\n",
|
||||
" (*Util.debug_matrix \"m_tau_1\" m_tau_1;*)\n",
|
||||
"\n",
|
||||
" (* gemm mm (gemm m_cos_tau transpose_mm) -> W cos(tau) Wt *)\n",
|
||||
" let a = gemm mm (gemm m_cos_tau transpose_mm) in\n",
|
||||
"\n",
|
||||
" (*Util.debug_matrix \"a\" a;*)\n",
|
||||
"\n",
|
||||
" (* gemm mm (gemm m_tau_1 ( gemm m_sin_tau (gemm transpose_mm m))) -> W tau^-1 sin(tau) Wt X *)\n",
|
||||
" let b = gemm mm (gemm m_tau_1 ( gemm m_sin_tau (gemm transpose_mm m))) in\n",
|
||||
"\n",
|
||||
" (*Util.debug_matrix \"b\" b;*)\n",
|
||||
"\n",
|
||||
" (* Somme de 2 matrices, ici -> a + b -> R *)\n",
|
||||
" let m_r = Mat.add a b (* Matrice de rotation R *)\n",
|
||||
" in gemm m_C m_r\n",
|
||||
";;\n",
|
||||
"\n",
|
||||
"(************************************************)\n",
|
||||
"\n",
|
||||
"(*\n",
|
||||
"f_alpha_boys m_C;;\n",
|
||||
"f_alpha_boys new_c;;\n",
|
||||
"*)\n",
|
||||
"\n",
|
||||
"(********************************************)\n",
|
||||
"\n",
|
||||
"let f_r alphaij m_C = \n",
|
||||
" let n_mo = Mat.dim2 m_C in\n",
|
||||
" \n",
|
||||
" let indice_i = alphaij.indice_ii in\n",
|
||||
" let indice_j = alphaij.indice_jj in\n",
|
||||
" let alpha = alphaij.alpha_max in\n",
|
||||
" (* Matrice des angles -> X *)\n",
|
||||
" let m_angle = Mat.init_cols n_mo n_mo (fun i j -> \n",
|
||||
" if (i = indice_i && j = indice_j) || (j = indice_i && i = indice_j) \n",
|
||||
" then alpha\n",
|
||||
" else 0.) in\n",
|
||||
" \n",
|
||||
" (*Util.debug_matrix \"m_angle\" m_angle;*)\n",
|
||||
" \n",
|
||||
" (*\n",
|
||||
" let m_alpha = alphad.m_alpha in\n",
|
||||
" let m_angle = Mat.init_cols n_mo n_mo (fun i j -> \n",
|
||||
" 0.1 *. m_alpha.{i,j})\n",
|
||||
" in\n",
|
||||
" *)\n",
|
||||
" (* Antisymétrisation et 0 sur la diagonale*)\n",
|
||||
" let m =Mat.init_cols n_mo n_mo (fun i j ->\n",
|
||||
" if i = j \n",
|
||||
" then 0.\n",
|
||||
" else if i>j \n",
|
||||
" then m_angle.{i,j} \n",
|
||||
" else -. m_angle.{i,j})\n",
|
||||
" \n",
|
||||
" in\n",
|
||||
" \n",
|
||||
" (*Util.debug_matrix \"m\" m;*)\n",
|
||||
" \n",
|
||||
" (* Mise au carré -> X² *)\n",
|
||||
" let mm = gemm m m in\n",
|
||||
" \n",
|
||||
" (*Util.debug_matrix \"mm\" mm;*)\n",
|
||||
" \n",
|
||||
" (* Diagonalisation de X² -> diag = vecteur contenant les eigenvalues (-tau²),\n",
|
||||
" m_angle2 -> Matrice avec les eigenvectors (W) *)\n",
|
||||
" let diag = syev ~vectors:true mm in\n",
|
||||
" (* Passage de -tau² à tau² *)\n",
|
||||
" let square_tau= Vec.abs diag in\n",
|
||||
" (* Passage de tau² à tau *)\n",
|
||||
" let tau = Vec.sqrt square_tau in \n",
|
||||
" (* Calcul de cos tau à partir du vecteur tau *)\n",
|
||||
" let cos_tau = Vec.cos tau in\n",
|
||||
" (* Matrice cos tau *)\n",
|
||||
" let m_cos_tau = Mat.init_cols n_mo n_mo (fun i j -> if i=j then cos_tau.{i} else 0.) in\n",
|
||||
" \n",
|
||||
" (*Util.debug_matrix \"m_cos_tau\" m_cos_tau;*)\n",
|
||||
" \n",
|
||||
" (* Calcul de sin tau à partir du vecteur tau *)\n",
|
||||
" let sin_tau = Vec.sin tau in \n",
|
||||
" (* Matrice de sin tau *)\n",
|
||||
" let m_sin_tau = Mat.init_cols n_mo n_mo (fun i j -> if i=j then sin_tau.{i} else 0.) in\n",
|
||||
" \n",
|
||||
" (*Util.debug_matrix \"m_sin_tau\" m_sin_tau;*)\n",
|
||||
" \n",
|
||||
" (* Calcul de la transposée de W (m_angles2) *)\n",
|
||||
" let transpose_mm = Mat.transpose_copy mm in\n",
|
||||
" \n",
|
||||
" (*Util.debug_matrix \"transpose_mm\" transpose_mm;*)\n",
|
||||
" \n",
|
||||
" (* Calcul du vecteur tau^-1 *)\n",
|
||||
" let tau_1 = Vec.init n_mo (fun i -> if tau.{i}<= 0.001 then 1.\n",
|
||||
" else 1. /. tau.{i}) in\n",
|
||||
" (* Calcul de la matrice tau^⁻1 *)\n",
|
||||
" let m_tau_1 = Mat.init_cols n_mo n_mo (fun i j -> if i=j then tau_1.{i} else 0.) in\n",
|
||||
" \n",
|
||||
" (*Util.debug_matrix \"m_tau_1\" m_tau_1;*)\n",
|
||||
" \n",
|
||||
" (* gemm mm (gemm m_cos_tau transpose_mm) -> W cos(tau) Wt *)\n",
|
||||
" let a = gemm mm (gemm m_cos_tau transpose_mm) in\n",
|
||||
" \n",
|
||||
" (*Util.debug_matrix \"a\" a;*)\n",
|
||||
" \n",
|
||||
" (* gemm mm (gemm m_tau_1 ( gemm m_sin_tau (gemm transpose_mm m))) -> W tau^-1 sin(tau) Wt X *)\n",
|
||||
" let b = gemm mm (gemm m_tau_1 ( gemm m_sin_tau (gemm transpose_mm m))) in\n",
|
||||
" \n",
|
||||
" (*Util.debug_matrix \"b\" b;*)\n",
|
||||
" \n",
|
||||
" (* Somme de 2 matrices, ici -> a + b -> R *)\n",
|
||||
"Mat.add a b (* Matrice de rotation R *)\n",
|
||||
";;\n",
|
||||
"\n",
|
||||
"(*******************************************************************) \n",
|
||||
"\n",
|
||||
"(*\n",
|
||||
"let m_r = f_r alphaij m_C;;\n",
|
||||
"gemm m_C m_r;;\n",
|
||||
"*)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
|
@ -1872,8 +2045,8 @@
|
|||
"\n",
|
||||
" (*Printf.printf \"%i\\n%!\" n;*)\n",
|
||||
" (*Printf.printf \"%f\\n%!\" epsilon;*)\n",
|
||||
" (*Util.debug_matrix \"m_C\" m_C;*)\n",
|
||||
" (*Util.debug_matrix \"new_alpha_m\" prev_m_alpha;*)\n",
|
||||
" (*Util.debug_matrix \"m_C\" m_C;\n",
|
||||
" Util.debug_matrix \"new_alpha_m\" prev_m_alpha;*)\n",
|
||||
"\n",
|
||||
"if n == 0 \n",
|
||||
" then m_C\n",
|
||||
|
@ -1881,97 +2054,89 @@
|
|||
"\n",
|
||||
" (* Fonction de calcul de la nouvelle matrice de coef après rotation d'un angle alpha *)\n",
|
||||
" let new_m_C m_C methode m_alpha epsilon =\n",
|
||||
"\n",
|
||||
" (*\n",
|
||||
" let alphaij = new_m_alpha m_alpha m_C 3 in\n",
|
||||
" let m_r = f_r alphaij m_C in\n",
|
||||
" (*Util.debug_matrix \"m_r\" m_r;*)\n",
|
||||
" let new_m = gemm m_C m_r in\n",
|
||||
" (*Util.debug_matrix \"new_m\" new_m;*)\n",
|
||||
" \n",
|
||||
" new_m, alphaij.alpha_max\n",
|
||||
" *)\n",
|
||||
" \n",
|
||||
" (* alphaij contient le alpha max ainsi que ses indices i et j *)\n",
|
||||
" let n_rec_alpha = 10 (* Nombre ditération max pour réduire les valeurs de alpha *)\n",
|
||||
" in\n",
|
||||
" let alphaij = new_m_alpha m_alpha m_C n_rec_alpha \n",
|
||||
" in\n",
|
||||
" let n_rec_alpha = 10 in (* Nombre ditération max pour réduire les valeurs de alpha *)\n",
|
||||
" let alphaij = new_m_alpha m_alpha m_C n_rec_alpha in\n",
|
||||
"\n",
|
||||
" (* Valeur de alpha max après calcul *) (* Epsilon = Pas <1. , 1. -> normal, sinon Pas plus petit *)\n",
|
||||
" let alpha = (alphaij.alpha_max) *. epsilon \n",
|
||||
" in\n",
|
||||
"\n",
|
||||
" let alpha = (alphaij.alpha_max) *. epsilon in\n",
|
||||
" \n",
|
||||
" (*Printf.printf \"%f\\n%!\" alpha;*)\n",
|
||||
"\n",
|
||||
" (* Indice i et j du alpha max après calcul *)\n",
|
||||
" let indice_i = alphaij.indice_ii \n",
|
||||
" in\n",
|
||||
" let indice_j = alphaij.indice_jj \n",
|
||||
" in\n",
|
||||
" let indice_i = alphaij.indice_ii in\n",
|
||||
" let indice_j = alphaij.indice_jj in\n",
|
||||
"\n",
|
||||
" (*Printf.printf \"%i %i\\n%!\" indice_i indice_j;*)\n",
|
||||
"\n",
|
||||
" \n",
|
||||
" (* Matrice de rotation *)\n",
|
||||
" let m_R = f_R alpha \n",
|
||||
" in\n",
|
||||
" let m_R = f_R alpha in\n",
|
||||
"\n",
|
||||
" (*Util.debug_matrix \"m_R\" m_R;*)\n",
|
||||
"\n",
|
||||
" \n",
|
||||
" (* Matrice qui va subir la rotation *)\n",
|
||||
" let m_Ksi = f_Ksi indice_i indice_j m_C \n",
|
||||
" in\n",
|
||||
" let m_Ksi = f_Ksi indice_i indice_j m_C in\n",
|
||||
"\n",
|
||||
" (*Util.debug_matrix \"m_Ksi\" m_Ksi;*)\n",
|
||||
"\n",
|
||||
" (* Matrice ayant subit la rotation *)\n",
|
||||
" let m_Ksi_tilde = f_Ksi_tilde m_R m_Ksi m_C \n",
|
||||
" in\n",
|
||||
" let m_Ksi_tilde = f_Ksi_tilde m_R m_Ksi m_C in\n",
|
||||
"\n",
|
||||
" (*Util.debug_matrix \"m_Ksi_tilde\" m_Ksi_tilde;*)\n",
|
||||
"\n",
|
||||
" (* Matrice pour supprimerles coef des orbitales i et j dans la matrice des coef *)\n",
|
||||
" let m_Psi = f_k m_Ksi indice_i indice_j m_C\n",
|
||||
" in\n",
|
||||
" let m_Psi = f_k m_Ksi indice_i indice_j m_C in\n",
|
||||
"\n",
|
||||
" (*Util.debug_matrix \"m_Psi\" m_Psi;*)\n",
|
||||
"\n",
|
||||
" (* Matrice pour ajouter les coef des orbitales i~ et j~ dans la matrice des coef *)\n",
|
||||
" let m_Psi_tilde = f_k m_Ksi_tilde indice_i indice_j m_C \n",
|
||||
" in\n",
|
||||
" let m_Psi_tilde = f_k m_Ksi_tilde indice_i indice_j m_C in\n",
|
||||
"\n",
|
||||
" (*Util.debug_matrix \"m_Psi_tilde\" m_Psi_tilde;*)\n",
|
||||
"\n",
|
||||
" (* Matrice avec les coef des orbitales i et j remplacés par 0 *)\n",
|
||||
" let m_interm = f_interm m_C m_Psi \n",
|
||||
" in\n",
|
||||
" let m_interm = f_interm m_C m_Psi in\n",
|
||||
"\n",
|
||||
" (*Util.debug_matrix \"m_interm\" m_interm;*)\n",
|
||||
"\n",
|
||||
" (* Matrice après rotation *)\n",
|
||||
" (Mat.add m_Psi_tilde m_interm, alpha)\n",
|
||||
"\n",
|
||||
" \n",
|
||||
" in\n",
|
||||
" (* Extraction de la nouvelle matrice des coef et du alpha_max *)\n",
|
||||
" let m_new_m_C, alpha_max = new_m_C m_C methode prev_m_alpha epsilon\n",
|
||||
" in\n",
|
||||
" let m_new_m_C, alpha_max = new_m_C m_C methode prev_m_alpha epsilon in\n",
|
||||
"\n",
|
||||
" (* Fonction de pattern matching en fonction de la méthode *)\n",
|
||||
" let alphad = m_alpha_d methode m_new_m_C\n",
|
||||
" in\n",
|
||||
" let alphad = m_alpha_d methode m_new_m_C in\n",
|
||||
" \n",
|
||||
" (* Matrice des alphas *)\n",
|
||||
" let m_alpha = alphad.m_alpha\n",
|
||||
" in\n",
|
||||
" let m_alpha = alphad.m_alpha in\n",
|
||||
" \n",
|
||||
" (* Critères possibles de localisation -> norme_alpha, moyenne_alpha, alpha, diff *)\n",
|
||||
" \n",
|
||||
" (* Norme de m_alpha, moyenne et max *)\n",
|
||||
" (*let norme_alpha = norme m_alpha\n",
|
||||
" in\n",
|
||||
" let moyenne_alpha = norme_alpha /. (float_of_int((Mat.dim1 m_C)* (Mat.dim2 m_C)))\n",
|
||||
" in\n",
|
||||
" let alpha = alpha_max /. epsilon\n",
|
||||
" in*)\n",
|
||||
" \n",
|
||||
" let norme_alpha = norme m_alpha in\n",
|
||||
" let moyenne_alpha = norme_alpha /. (float_of_int((Mat.dim1 m_C)* (Mat.dim2 m_C))) in\n",
|
||||
" let alpha = alpha_max /. epsilon in\n",
|
||||
" \n",
|
||||
" \n",
|
||||
" (* D critère à maximiser *)\n",
|
||||
" let critere_D = alphad.d \n",
|
||||
" in\n",
|
||||
" let diff = max_D -. critere_D \n",
|
||||
" in\n",
|
||||
" let critere_D = alphad.d in\n",
|
||||
" let diff = max_D -. critere_D in\n",
|
||||
" \n",
|
||||
" (*Printf.printf \"%f\\n%!\" diff;*)\n",
|
||||
" (*Printf.printf \"%i %f %f %f %f %f\\n%!\" n max_D critere_D alpha norme_alpha moyenne_alpha;*)\n",
|
||||
" Printf.printf \"%i %f %f %f %f %f\\n%!\" n max_D critere_D alpha norme_alpha moyenne_alpha;\n",
|
||||
" \n",
|
||||
" (* Stabilisation de la convergence *)\n",
|
||||
"\n",
|
||||
|
@ -1991,7 +2156,7 @@
|
|||
"\n",
|
||||
"\n",
|
||||
" (* Critère de conv pour sortir *)\n",
|
||||
" if alpha_max**2. +. 1. < cc**2.\n",
|
||||
" if alpha_max**2. < cc**2.\n",
|
||||
" then m_new_m_C\n",
|
||||
" else localisation m_new_m_C methode epsilon (n-1) critere_D m_alpha cc max_D;;"
|
||||
]
|
||||
|
@ -2003,17 +2168,14 @@
|
|||
"outputs": [],
|
||||
"source": [
|
||||
"let localise localisation m_C methode epsilon n cc=\n",
|
||||
" let alphad = m_alpha_d methode m_C \n",
|
||||
" in\n",
|
||||
" let prev_m_alpha = alphad.m_alpha\n",
|
||||
" in \n",
|
||||
" let prev_critere_D = 0.\n",
|
||||
" in\n",
|
||||
" let alphad = m_alpha_d methode m_C in\n",
|
||||
" let prev_m_alpha = alphad.m_alpha in \n",
|
||||
" let prev_critere_D = 0. in\n",
|
||||
" let max_D = 0.\n",
|
||||
"in\n",
|
||||
"localisation m_C methode epsilon n prev_critere_D prev_m_alpha cc max_D;;\n",
|
||||
" \n",
|
||||
"let m_B = localise localisation m_C \"BOYS\" 1. 100 10e-10;;"
|
||||
"(*let new_mc = new_c m_C 0.001;;\n",
|
||||
"let m_B = localise localisation new_mc \"Boys\" 1. 200 10e-10;;*)"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
@ -2044,7 +2206,7 @@
|
|||
"\n",
|
||||
"(* Fonction de séparation d'une matrice en 2 sous matrice, la première matrice correspondant aux colonnes de la matrice dont le numéro est présent\n",
|
||||
"dans la liste et la seconde à celles dont le numéro de colonne n'est pas présent dans la liste *)\n",
|
||||
"let split_mat mat list =\n",
|
||||
"let split_mat mat list = \n",
|
||||
" let vec_of_mat = Mat.to_col_vecs mat\n",
|
||||
" in\n",
|
||||
" let f a = vec_of_mat.(a-1)\n",
|
||||
|
@ -2061,6 +2223,11 @@
|
|||
" let vec_occ = Vec.init (nocc) (fun i -> float_of_int(i))\n",
|
||||
"in int_list vec_occ;;\n",
|
||||
"\n",
|
||||
"(* Liste des OMs de coeur *)\n",
|
||||
"let list_core = \n",
|
||||
" let vec_core = Vec.init (n_core) (fun i -> float_of_int(i))\n",
|
||||
"in int_list vec_core;;\n",
|
||||
"\n",
|
||||
"(* Fonction de rassemblement de 2 matrices *)\n",
|
||||
"let assemble m_occ m_vir =\n",
|
||||
" let v_occ = Mat.to_col_vecs m_occ\n",
|
||||
|
@ -2089,7 +2256,15 @@
|
|||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"let m_occ , m_vir = split_mat m_C list_occ;;"
|
||||
"let m_occ , m_vir = split_mat m_C list_occ;;\n",
|
||||
"let dim_m_core = Mat.dim1 m_core;;\n",
|
||||
"let m_core, m_occu = split_mat m_occ list_core;;\n",
|
||||
"let new_core = \n",
|
||||
" if dim_m_core = 0 \n",
|
||||
" then m_core \n",
|
||||
" else new_c m_core 0.001;;\n",
|
||||
"let new_occu = new_c m_occu 0.001;;\n",
|
||||
"let new_vir = new_c m_vir 0.001;;\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
@ -2104,13 +2279,13 @@
|
|||
"(*let new_m_boys = localise localisation m_C \"boys\" 1. 100 10e-7;;\n",
|
||||
"let new_m_er = localise localisation m_C \"ER\" 1. 100 10e-7;;\n",
|
||||
"*)\n",
|
||||
"\n",
|
||||
"let loc_m_occ_boys = localise localisation m_occ \"Boys\" 1. 1000 10e-7;;\n",
|
||||
"\n",
|
||||
"(*\n",
|
||||
"let loc_m_vir_boys = localise localisation m_vir \"boys\" 1. 100 10e-7;;\n",
|
||||
"let m_assemble_boys = assemble loc_m_occ_boys loc_m_vir_boys;;\n",
|
||||
"*)\n",
|
||||
"let loc_m_core_boys = \n",
|
||||
" if dim_m_core=0 \n",
|
||||
" then m_core \n",
|
||||
" else localise localisation m_core \"boys_er\" 1. 10 10e-3;;\n",
|
||||
"let loc_m_occ_boys = localise localisation new_occ \"boys_er\" 1. 10 10e-3;;\n",
|
||||
"let loc_m_vir_boys = localise localisation new_vir \"BOYS\" 1. 10 10e-3;;\n",
|
||||
"(*let m_assemble_boys = assemble loc_m_occ_boys loc_m_vir_boys;;*)\n",
|
||||
"\n",
|
||||
"(*\n",
|
||||
"let loc_m_occ_er = localise localisation m_occ \"ER\" 1. 100 10e-7;;\n",
|
||||
|
@ -2213,11 +2388,7 @@
|
|||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"jupyter": {
|
||||
"outputs_hidden": true
|
||||
}
|
||||
},
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"(*\n",
|
||||
|
@ -2298,6 +2469,55 @@
|
|||
"print_list print_int [3;6;78;5;2;34;7];;"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"let mat = mo_coef;;\n",
|
||||
" let n_ao = Mat.dim1 mat ;;\n",
|
||||
" let n_mo = Mat.dim2 mat ;;\n",
|
||||
" let m_pi = Mat.init_cols n_ao n_mo ( fun i j ->\n",
|
||||
" if mat.{i,j}**2. < 10e-8**2.\n",
|
||||
" then 0.\n",
|
||||
" else mat.{i,j})\n",
|
||||
" ;;\n",
|
||||
" Printf.printf \"%i\\n\" nocc;;\n",
|
||||
" Util.debug_matrix \"m_pi\" m_pi;;\n",
|
||||
" let vec = Mat.to_col_vecs m_pi;;\n",
|
||||
" let vec_dot = Vec.init (n_mo-nocc) (fun i -> dot vec.(0) vec.(i-1+nocc))\n",
|
||||
" ;;\n",
|
||||
" let vec_pi = Vec.init (n_mo-nocc) (fun i ->\n",
|
||||
" if vec_dot.{i} = 0.\n",
|
||||
" then float_of_int(i)\n",
|
||||
" else 0.);;\n",
|
||||
" \n",
|
||||
" let list_pi = int_list vec_pi;;\n",
|
||||
" let rec remove x list =\n",
|
||||
" match list with\n",
|
||||
" | [] -> []\n",
|
||||
" | var :: tail -> if var = x\n",
|
||||
" then remove x tail\n",
|
||||
" else var :: (remove x tail);;\n",
|
||||
" remove 0 list_pi\n",
|
||||
" "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
|
|
1754
Work_test.ipynb
1754
Work_test.ipynb
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,118 @@
|
|||
open Lacaml.D
|
||||
|
||||
let read_qp_mo dirname =
|
||||
let ic = Unix.open_process_in ("zcat "^dirname^"/mo_basis/mo_coef.gz") in
|
||||
let check = String.trim (input_line ic) in
|
||||
assert (check = "2");
|
||||
let int_list =
|
||||
input_line ic
|
||||
|> String.split_on_char ' '
|
||||
|> List.filter (fun x -> x <> "")
|
||||
|> List.map int_of_string
|
||||
in
|
||||
let n_ao, n_mo =
|
||||
match int_list with
|
||||
| [ x ; y ] -> x, y
|
||||
| _ -> assert false
|
||||
in
|
||||
let result =
|
||||
Mat.init_cols n_ao n_mo (fun i j ->
|
||||
let s = input_line ic in
|
||||
Scanf.sscanf s " %f " (fun x -> x)
|
||||
)
|
||||
in
|
||||
let exit_code = Unix.close_process_in ic in
|
||||
assert (exit_code = Unix.WEXITED 0);
|
||||
result
|
||||
|
||||
|
||||
|
||||
let () =
|
||||
let open Command_line in
|
||||
begin
|
||||
set_header_doc (Sys.argv.(0) ^ " - QCaml command");
|
||||
set_description_doc "Localizes MOs";
|
||||
set_specs
|
||||
[ { short='b' ; long="basis" ; opt=Mandatory;
|
||||
arg=With_arg "<string>";
|
||||
doc="Name of the file containing the basis set"; } ;
|
||||
|
||||
{ short='x' ; long="xyz" ; opt=Mandatory;
|
||||
arg=With_arg "<string>";
|
||||
doc="Name of the file containing the nuclear coordinates in xyz format"; } ;
|
||||
|
||||
{ short='m' ; long="multiplicity" ; opt=Optional;
|
||||
arg=With_arg "<int>";
|
||||
doc="Spin multiplicity (2S+1). Default is singlet"; } ;
|
||||
|
||||
{ short='c' ; long="charge" ; opt=Optional;
|
||||
arg=With_arg "<int>";
|
||||
doc="Total charge of the molecule. Default is 0"; } ;
|
||||
|
||||
{ short='o' ; long="output" ; opt=Mandatory;
|
||||
arg=With_arg "<string>";
|
||||
doc="Name of the file containing the localized MOs"; } ;
|
||||
|
||||
{ short='i' ; long="import" ; opt=Optional;
|
||||
arg=With_arg "<string>";
|
||||
doc="Name of the EZFIO directory containing MOs"; } ;
|
||||
|
||||
]
|
||||
end;
|
||||
|
||||
|
||||
let basis_file = Util.of_some @@ Command_line.get "basis" in
|
||||
|
||||
let nuclei_file = Util.of_some @@ Command_line.get "xyz" in
|
||||
|
||||
let ezfio_file = Command_line.get "import" in
|
||||
|
||||
let charge =
|
||||
match Command_line.get "charge" with
|
||||
| Some x -> int_of_string x
|
||||
| None -> 0
|
||||
in
|
||||
|
||||
let multiplicity =
|
||||
match Command_line.get "multiplicity" with
|
||||
| Some x -> int_of_string x
|
||||
| None -> 1
|
||||
in
|
||||
|
||||
let output_filename = Util.of_some @@ Command_line.get "output" in
|
||||
|
||||
|
||||
(* II : Hartree-Fock *)
|
||||
|
||||
(* 1. Def pour HF *)
|
||||
|
||||
let simulation =
|
||||
Simulation.of_filenames
|
||||
~charge ~multiplicity ~nuclei:nuclei_file basis_file
|
||||
in
|
||||
|
||||
(* 2. Calcul de Hartree-Fock*)
|
||||
let mo_basis =
|
||||
match ezfio_file with
|
||||
| Some ezfio_file ->
|
||||
let mo_coef = read_qp_mo ezfio_file in
|
||||
let mo_type = MOBasis.Localized "Boys" in
|
||||
let elec = Simulation.electrons simulation in
|
||||
let n_mo = Mat.dim2 mo_coef in
|
||||
let mo_occupation = Vec.init n_mo (fun i ->
|
||||
if i <= Electrons.n_beta elec then 2.
|
||||
else if i <= Electrons.n_alfa elec then 1.
|
||||
else 0.) in
|
||||
MOBasis.make ~simulation ~mo_type ~mo_occupation ~mo_coef ()
|
||||
| None -> HartreeFock.make simulation
|
||||
|> MOBasis.of_hartree_fock
|
||||
in
|
||||
|
||||
let local_mos = Localisation.localize mo_basis in
|
||||
|
||||
let oc = open_out output_filename in
|
||||
Printf.fprintf oc "[\n";
|
||||
Mat.as_vec local_mos
|
||||
|> Vec.iter (fun x -> Printf.fprintf oc "%20.15e,\n" x);
|
||||
Printf.fprintf oc "]\n";
|
||||
close_out oc
|
|
@ -1,913 +0,0 @@
|
|||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"hidden": true
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"(* Algorithme de localisation des orbitales : Méthode de Boys ou Edminston-Ruedenberg *)\n",
|
||||
"\n",
|
||||
"(*I : Position et base atomique*)\n",
|
||||
" (* 1. Coordonnées *)\n",
|
||||
" (* 2. Base atomique *)\n",
|
||||
"\n",
|
||||
"(* II : Hartree-Fock *)\n",
|
||||
" (* 1. Def pour HF *) (* !!! -> Charge !!! *)\n",
|
||||
" (* 2. Calcul de Hartree-Fock*)\n",
|
||||
" \n",
|
||||
"(* III : Définition des fonctions pour la localisation *)\n",
|
||||
" (* 1. Définitions de base nécessaire pour la suite *) \n",
|
||||
" (* 2. Fonction de calcul de tous les alpha ER *)\n",
|
||||
" (* 3. Fonction de calcul de tous les alpha Boys *)\n",
|
||||
" (* 4. Pattern matching : calcul de alpha et de D *)\n",
|
||||
" (* 5. Norme de alpha *)\n",
|
||||
" (* 6. Détermination alpha_max et ses indices i et j *) \n",
|
||||
" (* 7. Matrice de rotation 2 par 2 *)\n",
|
||||
" (* 8. Fonction : i,j -> matrice Ksi (n par 2) *)\n",
|
||||
" (* 9. Fonction : i~,j~ -> matrice Ksi~ (n par 2) *)\n",
|
||||
" (* 10. Matrice intermédiaire pour supprimer i j et ajouter i~ et j~ *)\n",
|
||||
" (* 11. Matrice intérmédiaire où les orbitales i et j ont été supprimées et remplacées par des 0*)\n",
|
||||
" \n",
|
||||
"(* IV : Localisation des OMs *)\n",
|
||||
" (* 1. Boucle de localisation des OMs *) (* !!! -> Choix paramètres et critères localisation !!! *)\n",
|
||||
" (* 2. Fonction de localisation *)\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"(* V : Fonctions pour la séparation et le rassemblement des matrices *)\n",
|
||||
" (* 1. Fonction de création d'une list d'entier à partir d'un vecteur de float*)\n",
|
||||
" (* 2. Fonction créant une liste à partir des éléments manquant d'une autre liste, dans l'intervalle [1 ; n_mo] *)\n",
|
||||
" (* 3. Fonction de séparation d'une matrice en 2 sous matrice *)\n",
|
||||
" (* 4. Liste des OMs occupées *)\n",
|
||||
" (* 5. Fonction de rassemblement de 2 matrices *) \n",
|
||||
" (* 6. Séparation des OMs -> m_occ : OMs occupées; m_vir : OMs vacantes *)\n",
|
||||
" \n",
|
||||
"(* VI : Calcul et assemblage des OMs occupées/virtuels *) (* !!! -> Choix paramètres de calcul !!! *)\n",
|
||||
" \n",
|
||||
"(* VII : Calcul Coef CI *)\n",
|
||||
" (* 1. Def de la mo_basis pour le HF pre CI *)\n",
|
||||
" (* 2. HF pour CI *)\n",
|
||||
" (* 3. Calcul de coef CI *)\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"open Lacaml.D\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"(*I : Position et base atomique*)\n",
|
||||
"\n",
|
||||
"(* 1. Coordonnées *) (* !!! Attention à bien mettre \"nbatome sur la même ligne !!! *)\n",
|
||||
"let charge = 1;;\n",
|
||||
"let xyz_string = \n",
|
||||
"\"8\n",
|
||||
"C1\n",
|
||||
"C 0.000000 0.000000 0.424165\n",
|
||||
"H 0.000000 0.000000 1.508704\n",
|
||||
"N 0.000000 1.158087 -0.174215\n",
|
||||
"N 0.000000 -1.158087 -0.174215\n",
|
||||
"H 0.000000 1.258360 -1.178487\n",
|
||||
"H 0.000000 2.005112 0.371143\n",
|
||||
"H 0.000000 -2.005112 0.371143\n",
|
||||
"H 0.000000 -1.258360 -1.178487\n",
|
||||
"\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"hidden": true
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"(* 2. Base atomique -> 6-31G *)\n",
|
||||
"\n",
|
||||
"let basis_string = \n",
|
||||
"\"\n",
|
||||
"HYDROGEN\n",
|
||||
"S 3\n",
|
||||
"1 0.1873113696E+02 0.3349460434E-01\n",
|
||||
"2 0.2825394365E+01 0.2347269535E+00\n",
|
||||
"3 0.6401216923E+00 0.8137573261E+00\n",
|
||||
"S 1\n",
|
||||
"1 0.1612777588E+00 1.0000000\n",
|
||||
"\n",
|
||||
"CARBON\n",
|
||||
"S 6\n",
|
||||
"1 0.3047524880E+04 0.1834737132E-02\n",
|
||||
"2 0.4573695180E+03 0.1403732281E-01\n",
|
||||
"3 0.1039486850E+03 0.6884262226E-01\n",
|
||||
"4 0.2921015530E+02 0.2321844432E+00\n",
|
||||
"5 0.9286662960E+01 0.4679413484E+00\n",
|
||||
"6 0.3163926960E+01 0.3623119853E+00\n",
|
||||
"S 3\n",
|
||||
"1 0.7868272350E+01 -0.1193324198E+00\n",
|
||||
"2 0.1881288540E+01 -0.1608541517E+00\n",
|
||||
"3 0.5442492580E+00 0.1143456438E+01\n",
|
||||
"S 1\n",
|
||||
"1 0.1687144782E+00 0.1000000000E+01\n",
|
||||
"P 3\n",
|
||||
"1 0.7868272350E+01 0.6899906659E-01\n",
|
||||
"2 0.1881288540E+01 0.3164239610E+00\n",
|
||||
"3 0.5442492580E+00 0.7443082909E+00\n",
|
||||
"P 1\n",
|
||||
"1 0.1687144782E+00 0.1000000000E+01\n",
|
||||
"\n",
|
||||
"NITROGEN\n",
|
||||
"S 6\n",
|
||||
"1 0.4173511460E+04 0.1834772160E-02\n",
|
||||
"2 0.6274579110E+03 0.1399462700E-01\n",
|
||||
"3 0.1429020930E+03 0.6858655181E-01\n",
|
||||
"4 0.4023432930E+02 0.2322408730E+00\n",
|
||||
"5 0.1282021290E+02 0.4690699481E+00\n",
|
||||
"6 0.4390437010E+01 0.3604551991E+00\n",
|
||||
"S 3\n",
|
||||
"1 0.1162636186E+02 -0.1149611817E+00\n",
|
||||
"2 0.2716279807E+01 -0.1691174786E+00\n",
|
||||
"3 0.7722183966E+00 0.1145851947E+01\n",
|
||||
"S 1\n",
|
||||
"1 0.2120314975E+00 0.1000000000E+01\n",
|
||||
"P 3\n",
|
||||
"1 0.1162636186E+02 0.6757974388E-01\n",
|
||||
"2 0.2716279807E+01 0.3239072959E+00\n",
|
||||
"3 0.7722183966E+00 0.7408951398E+00\n",
|
||||
"P 1\n",
|
||||
"1 0.2120314975E+00 0.1000000000E+01\n",
|
||||
"\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"hidden": true
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"(* II : Hartree-Fock *)\n",
|
||||
"\n",
|
||||
"(* 1. Def pour HF *)\n",
|
||||
"\n",
|
||||
"let nuclei =\n",
|
||||
" Nuclei.of_xyz_string xyz_string\n",
|
||||
" \n",
|
||||
"let basis = \n",
|
||||
" Basis.of_nuclei_and_basis_string nuclei basis_string\n",
|
||||
" \n",
|
||||
"let simulation = \n",
|
||||
" Simulation.make ~charge ~multiplicity:1 ~nuclei basis \n",
|
||||
" \n",
|
||||
"let ao_basis = \n",
|
||||
" Simulation.ao_basis simulation\n",
|
||||
" \n",
|
||||
"let nocc =\n",
|
||||
" let elec = Simulation.electrons simulation in\n",
|
||||
" Electrons.n_alfa elec\n",
|
||||
" "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"hidden": true
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"(* 2. Calcul de Hartree-Fock*)\n",
|
||||
"\n",
|
||||
"let hf = HartreeFock.make simulation\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"hidden": true
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"let mo_basis = MOBasis.of_hartree_fock hf\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"hidden": true
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"let mo_coef = MOBasis.mo_coef mo_basis\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"(* III : Définition des fonctions pour la localisation *)\n",
|
||||
"\n",
|
||||
"(* 1. Définitions de base nécessaire pour la suite *)\n",
|
||||
"let ee_ints = AOBasis.ee_ints ao_basis;;\n",
|
||||
"let m_C = MOBasis.mo_coef mo_basis;;\n",
|
||||
"let n_ao = Mat.dim1 m_C ;;\n",
|
||||
"let n_mo = Mat.dim2 m_C ;;\n",
|
||||
"let multipoles = \n",
|
||||
" AOBasis.multipole ao_basis;;\n",
|
||||
" \n",
|
||||
"let sum a = \n",
|
||||
" Array.fold_left (fun accu x -> accu +. x) 0. a\n",
|
||||
" \n",
|
||||
"let pi = 3.14159265358979323846264338;;\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"(* 2. Fonction de calcul de tous les alpha ER *)\n",
|
||||
"let f_alpha m_C =\n",
|
||||
"\n",
|
||||
" let n_mo = Mat.dim2 m_C in\n",
|
||||
" (*let t0 = Sys.time () in*)\n",
|
||||
" \n",
|
||||
" let m_b12 = Mat.init_cols n_mo n_mo (fun i j -> 0.) in\n",
|
||||
" let m_a12 = Mat.init_cols n_mo n_mo (fun i j -> 0.) in\n",
|
||||
" let v_d = Vec.init n_mo (fun i -> 0.) in\n",
|
||||
" \n",
|
||||
" (* Tableaux temporaires *)\n",
|
||||
" let m_pqr =\n",
|
||||
" Bigarray.(Array3.create Float64 fortran_layout n_ao n_ao n_ao)\n",
|
||||
" in\n",
|
||||
" let m_qr_i = Mat.create (n_ao*n_ao) n_mo in\n",
|
||||
" let m_ri_j = Mat.create (n_ao*n_mo) n_mo in\n",
|
||||
" let m_ij_k = Mat.create (n_mo*n_mo) n_mo in\n",
|
||||
" \n",
|
||||
" Array.iter (fun s ->\n",
|
||||
" (* Grosse boucle externe sur s *)\n",
|
||||
" Array.iter (fun r ->\n",
|
||||
" Array.iter (fun q ->\n",
|
||||
" Array.iter (fun p ->\n",
|
||||
" m_pqr.{p,q,r} <- ERI.get_phys ee_ints p q r s\n",
|
||||
" ) (Util.array_range 1 n_ao)\n",
|
||||
" ) (Util.array_range 1 n_ao)\n",
|
||||
" ) (Util.array_range 1 n_ao);\n",
|
||||
" \n",
|
||||
" (* Conversion d'un tableau a 3 indices en une matrice nao x nao^2 *)\n",
|
||||
" let m_p_qr =\n",
|
||||
" Bigarray.reshape (Bigarray.genarray_of_array3 m_pqr) [| n_ao ; n_ao*n_ao |]\n",
|
||||
" |> Bigarray.array2_of_genarray\n",
|
||||
" in\n",
|
||||
" \n",
|
||||
" let m_qr_i =\n",
|
||||
" (* (qr,i) = <i r|q s> = \\sum_p <p r | q s> C_{pi} *)\n",
|
||||
" gemm ~transa:`T ~c:m_qr_i m_p_qr m_C\n",
|
||||
" in\n",
|
||||
" \n",
|
||||
" let m_q_ri =\n",
|
||||
" (* Transformation de la matrice (qr,i) en (q,ri) *)\n",
|
||||
" Bigarray.reshape_2 (Bigarray.genarray_of_array2 m_qr_i) n_ao (n_ao*n_mo)\n",
|
||||
" in\n",
|
||||
" \n",
|
||||
" let m_ri_j =\n",
|
||||
" (* (ri,j) = <i r | j s> = \\sum_q <i r | q s> C_{bj} *)\n",
|
||||
" gemm ~transa:`T ~c:m_ri_j m_q_ri m_C\n",
|
||||
" in\n",
|
||||
" \n",
|
||||
" let m_r_ij =\n",
|
||||
" (* Transformation de la matrice (ri,j) en (r,ij) *)\n",
|
||||
" Bigarray.reshape_2 (Bigarray.genarray_of_array2 m_ri_j) n_ao (n_mo*n_mo)\n",
|
||||
" in\n",
|
||||
" \n",
|
||||
" let m_ij_k =\n",
|
||||
" (* (ij,k) = <i k | j s> = \\sum_r <i r | j s> C_{rk} *)\n",
|
||||
" gemm ~transa:`T ~c:m_ij_k m_r_ij m_C\n",
|
||||
" in\n",
|
||||
" \n",
|
||||
" let m_ijk =\n",
|
||||
" (* Transformation de la matrice (ei,j) en (e,ij) *)\n",
|
||||
" Bigarray.reshape (Bigarray.genarray_of_array2 m_ij_k) [| n_mo ; n_mo ; n_mo |]\n",
|
||||
" |> Bigarray.array3_of_genarray\n",
|
||||
" in\n",
|
||||
" \n",
|
||||
" Array.iter (fun j ->\n",
|
||||
" Array.iter (fun i ->\n",
|
||||
" m_b12.{i,j} <- m_b12.{i,j} +. m_C.{s,j} *. (m_ijk.{i,i,i} -. m_ijk.{j,i,j});\n",
|
||||
" m_a12.{i,j} <- m_a12.{i,j} +. m_ijk.{i,i,j} *. m_C.{s,j} -.\n",
|
||||
" 0.25 *. ( (m_ijk.{i,i,i} -. m_ijk.{j,i,j}) *. m_C.{s,i} +.\n",
|
||||
" (m_ijk.{j,j,j} -. m_ijk.{i,j,i}) *. m_C.{s,j})\n",
|
||||
" ) (Util.array_range 1 n_mo);\n",
|
||||
" v_d.{j} <- v_d.{j} +. m_ijk.{j,j,j} *. m_C.{s,j}\n",
|
||||
" ) (Util.array_range 1 n_mo)\n",
|
||||
" ) (Util.array_range 1 n_ao);\n",
|
||||
" \n",
|
||||
" (*let t1 = Sys.time () in\n",
|
||||
" Printf.printf \"t = %f s\\n%!\" (t1 -. t0);*)\n",
|
||||
" \n",
|
||||
" (Mat.init_cols n_mo n_mo ( fun i j ->\n",
|
||||
" if i= j then 0.\n",
|
||||
" else 0.25 *. (acos(-. m_a12.{i,j} /. sqrt((m_a12.{i,j}**2.) +. (m_b12.{i,j}**2. ))))\n",
|
||||
" ),Vec.sum v_d);;\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"(* 3. Fonction de calcul de tous les alpha Boys *)\n",
|
||||
"\n",
|
||||
"let f_alpha_boys m_C = \n",
|
||||
" let n_mo = Mat.dim2 m_C\n",
|
||||
" in\n",
|
||||
" let phi_x_phi =\n",
|
||||
" Multipole.matrix_x multipoles \n",
|
||||
" |> MOBasis.mo_matrix_of_ao_matrix ~mo_coef:m_C\n",
|
||||
" in \n",
|
||||
" let phi_y_phi =\n",
|
||||
" Multipole.matrix_y multipoles \n",
|
||||
" |> MOBasis.mo_matrix_of_ao_matrix ~mo_coef:m_C\n",
|
||||
" in\n",
|
||||
" let phi_z_phi =\n",
|
||||
" Multipole.matrix_z multipoles \n",
|
||||
" |> MOBasis.mo_matrix_of_ao_matrix ~mo_coef:m_C\n",
|
||||
" in \n",
|
||||
"\n",
|
||||
" let m_b12= \n",
|
||||
" let b12 g = Mat.init_cols n_mo n_mo ( fun i j ->\n",
|
||||
" (g.{i,i} -. g.{j,j}) *. g.{i,j})\n",
|
||||
"\n",
|
||||
" in \n",
|
||||
" Mat.add (b12 phi_x_phi) ( Mat.add (b12 phi_y_phi) (b12 phi_z_phi))\n",
|
||||
" in \n",
|
||||
" let m_a12 =\n",
|
||||
" let a12 g = Mat.init_cols n_mo n_mo ( fun i j -> \n",
|
||||
" g.{i,j} *. g.{i,j} -. 0.25 *. ((g.{i,i} -. g.{j,j}) *. (g.{i,i} -. g.{j,j})))\n",
|
||||
" in\n",
|
||||
" Mat.add (a12 phi_x_phi) ( Mat.add (a12 phi_y_phi) (a12 phi_z_phi))\n",
|
||||
" in\n",
|
||||
" (Mat.init_cols n_mo n_mo ( fun i j -> \n",
|
||||
" if i=j \n",
|
||||
" then 0.\n",
|
||||
" else 0.25 *. acos(-. m_a12.{i,j} /. sqrt((m_a12.{i,j}**2.) +. (m_b12.{i,j}**2.) ))),\n",
|
||||
" Vec.sum(Vec.init n_mo ( fun i -> (phi_x_phi.{i,i})**2. +. (phi_y_phi.{i,i})**2. +. (phi_z_phi.{i,i})**2.)));;\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"(* 4. Pattern matching : calcul de alpha et de D *)\n",
|
||||
"\n",
|
||||
"type alphad = {\n",
|
||||
"m_alpha : Mat.t;\n",
|
||||
"d : float;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"let m_alpha_d methode m_C = \n",
|
||||
" let alpha methode =\n",
|
||||
" \n",
|
||||
" match methode with \n",
|
||||
" | \"Boys\"\n",
|
||||
" | \"boys\" -> let alpha_boys , d_boys = f_alpha_boys m_C in {m_alpha = alpha_boys; d = d_boys}\n",
|
||||
" | \"ER\"\n",
|
||||
" | \"er\" -> let alpha_er , d_er = f_alpha m_C in {m_alpha = alpha_er; d = d_er}\n",
|
||||
" | _ -> invalid_arg \"Unknown method, please enter Boys or ER\"\n",
|
||||
"\n",
|
||||
"in \n",
|
||||
"alpha methode;;\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"(* 5. Norme de alpha *)\n",
|
||||
"\n",
|
||||
"let norme m = \n",
|
||||
" let vec_m = Mat.as_vec m\n",
|
||||
" in\n",
|
||||
" let vec2 = Vec.sqr vec_m\n",
|
||||
"in sqrt(Vec.sum vec2);;\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"(* 6. Détermination alpha_max et ses indices i et j.\n",
|
||||
"Si alpha max > pi/2 on soustrait pi/2 à la matrice des alphas de manière récursive *)\n",
|
||||
"type alphaij = {\n",
|
||||
" alpha_max : float;\n",
|
||||
" indice_ii : int;\n",
|
||||
" indice_jj : int;};;\n",
|
||||
"\n",
|
||||
"let rec new_m_alpha m_alpha m_C n_rec_alpha=\n",
|
||||
"\n",
|
||||
" let n_mo = Mat.dim2 m_C\n",
|
||||
" in\n",
|
||||
" let alpha_m =\n",
|
||||
" \n",
|
||||
" (*Printf.printf \"%i\\n%!\" n_rec_alpha;*)\n",
|
||||
" \n",
|
||||
" if n_rec_alpha == 0 \n",
|
||||
" then m_alpha \n",
|
||||
" else Mat.init_cols n_mo n_mo (fun i j -> \n",
|
||||
" if (m_alpha.{i,j}) > (pi /. 2.) \n",
|
||||
" then (m_alpha.{i,j} -. ( pi /. 2.))\n",
|
||||
" else if m_alpha.{i,j} < -. pi /. 2.\n",
|
||||
" then (m_alpha.{i,j} +. ( pi /. 2.))\n",
|
||||
" else if m_alpha.{i,j} < 0. \n",
|
||||
" then -. m_alpha.{i,j}\n",
|
||||
" else m_alpha.{i,j} )\n",
|
||||
" in \n",
|
||||
" \n",
|
||||
" (*Util.debug_matrix \"alpha_m\" alpha_m;*)\n",
|
||||
" \n",
|
||||
" (* Détermination de l'emplacement du alpha max *)\n",
|
||||
" let max_element3 alpha_m = \n",
|
||||
" Mat.as_vec alpha_m\n",
|
||||
" |> iamax\n",
|
||||
" in\n",
|
||||
" \n",
|
||||
" (* indice i et j du alpha max *)\n",
|
||||
" let indice_ii, indice_jj = \n",
|
||||
" let max = max_element3 alpha_m \n",
|
||||
" in\n",
|
||||
" (max - 1) mod n_mo +1, (max - 1) / n_mo +1\n",
|
||||
" in\n",
|
||||
" \n",
|
||||
" (* Valeur du alpha max*)\n",
|
||||
" let alpha alpha_m = \n",
|
||||
" let i = indice_ii \n",
|
||||
" in\n",
|
||||
" let j = indice_jj \n",
|
||||
" in\n",
|
||||
" alpha_m.{i,j}\n",
|
||||
" \n",
|
||||
" (*Printf.printf \"%i %i\\n%!\" i j;*)\n",
|
||||
" \n",
|
||||
" in\n",
|
||||
" let alpha_max = alpha alpha_m \n",
|
||||
" in\n",
|
||||
" \n",
|
||||
" (*Printf.printf \"%f\\n%!\" alpha_max;*)\n",
|
||||
" \n",
|
||||
" if alpha_max < pi /. 2.\n",
|
||||
" then {alpha_max; indice_ii; indice_jj}\n",
|
||||
" else new_m_alpha alpha_m m_C (n_rec_alpha-1);;\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"(* 7. Matrice de rotation 2 par 2 *)\n",
|
||||
"let f_R alpha =\n",
|
||||
" Mat.init_cols 2 2 (fun i j -> \n",
|
||||
" if i=j \n",
|
||||
" then cos alpha\n",
|
||||
" else if i>j \n",
|
||||
" then sin alpha \n",
|
||||
" else -. sin alpha )\n",
|
||||
";;\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"(* 8. Fonction d'extraction des 2 vecteurs propres i et j de la matrice des OMs pour les mettres dans la matrice Ksi (n par 2)\n",
|
||||
"pour appliquer R afin d'effectuer la rotation des orbitales *) (* {1,2} -> 1ere ligne, 2e colonne *)\n",
|
||||
"let f_Ksi indice_i indice_j m_C =\n",
|
||||
" let n_ao = Mat.dim1 m_C\n",
|
||||
"in\n",
|
||||
"Mat.init_cols n_ao 2 (fun i j -> if j=1 then m_C.{i,indice_i} else m_C.{i,indice_j} );;\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"(* 9. Fonction de calcul de ksi~ (matrice n par 2), nouvelle matrice par application de la matrice de rotation dans laquelle\n",
|
||||
"on obtient les deux orbitales que l'on va réinjecter dans la matrice Phi*)\n",
|
||||
"let f_Ksi_tilde m_R m_Ksi m_C = gemm m_Ksi m_R;;\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"(* 10. Fonction pour la création de matrice intermédiaire pour supprimer i j et ajouter i~ et j~ *)\n",
|
||||
"let f_k mat indice_i indice_j m_C = \n",
|
||||
"let n_mo = Mat.dim2 m_C\n",
|
||||
" in\n",
|
||||
" let n_ao = Mat.dim1 m_C\n",
|
||||
"in\n",
|
||||
"Mat.init_cols n_ao n_mo (fun i j -> \n",
|
||||
" if j=indice_i \n",
|
||||
" then mat.{i,1}\n",
|
||||
" else if j=indice_j \n",
|
||||
" then mat.{i,2}\n",
|
||||
" else 0.)\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"(* 11. Matrice intérmédiaire où les orbitales i et j ont été supprimées et remplacées par des 0, par soustraction de la matrice\n",
|
||||
"des coefs par la matrice *)\n",
|
||||
"let f_interm m_C m_Psi = Mat.sub m_C m_Psi;;\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"(* IV : Localisation des OMs *)\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"(* 1. Boucle de calcul de la nouvelle matrice des coefficient après n rotation d'orbitales *)\n",
|
||||
"let rec localisation m_C methode epsilon n prev_critere_D prev_m_alpha cc max_D=\n",
|
||||
"\n",
|
||||
" (*Printf.printf \"%i\\n%!\" n;*)\n",
|
||||
" (*Printf.printf \"%f\\n%!\" epsilon;*)\n",
|
||||
" (*Util.debug_matrix \"m_C\" m_C;*)\n",
|
||||
" (*Util.debug_matrix \"new_alpha_m\" prev_m_alpha;*)\n",
|
||||
"\n",
|
||||
"if n == 0 \n",
|
||||
" then m_C\n",
|
||||
" else\n",
|
||||
"\n",
|
||||
" (* Fonction de calcul de la nouvelle matrice de coef après rotation d'un angle alpha *)\n",
|
||||
" let new_m_C m_C methode m_alpha epsilon =\n",
|
||||
"\n",
|
||||
" (* alphaij contient le alpha max ainsi que ses indices i et j *)\n",
|
||||
" let n_rec_alpha = 10 (* Nombre ditération max pour réduire les valeurs de alpha *)\n",
|
||||
" in\n",
|
||||
" let alphaij = new_m_alpha m_alpha m_C n_rec_alpha \n",
|
||||
" in\n",
|
||||
"\n",
|
||||
" (* Valeur de alpha max après calcul *) (* Epsilon = Pas <1. , 1. -> normal, sinon Pas plus petit *)\n",
|
||||
" let alpha = (alphaij.alpha_max) *. epsilon \n",
|
||||
" in\n",
|
||||
"\n",
|
||||
" (*Printf.printf \"%f\\n%!\" alpha;*)\n",
|
||||
"\n",
|
||||
" (* Indice i et j du alpha max après calcul *)\n",
|
||||
" let indice_i = alphaij.indice_ii \n",
|
||||
" in\n",
|
||||
" let indice_j = alphaij.indice_jj \n",
|
||||
" in\n",
|
||||
"\n",
|
||||
" (*Printf.printf \"%i %i\\n%!\" indice_i indice_j;*)\n",
|
||||
"\n",
|
||||
" (* Matrice de rotation *)\n",
|
||||
" let m_R = f_R alpha \n",
|
||||
" in\n",
|
||||
"\n",
|
||||
" (*Util.debug_matrix \"m_R\" m_R;*)\n",
|
||||
"\n",
|
||||
" (* Matrice qui va subir la rotation *)\n",
|
||||
" let m_Ksi = f_Ksi indice_i indice_j m_C \n",
|
||||
" in\n",
|
||||
"\n",
|
||||
" (*Util.debug_matrix \"m_Ksi\" m_Ksi;*)\n",
|
||||
"\n",
|
||||
" (* Matrice ayant subit la rotation *)\n",
|
||||
" let m_Ksi_tilde = f_Ksi_tilde m_R m_Ksi m_C \n",
|
||||
" in\n",
|
||||
"\n",
|
||||
" (*Util.debug_matrix \"m_Ksi_tilde\" m_Ksi_tilde;*)\n",
|
||||
"\n",
|
||||
" (* Matrice pour supprimerles coef des orbitales i et j dans la matrice des coef *)\n",
|
||||
" let m_Psi = f_k m_Ksi indice_i indice_j m_C\n",
|
||||
" in\n",
|
||||
"\n",
|
||||
" (*Util.debug_matrix \"m_Psi\" m_Psi;*)\n",
|
||||
"\n",
|
||||
" (* Matrice pour ajouter les coef des orbitales i~ et j~ dans la matrice des coef *)\n",
|
||||
" let m_Psi_tilde = f_k m_Ksi_tilde indice_i indice_j m_C \n",
|
||||
" in\n",
|
||||
"\n",
|
||||
" (*Util.debug_matrix \"m_Psi_tilde\" m_Psi_tilde;*)\n",
|
||||
"\n",
|
||||
" (* Matrice avec les coef des orbitales i et j remplacés par 0 *)\n",
|
||||
" let m_interm = f_interm m_C m_Psi \n",
|
||||
" in\n",
|
||||
"\n",
|
||||
" (*Util.debug_matrix \"m_interm\" m_interm;*)\n",
|
||||
"\n",
|
||||
" (* Matrice après rotation *)\n",
|
||||
" (Mat.add m_Psi_tilde m_interm, alpha)\n",
|
||||
"\n",
|
||||
" in\n",
|
||||
" (* Extraction de la nouvelle matrice des coef et du alpha_max *)\n",
|
||||
" let m_new_m_C, alpha_max = new_m_C m_C methode prev_m_alpha epsilon\n",
|
||||
" in\n",
|
||||
"\n",
|
||||
" (* Fonction de pattern matching en fonction de la méthode *)\n",
|
||||
" let alphad = m_alpha_d methode m_new_m_C\n",
|
||||
" in\n",
|
||||
" \n",
|
||||
" (* Matrice des alphas *)\n",
|
||||
" let m_alpha = alphad.m_alpha\n",
|
||||
" in\n",
|
||||
" \n",
|
||||
" (* Critères possibles de localisation -> norme_alpha, moyenne_alpha, alpha, diff *)\n",
|
||||
" \n",
|
||||
" (* Norme de m_alpha, moyenne et max *)\n",
|
||||
" let norme_alpha = norme m_alpha\n",
|
||||
" in\n",
|
||||
" let moyenne_alpha = norme_alpha /. (float_of_int((Mat.dim1 m_C)* (Mat.dim2 m_C)))\n",
|
||||
" in\n",
|
||||
" let alpha = alpha_max /. epsilon\n",
|
||||
" in\n",
|
||||
" \n",
|
||||
" (* D critère à maximiser *)\n",
|
||||
" let critere_D = alphad.d \n",
|
||||
" in\n",
|
||||
" let diff = max_D -. critere_D \n",
|
||||
" in\n",
|
||||
" \n",
|
||||
" (*Printf.printf \"%f\\n%!\" diff;*)\n",
|
||||
" Printf.printf \"%i %f %f %f %f %f\\n%!\" n max_D critere_D alpha norme_alpha moyenne_alpha;\n",
|
||||
" \n",
|
||||
" (* Stabilisation de la convergence *)\n",
|
||||
"\n",
|
||||
" let max_D =\n",
|
||||
" if diff > 0.\n",
|
||||
" then max_D\n",
|
||||
" else critere_D\n",
|
||||
" in\n",
|
||||
" \n",
|
||||
" if diff > 0. && epsilon > 0.001\n",
|
||||
" then localisation m_C methode (epsilon /. 1000.) (n-1) critere_D prev_m_alpha cc max_D\n",
|
||||
" else let epsilon = 1.\n",
|
||||
" in\n",
|
||||
" \n",
|
||||
" (*Util.debug_matrix \"new_alpha_m\" m_alpha;*)\n",
|
||||
" (*Util.debug_matrix \"m_new_m_C\" m_new_m_C;*)\n",
|
||||
"\n",
|
||||
"\n",
|
||||
" (* Critère de conv pour sortir *)\n",
|
||||
" if alpha**2. < cc**2.\n",
|
||||
" then m_new_m_C\n",
|
||||
" else localisation m_new_m_C methode epsilon (n-1) critere_D m_alpha cc max_D;;\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"(* 2. Fonction de localisation *)\n",
|
||||
"let localise localisation m_C methode epsilon n cc=\n",
|
||||
" let alphad = m_alpha_d methode m_C \n",
|
||||
" in\n",
|
||||
" let prev_m_alpha = alphad.m_alpha\n",
|
||||
" in \n",
|
||||
" let prev_critere_D = 0.\n",
|
||||
" in\n",
|
||||
" let max_D = 0.\n",
|
||||
"in\n",
|
||||
"localisation m_C methode epsilon n prev_critere_D prev_m_alpha cc max_D;;"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"(* V : Fonctions pour la séparation et le rassemblement des matrices *)\n",
|
||||
"\n",
|
||||
"(* 1. Fonction de création d'une list d'entier à partir d'un vecteur de float*)\n",
|
||||
"let int_list vec = \n",
|
||||
" let float_list = Vec.to_list vec\n",
|
||||
" in\n",
|
||||
" let g a = int_of_float(a)\n",
|
||||
"in List.map g float_list;;\n",
|
||||
"\n",
|
||||
"(* 2. Fonction créant une liste à partir des éléments manquant d'une autre liste, dans l'intervalle [1 ; n_mo] *)\n",
|
||||
"let miss_elem mat list = \n",
|
||||
" let n_mo = Mat.dim2 mat\n",
|
||||
" in\n",
|
||||
" let vec = Vec.init (n_mo) (fun i ->\n",
|
||||
" if List.mem i list\n",
|
||||
" then 0.\n",
|
||||
" else float_of_int(i))\n",
|
||||
" in\n",
|
||||
" let list_int = int_list vec \n",
|
||||
"in\n",
|
||||
"List.filter (fun x -> x > 0) list_int;;\n",
|
||||
"\n",
|
||||
"(* 3. Fonction de séparation d'une matrice en 2 sous matrice, la première matrice correspondant aux colonnes de la matrice \n",
|
||||
"dont le numéro est présent dans la liste et la seconde à celles dont le numéro de colonne n'est pas présent dans la liste *)\n",
|
||||
"let split_mat mat list =\n",
|
||||
" let vec_of_mat = Mat.to_col_vecs mat\n",
|
||||
" in\n",
|
||||
" let f a = vec_of_mat.(a-1)\n",
|
||||
" in\n",
|
||||
" let vec_list_1 = List.map f list\n",
|
||||
" in\n",
|
||||
" let list_2 = miss_elem mat list\n",
|
||||
" in\n",
|
||||
" let vec_list_2 = List.map f list_2\n",
|
||||
"in (Mat.of_col_vecs_list vec_list_1,Mat.of_col_vecs_list vec_list_2);;\n",
|
||||
"\n",
|
||||
"(* 4. Liste des OMs occupées *)\n",
|
||||
"let list_occ = \n",
|
||||
" let vec_occ = Vec.init (nocc) (fun i -> float_of_int(i))\n",
|
||||
"in int_list vec_occ;;\n",
|
||||
"\n",
|
||||
"(* 5. Fonction de rassemblement de 2 matrices *)\n",
|
||||
"let assemble m_occ m_vir =\n",
|
||||
" let occ = Mat.to_col_vecs m_occ in\n",
|
||||
" let vir = Mat.to_col_vecs m_vir in\n",
|
||||
" Array.concat [ occ ; vir ]\n",
|
||||
" |> Mat.of_col_vecs\n",
|
||||
" \n",
|
||||
"(* 6. Séparation des OMs -> m_occ : OMs occupées; m_vir : OMs vacantes *)\n",
|
||||
"let m_occ , m_vir = split_mat m_C list_occ;;\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"(* VI : Calcul et assemblage des OMs occupées/virtuels *)\n",
|
||||
"\n",
|
||||
"(* Calcul : \n",
|
||||
"localise localisation / Matrice des coef / \"Methode\" (boys/er) / nb itération max / critère de convergence \n",
|
||||
"*)\n",
|
||||
"\n",
|
||||
"(*let new_m_boys = localise localisation m_C \"boys\" 1. 100 10e-7;;\n",
|
||||
"let new_m_er = localise localisation m_C \"ER\" 1. 100 10e-7;;\n",
|
||||
"*)\n",
|
||||
"(* Legende au dessus des valeurs print *)\n",
|
||||
"let texte = \"n max_D Critere_D alpha_max norme_alpha moyenne_alpha\"\n",
|
||||
"in Printf.printf \"%s\\n\" texte;;\n",
|
||||
"\n",
|
||||
"let loc_m_occ_boys = localise localisation m_occ \"Boys\" 1. 10000 10e-3;;\n",
|
||||
"let loc_m_vir_boys = localise localisation m_vir \"boys\" 1. 10000 10e-3;;\n",
|
||||
"let m_assemble_boys = assemble loc_m_occ_boys loc_m_vir_boys;;\n",
|
||||
"\n",
|
||||
"Printf.printf \"[\\n\";;\n",
|
||||
"Mat.as_vec m_assemble_boys\n",
|
||||
"|> Vec.iter (fun x -> Printf.printf \"%20.15e,\\n\" x);;\n",
|
||||
"Printf.printf \"]\\n\";;\n",
|
||||
"\n",
|
||||
"(*\n",
|
||||
"let loc_m_occ_er = localise localisation m_occ \"ER\" 1. 100 10e-7;;\n",
|
||||
"let loc_m_vir_er = localise localisation m_vir \"ER\" 1. 100 10e-7;;\n",
|
||||
"let m_assemble_er = assemble loc_m_occ_er loc_m_vir_er;;*)\n",
|
||||
"(*\n",
|
||||
"let loc_assemble_boys = localise localisation m_assemble_boys \"boys\" 1. 100 10e-7;;\n",
|
||||
"let loc_assemble_er = localise localisation m_assemble_er \"er\" 1. 100 10e-7;;*)\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"(*\n",
|
||||
"(* VII : Calcul Coef CI *)\n",
|
||||
"\n",
|
||||
"(* 1. Def de la mo_basis pour le HF pre CI *)\n",
|
||||
"\n",
|
||||
"(*\n",
|
||||
"let mo_base1 = MOBasis.make ~simulation ~mo_type:(MOBasis.Localized \"Boys\")\n",
|
||||
"~mo_occupation:(MOBasis.mo_occupation mo_basis) ~mo_coef:new_m_boys ();;\n",
|
||||
"\n",
|
||||
"let mo_base2 = MOBasis.make ~simulation ~mo_type:(MOBasis.Localized \"ER\")\n",
|
||||
"~mo_occupation:(MOBasis.mo_occupation mo_basis) ~mo_coef:new_m_er ();;\n",
|
||||
"*)\n",
|
||||
"\n",
|
||||
"let mo_base3 = MOBasis.make ~simulation ~mo_type:(MOBasis.Localized \"Boys\")\n",
|
||||
"~mo_occupation:(MOBasis.mo_occupation mo_basis) ~mo_coef:m_assemble_boys ();;\n",
|
||||
"\n",
|
||||
"(*\n",
|
||||
"let mo_base4 = MOBasis.make ~simulation ~mo_type:(MOBasis.Localized \"ER\")\n",
|
||||
"~mo_occupation:(MOBasis.mo_occupation mo_basis) ~mo_coef:m_assemble_er ();;\n",
|
||||
"\n",
|
||||
"let mo_base5 = MOBasis.make ~simulation ~mo_type:(MOBasis.Localized \"Boys\")\n",
|
||||
"~mo_occupation:(MOBasis.mo_occupation mo_basis) ~mo_coef:loc_assemble_boys ();;\n",
|
||||
"\n",
|
||||
"let mo_base6 = MOBasis.make ~simulation ~mo_type:(MOBasis.Localized \"ER\")\n",
|
||||
"~mo_occupation:(MOBasis.mo_occupation mo_basis) ~mo_coef:loc_assemble_er ();;\n",
|
||||
"*)\n",
|
||||
"*)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"(*\n",
|
||||
"(* 2. HF pour CI *)\n",
|
||||
"\n",
|
||||
"let nuclei =\n",
|
||||
" Nuclei.of_xyz_string xyz_string\n",
|
||||
" \n",
|
||||
"let basis = \n",
|
||||
" Basis.of_nuclei_and_basis_string nuclei basis_string\n",
|
||||
" \n",
|
||||
"let simulation = \n",
|
||||
" Simulation.make ~charge:0 ~multiplicity:1 ~nuclei basis\n",
|
||||
" \n",
|
||||
"let ao_basis = \n",
|
||||
" Simulation.ao_basis simulation\n",
|
||||
" \n",
|
||||
"let hf = HartreeFock.make simulation\n",
|
||||
"\n",
|
||||
"(*let mo_basis = MOBasis.of_hartree_fock hf*)\n",
|
||||
"let mo_basis = mo_base3\n",
|
||||
"*)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"(*\n",
|
||||
"(* 3. Calcul de coef CI *)\n",
|
||||
"\n",
|
||||
"let ci =\n",
|
||||
" DeterminantSpace.fci_of_mo_basis mo_basis ~frozen_core:false\n",
|
||||
" |> CI.make\n",
|
||||
" \n",
|
||||
"let ci_coef, ci_energy = Lazy.force ci.eigensystem ;;\n",
|
||||
"let m_ci_coef = Mat.as_vec ci_coef;;\n",
|
||||
"Vec.iteri (fun i x -> Printf.printf \"%d %e\\n\" i x) m_ci_coef;;\n",
|
||||
"*)"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "OCaml 4.10.0",
|
||||
"language": "OCaml",
|
||||
"name": "ocaml-jupyter"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": "text/x-ocaml",
|
||||
"file_extension": ".ml",
|
||||
"mimetype": "text/x-ocaml",
|
||||
"name": "OCaml",
|
||||
"nbconverter_exporter": null,
|
||||
"pygments_lexer": "OCaml",
|
||||
"version": "4.10.0"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
903
run_loc.ipynb
903
run_loc.ipynb
|
@ -1,903 +0,0 @@
|
|||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"hidden": true
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"(* Algorithme de localisation des orbitales : Méthode de Boys ou Edminston-Ruedenberg *)\n",
|
||||
"\n",
|
||||
"(*I : Position et base atomique*)\n",
|
||||
" (* 1. Coordonnées *)\n",
|
||||
" (* 2. Base atomique *)\n",
|
||||
"\n",
|
||||
"(* II : Hartree-Fock *)\n",
|
||||
" (* 1. Def pour HF *) (* !!! -> Charge !!! *)\n",
|
||||
" (* 2. Calcul de Hartree-Fock*)\n",
|
||||
" \n",
|
||||
"(* III : Définition des fonctions pour la localisation *)\n",
|
||||
" (* 1. Définitions de base nécessaire pour la suite *) \n",
|
||||
" (* 2. Fonction de calcul de tous les alpha ER *)\n",
|
||||
" (* 3. Fonction de calcul de tous les alpha Boys *)\n",
|
||||
" (* 4. Pattern matching : calcul de alpha et de D *)\n",
|
||||
" (* 5. Norme de alpha *)\n",
|
||||
" (* 6. Détermination alpha_max et ses indices i et j *) \n",
|
||||
" (* 7. Matrice de rotation 2 par 2 *)\n",
|
||||
" (* 8. Fonction : i,j -> matrice Ksi (n par 2) *)\n",
|
||||
" (* 9. Fonction : i~,j~ -> matrice Ksi~ (n par 2) *)\n",
|
||||
" (* 10. Matrice intermédiaire pour supprimer i j et ajouter i~ et j~ *)\n",
|
||||
" (* 11. Matrice intérmédiaire où les orbitales i et j ont été supprimées et remplacées par des 0*)\n",
|
||||
" \n",
|
||||
"(* IV : Localisation des OMs *)\n",
|
||||
" (* 1. Boucle de localisation des OMs *) (* !!! -> Choix paramètres et critères localisation !!! *)\n",
|
||||
" (* 2. Fonction de localisation *)\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"(* V : Fonctions pour la séparation et le rassemblement des matrices *)\n",
|
||||
" (* 1. Fonction de création d'une list d'entier à partir d'un vecteur de float*)\n",
|
||||
" (* 2. Fonction créant une liste à partir des éléments manquant d'une autre liste, dans l'intervalle [1 ; n_mo] *)\n",
|
||||
" (* 3. Fonction de séparation d'une matrice en 2 sous matrice *)\n",
|
||||
" (* 4. Liste des OMs occupées *)\n",
|
||||
" (* 5. Fonction de rassemblement de 2 matrices *) \n",
|
||||
" (* 6. Séparation des OMs -> m_occ : OMs occupées; m_vir : OMs vacantes *)\n",
|
||||
" \n",
|
||||
"(* VI : Calcul et assemblage des OMs occupées/virtuels *) (* !!! -> Choix paramètres de calcul !!! *)\n",
|
||||
" \n",
|
||||
"(* VII : Calcul Coef CI *)\n",
|
||||
" (* 1. Def de la mo_basis pour le HF pre CI *)\n",
|
||||
" (* 2. HF pour CI *)\n",
|
||||
" (* 3. Calcul de coef CI *)\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"open Lacaml.D\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"(*I : Position et base atomique*)\n",
|
||||
"\n",
|
||||
"(* 1. Coordonnées *)\n",
|
||||
"let xyz_string =\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"hidden": true
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"(* 2. Base atomique -> 6-31G *)\n",
|
||||
"\n",
|
||||
"let basis_string = \n",
|
||||
"\"\n",
|
||||
"HYDROGEN\n",
|
||||
"S 3\n",
|
||||
"1 0.1873113696E+02 0.3349460434E-01\n",
|
||||
"2 0.2825394365E+01 0.2347269535E+00\n",
|
||||
"3 0.6401216923E+00 0.8137573261E+00\n",
|
||||
"S 1\n",
|
||||
"1 0.1612777588E+00 1.0000000\n",
|
||||
"\n",
|
||||
"CARBON\n",
|
||||
"S 6\n",
|
||||
"1 0.3047524880E+04 0.1834737132E-02\n",
|
||||
"2 0.4573695180E+03 0.1403732281E-01\n",
|
||||
"3 0.1039486850E+03 0.6884262226E-01\n",
|
||||
"4 0.2921015530E+02 0.2321844432E+00\n",
|
||||
"5 0.9286662960E+01 0.4679413484E+00\n",
|
||||
"6 0.3163926960E+01 0.3623119853E+00\n",
|
||||
"S 3\n",
|
||||
"1 0.7868272350E+01 -0.1193324198E+00\n",
|
||||
"2 0.1881288540E+01 -0.1608541517E+00\n",
|
||||
"3 0.5442492580E+00 0.1143456438E+01\n",
|
||||
"S 1\n",
|
||||
"1 0.1687144782E+00 0.1000000000E+01\n",
|
||||
"P 3\n",
|
||||
"1 0.7868272350E+01 0.6899906659E-01\n",
|
||||
"2 0.1881288540E+01 0.3164239610E+00\n",
|
||||
"3 0.5442492580E+00 0.7443082909E+00\n",
|
||||
"P 1\n",
|
||||
"1 0.1687144782E+00 0.1000000000E+01\n",
|
||||
"\n",
|
||||
"NITROGEN\n",
|
||||
"S 6\n",
|
||||
"1 0.4173511460E+04 0.1834772160E-02\n",
|
||||
"2 0.6274579110E+03 0.1399462700E-01\n",
|
||||
"3 0.1429020930E+03 0.6858655181E-01\n",
|
||||
"4 0.4023432930E+02 0.2322408730E+00\n",
|
||||
"5 0.1282021290E+02 0.4690699481E+00\n",
|
||||
"6 0.4390437010E+01 0.3604551991E+00\n",
|
||||
"S 3\n",
|
||||
"1 0.1162636186E+02 -0.1149611817E+00\n",
|
||||
"2 0.2716279807E+01 -0.1691174786E+00\n",
|
||||
"3 0.7722183966E+00 0.1145851947E+01\n",
|
||||
"S 1\n",
|
||||
"1 0.2120314975E+00 0.1000000000E+01\n",
|
||||
"P 3\n",
|
||||
"1 0.1162636186E+02 0.6757974388E-01\n",
|
||||
"2 0.2716279807E+01 0.3239072959E+00\n",
|
||||
"3 0.7722183966E+00 0.7408951398E+00\n",
|
||||
"P 1\n",
|
||||
"1 0.2120314975E+00 0.1000000000E+01\n",
|
||||
"\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"hidden": true
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"(* II : Hartree-Fock *)\n",
|
||||
"\n",
|
||||
"(* 1. Def pour HF *)\n",
|
||||
"\n",
|
||||
"let nuclei =\n",
|
||||
" Nuclei.of_xyz_string xyz_string\n",
|
||||
" \n",
|
||||
"let basis = \n",
|
||||
" Basis.of_nuclei_and_basis_string nuclei basis_string\n",
|
||||
" \n",
|
||||
"let simulation = \n",
|
||||
" Simulation.make ~charge:0 ~multiplicity:1 ~nuclei basis \n",
|
||||
" \n",
|
||||
"let ao_basis = \n",
|
||||
" Simulation.ao_basis simulation\n",
|
||||
" \n",
|
||||
"let nocc =\n",
|
||||
" let elec = Simulation.electrons simulation in\n",
|
||||
" Electrons.n_alfa elec\n",
|
||||
" "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"hidden": true
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"(* 2. Calcul de Hartree-Fock*)\n",
|
||||
"\n",
|
||||
"let hf = HartreeFock.make simulation\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"hidden": true
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"let mo_basis = MOBasis.of_hartree_fock hf\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"hidden": true
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"let mo_coef = MOBasis.mo_coef mo_basis\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"(* III : Définition des fonctions pour la localisation *)\n",
|
||||
"\n",
|
||||
"(* 1. Définitions de base nécessaire pour la suite *)\n",
|
||||
"let ee_ints = AOBasis.ee_ints ao_basis;;\n",
|
||||
"let m_C = MOBasis.mo_coef mo_basis;;\n",
|
||||
"let n_ao = Mat.dim1 m_C ;;\n",
|
||||
"let n_mo = Mat.dim2 m_C ;;\n",
|
||||
"let multipoles = \n",
|
||||
" AOBasis.multipole ao_basis;;\n",
|
||||
" \n",
|
||||
"let sum a = \n",
|
||||
" Array.fold_left (fun accu x -> accu +. x) 0. a\n",
|
||||
" \n",
|
||||
"let pi = 3.14159265358979323846264338;;\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"(* 2. Fonction de calcul de tous les alpha ER *)\n",
|
||||
"let f_alpha m_C =\n",
|
||||
"\n",
|
||||
" let n_mo = Mat.dim2 m_C in\n",
|
||||
" (*let t0 = Sys.time () in*)\n",
|
||||
" \n",
|
||||
" let m_b12 = Mat.init_cols n_mo n_mo (fun i j -> 0.) in\n",
|
||||
" let m_a12 = Mat.init_cols n_mo n_mo (fun i j -> 0.) in\n",
|
||||
" let v_d = Vec.init n_mo (fun i -> 0.) in\n",
|
||||
" \n",
|
||||
" (* Tableaux temporaires *)\n",
|
||||
" let m_pqr =\n",
|
||||
" Bigarray.(Array3.create Float64 fortran_layout n_ao n_ao n_ao)\n",
|
||||
" in\n",
|
||||
" let m_qr_i = Mat.create (n_ao*n_ao) n_mo in\n",
|
||||
" let m_ri_j = Mat.create (n_ao*n_mo) n_mo in\n",
|
||||
" let m_ij_k = Mat.create (n_mo*n_mo) n_mo in\n",
|
||||
" \n",
|
||||
" Array.iter (fun s ->\n",
|
||||
" (* Grosse boucle externe sur s *)\n",
|
||||
" Array.iter (fun r ->\n",
|
||||
" Array.iter (fun q ->\n",
|
||||
" Array.iter (fun p ->\n",
|
||||
" m_pqr.{p,q,r} <- ERI.get_phys ee_ints p q r s\n",
|
||||
" ) (Util.array_range 1 n_ao)\n",
|
||||
" ) (Util.array_range 1 n_ao)\n",
|
||||
" ) (Util.array_range 1 n_ao);\n",
|
||||
" \n",
|
||||
" (* Conversion d'un tableau a 3 indices en une matrice nao x nao^2 *)\n",
|
||||
" let m_p_qr =\n",
|
||||
" Bigarray.reshape (Bigarray.genarray_of_array3 m_pqr) [| n_ao ; n_ao*n_ao |]\n",
|
||||
" |> Bigarray.array2_of_genarray\n",
|
||||
" in\n",
|
||||
" \n",
|
||||
" let m_qr_i =\n",
|
||||
" (* (qr,i) = <i r|q s> = \\sum_p <p r | q s> C_{pi} *)\n",
|
||||
" gemm ~transa:`T ~c:m_qr_i m_p_qr m_C\n",
|
||||
" in\n",
|
||||
" \n",
|
||||
" let m_q_ri =\n",
|
||||
" (* Transformation de la matrice (qr,i) en (q,ri) *)\n",
|
||||
" Bigarray.reshape_2 (Bigarray.genarray_of_array2 m_qr_i) n_ao (n_ao*n_mo)\n",
|
||||
" in\n",
|
||||
" \n",
|
||||
" let m_ri_j =\n",
|
||||
" (* (ri,j) = <i r | j s> = \\sum_q <i r | q s> C_{bj} *)\n",
|
||||
" gemm ~transa:`T ~c:m_ri_j m_q_ri m_C\n",
|
||||
" in\n",
|
||||
" \n",
|
||||
" let m_r_ij =\n",
|
||||
" (* Transformation de la matrice (ri,j) en (r,ij) *)\n",
|
||||
" Bigarray.reshape_2 (Bigarray.genarray_of_array2 m_ri_j) n_ao (n_mo*n_mo)\n",
|
||||
" in\n",
|
||||
" \n",
|
||||
" let m_ij_k =\n",
|
||||
" (* (ij,k) = <i k | j s> = \\sum_r <i r | j s> C_{rk} *)\n",
|
||||
" gemm ~transa:`T ~c:m_ij_k m_r_ij m_C\n",
|
||||
" in\n",
|
||||
" \n",
|
||||
" let m_ijk =\n",
|
||||
" (* Transformation de la matrice (ei,j) en (e,ij) *)\n",
|
||||
" Bigarray.reshape (Bigarray.genarray_of_array2 m_ij_k) [| n_mo ; n_mo ; n_mo |]\n",
|
||||
" |> Bigarray.array3_of_genarray\n",
|
||||
" in\n",
|
||||
" \n",
|
||||
" Array.iter (fun j ->\n",
|
||||
" Array.iter (fun i ->\n",
|
||||
" m_b12.{i,j} <- m_b12.{i,j} +. m_C.{s,j} *. (m_ijk.{i,i,i} -. m_ijk.{j,i,j});\n",
|
||||
" m_a12.{i,j} <- m_a12.{i,j} +. m_ijk.{i,i,j} *. m_C.{s,j} -.\n",
|
||||
" 0.25 *. ( (m_ijk.{i,i,i} -. m_ijk.{j,i,j}) *. m_C.{s,i} +.\n",
|
||||
" (m_ijk.{j,j,j} -. m_ijk.{i,j,i}) *. m_C.{s,j})\n",
|
||||
" ) (Util.array_range 1 n_mo);\n",
|
||||
" v_d.{j} <- v_d.{j} +. m_ijk.{j,j,j} *. m_C.{s,j}\n",
|
||||
" ) (Util.array_range 1 n_mo)\n",
|
||||
" ) (Util.array_range 1 n_ao);\n",
|
||||
" \n",
|
||||
" (*let t1 = Sys.time () in\n",
|
||||
" Printf.printf \"t = %f s\\n%!\" (t1 -. t0);*)\n",
|
||||
" \n",
|
||||
" (Mat.init_cols n_mo n_mo ( fun i j ->\n",
|
||||
" if i= j then 0.\n",
|
||||
" else 0.25 *. (acos(-. m_a12.{i,j} /. sqrt((m_a12.{i,j}**2.) +. (m_b12.{i,j}**2. ))))\n",
|
||||
" ),Vec.sum v_d);;\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"(* 3. Fonction de calcul de tous les alpha Boys *)\n",
|
||||
"\n",
|
||||
"let f_alpha_boys m_C = \n",
|
||||
" let n_mo = Mat.dim2 m_C\n",
|
||||
" in\n",
|
||||
" let phi_x_phi =\n",
|
||||
" Multipole.matrix_x multipoles \n",
|
||||
" |> MOBasis.mo_matrix_of_ao_matrix ~mo_coef:m_C\n",
|
||||
" in \n",
|
||||
" let phi_y_phi =\n",
|
||||
" Multipole.matrix_y multipoles \n",
|
||||
" |> MOBasis.mo_matrix_of_ao_matrix ~mo_coef:m_C\n",
|
||||
" in\n",
|
||||
" let phi_z_phi =\n",
|
||||
" Multipole.matrix_z multipoles \n",
|
||||
" |> MOBasis.mo_matrix_of_ao_matrix ~mo_coef:m_C\n",
|
||||
" in \n",
|
||||
"\n",
|
||||
" let m_b12= \n",
|
||||
" let b12 g = Mat.init_cols n_mo n_mo ( fun i j ->\n",
|
||||
" (g.{i,i} -. g.{j,j}) *. g.{i,j})\n",
|
||||
"\n",
|
||||
" in \n",
|
||||
" Mat.add (b12 phi_x_phi) ( Mat.add (b12 phi_y_phi) (b12 phi_z_phi))\n",
|
||||
" in \n",
|
||||
" let m_a12 =\n",
|
||||
" let a12 g = Mat.init_cols n_mo n_mo ( fun i j -> \n",
|
||||
" g.{i,j} *. g.{i,j} -. 0.25 *. ((g.{i,i} -. g.{j,j}) *. (g.{i,i} -. g.{j,j})))\n",
|
||||
" in\n",
|
||||
" Mat.add (a12 phi_x_phi) ( Mat.add (a12 phi_y_phi) (a12 phi_z_phi))\n",
|
||||
" in\n",
|
||||
" (Mat.init_cols n_mo n_mo ( fun i j -> \n",
|
||||
" if i=j \n",
|
||||
" then 0.\n",
|
||||
" else 0.25 *. acos(-. m_a12.{i,j} /. sqrt((m_a12.{i,j}**2.) +. (m_b12.{i,j}**2.) ))),\n",
|
||||
" Vec.sum(Vec.init n_mo ( fun i -> (phi_x_phi.{i,i})**2. +. (phi_y_phi.{i,i})**2. +. (phi_z_phi.{i,i})**2.)));;\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"(* 4. Pattern matching : calcul de alpha et de D *)\n",
|
||||
"\n",
|
||||
"type alphad = {\n",
|
||||
"m_alpha : Mat.t;\n",
|
||||
"d : float;\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"let m_alpha_d methode m_C = \n",
|
||||
" let alpha methode =\n",
|
||||
" \n",
|
||||
" match methode with \n",
|
||||
" | \"Boys\"\n",
|
||||
" | \"boys\" -> let alpha_boys , d_boys = f_alpha_boys m_C in {m_alpha = alpha_boys; d = d_boys}\n",
|
||||
" | \"ER\"\n",
|
||||
" | \"er\" -> let alpha_er , d_er = f_alpha m_C in {m_alpha = alpha_er; d = d_er}\n",
|
||||
" | _ -> invalid_arg \"Unknown method, please enter Boys or ER\"\n",
|
||||
"\n",
|
||||
"in \n",
|
||||
"alpha methode;;\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"(* 5. Norme de alpha *)\n",
|
||||
"\n",
|
||||
"let norme m = \n",
|
||||
" let vec_m = Mat.as_vec m\n",
|
||||
" in\n",
|
||||
" let vec2 = Vec.sqr vec_m\n",
|
||||
"in sqrt(Vec.sum vec2);;\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"(* 6. Détermination alpha_max et ses indices i et j.\n",
|
||||
"Si alpha max > pi/2 on soustrait pi/2 à la matrice des alphas de manière récursive *)\n",
|
||||
"type alphaij = {\n",
|
||||
" alpha_max : float;\n",
|
||||
" indice_ii : int;\n",
|
||||
" indice_jj : int;};;\n",
|
||||
"\n",
|
||||
"let rec new_m_alpha m_alpha m_C n_rec_alpha=\n",
|
||||
"\n",
|
||||
" let n_mo = Mat.dim2 m_C\n",
|
||||
" in\n",
|
||||
" let alpha_m =\n",
|
||||
" \n",
|
||||
" (*Printf.printf \"%i\\n%!\" n_rec_alpha;*)\n",
|
||||
" \n",
|
||||
" if n_rec_alpha == 0 \n",
|
||||
" then m_alpha \n",
|
||||
" else Mat.init_cols n_mo n_mo (fun i j -> \n",
|
||||
" if (m_alpha.{i,j}) > (pi /. 2.) \n",
|
||||
" then (m_alpha.{i,j} -. ( pi /. 2.))\n",
|
||||
" else if m_alpha.{i,j} < -. pi /. 2.\n",
|
||||
" then (m_alpha.{i,j} +. ( pi /. 2.))\n",
|
||||
" else if m_alpha.{i,j} < 0. \n",
|
||||
" then -. m_alpha.{i,j}\n",
|
||||
" else m_alpha.{i,j} )\n",
|
||||
" in \n",
|
||||
" \n",
|
||||
" (*Util.debug_matrix \"alpha_m\" alpha_m;*)\n",
|
||||
" \n",
|
||||
" (* Détermination de l'emplacement du alpha max *)\n",
|
||||
" let max_element3 alpha_m = \n",
|
||||
" Mat.as_vec alpha_m\n",
|
||||
" |> iamax\n",
|
||||
" in\n",
|
||||
" \n",
|
||||
" (* indice i et j du alpha max *)\n",
|
||||
" let indice_ii, indice_jj = \n",
|
||||
" let max = max_element3 alpha_m \n",
|
||||
" in\n",
|
||||
" (max - 1) mod n_mo +1, (max - 1) / n_mo +1\n",
|
||||
" in\n",
|
||||
" \n",
|
||||
" (* Valeur du alpha max*)\n",
|
||||
" let alpha alpha_m = \n",
|
||||
" let i = indice_ii \n",
|
||||
" in\n",
|
||||
" let j = indice_jj \n",
|
||||
" in\n",
|
||||
" alpha_m.{i,j}\n",
|
||||
" \n",
|
||||
" (*Printf.printf \"%i %i\\n%!\" i j;*)\n",
|
||||
" \n",
|
||||
" in\n",
|
||||
" let alpha_max = alpha alpha_m \n",
|
||||
" in\n",
|
||||
" \n",
|
||||
" (*Printf.printf \"%f\\n%!\" alpha_max;*)\n",
|
||||
" \n",
|
||||
" if alpha_max < pi /. 2.\n",
|
||||
" then {alpha_max; indice_ii; indice_jj}\n",
|
||||
" else new_m_alpha alpha_m m_C (n_rec_alpha-1);;\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"(* 7. Matrice de rotation 2 par 2 *)\n",
|
||||
"let f_R alpha =\n",
|
||||
" Mat.init_cols 2 2 (fun i j -> \n",
|
||||
" if i=j \n",
|
||||
" then cos alpha\n",
|
||||
" else if i>j \n",
|
||||
" then sin alpha \n",
|
||||
" else -. sin alpha )\n",
|
||||
";;\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"(* 8. Fonction d'extraction des 2 vecteurs propres i et j de la matrice des OMs pour les mettres dans la matrice Ksi (n par 2)\n",
|
||||
"pour appliquer R afin d'effectuer la rotation des orbitales *) (* {1,2} -> 1ere ligne, 2e colonne *)\n",
|
||||
"let f_Ksi indice_i indice_j m_C =\n",
|
||||
" let n_ao = Mat.dim1 m_C\n",
|
||||
"in\n",
|
||||
"Mat.init_cols n_ao 2 (fun i j -> if j=1 then m_C.{i,indice_i} else m_C.{i,indice_j} );;\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"(* 9. Fonction de calcul de ksi~ (matrice n par 2), nouvelle matrice par application de la matrice de rotation dans laquelle\n",
|
||||
"on obtient les deux orbitales que l'on va réinjecter dans la matrice Phi*)\n",
|
||||
"let f_Ksi_tilde m_R m_Ksi m_C = gemm m_Ksi m_R;;\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"(* 10. Fonction pour la création de matrice intermédiaire pour supprimer i j et ajouter i~ et j~ *)\n",
|
||||
"let f_k mat indice_i indice_j m_C = \n",
|
||||
"let n_mo = Mat.dim2 m_C\n",
|
||||
" in\n",
|
||||
" let n_ao = Mat.dim1 m_C\n",
|
||||
"in\n",
|
||||
"Mat.init_cols n_ao n_mo (fun i j -> \n",
|
||||
" if j=indice_i \n",
|
||||
" then mat.{i,1}\n",
|
||||
" else if j=indice_j \n",
|
||||
" then mat.{i,2}\n",
|
||||
" else 0.)\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"(* 11. Matrice intérmédiaire où les orbitales i et j ont été supprimées et remplacées par des 0, par soustraction de la matrice\n",
|
||||
"des coefs par la matrice *)\n",
|
||||
"let f_interm m_C m_Psi = Mat.sub m_C m_Psi;;\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"(* IV : Localisation des OMs *)\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"(* 1. Boucle de calcul de la nouvelle matrice des coefficient après n rotation d'orbitales *)\n",
|
||||
"let rec localisation m_C methode epsilon n prev_critere_D prev_m_alpha cc max_D=\n",
|
||||
"\n",
|
||||
" (*Printf.printf \"%i\\n%!\" n;*)\n",
|
||||
" (*Printf.printf \"%f\\n%!\" epsilon;*)\n",
|
||||
" (*Util.debug_matrix \"m_C\" m_C;*)\n",
|
||||
" (*Util.debug_matrix \"new_alpha_m\" prev_m_alpha;*)\n",
|
||||
"\n",
|
||||
"if n == 0 \n",
|
||||
" then m_C\n",
|
||||
" else\n",
|
||||
"\n",
|
||||
" (* Fonction de calcul de la nouvelle matrice de coef après rotation d'un angle alpha *)\n",
|
||||
" let new_m_C m_C methode m_alpha epsilon =\n",
|
||||
"\n",
|
||||
" (* alphaij contient le alpha max ainsi que ses indices i et j *)\n",
|
||||
" let n_rec_alpha = 10 (* Nombre ditération max pour réduire les valeurs de alpha *)\n",
|
||||
" in\n",
|
||||
" let alphaij = new_m_alpha m_alpha m_C n_rec_alpha \n",
|
||||
" in\n",
|
||||
"\n",
|
||||
" (* Valeur de alpha max après calcul *) (* Epsilon = Pas <1. , 1. -> normal, sinon Pas plus petit *)\n",
|
||||
" let alpha = (alphaij.alpha_max) *. epsilon \n",
|
||||
" in\n",
|
||||
"\n",
|
||||
" (*Printf.printf \"%f\\n%!\" alpha;*)\n",
|
||||
"\n",
|
||||
" (* Indice i et j du alpha max après calcul *)\n",
|
||||
" let indice_i = alphaij.indice_ii \n",
|
||||
" in\n",
|
||||
" let indice_j = alphaij.indice_jj \n",
|
||||
" in\n",
|
||||
"\n",
|
||||
" (*Printf.printf \"%i %i\\n%!\" indice_i indice_j;*)\n",
|
||||
"\n",
|
||||
" (* Matrice de rotation *)\n",
|
||||
" let m_R = f_R alpha \n",
|
||||
" in\n",
|
||||
"\n",
|
||||
" (*Util.debug_matrix \"m_R\" m_R;*)\n",
|
||||
"\n",
|
||||
" (* Matrice qui va subir la rotation *)\n",
|
||||
" let m_Ksi = f_Ksi indice_i indice_j m_C \n",
|
||||
" in\n",
|
||||
"\n",
|
||||
" (*Util.debug_matrix \"m_Ksi\" m_Ksi;*)\n",
|
||||
"\n",
|
||||
" (* Matrice ayant subit la rotation *)\n",
|
||||
" let m_Ksi_tilde = f_Ksi_tilde m_R m_Ksi m_C \n",
|
||||
" in\n",
|
||||
"\n",
|
||||
" (*Util.debug_matrix \"m_Ksi_tilde\" m_Ksi_tilde;*)\n",
|
||||
"\n",
|
||||
" (* Matrice pour supprimerles coef des orbitales i et j dans la matrice des coef *)\n",
|
||||
" let m_Psi = f_k m_Ksi indice_i indice_j m_C\n",
|
||||
" in\n",
|
||||
"\n",
|
||||
" (*Util.debug_matrix \"m_Psi\" m_Psi;*)\n",
|
||||
"\n",
|
||||
" (* Matrice pour ajouter les coef des orbitales i~ et j~ dans la matrice des coef *)\n",
|
||||
" let m_Psi_tilde = f_k m_Ksi_tilde indice_i indice_j m_C \n",
|
||||
" in\n",
|
||||
"\n",
|
||||
" (*Util.debug_matrix \"m_Psi_tilde\" m_Psi_tilde;*)\n",
|
||||
"\n",
|
||||
" (* Matrice avec les coef des orbitales i et j remplacés par 0 *)\n",
|
||||
" let m_interm = f_interm m_C m_Psi \n",
|
||||
" in\n",
|
||||
"\n",
|
||||
" (*Util.debug_matrix \"m_interm\" m_interm;*)\n",
|
||||
"\n",
|
||||
" (* Matrice après rotation *)\n",
|
||||
" (Mat.add m_Psi_tilde m_interm, alpha)\n",
|
||||
"\n",
|
||||
" in\n",
|
||||
" (* Extraction de la nouvelle matrice des coef et du alpha_max *)\n",
|
||||
" let m_new_m_C, alpha_max = new_m_C m_C methode prev_m_alpha epsilon\n",
|
||||
" in\n",
|
||||
"\n",
|
||||
" (* Fonction de pattern matching en fonction de la méthode *)\n",
|
||||
" let alphad = m_alpha_d methode m_new_m_C\n",
|
||||
" in\n",
|
||||
" \n",
|
||||
" (* Matrice des alphas *)\n",
|
||||
" let m_alpha = alphad.m_alpha\n",
|
||||
" in\n",
|
||||
" \n",
|
||||
" (* Critères possibles de localisation -> norme_alpha, moyenne_alpha, alpha, diff *)\n",
|
||||
" \n",
|
||||
" (* Norme de m_alpha, moyenne et max *)\n",
|
||||
" let norme_alpha = norme m_alpha\n",
|
||||
" in\n",
|
||||
" let moyenne_alpha = norme_alpha /. (float_of_int((Mat.dim1 m_C)* (Mat.dim2 m_C)))\n",
|
||||
" in\n",
|
||||
" let alpha = alpha_max /. epsilon\n",
|
||||
" in\n",
|
||||
" \n",
|
||||
" (* D critère à maximiser *)\n",
|
||||
" let critere_D = alphad.d \n",
|
||||
" in\n",
|
||||
" let diff = max_D -. critere_D \n",
|
||||
" in\n",
|
||||
" \n",
|
||||
" (*Printf.printf \"%f\\n%!\" diff;*)\n",
|
||||
" Printf.printf \"%i %f %f %f %f %f\\n%!\" n max_D critere_D alpha norme_alpha moyenne_alpha;\n",
|
||||
" \n",
|
||||
" (* Stabilisation de la convergence *)\n",
|
||||
"\n",
|
||||
" let max_D =\n",
|
||||
" if diff > 0.\n",
|
||||
" then max_D\n",
|
||||
" else critere_D\n",
|
||||
" in\n",
|
||||
" \n",
|
||||
" if diff > 0. && epsilon > 0.001\n",
|
||||
" then localisation m_C methode (epsilon /. 1000.) (n-1) critere_D prev_m_alpha cc max_D\n",
|
||||
" else let epsilon = 1.\n",
|
||||
" in\n",
|
||||
" \n",
|
||||
" (*Util.debug_matrix \"new_alpha_m\" m_alpha;*)\n",
|
||||
" (*Util.debug_matrix \"m_new_m_C\" m_new_m_C;*)\n",
|
||||
"\n",
|
||||
"\n",
|
||||
" (* Critère de conv pour sortir *)\n",
|
||||
" if alpha**2. < cc**2.\n",
|
||||
" then m_new_m_C\n",
|
||||
" else localisation m_new_m_C methode epsilon (n-1) critere_D m_alpha cc max_D;;\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"(* 2. Fonction de localisation *)\n",
|
||||
"let localise localisation m_C methode epsilon n cc=\n",
|
||||
" let alphad = m_alpha_d methode m_C \n",
|
||||
" in\n",
|
||||
" let prev_m_alpha = alphad.m_alpha\n",
|
||||
" in \n",
|
||||
" let prev_critere_D = 0.\n",
|
||||
" in\n",
|
||||
" let max_D = 0.\n",
|
||||
"in\n",
|
||||
"localisation m_C methode epsilon n prev_critere_D prev_m_alpha cc max_D;;"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"(* V : Fonctions pour la séparation et le rassemblement des matrices *)\n",
|
||||
"\n",
|
||||
"(* 1. Fonction de création d'une list d'entier à partir d'un vecteur de float*)\n",
|
||||
"let int_list vec = \n",
|
||||
" let float_list = Vec.to_list vec\n",
|
||||
" in\n",
|
||||
" let g a = int_of_float(a)\n",
|
||||
"in List.map g float_list;;\n",
|
||||
"\n",
|
||||
"(* 2. Fonction créant une liste à partir des éléments manquant d'une autre liste, dans l'intervalle [1 ; n_mo] *)\n",
|
||||
"let miss_elem mat list = \n",
|
||||
" let n_mo = Mat.dim2 mat\n",
|
||||
" in\n",
|
||||
" let vec = Vec.init (n_mo) (fun i ->\n",
|
||||
" if List.mem i list\n",
|
||||
" then 0.\n",
|
||||
" else float_of_int(i))\n",
|
||||
" in\n",
|
||||
" let list_int = int_list vec \n",
|
||||
"in\n",
|
||||
"List.filter (fun x -> x > 0) list_int;;\n",
|
||||
"\n",
|
||||
"(* 3. Fonction de séparation d'une matrice en 2 sous matrice, la première matrice correspondant aux colonnes de la matrice \n",
|
||||
"dont le numéro est présent dans la liste et la seconde à celles dont le numéro de colonne n'est pas présent dans la liste *)\n",
|
||||
"let split_mat mat list =\n",
|
||||
" let vec_of_mat = Mat.to_col_vecs mat\n",
|
||||
" in\n",
|
||||
" let f a = vec_of_mat.(a-1)\n",
|
||||
" in\n",
|
||||
" let vec_list_1 = List.map f list\n",
|
||||
" in\n",
|
||||
" let list_2 = miss_elem mat list\n",
|
||||
" in\n",
|
||||
" let vec_list_2 = List.map f list_2\n",
|
||||
"in (Mat.of_col_vecs_list vec_list_1,Mat.of_col_vecs_list vec_list_2);;\n",
|
||||
"\n",
|
||||
"(* 4. Liste des OMs occupées *)\n",
|
||||
"let list_occ = \n",
|
||||
" let vec_occ = Vec.init (nocc) (fun i -> float_of_int(i))\n",
|
||||
"in int_list vec_occ;;\n",
|
||||
"\n",
|
||||
"(* 5. Fonction de rassemblement de 2 matrices *)\n",
|
||||
"let assemble m_occ m_vir =\n",
|
||||
" let occ = Mat.to_col_vecs m_occ in\n",
|
||||
" let vir = Mat.to_col_vecs m_vir in\n",
|
||||
" Array.concat [ occ ; vir ]\n",
|
||||
" |> Mat.of_col_vecs\n",
|
||||
" \n",
|
||||
"(* 6. Séparation des OMs -> m_occ : OMs occupées; m_vir : OMs vacantes *)\n",
|
||||
"let m_occ , m_vir = split_mat m_C list_occ;;\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"(* VI : Calcul et assemblage des OMs occupées/virtuels *)\n",
|
||||
"\n",
|
||||
"(* Calcul : \n",
|
||||
"localise localisation / Matrice des coef / \"Methode\" (boys/er) / nb itération max / critère de convergence \n",
|
||||
"*)\n",
|
||||
"\n",
|
||||
"(*let new_m_boys = localise localisation m_C \"boys\" 1. 100 10e-7;;\n",
|
||||
"let new_m_er = localise localisation m_C \"ER\" 1. 100 10e-7;;\n",
|
||||
"*)\n",
|
||||
"(* Legende au dessus des valeurs print *)\n",
|
||||
"let texte = \"n max_D Critere_D alpha_max norme_alpha moyenne_alpha\"\n",
|
||||
"in Printf.printf \"%s\\n\" texte;;\n",
|
||||
"\n",
|
||||
"let loc_m_occ_boys = localise localisation m_occ \"Boys\" 1. 10000 10e-3;;\n",
|
||||
"let loc_m_vir_boys = localise localisation m_vir \"boys\" 1. 10000 10e-3;;\n",
|
||||
"let m_assemble_boys = assemble loc_m_occ_boys loc_m_vir_boys;;\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"Printf.printf \"[\\n\";;\n",
|
||||
"Mat.as_vec m_assemble_boys\n",
|
||||
"|> Vec.iter (fun x -> Printf.printf \"%20.15e,\\n\" x);;\n",
|
||||
"Printf.printf \"]\\n\";;\n",
|
||||
"\n",
|
||||
"(*\n",
|
||||
"let loc_m_occ_er = localise localisation m_occ \"ER\" 1. 100 10e-7;;\n",
|
||||
"let loc_m_vir_er = localise localisation m_vir \"ER\" 1. 100 10e-7;;\n",
|
||||
"let m_assemble_er = assemble loc_m_occ_er loc_m_vir_er;;*)\n",
|
||||
"(*\n",
|
||||
"let loc_assemble_boys = localise localisation m_assemble_boys \"boys\" 1. 100 10e-7;;\n",
|
||||
"let loc_assemble_er = localise localisation m_assemble_er \"er\" 1. 100 10e-7;;*)\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"(*\n",
|
||||
"(* VII : Calcul Coef CI *)\n",
|
||||
"\n",
|
||||
"(* 1. Def de la mo_basis pour le HF pre CI *)\n",
|
||||
"\n",
|
||||
"(*\n",
|
||||
"let mo_base1 = MOBasis.make ~simulation ~mo_type:(MOBasis.Localized \"Boys\")\n",
|
||||
"~mo_occupation:(MOBasis.mo_occupation mo_basis) ~mo_coef:new_m_boys ();;\n",
|
||||
"\n",
|
||||
"let mo_base2 = MOBasis.make ~simulation ~mo_type:(MOBasis.Localized \"ER\")\n",
|
||||
"~mo_occupation:(MOBasis.mo_occupation mo_basis) ~mo_coef:new_m_er ();;\n",
|
||||
"*)\n",
|
||||
"\n",
|
||||
"let mo_base3 = MOBasis.make ~simulation ~mo_type:(MOBasis.Localized \"Boys\")\n",
|
||||
"~mo_occupation:(MOBasis.mo_occupation mo_basis) ~mo_coef:m_assemble_boys ();;\n",
|
||||
"\n",
|
||||
"(*\n",
|
||||
"let mo_base4 = MOBasis.make ~simulation ~mo_type:(MOBasis.Localized \"ER\")\n",
|
||||
"~mo_occupation:(MOBasis.mo_occupation mo_basis) ~mo_coef:m_assemble_er ();;\n",
|
||||
"\n",
|
||||
"let mo_base5 = MOBasis.make ~simulation ~mo_type:(MOBasis.Localized \"Boys\")\n",
|
||||
"~mo_occupation:(MOBasis.mo_occupation mo_basis) ~mo_coef:loc_assemble_boys ();;\n",
|
||||
"\n",
|
||||
"let mo_base6 = MOBasis.make ~simulation ~mo_type:(MOBasis.Localized \"ER\")\n",
|
||||
"~mo_occupation:(MOBasis.mo_occupation mo_basis) ~mo_coef:loc_assemble_er ();;\n",
|
||||
"*)\n",
|
||||
"*)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"(*\n",
|
||||
"(* 2. HF pour CI *)\n",
|
||||
"\n",
|
||||
"let nuclei =\n",
|
||||
" Nuclei.of_xyz_string xyz_string\n",
|
||||
" \n",
|
||||
"let basis = \n",
|
||||
" Basis.of_nuclei_and_basis_string nuclei basis_string\n",
|
||||
" \n",
|
||||
"let simulation = \n",
|
||||
" Simulation.make ~charge:0 ~multiplicity:1 ~nuclei basis\n",
|
||||
" \n",
|
||||
"let ao_basis = \n",
|
||||
" Simulation.ao_basis simulation\n",
|
||||
" \n",
|
||||
"let hf = HartreeFock.make simulation\n",
|
||||
"\n",
|
||||
"(*let mo_basis = MOBasis.of_hartree_fock hf*)\n",
|
||||
"let mo_basis = mo_base3\n",
|
||||
"*)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"(*\n",
|
||||
"(* 3. Calcul de coef CI *)\n",
|
||||
"\n",
|
||||
"let ci =\n",
|
||||
" DeterminantSpace.fci_of_mo_basis mo_basis ~frozen_core:false\n",
|
||||
" |> CI.make\n",
|
||||
" \n",
|
||||
"let ci_coef, ci_energy = Lazy.force ci.eigensystem ;;\n",
|
||||
"let m_ci_coef = Mat.as_vec ci_coef;;\n",
|
||||
"Vec.iteri (fun i x -> Printf.printf \"%d %e\\n\" i x) m_ci_coef;;\n",
|
||||
"*)"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "OCaml 4.10.0",
|
||||
"language": "OCaml",
|
||||
"name": "ocaml-jupyter"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": "text/x-ocaml",
|
||||
"file_extension": ".ml",
|
||||
"mimetype": "text/x-ocaml",
|
||||
"name": "OCaml",
|
||||
"nbconverter_exporter": null,
|
||||
"pygments_lexer": "OCaml",
|
||||
"version": "4.10.0"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
Loading…
Reference in New Issue