Skip to content

Commit

Permalink
Merge pull request #184 from atillack/analytic_rotation_correction
Browse files Browse the repository at this point in the history
Analytical rotation coefficient gradient correction
  • Loading branch information
atillack authored Mar 23, 2022
2 parents 2c4f17d + 8bd9bd6 commit f8a0085
Show file tree
Hide file tree
Showing 10 changed files with 129 additions and 583 deletions.
5 changes: 3 additions & 2 deletions common/calcenergy_basic.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
#else
#define PI_FLOAT 3.14159265359f
#endif
#define PI_TIMES_2 2.0f*PI_FLOAT
#define PI_TIMES_2 (2.0f*PI_FLOAT)
#define PI_HALF (0.5f*PI_FLOAT)

// -------------------------------------------
// Gradient-related defines
Expand All @@ -77,7 +78,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
#define INV_INFINITESIMAL_RADIAN (1.0f/INFINITESIMAL_RADIAN)
#define COS_HALF_INFINITESIMAL_RADIAN cos(HALF_INFINITESIMAL_RADIAN)
#define SIN_HALF_INFINITESIMAL_RADIAN sin(HALF_INFINITESIMAL_RADIAN)
#define inv_angle_delta 500.0f / PI_FLOAT
#define inv_angle_delta (500.0f / PI_FLOAT)

/*
#define TRANGENE_ALPHA 1E-3
Expand Down
3 changes: 0 additions & 3 deletions cuda/GpuData.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,9 +129,6 @@ struct GpuData {
int* pMem_rotbonds_const;
int* pMem_rotbonds_atoms_const;
int* pMem_num_rotating_atoms_per_rotbond_const;
float* pMem_angle_const;
float* pMem_dependence_on_theta_const;
float* pMem_dependence_on_rotangle_const;

// CUDA-specific constants
unsigned int warpmask;
Expand Down
133 changes: 23 additions & 110 deletions cuda/calcMergeEneGra.cu
Original file line number Diff line number Diff line change
Expand Up @@ -103,19 +103,20 @@ __device__ void gpu_calc_energrad(
float genrotangle = genotype[5] * DEG_TO_RAD;

float4 genrot_unitvec;
float is_theta_gt_pi;
float is_theta_gt_pi, sin_half_rotangle, sin_theta;
if(cData.dockpars.true_ligand_atoms){
genrot_movingvec.x = genotype[0];
genrot_movingvec.y = genotype[1];
genrot_movingvec.z = genotype[2];
genrot_movingvec.w = 0.0f;
float sin_angle = sin(theta);
float s2 = sin(genrotangle*0.5f);
genrot_unitvec.x = s2*sin_angle*cos(phi);
genrot_unitvec.y = s2*sin_angle*sin(phi);
genrot_unitvec.z = s2*cos(theta);
sin_theta = sin(theta);
float cos_theta = cos(theta);
sin_half_rotangle = sin(genrotangle*0.5f);
genrot_unitvec.x = sin_half_rotangle*sin_theta*cos(phi);
genrot_unitvec.y = sin_half_rotangle*sin_theta*sin(phi);
genrot_unitvec.z = sin_half_rotangle*cos_theta;
genrot_unitvec.w = cos(genrotangle*0.5f);
is_theta_gt_pi = 1.0f-2.0f*(float)(sin_angle < 0.0f);
is_theta_gt_pi = 1.0f-2.0f*(float)(sin_theta < 0.0f);
}

uint32_t g1 = cData.dockpars.gridsize_x;
Expand Down Expand Up @@ -548,8 +549,6 @@ __device__ void gpu_calc_energrad(
float lower = atomic_distance * (DIEL_A * exp_el_DIEL_K + DIEL_B * exp_el);
lower *= lower;*/

