00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00018 #define _CRT_SECURE_NO_DEPRECATE
00019
00020 #include "yanera.h"
00021 #include "yanera_reflectivity.h"
00022 #include "yanera_quadrature.h"
00023
00024 void yanera_write_reflectivity(yanera_container *yanera)
00025 {
00026 double dq=0.0, q=0.0, r=0.0;
00027 int i1, i2;
00028 FILE *fp;
00029 char filename[50];
00030
00031 if (yanera->misc.fit_do == NO)
00032 {
00033
00034
00035
00036 if (yanera->misc.q_min == 0.0) yanera->misc.q_min = 1.0E-5;
00037 dq = (yanera->misc.q_max - yanera->misc.q_min)/((double)yanera->misc.q_num);
00038 }
00039
00040 for (i2=0; i2<yanera->number_of_models; i2++)
00041 {
00042
00043
00044
00045 memset(filename, '\0', 50);
00046 if (yanera->data[i2].file_name == NULL)
00047 { sprintf(filename, "result_%01d.ref", i2); }
00048 else sprintf(filename, "%s.ref", yanera->data[i2].file_name);
00049
00050
00051
00052
00053 if ((yanera->type == MODEL_COMPONENT) || \
00054 (yanera->type == MODEL_SLAB) || \
00055 (yanera->type == MODEL_FUNCTION))
00056 { doQuadrature(&yanera->models_complete[i2], yanera); }
00057
00058
00059
00060
00061 fp = NULL;
00062 fp = fopen(filename,"w");
00063 if (fp == NULL)
00064 {
00065 yanera_error("Can't open reflectivity file for writing", \
00066 __FILE__, __LINE__, yanera);
00067 }
00068
00069 if (yanera->misc.fit_do == NO)
00070 {
00071 for (i1 = 0; i1 <= yanera->misc.q_num; i1++)
00072 {
00073 q = yanera->misc.q_min + dq * (double)i1;
00074 r = calcReflectivity(q, &yanera->data[i2].resolution, \
00075 &yanera->models_complete[i2], yanera);
00076 fprintf(fp, "%g\t%g\n", q, r);
00077 }
00078 }
00079 else
00080 {
00081 for (i1 = 0; i1 < yanera->data[i2].n; i1++)
00082 {
00083 q = yanera->data[i2].q[i1];
00084 r = calcReflectivity(q, &yanera->data[i2].resolution, \
00085 &yanera->models_complete[i2], yanera);
00086 fprintf(fp, "%g\t%g\n", q, r);
00087 }
00088 }
00089
00090 fclose(fp);
00091 }
00092
00093 return;
00094 }
00095
00096 double calcReflectivity(double q, yanera_resolution *resolution, \
00097 yanera_model *model, yanera_container *yanera)
00098 {
00099 double tmp, value;
00100
00101 tmp = yanera->parrattFunction(q, model, yanera);
00102
00103
00104 value = 0.0;
00105 if ((resolution->type == RESOLUTION_CONSTANT) || \
00106 (resolution->type == RESOLUTION_RELATIVE))
00107 {
00108 value = resolution->value[0];
00109 }
00110 else if ((resolution->type == RESOLUTION_ARRAY_CONSTANT) || \
00111 (resolution->type == RESOLUTION_ARRAY_RELATIVE))
00112 {
00113 value = lookupResolution(q, resolution);
00114 }
00115
00116
00117 if (value != 0.0)
00118 {
00119
00120 if ((resolution->type == RESOLUTION_CONSTANT) || \
00121 (resolution->type == RESOLUTION_ARRAY_CONSTANT))
00122 {
00123 tmp += 0.882*yanera->parrattFunction(q+(0.25*value), model, yanera);
00124 tmp += 0.882*yanera->parrattFunction(q-(0.25*value), model, yanera);
00125 tmp += 0.607*yanera->parrattFunction(q+(0.50*value), model, yanera);
00126 tmp += 0.607*yanera->parrattFunction(q-(0.50*value), model, yanera);
00127 tmp += 0.325*yanera->parrattFunction(q+(0.75*value), model, yanera);
00128 tmp += 0.325*yanera->parrattFunction(q-(0.75*value), model, yanera);
00129 tmp += 0.135*yanera->parrattFunction(q+(1.00*value), model, yanera);
00130 tmp += 0.135*yanera->parrattFunction(q-(1.00*value), model, yanera);
00131 }
00132 else if ((resolution->type == RESOLUTION_RELATIVE) || \
00133 (resolution->type == RESOLUTION_ARRAY_RELATIVE))
00134 {
00135 tmp += 0.882*yanera->parrattFunction(q*(1.0+(0.25*value)), model, yanera);
00136 tmp += 0.882*yanera->parrattFunction(q*(1.0-(0.25*value)), model, yanera);
00137 tmp += 0.607*yanera->parrattFunction(q*(1.0+(0.50*value)), model, yanera);
00138 tmp += 0.607*yanera->parrattFunction(q*(1.0-(0.50*value)), model, yanera);
00139 tmp += 0.325*yanera->parrattFunction(q*(1.0+(0.75*value)), model, yanera);
00140 tmp += 0.325*yanera->parrattFunction(q*(1.0-(0.75*value)), model, yanera);
00141 tmp += 0.135*yanera->parrattFunction(q*(1.0+(1.00*value)), model, yanera);
00142 tmp += 0.135*yanera->parrattFunction(q*(1.0-(1.00*value)), model, yanera);
00143 }
00144 tmp /= (4.898);
00145 }
00146
00147
00148 if (model->background > -1)
00149 tmp += (yanera->parameters.p[model->background] * 1.0E-06);
00150
00151 return tmp;
00152
00153 }
00154
00155 double calcParrattFromSlabs(double q, \
00156 yanera_model *model, \
00157 yanera_container *yanera)
00158 {
00159 short i;
00160 double kv, tmpr, tmpi, result;
00161 gsl_complex kzn, kznp1;
00162 gsl_complex fr, R;
00163 gsl_complex tmp1, tmp2;
00164 gsl_complex argm, numtr, denom;
00165
00166 if (q <= 0.0) return 1.0;
00167
00168
00169
00170
00171
00172 tmpr = (q * q / 4.0) + (4.0 * M_PI * model->slabs.rsld[0] * 1E-6);
00173 tmpi = (4.0 * M_PI * model->slabs.isld[0] * 1E-6);
00174 GSL_SET_COMPLEX(&tmp1, tmpr, tmpi);
00175 kv = gsl_complex_abs(gsl_complex_sqrt(tmp1));
00176
00177
00178
00179
00180
00181
00182 GSL_SET_COMPLEX(&R, 0.0, 0.0);
00183 GSL_SET_COMPLEX(&fr, 0.0, 0.0);
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199 i = model->slabs.number_of_slabs-2;
00200 {
00201 tmpr = (kv * kv)-(4.0 * M_PI * model->slabs.rsld[i] * 1E-6);
00202 tmpi = (4.0 * M_PI * model->slabs.isld[i] * 1E-6);
00203 GSL_SET_COMPLEX(&tmp1, tmpr, tmpi);
00204 kzn = gsl_complex_sqrt(tmp1);
00205
00206 tmpr = (kv * kv)-(4.0 * M_PI * model->slabs.rsld[i+1] * 1E-6);
00207 tmpi = (4.0 * M_PI * model->slabs.isld[i+1] * 1E-6);
00208 GSL_SET_COMPLEX(&tmp1, tmpr, tmpi);
00209 kznp1 = gsl_complex_sqrt(tmp1);
00210
00211
00212 tmp1 = gsl_complex_sub(kzn, kznp1);
00213 tmp2 = gsl_complex_add(kzn, kznp1);
00214 R = gsl_complex_div(tmp1, tmp2);
00215 }
00216
00217
00218
00219
00220 for (i=model->slabs.number_of_slabs-3; i>=0; i--)
00221 {
00222 GSL_SET_COMPLEX(&kznp1, GSL_REAL(kzn), GSL_IMAG(kzn));
00223
00224 tmpr = (kv * kv)-(4.0 * M_PI * model->slabs.rsld[i] * 1E-6);
00225 tmpi = (4.0 * M_PI * model->slabs.isld[i] * 1E-6);
00226 GSL_SET_COMPLEX(&tmp1, tmpr, tmpi);
00227 kzn = gsl_complex_sqrt(tmp1);
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239 tmp1 = gsl_complex_sub(kzn, kznp1);
00240 tmp2 = gsl_complex_add(kzn, kznp1);
00241 fr = gsl_complex_div(tmp1, tmp2);
00242
00243
00244 tmp1 = gsl_complex_mul_imag(kznp1, 2.0*model->slabs.thik[i+1]);
00245 tmp2 = gsl_complex_exp(tmp1);
00246 argm = gsl_complex_mul(R, tmp2);
00247
00248
00249 numtr = gsl_complex_add(fr, argm);
00250
00251
00252 denom = gsl_complex_add_real(gsl_complex_mul(fr, argm), 1.0);
00253
00254 R = gsl_complex_div(numtr, denom);
00255 }
00256
00257
00258 result = gsl_complex_abs2(R);
00259
00260 return result;
00261 }
00262
00263 double calcParrattFromModel(double q, \
00264 yanera_model *model, \
00265 yanera_container *yanera)
00266 {
00267 double kv, tmpr, tmpi, result, rsld;
00268 gsl_complex kzn, kznp1;
00269 gsl_complex fr, r, R;
00270 gsl_complex tmp1, tmp2, tmp3;
00271 gsl_complex argm, numtr, denom;
00272 yanera_layer *layer;
00273
00274 if (q < 0) return 1.0;
00275
00276
00277
00278
00279
00280 layer = model->first_layer;
00281 rsld = yanera->parameters.p[layer->rsld];
00282 if (layer->polarized == POLARIZED_UP)
00283 rsld += yanera->parameters.p[layer->rmag];
00284 else if (layer->polarized == POLARIZED_DOWN)
00285 rsld -= yanera->parameters.p[layer->rmag];
00286 tmpr = (q * q / 4.0) + (4.0 * M_PI * rsld * 1E-6);
00287 if (layer->isld > -1)
00288 { tmpi = (4.0 * M_PI * yanera->parameters.p[layer->isld] * 1E-6); }
00289 else tmpi = 0.0;
00290 GSL_SET_COMPLEX(&tmp1, tmpr, tmpi);
00291 kv = gsl_complex_abs(gsl_complex_sqrt(tmp1));
00292
00293
00294
00295
00296
00297
00298 GSL_SET_COMPLEX(&R, 0.0, 0.0);
00299 GSL_SET_COMPLEX(&fr, 0.0, 0.0);
00300 GSL_SET_COMPLEX(&r, 0.0, 0.0);
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316 layer = model->last_layer->prev;
00317 {
00318 rsld = yanera->parameters.p[layer->rsld];
00319 if (layer->polarized == POLARIZED_UP)
00320 rsld += yanera->parameters.p[layer->rmag];
00321 else if (layer->polarized == POLARIZED_DOWN)
00322 rsld -= yanera->parameters.p[layer->rmag];
00323 tmpr = (kv * kv)-(4.0 * M_PI * rsld * 1E-6);
00324 if (layer->isld > -1)
00325 { tmpi = (4.0 * M_PI * yanera->parameters.p[layer->isld] * 1E-6); }
00326 else tmpi = 0.0;
00327 GSL_SET_COMPLEX(&tmp1, tmpr, tmpi);
00328 kzn = gsl_complex_sqrt(tmp1);
00329
00330 rsld = yanera->parameters.p[layer->next->rsld];
00331 if (layer->next->polarized == POLARIZED_UP)
00332 rsld += yanera->parameters.p[layer->next->rmag];
00333 else if (layer->next->polarized == POLARIZED_DOWN)
00334 rsld -= yanera->parameters.p[layer->next->rmag];
00335 tmpr = (kv * kv)-(4.0 * M_PI * rsld * 1E-6);
00336 if (layer->next->isld > -1)
00337 { tmpi = (4.0 * M_PI * yanera->parameters.p[layer->next->isld] * 1E-6); }
00338 else tmpi = 0.0;
00339 GSL_SET_COMPLEX(&tmp1, tmpr, tmpi);
00340 kznp1 = gsl_complex_sqrt(tmp1);
00341
00342
00343 tmp1 = gsl_complex_sub(kzn, kznp1);
00344 tmp2 = gsl_complex_add(kzn, kznp1);
00345 fr = gsl_complex_div(tmp1, tmp2);
00346
00347
00348 tmp1 = gsl_complex_mul(kzn,kznp1);
00349 tmpr = -2.0 * yanera->parameters.p[layer->next->sigz] * \
00350 yanera->parameters.p[layer->next->sigz];
00351 tmp2 = gsl_complex_mul_real(tmp1, tmpr);
00352 tmp3 = gsl_complex_exp(tmp2);
00353 R = gsl_complex_mul(fr, tmp3);
00354 }
00355
00356
00357
00358
00359 do
00360 {
00361 layer = layer->prev;
00362
00363 GSL_SET_COMPLEX(&kznp1, GSL_REAL(kzn), GSL_IMAG(kzn));
00364
00365 rsld = yanera->parameters.p[layer->rsld];
00366 if (layer->polarized == POLARIZED_UP)
00367 rsld += yanera->parameters.p[layer->rmag];
00368 else if (layer->polarized == POLARIZED_DOWN)
00369 rsld -= yanera->parameters.p[layer->rmag];
00370 tmpr = (kv * kv)-(4.0 * M_PI * rsld * 1E-6);
00371 if (layer->isld > -1)
00372 { tmpi = (4.0 * M_PI * yanera->parameters.p[layer->isld] * 1E-6); }
00373 else tmpi = 0.0;
00374 GSL_SET_COMPLEX(&tmp1, tmpr, tmpi);
00375 kzn = gsl_complex_sqrt(tmp1);
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394 tmp1 = gsl_complex_sub(kzn, kznp1);
00395 tmp2 = gsl_complex_add(kzn, kznp1);
00396 fr = gsl_complex_div(tmp1, tmp2);
00397
00398
00399 tmp1 = gsl_complex_mul(kzn,kznp1);
00400 tmpr = -2.0 * yanera->parameters.p[layer->next->sigz] * \
00401 yanera->parameters.p[layer->next->sigz];
00402 tmp2 = gsl_complex_mul_real(tmp1, tmpr);
00403 tmp3 = gsl_complex_exp(tmp2);
00404 r = gsl_complex_mul(fr, tmp3);
00405
00406
00407 tmp1 = gsl_complex_mul_imag(kznp1, \
00408 2.0*yanera->parameters.p[layer->next->thik]);
00409 tmp2 = gsl_complex_exp(tmp1);
00410 argm = gsl_complex_mul(R, tmp2);
00411
00412
00413 numtr = gsl_complex_add(r, argm);
00414
00415
00416 denom = gsl_complex_add_real(gsl_complex_mul(r, argm), 1.0);
00417
00418 R = gsl_complex_div(numtr, denom);
00419
00420 } while (layer != model->first_layer);
00421
00422
00423 result = gsl_complex_abs2(R);
00424
00425 return result;
00426 }
00427
00428 double lookupResolution(double q, yanera_resolution *resolution)
00429 {
00430 int i=0;
00431
00432
00433
00434
00435 for (i = resolution->n-1; i>=0; i--)
00436 {
00437 if (resolution->q[i] <= q) return resolution->value[i];
00438 }
00439
00440
00441 return 0.0;
00442 }
00443