diff options
author | Thomas White <taw@physics.org> | 2010-11-22 11:19:23 +0100 |
---|---|---|
committer | Thomas White <taw@physics.org> | 2012-02-22 15:27:06 +0100 |
commit | 20d05388833bd9f3b6819d82f983eea424663407 (patch) | |
tree | bb5ffe085ea697e4363d03003febeed517ec383b /src/post-refinement.c | |
parent | 10c4b9c1c596c6196e5ca478fca7f1fa27f2da0c (diff) |
Fix post refinement maths and take clamping status into account
Diffstat (limited to 'src/post-refinement.c')
-rw-r--r-- | src/post-refinement.c | 53 |
1 files changed, 44 insertions, 9 deletions
diff --git a/src/post-refinement.c b/src/post-refinement.c index 5ca0dc98..e2fa6d50 100644 --- a/src/post-refinement.c +++ b/src/post-refinement.c @@ -28,12 +28,33 @@ #include "geometry.h" +/* Returns dp/dr at "r" */ +static double partiality_gradient(double r, double profile_radius) +{ + double q, dpdq, dqdr; + + /* Calculate degree of penetration */ + q = (r + profile_radius)/(2.0*profile_radius); + + /* dp/dq */ + dpdq = 6.0*(q-pow(q, 2.0)); + + /* dq/dr */ + dqdr = 1.0 / (2.0*profile_radius); + + return dpdq * dqdr; +} + + /* Return the gradient of parameter 'k' given the current status of 'image'. */ double gradient(struct image *image, int k, - struct cpeak spot, double I_partial) + struct cpeak spot, double I_partial, double r) { double ds; double nom, den; + double r1g = 0.0; + double r2g = 0.0; + double g = 0.0; ds = 2.0 * resolution(image->indexed_cell, spot.h, spot.k, spot.l); @@ -43,9 +64,20 @@ double gradient(struct image *image, int k, return I_partial; case REF_DIV : - nom = sqrt(2.0) * ds * sin(image->div); - den = sqrt(1.0 - cos(image->div)); - return nom/den; + /* Calculate the gradient of r1 and r2 wrt divergence */ + if ( spot.clamp1 == 0 ) { + nom = sqrt(2.0) * ds * sin(image->div/2.0); + den = sqrt(1.0 - cos(image->div/2.0)); + r1g = nom/den; + g += r1g * partiality_gradient(spot.r1, r); + } + if ( spot.clamp2 == 0 ) { + nom = sqrt(2.0) * ds * sin(image->div/2.0); + den = sqrt(1.0 - cos(image->div/2.0)); + r2g = nom/den; + g += r2g * partiality_gradient(spot.r2, r); + } + return g; } @@ -171,7 +203,7 @@ double pr_iterate(struct image *image, double *i_full, const char *sym, for ( k=0; k<NUM_PARAMS; k++ ) { int g; - double v_c; + double v_c, gr; for ( g=0; g<NUM_PARAMS; g++ ) { @@ -179,16 +211,19 @@ double pr_iterate(struct image *image, double *i_full, const char *sym, M_curr = gsl_matrix_get(M, g, k); - M_c = gradient(image, g, spots[h], I_partial) - * gradient(image, k, spots[h], I_partial); + M_c = gradient(image, g, spots[h], I_partial, + image->profile_radius) + * gradient(image, k, spots[h], I_partial, + image->profile_radius); M_c *= pow(I_full, 2.0); gsl_matrix_set(M, g, k, M_curr + M_c); } - v_c = delta_I * I_full * gradient(image, k, spots[h], - I_partial); + gr = gradient(image, k, spots[h], I_partial, + image->profile_radius); + v_c = delta_I * I_full * gr; gsl_vector_set(v, k, v_c); } |