1
0
mirror of https://github.com/TREX-CoE/qmckl.git synced 2024-07-02 01:16:18 +02:00
qmckl/org/qmckl_point.org

17 KiB

Point

This data structure contains cartesian coordinates where the functions will be evaluated. For DFT codes these may be the integration grid points. For QMC codes, these are the electron coordinates of all the walkers.

Context

The following data stored in the context:

Variable Type Description
num int64_t Total number of points
coord_x double[num] X coordinates
coord_y double[num] Y coordinates
coord_z double[num] Z coordinates

We consider that 'transposed' and 'normal' storage follows the convention:

Normal Transposed
C [point_num][3] [3][point_num]
Fortran (3,point_num) (point_num,3)

Data structure

typedef struct qmckl_point_struct {
double*   coord_x;
double*   coord_y;
double*   coord_z;
int64_t   num;
} qmckl_point_struct;
qmckl_exit_code qmckl_init_point(qmckl_context context);
qmckl_exit_code qmckl_init_point(qmckl_context context) {

if (qmckl_context_check(context) == QMCKL_NULL_CONTEXT) {
 return false;
}

qmckl_context_struct* const ctx = (qmckl_context_struct* const) context;
assert (ctx != NULL);

qmckl_memory_info_struct mem_info = qmckl_memory_info_struct_zero;
mem_info.size = sizeof(qmckl_point_struct);
ctx->point = (qmckl_point_struct*) qmckl_malloc(context, mem_info);
if (ctx->point == NULL) {
 return qmckl_failwith( context,
                        QMCKL_ALLOCATION_FAILED,
                        "qmckl_init_point",
                        NULL);
}
memset(ctx->point, 0, sizeof(qmckl_point_struct)); 

return QMCKL_SUCCESS;
}

Access functions

Access functions return QMCKL_SUCCESS when the data has been successfully retrieved. They return QMCKL_INVALID_CONTEXT when the context is not a valid context. If the function returns successfully, the variable pointed by the pointer given in argument contains the requested data. Otherwise, this variable is untouched.

Number of points

Returns the number of points stored in the context.

interface
integer(c_int32_t) function qmckl_get_point_num(context, num) bind(C)
 use, intrinsic :: iso_c_binding
 import
 implicit none

 integer (c_int64_t) , intent(in)  , value :: context                                  
 integer (c_int64_t) , intent(out)         :: num 
end function
end interface

Point coordinates

Returns the point coordinates as sequences of (x,y,z). The pointer is assumed to point on a memory block of size size_max3 * point_num.

interface
integer(c_int32_t) function qmckl_get_point(context, coord, size_max) bind(C)
  use, intrinsic :: iso_c_binding
  import
  implicit none

  integer (c_int64_t) , intent(in)  , value :: context
  real    (c_double ) , intent(out)         :: coord(*)
  integer (c_int64_t) , intent(in)          :: size_max
end function
end interface

Returns the point coordinates in three different arrays, one for each component x,y,z. The pointers are assumed to point on a memory block of size size_maxpoint_num.

interface
integer(c_int32_t) function qmckl_get_point_xyz(context, &
     coord_x, coord_y, coord_z, size_max) bind(C)
  use, intrinsic :: iso_c_binding
  import
  implicit none

  integer (c_int64_t) , intent(in)  , value :: context
  real    (c_double ) , intent(out)         :: coord_x(*)
  real    (c_double ) , intent(out)         :: coord_y(*)
  real    (c_double ) , intent(out)         :: coord_z(*)
  integer (c_int64_t) , intent(in)          :: size_max
end function
end interface

Initialization functions

When the data is set in the context, if the arrays are large enough, we overwrite the data contained in them.

To set the data relative to the points in the context, one of the following functions need to be called.

qmckl_exit_code qmckl_set_point (qmckl_context context,
                              const double* coord,
                              const int64_t num);

Copy a sequence of (x,y,z) into the context.

qmckl_exit_code
qmckl_set_point (qmckl_context context,
              const double* coord,
              const int64_t num)
{

<<check_alloc>>

for (int64_t i=0 ; i<num ; ++i) {
 ctx->point->coord_x[i] = coord[3*i  ];
 ctx->point->coord_y[i] = coord[3*i+1];
 ctx->point->coord_z[i] = coord[3*i+2];
}

return QMCKL_SUCCESS;

}
interface
integer(c_int32_t) function qmckl_set_point(context, &
    coord_x, coord_y, coord_z, size_max) bind(C)
 use, intrinsic :: iso_c_binding
 import
 implicit none

 integer (c_int64_t) , intent(in)  , value :: context
 real    (c_double ) , intent(in)          :: coord_x(*)
 real    (c_double ) , intent(in)          :: coord_y(*)
 real    (c_double ) , intent(in)          :: coord_z(*)
 integer (c_int64_t) , intent(in)  , value :: size_max
end function
end interface
qmckl_exit_code qmckl_set_point_xyz (qmckl_context context,
                              const double* coord_x,
                              const double* coord_y,
                              const double* coord_z,
                              const int64_t num);
qmckl_exit_code
qmckl_set_point_xyz (qmckl_context context,
                  const double* coord_x,
                  const double* coord_y,
                  const double* coord_z,
                  const int64_t num)
{

<<check_alloc>>

memcpy(ctx->point->coord_x, coord_x, num*sizeof(double));
memcpy(ctx->point->coord_y, coord_y, num*sizeof(double));
memcpy(ctx->point->coord_z, coord_z, num*sizeof(double));

return QMCKL_SUCCESS;
}
interface
integer(c_int32_t) function qmckl_set_point_xyz(context, &
    coord_x, coord_y, coord_z, size_max) bind(C)
 use, intrinsic :: iso_c_binding
 import
 implicit none

 integer (c_int64_t) , intent(in)  , value :: context
 real    (c_double ) , intent(in)          :: coord_x(*)
 real    (c_double ) , intent(in)          :: coord_y(*)
 real    (c_double ) , intent(in)          :: coord_z(*)
 integer (c_int64_t) , intent(in)  , value :: size_max
end function
end interface

Test

/* Reference input data */
int64_t point_num = chbrclf_elec_num;
double* coord     = &(chbrclf_elec_coord[0][0][0]);

/* --- */

qmckl_exit_code rc;

rc = qmckl_set_point (context, coord, point_num);
assert(rc == QMCKL_SUCCESS);

int64_t n;
rc = qmckl_get_point_num (context, &n);
assert(rc == QMCKL_SUCCESS);
assert(n == point_num);

double coord2[point_num*3];
double coord_x[point_num];
double coord_y[point_num];
double coord_z[point_num];

rc = qmckl_get_point_xyz (context, coord_x, coord_y, coord_z, point_num);
assert(rc == QMCKL_SUCCESS);

rc = qmckl_get_point (context, coord2, (point_num*3));
assert(rc == QMCKL_SUCCESS);

for (int64_t i=0 ; i<3*point_num ; ++i) {
assert( coord[i] == coord2[i] );
}

for (int64_t i=0 ; i<point_num ; ++i) {
assert( coord[3*i+0] == coord_x[i] );
assert( coord[3*i+1] == coord_y[i] );
assert( coord[3*i+2] == coord_z[i] );
}