@@ -6452,6 +6452,11 @@ qmckl_exit_code
6452
6452
qmckl_get_forces_mo_g(qmckl_context context,
6453
6453
double* const forces_mo_g,
6454
6454
const int64_t size_max);
6455
+
6456
+ qmckl_exit_code
6457
+ qmckl_get_forces_mo_g_inplace(qmckl_context context,
6458
+ double* const forces_mo_g,
6459
+ const int64_t size_max);
6455
6460
#+end_src
6456
6461
6457
6462
#+begin_src c :comments org :tangle (eval c) :noweb yes :exports none
@@ -6462,7 +6467,10 @@ qmckl_get_forces_mo_g(qmckl_context context,
6462
6467
{
6463
6468
6464
6469
if (qmckl_context_check(context) == QMCKL_NULL_CONTEXT) {
6465
- return QMCKL_NULL_CONTEXT;
6470
+ return qmckl_failwith( context,
6471
+ QMCKL_INVALID_CONTEXT,
6472
+ "qmckl_get_forces_mo_g",
6473
+ NULL);
6466
6474
}
6467
6475
6468
6476
qmckl_exit_code rc;
@@ -6483,6 +6491,49 @@ qmckl_get_forces_mo_g(qmckl_context context,
6483
6491
6484
6492
memcpy(forces_mo_g, ctx->forces.forces_mo_g, sze * sizeof(double));
6485
6493
6494
+ return QMCKL_SUCCESS;
6495
+ }
6496
+ #+end_src
6497
+
6498
+ #+begin_src c :comments org :tangle (eval c) :noweb yes :exports none
6499
+ qmckl_exit_code
6500
+ qmckl_get_forces_mo_g_inplace (qmckl_context context,
6501
+ double* const forces_mo_g,
6502
+ const int64_t size_max)
6503
+ {
6504
+
6505
+ if (qmckl_context_check(context) == QMCKL_NULL_CONTEXT) {
6506
+ return qmckl_failwith( context,
6507
+ QMCKL_INVALID_CONTEXT,
6508
+ "qmckl_get_forces_mo_g",
6509
+ NULL);
6510
+ }
6511
+
6512
+ qmckl_exit_code rc;
6513
+
6514
+ qmckl_context_struct* const ctx = (qmckl_context_struct*) context;
6515
+ assert (ctx != NULL);
6516
+
6517
+ const int64_t sze = ctx->point.num * 3 * 3 * ctx->mo_basis.mo_num * ctx->nucleus.num;
6518
+ if (size_max < sze) {
6519
+ return qmckl_failwith( context,
6520
+ QMCKL_INVALID_ARG_3,
6521
+ "qmckl_get_forces_mo_g",
6522
+ "input array too small");
6523
+ }
6524
+
6525
+ rc = qmckl_context_touch(context);
6526
+ if (rc != QMCKL_SUCCESS) return rc;
6527
+
6528
+ double* old_array = ctx->forces.forces_mo_g;
6529
+
6530
+ ctx->forces.forces_mo_g = forces_mo_g;
6531
+
6532
+ rc = qmckl_provide_forces_mo_g(context);
6533
+ if (rc != QMCKL_SUCCESS) return rc;
6534
+
6535
+ ctx->forces.forces_mo_g = old_array;
6536
+
6486
6537
return QMCKL_SUCCESS;
6487
6538
}
6488
6539
#+end_src
@@ -6500,6 +6551,19 @@ qmckl_get_forces_mo_g(qmckl_context context,
6500
6551
integer (c_int64_t) , intent(in) , value :: size_max
6501
6552
end function qmckl_get_forces_mo_g
6502
6553
end interface
6554
+
6555
+ interface
6556
+ integer(qmckl_exit_code) function qmckl_get_forces_mo_g_inplace (context, &
6557
+ forces_mo_g, size_max) bind(C)
6558
+ use, intrinsic :: iso_c_binding
6559
+ import
6560
+ implicit none
6561
+
6562
+ integer (c_int64_t) , intent(in) , value :: context
6563
+ real(c_double), intent(out) :: forces_mo_g(*)
6564
+ integer (c_int64_t) , intent(in) , value :: size_max
6565
+ end function qmckl_get_forces_mo_g_inplace
6566
+ end interface
6503
6567
#+end_src
6504
6568
6505
6569
*** Provide :noexport:
@@ -6527,7 +6591,7 @@ qmckl_exit_code qmckl_provide_forces_mo_g(qmckl_context context)
6527
6591
if (!ctx->mo_basis.provided) {
6528
6592
return qmckl_failwith( context,
6529
6593
QMCKL_NOT_PROVIDED,
6530
- "qmckl_provide_mo_basis_mo_vgl ",
6594
+ "qmckl_provide_forces_mo_g ",
6531
6595
NULL);
6532
6596
}
6533
6597
@@ -6573,18 +6637,18 @@ qmckl_exit_code qmckl_provide_forces_mo_g(qmckl_context context)
6573
6637
NULL);
6574
6638
}
6575
6639
6576
- rc = qmckl_compute_forces_mo_g_doc (context,
6577
- ctx->ao_basis.ao_num,
6578
- ctx->mo_basis.mo_num,
6579
- ctx->point.num,
6580
- ctx->nucleus.num,
6581
- ctx->ao_basis.shell_num,
6582
- ctx->ao_basis.nucleus_index,
6583
- ctx->ao_basis.nucleus_shell_num,
6584
- ctx->ao_basis.shell_ang_mom,
6585
- ctx->mo_basis.coefficient_t,
6586
- ctx->ao_basis.ao_hessian,
6587
- ctx->forces.forces_mo_g);
6640
+ rc = qmckl_compute_forces_mo_g (context,
6641
+ ctx->ao_basis.ao_num,
6642
+ ctx->mo_basis.mo_num,
6643
+ ctx->point.num,
6644
+ ctx->nucleus.num,
6645
+ ctx->ao_basis.shell_num,
6646
+ ctx->ao_basis.nucleus_index,
6647
+ ctx->ao_basis.nucleus_shell_num,
6648
+ ctx->ao_basis.shell_ang_mom,
6649
+ ctx->mo_basis.coefficient_t,
6650
+ ctx->ao_basis.ao_hessian,
6651
+ ctx->forces.forces_mo_g);
6588
6652
6589
6653
if (rc != QMCKL_SUCCESS) {
6590
6654
return rc;
@@ -6641,6 +6705,34 @@ integer function qmckl_compute_forces_mo_g_doc(context, &
6641
6705
integer*8 :: i,j, m, n,a
6642
6706
double precision :: c1
6643
6707
6708
+
6709
+ info = qmckl_dgemm(context,'N', 'N', mo_num, 3*point_num*3*nucl_num, ao_num, &
6710
+ -1.d0, coefficient_t, mo_num, &
6711
+ ao_hessian(1:ao_num, 1:3, 1:point_num, 1:3, 1:nucl_num), ao_num, &
6712
+ 0.d0, forces_mo_g(1:mo_num, 1:3, 1:point_num, 1:3, 1:nucl_num), mo_num)
6713
+
6714
+ end function qmckl_compute_forces_mo_g_doc
6715
+ #+end_src
6716
+
6717
+ #+begin_src f90 :comments org :tangle (eval f) :noweb yes
6718
+ integer function qmckl_compute_forces_mo_g_hpc(context, &
6719
+ ao_num, mo_num, point_num, nucl_num, &
6720
+ shell_num, nucleus_index, nucleus_shell_num, shell_ang_mom, &
6721
+ coefficient_t, ao_hessian, forces_mo_g) &
6722
+ bind(C) result(info)
6723
+ use qmckl
6724
+ implicit none
6725
+ integer(qmckl_context), intent(in), value :: context
6726
+ integer (c_int64_t) , intent(in), value :: nucl_num, ao_num, mo_num, point_num, shell_num
6727
+ integer (c_int64_t) , intent(in) :: nucleus_index(nucl_num)
6728
+ integer (c_int64_t) , intent(in) :: nucleus_shell_num(nucl_num)
6729
+ integer (c_int32_t) , intent(in) :: shell_ang_mom(shell_num)
6730
+ real (c_double ) , intent(in) :: coefficient_t(mo_num,ao_num)
6731
+ real (c_double ) , intent(in) :: ao_hessian(ao_num,4,point_num,3,nucl_num)
6732
+ real (c_double ) , intent(out) :: forces_mo_g(mo_num,3,point_num,3,nucl_num)
6733
+ integer*8 :: i,j, m, n,a
6734
+ double precision :: c1
6735
+
6644
6736
integer :: l, il, k
6645
6737
integer*8 :: ishell_start, ishell_end, ishell
6646
6738
integer :: lstart(0:20)
@@ -6673,18 +6765,14 @@ integer function qmckl_compute_forces_mo_g_doc(context, &
6673
6765
do j=1,point_num
6674
6766
do m = 1, 3
6675
6767
do ishell = ishell_start, ishell_end
6676
- k = ao_index(ishell)
6677
6768
l = shell_ang_mom(ishell)
6678
- do il = lstart(l), lstart(l+1)-1
6769
+ il = lstart(l+1)-lstart(l)
6770
+ do k = ao_index(ishell), ao_index(ishell) + il - 1
6679
6771
c1 = ao_hessian(k, m, j, n, a)
6680
- if (c1 == 0.d0) then
6681
- k = k + 1
6682
- cycle
6683
- end if
6772
+ if (c1 == 0.d0) cycle
6684
6773
do i=1,mo_num
6685
6774
forces_mo_g(i, m, j, n, a) = forces_mo_g(i, m, j, n, a) - coefficient_t(i,k) * c1
6686
6775
end do
6687
- k = k+1
6688
6776
end do
6689
6777
end do
6690
6778
end do
@@ -6695,26 +6783,39 @@ integer function qmckl_compute_forces_mo_g_doc(context, &
6695
6783
deallocate(ao_index)
6696
6784
6697
6785
6698
-
6699
-
6700
- !do a=1,nucl_num
6701
- ! do n = 1,3
6702
- ! do m = 1, 3
6703
- ! info = qmckl_dgemm(context,'N', 'N', mo_num, point_num, ao_num, &
6704
- ! -1.d0, coefficient_t, mo_num, &
6705
- ! ao_hessian(:, m, :, n, a), ao_num, &
6706
- ! 1.d0, forces_mo_g(:, m, :, n, a), mo_num)
6707
- ! end do
6708
- ! end do
6709
- !end do
6710
-
6711
-
6712
- end function qmckl_compute_forces_mo_g_doc
6786
+ end function qmckl_compute_forces_mo_g_hpc
6713
6787
#+end_src
6714
6788
6715
- #+RESULTS:
6716
6789
#+begin_src c :tangle (eval h_func) :comments org
6717
- qmckl_exit_code qmckl_compute_forces_mo_g_doc (
6790
+ qmckl_exit_code qmckl_compute_forces_mo_g (
6791
+ const qmckl_context context,
6792
+ const int64_t ao_num,
6793
+ const int64_t mo_num,
6794
+ const int64_t point_num,
6795
+ const int64_t nucl_num,
6796
+ const int64_t shell_num,
6797
+ const int64_t* nucleus_index,
6798
+ const int64_t* nucleus_shell_num,
6799
+ const int32_t* shell_ang_mom,
6800
+ const double* coefficient_t,
6801
+ const double* ao_hessian,
6802
+ double* const forces_mo_g );
6803
+
6804
+ qmckl_exit_code qmckl_compute_forces_mo_g_doc (
6805
+ const qmckl_context context,
6806
+ const int64_t ao_num,
6807
+ const int64_t mo_num,
6808
+ const int64_t point_num,
6809
+ const int64_t nucl_num,
6810
+ const int64_t shell_num,
6811
+ const int64_t* nucleus_index,
6812
+ const int64_t* nucleus_shell_num,
6813
+ const int32_t* shell_ang_mom,
6814
+ const double* coefficient_t,
6815
+ const double* ao_hessian,
6816
+ double* const forces_mo_g );
6817
+
6818
+ qmckl_exit_code qmckl_compute_forces_mo_g_hpc (
6718
6819
const qmckl_context context,
6719
6820
const int64_t ao_num,
6720
6821
const int64_t mo_num,
@@ -6728,6 +6829,31 @@ end function qmckl_compute_forces_mo_g_doc
6728
6829
const double* ao_hessian,
6729
6830
double* const forces_mo_g );
6730
6831
#+end_src
6832
+
6833
+ #+begin_src c :tangle (eval c) :comments org :exports none
6834
+ qmckl_exit_code qmckl_compute_forces_mo_g (
6835
+ const qmckl_context context,
6836
+ const int64_t ao_num,
6837
+ const int64_t mo_num,
6838
+ const int64_t point_num,
6839
+ const int64_t nucl_num,
6840
+ const int64_t shell_num,
6841
+ const int64_t* nucleus_index,
6842
+ const int64_t* nucleus_shell_num,
6843
+ const int32_t* shell_ang_mom,
6844
+ const double* coefficient_t,
6845
+ const double* ao_hessian,
6846
+ double* const forces_mo_g )
6847
+ {
6848
+ #ifdef HAVE_HPC
6849
+ return qmckl_compute_forces_mo_g_hpc
6850
+ #else
6851
+ return qmckl_compute_forces_mo_g_doc
6852
+ #endif
6853
+ (context, ao_num, mo_num, point_num, nucl_num, shell_num, nucleus_index,
6854
+ nucleus_shell_num, shell_ang_mom, coefficient_t, ao_hessian, forces_mo_g );
6855
+ }
6856
+ #+end_src
6731
6857
6732
6858
*** Test :noexport:
6733
6859
@@ -6795,7 +6921,8 @@ for (int64_t a = 0; a < nucl_num; a++) {
6795
6921
if (m == -4) {
6796
6922
finite_difference_force_mo_g[k*3*mo_num*point_num*nucl_num + a*3*mo_num*point_num + i*3*mo_num + n*mo_num + j] = 0.0;
6797
6923
}
6798
- finite_difference_force_mo_g[k*3*mo_num*point_num*nucl_num + a*3*mo_num*point_num + i*3*mo_num + n*mo_num + j] += coef[m + 4] * mo_output[i*mo_num*5 + (n+1)*mo_num + j]/delta_x;
6924
+ finite_difference_force_mo_g[k*3*mo_num*point_num*nucl_num + a*3*mo_num*point_num + i*3*mo_num + n*mo_num + j] +=
6925
+ coef[m + 4] * mo_output[i*mo_num*5 + (n+1)*mo_num + j]/delta_x;
6799
6926
}
6800
6927
}
6801
6928
}
@@ -6817,15 +6944,19 @@ free(mo_output);
6817
6944
6818
6945
6819
6946
6820
- for (int j = 0; j < mo_num; j ++){
6947
+ for (int a = 0; a < nucl_num; a ++) {
6821
6948
for (int n = 0; n < 3; n++){
6822
- for (int i = 0; i < point_num; i++){
6823
- for (int a = 0; a < nucl_num; a++) {
6824
- for (int k = 0; k < 3; k++){
6825
- //printf("k=%i a=%i i=%i n=%i j=%i\n", k, a, i, n, j);
6826
- //printf("%.10f\t", finite_difference_force_mo_g[k*3*mo_num*point_num*nucl_num + a*3*mo_num*point_num + i*3*mo_num + n*mo_num + j]);
6827
- //printf("%.10f\n", forces_mo_g[a*9*mo_num*point_num + k*3*mo_num*point_num + i*3*mo_num + n*mo_num + j]);
6828
- assert(fabs(finite_difference_force_mo_g[k*3*mo_num*point_num*nucl_num + a*3*mo_num*point_num + i*3*mo_num + n*mo_num + j] - forces_mo_g[a*9*mo_num*point_num + k*3*mo_num*point_num + i*3*mo_num + n*mo_num + j]) < 1.e-9);
6949
+ for (int j = 0; j < point_num; j++){
6950
+ for (int m = 0; m < 3; m++){
6951
+ for (int i = 0; i < mo_num; i++){
6952
+ printf("a=%i n=%i j=%i m=%i i=%i\n", a, n, j, m, i);
6953
+ printf("%.10f\t", finite_difference_force_mo_g[n*3*mo_num*point_num*nucl_num + a*3*mo_num*point_num + j*3*mo_num + m*mo_num + i]);
6954
+ printf("%.10f\n", forces_mo_g[a*9*mo_num*point_num + n*3*mo_num*point_num + j*3*mo_num + m*mo_num + i]);
6955
+ assert(fabs(finite_difference_force_mo_g[n*3*mo_num*point_num*nucl_num +
6956
+ a*3*mo_num*point_num + j*3*mo_num +
6957
+ m*mo_num + i] -
6958
+ forces_mo_g[a*9*mo_num*point_num + n*3*mo_num*point_num +
6959
+ j*3*mo_num + m*mo_num + i]) < 1.e-9);
6829
6960
}
6830
6961
}
6831
6962
}
0 commit comments