00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00019 #define _CRT_SECURE_NO_DEPRECATE
00020
00021 #include "yanera.h"
00022 #include "yanera_profile.h"
00023 #include "yanera_postfix.h"
00024
00025 void yanera_write_profile(yanera_container *yanera)
00026 {
00027 double minz, maxz, dz, z, rsld, isld;
00028 short i1, i2;
00029 FILE *fp;
00030 char filename[50];
00031
00032
00033
00034
00035
00036 for (i2=0; i2<yanera->number_of_models; i2++)
00037 {
00038
00039
00040
00041 memset(filename, '\0', 50);
00042 if (yanera->data[i2].file_name == NULL)
00043 { sprintf(filename, "result_%01d.pro", i2); }
00044 else sprintf(filename, "%s.pro", yanera->data[i2].file_name);
00045
00046
00047
00048
00049 minMaxProfile(&minz, &maxz, &yanera->models_complete[i2], yanera);
00050 dz = (maxz - minz)/(double)yanera->misc.z_num;
00051
00052
00053
00054
00055 fp = NULL;
00056 fp = fopen(filename,"w");
00057 if (fp == NULL)
00058 {
00059 yanera_error("Can't open profile file for writing.", \
00060 __FILE__, __LINE__, yanera);
00061 }
00062
00063
00064
00065 for (i1 = 0; i1 <= yanera->misc.z_num; i1++)
00066 {
00067 z = minz + dz * (double)i1;
00068 rsld = yanera->profileFunctionReal(z, &yanera->models_complete[i2], \
00069 yanera);
00070 isld = yanera->profileFunctionImag(z, &yanera->models_complete[i2], \
00071 yanera);
00072 fprintf(fp, "%f\t%f\t%f\n", z, rsld, isld);
00073 }
00074 fclose(fp);
00075 }
00076
00077 return;
00078 }
00079
00080 double layerProfileReal(double z, yanera_model *model, yanera_container *yanera)
00081 {
00082 double thik, sld, tmp1, rho1, rho2;
00083 yanera_layer *layer1, *layer2;
00084
00085
00086
00087
00088 layer1 = model->first_layer;
00089 sld = yanera->parameters.p[layer1->rsld];
00090 if (layer1->polarized == POLARIZED_UP)
00091 sld += yanera->parameters.p[layer1->rmag];
00092 else if (layer1->polarized == POLARIZED_DOWN)
00093 sld -= yanera->parameters.p[layer1->rmag];
00094
00095
00096
00097
00098
00099 layer2 = layer1;
00100 layer1 = layer1->next;
00101 thik = 0.0;
00102
00103 while (layer1 != NULL)
00104 {
00105
00106 rho1 = yanera->parameters.p[layer1->rsld];
00107 if (layer1->polarized == POLARIZED_UP)
00108 rho1 += yanera->parameters.p[layer1->rmag];
00109 else if (layer1->polarized == POLARIZED_DOWN)
00110 rho1 -= yanera->parameters.p[layer1->rmag];
00111
00112
00113 rho2 = yanera->parameters.p[layer2->rsld];
00114 if (layer2->polarized == POLARIZED_UP)
00115 rho2 += yanera->parameters.p[layer2->rmag];
00116 else if (layer2->polarized == POLARIZED_DOWN)
00117 rho2 -= yanera->parameters.p[layer2->rmag];
00118
00119 if (yanera->parameters.p[layer1->sigz] == 0)
00120 {
00121 if (z >= thik) sld += (rho1 - rho2);
00122 }
00123 else
00124 {
00125 tmp1 = (z-thik)/(M_SQRT2*fabs(yanera->parameters.p[layer1->sigz]));
00126 sld += (rho1 - rho2) * (1.0 + gsl_sf_erf(tmp1)) / 2.0;
00127 }
00128
00129
00130
00131
00132
00133
00134 if (layer1->thik > -1)
00135 thik += yanera->parameters.p[layer1->thik];
00136
00137 layer1 = layer1->next;
00138 layer2 = layer2->next;
00139 }
00140
00141 return sld;
00142 }
00143
00144 double componentProfileReal(double z, yanera_model *model, \
00145 yanera_container *yanera)
00146 {
00147 double zpos, sld, tmp1, tmp2, tmpl, tmph, tmpsld;
00148 yanera_layer *layer;
00149
00150 sld = 0.0;
00151
00152
00153
00154
00155
00156 layer = model->first_layer;
00157 tmpsld = yanera->parameters.p[layer->rsld];
00158 if (layer->polarized == POLARIZED_UP)
00159 tmpsld += yanera->parameters.p[layer->rmag];
00160 else if (layer->polarized == POLARIZED_DOWN)
00161 tmpsld -= yanera->parameters.p[layer->rmag];
00162 zpos = 0.0;
00163 if (yanera->parameters.p[layer->sigz] == 0.0)
00164 {
00165 if (z < zpos) sld += tmpsld;
00166 }
00167 else
00168 {
00169 tmp1 = (z-zpos)/(M_SQRT2*fabs(yanera->parameters.p[layer->sigz]));
00170 sld += tmpsld * (1.0 - gsl_sf_erf(tmp1)) / 2.0;
00171 }
00172
00173
00174
00175
00176 layer=layer->next;
00177 while (layer->next != NULL)
00178 {
00179 tmpsld = yanera->parameters.p[layer->rsld];
00180 if (layer->polarized == POLARIZED_UP)
00181 tmpsld += yanera->parameters.p[layer->rmag];
00182 else if (layer->polarized == POLARIZED_DOWN)
00183 tmpsld -= yanera->parameters.p[layer->rmag];
00184 zpos = yanera->parameters.p[layer->cntr];
00185
00186 if (layer->type == LAYER_BOX)
00187 {
00188 tmpl = zpos - yanera->parameters.p[layer->thik]/2.0;
00189 tmph = zpos + yanera->parameters.p[layer->thik]/2.0;
00190
00191 if (yanera->parameters.p[layer->sigz]== 0.0)
00192 {
00193 if ((z>tmpl)&&(z<tmph)) sld += tmpsld;
00194 }
00195 else
00196 {
00197 tmp1 = (z-tmpl)/(M_SQRT2*fabs(yanera->parameters.p[layer->sigz]));
00198 tmp2 = (z-tmph)/(M_SQRT2*fabs(yanera->parameters.p[layer->sigz]));
00199 sld += tmpsld * \
00200 (gsl_sf_erf(tmp1) - gsl_sf_erf(tmp2)) / 2.0;
00201 }
00202
00203 }
00204 else if (layer->type == LAYER_GAUSSIAN)
00205 {
00206 tmp1 = (zpos - z) / yanera->parameters.p[layer->sigz];
00207 sld += tmpsld * exp(-1.0 * tmp1 * tmp1);
00208 }
00209 else
00210 {
00211 yanera_error("Unknown component type.", __FILE__, __LINE__, yanera);
00212 }
00213 layer = layer->next;
00214 }
00215
00216
00217
00218
00219
00220
00221 tmpsld = yanera->parameters.p[layer->rsld];
00222 if (layer->polarized == POLARIZED_UP)
00223 tmpsld += yanera->parameters.p[layer->rmag];
00224 else if (layer->polarized == POLARIZED_DOWN)
00225 tmpsld -= yanera->parameters.p[layer->rmag];
00226 zpos = yanera->parameters.p[layer->cntr];
00227 if (yanera->parameters.p[layer->sigz] == 0)
00228 {
00229 if (z >= zpos) sld += tmpsld;
00230 }
00231 else
00232 {
00233 tmp1 = (z-zpos)/(M_SQRT2*fabs(yanera->parameters.p[layer->sigz]));
00234 sld += tmpsld * (1.0 + gsl_sf_erf(tmp1)) / 2.0;
00235 }
00236 return sld;
00237 }
00238
00239 double functionProfileReal(double z, yanera_model *model, \
00240 yanera_container *yanera)
00241 {
00242 double thik, sld, tmp1, rho1, rho2;
00243 yanera_layer *layer1, *layer2;
00244
00245
00246
00247
00248 layer1 = model->first_layer;
00249 sld = yanera->parameters.p[layer1->rsld];
00250 if (layer1->polarized == POLARIZED_UP)
00251 sld += yanera->parameters.p[layer1->rmag];
00252 else if (layer1->polarized == POLARIZED_DOWN)
00253 sld -= yanera->parameters.p[layer1->rmag];
00254
00255
00256
00257
00258
00259 layer2 = layer1;
00260 layer1 = layer1->next;
00261 thik = 0.0;
00262
00263 while (layer1 != NULL)
00264 {
00265 rho1 = 0;
00266 if (layer1->type == LAYER_FUNCTION)
00267 {
00268 rho1 = evaluate_postfix(layer1->func_postfix, z, yanera->parameters.p);
00269 }
00270 else
00271 {
00272 rho1 = yanera->parameters.p[layer1->rsld];
00273 if (layer1->polarized == POLARIZED_UP)
00274 rho1 += yanera->parameters.p[layer1->rmag];
00275 else if (layer1->polarized == POLARIZED_DOWN)
00276 rho1 -= yanera->parameters.p[layer1->rmag];
00277 }
00278
00279 rho2 = 0;
00280 if (layer2->type == LAYER_FUNCTION)
00281 {
00282 rho2 = evaluate_postfix(layer2->func_postfix, z, yanera->parameters.p);
00283 }
00284 else
00285 {
00286 rho2 = yanera->parameters.p[layer2->rsld];
00287 if (layer2->polarized == POLARIZED_UP)
00288 rho2 += yanera->parameters.p[layer2->rmag];
00289 else if (layer2->polarized == POLARIZED_DOWN)
00290 rho2 -= yanera->parameters.p[layer2->rmag];
00291 }
00292
00293 if (yanera->parameters.p[layer1->sigz] == 0)
00294 {
00295 if (z >= thik) sld += (rho1 - rho2);
00296 }
00297 else
00298 {
00299 tmp1 = (z-thik)/(M_SQRT2*fabs(yanera->parameters.p[layer1->sigz]));
00300 sld += (rho1 - rho2) * (1.0 + gsl_sf_erf(tmp1)) / 2.0;
00301 }
00302
00303
00304
00305
00306
00307
00308 if (layer1->thik > -1)
00309 thik += yanera->parameters.p[layer1->thik];
00310
00311 layer1 = layer1->next;
00312 layer2 = layer2->next;
00313 }
00314
00315 return sld;
00316 }
00317
00318 double layerProfileImag(double z, yanera_model *model, yanera_container *yanera)
00319 {
00320 double thik, sld, tmp1, rho1, rho2;
00321 yanera_layer *layer1, *layer2;
00322
00323
00324
00325
00326 layer1 = model->first_layer;
00327 if (layer1->isld > -1) sld = yanera->parameters.p[layer1->isld];
00328 else sld = 0.0;
00329
00330
00331
00332
00333 layer2 = layer1;
00334 layer1 = layer1->next;
00335 thik = 0.0;
00336
00337 while (layer1 != NULL)
00338 {
00339 if (layer1->isld > -1) rho1 = yanera->parameters.p[layer1->isld];
00340 else rho1 = 0.0;
00341
00342 if (layer2->isld > -1) rho2 = yanera->parameters.p[layer2->isld];
00343 else rho2 = 0.0;
00344
00345 if (yanera->parameters.p[layer1->sigz] == 0)
00346 {
00347 if (z >= thik) sld += (rho1 - rho2);
00348 }
00349 else
00350 {
00351 tmp1 = (z-thik)/(M_SQRT2*fabs(yanera->parameters.p[layer1->sigz]));
00352 sld += (rho1 - rho2) * (1.0 + gsl_sf_erf(tmp1)) / 2.0;
00353 }
00354
00355
00356
00357
00358
00359
00360 if (layer1->thik > -1)
00361 thik += yanera->parameters.p[layer1->thik];
00362
00363 layer1 = layer1->next;
00364 layer2 = layer2->next;
00365 }
00366
00367 return sld;
00368 }
00369
00370 double componentProfileImag(double z, yanera_model *model, \
00371 yanera_container *yanera)
00372 {
00373 double zpos, sld, tmp1, tmp2, tmpl, tmph, tmpsld;
00374 yanera_layer *layer;
00375
00376 sld = 0.0;
00377
00378
00379
00380
00381
00382 layer = model->first_layer;
00383 if (layer->isld > -1) tmpsld = yanera->parameters.p[layer->isld];
00384 else tmpsld = 0.0;
00385 zpos = 0.0;
00386 if (yanera->parameters.p[layer->sigz] == 0.0)
00387 {
00388 if (z < zpos) sld += tmpsld;
00389 }
00390 else
00391 {
00392 tmp1 = (z-zpos)/(M_SQRT2*fabs(yanera->parameters.p[layer->sigz]));
00393 sld += tmpsld * (1.0 - gsl_sf_erf(tmp1)) / 2.0;
00394 }
00395
00396
00397
00398
00399 layer=layer->next;
00400 while (layer->next != NULL)
00401 {
00402 if (layer->isld > -1) tmpsld = yanera->parameters.p[layer->isld];
00403 else tmpsld = 0.0;
00404 zpos = yanera->parameters.p[layer->cntr];
00405
00406 if (layer->type == LAYER_BOX)
00407 {
00408 tmpl = zpos - yanera->parameters.p[layer->thik]/2.0;
00409 tmph = zpos + yanera->parameters.p[layer->thik]/2.0;
00410
00411 if (yanera->parameters.p[layer->sigz]== 0.0)
00412 {
00413 if ((z>tmpl)&&(z<tmph)) sld += tmpsld;
00414 }
00415 else
00416 {
00417 tmp1 = (z-tmpl)/(M_SQRT2*fabs(yanera->parameters.p[layer->sigz]));
00418 tmp2 = (z-tmph)/(M_SQRT2*fabs(yanera->parameters.p[layer->sigz]));
00419 sld += tmpsld * \
00420 (gsl_sf_erf(tmp1) - gsl_sf_erf(tmp2)) / 2.0;
00421 }
00422
00423 }
00424 else if (layer->type == LAYER_GAUSSIAN)
00425 {
00426 tmp1 = (zpos - z) / yanera->parameters.p[layer->sigz];
00427 sld += tmpsld * exp(-1.0 * tmp1 * tmp1);
00428 }
00429 else
00430 {
00431 yanera_error("Unknown component type.", __FILE__, __LINE__, yanera);
00432 }
00433
00434 layer = layer->next;
00435 }
00436
00437
00438
00439
00440
00441
00442 if (layer->isld > -1) tmpsld = yanera->parameters.p[layer->isld];
00443 else tmpsld = 0.0;
00444 zpos = yanera->parameters.p[layer->cntr];
00445 if (yanera->parameters.p[layer->sigz] == 0)
00446 {
00447 if (z >= zpos) sld += tmpsld;
00448 }
00449 else
00450 {
00451 tmp1 = (z-zpos)/(M_SQRT2*fabs(yanera->parameters.p[layer->sigz]));
00452 sld += tmpsld * (1.0 + gsl_sf_erf(tmp1)) / 2.0;
00453 }
00454 return sld;
00455 }
00456
00457 double functionProfileImag(double z, yanera_model *model, \
00458 yanera_container *yanera)
00459 {
00460 double thik, sld, tmp1, rho1, rho2;
00461 yanera_layer *layer1, *layer2;
00462
00463
00464
00465
00466 layer1 = model->first_layer;
00467 if (layer1->isld > -1) sld = yanera->parameters.p[layer1->isld];
00468 else sld = 0.0;
00469
00470
00471
00472
00473 layer2 = layer1;
00474 layer1 = layer1->next;
00475 thik = 0.0;
00476
00477 while (layer1 != NULL)
00478 {
00479 rho1 = 0;
00480 if (layer1->type == LAYER_FUNCTION)
00481 {
00482 rho1 = 0.0;
00483 }
00484 else
00485 {
00486 if (layer1->isld > -1) rho1 = yanera->parameters.p[layer1->isld];
00487 else rho1 = 0.0;
00488
00489 }
00490
00491 rho2 = 0;
00492 if (layer2->type == LAYER_FUNCTION)
00493 {
00494 rho2 = 0.0;
00495 }
00496 else
00497 {
00498 if (layer1->isld > -1) rho2 = yanera->parameters.p[layer1->isld];
00499 else rho2 = 0.0;
00500 }
00501
00502 if (yanera->parameters.p[layer1->sigz] == 0)
00503 {
00504 if (z >= thik) sld += (rho1 - rho2);
00505 }
00506 else
00507 {
00508 tmp1 = (z-thik)/(M_SQRT2*fabs(yanera->parameters.p[layer1->sigz]));
00509 sld += (rho1 - rho2) * (1.0 + gsl_sf_erf(tmp1)) / 2.0;
00510 }
00511
00512
00513
00514
00515
00516
00517 if (layer1->thik > -1)
00518 thik += yanera->parameters.p[layer1->thik];
00519
00520 layer1 = layer1->next;
00521 layer2 = layer2->next;
00522 }
00523
00524 return sld;
00525 }
00526
00527 void minMaxProfile(double *min, double *max, yanera_model *model, \
00528 yanera_container *yanera)
00529 {
00530 double cntr, sigz;
00531 yanera_layer *layer;
00532
00533
00534
00535
00536 layer = model->first_layer;
00537 min[0] = -1.0;
00538 if ((yanera->type == MODEL_LAYER) || \
00539 (yanera->type == MODEL_SLAB) || \
00540 (yanera->type == MODEL_FUNCTION))
00541 {
00542
00543
00544
00545
00546 if (yanera->parameters.p[layer->next->sigz] != 0.0)
00547 { min[0] = -5.0 * fabs(yanera->parameters.p[layer->next->sigz]); }
00548 else { min[0] -= 1.0; }
00549
00550 }
00551 else if (yanera->type == MODEL_COMPONENT)
00552 {
00553
00554
00555
00556
00557 cntr = 0.0;
00558 if (yanera->parameters.p[layer->sigz] == 0.0) sigz = -1.0;
00559 else sigz = -5.0 * fabs(yanera->parameters.p[layer->sigz]);
00560 min[0] = cntr+sigz;
00561
00562
00563
00564
00565 layer = layer->next;
00566 while (layer != NULL)
00567 {
00568 cntr = yanera->parameters.p[layer->cntr];
00569 if (layer->type == LAYER_BOX)
00570 { cntr -= fabs(yanera->parameters.p[layer->thik]) / 2.0; }
00571 if (yanera->parameters.p[layer->sigz] == 0.0) sigz = -1.0;
00572 else sigz = -5.0 * fabs(yanera->parameters.p[layer->sigz]);
00573 if (min[0] > (cntr+sigz)) min[0] = cntr + sigz;
00574 layer = layer->next;
00575 }
00576 }
00577 else
00578 {
00579 yanera_error("Unknown model type in minMaxProfile.",\
00580 __FILE__, __LINE__, yanera);
00581 }
00582
00583
00584
00585
00586 max[0] = 0.0;
00587 layer = model->first_layer;
00588 layer = layer->next;
00589 while (layer->next != NULL)
00590 {
00591
00592 if ((yanera->type == MODEL_LAYER) || \
00593 (yanera->type == MODEL_SLAB) || \
00594 (yanera->type == MODEL_FUNCTION))
00595 {
00596 max[0] += yanera->parameters.p[layer->thik];
00597 }
00598
00599
00600
00601 if (yanera->type == MODEL_COMPONENT)
00602 {
00603 cntr = yanera->parameters.p[layer->cntr];
00604 if (layer->type == LAYER_BOX)
00605 { cntr += fabs(yanera->parameters.p[layer->thik]) / 2.0; }
00606 if (yanera->parameters.p[layer->sigz] == 0.0) sigz = 1.0;
00607 else sigz = 5.0 * fabs(yanera->parameters.p[layer->sigz]);
00608 if (max[0] < (cntr+sigz)) max[0] = cntr + sigz;
00609 }
00610 layer = layer->next;
00611 }
00612
00613
00614 if ((yanera->type == MODEL_LAYER) || \
00615 (yanera->type == MODEL_SLAB) || \
00616 (yanera->type == MODEL_FUNCTION))
00617 {
00618 if (yanera->parameters.p[layer->sigz] == 0.0) max[0] += 1.0;
00619 else max[0] += 5.0 * yanera->parameters.p[layer->sigz];
00620 }
00621
00622 if (yanera->type == MODEL_COMPONENT)
00623 {
00624 cntr = yanera->parameters.p[layer->cntr];
00625 if (layer->type == LAYER_BOX)
00626 { cntr += fabs(yanera->parameters.p[layer->thik]) / 2.0; }
00627 if (yanera->parameters.p[layer->sigz] == 0.0) sigz = 1.0;
00628 else sigz = 5.0 * fabs(yanera->parameters.p[layer->sigz]);
00629 if (max[0] < (cntr+sigz)) max[0] = cntr + sigz;
00630 }
00631
00632 return;
00633 }
00634