#include "macrodef.h" #include "share_func.h" #include /* * fderivs_shc — shell first derivatives converted to Cartesian via chain rule. * * Calls fderivs_sh internally, then: * fx = drhodx * df/drho + dsigmadx * df/dsigma + dRdx * df/dR * fy = drhody * df/drho + dsigmady * df/dsigma + dRdy * df/dR * fz = drhodz * df/drho + dsigmadz * df/dsigma + dRdz * df/dR */ // Forward declaration (defined in fderivs_sh_c.C with extern "C" name fderivs_sh_) extern "C" { void fderivs_sh_(const int ex[3], const double *f, double *fx, double *fy, double *fz, const double *X, const double *Y, const double *Z, double SYM1, double SYM2, double SYM3, int Symmetry, int onoff, int sst); void fderivs_shc_(int *ex, double *f, double *fx, double *fy, double *fz, double *crho, double *sigma, double *R, double &SYM1, double &SYM2, double &SYM3, int &Symmetry, int &Lev, int &sst, double *drhodx, double *drhody, double *drhodz, double *dsigmadx, double *dsigmady, double *dsigmadz, double *dRdx, double *dRdy, double *dRdz) { const int ex3[3] = { ex[0], ex[1], ex[2] }; const size_t n = (size_t)ex[0] * (size_t)ex[1] * (size_t)ex[2]; // Temporary shell-coordinate derivatives double *gx = (double*)malloc(n * sizeof(double)); double *gy = (double*)malloc(n * sizeof(double)); double *gz = (double*)malloc(n * sizeof(double)); if (!gx || !gy || !gz) { free(gx); free(gy); free(gz); return; } // Compute shell-coordinate derivatives fderivs_sh_(ex3, f, gx, gy, gz, crho, sigma, R, SYM1, SYM2, SYM3, Symmetry, Lev, sst); // Chain rule to Cartesian for (size_t i = 0; i < n; ++i) { fx[i] = drhodx[i] * gx[i] + dsigmadx[i] * gy[i] + dRdx[i] * gz[i]; fy[i] = drhody[i] * gx[i] + dsigmady[i] * gy[i] + dRdy[i] * gz[i]; fz[i] = drhodz[i] * gx[i] + dsigmadz[i] * gy[i] + dRdz[i] * gz[i]; } free(gx); free(gy); free(gz); } } // extern "C"