// priv_gradient_per_intracontributor += -dockpars_coeff_elec * q1 * q2 * native_divide (upper, lower) -
// 0.0771605f * atomic_distance * desolv_energy;
priv_gradient_per_intracontributor += -(es_energy / atomic_distance) * diel
#ifndef DIEL_FIT_ABC
-es_energy * 2.21718f / (dist2*dist_shift)
Expand Down Expand Up @@ -708,25 +707,22 @@ __device__ void gpu_calc_energrad(
// Derived from rotation.py/axisangle_to_q()
// genes[3:7] = rotation.axisangle_to_q(torque, rad)
float torque_length = norm3df(torque_rot.x, torque_rot.y, torque_rot.z);
torque_length += (torque_length<1e-20f)*1e-20f;

float orientation_scaling = orientation_scaling = (torque_length<INFINITESIMAL_RADIAN) ? 1.0f : torque_length * INV_INFINITESIMAL_RADIAN;

float torque_scale = (torque_length<INFINITESIMAL_RADIAN) ? 0.5f - torque_length*torque_length/48.0f : SIN_HALF_INFINITESIMAL_RADIAN/torque_length;

#if defined (PRINT_GRAD_ROTATION_GENES)
printf("\n%s\n", "----------------------------------------------------------");
printf("%-20s %-10.6f\n", "torque length: ", torque_length);
#endif

/*
// Infinitesimal rotation in radians
const float infinitesimal_radian = 1E-5;
*/

// Finding the quaternion that performs
// the infinitesimal rotation around torque axis
float4 quat_torque;
quat_torque.x = torque_rot.x * SIN_HALF_INFINITESIMAL_RADIAN / torque_length;
quat_torque.y = torque_rot.y * SIN_HALF_INFINITESIMAL_RADIAN / torque_length;
quat_torque.z = torque_rot.z * SIN_HALF_INFINITESIMAL_RADIAN / torque_length;
quat_torque.w = COS_HALF_INFINITESIMAL_RADIAN;
quat_torque.x = torque_rot.x * torque_scale;
quat_torque.y = torque_rot.y * torque_scale;
quat_torque.z = torque_rot.z * torque_scale;
quat_torque.w = (torque_length<INFINITESIMAL_RADIAN) ? 1.0f-torque_length*torque_length*0.125f : COS_HALF_INFINITESIMAL_RADIAN;

#if defined (PRINT_GRAD_ROTATION_GENES)
printf("\n%s\n", "----------------------------------------------------------");
Expand Down Expand Up @@ -777,15 +773,7 @@ __device__ void gpu_calc_energrad(
// in shoemake space. This is to guarantee that the direction of
// the displacement in shoemake space is not distorted.
// The correct amount of displacement in shoemake space is obtained
// by multiplying the infinitesimal displacement by shoemake_scaling:
//float shoemake_scaling = native_divide(torque_length, INFINITESIMAL_RADIAN/*infinitesimal_radian*/);
float orientation_scaling = torque_length * INV_INFINITESIMAL_RADIAN;

#if defined (PRINT_GRAD_ROTATION_GENES)
printf("\n%s\n", "----------------------------------------------------------");
printf("%-30s %-10.6f\n", "orientation_scaling: ", orientation_scaling);
#endif

// by multiplying the infinitesimal displacement by shoemake_scaling
// Derivates in cube3
float grad_phi, grad_theta, grad_rotangle;
grad_phi = orientation_scaling * (fmod_pi2(target_phi - current_phi + PI_FLOAT) - PI_FLOAT);
Expand All @@ -799,88 +787,13 @@ __device__ void gpu_calc_energrad(
printf("%-13.6f %-13.6f %-13.6f\n", grad_phi, grad_theta, grad_rotangle);
#endif

// Correcting theta gradients interpolating
// values from correction look-up-tables
// (X0,Y0) and (X1,Y1) are known points
// How to find the Y value in the straight line between Y0 and Y1,
// corresponding to a certain X?
/*
| dependence_on_theta_const
| dependence_on_rotangle_const
|
|
| Y1
|
| Y=?
| Y0
|_________________________________ angle_const
X0 X X1
*/

// Finding the index-position of "grad_delta" in the "angle_const" array
//uint index_theta = floor(native_divide(current_theta - angle_const[0], angle_delta));
//uint index_rotangle = floor(native_divide(current_rotangle - angle_const[0], angle_delta));
uint index_theta = floor((current_theta - cData.pMem_angle_const[0]) * inv_angle_delta);
uint index_rotangle = floor((current_rotangle - cData.pMem_angle_const[0]) * inv_angle_delta);

// Interpolating theta values
// X0 -> index - 1
// X1 -> index + 1
// Expresed as weighted average:
// Y = [Y0 * ((X1 - X) / (X1-X0))] + [Y1 * ((X - X0) / (X1-X0))]
// Simplified for GPU (less terms):
// Y = [Y0 * (X1 - X) + Y1 * (X - X0)] / (X1 - X0)
// Taking advantage of constant:
// Y = [Y0 * (X1 - X) + Y1 * (X - X0)] * inv_angle_delta

float X0, Y0;
float X1, Y1;
float dependence_on_theta; //Y = dependence_on_theta

// Using interpolation on out-of-bounds elements results in hang
if ((index_theta <= 0) || (index_theta >= 999))
{
dependence_on_theta = cData.pMem_dependence_on_theta_const[stick_to_bounds(index_theta,0,999)];
} else
{
X0 = cData.pMem_angle_const[index_theta];
X1 = cData.pMem_angle_const[index_theta+1];
Y0 = cData.pMem_dependence_on_theta_const[index_theta];
Y1 = cData.pMem_dependence_on_theta_const[index_theta+1];
dependence_on_theta = (Y0 * (X1-current_theta) + Y1 * (current_theta-X0)) * inv_angle_delta;
}
float rot_angle_corr = 4.0f * sin_half_rotangle * sin_half_rotangle; // 4*sin(rotangle/2)^2

#if defined (PRINT_GRAD_ROTATION_GENES)
printf("\n%s\n", "----------------------------------------------------------");
printf("%-30s %-10.6f\n", "dependence_on_theta: ", dependence_on_theta);
#endif

// Interpolating rotangle values
float dependence_on_rotangle; //Y = dependence_on_rotangle
// Using interpolation on previous and/or next elements results in hang
// Using interpolation on out-of-bounds elements results in hang
if ((index_rotangle <= 0) || (index_rotangle >= 999))
{
dependence_on_rotangle = cData.pMem_dependence_on_rotangle_const[stick_to_bounds(index_rotangle,0,999)];
} else
{
X0 = cData.pMem_angle_const[index_rotangle];
X1 = cData.pMem_angle_const[index_rotangle+1];
Y0 = cData.pMem_dependence_on_rotangle_const[index_rotangle];
Y1 = cData.pMem_dependence_on_rotangle_const[index_rotangle+1];
dependence_on_rotangle = (Y0 * (X1-current_rotangle) + Y1 * (current_rotangle-X0)) * inv_angle_delta;
}

#if defined (PRINT_GRAD_ROTATION_GENES)
printf("\n%s\n", "----------------------------------------------------------");
printf("%-30s %-10.6f\n", "dependence_on_rotangle: ", dependence_on_rotangle);
#endif

// Setting gradient rotation-related genotypes in cube
// Multiplicating by DEG_TO_RAD is to make it uniform to DEG (see torsion gradients)
// Multiplicating by DEG_TO_RAD is to make it uniform to DEG (see torsion gradients)
#ifdef FLOAT_GRADIENTS
fgradient_genotype[3] = (grad_phi / (dependence_on_theta * dependence_on_rotangle)) * DEG_TO_RAD;
fgradient_genotype[4] = (grad_theta / dependence_on_rotangle) * DEG_TO_RAD;
fgradient_genotype[3] = grad_phi * sin_theta * sin_theta * rot_angle_corr * DEG_TO_RAD;
fgradient_genotype[4] = grad_theta * rot_angle_corr * DEG_TO_RAD;
fgradient_genotype[5] = grad_rotangle * DEG_TO_RAD;
#if defined (PRINT_GRAD_ROTATION_GENES)
printf("\n%s\n", "----------------------------------------------------------");
Expand All @@ -889,8 +802,8 @@ __device__ void gpu_calc_energrad(
printf("%-13.6f %-13.6f %-13.6f\n", fgradient_genotype[3], fgradient_genotype[4], fgradient_genotype[5]);
#endif
#else
gradient_genotype[3] = lrintf(fminf(MAXTERM, fmaxf(-MAXTERM, TERMSCALE * (grad_phi / (dependence_on_theta * dependence_on_rotangle)) * DEG_TO_RAD)));
gradient_genotype[4] = lrintf(fminf(MAXTERM, fmaxf(-MAXTERM, TERMSCALE * (grad_theta / dependence_on_rotangle) * DEG_TO_RAD)));
gradient_genotype[3] = lrintf(fminf(MAXTERM, fmaxf(-MAXTERM, TERMSCALE * grad_phi * sin_theta * sin_theta * rot_angle_corr * DEG_TO_RAD)));
gradient_genotype[4] = lrintf(fminf(MAXTERM, fmaxf(-MAXTERM, TERMSCALE * grad_theta * rot_angle_corr * DEG_TO_RAD)));
gradient_genotype[5] = lrintf(fminf(MAXTERM, fmaxf(-MAXTERM, TERMSCALE * grad_rotangle * DEG_TO_RAD)));
#if defined (PRINT_GRAD_ROTATION_GENES)
printf("\n%s\n", "----------------------------------------------------------");
Expand Down
Loading

0 comments on commit f8a0085

Please sign in to comment.