1
0
mirror of https://github.com/TREX-CoE/qmckl.git synced 2024-09-27 03:51:09 +02:00

Make eN scaling nucleus-specific

This commit is contained in:
Anthony Scemama 2022-09-08 14:04:49 +02:00
parent 170109d986
commit 9f4731ff94
3 changed files with 456 additions and 399 deletions

View File

@ -80,13 +80,13 @@ int main() {
The following data stored in the context: The following data stored in the context:
| Variable | Type | Description | | Variable | Type | Description |
|---------------------------+---------------+---------------------------------------| |---------------------------+--------------------+--------------------------------------|
| ~uninitialized~ | ~int32_t~ | Keeps bit set for uninitialized data | | ~uninitialized~ | ~int32_t~ | Keeps bit set for uninitialized data |
| ~num~ | ~int64_t~ | Total number of electrons | | ~num~ | ~int64_t~ | Total number of electrons |
| ~up_num~ | ~int64_t~ | Number of up-spin electrons | | ~up_num~ | ~int64_t~ | Number of up-spin electrons |
| ~down_num~ | ~int64_t~ | Number of down-spin electrons | | ~down_num~ | ~int64_t~ | Number of down-spin electrons |
| ~rescale_factor_kappa_ee~ | ~double~ | The distance scaling factor | | ~rescale_factor_kappa_ee~ | ~double~ | The distance scaling factor |
| ~rescale_factor_kappa_en~ | ~double~ | The distance scaling factor | | ~rescale_factor_kappa_en~ | ~double[nucl_num]~ | The distance scaling factor |
| ~provided~ | ~bool~ | If true, ~electron~ is valid | | ~provided~ | ~bool~ | If true, ~electron~ is valid |
| ~walker~ | ~qmckl_point~ | Current set of walkers | | ~walker~ | ~qmckl_point~ | Current set of walkers |
| ~walker_old~ | ~qmckl_point~ | Previous set of walkers | | ~walker_old~ | ~qmckl_point~ | Previous set of walkers |
@ -94,7 +94,7 @@ int main() {
Computed data: Computed data:
| Variable | Type | Description | | Variable | Type | Description |
|-------------------------------------+--------------------------------------+----------------------------------------------------------------------| |-------------------------------------+----------------------------------------+----------------------------------------------------------------------|
| ~ee_distance~ | ~double[walker.num][num][num]~ | Electron-electron distances | | ~ee_distance~ | ~double[walker.num][num][num]~ | Electron-electron distances |
| ~ee_distance_date~ | ~uint64_t~ | Last modification date of the electron-electron distances | | ~ee_distance_date~ | ~uint64_t~ | Last modification date of the electron-electron distances |
| ~en_distance~ | ~double[walker.num][nucl_num][num]~ | Electron-nucleus distances | | ~en_distance~ | ~double[walker.num][nucl_num][num]~ | Electron-nucleus distances |
@ -128,7 +128,7 @@ typedef struct qmckl_electron_struct {
qmckl_walker walker; qmckl_walker walker;
qmckl_walker walker_old; qmckl_walker walker_old;
double rescale_factor_kappa_ee; double rescale_factor_kappa_ee;
double rescale_factor_kappa_en; double* rescale_factor_kappa_en;
uint64_t ee_distance_date; uint64_t ee_distance_date;
uint64_t en_distance_date; uint64_t en_distance_date;
uint64_t ee_potential_date; uint64_t ee_potential_date;
@ -172,11 +172,10 @@ qmckl_exit_code qmckl_init_electron(qmckl_context context) {
qmckl_context_struct* const ctx = (qmckl_context_struct*) context; qmckl_context_struct* const ctx = (qmckl_context_struct*) context;
assert (ctx != NULL); assert (ctx != NULL);
ctx->electron.uninitialized = (1 << 1) - 1; ctx->electron.uninitialized = (1 << 2) - 1;
/* Default values */ /* Default values */
ctx->electron.rescale_factor_kappa_ee = 1.0; ctx->electron.rescale_factor_kappa_ee = 1.0;
ctx->electron.rescale_factor_kappa_en = 1.0;
return QMCKL_SUCCESS; return QMCKL_SUCCESS;
} }
@ -201,6 +200,259 @@ bool qmckl_electron_provided(const qmckl_context context) {
} }
#+end_src #+end_src
** Initialization functions
To set the data relative to the electrons in the context, the
following functions need to be called. When the data structure is
initialized, the internal ~coord_new~ and ~coord_old~ arrays are
both not allocated.
#+begin_src c :comments org :tangle (eval h_func)
qmckl_exit_code qmckl_set_electron_num (qmckl_context context, const int64_t up_num, const int64_t down_num);
qmckl_exit_code qmckl_set_electron_coord (qmckl_context context, const char transp, const int64_t walk_num, const double* coord, const int64_t size_max);
qmckl_exit_code qmckl_set_electron_rescale_factor_ee (qmckl_context context, const double kappa_ee);
qmckl_exit_code qmckl_set_electron_rescale_factor_en (qmckl_context context, const double* kappa_en, const int size_max);
#+end_src
#+NAME:pre2
#+begin_src c :exports none
if (qmckl_context_check(context) == QMCKL_NULL_CONTEXT) {
return QMCKL_NULL_CONTEXT;
}
qmckl_context_struct* const ctx = (qmckl_context_struct*) context;
if (mask != 0 && !(ctx->electron.uninitialized & mask)) {
return qmckl_failwith( context,
QMCKL_ALREADY_SET,
"qmckl_set_electron_*",
NULL);
}
#+end_src
#+NAME:post
#+begin_src c :exports none
ctx->electron.uninitialized &= ~mask;
ctx->electron.provided = (ctx->electron.uninitialized == 0);
return QMCKL_SUCCESS;
#+end_src
To set the number of electrons, we give the number of up-spin and
down-spin electrons to the context and we set the number of walkers.
#+begin_src c :comments org :tangle (eval c) :noweb yes :exports none
qmckl_exit_code
qmckl_set_electron_num(qmckl_context context,
const int64_t up_num,
const int64_t down_num) {
int32_t mask = 1 << 0;
<<pre2>>
if (up_num <= 0) {
return qmckl_failwith( context,
QMCKL_INVALID_ARG_2,
"qmckl_set_electron_num",
"up_num <= 0");
}
if (down_num < 0) {
return qmckl_failwith( context,
QMCKL_INVALID_ARG_3,
"qmckl_set_electron_num",
"down_num < 0");
}
ctx->electron.up_num = up_num;
ctx->electron.down_num = down_num;
ctx->electron.num = up_num + down_num;
<<post>>
}
#+end_src
Next we set the rescale parameter for the rescaled distance metric.
#+begin_src c :comments org :tangle (eval c) :noweb yes :exports none
qmckl_exit_code
qmckl_set_electron_rescale_factor_ee(qmckl_context context,
const double rescale_factor_kappa_ee) {
int32_t mask = 0; // can be changed
<<pre2>>
if (rescale_factor_kappa_ee <= 0.0) {
return qmckl_failwith( context,
QMCKL_INVALID_ARG_2,
"qmckl_set_electron_rescale_factor_ee",
"rescale_factor_kappa_ee <= 0.0");
}
ctx->electron.rescale_factor_kappa_ee = rescale_factor_kappa_ee;
<<post>>
}
#+end_src
#+begin_src c :comments org :tangle (eval c) :noweb yes :exports none
qmckl_exit_code
qmckl_set_electron_rescale_factor_en(qmckl_context context,
const double* rescale_factor_kappa_en, const int64_t size_max) {
int32_t mask = 1 << 1;
<<pre2>>
if (rescale_factor_kappa_en == NULL) {
return qmckl_failwith( context,
QMCKL_INVALID_ARG_2,
"qmckl_set_electron_rescale_factor_en",
"Null pointer");
}
if (size_max < ctx->nucleus.num) {
return qmckl_failwith( context,
QMCKL_INVALID_ARG_3,
"qmckl_set_electron_rescale_factor_en",
"Array too small");
}
if (ctx->electron.rescale_factor_kappa_en != NULL) {
return qmckl_failwith( context,
QMCKL_INVALID_ARG_3,
"qmckl_set_electron_rescale_factor_en",
"Already set");
}
qmckl_memory_info_struct mem_info = qmckl_memory_info_struct_zero;
mem_info.size = ctx->nucleus.num * sizeof(double);
ctx->electron.rescale_factor_kappa_en = (double*) qmckl_malloc(context, mem_info);
for (int64_t i=0 ; i<ctx->nucleus.num ; ++i) {
if (rescale_factor_kappa_en[i] <= 0.0) {
return qmckl_failwith( context,
QMCKL_INVALID_ARG_2,
"qmckl_set_electron_rescale_factor_en",
"rescale_factor_kappa_en <= 0.0");
}
ctx->electron.rescale_factor_kappa_en[i] = rescale_factor_kappa_en[i];
}
<<post>>
}
#+end_src
#+begin_src f90 :comments org :tangle (eval fh_func) :noweb yes
interface
integer(c_int32_t) function qmckl_set_electron_num(context, alpha, beta) bind(C)
use, intrinsic :: iso_c_binding
import
implicit none
integer (c_int64_t) , intent(in) , value :: context
integer (c_int64_t) , intent(in) , value :: alpha
integer (c_int64_t) , intent(in) , value :: beta
end function
end interface
#+end_src
The following function sets the electron coordinates of all the
walkers. When this is done, the pointers to the old and new sets
of coordinates are swapped, and the new coordinates are
overwritten. This can be done only when the data relative to
electrons have been set.
~size_max~ should be equal equal or geater than ~elec_num *
walker.num * 3~, to be symmetric with ~qmckl_get_electron_coord~.
Important: changing the electron coordinates increments the date
in the context.
#+begin_src c :comments org :tangle (eval c) :noweb yes :exports none
qmckl_exit_code
qmckl_set_electron_coord(qmckl_context context,
const char transp,
const int64_t walk_num,
const double* coord,
const int64_t size_max)
{
int32_t mask = 0; // coord can be changed
<<pre2>>
if (transp != 'N' && transp != 'T') {
return qmckl_failwith( context,
QMCKL_INVALID_ARG_2,
"qmckl_set_electron_coord",
"transp should be 'N' or 'T'");
}
if (walk_num <= 0) {
return qmckl_failwith( context,
QMCKL_INVALID_ARG_3,
"qmckl_set_electron_coord",
"walk_num <= 0");
}
if (coord == NULL) {
return qmckl_failwith( context,
QMCKL_INVALID_ARG_3,
"qmckl_set_electron_coord",
"coord is a null pointer");
}
const int64_t elec_num = ctx->electron.num;
if (elec_num == 0L) {
return qmckl_failwith( context,
QMCKL_FAILURE,
"qmckl_set_electron_coord",
"elec_num is not set");
}
/* Swap pointers */
qmckl_walker tmp = ctx->electron.walker_old;
ctx->electron.walker_old = ctx->electron.walker;
ctx->electron.walker = tmp;
memcpy(&(ctx->point), &(ctx->electron.walker.point), sizeof(qmckl_point_struct));
qmckl_exit_code rc;
rc = qmckl_set_point(context, transp, walk_num*elec_num, coord, size_max);
if (rc != QMCKL_SUCCESS) return rc;
ctx->electron.walker.num = walk_num;
memcpy(&(ctx->electron.walker.point), &(ctx->point), sizeof(qmckl_point_struct));
return QMCKL_SUCCESS;
}
#+end_src
#+begin_src f90 :comments org :tangle (eval fh_func) :noweb yes
interface
integer(c_int32_t) function qmckl_set_electron_coord(context, transp, walk_num, coord, size_max) bind(C)
use, intrinsic :: iso_c_binding
import
implicit none
integer (c_int64_t) , intent(in) , value :: context
character , intent(in) , value :: transp
integer (c_int64_t) , intent(in) , value :: walk_num
double precision , intent(in) :: coord(*)
integer (c_int64_t) , intent(in) , value :: size_max
end function
end interface
#+end_src
** Access functions ** Access functions
Access functions return ~QMCKL_SUCCESS~ when the data has been Access functions return ~QMCKL_SUCCESS~ when the data has been
@ -210,13 +462,6 @@ bool qmckl_electron_provided(const qmckl_context context) {
successfully, the variable pointed by the pointer given in argument successfully, the variable pointed by the pointer given in argument
contains the requested data. Otherwise, this variable is untouched. contains the requested data. Otherwise, this variable is untouched.
#+NAME:post
#+begin_src c :exports none
if ( (ctx->electron.uninitialized & mask) != 0) {
return NULL;
}
#+end_src
*** Number of electrons *** Number of electrons
#+begin_src c :comments org :tangle (eval h_func) :exports none #+begin_src c :comments org :tangle (eval h_func) :exports none
@ -347,7 +592,7 @@ qmckl_get_electron_walk_num (const qmckl_context context, int64_t* const walk_nu
#+begin_src c :comments org :tangle (eval h_func) :exports none #+begin_src c :comments org :tangle (eval h_func) :exports none
qmckl_exit_code qmckl_get_electron_rescale_factor_ee (const qmckl_context context, double* const rescale_factor_kappa_ee); qmckl_exit_code qmckl_get_electron_rescale_factor_ee (const qmckl_context context, double* const rescale_factor_kappa_ee);
qmckl_exit_code qmckl_get_electron_rescale_factor_en (const qmckl_context context, double* const rescale_factor_kappa_en); qmckl_exit_code qmckl_get_electron_rescale_factor_en (const qmckl_context context, double* const rescale_factor_kappa_en, const int64_t size_max);
#+end_src #+end_src
#+begin_src c :comments org :tangle (eval c) :noweb yes :exports none #+begin_src c :comments org :tangle (eval c) :noweb yes :exports none
@ -370,13 +615,13 @@ qmckl_get_electron_rescale_factor_ee (const qmckl_context context, double* const
assert (ctx->electron.rescale_factor_kappa_ee > 0.0); assert (ctx->electron.rescale_factor_kappa_ee > 0.0);
*rescale_factor_kappa_ee = ctx->electron.rescale_factor_kappa_ee; ,*rescale_factor_kappa_ee = ctx->electron.rescale_factor_kappa_ee;
return QMCKL_SUCCESS; return QMCKL_SUCCESS;
} }
qmckl_exit_code qmckl_exit_code
qmckl_get_electron_rescale_factor_en (const qmckl_context context, double* const rescale_factor_kappa_en) { qmckl_get_electron_rescale_factor_en (const qmckl_context context, double* const rescale_factor_kappa_en, const int64_t size_max) {
if (qmckl_context_check(context) == QMCKL_NULL_CONTEXT) { if (qmckl_context_check(context) == QMCKL_NULL_CONTEXT) {
return QMCKL_INVALID_CONTEXT; return QMCKL_INVALID_CONTEXT;
} }
@ -388,11 +633,26 @@ qmckl_get_electron_rescale_factor_en (const qmckl_context context, double* const
"rescale_factor_kappa_en is a null pointer"); "rescale_factor_kappa_en is a null pointer");
} }
if (size_max < nucl_num) {
return qmckl_failwith( context,
QMCKL_INVALID_ARG_3,
"qmckl_get_electron_rescale_factor_en",
"Array to small");
}
qmckl_context_struct* const ctx = (qmckl_context_struct*) context; qmckl_context_struct* const ctx = (qmckl_context_struct*) context;
assert (ctx != NULL); assert (ctx != NULL);
assert (ctx->electron.rescale_factor_kappa_en > 0.0); if (ctx->electron.rescale_factor_kappa_en != NULL) {
*rescale_factor_kappa_en = ctx->electron.rescale_factor_kappa_en; for (int64_t i=0 ; i<ctx->nucleus.num ; ++i) {
rescale_factor_kappa_en[i] = ctx->electron.rescale_factor_kappa_en[i];
}
} else {
for (int64_t i=0 ; i<ctx->nucleus.num ; ++i) {
rescale_factor_kappa_en[i] = 1.0;
}
}
return QMCKL_SUCCESS; return QMCKL_SUCCESS;
} }
#+end_src #+end_src
@ -470,230 +730,6 @@ qmckl_get_electron_coord (const qmckl_context context,
} }
#+end_src #+end_src
** Initialization functions
To set the data relative to the electrons in the context, the
following functions need to be called. When the data structure is
initialized, the internal ~coord_new~ and ~coord_old~ arrays are
both not allocated.
#+begin_src c :comments org :tangle (eval h_func)
qmckl_exit_code qmckl_set_electron_num (qmckl_context context, const int64_t up_num, const int64_t down_num);
qmckl_exit_code qmckl_set_electron_coord (qmckl_context context, const char transp, const int64_t walk_num, const double* coord, const int64_t size_max);
qmckl_exit_code qmckl_set_electron_rescale_factor_ee (qmckl_context context, const double kappa_ee);
qmckl_exit_code qmckl_set_electron_rescale_factor_en (qmckl_context context, const double kappa_en);
#+end_src
#+NAME:pre2
#+begin_src c :exports none
if (qmckl_context_check(context) == QMCKL_NULL_CONTEXT) {
return QMCKL_NULL_CONTEXT;
}
qmckl_context_struct* const ctx = (qmckl_context_struct*) context;
if (mask != 0 && !(ctx->electron.uninitialized & mask)) {
return qmckl_failwith( context,
QMCKL_ALREADY_SET,
"qmckl_set_electron_*",
NULL);
}
#+end_src
#+NAME:post2
#+begin_src c :exports none
ctx->electron.uninitialized &= ~mask;
ctx->electron.provided = (ctx->electron.uninitialized == 0);
return QMCKL_SUCCESS;
#+end_src
To set the number of electrons, we give the number of up-spin and
down-spin electrons to the context and we set the number of walkers.
#+begin_src c :comments org :tangle (eval c) :noweb yes :exports none
qmckl_exit_code
qmckl_set_electron_num(qmckl_context context,
const int64_t up_num,
const int64_t down_num) {
int32_t mask = 1 << 0;
<<pre2>>
if (up_num <= 0) {
return qmckl_failwith( context,
QMCKL_INVALID_ARG_2,
"qmckl_set_electron_num",
"up_num <= 0");
}
if (down_num < 0) {
return qmckl_failwith( context,
QMCKL_INVALID_ARG_3,
"qmckl_set_electron_num",
"down_num < 0");
}
ctx->electron.up_num = up_num;
ctx->electron.down_num = down_num;
ctx->electron.num = up_num + down_num;
<<post2>>
}
#+end_src
Next we set the rescale parameter for the rescaled distance metric.
#+begin_src c :comments org :tangle (eval c) :noweb yes :exports none
qmckl_exit_code
qmckl_set_electron_rescale_factor_ee(qmckl_context context,
const double rescale_factor_kappa_ee) {
int32_t mask = 0; // can be changed
<<pre2>>
if (rescale_factor_kappa_ee <= 0.0) {
return qmckl_failwith( context,
QMCKL_INVALID_ARG_2,
"qmckl_set_electron_rescale_factor_ee",
"rescale_factor_kappa_ee <= 0.0");
}
ctx->electron.rescale_factor_kappa_ee = rescale_factor_kappa_ee;
return QMCKL_SUCCESS;
}
qmckl_exit_code
qmckl_set_electron_rescale_factor_en(qmckl_context context,
const double rescale_factor_kappa_en) {
int32_t mask = 0; // can be changed
<<pre2>>
if (rescale_factor_kappa_en <= 0.0) {
return qmckl_failwith( context,
QMCKL_INVALID_ARG_2,
"qmckl_set_electron_rescale_factor_en",
"rescale_factor_kappa_en <= 0.0");
}
ctx->electron.rescale_factor_kappa_en = rescale_factor_kappa_en;
return QMCKL_SUCCESS;
}
#+end_src
#+begin_src f90 :comments org :tangle (eval fh_func) :noweb yes
interface
integer(c_int32_t) function qmckl_set_electron_num(context, alpha, beta) bind(C)
use, intrinsic :: iso_c_binding
import
implicit none
integer (c_int64_t) , intent(in) , value :: context
integer (c_int64_t) , intent(in) , value :: alpha
integer (c_int64_t) , intent(in) , value :: beta
end function
end interface
#+end_src
The following function sets the electron coordinates of all the
walkers. When this is done, the pointers to the old and new sets
of coordinates are swapped, and the new coordinates are
overwritten. This can be done only when the data relative to
electrons have been set.
~size_max~ should be equal equal or geater than ~elec_num *
walker.num * 3~, to be symmetric with ~qmckl_get_electron_coord~.
Important: changing the electron coordinates increments the date
in the context.
#+begin_src c :comments org :tangle (eval c) :noweb yes :exports none
qmckl_exit_code
qmckl_set_electron_coord(qmckl_context context,
const char transp,
const int64_t walk_num,
const double* coord,
const int64_t size_max)
{
int32_t mask = 0; // coord can be changed
<<pre2>>
if (transp != 'N' && transp != 'T') {
return qmckl_failwith( context,
QMCKL_INVALID_ARG_2,
"qmckl_set_electron_coord",
"transp should be 'N' or 'T'");
}
if (walk_num <= 0) {
return qmckl_failwith( context,
QMCKL_INVALID_ARG_3,
"qmckl_set_electron_coord",
"walk_num <= 0");
}
if (coord == NULL) {
return qmckl_failwith( context,
QMCKL_INVALID_ARG_3,
"qmckl_set_electron_coord",
"coord is a null pointer");
}
const int64_t elec_num = ctx->electron.num;
if (elec_num == 0L) {
return qmckl_failwith( context,
QMCKL_FAILURE,
"qmckl_set_electron_coord",
"elec_num is not set");
}
/* Swap pointers */
qmckl_walker tmp = ctx->electron.walker_old;
ctx->electron.walker_old = ctx->electron.walker;
ctx->electron.walker = tmp;
memcpy(&(ctx->point), &(ctx->electron.walker.point), sizeof(qmckl_point_struct));
qmckl_exit_code rc;
rc = qmckl_set_point(context, transp, walk_num*elec_num, coord, size_max);
if (rc != QMCKL_SUCCESS) return rc;
ctx->electron.walker.num = walk_num;
memcpy(&(ctx->electron.walker.point), &(ctx->point), sizeof(qmckl_point_struct));
return QMCKL_SUCCESS;
}
#+end_src
#+begin_src f90 :comments org :tangle (eval fh_func) :noweb yes
interface
integer(c_int32_t) function qmckl_set_electron_coord(context, transp, walk_num, coord, size_max) bind(C)
use, intrinsic :: iso_c_binding
import
implicit none
integer (c_int64_t) , intent(in) , value :: context
character , intent(in) , value :: transp
integer (c_int64_t) , intent(in) , value :: walk_num
double precision , intent(in) :: coord(*)
integer (c_int64_t) , intent(in) , value :: size_max
end function
end interface
#+end_src
** Test ** Test
#+begin_src python :results output :exports none #+begin_src python :results output :exports none
@ -707,15 +743,16 @@ int64_t walk_num = chbrclf_walk_num;
int64_t elec_num = chbrclf_elec_num; int64_t elec_num = chbrclf_elec_num;
int64_t elec_up_num = chbrclf_elec_up_num; int64_t elec_up_num = chbrclf_elec_up_num;
int64_t elec_dn_num = chbrclf_elec_dn_num; int64_t elec_dn_num = chbrclf_elec_dn_num;
double rescale_factor_kappa_ee = 1.0;
double rescale_factor_kappa_en = 1.0;
double nucl_rescale_factor_kappa = 1.0;
double* elec_coord = &(chbrclf_elec_coord[0][0][0]);
int64_t nucl_num = chbrclf_nucl_num; int64_t nucl_num = chbrclf_nucl_num;
double* charge = chbrclf_charge; double* charge = chbrclf_charge;
double* nucl_coord = &(chbrclf_nucl_coord[0][0]); double* nucl_coord = &(chbrclf_nucl_coord[0][0]);
double rescale_factor_kappa_ee = 1.0;
double rescale_factor_kappa_en[nucl_num] = { 1.0, 1.0, 1.0, 1.0, 1.0} ;
double nucl_rescale_factor_kappa = 1.0;
double* elec_coord = &(chbrclf_elec_coord[0][0][0]);
/* --- */ /* --- */
qmckl_exit_code rc; qmckl_exit_code rc;
@ -750,16 +787,18 @@ assert(rc == QMCKL_SUCCESS);
assert(n == elec_num); assert(n == elec_num);
double k_ee = 0.; double k_ee = 0.;
double k_en = 0.; double k_en[nucl_num] = { 0., 0., 0., 0., 0.};
rc = qmckl_get_electron_rescale_factor_ee (context, &k_ee); rc = qmckl_get_electron_rescale_factor_ee (context, &k_ee);
assert(rc == QMCKL_SUCCESS); assert(rc == QMCKL_SUCCESS);
assert(k_ee == 1.0); assert(k_ee == 1.0);
rc = qmckl_get_electron_rescale_factor_en (context, &k_en); rc = qmckl_get_electron_rescale_factor_en (context, &(k_en[0]), nucl_num);
assert(rc == QMCKL_SUCCESS); assert(rc == QMCKL_SUCCESS);
assert(k_en == 1.0); for (int i=0 ; i<nucl_num ; ++i) {
assert(k_en[i] == rescale_factor_kappa_en[i]);
}
rc = qmckl_set_electron_rescale_factor_en(context, rescale_factor_kappa_en); rc = qmckl_set_electron_rescale_factor_en(context, rescale_factor_kappa_en, nucl_num);
assert(rc == QMCKL_SUCCESS); assert(rc == QMCKL_SUCCESS);
rc = qmckl_set_electron_rescale_factor_ee(context, rescale_factor_kappa_ee); rc = qmckl_set_electron_rescale_factor_ee(context, rescale_factor_kappa_ee);
@ -769,9 +808,11 @@ rc = qmckl_get_electron_rescale_factor_ee (context, &k_ee);
assert(rc == QMCKL_SUCCESS); assert(rc == QMCKL_SUCCESS);
assert(k_ee == rescale_factor_kappa_ee); assert(k_ee == rescale_factor_kappa_ee);
rc = qmckl_get_electron_rescale_factor_en (context, &k_en); rc = qmckl_get_electron_rescale_factor_en (context, &(k_en[0]), nucl_num);
assert(rc == QMCKL_SUCCESS); assert(rc == QMCKL_SUCCESS);
assert(k_en == rescale_factor_kappa_en); for (int i=0 ; i<nucl_num ; ++i) {
assert(k_en[i] == rescale_factor_kappa_en[i]);
}
int64_t w = 0; int64_t w = 0;
@ -1146,7 +1187,7 @@ qmckl_exit_code qmckl_provide_ee_distance_rescaled(qmckl_context context)
qmckl_exit_code rc = qmckl_exit_code rc =
qmckl_compute_ee_distance_rescaled(context, qmckl_compute_ee_distance_rescaled(context,
ctx->electron.num, ctx->electron.num,
ctx->electron.rescale_factor_kappa_en, ctx->electron.rescale_factor_kappa_ee,
ctx->electron.walker.num, ctx->electron.walker.num,
ctx->electron.walker.point.coord.data, ctx->electron.walker.point.coord.data,
ctx->electron.ee_distance_rescaled); ctx->electron.ee_distance_rescaled);
@ -1397,7 +1438,7 @@ qmckl_exit_code qmckl_provide_ee_distance_rescaled_deriv_e(qmckl_context context
qmckl_exit_code rc = qmckl_exit_code rc =
qmckl_compute_ee_distance_rescaled_deriv_e(context, qmckl_compute_ee_distance_rescaled_deriv_e(context,
ctx->electron.num, ctx->electron.num,
ctx->electron.rescale_factor_kappa_en, ctx->electron.rescale_factor_kappa_ee,
ctx->electron.walker.num, ctx->electron.walker.num,
ctx->electron.walker.point.coord.data, ctx->electron.walker.point.coord.data,
ctx->electron.ee_distance_rescaled_deriv_e); ctx->electron.ee_distance_rescaled_deriv_e);
@ -2158,7 +2199,7 @@ qmckl_exit_code qmckl_provide_en_distance_rescaled(qmckl_context context)
| ~context~ | ~qmckl_context~ | in | Global state | | ~context~ | ~qmckl_context~ | in | Global state |
| ~elec_num~ | ~int64_t~ | in | Number of electrons | | ~elec_num~ | ~int64_t~ | in | Number of electrons |
| ~nucl_num~ | ~int64_t~ | in | Number of nuclei | | ~nucl_num~ | ~int64_t~ | in | Number of nuclei |
| ~rescale_factor_kappa_en~ | ~double~ | in | The factor for rescaled distances | | ~rescale_factor_kappa_en~ | ~double[nucl_num]~ | in | The factor for rescaled distances |
| ~walk_num~ | ~int64_t~ | in | Number of walkers | | ~walk_num~ | ~int64_t~ | in | Number of walkers |
| ~elec_coord~ | ~double[3][walk_num][elec_num]~ | in | Electron coordinates | | ~elec_coord~ | ~double[3][walk_num][elec_num]~ | in | Electron coordinates |
| ~nucl_coord~ | ~double[3][elec_num]~ | in | Nuclear coordinates | | ~nucl_coord~ | ~double[3][elec_num]~ | in | Nuclear coordinates |
@ -2173,13 +2214,14 @@ integer function qmckl_compute_en_distance_rescaled_f(context, elec_num, nucl_nu
integer(qmckl_context), intent(in) :: context integer(qmckl_context), intent(in) :: context
integer*8 , intent(in) :: elec_num integer*8 , intent(in) :: elec_num
integer*8 , intent(in) :: nucl_num integer*8 , intent(in) :: nucl_num
double precision , intent(in) :: rescale_factor_kappa_en double precision , intent(in) :: rescale_factor_kappa_en(nucl_num)
integer*8 , intent(in) :: walk_num integer*8 , intent(in) :: walk_num
double precision , intent(in) :: elec_coord(elec_num,walk_num,3) double precision , intent(in) :: elec_coord(elec_num,walk_num,3)
double precision , intent(in) :: nucl_coord(nucl_num,3) double precision , intent(in) :: nucl_coord(nucl_num,3)
double precision , intent(out) :: en_distance_rescaled(elec_num,nucl_num,walk_num) double precision , intent(out) :: en_distance_rescaled(elec_num,nucl_num,walk_num)
integer*8 :: k integer*8 :: k
double precision :: coord(3)
info = QMCKL_SUCCESS info = QMCKL_SUCCESS
@ -2198,26 +2240,22 @@ integer function qmckl_compute_en_distance_rescaled_f(context, elec_num, nucl_nu
return return
endif endif
! TODO: comparison with 0
!if (rescale_factor_kappa_en <= 0) then
! info = QMCKL_INVALID_ARG_4
! return
!endif
if (walk_num <= 0) then if (walk_num <= 0) then
info = QMCKL_INVALID_ARG_5 info = QMCKL_INVALID_ARG_5
return return
endif endif
do i=1,nucl_num
coord(1:3) = nucl_coord(i,1:3)
do k=1,walk_num do k=1,walk_num
info = qmckl_distance_rescaled(context, 'T', 'T', elec_num, nucl_num, & info = qmckl_distance_rescaled(context, 'T', 'T', elec_num, 1, &
elec_coord(1,k,1), elec_num*walk_num, & elec_coord(1,k,1), elec_num*walk_num, coord, 1, &
nucl_coord, nucl_num, & en_distance_rescaled(1,i,k), elec_num, rescale_factor_kappa_en(i))
en_distance_rescaled(1,1,k), elec_num, rescale_factor_kappa_en)
if (info /= QMCKL_SUCCESS) then if (info /= QMCKL_SUCCESS) then
exit return
endif endif
end do end do
end do
end function qmckl_compute_en_distance_rescaled_f end function qmckl_compute_en_distance_rescaled_f
#+end_src #+end_src
@ -2227,7 +2265,7 @@ qmckl_exit_code qmckl_compute_en_distance_rescaled (
const qmckl_context context, const qmckl_context context,
const int64_t elec_num, const int64_t elec_num,
const int64_t nucl_num, const int64_t nucl_num,
const double rescale_factor_kappa_en, const double* rescale_factor_kappa_en,
const int64_t walk_num, const int64_t walk_num,
const double* elec_coord, const double* elec_coord,
const double* nucl_coord, const double* nucl_coord,
@ -2239,7 +2277,14 @@ qmckl_exit_code qmckl_compute_en_distance_rescaled (
#+RESULTS: #+RESULTS:
#+begin_src f90 :tangle (eval f) :comments org :exports none #+begin_src f90 :tangle (eval f) :comments org :exports none
integer(c_int32_t) function qmckl_compute_en_distance_rescaled & integer(c_int32_t) function qmckl_compute_en_distance_rescaled &
(context, elec_num, nucl_num, rescale_factor_kappa_en, walk_num, elec_coord, nucl_coord, en_distance_rescaled) & (context, &
elec_num, &
nucl_num, &
rescale_factor_kappa_en, &
walk_num, &
elec_coord, &
nucl_coord, &
en_distance_rescaled) &
bind(C) result(info) bind(C) result(info)
use, intrinsic :: iso_c_binding use, intrinsic :: iso_c_binding
@ -2248,7 +2293,7 @@ qmckl_exit_code qmckl_compute_en_distance_rescaled (
integer (c_int64_t) , intent(in) , value :: context integer (c_int64_t) , intent(in) , value :: context
integer (c_int64_t) , intent(in) , value :: elec_num integer (c_int64_t) , intent(in) , value :: elec_num
integer (c_int64_t) , intent(in) , value :: nucl_num integer (c_int64_t) , intent(in) , value :: nucl_num
real (c_double ) , intent(in) , value :: rescale_factor_kappa_en real (c_double ) , intent(in) :: rescale_factor_kappa_en(nucl_num)
integer (c_int64_t) , intent(in) , value :: walk_num integer (c_int64_t) , intent(in) , value :: walk_num
real (c_double ) , intent(in) :: elec_coord(elec_num,walk_num,3) real (c_double ) , intent(in) :: elec_coord(elec_num,walk_num,3)
real (c_double ) , intent(in) :: nucl_coord(elec_num,3) real (c_double ) , intent(in) :: nucl_coord(elec_num,3)
@ -2256,7 +2301,14 @@ qmckl_exit_code qmckl_compute_en_distance_rescaled (
integer(c_int32_t), external :: qmckl_compute_en_distance_rescaled_f integer(c_int32_t), external :: qmckl_compute_en_distance_rescaled_f
info = qmckl_compute_en_distance_rescaled_f & info = qmckl_compute_en_distance_rescaled_f &
(context, elec_num, nucl_num, rescale_factor_kappa_en, walk_num, elec_coord, nucl_coord, en_distance_rescaled) (context, &
elec_num, &
nucl_num, &
rescale_factor_kappa_en, &
walk_num, &
elec_coord, &
nucl_coord, &
en_distance_rescaled)
end function qmckl_compute_en_distance_rescaled end function qmckl_compute_en_distance_rescaled
#+end_src #+end_src
@ -2441,7 +2493,7 @@ qmckl_exit_code qmckl_provide_en_distance_rescaled_deriv_e(qmckl_context context
| ~context~ | ~qmckl_context~ | in | Global state | | ~context~ | ~qmckl_context~ | in | Global state |
| ~elec_num~ | ~int64_t~ | in | Number of electrons | | ~elec_num~ | ~int64_t~ | in | Number of electrons |
| ~nucl_num~ | ~int64_t~ | in | Number of nuclei | | ~nucl_num~ | ~int64_t~ | in | Number of nuclei |
| ~rescale_factor_kappa_en~ | ~double~ | in | The factor for rescaled distances | | ~rescale_factor_kappa_en~ | ~double[nucl_num]~ | in | The factors for rescaled distances |
| ~walk_num~ | ~int64_t~ | in | Number of walkers | | ~walk_num~ | ~int64_t~ | in | Number of walkers |
| ~elec_coord~ | ~double[3][walk_num][elec_num]~ | in | Electron coordinates | | ~elec_coord~ | ~double[3][walk_num][elec_num]~ | in | Electron coordinates |
| ~nucl_coord~ | ~double[3][elec_num]~ | in | Nuclear coordinates | | ~nucl_coord~ | ~double[3][elec_num]~ | in | Nuclear coordinates |
@ -2457,13 +2509,14 @@ integer function qmckl_compute_en_distance_rescaled_deriv_e_f(context, elec_num,
integer(qmckl_context), intent(in) :: context integer(qmckl_context), intent(in) :: context
integer*8 , intent(in) :: elec_num integer*8 , intent(in) :: elec_num
integer*8 , intent(in) :: nucl_num integer*8 , intent(in) :: nucl_num
double precision , intent(in) :: rescale_factor_kappa_en double precision , intent(in) :: rescale_factor_kappa_en(nucl_num)
integer*8 , intent(in) :: walk_num integer*8 , intent(in) :: walk_num
double precision , intent(in) :: elec_coord(elec_num,walk_num,3) double precision , intent(in) :: elec_coord(elec_num,walk_num,3)
double precision , intent(in) :: nucl_coord(nucl_num,3) double precision , intent(in) :: nucl_coord(nucl_num,3)
double precision , intent(out) :: en_distance_rescaled_deriv_e(4,elec_num,nucl_num,walk_num) double precision , intent(out) :: en_distance_rescaled_deriv_e(4,elec_num,nucl_num,walk_num)
integer*8 :: k integer*8 :: i, k
double precision :: coord(3)
info = QMCKL_SUCCESS info = QMCKL_SUCCESS
@ -2482,26 +2535,23 @@ integer function qmckl_compute_en_distance_rescaled_deriv_e_f(context, elec_num,
return return
endif endif
! TODO: comparison with 0
!if (rescale_factor_kappa_en <= 0) then
! info = QMCKL_INVALID_ARG_4
! return
!endif
if (walk_num <= 0) then if (walk_num <= 0) then
info = QMCKL_INVALID_ARG_5 info = QMCKL_INVALID_ARG_5
return return
endif endif
do i=1, nucl_num
coord(1:3) = nucl_coord(i,1:3)
do k=1,walk_num do k=1,walk_num
info = qmckl_distance_rescaled_deriv_e(context, 'T', 'T', elec_num, nucl_num, & info = qmckl_distance_rescaled_deriv_e(context, 'T', 'T', elec_num, 1, &
elec_coord(1,k,1), elec_num*walk_num, & elec_coord(1,k,1), elec_num*walk_num, &
nucl_coord, nucl_num, & coord, 1, &
en_distance_rescaled_deriv_e(1,1,1,k), elec_num, rescale_factor_kappa_en) en_distance_rescaled_deriv_e(1,1,i,k), elec_num, rescale_factor_kappa_en(i))
if (info /= QMCKL_SUCCESS) then if (info /= QMCKL_SUCCESS) then
exit return
endif endif
end do end do
end do
end function qmckl_compute_en_distance_rescaled_deriv_e_f end function qmckl_compute_en_distance_rescaled_deriv_e_f
#+end_src #+end_src
@ -2511,7 +2561,7 @@ qmckl_exit_code qmckl_compute_en_distance_rescaled_deriv_e (
const qmckl_context context, const qmckl_context context,
const int64_t elec_num, const int64_t elec_num,
const int64_t nucl_num, const int64_t nucl_num,
const double rescale_factor_kappa_en, const double* rescale_factor_kappa_en,
const int64_t walk_num, const int64_t walk_num,
const double* elec_coord, const double* elec_coord,
const double* nucl_coord, const double* nucl_coord,
@ -2523,7 +2573,14 @@ qmckl_exit_code qmckl_compute_en_distance_rescaled_deriv_e (
#+RESULTS: #+RESULTS:
#+begin_src f90 :tangle (eval f) :comments org :exports none #+begin_src f90 :tangle (eval f) :comments org :exports none
integer(c_int32_t) function qmckl_compute_en_distance_rescaled_deriv_e & integer(c_int32_t) function qmckl_compute_en_distance_rescaled_deriv_e &
(context, elec_num, nucl_num, rescale_factor_kappa_en, walk_num, elec_coord, nucl_coord, en_distance_rescaled_deriv_e) & (context, &
elec_num, &
nucl_num, &
rescale_factor_kappa_en, &
walk_num, &
elec_coord, &
nucl_coord, &
en_distance_rescaled_deriv_e) &
bind(C) result(info) bind(C) result(info)
use, intrinsic :: iso_c_binding use, intrinsic :: iso_c_binding
@ -2532,15 +2589,22 @@ qmckl_exit_code qmckl_compute_en_distance_rescaled_deriv_e (
integer (c_int64_t) , intent(in) , value :: context integer (c_int64_t) , intent(in) , value :: context
integer (c_int64_t) , intent(in) , value :: elec_num integer (c_int64_t) , intent(in) , value :: elec_num
integer (c_int64_t) , intent(in) , value :: nucl_num integer (c_int64_t) , intent(in) , value :: nucl_num
real (c_double ) , intent(in) , value :: rescale_factor_kappa_en real (c_double ) , intent(in) :: rescale_factor_kappa_en(nucl_num)
integer (c_int64_t) , intent(in) , value :: walk_num integer (c_int64_t) , intent(in) , value :: walk_num
real (c_double ) , intent(in) :: elec_coord(elec_num,walk_num,3) real (c_double ) , intent(in) :: elec_coord(elec_num,walk_num,3)
real (c_double ) , intent(in) :: nucl_coord(elec_num,3) real (c_double ) , intent(in) :: nucl_coord(elec_num,3)
real (c_double ) , intent(out) :: en_distance_rescaled_deriv_e(elec_num,nucl_num,walk_num) real (c_double ) , intent(out) :: en_distance_rescaled_deriv_e(4,elec_num,nucl_num,walk_num)
integer(c_int32_t), external :: qmckl_compute_en_distance_rescaled_deriv_e_f integer(c_int32_t), external :: qmckl_compute_en_distance_rescaled_deriv_e_f
info = qmckl_compute_en_distance_rescaled_deriv_e_f & info = qmckl_compute_en_distance_rescaled_deriv_e_f &
(context, elec_num, nucl_num, rescale_factor_kappa_en, walk_num, elec_coord, nucl_coord, en_distance_rescaled_deriv_e) (context, &
elec_num, &
nucl_num, &
rescale_factor_kappa_en, &
walk_num, &
elec_coord, &
nucl_coord, &
en_distance_rescaled_deriv_e)
end function qmckl_compute_en_distance_rescaled_deriv_e end function qmckl_compute_en_distance_rescaled_deriv_e
#+end_src #+end_src

View File

@ -12,15 +12,15 @@
J(\mathbf{r},\mathbf{R}) = J_{\text{eN}}(\mathbf{r},\mathbf{R}) + J_{\text{ee}}(\mathbf{r}) + J_{\text{eeN}}(\mathbf{r},\mathbf{R}) J(\mathbf{r},\mathbf{R}) = J_{\text{eN}}(\mathbf{r},\mathbf{R}) + J_{\text{ee}}(\mathbf{r}) + J_{\text{eeN}}(\mathbf{r},\mathbf{R})
\] \]
In the following, we us the notations $r_{ij} = |\mathbf{r}_i - \mathbf{r}_j|$ and In the following, we use the notations $r_{ij} = |\mathbf{r}_i - \mathbf{r}_j|$ and
$R_{i\alpha} = |\mathbf{r}_i - \mathbf{R}_\alpha|$. $R_{i\alpha} = |\mathbf{r}_i - \mathbf{R}_\alpha|$.
$J_{\text{eN}}$ contains electron-nucleus terms: $J_{\text{eN}}$ contains electron-nucleus terms:
\[ \[
J_{\text{eN}}(\mathbf{r},\mathbf{R}) = \sum_{i=1}^{N_\text{elec}} \sum_{\alpha=1}^{N_\text{nucl}} J_{\text{eN}}(\mathbf{r},\mathbf{R}) = \sum_{i=1}^{N_\text{elec}} \sum_{\alpha=1}^{N_\text{nucl}}
\frac{a_1\, f(R_{i\alpha})}{1+a_2\, f(R_{i\alpha})} + \frac{a_{1,\alpha}\, g_\alpha(R_{i\alpha})}{1+a_{2,\alpha}\, g_\alpha(R_{i\alpha})} +
\sum_{p=2}^{N_\text{ord}^a} a_{p+1}\, [f(R_{i\alpha})]^p - J_{eN}^\infty \sum_{p=2}^{N_\text{ord}^a} a_{p+1,\alpha}\, [g_\alpha(R_{i\alpha})]^p - J_{eN}^\infty
\] \]
$J_{\text{ee}}$ contains electron-electron terms: $J_{\text{ee}}$ contains electron-electron terms:
@ -41,9 +41,9 @@
\sum_{p=2}^{N_{\text{ord}}} \sum_{p=2}^{N_{\text{ord}}}
\sum_{k=0}^{p-1} \sum_{k=0}^{p-1}
\sum_{l=0}^{p-k-2\delta_{k,0}} \sum_{l=0}^{p-k-2\delta_{k,0}}
c_{lkp\alpha} \left[ g({r}_{ij}) \right]^k c_{lkp\alpha} \left[ f({r}_{ij}) \right]^k
\left[ \left[ g({R}_{i\alpha}) \right]^l + \left[ g({R}_{j\alpha}) \right]^l \right] \left[ \left[ g_\alpha({R}_{i\alpha}) \right]^l + \left[ g_\alpha({R}_{j\alpha}) \right]^l \right]
\left[ g({R}_{i\,\alpha}) \, g({R}_{j\alpha}) \right]^{(p-k-l)/2} \left[ g_\alpha({R}_{i\,\alpha}) \, g_\alpha({R}_{j\alpha}) \right]^{(p-k-l)/2}
\] \]
$c_{lkp\alpha}$ are non-zero only when $p-k-l$ is even. $c_{lkp\alpha}$ are non-zero only when $p-k-l$ is even.
@ -52,7 +52,7 @@
\[ \[
f(r) = \frac{1-e^{-\kappa\, r}}{\kappa} \text{ and } f(r) = \frac{1-e^{-\kappa\, r}}{\kappa} \text{ and }
g(r) = e^{-\kappa\, r}. g_\alpha(r) = e^{-\kappa_\alpha\, r}.
\] \]
The terms $J_{\text{ee}}^\infty$ and $J_{\text{eN}}^\infty$ are shifts to ensure that The terms $J_{\text{ee}}^\infty$ and $J_{\text{eN}}^\infty$ are shifts to ensure that
@ -161,7 +161,7 @@ int main() {
computed data: computed data:
| Variable | Type | In/Out | | Variable | Type | In/Out |
|----------------------------+-----------------------------------------------------------------+-------------------------------------------------| |-------------------------------+-------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------|
| ~dim_cord_vect~ | ~int64_t~ | Number of unique C coefficients | | ~dim_cord_vect~ | ~int64_t~ | Number of unique C coefficients |
| ~dim_cord_vect_date~ | ~uint64_t~ | Number of unique C coefficients | | ~dim_cord_vect_date~ | ~uint64_t~ | Number of unique C coefficients |
| ~asymp_jasb~ | ~double[2]~ | Asymptotic component | | ~asymp_jasb~ | ~double[2]~ | Asymptotic component |

View File

@ -138,13 +138,6 @@ qmckl_exit_code qmckl_init_nucleus(qmckl_context context) {
#+end_src #+end_src
** Access functions ** Access functions
#+NAME:post
#+begin_src c :exports none
if ( (ctx->nucleus.uninitialized & mask) != 0) {
return NULL;
}
#+end_src
#+begin_src c :comments org :tangle (eval h_func) :exports none #+begin_src c :comments org :tangle (eval h_func) :exports none
qmckl_exit_code qmckl_exit_code
@ -438,7 +431,7 @@ if (mask != 0 && !(ctx->nucleus.uninitialized & mask)) {
} }
#+end_src #+end_src
#+NAME:post2 #+NAME:post
#+begin_src c :exports none #+begin_src c :exports none
ctx->nucleus.uninitialized &= ~mask; ctx->nucleus.uninitialized &= ~mask;
ctx->nucleus.provided = (ctx->nucleus.uninitialized == 0); ctx->nucleus.provided = (ctx->nucleus.uninitialized == 0);
@ -475,7 +468,7 @@ qmckl_set_nucleus_num(qmckl_context context,
ctx->nucleus.num = num; ctx->nucleus.num = num;
<<post2>> <<post>>
} }
#+end_src #+end_src
@ -541,7 +534,7 @@ qmckl_set_nucleus_charge(qmckl_context context,
"Error in vector->double* conversion"); "Error in vector->double* conversion");
} }
<<post2>> <<post>>
} }
#+end_src #+end_src
@ -619,7 +612,7 @@ qmckl_set_nucleus_coord(qmckl_context context,
} }
if (rc != QMCKL_SUCCESS) return rc; if (rc != QMCKL_SUCCESS) return rc;
<<post2>> <<post>>
} }
#+end_src #+end_src