From kristian.nielsen at risoe.dk Mon Oct 4 11:31:02 1999 From: kristian.nielsen at risoe.dk (Kristian Nielsen) Date: Mon, 04 Oct 1999 11:31:02 +0200 Subject: McStas graphical front-end and PgPerl solutions Message-ID: <01JGQH322CI28WY5R9@risoe.dk> In McStas version 1.1, the front-end programs require several external software packages that must be properly installed before the McStas front-ends can be used. Particularly the "PgPerl" front-end, which is an interface between the Perl language and the PGPLOT graphics library, has been troublesome. Hoping to solve some of these problems, I have now made available binary packages (in the form of "RPM" files) of the necessary libraries for Red Hat Linux on Intel PCs; hopefully they also work on other Linux distributions that use RPM (ie. Suse). They are available from http://neutron.risoe.dk/mcstas/download.html I have also added a section to the FAQ that gives some hints on compiling PgPerl: http://neutron.risoe.dk/mcstas/FAQ.html Please let me know if there are any further problems, and I will try to help. - Kristian. -- Kristian Nielsen kristian.nielsen at risoe.dk Ris? National Laboratory Condensed Matter Physics and Chemistry Department Tel. +45 4677 5515 Fax +45 4677 4790 From kristian.nielsen at risoe.dk Fri Oct 1 11:50:19 1999 From: kristian.nielsen at risoe.dk (Kristian Nielsen) Date: 1 Oct 1999 11:50:19 +0200 Subject: Optimizer : Great In-Reply-To: <37F38CA9.BB8C504A@ill.fr> (message from Farhi on Thu, 30 Sep 1999 18:15:37 +0200) Message-ID: > Date: Thu, 30 Sep 1999 18:15:37 +0200 > From: Farhi > I now have an optimizer that increases count numbers on detector by > about a factor 40 to 50 ! That sounds very nice indeed! Do you have some idea where the neutrons are getting lost when the optimizer is not used (guide absorption, missing monochromator or sample, wrong energy, ...)? > What's long in computation is the random generator. ABSORB comes after, > and so do not affect drastically the computation time (perhaps a factor > 2). A better solution is to use the 'bad' random numbers and to convert > them to some more effective values. That's what I do. Yes, this problem is actually why I choose to integrate the optimizer in the source component; just by generating the useless neutrons you are already wasting a log of computation time, even more so since most neutrons usually get lost early in the instrument. But this also sounds like I may need to look at optimizing the random number generation routine (in fact I already put in a better-quality random number generator in the version you are now using). But anyway, I am very much looking forward to seeing your code when it is ready. Have you considered writing some documentation that would make your optimizer suitable for inclusion in the McStas manual and thereby in the official release? - Kristian. From farhi at ill.fr Tue Oct 5 11:39:51 1999 From: farhi at ill.fr (Farhi) Date: Tue, 05 Oct 1999 11:39:51 +0200 Subject: kw_monitor Message-ID: <37F9C767.B04EDB5A@ill.fr> Hy Kristian, Concerning the kw_monitor, I saw you installed it in the unofficial additions to McStas. It's great, thanks. Anyway, I modified a line at the begining in order to be able to use more than one of these monitors in one instrument definition. Could you update this ? OUTPUT PARAMETERS (Nsum, psum, p2sum,file,nlines) I attach the total file as well. I'm still on the optimizer. I got some problems in computing the adapted 'pi' probability. For some neutrons, it becomes very big, that makes spikes on instruments monitors. The neutrons responsible for this are those whose efficiency is low (the optimized source should emit few of those, thus their weight is high). I'm thinking about suppresing them... Cheers. -- Emmanuel FARHI, http://www.ill.fr/tas/people/Farhi.html \|/ ____ \|/ TAS-Group, Institut Laue-Langevin (ILL) Grenoble ~@-/ oO \-@~ Avenue des Martyrs, BP 156, 38042 Grenoble Cedex 9,France /_( \__/ )_\ Work :Tel (33/0) 4 76 20 71 83. Fax (33/0) 4 76 48 39 06 \__U_/ La Grande Arche, Chateau d'Uriage, 38410 Saint Martin d'Uriage 04 76 59 73 94 -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- /******************************************************************************* * * McStas, version 1.1, released * Maintained by Kristian Nielsen and Kim Lefmann, * Risoe National Laboratory, Roskilde, Denmark * * Component: kw_monitor * * Written by: EF, 17 Sept 1999 * * A monitor that list all neutron (k,w). * Output is a 2D matrix of lines [ kx ky kz Omega Intensity DeltaIntensity ] * stored if a file. The integrated flux is also measured. * * INPUT PARAMETERS: * * xmin: Lower x bound of detector opening (m) * xmax: Upper x bound of detector opening (m) * ymin: Lower y bound of detector opening (m) * ymax: Upper y bound of detector opening (m) * filename: Name of file in which to store the counts (text) * * OUTPUT PARAMETERS: * * Nsum: Integrated neutron counts * psum: Integrated neutron weight counts * p2sum: Integrated second moments * *******************************************************************************/ DEFINE COMPONENT kw_monitor DEFINITION PARAMETERS (xmin, xmax, ymin, ymax, filename) SETTING PARAMETERS () OUTPUT PARAMETERS (Nsum, psum, p2sum,file,nlines) STATE PARAMETERS (x,y,z,vx,vy,vz,t,s1,s2,p) DECLARE %{ int nlines; int Nsum; double psum, p2sum; FILE *file; double kx, ky, kz, E; %} INITIALIZE %{ psum = 0; p2sum = 0; Nsum = 0; nlines = 0; file = fopen(filename, "w"); if(!file) { fprintf(stderr, "Error: %s : could not open output file '%s'\n", mccompcurname, filename); exit(-1); } else { fprintf(file,"# Instrument-source: %s\n", mcinstrument_source); mcruninfo_out("# ", file); fprintf(file,"# type: array_2d(-1,6) (See end of file for exact dimensions)\n"); fprintf(file,"# component: %s\n", mccompcurname); fprintf(file,"# title: Resolution (\\vec{k},omega) Monitor\n"); fprintf(file,"# filename: '%s'\n",filename); fprintf(file,"# variables: Kx Ky Kz E I I_err\n"); fprintf(file,"# xvar: (Kx Ky Kz E)\n"); fprintf(file,"# yvar: (I,I_err)\n"); fprintf(file,"# xlabel: 'Wavevector [Angs-1], Energie [meV]'\n"); fprintf(file,"# ylabel: 'Intensity'\n"); } %} TRACE %{ PROP_Z0; if (x>xmin && xymin && y (message from Farhi on Tue, 05 Oct 1999 11:39:51 +0200) Message-ID: > Date: Tue, 05 Oct 1999 11:39:51 +0200 > From: Farhi > Hy Kristian, > Concerning the kw_monitor, I saw you installed it in the unofficial > additions to McStas. It's great, thanks. Anyway, I modified a line at > the begining in order to be able to use more than one of these monitors > in one instrument definition. Could you update this ? I have now put the updated component on the page. > I'm still on the optimizer. I got some problems in computing the adapted > 'pi' probability. > For some neutrons, it becomes very big, that makes spikes on instruments > monitors. > The neutrons responsible for this are those whose efficiency is low (the > optimized source should emit few of those, thus their weight is high). Ah! Yes, I also found the hard way that a lot of care is needed when designing the strategy for optimizing the neutron emission when I did my adaptive source component. I think I use a slightly different strategy from yours, maybe it can serve as inspiration. I do not think in terms of optimizing the number of neutrons in the detector; rather I think in terms of minimizing the statistical error in the detector. The statistical error depends not only on the number of neutrons, but also on the variance of the neutron weights in the detector. The lower the variance, the lower the statistical error. Therefore, the optimization criteria for the adaptive source is to make the neutron weights about equal at the point of optimization. So if a neutron reaches the optimization point with lower-than-avarage weight (or if it is absorbed->weight equals zero), the probability for those initial parameters is reduced, causing a higher initial weight. And vice versa, a neutron with a very high weight will cause an increased probability of its initial parameters, and hence a lower initial weight. Ok, maybe in my case things are slightly different, since I actually change the initial parameter probabilities after every neutron (but only a little bit each time). You mentioned spikes on instrument monitors, and I was not quite sure what you meant. I do see these spikes sometimes with my source. For example if I have a gaussian energy spectrum reflected from a monochromator, and optimize the flux on the sample, the optimization will minimize the statistical error on the value of the total flux. This optimum is obtained by spending most of the computational effort on the center of the energy spectrum, where the neutron weights are large, and less on the tails of the spectrum. Thus the errors in the tails of the energy spectrum will be relatively large, possibly causing spikes in an energy monitor, but the error on the integrated flux will be small. In case one is especially interested in the tails, one should use an optimization criteria that reflects this fact. Maybe we should try to set up the same simulation with both yours and my optimizer and compare the results, that would probably be instructive. What instrument are you using as benchmark? The "in14_6.instr" you sent me? - Kristian. From farhi at ill.fr Fri Oct 8 17:09:44 1999 From: farhi at ill.fr (Farhi) Date: Fri, 08 Oct 1999 17:09:44 +0200 Subject: mcplot mcdisplay Message-ID: <37FE0938.C83FD390@ill.fr> Hy Kristian, I've been trying mcplot and mcdisplay (what I never made before). They are great and run perfectly ! Thanks. I'm now passing to a Flux_adapter in order to simulate a real source from a reference file... EF. -- Emmanuel FARHI, http://www.ill.fr/tas/people/Farhi.html \|/ ____ \|/ TAS-Group, Institut Laue-Langevin (ILL) Grenoble ~@-/ oO \-@~ Avenue des Martyrs, BP 156, 38042 Grenoble Cedex 9,France /_( \__/ )_\ Work :Tel (33/0) 4 76 20 71 83. Fax (33/0) 4 76 48 39 06 \__U_/ La Grande Arche, Chateau d'Uriage, 38410 Saint Martin d'Uriage 04 76 59 73 94 -------------- next part -------------- An HTML attachment was scrubbed... URL: From mja at ansto.gov.au Mon Oct 11 01:49:29 1999 From: mja at ansto.gov.au (JAMES, Michael) Date: Mon, 11 Oct 1999 09:49:29 +1000 Subject: No subject Message-ID: <40BF49FB0D7DD311922000A0C966E30E0E4CE9@pdnt53.anp.ansto.gov.au> Dear Kristian A colleague mentioned that he thought that a new flat monochromator component had been developed to account for secondary extinction. I have searched for this component and have turned-up a blank. Also have you heard of any similar components that account for variations in reflectivity with wavelength ? Thanks Dr Michael James Neutron Scattering Group ANSTO PMB 1 Menai 2234 Australia From kristian.nielsen at risoe.dk Mon Oct 11 14:44:56 1999 From: kristian.nielsen at risoe.dk (Kristian Nielsen) Date: 11 Oct 1999 14:44:56 +0200 Subject: McStas and monochromators In-Reply-To: <40BF49FB0D7DD311922000A0C966E30E0E4CE9@pdnt53.anp.ansto.gov.au> (mja@ansto.gov.au) Message-ID: > Date: Mon, 11 Oct 1999 09:49:29 +1000 > From: "JAMES, Michael" > A colleague mentioned that he thought that a new flat monochromator component had been developed to > account for secondary extinction. I have searched for this component and have turned-up a blank. > Also have you heard of any similar components that account for variations in reflectivity with > wavelength ? We do have a new monochromator in development, and it is close to finished, but not completely finished yet unfortunately. I could send you some code, but given that there are still unresolved issues and no documentation yet I am not sure that it would be useful, unfortunately. The component is designed to handle multiple scattering events inside the crystal, and should correctly handle secondary extinction as well as wavelength dependency. I think the main error compared to a real monochromator is in the modelling of the mosaicity. A gaussian mosaicity is assumed with a large number of small microcrystals. This assumption may not be valid in real mosaic crystals. - Kristian. From rotter at physik.tu-dresden.de Tue Oct 12 15:01:26 1999 From: rotter at physik.tu-dresden.de (martin rotter) Date: Tue, 12 Oct 1999 14:01:26 +0100 Subject: new modules References: <01JGGW4AE4NQ8Y628A@risoe.dk> Message-ID: <38033126.E270F347@physik.tu-dresden.de> > Ok, I am now safely back from Oxford, so here is my latest development > version of McStas. I should warn you that this is all still in the > development phase, so it may not be as stable as the proper > releases. Just ask me if you have any problems. The new version includes > > - The resolution calculation stuff, with some documentation. > - The adaptive importance sampling source Source_adapt.comp. There is a > little bit of documentation in comments in the file and in postscript. > > You will need to install a new version of mcstas, called "mcstas-1.15 > ALPHA". Since this is not of release-quality (yet!), I would like to > know if you pass it on to others. > Dear Kristian Nielsen, thank you very much for this new version of mcstas: I installed it on my computer and tried to simulate my old program, it worked well. Using the adaptive source, however there came the following error messages from the cc compiler (Linux cc)- if you know immediat remedy to this problem, please contact me. I will try meyself to go into the details of this problem. best wishes Martin /root/mcstas.a/lib/Source_adapt.comp: In function cinit': /root/mcstas.a/lib/Source_adapt.comp:100: warning: assignment makes pointer from integer without a cast /root/mcstas.a/lib/Source_adapt.comp: In function craytrace': /root/mcstas.a/lib/Source_adapt.comp:127: dereferencing pointer to incomplete type /root/mcstas.a/lib/Source_adapt.comp:132: dereferencing pointer to incomplete type /root/mcstas.a/lib/Source_adapt.comp:160: dereferencing pointer to incomplete type /root/mcstas.a/lib/Source_adapt.comp:160: dereferencing pointer to incomplete type /root/mcstas.a/lib/Source_adapt.comp:172: dereferencing pointer to incomplete type /root/mcstas.a/lib/Adapt_check.comp:33: ccsource_comp_adpt' undeclared (first use this function) /root/mcstas.a/lib/Adapt_check.comp:33: (Each undeclared identifier is reported only once /root/mcstas.a/lib/Adapt_check.comp:33: for each function it appears in.) /root/mcstas.a/lib/Adapt_check.comp:43: dereferencing pointer to incomplete type /root/mcstas.a/lib/Source_adapt.comp: In function cfinally': /root/mcstas.a/lib/Source_adapt.comp:193: dereferencing pointer to incomplete type /root/mcstas.a/lib/Source_adapt.comp:193: dereferencing pointer to incomplete type -------------- next part -------------- A non-text attachment was scrubbed... Name: vcard.vcf Type: text/x-vcard Size: 460 bytes Desc: Visitenkarte f|r Martin Rotter URL: From kristian.nielsen at risoe.dk Tue Oct 12 14:49:04 1999 From: kristian.nielsen at risoe.dk (Kristian Nielsen) Date: 12 Oct 1999 14:49:04 +0200 Subject: new modules In-Reply-To: <38033126.E270F347@physik.tu-dresden.de> (message from martin rotter on Tue, 12 Oct 1999 14:01:26 +0100) Message-ID: > Date: Tue, 12 Oct 1999 14:01:26 +0100 > From: martin rotter > thank you very much for this new version of mcstas: I installed it on my computer and > tried to simulate my old program, it worked well. Using the adaptive source, however > /root/mcstas.a/lib/Source_adapt.comp:100: warning: assignment makes pointer > from integer without a cast > /root/mcstas.a/lib/Source_adapt.comp:127: dereferencing pointer to > incomplete type These strongly suggest that McStas is picking up the wrong version of the file "mcstas-r.h". In fact, the whole reason for needing the new version of McStas is that this file has been updated for the adaptive source. I can see two possibilities: 1. You tried using the new Source_adapt component with an old version of McStas (try "mcstas --version", it should say 1.15A). 2. You accidentally left an old mcstas-r.h file somewhere where the new McStas picks it up (perhaps the environment variable "MCSTAS" is set to point in the wrong place?). Hope this helps, - Kristian. From cgou at iris.ciae.ac.cn Wed Oct 13 02:41:35 1999 From: cgou at iris.ciae.ac.cn (cgou) Date: Wed, 13 Oct 1999 08:41:35 +0800 Subject: Papers and address Message-ID: <000901bf1513$c35431a0$8f0a26ca@mipsa.ciae.ac.cn> Dear Dr. Kristan, I'm very intrested in McStas, so I want to know about more information of McStas. I loaded your WWW page, and found that you have a paper which will be published.If it is possible ,please send me a copy by mail or Email. Moreover, Whether you know other paper author's mail or email adress, Such as P.Link and A.R.Wildes. I hope I can contact them and get their paper. If you have their address or paper of McStas,Please send them to me. Best Wishes Sun Kai ********************************* Mail address: P.O.Box 275-30, Beijing, P.R.China Email address: cgou at iris.ciae.ac.cn Tel: 86-10-69357727 Fax: 86-10-69357787 From kristian.nielsen at risoe.dk Wed Oct 13 09:00:33 1999 From: kristian.nielsen at risoe.dk (Kristian Nielsen) Date: 13 Oct 1999 09:00:33 +0200 Subject: Papers and address In-Reply-To: <000901bf1513$c35431a0$8f0a26ca@mipsa.ciae.ac.cn> (message from cgou on Wed, 13 Oct 1999 08:41:35 +0800) Message-ID: > Date: Wed, 13 Oct 1999 08:41:35 +0800 > From: cgou > Dear Dr. Kristan, > > I'm very intrested in McStas, so I want to know about more information of > McStas. I loaded your WWW page, and found that you have a paper which will > be published.If it is possible ,please send me a copy by mail or Email. > Moreover, Whether you know other paper author's mail or email adress, Such > as P.Link and A.R.Wildes. I hope I can contact them and get their paper. If > you have their address or paper of McStas,Please send them to me. Thank you for your interest in McStas. I have attached a copy of our paper in postscript format, I hope you will be able to print it. In case of difficulty, I can send you a fax instead. Here are some e-mail addresses: Georg Artus Georg_Artus at Physik.TU-Muenchen.DE Andrew Wildes wildes at ill.fr Peter Link Peter_Link at physik.tu-muenchen.de Hope this helps, - Kristian. -------------- next part -------------- A non-text attachment was scrubbed... Name: mcstas.ps Type: application/postscript Size: 135797 bytes Desc: not available URL: From dfchen at anl.gov Tue Oct 26 22:26:09 1999 From: dfchen at anl.gov (Dongfeng Chen) Date: Tue, 26 Oct 1999 15:26:09 -0500 Subject: Guest account Message-ID: <199910262026.PAA06528@oberon.ctd.anl.gov> Dear Kristian Nielsen, My name is Dongfeng Chen, working in IPNS, Argonne National Lab. I heard form my colleague that there is a MaStas which is useful for instrument design. I am very interested in this software and downloaded it to out Linux. I unpacked correctly I think, but I can not run "make install" smoothly, because I have not superuser privileges. I also try to use --prefix = /.automount/salamander/home/dfchen as the guide, and it did not work either. Would you please give some suggestion about how to install it correctly if I am not superuser. On the other hand, can I have a Riso HP-3000 workstation account on fys-hp-2.risoe.dk if possible? Thanks for your help! Dongfeng Chen From kristian.nielsen at risoe.dk Wed Oct 27 09:01:18 1999 From: kristian.nielsen at risoe.dk (Kristian Nielsen) Date: 27 Oct 1999 09:01:18 +0200 Subject: Guest account In-Reply-To: <199910262026.PAA06528@oberon.ctd.anl.gov> (message from Dongfeng Chen on Tue, 26 Oct 1999 15:26:09 -0500) Message-ID: > Date: Tue, 26 Oct 1999 15:26:09 -0500 > From: Dongfeng Chen > I unpacked correctly I think, but I can not run "make install" smoothly, > because I have not superuser privileges. I also try to use --prefix = > /.automount/salamander/home/dfchen > as the guide, and it did not work either. I assume you already know that there is a running version of McStas installed at the IPNS on the Linux machines in the terminal room? It is used by John Ankner/Frank Close for their SNS reflectometer design; I think Ken Herwig is the one to contact about how to get an account on the machines. Erik Iverson also has a running McStas, I believe. Anyway, to install McStas without superuser privileges, that should not be a problem, but it would help if you gave me some detail of what went wrong, such as the full output of the commands you gave ("./configure", "make", "make install", and "mcstas --version"). The procedure should be simply ./configure --prefix=/.automount/salamander/home/dfchen make clean # Remove old files with wrong prefix make make install (do you really have the dot (".") in that prefix pathname? Also, there must be no spaces around the equals ("=").) The programs will be installed in /.automount/salamander/home/dfchen/bin, so that directory should be in your PATH, ie. setenv PATH $PATH:/.automount/salamander/home/dfchen/bin rehash assuming the shell you use is tcsh. If that does not work, mail me some more details and I will try to sort it out. If all else fails we can probably get you a guest account, but I think you would be better served by a local installation. - Kristian. -- Kristian Nielsen kristian.nielsen at risoe.dk Ris? National Laboratory Condensed Matter Physics and Chemistry Department Tel. +45 4677 5515 Fax +45 4677 4790 From farhi at ill.fr Wed Oct 6 20:14:11 1999 From: farhi at ill.fr (Farhi) Date: Wed, 06 Oct 1999 20:14:11 +0200 Subject: kw_monitor References: <01JGRYJ5M5AQ8WY8MV@risoe.dk> Message-ID: <37FB9173.3BC293EF@ill.fr> Hy Kristian Here are the files for the Optimizer. Yes I use the in14_6 instrument to evaluate the optimizer efficiency. You can plot the kw resolution function at the end. as a reference I also include a in14_6n instrument without optimization. If you got some pbs in compiling, tell me... here follows a Log for a simulation : mcstas in14_6.instr gcc -O2 -o in14_6 in14_6.c -lm farhi at macfarhi Instr:153> in14_6 -n 1e6 KI=2.66 WN=0.03 ORDER=1 MHV=3 Instrument : IN14, v60 (21/09/99) on macfarhi. Flat source, m=3.00 noze, width 0.03 Monochromator : (DM = 3.355) A1 = 20.61, A2 = 41.22 (deg) Ki = 2.66 Angs-1 (Energy = 14.7 meV, Velocity = 1.68e+03 m/s) RM = 0.669 Deg, RH = 0.714 Deg Sample : A3 = 0.00, A4 = 0.00 (deg) Energy transfert 0 meV, Moment transfert 0 Angs-1 Analyser : (DA = 3.355) A5 = 20.61, A6 = 41.22 (deg) Kf = 2.66 Angs-1 (Energy = 14.7 meV, Velocity = 1.68e+03 m/s) RA = 1.21 Deg Detectors : >> OPTIM_PHASE_SET_REF (1000 neutrons) >> AUTO monitor has reached 100 counts (non optimized, absorbed) 0.119690 119690 >> OPTIM_PHASE_SET_SOURCE (119690 neutrons) from Ref Counts : reference = 119690, passing = 119690, monitor = 100 Flux : reference = 1.9e+11, passing = 1.9e+11, monitor = 3.7e+07 >> OPTIM_PHASE_SET_SOURCE (119690 neutrons) Number of redirections : 106379 Counts : reference = 119690, passing = 119690, monitor = 4539 Flux : reference = 1.9e+11, passing = 1.9e+12, monitor = 3.4e+07 >> OPTIM_PHASE_SET_SOURCE (119690 neutrons) Number of redirections : 212824 Counts : reference = 119690, passing = 119690, monitor = 4544 Flux : reference = 1.9e+11, passing = 1.9e+12, monitor = 3.4e+07 >> OPTIM_PHASE_SET_SOURCE (119690 neutrons) Number of redirections : 319299 Counts : reference = 119690, passing = 119690, monitor = 4580 Flux : reference = 1.9e+11, passing = 1.9e+12, monitor = 3.4e+07 >> OPTIM_PHASE_SET_SOURCE (119690 neutrons) Number of redirections : 425880 Counts : reference = 119690, passing = 119690, monitor = 4588 Flux : reference = 1.9e+11, passing = 1.9e+12, monitor = 3.1e+07 >> OPTIM_PHASE_SET_SOURCE (119690 neutrons) Number of redirections : 532178 Counts : reference = 119690, passing = 119690, monitor = 4606 Flux : reference = 1.9e+11, passing = 1.9e+12, monitor = 3.4e+07 >> OPTIM_PHASE_SET_SOURCE (119690 neutrons) Number of redirections : 638681 Counts : reference = 119690, passing = 119690, monitor = 4629 Flux : reference = 1.9e+11, passing = 1.9e+12, monitor = 3.3e+07 >> OPTIM_PHASE_SET_SOURCE (119690 neutrons) Number of redirections : 745164 Counts : reference = 119690, passing = 119690, monitor = 4658 Flux : reference = 1.9e+11, passing = 1.9e+12, monitor = 3.6e+07 End of optimization Optim_Normal_Monitor_Counts = 100 (2 steps), Optim_Total_Monitor_Counts = 32968 Optimizer speedup : 78.9 Number of redirections : 761697 Counts : reference = 119690, passing = 28691, monitor = 724 Flux : reference = 1.9e+11, passing = 1.9e+12, monitor = 6.5e+06 Detector: kw1_I=7.07511e+11 kw1_ERR=1.34359e+10 kw1_N=60746 Detector: PSDSample_I=2.41983e+08 PSDSample_ERR=2.85056e+06 PSDSample_N=32868 Detector: Int4Sample_I=2.3616e+08 Int4Sample_ERR=2.81932e+06 Int4Sample_N=29140 Detector: Flux1Sample_I=3.57466e+07 Flux1Sample_ERR=1.05143e+06 Flux1Sample_N=3677 Detector: ESample_I=3.54956e+07 ESample_ERR=1.04524e+06 ESample_N=3654 Detector: DivSample_I=2.9073e+07 DivSample_ERR=950905 DivSample_N=2399 Detector: kw_I=3.56749e+07 kw_ERR=1.04785e+06 kw_N=3669 Output files : sim/i60_k27w30d1m3.psd sim/i60_k27w30d1m3.nrj sim/i60_k27w30d1m3.div sim/i60_k27w30d1m3.kw Cheers ! -- Emmanuel FARHI, http://www.ill.fr/tas/people/Farhi.html \|/ ____ \|/ TAS-Group, Institut Laue-Langevin (ILL) Grenoble ~@-/ oO \-@~ Avenue des Martyrs, BP 156, 38042 Grenoble Cedex 9,France /_( \__/ )_\ Work :Tel (33/0) 4 76 20 71 83. Fax (33/0) 4 76 48 39 06 \__U_/ La Grande Arche, Chateau d'Uriage, 38410 Saint Martin d'Uriage 04 76 59 73 94 -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- /******************************************************************************* * * McStas, version 1.1, released * Maintained by Kristian Nielsen and Kim Lefmann, * Risoe National Laboratory, Roskilde, Denmark * * Component: Source_Optimizer * * Written by: EF, 17 Sept 1999 * * Usage: A component that optimizes the neutron flux passing through the * Source_optimizer in order to have the maximum flux at the * Monitor_Optimizer position. * * Principle: The optimizer first computes neutron state parameter limits * (step 1), and then records a Reference source (step 2). The optimization then * starts (step 3), and focuses new neutrons on the Monitor_Optimizer. * * Options: The optimized source can be computed regularly ('continuous' option) * or only once ('fixed'). The energy distribution can be kept during optimization * ('keepE') or released ('freeE'). The time spent in steps 1 and 2 can be reduced * for a better optimization ('auto'). The neutrons passing during steps 1 and 2 * can be absorbed for a better neutron weight distribution. * * Source_optimizer should be placed just after the source. * Monitor_Optimizer should be placed at position to optimize. * * INPUT PARAMETERS: * * xmin: Lower x bound of optimizer opening (m) * xmax: Upper x bound of optimizer opening (m) * ymin: Lower y bound of optimizer opening (m) * ymax: Upper y bound of optimizer opening (m) * bins: Number of cells for sampling of neutron state distribution (10 is default) * step: Optimizer step (%, 10 is default) * The two first steps are not optimized. * keep: Percentage of initial source distribution kept (%, 10 is default) * file: Filename where to save optimized source distributions * options: string that can contain * 'continuous' for continuous source optimization (default) * 'fixed' same as 'not continuous' optimization * 'keepE' to keep energy and velocity if pos. (default) * 'freeE' same as 'no keepE' * 'verbose' displays optimization process * 'auto' uses the shortest possible 'step 1' and 'step 2' * and set 'step' as required. Make sure to have * enough neutrons in simulation (ncount) * 'absorb' absorbs step 1 and 2 neutrons if possible. * * parameters bins, step, keep can be -1 for default values. * * OUTPUT PARAMETERS: * * distributions if filename is not empty ("") * * EXAMPLE: I use the following settings * xmin = -0.03, xmax = 0.03, * ymin = -0.06, ymax = 0.06, * bins = -1, step = -1, keep = -1, * file="source.optim", * options="absorb+auto" * *******************************************************************************/ /* History : Sep 17 1999 : v0.00 first release (not effective) Sep 26 1999 : v0.01 New_Source for continuous optimisation Sep 27 1999 : optimizer is ok, but not efficient Sep 29 1999 : v0.02 re-direct 'bad' neutrons instead of ABSORB (rand generator for nothing) */ DEFINE COMPONENT Source_Optimizer DEFINITION PARAMETERS (xmin, xmax, ymin, ymax, bins, step, keep,file,options) SETTING PARAMETERS () STATE PARAMETERS (x,y,z,vx,vy,vz,t,s1,s2,p) DECLARE %{ #ifndef MCSTAS_GEN_OPTIM /* McStas General optimizer ID */ #define MCSTAS_GEN_OPTIM #else #error McStas : Source_Optimizer should only be used once per instrument #endif #ifndef FLT_MAX #define FLT_MAX 1e37 #endif #define OPTIM_PHASE_SET_LIMITS 0 /* set array limits to 0, then ask for GET_LIMITS */ #define OPTIM_PHASE_GET_LIMITS 1 /* compute array limits, then ask for SET_REF */ #define OPTIM_PHASE_SET_REF 2 /* set Ref and New_Source to to 0, then ask for GET_REF */ #define OPTIM_PHASE_GET_REF 3 /* compute Ref (and New_Source in Monitor), then ask for SET_SOURCE */ #define OPTIM_PHASE_SET_SOURCE 4 /* set Source to Ref*x%+New_Source, normalize to Ref, Passing to 0, then ask for OPTIM */ #define OPTIM_PHASE_OPTIM 5 /* Optimize and get New_Source (continuous optimization), then reask SET_SOURCE when required */ #define OPTIM_MOD_X 1 #define OPTIM_MOD_Y 2 #define OPTIM_MOD_VX 4 #define OPTIM_MOD_VY 8 #define OPTIM_MOD_VZ 16 #define OPTIM_MOD_S1 32 #define OPTIM_MOD_S2 64 #define OPTIM_MOD_P 128 /* These are distribution arrays[bins] within limits * flux is kept during optimisation * NOT stored : z is the position of this component * t time (linked to z) */ /* initial Reference distribution arrays (for weights) */ long *Optim_Reference_x; long *Optim_Reference_y; long *Optim_Reference_vx; long *Optim_Reference_vy; long *Optim_Reference_vz; long *Optim_Reference_s1; long *Optim_Reference_s2; long *Optim_Reference_p; /* optimized Source distribution arrays (to reach) */ long *Optim_Source_x; long *Optim_Source_y; long *Optim_Source_vx; long *Optim_Source_vy; long *Optim_Source_vz; long *Optim_Source_s1; long *Optim_Source_s2; long *Optim_Source_p; /* optimized New_Source distribution arrays (to reach in next step, passed to Source) */ long *Optim_New_Source_x; long *Optim_New_Source_y; long *Optim_New_Source_vx; long *Optim_New_Source_vy; long *Optim_New_Source_vz; long *Optim_New_Source_s1; long *Optim_New_Source_s2; long *Optim_New_Source_p; /* Passing distribution arrays (should grow to reach Source) */ long *Optim_Passing_x; long *Optim_Passing_y; long *Optim_Passing_vx; long *Optim_Passing_vy; long *Optim_Passing_vz; long *Optim_Passing_s1; long *Optim_Passing_s2; long *Optim_Passing_p; /* limits for state parameters */ /* x and y are Optimizer dimensions (input parameters) */ double Optim_x_min, Optim_x_max; double Optim_y_min, Optim_y_max; double Optim_vx_min, Optim_vx_max; double Optim_vy_min, Optim_vy_max; double Optim_vz_min, Optim_vz_max; double Optim_s1_min, Optim_s1_max; double Optim_s2_min, Optim_s2_max; double Optim_p_min, Optim_p_max; int Optim_index=0; /* a running Optim_index */ int Optim_index_x=0; /* indexes for last neutron that passed through */ int Optim_index_y=0; int Optim_index_vx=0; int Optim_index_vy=0; int Optim_index_vz=0; int Optim_index_s1=0; int Optim_index_s2=0; int Optim_index_p=0; int Optim_good_x=0; /* indexes for last 'good' neutron that passed through */ int Optim_good_y=0; int Optim_good_vx=0; int Optim_good_vy=0; int Optim_good_vz=0; int Optim_good_s1=0; int Optim_good_s2=0; int Optim_good_p=0; int Optim_bins; long Optim_n_redirect; /* number of consecutive ABSORB */ int Optim_Phase; /* Optimizer function */ long Optim_Phase_Counts =0; /* neutron counts to achieve in each Phase */ long Optim_Phase_Counts_L =0; /* neutron counts to achieve in Limits Phase */ long Optim_Phase_Counts_R =0; /* neutron counts to achieve in Reference Phase */ char Optim_Flag_Continuous =0; /* 1 : continuous Source optimization */ char Optim_Flag_Recycle =0; /* record of neutron state changes by OPTIM_MOD_xx */ char Optim_Flag_KeepE =0; /* 1 : keep E as poss. when recycling */ /* i.e. keep E and |v| distribution */ char Optim_Flag_Verbose =0; /* displays optimization informations */ char Optim_Flag_Absorb =0; /* 1 means that first steps non optimized neutrons are absorbed */ char Optim_Flag_Auto =0; /* 1 is for minimum counts in 2 first steps */ long Optim_Limits_Counts =0; /* passing neutron counts in each Optim_Phase */ long Optim_Reference_Counts =0; long Optim_Passing_Counts =0; long Optim_Monitor_Counts =0; double Optim_Limits_Flux =0; /* passing neutron flux in each Optim_Phase */ double Optim_Reference_Flux=0; double Optim_Passing_Flux =0; double Optim_Monitor_Flux =0; double Optim_Monitor_pmax =0; float Optim_keep; float Optim_step; double Optim_vx; /* save neutron characteristics for Monitor and ABSORDed->Redirected neutrons */ double Optim_vy; double Optim_vz; double Optim_x; double Optim_y; double Optim_s1; double Optim_s2; double Optim_p; double Optim_v2; double Optim_t1; /* tempo vars */ double Optim_t2; double Optim_t3; double Optim_u1; /* tempo vars */ double Optim_u2; double Optim_u3; int Optim_i1; /* tempo vars */ int Optim_i2; int Optim_i3; long Optim_Normal_Monitor_Counts = 0; /* counts without optim */ long Optim_Total_Monitor_Counts =0; /* final monitor counts */ FILE *hfile; /* end declare */ %} INITIALIZE %{ Optim_n_redirect = 0; Optim_Phase = OPTIM_PHASE_SET_LIMITS; Optim_x_min = xmin; Optim_x_max = xmax; Optim_y_min = ymin; Optim_y_max = ymax; Optim_bins = (int)bins; Optim_step = step; Optim_keep = keep; if (Optim_step < 0) Optim_step = .1; /* default values if -1 is given */ if (Optim_bins < 0) Optim_bins = 10; if (Optim_keep < 0) Optim_keep = .1; if (Optim_step >= 1) Optim_step = Optim_step/100; /* in case user gives % in 1-100 */ if (Optim_step < .01) Optim_step = .01; if (Optim_step > 1) Optim_step = 1; if (Optim_keep >= 1) Optim_keep = Optim_keep/100; /* in case user gives % in 1-100 */ if (Optim_keep < .01) Optim_keep = .01; if (Optim_keep > 1) Optim_keep = 1; Optim_Phase_Counts = mcget_ncount() * Optim_step; Optim_Phase_Counts_L = Optim_Phase_Counts; Optim_Phase_Counts_R = Optim_Phase_Counts; if (Optim_bins < 1) Optim_bins = 1; if (Optim_bins > 100) Optim_bins = 100; if (strstr(options,"continuous")) Optim_Flag_Continuous = 1; if (strstr(options,"fixed")) Optim_Flag_Continuous = 0; if (strstr(options,"keepE")) Optim_Flag_KeepE = 1; if (strstr(options,"freeE")) Optim_Flag_KeepE = 0; if (strstr(options,"verbose")) Optim_Flag_Verbose = 1; if (strstr(options,"auto")) { Optim_Flag_Auto = 1; if (Optim_bins*10 < Optim_Phase_Counts) Optim_Phase_Counts_L = Optim_bins*100; /* need at least 10 counts per bin for Limits */ Optim_Phase_Counts_R = mcget_ncount(); Optim_Phase_Counts = mcget_ncount(); } if (strstr(options,"absorb")) Optim_Flag_Absorb = 1; if ((Optim_Source_x = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_Source_y = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_Source_vx = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_Source_vy = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_Source_vz = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_Source_s1 = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_Source_s2 = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_Source_p = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_New_Source_x = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_New_Source_y = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_New_Source_vx = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_New_Source_vy = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_New_Source_vz = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_New_Source_s1 = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_New_Source_s2 = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_New_Source_p = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_Passing_x = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_Passing_y = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_Passing_vx = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_Passing_vy = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_Passing_vz = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_Passing_s1 = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_Passing_s2 = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_Passing_p = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_Reference_x = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_Reference_y = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_Reference_vx = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_Reference_vy = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_Reference_vz = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_Reference_s1 = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_Reference_s2 = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_Reference_p = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } /* end initialize */ %} TRACE %{ PROP_Z0; if (x>Optim_x_min && xOptim_y_min && y= Optim_Phase_Counts_L)) { Optim_Phase = OPTIM_PHASE_SET_REF; if (Optim_Flag_Verbose) printf(">> OPTIM_PHASE_SET_REF (%i neutrons)\n", Optim_Limits_Counts); } if ((Optim_Phase == OPTIM_PHASE_GET_REF) && (Optim_Reference_Counts >= Optim_Phase_Counts_R)) { Optim_Phase = OPTIM_PHASE_SET_SOURCE; Optim_Phase_Counts_R = Optim_Phase_Counts; if (Optim_Flag_Verbose) { printf(">> OPTIM_PHASE_SET_SOURCE (%i neutrons) from Ref\n", Optim_Reference_Counts); printf("Counts : reference = %i, passing = %i, monitor = %i\n", Optim_Reference_Counts, Optim_Reference_Counts, Optim_Monitor_Counts); printf("Flux : reference = %.2g, passing = %.2g, monitor = %.2g\n", Optim_Reference_Flux, Optim_Reference_Flux, Optim_Monitor_Flux); } } if ((Optim_Phase == OPTIM_PHASE_OPTIM) && (Optim_Passing_Counts >= Optim_Phase_Counts)) { Optim_Phase = OPTIM_PHASE_SET_SOURCE; if (Optim_Flag_Verbose) { printf(">> OPTIM_PHASE_SET_SOURCE (%i neutrons)\n", Optim_Passing_Counts); printf("Number of redirections : %i\n",Optim_n_redirect); printf("Counts : reference = %i, passing = %i, monitor = %i\n", Optim_Reference_Counts, Optim_Passing_Counts, Optim_Monitor_Counts); printf("Flux : reference = %.2g, passing = %.2g, monitor = %.2g\n", Optim_Reference_Flux, Optim_Passing_Flux, Optim_Monitor_Flux); } } /* handle Optim_Phase functions */ if (Optim_Phase == OPTIM_PHASE_SET_LIMITS) /* init : need to compute limits and flux */ { Optim_Limits_Counts = 0; Optim_Limits_Flux = 0; Optim_vx_min = FLT_MAX; Optim_vx_max = -FLT_MAX; Optim_vy_min = FLT_MAX; Optim_vy_max = -FLT_MAX; Optim_vz_min = FLT_MAX; Optim_vz_max = -FLT_MAX; Optim_s1_min = FLT_MAX; Optim_s1_max = -FLT_MAX; Optim_s2_min = FLT_MAX; Optim_s2_max = -FLT_MAX; Optim_p_min = FLT_MAX; Optim_p_max = -FLT_MAX; Optim_Phase = OPTIM_PHASE_GET_LIMITS; } /* end OPTIM_PHASE_SET_LIMITS */ if (Optim_Phase == OPTIM_PHASE_GET_LIMITS) /* init : need to compute limits and flux */ { Optim_Limits_Counts++; Optim_Limits_Flux += p; if (x < Optim_x_min) Optim_x_min = x; if (y < Optim_y_min) Optim_y_min = y; if (x > Optim_x_max) Optim_x_max = x; if (y > Optim_y_max) Optim_y_max = y; if (vx < Optim_vx_min) Optim_vx_min = vx; if (vx > Optim_vx_max) Optim_vx_max = vx; if (vy < Optim_vy_min) Optim_vy_min = vy; if (vy > Optim_vy_max) Optim_vy_max = vy; if (vz < Optim_vz_min) Optim_vz_min = vz; if (vz > Optim_vz_max) Optim_vz_max = vz; if (p < Optim_p_min) Optim_p_min = p; if (p > Optim_p_max) Optim_p_max = p; if (s1 < Optim_s1_min) Optim_s1_min = s1; if (s1 > Optim_s1_max) Optim_s1_max = s1; if (s2 < Optim_s2_min) Optim_s2_min = s2; if (s2 > Optim_s2_max) Optim_s2_max = s2; if (Optim_Flag_Absorb) ABSORB; } /* end if OPTIM_PHASE_GET_LIMITS */ if (Optim_Phase == OPTIM_PHASE_SET_REF) /* Set Ref and New_Source to 0 */ { Optim_Reference_Counts = 0; Optim_Reference_Flux = 0; Optim_Monitor_Counts = 0; /* also counted as New_Source */ Optim_Monitor_Flux = 0; for (Optim_index=0; Optim_index < Optim_bins; Optim_index++) { Optim_Reference_x[Optim_index] = 0; /* initial distribution will be recorded first */ Optim_Reference_y[Optim_index] = 0; Optim_Reference_vx[Optim_index] = 0; Optim_Reference_vy[Optim_index] = 0; Optim_Reference_vz[Optim_index] = 0; Optim_Reference_s1[Optim_index] = 0; Optim_Reference_s2[Optim_index] = 0; Optim_Reference_p[Optim_index] = 0; Optim_New_Source_x[Optim_index] = 0; /* Monitor_Optimizer will compute the */ Optim_New_Source_y[Optim_index] = 0; /* optimized New_Source distribution */ Optim_New_Source_vx[Optim_index] = 0; /* that will become Source for Optim Optim_step */ Optim_New_Source_vy[Optim_index] = 0; Optim_New_Source_vz[Optim_index] = 0; Optim_New_Source_s1[Optim_index] = 0; Optim_New_Source_s2[Optim_index] = 0; Optim_New_Source_p[Optim_index] = 0; } /* end for */ Optim_Phase = OPTIM_PHASE_GET_REF; } /* end OPTIM_PHASE_SET_REF */ if (Optim_Phase == OPTIM_PHASE_GET_REF) /* now build the Reference in limits */ { /* New_Source is set by Monitor_Optimizer */ Optim_Reference_Counts++; Optim_Reference_Flux += p; if (Optim_vx_max-Optim_vx_min) Optim_index = (int)rint(Optim_bins * (vx -Optim_vx_min)/(Optim_vx_max-Optim_vx_min)); else Optim_index = 0; if (Optim_index < 0) Optim_index = 0; if (Optim_index >= Optim_bins) Optim_index = Optim_bins - 1; Optim_Reference_vx[Optim_index]++; if (Optim_vy_max-Optim_vy_min) Optim_index = (int)rint(Optim_bins * (vy -Optim_vy_min)/(Optim_vy_max-Optim_vy_min)); else Optim_index = 0; if (Optim_index < 0) Optim_index = 0; if (Optim_index >= Optim_bins) Optim_index = Optim_bins - 1; Optim_Reference_vy[Optim_index]++; if (Optim_vz_max-Optim_vz_min) Optim_index = (int)rint(Optim_bins * (vz -Optim_vz_min)/(Optim_vz_max-Optim_vz_min)); else Optim_index = 0; if (Optim_index < 0) Optim_index = 0; if (Optim_index >= Optim_bins) Optim_index = Optim_bins - 1; Optim_Reference_vz[Optim_index]++; if (Optim_x_max-Optim_x_min) Optim_index = (int)rint(Optim_bins * (x -Optim_x_min)/(Optim_x_max-Optim_x_min)); else Optim_index = 0; if (Optim_index < 0) Optim_index = 0; if (Optim_index >= Optim_bins) Optim_index = Optim_bins - 1; Optim_Reference_x[Optim_index]++; if (Optim_y_max-Optim_y_min) Optim_index = (int)rint(Optim_bins * (y -Optim_y_min)/(Optim_y_max-Optim_y_min)); else Optim_index = 0; if (Optim_index < 0) Optim_index = 0; if (Optim_index >= Optim_bins) Optim_index = Optim_bins - 1; Optim_Reference_y[Optim_index]++; if (Optim_s1_max-Optim_s1_min) Optim_index = (int)rint(Optim_bins * (s1 -Optim_s1_min)/(Optim_s1_max-Optim_s1_min)); else Optim_index = 0; if (Optim_index < 0) Optim_index = 0; if (Optim_index >= Optim_bins) Optim_index = Optim_bins - 1; Optim_Reference_s1[Optim_index]++; if (Optim_s2_max-Optim_s2_min) Optim_index = (int)rint(Optim_bins * (s2 -Optim_s2_min)/(Optim_s2_max-Optim_s2_min)); else Optim_index = 0; if (Optim_index < 0) Optim_index = 0; if (Optim_index >= Optim_bins) Optim_index = Optim_bins - 1; Optim_Reference_s2[Optim_index]++; if (Optim_p_max-Optim_p_min) Optim_index = (int)rint(Optim_bins * (p -Optim_p_min)/(Optim_p_max-Optim_p_min)); else Optim_index = 0; if (Optim_index < 0) Optim_index = 0; if (Optim_index >= Optim_bins) Optim_index = Optim_bins - 1; Optim_Reference_p[Optim_index]++; } /* end if OPTIM_PHASE_GET_REF */ if (Optim_Phase == OPTIM_PHASE_SET_SOURCE) /* Define optimized Source (normalized to Reference) */ { if (Optim_Monitor_Counts) Optim_t1 = (1 - Optim_keep) * Optim_Reference_Counts/Optim_Monitor_Counts; else Optim_t1 = 0; Optim_Passing_Counts = 0; Optim_Passing_Flux = 0; if (Optim_Normal_Monitor_Counts == 0) Optim_Normal_Monitor_Counts = Optim_Total_Monitor_Counts; /* 2 first un-optimized steps */ Optim_Monitor_Counts = 0; /* also counted as New_Source */ Optim_Monitor_Flux = 0; for (Optim_index = 0; Optim_index < Optim_bins; Optim_index++) { /* get Optim_keep % of Reference, and 1-Optim_keep% of New_Source normalized to Reference Counts */ if (Optim_Flag_Continuous | (Optim_n_redirect == 0)) { Optim_Source_x[Optim_index] = (long)(rint(Optim_keep * Optim_Reference_x[Optim_index]) + Optim_t1 * Optim_New_Source_x[Optim_index] ); Optim_Source_y[Optim_index] = (long)(rint(Optim_keep * Optim_Reference_y[Optim_index]) + Optim_t1 * Optim_New_Source_y[Optim_index] ); Optim_Source_vx[Optim_index] = (long)(rint(Optim_keep * Optim_Reference_vx[Optim_index]) + Optim_t1 * Optim_New_Source_vx[Optim_index] ); Optim_Source_vy[Optim_index] = (long)(rint(Optim_keep * Optim_Reference_vy[Optim_index]) + Optim_t1 * Optim_New_Source_vy[Optim_index] ); Optim_Source_vz[Optim_index] = (long)(rint(Optim_keep * Optim_Reference_vz[Optim_index]) + Optim_t1 * Optim_New_Source_vz[Optim_index] ); Optim_Source_s1[Optim_index] = (long)(rint(Optim_keep * Optim_Reference_s1[Optim_index]) + Optim_t1 * Optim_New_Source_s1[Optim_index] ); Optim_Source_s2[Optim_index] = (long)(rint(Optim_keep * Optim_Reference_s2[Optim_index]) + Optim_t1 * Optim_New_Source_s2[Optim_index] ); Optim_Source_p[Optim_index] = (long)(rint(Optim_keep * Optim_Reference_p[Optim_index]) + Optim_t1 * Optim_New_Source_p[Optim_index] ); if (Optim_New_Source_x[Optim_index] > Optim_New_Source_x[Optim_good_x]) Optim_good_x = Optim_index; if (Optim_New_Source_y[Optim_index] > Optim_New_Source_y[Optim_good_y]) Optim_good_y = Optim_index; if (Optim_New_Source_vx[Optim_index] > Optim_New_Source_vx[Optim_good_vx]) Optim_good_vx = Optim_index; if (Optim_New_Source_vy[Optim_index] > Optim_New_Source_vy[Optim_good_vy]) Optim_good_vy = Optim_index; if (Optim_New_Source_vz[Optim_index] > Optim_New_Source_vz[Optim_good_vz]) Optim_good_vz = Optim_index; if (Optim_New_Source_s1[Optim_index] > Optim_New_Source_s1[Optim_good_s1]) Optim_good_s1 = Optim_index; if (Optim_New_Source_s2[Optim_index] > Optim_New_Source_s2[Optim_good_s2]) Optim_good_s2 = Optim_index; if (Optim_New_Source_p[Optim_index] > Optim_New_Source_p[Optim_good_p]) Optim_good_p = Optim_index; } Optim_Passing_x[Optim_index] = 0; /* Passing neutrons will then reach Source */ Optim_Passing_y[Optim_index] = 0; /* weights will be adapted to match Reference */ Optim_Passing_vx[Optim_index] = 0; Optim_Passing_vy[Optim_index] = 0; Optim_Passing_vz[Optim_index] = 0; Optim_Passing_s1[Optim_index] = 0; Optim_Passing_s2[Optim_index] = 0; Optim_Passing_p[Optim_index] = 0; Optim_New_Source_x[Optim_index] = 0; /* Init of next Source */ Optim_New_Source_y[Optim_index] = 0; Optim_New_Source_vx[Optim_index] = 0; Optim_New_Source_vy[Optim_index] = 0; Optim_New_Source_vz[Optim_index] = 0; Optim_New_Source_s1[Optim_index] = 0; Optim_New_Source_s2[Optim_index] = 0; Optim_New_Source_p[Optim_index] = 0; } /* end for */ Optim_Phase = OPTIM_PHASE_OPTIM; } /* end OPTIM_PHASE_SET_SOURCE */ if (Optim_Phase == OPTIM_PHASE_OPTIM) /* Use optimized Source */ { Optim_Flag_Recycle = 0; Optim_index_x = Optim_good_x; Optim_index_y = Optim_good_y; Optim_index_vx= Optim_good_vx; Optim_index_vy= Optim_good_vy; Optim_index_vz= Optim_good_vz; Optim_index_s1= Optim_good_s1; Optim_index_s2= Optim_good_s2; Optim_index_p = Optim_good_p; if (Optim_vz_max-Optim_vz_min) Optim_index = (int)rint(Optim_bins * (vz -Optim_vz_min)/(Optim_vz_max-Optim_vz_min)); else Optim_index = 0; if (Optim_index < 0) Optim_index = 0; if (Optim_index >= Optim_bins) Optim_index = Optim_bins - 1; if (Optim_Passing_vz[Optim_index] >= Optim_Source_vz[Optim_index]) { Optim_Flag_Recycle |= OPTIM_MOD_VX; Optim_vz += (Optim_index_vz-Optim_index)*(Optim_vz_max - Optim_vz_min)/Optim_bins; } else Optim_index_vz = Optim_index; if (Optim_vx_max-Optim_vx_min) Optim_index = (int)rint(Optim_bins * (vx -Optim_vx_min)/(Optim_vx_max-Optim_vx_min)); else Optim_index = 0; if (Optim_index < 0) Optim_index = 0; if (Optim_index >= Optim_bins) Optim_index = Optim_bins - 1; if (Optim_Passing_vx[Optim_index] >= Optim_Source_vx[Optim_index]) /* distribution achieved : redirect neutron near last neutron characteristic */ { Optim_Flag_Recycle |= OPTIM_MOD_VY; Optim_vx += (Optim_index_vx-Optim_index)*(Optim_vx_max - Optim_vx_min)/Optim_bins; } else Optim_index_vx = Optim_index; if (Optim_vy_max-Optim_vy_min) Optim_index = (int)rint(Optim_bins * (vy -Optim_vy_min)/(Optim_vy_max-Optim_vy_min)); else Optim_index = 0; if (Optim_index < 0) Optim_index = 0; if (Optim_index >= Optim_bins) Optim_index = Optim_bins - 1; if (Optim_Passing_vy[Optim_index] >= Optim_Source_vy[Optim_index]) { Optim_Flag_Recycle |= OPTIM_MOD_VZ; Optim_vy += (Optim_index_vy-Optim_index)*(Optim_vy_max - Optim_vy_min)/Optim_bins; } else Optim_index_vy = Optim_index; if ((Optim_Flag_Recycle & (OPTIM_MOD_VX|OPTIM_MOD_VY|OPTIM_MOD_VZ)) && Optim_Flag_KeepE) { /* now try to keep E distribution */ Optim_t1 = Optim_v2 - Optim_vz*Optim_vz - Optim_vy*Optim_vy; Optim_t2 = Optim_v2 - Optim_vz*Optim_vz - Optim_vx*Optim_vx; Optim_t3 = Optim_v2 - Optim_vx*Optim_vx - Optim_vy*Optim_vy; /* we affect the component wich is the most optimized (largest Source/Ref) */ if ((Optim_vx_max-Optim_vx_min) && (Optim_t1 > 0)) { Optim_t1 = sqrt(Optim_t1); if (vx < 0) Optim_t1 = -Optim_t1; Optim_i1 = (int)rint(Optim_bins * (Optim_t1 -Optim_vx_min)/(Optim_vx_max-Optim_vx_min)); if (Optim_i1 < 0) Optim_i1 = 0; if (Optim_i1 >= Optim_bins) Optim_i1 = Optim_bins - 1; Optim_u1 = (double)Optim_Source_vx[Optim_i1]/(Optim_Reference_vx[Optim_i1]+1); } else Optim_u1 = 0; if ((Optim_vy_max-Optim_vy_min) && (Optim_t2 > 0)) { Optim_t2 = sqrt(Optim_t2); if (vy < 0) Optim_t2 = -Optim_t2; Optim_i2 = (int)rint(Optim_bins * (Optim_t2 -Optim_vy_min)/(Optim_vy_max-Optim_vy_min)); if (Optim_i2 < 0) Optim_i2 = 0; if (Optim_i2 >= Optim_bins) Optim_i2 = Optim_bins - 1; Optim_u2 = (double)Optim_Source_vy[Optim_i2]/(Optim_Reference_vy[Optim_i2]+1); } else Optim_u2 = 0; if ((Optim_vz_max-Optim_vz_min) && (Optim_t3 > 0)) { Optim_t3 = sqrt(Optim_t3); if (vz < 0) Optim_t3 = -Optim_t3; Optim_i3 = (int)rint(Optim_bins * (Optim_t3 -Optim_vz_min)/(Optim_vz_max-Optim_vz_min)); if (Optim_i3 < 0) Optim_i3 = 0; if (Optim_i3 >= Optim_bins) Optim_i3 = Optim_bins - 1; Optim_u3 = (double)Optim_Source_vz[Optim_i3]/(Optim_Reference_vz[Optim_i3]+1); } else Optim_u3 = 0; if ((Optim_u1 > Optim_u2) && (Optim_u1 > Optim_u3)) { Optim_vx = Optim_t1; Optim_index_vx = Optim_i1; Optim_Flag_Recycle |= OPTIM_MOD_VX; Optim_index = -1; } if ((Optim_u2 > Optim_u1) && (Optim_u2 > Optim_u3) ) { Optim_vy = Optim_t2; Optim_index_vy = Optim_i2; Optim_Flag_Recycle |= OPTIM_MOD_VY; Optim_index = -1; } if ((Optim_u3 > Optim_u1) && (Optim_u3 > Optim_u1)) { Optim_vz = Optim_t3; Optim_index_vz = Optim_i3; Optim_Flag_Recycle |= OPTIM_MOD_VZ; Optim_index = -1; } } vx = Optim_vx; vy = Optim_vy; vz = Optim_vz; if (Optim_x_max-Optim_x_min) Optim_index = (int)rint(Optim_bins * (x -Optim_x_min)/(Optim_x_max-Optim_x_min)); else Optim_index = 0; if (Optim_index < 0) Optim_index = 0; if (Optim_index >= Optim_bins) Optim_index = Optim_bins - 1; if (Optim_Passing_x[Optim_index] >= Optim_Source_x[Optim_index]) { Optim_Flag_Recycle |= OPTIM_MOD_X; Optim_x += (Optim_index_x-Optim_index)*(Optim_x_max - Optim_x_min)/Optim_bins; x = Optim_x; } else Optim_index_x = Optim_index; if (Optim_y_max-Optim_y_min) Optim_index = (int)rint(Optim_bins * (y -Optim_y_min)/(Optim_y_max-Optim_y_min)); else Optim_index = 0; if (Optim_index < 0) Optim_index = 0; if (Optim_index >= Optim_bins) Optim_index = Optim_bins - 1; if (Optim_Passing_y[Optim_index] >= Optim_Source_y[Optim_index]) { Optim_Flag_Recycle |= OPTIM_MOD_Y; Optim_y += (Optim_index_y-Optim_index)*(Optim_y_max - Optim_y_min)/Optim_bins; y = Optim_y; } else Optim_index_y = Optim_index; if (Optim_s1_max-Optim_s1_min) Optim_index = (int)rint(Optim_bins * (s1 -Optim_s1_min)/(Optim_s1_max-Optim_s1_min)); else Optim_index = 0; if (Optim_index < 0) Optim_index = 0; if (Optim_index >= Optim_bins) Optim_index = Optim_bins - 1; if (Optim_Passing_s1[Optim_index] >= Optim_Source_s1[Optim_index]) { Optim_Flag_Recycle |= OPTIM_MOD_S1; Optim_s1 += (Optim_index_s1-Optim_index)*(Optim_s1_max - Optim_s1_min)/Optim_bins; s1 = Optim_s1; } else Optim_index_s1 = Optim_index; if (Optim_s2_max-Optim_s2_min) Optim_index = (int)rint(Optim_bins * (s2 -Optim_s2_min)/(Optim_s2_max-Optim_s2_min)); else Optim_index = 0; if (Optim_index < 0) Optim_index = 0; if (Optim_index >= Optim_bins) Optim_index = Optim_bins - 1; if (Optim_Passing_s2[Optim_index] >= Optim_Source_s2[Optim_index]) { Optim_Flag_Recycle |= OPTIM_MOD_S2; Optim_s2 += (Optim_index_s2-Optim_index)*(Optim_s2_max - Optim_s2_min)/Optim_bins; s2 = Optim_s2; } else Optim_index_s2 = Optim_index; if (Optim_p_max-Optim_p_min) Optim_index = (int)rint(Optim_bins * (p -Optim_p_min)/(Optim_p_max-Optim_p_min)); else Optim_index = 0; if (Optim_index < 0) Optim_index = 0; if (Optim_index >= Optim_bins) Optim_index = Optim_bins - 1; if (Optim_Passing_p[Optim_index] >= Optim_Source_p[Optim_index]) { Optim_Flag_Recycle |= OPTIM_MOD_P; Optim_p += (Optim_index_p-Optim_index)*(Optim_p_max - Optim_p_min)/Optim_bins; p = Optim_p; } else Optim_index_p = Optim_index; /* neutron is passed ! */ if (Optim_Source_vx[Optim_index_vx] && Optim_Source_vy[Optim_index_vy] && Optim_Source_vz[Optim_index_vz] && Optim_Source_x[Optim_index_x] && Optim_Source_y[Optim_index_y] && Optim_Source_s1[Optim_index_s1] && Optim_Source_s2[Optim_index_s2] && Optim_Source_p[Optim_index_p] && Optim_Reference_vx[Optim_index_vx] && Optim_Reference_vy[Optim_index_vy] && Optim_Reference_vz[Optim_index_vz] && Optim_Reference_x[Optim_index_x] && Optim_Reference_y[Optim_index_y] && Optim_Reference_s1[Optim_index_s1] && Optim_Reference_s2[Optim_index_s2] && Optim_Reference_p[Optim_index_p]) { Optim_t1 = 1; /* good neutrons have an improved distribution, so Ref/Source < 1 */ /* unmodified (form Ref kept fraction) neutrons have Passing < Ref*Optim_keep. their weight should be kept */ /* at the end there will be of those : 2*Optim_step*Optim_keep + (1-2*Optim_step)*Optim_keep = Optim_keep % of unmodified neutrons */ /* the remining part (1-Optim_keep neutrons) should have an integrated flux of (1-Optim_keep) */ Optim_t2 = (double)Optim_Reference_vx[Optim_index_vx]/Optim_Source_vx[Optim_index_vx]; if (Optim_t2 < 1) Optim_good_vx = Optim_index_vx; Optim_t1 *= Optim_t2; Optim_t2 = (double)Optim_Reference_vy[Optim_index_vy]/Optim_Source_vy[Optim_index_vy]; if (Optim_t2 < 1) Optim_good_vy = Optim_index_vy; Optim_t1 *= Optim_t2; Optim_t2 = (double)Optim_Reference_vz[Optim_index_vz]/Optim_Source_vz[Optim_index_vz]; if (Optim_t2 < 1) Optim_good_vz = Optim_index_vz; Optim_t1 *= Optim_t2; Optim_t2 = (double)Optim_Reference_x[Optim_index_x]/Optim_Source_x[Optim_index_x]; if (Optim_t2 < 1) Optim_good_x = Optim_index_x; Optim_t1 *= Optim_t2; Optim_t2 = (double)Optim_Reference_y[Optim_index_y]/Optim_Source_y[Optim_index_y]; if (Optim_t2 < 1) Optim_good_y = Optim_index_y; Optim_t1 *= Optim_t2; Optim_t2 = (double)Optim_Reference_s1[Optim_index_s1]/Optim_Source_s1[Optim_index_s1]; if (Optim_t2 < 1) Optim_good_s1= Optim_index_s1; Optim_t1 *= Optim_t2; Optim_t2 = (double)Optim_Reference_s2[Optim_index_s2]/Optim_Source_s2[Optim_index_s2]; if (Optim_t2 < 1) Optim_good_s2= Optim_index_s2; Optim_t1 *= Optim_t2; Optim_t2 = (double)Optim_Reference_p[Optim_index_p]/Optim_Source_p[Optim_index_p]; if (Optim_t2 < 1) Optim_good_p = Optim_index_p; Optim_t1 *= Optim_t2; /* now normalize to intial distribution */ Optim_p *= Optim_t1; if (Optim_Flag_Recycle) { Optim_n_redirect++; } /* Optim_p /= Optim_Flag_Recycle; */ p = Optim_p; } else ABSORB; /* can't modify neutron weight -> eject */ Optim_Passing_vx[Optim_index_vx]++; Optim_Passing_vy[Optim_index_vy]++; Optim_Passing_vz[Optim_index_vz]++; Optim_Passing_x[Optim_index_x]++; Optim_Passing_y[Optim_index_y]++; Optim_Passing_s1[Optim_index_s1]++; Optim_Passing_s2[Optim_index_s2]++; Optim_Passing_p[Optim_index_p]++; Optim_Passing_Counts++; Optim_Passing_Flux += p; } /* end if OPTIM_PHASE_OPTIM */ } /* end if xy in optimizer */ /* end trace */ %} FINALLY %{ if (strlen(file) > 0) { hfile = fopen(file, "w"); if(!hfile) { fprintf(stderr, "Error: %s : could not open output file '%s'\n", mccompcurname, file); } else { fprintf(hfile,"# Instrument-source: %s\n", mcinstrument_source); mcruninfo_out("# ", hfile); fprintf(hfile,"# type: array_2d(%i,6) \n",Optim_bins); fprintf(hfile,"# component: %s\n", mccompcurname); fprintf(hfile,"# title: General Optimizer distributions\n"); fprintf(hfile,"# filename: '%s'\n",file); fprintf(hfile,"# variables: x dx y dy vx dvx vy dvy vz dvz s1 ds1 s2 ds2 p dp\n"); fprintf(hfile,"# xvar: (x y vx vy vz s1 s2 p)\n"); fprintf(hfile,"# yvar: (dx dy dvx dvy dvz ds1 ds2 dp)\n"); fprintf(hfile,"# xlabel: 'Distributions'\n"); fprintf(hfile,"# ylabel: 'Counts'\n"); if (Optim_Normal_Monitor_Counts != 0) fprintf(hfile,"# Optimizer speedup estimate: %.3g [Monitor Normal counts %i (extrapolated), Optimized %i ]\n", (double)(Optim_Total_Monitor_Counts)/Optim_Normal_Monitor_Counts*2*Optim_step,(int)ceil(Optim_Normal_Monitor_Counts/2/Optim_step), Optim_Total_Monitor_Counts); fprintf(hfile,"# Optimizer options: %s\n",options); fprintf(hfile,"# Redirected neutrons: %i (%.2f \%)\n",Optim_n_redirect,(double)(100*Optim_n_redirect/mcget_ncount())); fprintf(hfile,"# data: Optimzed Source\n"); for (Optim_index = 0; Optim_index < Optim_bins; Optim_index++) { fprintf(hfile,"%10.4g ",(Optim_x_min+((Optim_index+0.5)/Optim_bins)*(Optim_x_max - Optim_x_min))); fprintf(hfile,"%10i\t",Optim_Source_x[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_y_min+((Optim_index+0.5)/Optim_bins)*(Optim_y_max - Optim_y_min))); fprintf(hfile,"%10i\t",Optim_Source_y[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_vx_min+((Optim_index+0.5)/Optim_bins)*(Optim_vx_max - Optim_vx_min))); fprintf(hfile,"%10i\t",Optim_Source_vx[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_vy_min+((Optim_index+0.5)/Optim_bins)*(Optim_vy_max - Optim_vy_min))); fprintf(hfile,"%10i\t",Optim_Source_vy[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_vz_min+((Optim_index+0.5)/Optim_bins)*(Optim_vz_max - Optim_vz_min))); fprintf(hfile,"%10i\t",Optim_Source_vz[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_s1_min+((Optim_index+0.5)/Optim_bins)*(Optim_s1_max - Optim_s1_min))); fprintf(hfile,"%10i\t",Optim_Source_s1[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_s2_min+((Optim_index+0.5)/Optim_bins)*(Optim_s2_max - Optim_s2_min))); fprintf(hfile,"%10i\t",Optim_Source_s2[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_p_min+((Optim_index+0.5)/Optim_bins)*(Optim_p_max - Optim_p_min))); fprintf(hfile,"%10i\t",Optim_Source_p[Optim_index]); fprintf(hfile,"\n"); } fprintf(hfile,"# data: Reference Source\n"); for (Optim_index = 0; Optim_index < Optim_bins; Optim_index++) { fprintf(hfile,"%10.4g ",(Optim_x_min+((Optim_index+0.5)/Optim_bins)*(Optim_x_max - Optim_x_min))); fprintf(hfile,"%10i\t",Optim_Reference_x[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_y_min+((Optim_index+0.5)/Optim_bins)*(Optim_y_max - Optim_y_min))); fprintf(hfile,"%10i\t",Optim_Reference_y[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_vx_min+((Optim_index+0.5)/Optim_bins)*(Optim_vx_max - Optim_vx_min))); fprintf(hfile,"%10i\t",Optim_Reference_vx[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_vy_min+((Optim_index+0.5)/Optim_bins)*(Optim_vy_max - Optim_vy_min))); fprintf(hfile,"%10i\t",Optim_Reference_vy[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_vz_min+((Optim_index+0.5)/Optim_bins)*(Optim_vz_max - Optim_vz_min))); fprintf(hfile,"%10i\t",Optim_Reference_vz[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_s1_min+((Optim_index+0.5)/Optim_bins)*(Optim_s1_max - Optim_s1_min))); fprintf(hfile,"%10i\t",Optim_Reference_s1[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_s2_min+((Optim_index+0.5)/Optim_bins)*(Optim_s2_max - Optim_s2_min))); fprintf(hfile,"%10i\t",Optim_Reference_s2[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_p_min+((Optim_index+0.5)/Optim_bins)*(Optim_p_max - Optim_p_min))); fprintf(hfile,"%10i\t",Optim_Reference_p[Optim_index]); fprintf(hfile,"\n"); } fprintf(hfile,"# data: Passing\n"); for (Optim_index = 0; Optim_index < Optim_bins; Optim_index++) { fprintf(hfile,"%10.4g ",(Optim_x_min+((Optim_index+0.5)/Optim_bins)*(Optim_x_max - Optim_x_min))); fprintf(hfile,"%10i\t",Optim_Passing_x[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_y_min+((Optim_index+0.5)/Optim_bins)*(Optim_y_max - Optim_y_min))); fprintf(hfile,"%10i\t",Optim_Passing_y[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_vx_min+((Optim_index+0.5)/Optim_bins)*(Optim_vx_max - Optim_vx_min))); fprintf(hfile,"%10i\t",Optim_Passing_vx[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_vy_min+((Optim_index+0.5)/Optim_bins)*(Optim_vy_max - Optim_vy_min))); fprintf(hfile,"%10i\t",Optim_Passing_vy[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_vz_min+((Optim_index+0.5)/Optim_bins)*(Optim_vz_max - Optim_vz_min))); fprintf(hfile,"%10i\t",Optim_Passing_vz[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_s1_min+((Optim_index+0.5)/Optim_bins)*(Optim_s1_max - Optim_s1_min))); fprintf(hfile,"%10i\t",Optim_Passing_s1[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_s2_min+((Optim_index+0.5)/Optim_bins)*(Optim_s2_max - Optim_s2_min))); fprintf(hfile,"%10i\t",Optim_Passing_s2[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_p_min+((Optim_index+0.5)/Optim_bins)*(Optim_p_max - Optim_p_min))); fprintf(hfile,"%10i\t",Optim_Passing_p[Optim_index]); fprintf(hfile,"\n"); } fprintf(hfile,"# data: New_Source\n"); for (Optim_index = 0; Optim_index < Optim_bins; Optim_index++) { fprintf(hfile,"%10.4g ",(Optim_x_min+((Optim_index+0.5)/Optim_bins)*(Optim_x_max - Optim_x_min))); fprintf(hfile,"%10i\t",Optim_New_Source_x[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_y_min+((Optim_index+0.5)/Optim_bins)*(Optim_y_max - Optim_y_min))); fprintf(hfile,"%10i\t",Optim_New_Source_y[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_vx_min+((Optim_index+0.5)/Optim_bins)*(Optim_vx_max - Optim_vx_min))); fprintf(hfile,"%10i\t",Optim_New_Source_vx[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_vy_min+((Optim_index+0.5)/Optim_bins)*(Optim_vy_max - Optim_vy_min))); fprintf(hfile,"%10i\t",Optim_New_Source_vy[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_vz_min+((Optim_index+0.5)/Optim_bins)*(Optim_vz_max - Optim_vz_min))); fprintf(hfile,"%10i\t",Optim_New_Source_vz[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_s1_min+((Optim_index+0.5)/Optim_bins)*(Optim_s1_max - Optim_s1_min))); fprintf(hfile,"%10i\t",Optim_New_Source_s1[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_s2_min+((Optim_index+0.5)/Optim_bins)*(Optim_s2_max - Optim_s2_min))); fprintf(hfile,"%10i\t",Optim_New_Source_s2[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_p_min+((Optim_index+0.5)/Optim_bins)*(Optim_p_max - Optim_p_min))); fprintf(hfile,"%10i\t",Optim_New_Source_p[Optim_index]); fprintf(hfile,"\n"); } fclose(hfile); } if (Optim_Flag_Verbose) { printf("End of optimization\n"); printf("Optim_Normal_Monitor_Counts = %i (2 steps), Optim_Total_Monitor_Counts = %i \n",Optim_Normal_Monitor_Counts, Optim_Total_Monitor_Counts); if (Optim_Normal_Monitor_Counts != 0) printf("Optimizer speedup : %.3g \n", (double)(Optim_Total_Monitor_Counts)/Optim_Normal_Monitor_Counts*2*Optim_step); printf("Number of redirections : %i\n",Optim_n_redirect); printf("Counts : reference = %i, passing = %i, monitor = %i\n", Optim_Reference_Counts, Optim_Passing_Counts, Optim_Monitor_Counts); printf("Flux : reference = %.2g, passing = %.2g, monitor = %.2g\n", Optim_Reference_Flux, Optim_Passing_Flux, Optim_Monitor_Flux); } } %} MCDISPLAY %{ magnify("xy"); multiline(5, (double)xmin, (double)ymin, 0.0, (double)xmax, (double)ymin, 0.0, (double)xmax, (double)ymax, 0.0, (double)xmin, (double)ymax, 0.0, (double)xmin, (double)ymin, 0.0); %} END -------------- next part -------------- /******************************************************************************* * * McStas, version 1.1, released * Maintained by Kristian Nielsen and Kim Lefmann, * Risoe National Laboratory, Roskilde, Denmark * * Component: Monitor_Optimizer * * Written by: EF, 17 Sept 1999 * * A component that optimizes the neutron flux passing through the * Source_optimizer in order to have the maximum flux at the * Monitor_Optimizer position. * Source_optimizer should be placed just after the source. * Monitor_Optimizer should be placed at position to optimize. * * INPUT PARAMETERS: * * xmin: Lower x bound of detector opening (m) * xmax: Upper x bound of detector opening (m) * ymin: Lower y bound of detector opening (m) * ymax: Upper y bound of detector opening (m) * * OUTPUT PARAMETERS: * * distributions, optimizer efficiency * *******************************************************************************/ DEFINE COMPONENT Monitor_Optimizer DEFINITION PARAMETERS (xmin, xmax, ymin, ymax) SETTING PARAMETERS () STATE PARAMETERS (x,y,z,vx,vy,vz,t,s1,s2,p) DECLARE %{ #ifndef MCSTAS_GEN_OPTIM #error McStas : Source_Optimizer component has to be used before Monitor_Optimizer #endif %} INITIALIZE %{ %} TRACE %{ PROP_Z0; if (x>xmin && xymin && y 2*Optim_Phase_Counts*Optim_step) && (Optim_Monitor_Counts >= Optim_bins*5)) || (Optim_Monitor_Counts >= Optim_bins*10)) { Optim_Phase_Counts_R = 0; /* enough counts on monitor */ if (Optim_Flag_Verbose) { printf(">> AUTO monitor has reached %i counts (non optimized",Optim_Monitor_Counts); if (Optim_Flag_Absorb) printf(", absorbed"); printf(")\n"); } Optim_step = (double)Optim_Reference_Counts/Optim_Phase_Counts; Optim_Phase_Counts = Optim_Reference_Counts; } } if ((Optim_Phase == OPTIM_PHASE_GET_REF) || ((Optim_Phase == OPTIM_PHASE_OPTIM) && (Optim_Flag_Continuous) )) /* build the Optimized Source distributions */ { if (Optim_Monitor_pmax == 0 & p > Optim_Monitor_pmax) Optim_Monitor_pmax = p; if (Optim_vx_max-Optim_vx_min) Optim_index = (int)rint(Optim_bins * (Optim_vx -Optim_vx_min)/(Optim_vx_max-Optim_vx_min)); else Optim_index = 0; if (Optim_index < 0) Optim_index = 0; if (Optim_index >= Optim_bins) Optim_index = Optim_bins - 1; Optim_New_Source_vx[Optim_index]++; if (Optim_vy_max-Optim_vy_min) Optim_index = (int)rint(Optim_bins * (Optim_vy -Optim_vy_min)/(Optim_vy_max-Optim_vy_min)); else Optim_index = 0; if (Optim_index < 0) Optim_index = 0; if (Optim_index >= Optim_bins) Optim_index = Optim_bins - 1; Optim_New_Source_vy[Optim_index]++; if (Optim_vz_max-Optim_vz_min) Optim_index = (int)rint(Optim_bins * (Optim_vz -Optim_vz_min)/(Optim_vz_max-Optim_vz_min)); else Optim_index = 0; if (Optim_index < 0) Optim_index = 0; if (Optim_index >= Optim_bins) Optim_index = Optim_bins - 1; Optim_New_Source_vz[Optim_index]++; if (Optim_x_max-Optim_x_min) Optim_index = (int)rint(Optim_bins * (Optim_x -Optim_x_min)/(Optim_x_max-Optim_x_min)); else Optim_index = 0; if (Optim_index < 0) Optim_index = 0; if (Optim_index >= Optim_bins) Optim_index = Optim_bins - 1; Optim_New_Source_x[Optim_index]++; if (Optim_y_max-Optim_y_min) Optim_index = (int)rint(Optim_bins * (Optim_y -Optim_y_min)/(Optim_y_max-Optim_y_min)); else Optim_index = 0; if (Optim_index < 0) Optim_index = 0; if (Optim_index >= Optim_bins) Optim_index = Optim_bins - 1; Optim_New_Source_y[Optim_index]++; if (Optim_s1_max-Optim_s1_min) Optim_index = (int)rint(Optim_bins * (Optim_s1 -Optim_s1_min)/(Optim_s1_max-Optim_s1_min)); else Optim_index = 0; if (Optim_index < 0) Optim_index = 0; if (Optim_index >= Optim_bins) Optim_index = Optim_bins - 1; Optim_New_Source_s1[Optim_index]++; if (Optim_s2_max-Optim_s2_min) Optim_index = (int)rint(Optim_bins * (Optim_s2 -Optim_s2_min)/(Optim_s2_max-Optim_s2_min)); else Optim_index = 0; if (Optim_index < 0) Optim_index = 0; if (Optim_index >= Optim_bins) Optim_index = Optim_bins - 1; Optim_New_Source_s2[Optim_index]++; if (Optim_p_max-Optim_p_min) Optim_index = (int)rint(Optim_bins * (Optim_p -Optim_p_min)/(Optim_p_max-Optim_p_min)); else Optim_index = 0; if (Optim_index < 0) Optim_index = 0; if (Optim_index >= Optim_bins) Optim_index = Optim_bins - 1; Optim_New_Source_p[Optim_index]++; } /* end if Optim_Phase */ if (Optim_Flag_Absorb && (Optim_Phase == OPTIM_PHASE_GET_REF)) ABSORB; } /* end if xy in optimizer */ /* end trace */ %} FINALLY %{ /* initial Reference distribution arrays (for weights) */ free(Optim_Reference_x); free(Optim_Reference_y); free(Optim_Reference_vx); free(Optim_Reference_vy); free(Optim_Reference_vz); free(Optim_Reference_s1); free(Optim_Reference_s2); free(Optim_Reference_p); /* optimized Source distribution arrays (to reach) */ free(Optim_Source_x); free(Optim_Source_y); free(Optim_Source_vx); free(Optim_Source_vy); free(Optim_Source_vz); free(Optim_Source_s1); free(Optim_Source_s2); free(Optim_Source_p); /* optimized New_Source distribution arrays (to reach in next step, passed to Source) */ free(Optim_New_Source_x); free(Optim_New_Source_y); free(Optim_New_Source_vx); free(Optim_New_Source_vy); free(Optim_New_Source_vz); free(Optim_New_Source_s1); free(Optim_New_Source_s2); free(Optim_New_Source_p); /* Passing distribution arrays (should grow to reach Source) */ free(Optim_Passing_x); free(Optim_Passing_y); free(Optim_Passing_vx); free(Optim_Passing_vy); free(Optim_Passing_vz); free(Optim_Passing_s1); free(Optim_Passing_s2); free(Optim_Passing_p); %} MCDISPLAY %{ magnify("xy"); multiline(5, (double)xmin, (double)ymin, 0.0, (double)xmax, (double)ymin, 0.0, (double)xmax, (double)ymax, 0.0, (double)xmin, (double)ymax, 0.0, (double)xmin, (double)ymin, 0.0); %} END -------------- next part -------------- /******************************************************************************* * * McStas, version 1.0, released October 26, 1998 * Maintained by Kristian Nielsen and Kim Lefmann, * Risoe National Laboratory, Roskilde, Denmark * * Component: Guide2. * * Written by: KN, September 2 1998 * Modified by: KL, October 6, 1998 * * Models a rectangular guide tube centered on the Z axis. The entrance lies * in the X-Y plane. * For details on the geometry calculation see the description in the McStas * reference manual. * * INPUT PARAMETERS: * * w1: (m) Width at the guide entry * h1: (m) Height at the guide entry * w2: (m) Width at the guide exit * h2: (m) Height at the guide exit * l: (m) length of guide * R0: (1) Low-angle reflectivity * Qc: (AA-1) Critical scattering vector * alpha: (AA) Slope of reflectivity * mh: (1) m-horizontal value of material * mv: (1) m-vertical value of material * W: (AA-1) Width of supermirror cut-off * * Example values: m=4 Qc=0.02 W=1/300 alpha=6.49 R0=1 */ DEFINE COMPONENT Guide2 DEFINITION PARAMETERS (w1, h1, w2, h2, l, R0, Qc, alpha, mh, mv, W) SETTING PARAMETERS () STATE PARAMETERS (x,y,z,vx,vy,vz,t,s1,s2,p) TRACE %{ double t1,t2; /* Intersection times. */ double av,ah,bv,bh,cv1,cv2,ch1,ch2,d; /* Intermediate values */ double vdotn_v1,vdotn_v2,vdotn_h1,vdotn_h2; /* Dot products. */ int i; /* Which mirror hit? */ double q; /* Q [1/AA] of reflection */ double vlen2,nlen2; /* Vector lengths squared */ /* ToDo: These could be precalculated. */ double ww = .5*(w2 - w1), hh = .5*(h2 - h1); double whalf = .5*w1, hhalf = .5*h1; double lwhalf = l*whalf, lhhalf = l*hhalf; /* Propagate neutron to guide entrance. */ PROP_Z0; if(x <= -whalf || x >= whalf || y <= -hhalf || y >= hhalf) ABSORB; for(;;) { /* Compute the dot products of v and n for the four mirrors. */ av = l*vx; bv = ww*vz; ah = l*vy; bh = hh*vz; vdotn_v1 = bv + av; /* Left vertical */ vdotn_v2 = bv - av; /* Right vertical */ vdotn_h1 = bh + ah; /* Lower horizontal */ vdotn_h2 = bh - ah; /* Upper horizontal */ /* Compute the dot products of (O - r) and n as c1+c2 and c1-c2 */ cv1 = -whalf*l - z*ww; cv2 = x*l; ch1 = -hhalf*l - z*hh; ch2 = y*l; /* Compute intersection times. */ t1 = (l - z)/vz; i = 0; if(vdotn_v1 < 0 && (t2 = (cv1 - cv2)/vdotn_v1) < t1) { t1 = t2; i = 1; } if(vdotn_v2 < 0 && (t2 = (cv1 + cv2)/vdotn_v2) < t1) { t1 = t2; i = 2; } if(vdotn_h1 < 0 && (t2 = (ch1 - ch2)/vdotn_h1) < t1) { t1 = t2; i = 3; } if(vdotn_h2 < 0 && (t2 = (ch1 + ch2)/vdotn_h2) < t1) { t1 = t2; i = 4; } if(i == 0) break; /* Neutron left guide. */ PROP_DT(t1); switch(i) { case 1: /* Left vertical mirror */ nlen2 = l*l + ww*ww; q = V2Q*(-2)*vdotn_v1/sqrt(nlen2); d = 2*vdotn_v1/nlen2; vx = vx - d*l; vz = vz - d*ww; break; case 2: /* Right vertical mirror */ nlen2 = l*l + ww*ww; q = V2Q*(-2)*vdotn_v2/sqrt(nlen2); d = 2*vdotn_v2/nlen2; vx = vx + d*l; vz = vz - d*ww; break; case 3: /* Lower horizontal mirror */ nlen2 = l*l + hh*hh; q = V2Q*(-2)*vdotn_h1/sqrt(nlen2); d = 2*vdotn_h1/nlen2; vy = vy - d*l; vz = vz - d*hh; break; case 4: /* Upper horizontal mirror */ nlen2 = l*l + hh*hh; q = V2Q*(-2)*vdotn_h2/sqrt(nlen2); d = 2*vdotn_h2/nlen2; vy = vy + d*l; vz = vz - d*hh; break; } /* Now compute reflectivity. */ if(q > Qc) { double arg = (q - (i <= 2 ? mv : mh)*Qc)/W; if(arg < 10) p *= .5*(1-tanh(arg))*(1-alpha*(q-Qc)); else ABSORB; /* Cutoff ~ 1E-10 */ } p *= R0; } %} END -------------- next part -------------- DEFINE INSTRUMENT IN14(KI,WN,ORDER,MHV) /* preprocess with : mcstas in14_4.instr */ /* compile on mica with : cc -Ofast -64 -o in14_3 in14_3.c -lm */ /* Test with : */ /* in14_6 -n 1e6 KI=2.66 WN=0.03 ORDER=1 MHV=3 */ DECLARE %{ #define VERSION "60" double L1 = 16.68; /* source-mono */ double L2 = 2.12; /* mono-sample */ double L3 = 1.35; /* sample-ana */ double L4 = 0.70; /* ana-det */ int SM,SS,SA; double A1,A3,A5; double LM1, LM1b; /* distances to monitors M1 and M2 */ double LM2, LM2b; double A2,A4,A6,RM,RH; char *pfile; char *efile; char *dfile; char *kfile; /* ==================== Source description ==================== */ double EN; double D_EN; double EMIN, EMAX; double FLUX = 1e13; /* n/cm^2/s on guide entry */ /* ==================== Monochromator desciption ==================== */ double ETAM = 30; /* Mosaicity used on monochromator 30 */ double DM = 3.355; /* Monochromator d-spacing in Angs */ /* PG002 Orders : 1st 3.355 2e 1.6775, 3e 1.1183 */ double mono_r0 = 0.9; /* mean reflectivity */ double mono_width = 0.15; double mono_heigh = .122; double mono_gap = 0; /* slates are adjacent */ int mono_segment_number_vert = 7; int mono_segment_number_horz = 1; double mono_curv_vert; /* Vertical Rotation between adjacent slabs. */ double mono_curv_horz; /* Horizontal Rotation between adjacent slabs. */ double mono_slate_heigh; /* size (height) of slates */ double mono_slate_width; /* size (width) of slates */ double mono_q; /* Q vector for bragg scattering with monochromator and analysator */ double Ki, Ei; double TM, GM; /* ==================== Sample desciption ==================== */ double TU, TL; double GU, GL; /* ==================== Analyser desciption ==================== */ double ETAA = 30; /* Mosaicity used on analyser 30 */ double DA = 3.355; /* analyser d-spacing in Angs */ /* PG002 Orders : 1st 3.355 2e 1.6775, 3e 1.1183 */ double ana_r0 = 0.9; /* mean reflectivity */ double ana_width = 0.10; double ana_heigh = .14; double ana_gap = 0; /* slates are adjacent */ int ana_segment_number_vert = 7; int ana_segment_number_horz = 1; double ana_curv_vert; /* Vertical Rotation between adjacent slabs. */ double ana_curv_horz; /* Horizontal Rotation between adjacent slabs. */ double ana_slate_heigh; /* size (height) of slates */ double ana_slate_width; /* size (width) of slates */ double ana_q; /* Q vector for bragg scattering with monochromator and analysator */ double Kf, Ef; double TA, GA; %} INITIALIZE %{ double vi,vf,sample_q; mono_q = 2*PI*ORDER/DM; /* Q mono in Angs-1 */ A4 = 0; A2 = asin(mono_q/2/KI)*RAD2DEG*2; A6 = A2; printf("Instrument : IN14, v%s (21/09/99) on %s.\n",VERSION,getenv("HOSTNAME")); /* SM : scattering at mono to the right (-1)/left(+1) */ /* SS : scattering at sample to the right (-1)/left(+1) */ /* SA : scattering at analyser to the right (-1)/left(+1) */ SM = 1; SS = 1; SA = 1; A2 *= SM; /* A1 : mono theta (crystal) */ A1 = A2/2; /* A2 : mono 2 theta (arm to sample) */ A4 *= SS; /* A3 : sample theta */ A3 = A4/2; /* A4 : sample 2 theta (arm to analyser) */ A6 *= SA; /* A5 : analyser theta (crystal) */ A5 = A6/2; /* A6 : analyser 2 theta (arm to detector) */ TM = 0; /* TM : translation mono */ GM = 0; /* GM : tilt mono */ GU = 0; /* GU : tilt sample Up */ GL = 0; /* GL : tilt sample Low */ TU = 0; /* TU : translation sample Up */ TL = 0; /* TL : translation sample Low */ TA = 0; /* TA : translation analyser */ GA = 0; /* GA : tilt analyser */ /* RA : horizontal curvature analyser */ if ((fabs(mono_q/2/KI) < 1) && (sin(DEG2RAD*A1) != 0)) Ki = mono_q/2/sin(DEG2RAD*A1); else { printf("Warn : Can't define incident wave vector Ki\n"); Ki = 0; printf("Skipping simulation\n"); exit(-1); } vi = K2V*fabs(Ki); Ei = VS2E*vi*vi; EN = Ei; D_EN = .5; /* optimize source on Ki */ ana_q = 2*PI/DA; /* Q ana in Angs-1 */ if (sin(DEG2RAD*A5) != 0) Kf = ana_q/2/sin(DEG2RAD*A5); else { printf("Warn : Can't define outgoing wave vector Kf\n"); Kf = 0; } vf = K2V*fabs(Kf); Ef = VS2E*vf*vf; sample_q = sqrt(Ki*Ki + Kf*Kf -2*fabs(Ki*Kf)*cos(DEG2RAD*A4)); mono_slate_heigh = mono_heigh/mono_segment_number_vert; /* slates are adjacent */ mono_curv_vert = fabs(mono_slate_heigh*RAD2DEG/(2*L2*sin(DEG2RAD*A1))); /* RM : vertical mono curvature */ mono_slate_width = mono_width/mono_segment_number_horz; /* slates are adjacent */ mono_curv_horz = fabs(mono_slate_width*RAD2DEG*sin(DEG2RAD*A1)/(2*L2)); /* RH : horizontal mono curvature */ ana_slate_heigh = ana_heigh/ana_segment_number_vert; /* slates are adjacent */ ana_curv_vert = fabs(ana_slate_heigh*RAD2DEG/(2*L3*sin(DEG2RAD*A5))); /* RA : vertical ana curvature */ ana_slate_width = ana_width/ana_segment_number_horz; /* slates are adjacent */ ana_curv_horz = fabs(ana_slate_width*RAD2DEG*sin(DEG2RAD*A5)/(2*L3)); /* RHA : horizontal ana curvature */ /* print instrument config */ printf("Flat source, m=%.2f noze, width %.2f\n",MHV,WN); printf("Monochromator : (DM = %g)\n",DM); printf("A1 = %.2f, A2 = %.2f (deg)\n",A1,A2); printf("Ki = %.3g Angs-1 (Energy = %.3g meV, Velocity = %.3g m/s) \n", Ki, Ei,vi); printf("RM = %.3g Deg, RH = %.3g Deg\n",mono_curv_vert,mono_curv_horz); printf("\n"); printf("Sample :\n"); printf("A3 = %.2f, A4 = %.2f (deg)\n",A3,A4); printf("Energy transfert %.3g meV, Moment transfert %.3g Angs-1\n",Ef-Ei,sample_q); printf("\n"); printf("Analyser : (DA = %g)\n",DA); printf("A5 = %.2f, A6 = %.2f (deg)\n",A5,A6); printf("Kf = %.3g Angs-1 (Energy = %.3g meV, Velocity = %.3g m/s) \n", Kf, Ef,vf); printf("RA = %.3g Deg\n",ana_curv_vert); printf("\n"); printf("Detectors :\n"); /* local variables ------------------------------------ */ LM1 = L2*.9; LM1b = LM1+0.001; LM2 = L3/2; LM2b = LM2+0.001; EMIN = EN - D_EN; EMAX = EN + D_EN; pfile = (char *)malloc(256); efile = (char *)malloc(256); dfile = (char *)malloc(256); kfile = (char *)malloc(256); sprintf(pfile,"sim/i%s_k%iw%id%im%i.psd",VERSION,(int)floor(10*Ki+0.5),(int)floor(1000*WN),(int)floor(ORDER),(int)floor(MHV+0.5)); sprintf(efile,"sim/i%s_k%iw%id%im%i.nrj",VERSION,(int)floor(10*Ki+0.5),(int)floor(1000*WN),(int)floor(ORDER),(int)floor(MHV+0.5)); sprintf(dfile,"sim/i%s_k%iw%id%im%i.div",VERSION,(int)floor(10*Ki+0.5),(int)floor(1000*WN),(int)floor(ORDER),(int)floor(MHV+0.5)); sprintf(kfile,"sim/i%s_k%iw%id%im%i.kw",VERSION,(int)floor(10*Ki+0.5),(int)floor(1000*WN),(int)floor(ORDER),(int)floor(MHV+0.5)); %} TRACE COMPONENT origin = Arm() AT (0,0,0) ABSOLUTE COMPONENT source = Source_flux( radius = 0.20, dist = 2.16, xw = 0.06, yh = 0.12, E0 = EN, dE = D_EN, flux=FLUX) AT (0,0,0) RELATIVE origin ROTATED (0,0,0) RELATIVE origin COMPONENT optim_s = Source_Optimizer( xmin = -0.03, xmax = 0.03, ymin = -0.06, ymax = 0.06, bins = -1, step = 10, keep = 10, file="source.optim", options="verbose+absorb+auto") AT (0,0,2.14) RELATIVE origin ROTATED (0,0,0) RELATIVE origin COMPONENT kw1 = kw_monitor( xmin = -0.01, xmax = 0.01, ymin = -0.01, ymax = 0.01, filename = "kguide.kw") AT(0, 0, 2.145) RELATIVE origin ROTATED (0,0,0) RELATIVE origin COMPONENT doigt_de_gant = Guide( w1 = 0.06, h1 = 0.12, w2 = 0.06, h2 = 0.12, l = 2.75, /* guide into the doigt de gant */ R0 = 1, m=1.2, /* Ni 58 */ Qc = 0.021, alpha = 2.33, W = 2e-3) AT (0,0,2.15) RELATIVE origin ROTATED (0,0,0) RELATIVE origin COMPONENT external_guide = Guide2( w1 = 0.06, h1 = 0.12, w2 = 0.06, h2 = 0.12, l = 13.67, /* external guide between doigt de gant and mono */ R0 = 1, Qc = 0.021, alpha = 2.33, mh=1.2, /* 1.2 Ni 58, 3 Super mirror */ mv=1.2, W = 2e-3) AT (0,0,4.91) RELATIVE origin ROTATED (0,0,0) RELATIVE origin /* -------------- Start of monochromator building -------------- */ /* support of mono */ COMPONENT focus_mono = Arm() AT (0, 0, L1) RELATIVE origin ROTATED (0, A1, 0) RELATIVE origin COMPONENT m0 = Mon_2foc( zwidth=mono_slate_width, ywidth=mono_slate_heigh, gap=mono_gap, NH=mono_segment_number_vert, NV=mono_segment_number_horz, mosaich=ETAM, mosaicv=ETAM, r0=mono_r0, Q=mono_q, RH=mono_curv_vert, RV=mono_curv_horz) AT (TM, 0, 0) RELATIVE focus_mono ROTATED (0, 0, GM) RELATIVE focus_mono /* on mono, pointing towards sample */ COMPONENT out_mono = Arm() AT (0,0,0) RELATIVE focus_mono ROTATED (0, A2, 0) RELATIVE origin /* -------------- End of monochromator building -------------- */ COMPONENT noze = Guide2( w1 = 0.05, h1 = 0.05, w2 = WN, h2 = 0.05, l = .825, R0 = 1, Qc = 0.021, alpha = 2.33, mh=1e-5, mv = MHV, /* Ni 58 */ W = 2e-3) AT (0, 0, .9) RELATIVE out_mono ROTATED (0,0,0) RELATIVE out_mono /* COMPONENT M1 = Monitor( xmin = -0.03, xmax = 0.03, ymin = -0.06, ymax = 0.06) AT (0, 0, LM1) RELATIVE out_mono ROTATED (0,0,0) RELATIVE out_mono */ /* -------------- Start of sample building -------------- */ /* support of sample */ COMPONENT focus_sample = Arm() AT (0, 0, L2) RELATIVE out_mono ROTATED (0,A3,0) RELATIVE out_mono /* COMPONENT sample = Powder1( radius = 0.007, h = 0.015, q = 1.8049, d_phi0 = 4, pack = 1, j = 6, DW = 1, F2 = 56.8, Vc = 85.0054, sigma_a = 0.463, target_x = alu_focus_x, target_y = 0, target_z = 1000) AT (GU, 0, GL) RELATIVE focus_sample ROTATED (TU,0,TL) RELATIVE focus_sample */ /* COMPONENT AtSample = Monitor( xmin = -0.05, xmax = 0.05, ymin = -0.05, ymax = 0.05) AT (0, 0, 0) RELATIVE focus_sample ROTATED (0,0,0) RELATIVE focus_sample */ COMPONENT optim_m = Monitor_Optimizer( xmin = -0.05, xmax = 0.05, ymin = -0.05, ymax = 0.05) AT(0, 0, 0) RELATIVE focus_sample ROTATED (0,0,0) RELATIVE focus_sample COMPONENT PSDSample = PSD_monitor( xmin = -0.05, xmax = 0.05, ymin = -0.05, ymax = 0.05, nx = 50, ny = 50, filename = pfile) AT(0, 0, 0.001) RELATIVE focus_sample ROTATED (0,0,0) RELATIVE focus_sample COMPONENT Int4Sample = Monitor( xmin = -0.02, xmax = 0.02, ymin = -0.02, ymax = 0.02) AT(0, 0, 0.002) RELATIVE focus_sample ROTATED (0,0,0) RELATIVE focus_sample COMPONENT Flux1Sample = Monitor( xmin = -0.005, xmax = 0.005, ymin = -0.005, ymax = 0.005) AT(0, 0, 0.003) RELATIVE focus_sample ROTATED (0,0,0) RELATIVE focus_sample COMPONENT ESample = E_monitor( xmin = -0.005, xmax = 0.005, ymin = -0.005, ymax = 0.005, Emin = EMIN, Emax = EMAX, nchan = 21, filename = efile) AT(0, 0, 0.004) RELATIVE focus_sample ROTATED (0,0,0) RELATIVE focus_sample COMPONENT DivSample = Divergence_monitor( xmin = -0.005, xmax = 0.005, ymin = -0.005, ymax = 0.005, nv = 10, nh= 10, v_maxdiv = 1, h_maxdiv = 1, filename = dfile) AT(0, 0, 0.005) RELATIVE focus_sample ROTATED (0,0,0) RELATIVE focus_sample COMPONENT kw = kw_monitor( xmin = -0.005, xmax = 0.005, ymin = -0.005, ymax = 0.005, filename = kfile) AT(0, 0, 0.006) RELATIVE focus_sample ROTATED (0,0,0) RELATIVE focus_sample /* on sample, pointing towards ana */ COMPONENT out_sample = Arm() AT (0,0,0) RELATIVE focus_sample ROTATED (0, A4, 0) RELATIVE out_mono /* -------------- End of sample building -------------- */ /* COMPONENT M2 = Monitor( xmin = -0.1, xmax = 0.1, ymin = -0.1, ymax = 0.1) AT (0, 0, LM2) RELATIVE out_sample ROTATED (0,0,0) RELATIVE out_sample */ /* -------------- Start of analyzer building -------------- */ /* support of analyzer */ /* COMPONENT focus_ana = Arm() AT (0, 0, L3) RELATIVE out_sample ROTATED (0,A5,0) RELATIVE out_sample COMPONENT a0 = Mon_2foc( zwidth = ana_half_width, ywidth = ana_half_heigh, gap = 0, NH = 1, NV = 1, mosaich = ETAA, mosaicv = ETAA, r0 = ana_r0, Q = ana_q, RH=ana_curv_vert, RV=ana_curv_horz) AT (TA, 0, 0) RELATIVE focus_ana ROTATED (0, 0, GA) RELATIVE focus_ana COMPONENT out_ana = Arm() AT (0, 0, 0) RELATIVE focus_ana ROTATED (0, A6, 0) RELATIVE out_sample */ /* -------------- End of analyzer building -------------- */ /* COMPONENT focus_det = Arm() AT (0, 0, L4) RELATIVE out_ana ROTATED (0,0,0) RELATIVE out_ana COMPONENT Detector = Monitor( xmin = -0.02, xmax = 0.02, ymin = -0.05, ymax = 0.05) AT(0, 0, 0) RELATIVE focus_det ROTATED (0,0,0) RELATIVE focus_det COMPONENT emon2 = E_monitor( xmin = -0.02, xmax = 0.02, ymin = -0.05, ymax = 0.05, Emin = 10, Emax = 20, nchan = 35, filename = "sim/in14_EM2.vmon") AT(0, 0, 0.01) RELATIVE focus_det ROTATED (0,0,0) RELATIVE focus_det */ FINALLY %{ printf("Output files : %s %s %s %s\n",pfile,efile,dfile,kfile); free(pfile); free(dfile); free(efile); free(kfile); %} END -------------- next part -------------- DEFINE INSTRUMENT IN14(KI,WN,ORDER,MHV) /* preprocess with : mcstas in14_4.instr */ /* compile on mica with : cc -Ofast -64 -o in14_3 in14_3.c -lm */ /* Test with : in14_4 KI=1.55 WN=5 */ /* in14_6n -n 1e6 KI=2.66 WN=0.03 ORDER=1 MHV=3 */ DECLARE %{ #define VERSION "61" double L1 = 16.68; /* source-mono */ double L2 = 2.12; /* mono-sample */ double L3 = 1.35; /* sample-ana */ double L4 = 0.70; /* ana-det */ int SM,SS,SA; double A1,A3,A5; double LM1, LM1b; /* distances to monitors M1 and M2 */ double LM2, LM2b; double A2,A4,A6,RM,RH; char *pfile; char *efile; char *dfile; char *kfile; /* ==================== Source description ==================== */ double EN; double D_EN; double EMIN, EMAX; double FLUX = 1e13; /* n/cm^2/s on guide entry */ /* ==================== Monochromator desciption ==================== */ double ETAM = 30; /* Mosaicity used on monochromator 30 */ double DM = 3.355; /* Monochromator d-spacing in Angs */ /* PG002 Orders : 1st 3.355 2e 1.6775, 3e 1.1183 */ double mono_r0 = 0.9; /* mean reflectivity */ double mono_width = 0.15; double mono_heigh = .122; double mono_gap = 0; /* slates are adjacent */ int mono_segment_number_vert = 7; int mono_segment_number_horz = 1; double mono_curv_vert; /* Vertical Rotation between adjacent slabs. */ double mono_curv_horz; /* Horizontal Rotation between adjacent slabs. */ double mono_slate_heigh; /* size (height) of slates */ double mono_slate_width; /* size (width) of slates */ double mono_q; /* Q vector for bragg scattering with monochromator and analysator */ double Ki, Ei; double TM, GM; /* ==================== Sample desciption ==================== */ double TU, TL; double GU, GL; /* ==================== Analyser desciption ==================== */ double ETAA = 30; /* Mosaicity used on analyser 30 */ double DA = 3.355; /* analyser d-spacing in Angs */ /* PG002 Orders : 1st 3.355 2e 1.6775, 3e 1.1183 */ double ana_r0 = 0.9; /* mean reflectivity */ double ana_width = 0.10; double ana_heigh = .14; double ana_gap = 0; /* slates are adjacent */ int ana_segment_number_vert = 7; int ana_segment_number_horz = 1; double ana_curv_vert; /* Vertical Rotation between adjacent slabs. */ double ana_curv_horz; /* Horizontal Rotation between adjacent slabs. */ double ana_slate_heigh; /* size (height) of slates */ double ana_slate_width; /* size (width) of slates */ double ana_q; /* Q vector for bragg scattering with monochromator and analysator */ double Kf, Ef; double TA, GA; %} INITIALIZE %{ double vi,vf,sample_q; mono_q = 2*PI*ORDER/DM; /* Q mono in Angs-1 */ A4 = 0; A2 = asin(mono_q/2/KI)*RAD2DEG*2; A6 = A2; printf("Instrument : IN14, v%s (21/09/99) on %s.\n",VERSION,getenv("HOSTNAME")); /* SM : scattering at mono to the right (-1)/left(+1) */ /* SS : scattering at sample to the right (-1)/left(+1) */ /* SA : scattering at analyser to the right (-1)/left(+1) */ SM = 1; SS = 1; SA = 1; A2 *= SM; /* A1 : mono theta (crystal) */ A1 = A2/2; /* A2 : mono 2 theta (arm to sample) */ A4 *= SS; /* A3 : sample theta */ A3 = A4/2; /* A4 : sample 2 theta (arm to analyser) */ A6 *= SA; /* A5 : analyser theta (crystal) */ A5 = A6/2; /* A6 : analyser 2 theta (arm to detector) */ TM = 0; /* TM : translation mono */ GM = 0; /* GM : tilt mono */ GU = 0; /* GU : tilt sample Up */ GL = 0; /* GL : tilt sample Low */ TU = 0; /* TU : translation sample Up */ TL = 0; /* TL : translation sample Low */ TA = 0; /* TA : translation analyser */ GA = 0; /* GA : tilt analyser */ /* RA : horizontal curvature analyser */ if ((fabs(mono_q/2/KI) < 1) && (sin(DEG2RAD*A1) != 0)) Ki = mono_q/2/sin(DEG2RAD*A1); else { printf("Warn : Can't define incident wave vector Ki\n"); Ki = 0; printf("Skipping simulation\n"); exit(-1); } vi = K2V*fabs(Ki); Ei = VS2E*vi*vi; EN = Ei; D_EN = .5; /* optimize source on Ki */ ana_q = 2*PI/DA; /* Q ana in Angs-1 */ if (sin(DEG2RAD*A5) != 0) Kf = ana_q/2/sin(DEG2RAD*A5); else { printf("Warn : Can't define outgoing wave vector Kf\n"); Kf = 0; } vf = K2V*fabs(Kf); Ef = VS2E*vf*vf; sample_q = sqrt(Ki*Ki + Kf*Kf -2*fabs(Ki*Kf)*cos(DEG2RAD*A4)); mono_slate_heigh = mono_heigh/mono_segment_number_vert; /* slates are adjacent */ mono_curv_vert = fabs(mono_slate_heigh*RAD2DEG/(2*L2*sin(DEG2RAD*A1))); /* RM : vertical mono curvature */ mono_slate_width = mono_width/mono_segment_number_horz; /* slates are adjacent */ mono_curv_horz = fabs(mono_slate_width*RAD2DEG*sin(DEG2RAD*A1)/(2*L2)); /* RH : horizontal mono curvature */ ana_slate_heigh = ana_heigh/ana_segment_number_vert; /* slates are adjacent */ ana_curv_vert = fabs(ana_slate_heigh*RAD2DEG/(2*L3*sin(DEG2RAD*A5))); /* RA : vertical ana curvature */ ana_slate_width = ana_width/ana_segment_number_horz; /* slates are adjacent */ ana_curv_horz = fabs(ana_slate_width*RAD2DEG*sin(DEG2RAD*A5)/(2*L3)); /* RHA : horizontal ana curvature */ /* print instrument config */ printf("Flat source, m=%.2f noze, width %.2f\n",MHV,WN); printf("Monochromator : (DM = %g)\n",DM); printf("A1 = %.2f, A2 = %.2f (deg)\n",A1,A2); printf("Ki = %.3g Angs-1 (Energy = %.3g meV, Velocity = %.3g m/s) \n", Ki, Ei,vi); printf("RM = %.3g Deg, RH = %.3g Deg\n",mono_curv_vert,mono_curv_horz); printf("\n"); printf("Sample :\n"); printf("A3 = %.2f, A4 = %.2f (deg)\n",A3,A4); printf("Energy transfert %.3g meV, Moment transfert %.3g Angs-1\n",Ef-Ei,sample_q); printf("\n"); printf("Analyser : (DA = %g)\n",DA); printf("A5 = %.2f, A6 = %.2f (deg)\n",A5,A6); printf("Kf = %.3g Angs-1 (Energy = %.3g meV, Velocity = %.3g m/s) \n", Kf, Ef,vf); printf("RA = %.3g Deg\n",ana_curv_vert); printf("\n"); printf("Detectors :\n"); /* local variables ------------------------------------ */ LM1 = L2*.9; LM1b = LM1+0.001; LM2 = L3/2; LM2b = LM2+0.001; EMIN = EN - D_EN; EMAX = EN + D_EN; pfile = (char *)malloc(256); efile = (char *)malloc(256); dfile = (char *)malloc(256); kfile = (char *)malloc(256); sprintf(pfile,"sim/i%s_k%iw%id%im%i.psd",VERSION,(int)floor(10*Ki+0.5),(int)floor(1000*WN),(int)floor(ORDER),(int)floor(MHV+0.5)); sprintf(efile,"sim/i%s_k%iw%id%im%i.nrj",VERSION,(int)floor(10*Ki+0.5),(int)floor(1000*WN),(int)floor(ORDER),(int)floor(MHV+0.5)); sprintf(dfile,"sim/i%s_k%iw%id%im%i.div",VERSION,(int)floor(10*Ki+0.5),(int)floor(1000*WN),(int)floor(ORDER),(int)floor(MHV+0.5)); sprintf(kfile,"sim/i%s_k%iw%id%im%i.kw",VERSION,(int)floor(10*Ki+0.5),(int)floor(1000*WN),(int)floor(ORDER),(int)floor(MHV+0.5)); %} TRACE COMPONENT origin = Arm() AT (0,0,0) ABSOLUTE COMPONENT source = Source_flux( radius = 0.20, dist = 2.16, xw = 0.06, yh = 0.12, E0 = EN, dE = D_EN, flux=FLUX) AT (0,0,0) RELATIVE origin ROTATED (0,0,0) RELATIVE origin COMPONENT doigt_de_gant = Guide( w1 = 0.06, h1 = 0.12, w2 = 0.06, h2 = 0.12, l = 2.75, /* guide into the doigt de gant */ R0 = 1, m=1.2, /* Ni 58 */ Qc = 0.021, alpha = 2.33, W = 2e-3) AT (0,0,2.15) RELATIVE origin ROTATED (0,0,0) RELATIVE origin COMPONENT external_guide = Guide2( w1 = 0.06, h1 = 0.12, w2 = 0.06, h2 = 0.12, l = 13.67, /* external guide between doigt de gant and mono */ R0 = 1, Qc = 0.021, alpha = 2.33, mh=1.2, /* 1.2 Ni 58, 3 Super mirror */ mv=1.2, W = 2e-3) AT (0,0,4.91) RELATIVE origin ROTATED (0,0,0) RELATIVE origin /* -------------- Start of monochromator building -------------- */ /* support of mono */ COMPONENT focus_mono = Arm() AT (0, 0, L1) RELATIVE origin ROTATED (0, A1, 0) RELATIVE origin COMPONENT m0 = Mon_2foc( zwidth=mono_slate_width, ywidth=mono_slate_heigh, gap=mono_gap, NH=mono_segment_number_vert, NV=mono_segment_number_horz, mosaich=ETAM, mosaicv=ETAM, r0=mono_r0, Q=mono_q, RH=mono_curv_vert, RV=mono_curv_horz) AT (TM, 0, 0) RELATIVE focus_mono ROTATED (0, 0, GM) RELATIVE focus_mono /* on mono, pointing towards sample */ COMPONENT out_mono = Arm() AT (0,0,0) RELATIVE focus_mono ROTATED (0, A2, 0) RELATIVE origin /* -------------- End of monochromator building -------------- */ COMPONENT noze = Guide2( w1 = 0.05, h1 = 0.05, w2 = WN, h2 = 0.05, l = .825, R0 = 1, Qc = 0.021, alpha = 2.33, mh=1e-5, mv = MHV, /* Ni 58 */ W = 2e-3) AT (0, 0, .9) RELATIVE out_mono ROTATED (0,0,0) RELATIVE out_mono /* COMPONENT M1 = Monitor( xmin = -0.03, xmax = 0.03, ymin = -0.06, ymax = 0.06) AT (0, 0, LM1) RELATIVE out_mono ROTATED (0,0,0) RELATIVE out_mono */ /* -------------- Start of sample building -------------- */ /* support of sample */ COMPONENT focus_sample = Arm() AT (0, 0, L2) RELATIVE out_mono ROTATED (0,A3,0) RELATIVE out_mono /* COMPONENT sample = Powder1( radius = 0.007, h = 0.015, q = 1.8049, d_phi0 = 4, pack = 1, j = 6, DW = 1, F2 = 56.8, Vc = 85.0054, sigma_a = 0.463, target_x = alu_focus_x, target_y = 0, target_z = 1000) AT (GU, 0, GL) RELATIVE focus_sample ROTATED (TU,0,TL) RELATIVE focus_sample */ /* COMPONENT AtSample = Monitor( xmin = -0.05, xmax = 0.05, ymin = -0.05, ymax = 0.05) AT (0, 0, 0) RELATIVE focus_sample ROTATED (0,0,0) RELATIVE focus_sample */ COMPONENT PSDSample = PSD_monitor( xmin = -0.05, xmax = 0.05, ymin = -0.05, ymax = 0.05, nx = 50, ny = 50, filename = pfile) AT(0, 0, 0.001) RELATIVE focus_sample ROTATED (0,0,0) RELATIVE focus_sample COMPONENT Int4Sample = Monitor( xmin = -0.02, xmax = 0.02, ymin = -0.02, ymax = 0.02) AT(0, 0, 0.002) RELATIVE focus_sample ROTATED (0,0,0) RELATIVE focus_sample COMPONENT Flux1Sample = Monitor( xmin = -0.005, xmax = 0.005, ymin = -0.005, ymax = 0.005) AT(0, 0, 0.003) RELATIVE focus_sample ROTATED (0,0,0) RELATIVE focus_sample COMPONENT ESample = E_monitor( xmin = -0.005, xmax = 0.005, ymin = -0.005, ymax = 0.005, Emin = EMIN, Emax = EMAX, nchan = 21, filename = efile) AT(0, 0, 0.004) RELATIVE focus_sample ROTATED (0,0,0) RELATIVE focus_sample COMPONENT DivSample = Divergence_monitor( xmin = -0.005, xmax = 0.005, ymin = -0.005, ymax = 0.005, nv = 10, nh= 10, v_maxdiv = 1, h_maxdiv = 1, filename = dfile) AT(0, 0, 0.005) RELATIVE focus_sample ROTATED (0,0,0) RELATIVE focus_sample COMPONENT kw = kw_monitor( xmin = -0.005, xmax = 0.005, ymin = -0.005, ymax = 0.005, filename = kfile) AT(0, 0, 0.006) RELATIVE focus_sample ROTATED (0,0,0) RELATIVE focus_sample /* on sample, pointing towards ana */ COMPONENT out_sample = Arm() AT (0,0,0) RELATIVE focus_sample ROTATED (0, A4, 0) RELATIVE out_mono /* -------------- End of sample building -------------- */ /* COMPONENT M2 = Monitor( xmin = -0.1, xmax = 0.1, ymin = -0.1, ymax = 0.1) AT (0, 0, LM2) RELATIVE out_sample ROTATED (0,0,0) RELATIVE out_sample */ /* -------------- Start of analyzer building -------------- */ /* support of analyzer */ /* COMPONENT focus_ana = Arm() AT (0, 0, L3) RELATIVE out_sample ROTATED (0,A5,0) RELATIVE out_sample COMPONENT a0 = Mon_2foc( zwidth = ana_half_width, ywidth = ana_half_heigh, gap = 0, NH = 1, NV = 1, mosaich = ETAA, mosaicv = ETAA, r0 = ana_r0, Q = ana_q, RH=ana_curv_vert, RV=ana_curv_horz) AT (TA, 0, 0) RELATIVE focus_ana ROTATED (0, 0, GA) RELATIVE focus_ana COMPONENT out_ana = Arm() AT (0, 0, 0) RELATIVE focus_ana ROTATED (0, A6, 0) RELATIVE out_sample */ /* -------------- End of analyzer building -------------- */ /* COMPONENT focus_det = Arm() AT (0, 0, L4) RELATIVE out_ana ROTATED (0,0,0) RELATIVE out_ana COMPONENT Detector = Monitor( xmin = -0.02, xmax = 0.02, ymin = -0.05, ymax = 0.05) AT(0, 0, 0) RELATIVE focus_det ROTATED (0,0,0) RELATIVE focus_det COMPONENT emon2 = E_monitor( xmin = -0.02, xmax = 0.02, ymin = -0.05, ymax = 0.05, Emin = 10, Emax = 20, nchan = 35, filename = "sim/in14_EM2.vmon") AT(0, 0, 0.01) RELATIVE focus_det ROTATED (0,0,0) RELATIVE focus_det */ FINALLY %{ printf("Output files : %s %s %s %s\n",pfile,efile,dfile,kfile); free(pfile); free(dfile); free(efile); %} END From farhi at ill.fr Thu Oct 7 11:15:37 1999 From: farhi at ill.fr (Farhi) Date: Thu, 07 Oct 1999 11:15:37 +0200 Subject: Optimizer (new doc) Message-ID: <37FC64B9.954A8AEC@ill.fr> I've added some details about using the optimizer in the header of Source_optimizer.comp. I think it's ok now, and also I've activated the options 'continuous' and 'keepE' as default. The speed increase is about 15, and the efficiency in targetting is about 40 in normal conditions and settings. As a reference : with continuous+keepE+absorb+auto time in14_6 -n 1e6 KI=2.66 WN=0.03 ORDER=1 MHV=3 -> 26 sec. (1200 n/s on PSD) PSD has got 31340 neutrons, error I_err = 1.1 % time in14_6 -n 1e6 KI=2.66 WN=0.03 ORDER=1 MHV=3 -> 9 sec. (82 n/s on PSD) PSD has got 738 neutrons, error I_err = 6.9 % Cheers. EF. -- Emmanuel FARHI, http://www.ill.fr/tas/people/Farhi.html \|/ ____ \|/ TAS-Group, Institut Laue-Langevin (ILL) Grenoble ~@-/ oO \-@~ Avenue des Martyrs, BP 156, 38042 Grenoble Cedex 9,France /_( \__/ )_\ Work :Tel (33/0) 4 76 20 71 83. Fax (33/0) 4 76 48 39 06 \__U_/ La Grande Arche, Chateau d'Uriage, 38410 Saint Martin d'Uriage 04 76 59 73 94 -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- /******************************************************************************* * * McStas, version 1.1, released * Maintained by Kristian Nielsen and Kim Lefmann, * Risoe National Laboratory, Roskilde, Denmark * * Component: Source_Optimizer * * Written by: EF, 17 Sept 1999 * * Usage: A component that optimizes the neutron flux passing through the * Source_optimizer in order to have the maximum flux at the * Monitor_Optimizer position. * * Principle: The optimizer first computes neutron state parameter limits * (step 1) passing in the Source_Optimizer, and then records a Reference source * (step 2) as well as the state (at Source_Optimizer position) of neutrons * reaching Monitor. The optimized source is defined as a fraction of the * Reference source plus the distribution of 'good' neutrons reaching the * Monitor. The optimization then starts (step 3), and focuses new neutrons on * the Monitor_Optimizer. In fact it changes 'bad' neutrons into 'good' ones (that * reach the Monitor). The overall flux is kept during process. * * Options: The optimized source can be computed regularly ('continuous' option) * or only once ('fixed'). The energy distribution can be kept during optimization * ('keepE') or released ('freeE'). The time spent in steps 1 and 2 can be reduced * for a better optimization ('auto'). The neutrons passing during steps 1 and 2 * can be absorbed for a better neutron weight distribution ('absorb'). * * Source_optimizer can be placed just after the source (for instance). * Monitor_Optimizer should be placed at position to optimize. * * INPUT PARAMETERS: * * xmin: Lower x bound of optimizer opening (m) * xmax: Upper x bound of optimizer opening (m) * ymin: Lower y bound of optimizer opening (m) * ymax: Upper y bound of optimizer opening (m) * bins: Number of cells for sampling of neutron state distribution (10 is default) * step: Optimizer step (%, 10 is default). Overridden by 'auto' option. * The two first steps are not optimized. * keep: Percentage of initial source distribution kept (%, 10 is default) * file: Filename where to save optimized source distributions * options: string that can contain * 'continuous' for continuous source optimization (default) * 'fixed' same as 'not continuous' optimization * 'keepE' to keep energy and velocity if pos. (default) * 'freeE' same as 'no keepE' * 'verbose' displays optimization process * 'auto' uses the shortest possible 'step 1' and 'step 2' * and sets 'step' as required. * 'absorb' absorbs step 1 and 2 neutrons if possible. * * parameters bins, step, keep can be -1 for default values. * * OUTPUT PARAMETERS: * * distributions if filename is not empty ("") * * EXAMPLE: I use the following settings * xmin = -0.03, xmax = 0.03, * ymin = -0.06, ymax = 0.06, * bins = -1, step = -1, keep = -1, * file="source.optim", * options="absorb+auto" * A good optimization needs to record enough non optimized neutrons on Monitor * during step 2. Typical enhancement in computation speed is by a factor 20. * *******************************************************************************/ /* History : Sep 17 1999 : v0.00 first release (not effective) Sep 26 1999 : v0.01 New_Source for continuous optimisation Sep 27 1999 : optimizer is ok, but not very efficient Sep 29 1999 : v0.02 re-direct 'bad' neutrons instead of ABSORB (rand generator for nothing) Oct 06 1999 : v0.03 installed options, corrected bugs, improved efficiency */ /* NOTE : The 'Optim_' variables are reserved by those components. */ DEFINE COMPONENT Source_Optimizer DEFINITION PARAMETERS (xmin, xmax, ymin, ymax, bins, step, keep,file,options) SETTING PARAMETERS () STATE PARAMETERS (x,y,z,vx,vy,vz,t,s1,s2,p) DECLARE %{ #ifndef MCSTAS_GEN_OPTIM /* McStas General optimizer ID */ #define MCSTAS_GEN_OPTIM #else #error McStas : Source_Optimizer should only be used once per instrument #endif #ifndef FLT_MAX #define FLT_MAX 1e37 #endif #define OPTIM_PHASE_SET_LIMITS 0 /* set array limits to 0, then ask for GET_LIMITS */ #define OPTIM_PHASE_GET_LIMITS 1 /* compute array limits, then ask for SET_REF */ #define OPTIM_PHASE_SET_REF 2 /* set Ref and New_Source to to 0, then ask for GET_REF */ #define OPTIM_PHASE_GET_REF 3 /* compute Ref (and New_Source in Monitor), then ask for SET_SOURCE */ #define OPTIM_PHASE_SET_SOURCE 4 /* set Source to Ref*x%+New_Source, normalize to Ref, Passing to 0, then ask for OPTIM */ #define OPTIM_PHASE_OPTIM 5 /* Optimize and get New_Source (continuous optimization), then reask SET_SOURCE when required */ #define OPTIM_MOD_X 1 #define OPTIM_MOD_Y 2 #define OPTIM_MOD_VX 4 #define OPTIM_MOD_VY 8 #define OPTIM_MOD_VZ 16 #define OPTIM_MOD_S1 32 #define OPTIM_MOD_S2 64 #define OPTIM_MOD_P 128 /* These are distribution arrays[bins] within limits * flux is kept during optimisation * NOT stored : z is the position of this component * t time (linked to z) */ /* initial Reference distribution arrays (for weights) */ long *Optim_Reference_x; long *Optim_Reference_y; long *Optim_Reference_vx; long *Optim_Reference_vy; long *Optim_Reference_vz; long *Optim_Reference_s1; long *Optim_Reference_s2; long *Optim_Reference_p; /* optimized Source distribution arrays (to reach) */ long *Optim_Source_x; long *Optim_Source_y; long *Optim_Source_vx; long *Optim_Source_vy; long *Optim_Source_vz; long *Optim_Source_s1; long *Optim_Source_s2; long *Optim_Source_p; /* optimized New_Source distribution arrays (to reach in next step, passed to Source) */ long *Optim_New_Source_x; long *Optim_New_Source_y; long *Optim_New_Source_vx; long *Optim_New_Source_vy; long *Optim_New_Source_vz; long *Optim_New_Source_s1; long *Optim_New_Source_s2; long *Optim_New_Source_p; /* Passing distribution arrays (should grow to reach Source) */ long *Optim_Passing_x; long *Optim_Passing_y; long *Optim_Passing_vx; long *Optim_Passing_vy; long *Optim_Passing_vz; long *Optim_Passing_s1; long *Optim_Passing_s2; long *Optim_Passing_p; /* limits for state parameters */ /* x and y are Optimizer dimensions (input parameters) */ double Optim_x_min, Optim_x_max; double Optim_y_min, Optim_y_max; double Optim_vx_min, Optim_vx_max; double Optim_vy_min, Optim_vy_max; double Optim_vz_min, Optim_vz_max; double Optim_s1_min, Optim_s1_max; double Optim_s2_min, Optim_s2_max; double Optim_p_min, Optim_p_max; int Optim_index=0; /* a running Optim_index */ int Optim_index_x=0; /* indexes for last neutron that passed through */ int Optim_index_y=0; int Optim_index_vx=0; int Optim_index_vy=0; int Optim_index_vz=0; int Optim_index_s1=0; int Optim_index_s2=0; int Optim_index_p=0; int Optim_good_x=0; /* indexes for last 'good' neutron that passed through */ int Optim_good_y=0; int Optim_good_vx=0; int Optim_good_vy=0; int Optim_good_vz=0; int Optim_good_s1=0; int Optim_good_s2=0; int Optim_good_p=0; int Optim_bins; long Optim_n_redirect; /* number of consecutive ABSORB */ int Optim_Phase; /* Optimizer function */ long Optim_Phase_Counts =0; /* neutron counts to achieve in each Phase */ long Optim_Phase_Counts_L =0; /* neutron counts to achieve in Limits Phase */ long Optim_Phase_Counts_R =0; /* neutron counts to achieve in Reference Phase */ char Optim_Flag_Continuous =1; /* 1 : continuous Source optimization */ char Optim_Flag_Recycle =0; /* record of neutron state changes by OPTIM_MOD_xx */ char Optim_Flag_KeepE =1; /* 1 : keep E as poss. when recycling */ /* i.e. keep E and |v| distribution */ char Optim_Flag_Verbose =0; /* displays optimization informations */ char Optim_Flag_Absorb =0; /* 1 means that first steps non optimized neutrons are absorbed */ char Optim_Flag_Auto =0; /* 1 is for minimum counts in 2 first steps */ long Optim_Limits_Counts =0; /* passing neutron counts in each Optim_Phase */ long Optim_Reference_Counts =0; long Optim_Passing_Counts =0; long Optim_Monitor_Counts =0; double Optim_Limits_Flux =0; /* passing neutron flux in each Optim_Phase */ double Optim_Reference_Flux=0; double Optim_Passing_Flux =0; double Optim_Monitor_Flux =0; double Optim_Monitor_pmax =0; float Optim_keep; float Optim_step; double Optim_vx; /* save neutron characteristics for Monitor and ABSORDed->Redirected neutrons */ double Optim_vy; double Optim_vz; double Optim_x; double Optim_y; double Optim_s1; double Optim_s2; double Optim_p; double Optim_v2; double Optim_t1; /* tempo vars */ double Optim_t2; double Optim_t3; double Optim_u1; /* tempo vars */ double Optim_u2; double Optim_u3; int Optim_i1; /* tempo vars */ int Optim_i2; int Optim_i3; long Optim_Normal_Monitor_Counts = 0; /* counts without optim */ long Optim_Total_Monitor_Counts =0; /* final monitor counts */ FILE *hfile; /* end declare */ %} INITIALIZE %{ Optim_n_redirect = 0; Optim_Phase = OPTIM_PHASE_SET_LIMITS; Optim_x_min = xmin; Optim_x_max = xmax; Optim_y_min = ymin; Optim_y_max = ymax; Optim_bins = (int)bins; Optim_step = step; Optim_keep = keep; if (Optim_step < 0) Optim_step = .1; /* default values if -1 is given */ if (Optim_bins < 0) Optim_bins = 10; if (Optim_keep < 0) Optim_keep = .1; if (Optim_step >= 1) Optim_step = Optim_step/100; /* in case user gives % in 1-100 */ if (Optim_step < .01) Optim_step = .01; if (Optim_step > 1) Optim_step = 1; if (Optim_keep >= 1) Optim_keep = Optim_keep/100; /* in case user gives % in 1-100 */ if (Optim_keep < .01) Optim_keep = .01; if (Optim_keep > 1) Optim_keep = 1; Optim_Phase_Counts = mcget_ncount() * Optim_step; Optim_Phase_Counts_L = Optim_Phase_Counts; Optim_Phase_Counts_R = Optim_Phase_Counts; if (Optim_bins < 1) Optim_bins = 1; if (Optim_bins > 100) Optim_bins = 100; if (strstr(options,"continuous")) Optim_Flag_Continuous = 1; if (strstr(options,"fixed")) Optim_Flag_Continuous = 0; if (strstr(options,"keepE")) Optim_Flag_KeepE = 1; if (strstr(options,"freeE")) Optim_Flag_KeepE = 0; if (strstr(options,"verbose")) Optim_Flag_Verbose = 1; if (strstr(options,"auto")) { Optim_Flag_Auto = 1; if (Optim_bins*10 < Optim_Phase_Counts) Optim_Phase_Counts_L = Optim_bins*100; /* need at least 10 counts per bin for Limits */ Optim_Phase_Counts_R = mcget_ncount(); Optim_Phase_Counts = mcget_ncount(); } if (strstr(options,"absorb")) Optim_Flag_Absorb = 1; if ((Optim_Source_x = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_Source_y = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_Source_vx = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_Source_vy = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_Source_vz = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_Source_s1 = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_Source_s2 = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_Source_p = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_New_Source_x = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_New_Source_y = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_New_Source_vx = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_New_Source_vy = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_New_Source_vz = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_New_Source_s1 = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_New_Source_s2 = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_New_Source_p = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_Passing_x = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_Passing_y = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_Passing_vx = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_Passing_vy = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_Passing_vz = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_Passing_s1 = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_Passing_s2 = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_Passing_p = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_Reference_x = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_Reference_y = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_Reference_vx = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_Reference_vy = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_Reference_vz = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_Reference_s1 = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_Reference_s2 = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_Reference_p = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } /* end initialize */ %} TRACE %{ PROP_Z0; if (x>Optim_x_min && xOptim_y_min && y= Optim_Phase_Counts_L)) { Optim_Phase = OPTIM_PHASE_SET_REF; if (Optim_Flag_Verbose) printf(">> OPTIM_PHASE_SET_REF (%i neutrons)\n", Optim_Limits_Counts); } if ((Optim_Phase == OPTIM_PHASE_GET_REF) && (Optim_Reference_Counts >= Optim_Phase_Counts_R)) { Optim_Phase = OPTIM_PHASE_SET_SOURCE; Optim_Phase_Counts_R = Optim_Phase_Counts; if (Optim_Flag_Verbose) { printf(">> OPTIM_PHASE_SET_SOURCE (%i neutrons) from Ref\n", Optim_Reference_Counts); printf("Counts : reference = %i, passing = %i, monitor = %i\n", Optim_Reference_Counts, Optim_Reference_Counts, Optim_Monitor_Counts); printf("Flux : reference = %.2g, passing = %.2g, monitor = %.2g\n", Optim_Reference_Flux, Optim_Reference_Flux, Optim_Monitor_Flux); } } if ((Optim_Phase == OPTIM_PHASE_OPTIM) && (Optim_Passing_Counts >= Optim_Phase_Counts)) { Optim_Phase = OPTIM_PHASE_SET_SOURCE; if (Optim_Flag_Verbose) { printf(">> OPTIM_PHASE_SET_SOURCE (%i neutrons)\n", Optim_Passing_Counts); printf("Number of redirections : %i\n",Optim_n_redirect); printf("Counts : reference = %i, passing = %i, monitor = %i\n", Optim_Reference_Counts, Optim_Passing_Counts, Optim_Monitor_Counts); printf("Flux : reference = %.2g, passing = %.2g, monitor = %.2g\n", Optim_Reference_Flux, Optim_Passing_Flux, Optim_Monitor_Flux); } } /* handle Optim_Phase functions */ if (Optim_Phase == OPTIM_PHASE_SET_LIMITS) /* init : need to compute limits and flux */ { Optim_Limits_Counts = 0; Optim_Limits_Flux = 0; Optim_vx_min = FLT_MAX; Optim_vx_max = -FLT_MAX; Optim_vy_min = FLT_MAX; Optim_vy_max = -FLT_MAX; Optim_vz_min = FLT_MAX; Optim_vz_max = -FLT_MAX; Optim_s1_min = FLT_MAX; Optim_s1_max = -FLT_MAX; Optim_s2_min = FLT_MAX; Optim_s2_max = -FLT_MAX; Optim_p_min = FLT_MAX; Optim_p_max = -FLT_MAX; Optim_Phase = OPTIM_PHASE_GET_LIMITS; } /* end OPTIM_PHASE_SET_LIMITS */ if (Optim_Phase == OPTIM_PHASE_GET_LIMITS) /* init : need to compute limits and flux */ { Optim_Limits_Counts++; Optim_Limits_Flux += p; if (x < Optim_x_min) Optim_x_min = x; if (y < Optim_y_min) Optim_y_min = y; if (x > Optim_x_max) Optim_x_max = x; if (y > Optim_y_max) Optim_y_max = y; if (vx < Optim_vx_min) Optim_vx_min = vx; if (vx > Optim_vx_max) Optim_vx_max = vx; if (vy < Optim_vy_min) Optim_vy_min = vy; if (vy > Optim_vy_max) Optim_vy_max = vy; if (vz < Optim_vz_min) Optim_vz_min = vz; if (vz > Optim_vz_max) Optim_vz_max = vz; if (p < Optim_p_min) Optim_p_min = p; if (p > Optim_p_max) Optim_p_max = p; if (s1 < Optim_s1_min) Optim_s1_min = s1; if (s1 > Optim_s1_max) Optim_s1_max = s1; if (s2 < Optim_s2_min) Optim_s2_min = s2; if (s2 > Optim_s2_max) Optim_s2_max = s2; if (Optim_Flag_Absorb) ABSORB; } /* end if OPTIM_PHASE_GET_LIMITS */ if (Optim_Phase == OPTIM_PHASE_SET_REF) /* Set Ref and New_Source to 0 */ { Optim_Reference_Counts = 0; Optim_Reference_Flux = 0; Optim_Monitor_Counts = 0; /* also counted as New_Source */ Optim_Monitor_Flux = 0; for (Optim_index=0; Optim_index < Optim_bins; Optim_index++) { Optim_Reference_x[Optim_index] = 0; /* initial distribution will be recorded first */ Optim_Reference_y[Optim_index] = 0; Optim_Reference_vx[Optim_index] = 0; Optim_Reference_vy[Optim_index] = 0; Optim_Reference_vz[Optim_index] = 0; Optim_Reference_s1[Optim_index] = 0; Optim_Reference_s2[Optim_index] = 0; Optim_Reference_p[Optim_index] = 0; Optim_New_Source_x[Optim_index] = 0; /* Monitor_Optimizer will compute the */ Optim_New_Source_y[Optim_index] = 0; /* optimized New_Source distribution */ Optim_New_Source_vx[Optim_index] = 0; /* that will become Source for Optim Optim_step */ Optim_New_Source_vy[Optim_index] = 0; Optim_New_Source_vz[Optim_index] = 0; Optim_New_Source_s1[Optim_index] = 0; Optim_New_Source_s2[Optim_index] = 0; Optim_New_Source_p[Optim_index] = 0; } /* end for */ Optim_Phase = OPTIM_PHASE_GET_REF; } /* end OPTIM_PHASE_SET_REF */ if (Optim_Phase == OPTIM_PHASE_GET_REF) /* now build the Reference in limits */ { /* New_Source is set by Monitor_Optimizer */ Optim_Reference_Counts++; Optim_Reference_Flux += p; if (Optim_vx_max-Optim_vx_min) Optim_index = (int)rint(Optim_bins * (vx -Optim_vx_min)/(Optim_vx_max-Optim_vx_min)); else Optim_index = 0; if (Optim_index < 0) Optim_index = 0; if (Optim_index >= Optim_bins) Optim_index = Optim_bins - 1; Optim_Reference_vx[Optim_index]++; if (Optim_vy_max-Optim_vy_min) Optim_index = (int)rint(Optim_bins * (vy -Optim_vy_min)/(Optim_vy_max-Optim_vy_min)); else Optim_index = 0; if (Optim_index < 0) Optim_index = 0; if (Optim_index >= Optim_bins) Optim_index = Optim_bins - 1; Optim_Reference_vy[Optim_index]++; if (Optim_vz_max-Optim_vz_min) Optim_index = (int)rint(Optim_bins * (vz -Optim_vz_min)/(Optim_vz_max-Optim_vz_min)); else Optim_index = 0; if (Optim_index < 0) Optim_index = 0; if (Optim_index >= Optim_bins) Optim_index = Optim_bins - 1; Optim_Reference_vz[Optim_index]++; if (Optim_x_max-Optim_x_min) Optim_index = (int)rint(Optim_bins * (x -Optim_x_min)/(Optim_x_max-Optim_x_min)); else Optim_index = 0; if (Optim_index < 0) Optim_index = 0; if (Optim_index >= Optim_bins) Optim_index = Optim_bins - 1; Optim_Reference_x[Optim_index]++; if (Optim_y_max-Optim_y_min) Optim_index = (int)rint(Optim_bins * (y -Optim_y_min)/(Optim_y_max-Optim_y_min)); else Optim_index = 0; if (Optim_index < 0) Optim_index = 0; if (Optim_index >= Optim_bins) Optim_index = Optim_bins - 1; Optim_Reference_y[Optim_index]++; if (Optim_s1_max-Optim_s1_min) Optim_index = (int)rint(Optim_bins * (s1 -Optim_s1_min)/(Optim_s1_max-Optim_s1_min)); else Optim_index = 0; if (Optim_index < 0) Optim_index = 0; if (Optim_index >= Optim_bins) Optim_index = Optim_bins - 1; Optim_Reference_s1[Optim_index]++; if (Optim_s2_max-Optim_s2_min) Optim_index = (int)rint(Optim_bins * (s2 -Optim_s2_min)/(Optim_s2_max-Optim_s2_min)); else Optim_index = 0; if (Optim_index < 0) Optim_index = 0; if (Optim_index >= Optim_bins) Optim_index = Optim_bins - 1; Optim_Reference_s2[Optim_index]++; if (Optim_p_max-Optim_p_min) Optim_index = (int)rint(Optim_bins * (p -Optim_p_min)/(Optim_p_max-Optim_p_min)); else Optim_index = 0; if (Optim_index < 0) Optim_index = 0; if (Optim_index >= Optim_bins) Optim_index = Optim_bins - 1; Optim_Reference_p[Optim_index]++; } /* end if OPTIM_PHASE_GET_REF */ if (Optim_Phase == OPTIM_PHASE_SET_SOURCE) /* Define optimized Source (normalized to Reference) */ { if (Optim_Monitor_Counts) Optim_t1 = (1 - Optim_keep) * Optim_Reference_Counts/Optim_Monitor_Counts; else Optim_t1 = 0; Optim_Passing_Counts = 0; Optim_Passing_Flux = 0; if (Optim_Normal_Monitor_Counts == 0) Optim_Normal_Monitor_Counts = Optim_Total_Monitor_Counts; /* 2 first un-optimized steps */ Optim_Monitor_Counts = 0; /* also counted as New_Source */ Optim_Monitor_Flux = 0; for (Optim_index = 0; Optim_index < Optim_bins; Optim_index++) { /* get Optim_keep % of Reference, and 1-Optim_keep% of New_Source normalized to Reference Counts */ if (Optim_Flag_Continuous | (Optim_n_redirect == 0)) { Optim_Source_x[Optim_index] = (long)(rint(Optim_keep * Optim_Reference_x[Optim_index]) + Optim_t1 * Optim_New_Source_x[Optim_index] ); Optim_Source_y[Optim_index] = (long)(rint(Optim_keep * Optim_Reference_y[Optim_index]) + Optim_t1 * Optim_New_Source_y[Optim_index] ); Optim_Source_vx[Optim_index] = (long)(rint(Optim_keep * Optim_Reference_vx[Optim_index]) + Optim_t1 * Optim_New_Source_vx[Optim_index] ); Optim_Source_vy[Optim_index] = (long)(rint(Optim_keep * Optim_Reference_vy[Optim_index]) + Optim_t1 * Optim_New_Source_vy[Optim_index] ); Optim_Source_vz[Optim_index] = (long)(rint(Optim_keep * Optim_Reference_vz[Optim_index]) + Optim_t1 * Optim_New_Source_vz[Optim_index] ); Optim_Source_s1[Optim_index] = (long)(rint(Optim_keep * Optim_Reference_s1[Optim_index]) + Optim_t1 * Optim_New_Source_s1[Optim_index] ); Optim_Source_s2[Optim_index] = (long)(rint(Optim_keep * Optim_Reference_s2[Optim_index]) + Optim_t1 * Optim_New_Source_s2[Optim_index] ); Optim_Source_p[Optim_index] = (long)(rint(Optim_keep * Optim_Reference_p[Optim_index]) + Optim_t1 * Optim_New_Source_p[Optim_index] ); if (Optim_New_Source_x[Optim_index] > Optim_New_Source_x[Optim_good_x]) Optim_good_x = Optim_index; if (Optim_New_Source_y[Optim_index] > Optim_New_Source_y[Optim_good_y]) Optim_good_y = Optim_index; if (Optim_New_Source_vx[Optim_index] > Optim_New_Source_vx[Optim_good_vx]) Optim_good_vx = Optim_index; if (Optim_New_Source_vy[Optim_index] > Optim_New_Source_vy[Optim_good_vy]) Optim_good_vy = Optim_index; if (Optim_New_Source_vz[Optim_index] > Optim_New_Source_vz[Optim_good_vz]) Optim_good_vz = Optim_index; if (Optim_New_Source_s1[Optim_index] > Optim_New_Source_s1[Optim_good_s1]) Optim_good_s1 = Optim_index; if (Optim_New_Source_s2[Optim_index] > Optim_New_Source_s2[Optim_good_s2]) Optim_good_s2 = Optim_index; if (Optim_New_Source_p[Optim_index] > Optim_New_Source_p[Optim_good_p]) Optim_good_p = Optim_index; } Optim_Passing_x[Optim_index] = 0; /* Passing neutrons will then reach Source */ Optim_Passing_y[Optim_index] = 0; /* weights will be adapted to match Reference */ Optim_Passing_vx[Optim_index] = 0; Optim_Passing_vy[Optim_index] = 0; Optim_Passing_vz[Optim_index] = 0; Optim_Passing_s1[Optim_index] = 0; Optim_Passing_s2[Optim_index] = 0; Optim_Passing_p[Optim_index] = 0; Optim_New_Source_x[Optim_index] = 0; /* Init of next Source */ Optim_New_Source_y[Optim_index] = 0; Optim_New_Source_vx[Optim_index] = 0; Optim_New_Source_vy[Optim_index] = 0; Optim_New_Source_vz[Optim_index] = 0; Optim_New_Source_s1[Optim_index] = 0; Optim_New_Source_s2[Optim_index] = 0; Optim_New_Source_p[Optim_index] = 0; } /* end for */ Optim_Phase = OPTIM_PHASE_OPTIM; } /* end OPTIM_PHASE_SET_SOURCE */ if (Optim_Phase == OPTIM_PHASE_OPTIM) /* Use optimized Source */ { Optim_Flag_Recycle = 0; Optim_index_x = Optim_good_x; Optim_index_y = Optim_good_y; Optim_index_vx= Optim_good_vx; Optim_index_vy= Optim_good_vy; Optim_index_vz= Optim_good_vz; Optim_index_s1= Optim_good_s1; Optim_index_s2= Optim_good_s2; Optim_index_p = Optim_good_p; if (Optim_vz_max-Optim_vz_min) Optim_index = (int)rint(Optim_bins * (vz -Optim_vz_min)/(Optim_vz_max-Optim_vz_min)); else Optim_index = 0; if (Optim_index < 0) Optim_index = 0; if (Optim_index >= Optim_bins) Optim_index = Optim_bins - 1; if (Optim_Passing_vz[Optim_index] >= Optim_Source_vz[Optim_index]) { Optim_Flag_Recycle |= OPTIM_MOD_VX; Optim_vz += (Optim_index_vz-Optim_index)*(Optim_vz_max - Optim_vz_min)/Optim_bins; } else Optim_index_vz = Optim_index; if (Optim_vx_max-Optim_vx_min) Optim_index = (int)rint(Optim_bins * (vx -Optim_vx_min)/(Optim_vx_max-Optim_vx_min)); else Optim_index = 0; if (Optim_index < 0) Optim_index = 0; if (Optim_index >= Optim_bins) Optim_index = Optim_bins - 1; if (Optim_Passing_vx[Optim_index] >= Optim_Source_vx[Optim_index]) /* distribution achieved : redirect neutron near last neutron characteristic */ { Optim_Flag_Recycle |= OPTIM_MOD_VY; Optim_vx += (Optim_index_vx-Optim_index)*(Optim_vx_max - Optim_vx_min)/Optim_bins; } else Optim_index_vx = Optim_index; if (Optim_vy_max-Optim_vy_min) Optim_index = (int)rint(Optim_bins * (vy -Optim_vy_min)/(Optim_vy_max-Optim_vy_min)); else Optim_index = 0; if (Optim_index < 0) Optim_index = 0; if (Optim_index >= Optim_bins) Optim_index = Optim_bins - 1; if (Optim_Passing_vy[Optim_index] >= Optim_Source_vy[Optim_index]) { Optim_Flag_Recycle |= OPTIM_MOD_VZ; Optim_vy += (Optim_index_vy-Optim_index)*(Optim_vy_max - Optim_vy_min)/Optim_bins; } else Optim_index_vy = Optim_index; if ((Optim_Flag_Recycle & (OPTIM_MOD_VX|OPTIM_MOD_VY|OPTIM_MOD_VZ)) && Optim_Flag_KeepE) { /* now try to keep E distribution */ Optim_t1 = Optim_v2 - Optim_vz*Optim_vz - Optim_vy*Optim_vy; Optim_t2 = Optim_v2 - Optim_vz*Optim_vz - Optim_vx*Optim_vx; Optim_t3 = Optim_v2 - Optim_vx*Optim_vx - Optim_vy*Optim_vy; /* we affect the component wich is the most optimized (largest Source/Ref) */ if ((Optim_vx_max-Optim_vx_min) && (Optim_t1 > 0)) { Optim_t1 = sqrt(Optim_t1); if (vx < 0) Optim_t1 = -Optim_t1; Optim_i1 = (int)rint(Optim_bins * (Optim_t1 -Optim_vx_min)/(Optim_vx_max-Optim_vx_min)); if (Optim_i1 < 0) Optim_i1 = 0; if (Optim_i1 >= Optim_bins) Optim_i1 = Optim_bins - 1; Optim_u1 = (double)Optim_Source_vx[Optim_i1]/(Optim_Reference_vx[Optim_i1]+1); } else Optim_u1 = 0; if ((Optim_vy_max-Optim_vy_min) && (Optim_t2 > 0)) { Optim_t2 = sqrt(Optim_t2); if (vy < 0) Optim_t2 = -Optim_t2; Optim_i2 = (int)rint(Optim_bins * (Optim_t2 -Optim_vy_min)/(Optim_vy_max-Optim_vy_min)); if (Optim_i2 < 0) Optim_i2 = 0; if (Optim_i2 >= Optim_bins) Optim_i2 = Optim_bins - 1; Optim_u2 = (double)Optim_Source_vy[Optim_i2]/(Optim_Reference_vy[Optim_i2]+1); } else Optim_u2 = 0; if ((Optim_vz_max-Optim_vz_min) && (Optim_t3 > 0)) { Optim_t3 = sqrt(Optim_t3); if (vz < 0) Optim_t3 = -Optim_t3; Optim_i3 = (int)rint(Optim_bins * (Optim_t3 -Optim_vz_min)/(Optim_vz_max-Optim_vz_min)); if (Optim_i3 < 0) Optim_i3 = 0; if (Optim_i3 >= Optim_bins) Optim_i3 = Optim_bins - 1; Optim_u3 = (double)Optim_Source_vz[Optim_i3]/(Optim_Reference_vz[Optim_i3]+1); } else Optim_u3 = 0; if ((Optim_u1 > Optim_u2) && (Optim_u1 > Optim_u3)) { Optim_vx = Optim_t1; Optim_index_vx = Optim_i1; Optim_Flag_Recycle |= OPTIM_MOD_VX; Optim_index = -1; } if ((Optim_u2 > Optim_u1) && (Optim_u2 > Optim_u3) ) { Optim_vy = Optim_t2; Optim_index_vy = Optim_i2; Optim_Flag_Recycle |= OPTIM_MOD_VY; Optim_index = -1; } if ((Optim_u3 > Optim_u1) && (Optim_u3 > Optim_u1)) { Optim_vz = Optim_t3; Optim_index_vz = Optim_i3; Optim_Flag_Recycle |= OPTIM_MOD_VZ; Optim_index = -1; } } vx = Optim_vx; vy = Optim_vy; vz = Optim_vz; if (Optim_x_max-Optim_x_min) Optim_index = (int)rint(Optim_bins * (x -Optim_x_min)/(Optim_x_max-Optim_x_min)); else Optim_index = 0; if (Optim_index < 0) Optim_index = 0; if (Optim_index >= Optim_bins) Optim_index = Optim_bins - 1; if (Optim_Passing_x[Optim_index] >= Optim_Source_x[Optim_index]) { Optim_Flag_Recycle |= OPTIM_MOD_X; Optim_x += (Optim_index_x-Optim_index)*(Optim_x_max - Optim_x_min)/Optim_bins; x = Optim_x; } else Optim_index_x = Optim_index; if (Optim_y_max-Optim_y_min) Optim_index = (int)rint(Optim_bins * (y -Optim_y_min)/(Optim_y_max-Optim_y_min)); else Optim_index = 0; if (Optim_index < 0) Optim_index = 0; if (Optim_index >= Optim_bins) Optim_index = Optim_bins - 1; if (Optim_Passing_y[Optim_index] >= Optim_Source_y[Optim_index]) { Optim_Flag_Recycle |= OPTIM_MOD_Y; Optim_y += (Optim_index_y-Optim_index)*(Optim_y_max - Optim_y_min)/Optim_bins; y = Optim_y; } else Optim_index_y = Optim_index; if (Optim_s1_max-Optim_s1_min) Optim_index = (int)rint(Optim_bins * (s1 -Optim_s1_min)/(Optim_s1_max-Optim_s1_min)); else Optim_index = 0; if (Optim_index < 0) Optim_index = 0; if (Optim_index >= Optim_bins) Optim_index = Optim_bins - 1; if (Optim_Passing_s1[Optim_index] >= Optim_Source_s1[Optim_index]) { Optim_Flag_Recycle |= OPTIM_MOD_S1; Optim_s1 += (Optim_index_s1-Optim_index)*(Optim_s1_max - Optim_s1_min)/Optim_bins; s1 = Optim_s1; } else Optim_index_s1 = Optim_index; if (Optim_s2_max-Optim_s2_min) Optim_index = (int)rint(Optim_bins * (s2 -Optim_s2_min)/(Optim_s2_max-Optim_s2_min)); else Optim_index = 0; if (Optim_index < 0) Optim_index = 0; if (Optim_index >= Optim_bins) Optim_index = Optim_bins - 1; if (Optim_Passing_s2[Optim_index] >= Optim_Source_s2[Optim_index]) { Optim_Flag_Recycle |= OPTIM_MOD_S2; Optim_s2 += (Optim_index_s2-Optim_index)*(Optim_s2_max - Optim_s2_min)/Optim_bins; s2 = Optim_s2; } else Optim_index_s2 = Optim_index; if (Optim_p_max-Optim_p_min) Optim_index = (int)rint(Optim_bins * (p -Optim_p_min)/(Optim_p_max-Optim_p_min)); else Optim_index = 0; if (Optim_index < 0) Optim_index = 0; if (Optim_index >= Optim_bins) Optim_index = Optim_bins - 1; if (Optim_Passing_p[Optim_index] >= Optim_Source_p[Optim_index]) { Optim_Flag_Recycle |= OPTIM_MOD_P; Optim_p += (Optim_index_p-Optim_index)*(Optim_p_max - Optim_p_min)/Optim_bins; p = Optim_p; } else Optim_index_p = Optim_index; /* neutron is passed ! */ if (Optim_Source_vx[Optim_index_vx] && Optim_Source_vy[Optim_index_vy] && Optim_Source_vz[Optim_index_vz] && Optim_Source_x[Optim_index_x] && Optim_Source_y[Optim_index_y] && Optim_Source_s1[Optim_index_s1] && Optim_Source_s2[Optim_index_s2] && Optim_Source_p[Optim_index_p] && Optim_Reference_vx[Optim_index_vx] && Optim_Reference_vy[Optim_index_vy] && Optim_Reference_vz[Optim_index_vz] && Optim_Reference_x[Optim_index_x] && Optim_Reference_y[Optim_index_y] && Optim_Reference_s1[Optim_index_s1] && Optim_Reference_s2[Optim_index_s2] && Optim_Reference_p[Optim_index_p]) { Optim_t1 = 1; /* good neutrons have an improved distribution, so Ref/Source < 1 */ /* unmodified (form Ref kept fraction) neutrons have Passing < Ref*Optim_keep. their weight should be kept */ /* at the end there will be of those : 2*Optim_step*Optim_keep + (1-2*Optim_step)*Optim_keep = Optim_keep % of unmodified neutrons */ /* the remining part (1-Optim_keep neutrons) should have an integrated flux of (1-Optim_keep) */ Optim_t2 = (double)Optim_Reference_vx[Optim_index_vx]/Optim_Source_vx[Optim_index_vx]; if (Optim_t2 < 1) Optim_good_vx = Optim_index_vx; Optim_t1 *= Optim_t2; Optim_t2 = (double)Optim_Reference_vy[Optim_index_vy]/Optim_Source_vy[Optim_index_vy]; if (Optim_t2 < 1) Optim_good_vy = Optim_index_vy; Optim_t1 *= Optim_t2; Optim_t2 = (double)Optim_Reference_vz[Optim_index_vz]/Optim_Source_vz[Optim_index_vz]; if (Optim_t2 < 1) Optim_good_vz = Optim_index_vz; Optim_t1 *= Optim_t2; Optim_t2 = (double)Optim_Reference_x[Optim_index_x]/Optim_Source_x[Optim_index_x]; if (Optim_t2 < 1) Optim_good_x = Optim_index_x; Optim_t1 *= Optim_t2; Optim_t2 = (double)Optim_Reference_y[Optim_index_y]/Optim_Source_y[Optim_index_y]; if (Optim_t2 < 1) Optim_good_y = Optim_index_y; Optim_t1 *= Optim_t2; Optim_t2 = (double)Optim_Reference_s1[Optim_index_s1]/Optim_Source_s1[Optim_index_s1]; if (Optim_t2 < 1) Optim_good_s1= Optim_index_s1; Optim_t1 *= Optim_t2; Optim_t2 = (double)Optim_Reference_s2[Optim_index_s2]/Optim_Source_s2[Optim_index_s2]; if (Optim_t2 < 1) Optim_good_s2= Optim_index_s2; Optim_t1 *= Optim_t2; Optim_t2 = (double)Optim_Reference_p[Optim_index_p]/Optim_Source_p[Optim_index_p]; if (Optim_t2 < 1) Optim_good_p = Optim_index_p; Optim_t1 *= Optim_t2; /* now normalize to intial distribution */ Optim_p *= Optim_t1; if (Optim_Flag_Recycle) { Optim_n_redirect++; } /* Optim_p /= Optim_Flag_Recycle; */ p = Optim_p; } else ABSORB; /* can't modify neutron weight -> eject */ Optim_Passing_vx[Optim_index_vx]++; Optim_Passing_vy[Optim_index_vy]++; Optim_Passing_vz[Optim_index_vz]++; Optim_Passing_x[Optim_index_x]++; Optim_Passing_y[Optim_index_y]++; Optim_Passing_s1[Optim_index_s1]++; Optim_Passing_s2[Optim_index_s2]++; Optim_Passing_p[Optim_index_p]++; Optim_Passing_Counts++; Optim_Passing_Flux += p; } /* end if OPTIM_PHASE_OPTIM */ } /* end if xy in optimizer */ /* end trace */ %} FINALLY %{ if (strlen(file) > 0) { hfile = fopen(file, "w"); if(!hfile) { fprintf(stderr, "Error: %s : could not open output file '%s'\n", mccompcurname, file); } else { fprintf(hfile,"# Instrument-source: %s\n", mcinstrument_source); mcruninfo_out("# ", hfile); fprintf(hfile,"# type: array_2d(%i,6) \n",Optim_bins); fprintf(hfile,"# component: %s\n", mccompcurname); fprintf(hfile,"# title: General Optimizer distributions\n"); fprintf(hfile,"# filename: '%s'\n",file); fprintf(hfile,"# variables: x dx y dy vx dvx vy dvy vz dvz s1 ds1 s2 ds2 p dp\n"); fprintf(hfile,"# xvar: (x y vx vy vz s1 s2 p)\n"); fprintf(hfile,"# yvar: (dx dy dvx dvy dvz ds1 ds2 dp)\n"); fprintf(hfile,"# xlabel: 'Distributions'\n"); fprintf(hfile,"# ylabel: 'Counts'\n"); if (Optim_Normal_Monitor_Counts != 0) fprintf(hfile,"# Optimizer speedup estimate: %.3g [Monitor Normal counts %i (extrapolated), Optimized %i ]\n", (double)(Optim_Total_Monitor_Counts)/Optim_Normal_Monitor_Counts*2*Optim_step,(int)ceil(Optim_Normal_Monitor_Counts/2/Optim_step), Optim_Total_Monitor_Counts); fprintf(hfile,"# Optimizer options: %s\n",options); fprintf(hfile,"# Redirected neutrons: %i (%.2f \%)\n",Optim_n_redirect,(double)(100*Optim_n_redirect/mcget_ncount())); fprintf(hfile,"# data: Optimzed Source\n"); for (Optim_index = 0; Optim_index < Optim_bins; Optim_index++) { fprintf(hfile,"%10.4g ",(Optim_x_min+((Optim_index+0.5)/Optim_bins)*(Optim_x_max - Optim_x_min))); fprintf(hfile,"%10i\t",Optim_Source_x[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_y_min+((Optim_index+0.5)/Optim_bins)*(Optim_y_max - Optim_y_min))); fprintf(hfile,"%10i\t",Optim_Source_y[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_vx_min+((Optim_index+0.5)/Optim_bins)*(Optim_vx_max - Optim_vx_min))); fprintf(hfile,"%10i\t",Optim_Source_vx[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_vy_min+((Optim_index+0.5)/Optim_bins)*(Optim_vy_max - Optim_vy_min))); fprintf(hfile,"%10i\t",Optim_Source_vy[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_vz_min+((Optim_index+0.5)/Optim_bins)*(Optim_vz_max - Optim_vz_min))); fprintf(hfile,"%10i\t",Optim_Source_vz[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_s1_min+((Optim_index+0.5)/Optim_bins)*(Optim_s1_max - Optim_s1_min))); fprintf(hfile,"%10i\t",Optim_Source_s1[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_s2_min+((Optim_index+0.5)/Optim_bins)*(Optim_s2_max - Optim_s2_min))); fprintf(hfile,"%10i\t",Optim_Source_s2[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_p_min+((Optim_index+0.5)/Optim_bins)*(Optim_p_max - Optim_p_min))); fprintf(hfile,"%10i\t",Optim_Source_p[Optim_index]); fprintf(hfile,"\n"); } fprintf(hfile,"# data: Reference Source\n"); for (Optim_index = 0; Optim_index < Optim_bins; Optim_index++) { fprintf(hfile,"%10.4g ",(Optim_x_min+((Optim_index+0.5)/Optim_bins)*(Optim_x_max - Optim_x_min))); fprintf(hfile,"%10i\t",Optim_Reference_x[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_y_min+((Optim_index+0.5)/Optim_bins)*(Optim_y_max - Optim_y_min))); fprintf(hfile,"%10i\t",Optim_Reference_y[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_vx_min+((Optim_index+0.5)/Optim_bins)*(Optim_vx_max - Optim_vx_min))); fprintf(hfile,"%10i\t",Optim_Reference_vx[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_vy_min+((Optim_index+0.5)/Optim_bins)*(Optim_vy_max - Optim_vy_min))); fprintf(hfile,"%10i\t",Optim_Reference_vy[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_vz_min+((Optim_index+0.5)/Optim_bins)*(Optim_vz_max - Optim_vz_min))); fprintf(hfile,"%10i\t",Optim_Reference_vz[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_s1_min+((Optim_index+0.5)/Optim_bins)*(Optim_s1_max - Optim_s1_min))); fprintf(hfile,"%10i\t",Optim_Reference_s1[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_s2_min+((Optim_index+0.5)/Optim_bins)*(Optim_s2_max - Optim_s2_min))); fprintf(hfile,"%10i\t",Optim_Reference_s2[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_p_min+((Optim_index+0.5)/Optim_bins)*(Optim_p_max - Optim_p_min))); fprintf(hfile,"%10i\t",Optim_Reference_p[Optim_index]); fprintf(hfile,"\n"); } fprintf(hfile,"# data: Passing\n"); for (Optim_index = 0; Optim_index < Optim_bins; Optim_index++) { fprintf(hfile,"%10.4g ",(Optim_x_min+((Optim_index+0.5)/Optim_bins)*(Optim_x_max - Optim_x_min))); fprintf(hfile,"%10i\t",Optim_Passing_x[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_y_min+((Optim_index+0.5)/Optim_bins)*(Optim_y_max - Optim_y_min))); fprintf(hfile,"%10i\t",Optim_Passing_y[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_vx_min+((Optim_index+0.5)/Optim_bins)*(Optim_vx_max - Optim_vx_min))); fprintf(hfile,"%10i\t",Optim_Passing_vx[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_vy_min+((Optim_index+0.5)/Optim_bins)*(Optim_vy_max - Optim_vy_min))); fprintf(hfile,"%10i\t",Optim_Passing_vy[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_vz_min+((Optim_index+0.5)/Optim_bins)*(Optim_vz_max - Optim_vz_min))); fprintf(hfile,"%10i\t",Optim_Passing_vz[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_s1_min+((Optim_index+0.5)/Optim_bins)*(Optim_s1_max - Optim_s1_min))); fprintf(hfile,"%10i\t",Optim_Passing_s1[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_s2_min+((Optim_index+0.5)/Optim_bins)*(Optim_s2_max - Optim_s2_min))); fprintf(hfile,"%10i\t",Optim_Passing_s2[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_p_min+((Optim_index+0.5)/Optim_bins)*(Optim_p_max - Optim_p_min))); fprintf(hfile,"%10i\t",Optim_Passing_p[Optim_index]); fprintf(hfile,"\n"); } fprintf(hfile,"# data: New_Source\n"); for (Optim_index = 0; Optim_index < Optim_bins; Optim_index++) { fprintf(hfile,"%10.4g ",(Optim_x_min+((Optim_index+0.5)/Optim_bins)*(Optim_x_max - Optim_x_min))); fprintf(hfile,"%10i\t",Optim_New_Source_x[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_y_min+((Optim_index+0.5)/Optim_bins)*(Optim_y_max - Optim_y_min))); fprintf(hfile,"%10i\t",Optim_New_Source_y[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_vx_min+((Optim_index+0.5)/Optim_bins)*(Optim_vx_max - Optim_vx_min))); fprintf(hfile,"%10i\t",Optim_New_Source_vx[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_vy_min+((Optim_index+0.5)/Optim_bins)*(Optim_vy_max - Optim_vy_min))); fprintf(hfile,"%10i\t",Optim_New_Source_vy[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_vz_min+((Optim_index+0.5)/Optim_bins)*(Optim_vz_max - Optim_vz_min))); fprintf(hfile,"%10i\t",Optim_New_Source_vz[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_s1_min+((Optim_index+0.5)/Optim_bins)*(Optim_s1_max - Optim_s1_min))); fprintf(hfile,"%10i\t",Optim_New_Source_s1[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_s2_min+((Optim_index+0.5)/Optim_bins)*(Optim_s2_max - Optim_s2_min))); fprintf(hfile,"%10i\t",Optim_New_Source_s2[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_p_min+((Optim_index+0.5)/Optim_bins)*(Optim_p_max - Optim_p_min))); fprintf(hfile,"%10i\t",Optim_New_Source_p[Optim_index]); fprintf(hfile,"\n"); } fclose(hfile); } if (Optim_Flag_Verbose) { printf("End of optimization\n"); printf("Optim_Normal_Monitor_Counts = %i (2 steps), Optim_Total_Monitor_Counts = %i \n",Optim_Normal_Monitor_Counts, Optim_Total_Monitor_Counts); if (Optim_Normal_Monitor_Counts != 0) printf("Optimizer speedup : %.3g \n", (double)(Optim_Total_Monitor_Counts)/Optim_Normal_Monitor_Counts*2*Optim_step); printf("Number of redirections : %i\n",Optim_n_redirect); printf("Counts : reference = %i, passing = %i, monitor = %i\n", Optim_Reference_Counts, Optim_Passing_Counts, Optim_Monitor_Counts); printf("Flux : reference = %.2g, passing = %.2g, monitor = %.2g\n", Optim_Reference_Flux, Optim_Passing_Flux, Optim_Monitor_Flux); } } %} MCDISPLAY %{ magnify("xy"); multiline(5, (double)xmin, (double)ymin, 0.0, (double)xmax, (double)ymin, 0.0, (double)xmax, (double)ymax, 0.0, (double)xmin, (double)ymax, 0.0, (double)xmin, (double)ymin, 0.0); %} END From farhi at ill.fr Thu Oct 21 18:58:06 1999 From: farhi at ill.fr (Farhi) Date: Thu, 21 Oct 1999 18:58:06 +0200 Subject: McStas : flux adapter Message-ID: <380F461E.30D06E09@ill.fr> Hello Kristian, I've written a component in order to adapt a flux to a real reactor distribution. It can handle tables versus energy, wavevector and wavelength, and works with an external 'flux description' file in free format (just needs to see two columns somewhere inside). I attach an example (with the in14_6 instrument version "60a", also provided). The optimizer works fine with the flux adapter . I've improved the optimzer (works with any flux distrubution, auto mode is now better, and some new options and default mode is more general). Hope you'll enjoy this. .In real usage, the flux description file should be normalized when in 'multiply' mode. Concerning some 'spikes' of weight 'p' that I had after the optimization in the (k,w) distribution, they are normal : as some neutrons are not very efficient, and so not often used, thiri weight is bigger. One should then integrate somehow the p distribution. A neutron alone is not representative, but an assembly is ok. Cheers... EF. -- Emmanuel FARHI, http://www.ill.fr/tas/people/Farhi.html \|/ ____ \|/ TAS-Group, Institut Laue-Langevin (ILL) Grenoble ~@-/ oO \-@~ Avenue des Martyrs, BP 156, 38042 Grenoble Cedex 9,France /_( \__/ )_\ Work :Tel (33/0) 4 76 20 71 83. Fax (33/0) 4 76 48 39 06 \__U_/ La Grande Arche, Chateau d'Uriage, 38410 Saint Martin d'Uriage 04 76 59 73 94 -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- DEFINE INSTRUMENT IN14(KI,WN,ORDER,MHV) /* preprocess with : mcstas in14_4.instr */ /* compile on mica with : cc -Ofast -64 -o in14_3 in14_3.c -lm */ /* Test with : */ /* in14_6 -n 1e6 KI=2.66 WN=0.03 ORDER=1 MHV=3 */ DECLARE %{ #define VERSION "60a" double L1 = 16.68; /* source-mono */ double L2 = 2.12; /* mono-sample */ double L3 = 1.35; /* sample-ana */ double L4 = 0.70; /* ana-det */ int SM,SS,SA; double A1,A3,A5; double LM1, LM1b; /* distances to monitors M1 and M2 */ double LM2, LM2b; double A2,A4,A6,RM,RH; char *pfile; char *efile; char *dfile; char *kfile; /* ==================== Source description ==================== */ double EN; double D_EN; double EMIN, EMAX; double FLUX = 1e13; /* n/cm^2/s on guide entry */ /* ==================== Monochromator desciption ==================== */ double ETAM = 30; /* Mosaicity used on monochromator 30 */ double DM = 3.355; /* Monochromator d-spacing in Angs */ /* PG002 Orders : 1st 3.355 2e 1.6775, 3e 1.1183 */ double mono_r0 = 0.9; /* mean reflectivity */ double mono_width = 0.15; double mono_heigh = .122; double mono_gap = 0; /* slates are adjacent */ int mono_segment_number_vert = 7; int mono_segment_number_horz = 1; double mono_curv_vert; /* Vertical Rotation between adjacent slabs. */ double mono_curv_horz; /* Horizontal Rotation between adjacent slabs. */ double mono_slate_heigh; /* size (height) of slates */ double mono_slate_width; /* size (width) of slates */ double mono_q; /* Q vector for bragg scattering with monochromator and analysator */ double Ki, Ei; double TM, GM; /* ==================== Sample desciption ==================== */ double TU, TL; double GU, GL; /* ==================== Analyser desciption ==================== */ double ETAA = 30; /* Mosaicity used on analyser 30 */ double DA = 3.355; /* analyser d-spacing in Angs */ /* PG002 Orders : 1st 3.355 2e 1.6775, 3e 1.1183 */ double ana_r0 = 0.9; /* mean reflectivity */ double ana_width = 0.10; double ana_heigh = .14; double ana_gap = 0; /* slates are adjacent */ int ana_segment_number_vert = 7; int ana_segment_number_horz = 1; double ana_curv_vert; /* Vertical Rotation between adjacent slabs. */ double ana_curv_horz; /* Horizontal Rotation between adjacent slabs. */ double ana_slate_heigh; /* size (height) of slates */ double ana_slate_width; /* size (width) of slates */ double ana_q; /* Q vector for bragg scattering with monochromator and analysator */ double Kf, Ef; double TA, GA; %} INITIALIZE %{ double vi,vf,sample_q; mono_q = 2*PI*ORDER/DM; /* Q mono in Angs-1 */ A4 = 0; A2 = asin(mono_q/2/KI)*RAD2DEG*2; A6 = A2; printf("Instrument : IN14, v%s (21/09/99) on %s.\n",VERSION,getenv("HOSTNAME")); /* SM : scattering at mono to the right (-1)/left(+1) */ /* SS : scattering at sample to the right (-1)/left(+1) */ /* SA : scattering at analyser to the right (-1)/left(+1) */ SM = 1; SS = 1; SA = 1; A2 *= SM; /* A1 : mono theta (crystal) */ A1 = A2/2; /* A2 : mono 2 theta (arm to sample) */ A4 *= SS; /* A3 : sample theta */ A3 = A4/2; /* A4 : sample 2 theta (arm to analyser) */ A6 *= SA; /* A5 : analyser theta (crystal) */ A5 = A6/2; /* A6 : analyser 2 theta (arm to detector) */ TM = 0; /* TM : translation mono */ GM = 0; /* GM : tilt mono */ GU = 0; /* GU : tilt sample Up */ GL = 0; /* GL : tilt sample Low */ TU = 0; /* TU : translation sample Up */ TL = 0; /* TL : translation sample Low */ TA = 0; /* TA : translation analyser */ GA = 0; /* GA : tilt analyser */ /* RA : horizontal curvature analyser */ if ((fabs(mono_q/2/KI) < 1) && (sin(DEG2RAD*A1) != 0)) Ki = mono_q/2/sin(DEG2RAD*A1); else { printf("Warn : Can't define incident wave vector Ki\n"); Ki = 0; printf("Skipping simulation\n"); exit(-1); } vi = K2V*fabs(Ki); Ei = VS2E*vi*vi; EN = Ei; D_EN = .5; /* optimize source on Ki */ ana_q = 2*PI/DA; /* Q ana in Angs-1 */ if (sin(DEG2RAD*A5) != 0) Kf = ana_q/2/sin(DEG2RAD*A5); else { printf("Warn : Can't define outgoing wave vector Kf\n"); Kf = 0; } vf = K2V*fabs(Kf); Ef = VS2E*vf*vf; sample_q = sqrt(Ki*Ki + Kf*Kf -2*fabs(Ki*Kf)*cos(DEG2RAD*A4)); mono_slate_heigh = mono_heigh/mono_segment_number_vert; /* slates are adjacent */ mono_curv_vert = fabs(mono_slate_heigh*RAD2DEG/(2*L2*sin(DEG2RAD*A1))); /* RM : vertical mono curvature */ mono_slate_width = mono_width/mono_segment_number_horz; /* slates are adjacent */ mono_curv_horz = fabs(mono_slate_width*RAD2DEG*sin(DEG2RAD*A1)/(2*L2)); /* RH : horizontal mono curvature */ ana_slate_heigh = ana_heigh/ana_segment_number_vert; /* slates are adjacent */ ana_curv_vert = fabs(ana_slate_heigh*RAD2DEG/(2*L3*sin(DEG2RAD*A5))); /* RA : vertical ana curvature */ ana_slate_width = ana_width/ana_segment_number_horz; /* slates are adjacent */ ana_curv_horz = fabs(ana_slate_width*RAD2DEG*sin(DEG2RAD*A5)/(2*L3)); /* RHA : horizontal ana curvature */ /* print instrument config */ printf("Flat source, m=%.2f noze, width %.2f\n",MHV,WN); printf("Monochromator : (DM = %g)\n",DM); printf("A1 = %.2f, A2 = %.2f (deg)\n",A1,A2); printf("Ki = %.3g Angs-1 (Energy = %.3g meV, Velocity = %.3g m/s) \n", Ki, Ei,vi); printf("RM = %.3g Deg, RH = %.3g Deg\n",mono_curv_vert,mono_curv_horz); printf("\n"); printf("Sample :\n"); printf("A3 = %.2f, A4 = %.2f (deg)\n",A3,A4); printf("Energy transfert %.3g meV, Moment transfert %.3g Angs-1\n",Ef-Ei,sample_q); printf("\n"); printf("Analyser : (DA = %g)\n",DA); printf("A5 = %.2f, A6 = %.2f (deg)\n",A5,A6); printf("Kf = %.3g Angs-1 (Energy = %.3g meV, Velocity = %.3g m/s) \n", Kf, Ef,vf); printf("RA = %.3g Deg\n",ana_curv_vert); printf("\n"); printf("Detectors :\n"); /* local variables ------------------------------------ */ LM1 = L2*.9; LM1b = LM1+0.001; LM2 = L3/2; LM2b = LM2+0.001; EMIN = EN - D_EN; EMAX = EN + D_EN; pfile = (char *)malloc(256); efile = (char *)malloc(256); dfile = (char *)malloc(256); kfile = (char *)malloc(256); sprintf(pfile,"sim/i%s_k%iw%id%im%i.psd",VERSION,(int)floor(10*Ki+0.5),(int)floor(1000*WN),(int)floor(ORDER),(int)floor(MHV+0.5)); sprintf(efile,"sim/i%s_k%iw%id%im%i.nrj",VERSION,(int)floor(10*Ki+0.5),(int)floor(1000*WN),(int)floor(ORDER),(int)floor(MHV+0.5)); sprintf(dfile,"sim/i%s_k%iw%id%im%i.div",VERSION,(int)floor(10*Ki+0.5),(int)floor(1000*WN),(int)floor(ORDER),(int)floor(MHV+0.5)); sprintf(kfile,"sim/i%s_k%iw%id%im%i.kw",VERSION,(int)floor(10*Ki+0.5),(int)floor(1000*WN),(int)floor(ORDER),(int)floor(MHV+0.5)); %} TRACE COMPONENT origin = Arm() AT (0,0,0) ABSOLUTE COMPONENT source = Source_flux( radius = 0.20, dist = 2.16, xw = 0.06, yh = 0.12, E0 = EN, dE = D_EN, flux=FLUX) AT (0,0,0) RELATIVE origin ROTATED (0,0,0) RELATIVE origin COMPONENT fa = Flux_adapter( xmin = -0.1, xmax = 0.1, ymin = -0.1, ymax = 0.1, file="source.flux", options="") AT (0,0,0.1) RELATIVE origin ROTATED (0,0,0) RELATIVE origin COMPONENT kw1 = kw_monitor( xmin = -0.01, xmax = 0.01, ymin = -0.01, ymax = 0.01, filename = "kguide.kw") AT(0, 0, 2.14) RELATIVE origin ROTATED (0,0,0) RELATIVE origin COMPONENT optim_s = Source_Optimizer( xmin = -0.03, xmax = 0.03, ymin = -0.06, ymax = 0.06, bins = -1, step = 10, keep = 10, file="source.optim", options="auto") AT (0,0,2.145) RELATIVE origin ROTATED (0,0,0) RELATIVE origin COMPONENT doigt_de_gant = Guide( w1 = 0.06, h1 = 0.12, w2 = 0.06, h2 = 0.12, l = 2.75, /* guide into the doigt de gant */ R0 = 1, m=1.2, /* Ni 58 */ Qc = 0.021, alpha = 2.33, W = 2e-3) AT (0,0,2.15) RELATIVE origin ROTATED (0,0,0) RELATIVE origin COMPONENT external_guide = Guide2( w1 = 0.06, h1 = 0.12, w2 = 0.06, h2 = 0.12, l = 13.67, /* external guide between doigt de gant and mono */ R0 = 1, Qc = 0.021, alpha = 2.33, mh=1.2, /* 1.2 Ni 58, 3 Super mirror */ mv=1.2, W = 2e-3) AT (0,0,4.91) RELATIVE origin ROTATED (0,0,0) RELATIVE origin /* -------------- Start of monochromator building -------------- */ /* support of mono */ COMPONENT focus_mono = Arm() AT (0, 0, L1) RELATIVE origin ROTATED (0, A1, 0) RELATIVE origin COMPONENT m0 = Mon_2foc( zwidth=mono_slate_width, ywidth=mono_slate_heigh, gap=mono_gap, NH=mono_segment_number_vert, NV=mono_segment_number_horz, mosaich=ETAM, mosaicv=ETAM, r0=mono_r0, Q=mono_q, RH=mono_curv_vert, RV=mono_curv_horz) AT (TM, 0, 0) RELATIVE focus_mono ROTATED (0, 0, GM) RELATIVE focus_mono /* on mono, pointing towards sample */ COMPONENT out_mono = Arm() AT (0,0,0) RELATIVE focus_mono ROTATED (0, A2, 0) RELATIVE origin /* -------------- End of monochromator building -------------- */ COMPONENT noze = Guide2( w1 = 0.05, h1 = 0.05, w2 = WN, h2 = 0.05, l = .825, R0 = 1, Qc = 0.021, alpha = 2.33, mh=1e-5, mv = MHV, /* Ni 58 */ W = 2e-3) AT (0, 0, .9) RELATIVE out_mono ROTATED (0,0,0) RELATIVE out_mono /* COMPONENT M1 = Monitor( xmin = -0.03, xmax = 0.03, ymin = -0.06, ymax = 0.06) AT (0, 0, LM1) RELATIVE out_mono ROTATED (0,0,0) RELATIVE out_mono */ /* -------------- Start of sample building -------------- */ /* support of sample */ COMPONENT focus_sample = Arm() AT (0, 0, L2) RELATIVE out_mono ROTATED (0,A3,0) RELATIVE out_mono /* COMPONENT sample = Powder1( radius = 0.007, h = 0.015, q = 1.8049, d_phi0 = 4, pack = 1, j = 6, DW = 1, F2 = 56.8, Vc = 85.0054, sigma_a = 0.463, target_x = alu_focus_x, target_y = 0, target_z = 1000) AT (GU, 0, GL) RELATIVE focus_sample ROTATED (TU,0,TL) RELATIVE focus_sample */ /* COMPONENT AtSample = Monitor( xmin = -0.05, xmax = 0.05, ymin = -0.05, ymax = 0.05) AT (0, 0, 0) RELATIVE focus_sample ROTATED (0,0,0) RELATIVE focus_sample */ COMPONENT optim_m = Monitor_Optimizer( xmin = -0.05, xmax = 0.05, ymin = -0.05, ymax = 0.05) AT(0, 0, 0) RELATIVE focus_sample ROTATED (0,0,0) RELATIVE focus_sample COMPONENT PSDSample = PSD_monitor( xmin = -0.05, xmax = 0.05, ymin = -0.05, ymax = 0.05, nx = 50, ny = 50, filename = pfile) AT(0, 0, 0.001) RELATIVE focus_sample ROTATED (0,0,0) RELATIVE focus_sample COMPONENT Int4Sample = Monitor( xmin = -0.02, xmax = 0.02, ymin = -0.02, ymax = 0.02) AT(0, 0, 0.002) RELATIVE focus_sample ROTATED (0,0,0) RELATIVE focus_sample COMPONENT Flux1Sample = Monitor( xmin = -0.005, xmax = 0.005, ymin = -0.005, ymax = 0.005) AT(0, 0, 0.003) RELATIVE focus_sample ROTATED (0,0,0) RELATIVE focus_sample COMPONENT ESample = E_monitor( xmin = -0.005, xmax = 0.005, ymin = -0.005, ymax = 0.005, Emin = EMIN, Emax = EMAX, nchan = 21, filename = efile) AT(0, 0, 0.004) RELATIVE focus_sample ROTATED (0,0,0) RELATIVE focus_sample COMPONENT DivSample = Divergence_monitor( xmin = -0.005, xmax = 0.005, ymin = -0.005, ymax = 0.005, nv = 10, nh= 10, v_maxdiv = 1, h_maxdiv = 1, filename = dfile) AT(0, 0, 0.005) RELATIVE focus_sample ROTATED (0,0,0) RELATIVE focus_sample COMPONENT kw = kw_monitor( xmin = -0.005, xmax = 0.005, ymin = -0.005, ymax = 0.005, filename = kfile) AT(0, 0, 0.006) RELATIVE focus_sample ROTATED (0,0,0) RELATIVE focus_sample /* on sample, pointing towards ana */ COMPONENT out_sample = Arm() AT (0,0,0) RELATIVE focus_sample ROTATED (0, A4, 0) RELATIVE out_mono /* -------------- End of sample building -------------- */ /* COMPONENT M2 = Monitor( xmin = -0.1, xmax = 0.1, ymin = -0.1, ymax = 0.1) AT (0, 0, LM2) RELATIVE out_sample ROTATED (0,0,0) RELATIVE out_sample */ /* -------------- Start of analyzer building -------------- */ /* support of analyzer */ /* COMPONENT focus_ana = Arm() AT (0, 0, L3) RELATIVE out_sample ROTATED (0,A5,0) RELATIVE out_sample COMPONENT a0 = Mon_2foc( zwidth = ana_half_width, ywidth = ana_half_heigh, gap = 0, NH = 1, NV = 1, mosaich = ETAA, mosaicv = ETAA, r0 = ana_r0, Q = ana_q, RH=ana_curv_vert, RV=ana_curv_horz) AT (TA, 0, 0) RELATIVE focus_ana ROTATED (0, 0, GA) RELATIVE focus_ana COMPONENT out_ana = Arm() AT (0, 0, 0) RELATIVE focus_ana ROTATED (0, A6, 0) RELATIVE out_sample */ /* -------------- End of analyzer building -------------- */ /* COMPONENT focus_det = Arm() AT (0, 0, L4) RELATIVE out_ana ROTATED (0,0,0) RELATIVE out_ana COMPONENT Detector = Monitor( xmin = -0.02, xmax = 0.02, ymin = -0.05, ymax = 0.05) AT(0, 0, 0) RELATIVE focus_det ROTATED (0,0,0) RELATIVE focus_det COMPONENT emon2 = E_monitor( xmin = -0.02, xmax = 0.02, ymin = -0.05, ymax = 0.05, Emin = 10, Emax = 20, nchan = 35, filename = "sim/in14_EM2.vmon") AT(0, 0, 0.01) RELATIVE focus_det ROTATED (0,0,0) RELATIVE focus_det */ FINALLY %{ printf("Output files : %s %s %s %s\n",pfile,efile,dfile,kfile); free(pfile); free(dfile); free(efile); free(kfile); %} END -------------- next part -------------- # energy multiply 0 3 2 3 10 3 100 3 -------------- next part -------------- /*********************************************************************** * * McStas, version 1.1, released ?? * Maintained by Kristian Nielsen and Kim Lefmann, * Risoe National Laboratory, Roskilde, Denmark * * Component: Flux_adapter * * Written by: EF, Oct 14, 1999 * * The routine changes the neutron flux (weight) in order to match * a reference source table on disk. This file can be on format * (k[Angs-1],p), (omega[meV],p), (lambda[Angs],p) where p is the weight * A linear interpolation is performed during simulation. * This component should be placed after a source, in order to * simulate a real source. * * file : name of the file to look at (two columns data) * data should be sorted (ascending order) and monotonic * file can contain options (see below) as comment * options : string that can contain * "[ k p ]" or "wavector" for file type * "[ omega p]" or "energy" * "[ lambda p ]" or "wavelength" * "set" to set the weight according to the table * "multiply" to multiply (instead of set) the weight by factor * "add" to add to current flux * "unactivate" to unactivate flux_adapter (in flux file for test) * "verbose" to display additional informations * * EXAMPLE : * (xmin = -0.1, xmax = 0.1, * ymin = -0.1, ymax = 0.1, * file="source.flux", * options="") * With file "source.flux" beeing something like * # energy multiply * # [ meV flux_factor ] * 0 1 * 2 1.2 * 10 1.5 * 100 1 * ***********************************************************************/ DEFINE COMPONENT Flux_adapter DEFINITION PARAMETERS (xmin, xmax, ymin, ymax, file, options) SETTING PARAMETERS () OUTPUT PARAMETERS (KE_Table,Weight_Table,Type_table,Mode_Table,Length_Table) STATE PARAMETERS (x,y,z,vx,vy,vz,t,s1,s2,p) DECLARE %{ #define LINE_MAX_LENGTH 1024 #define UNKNOWN_TABLE 0 #define ENERGY_TABLE 1 #define WAVEVECTOR_TABLE 2 #define WAVELENGTH_TABLE 3 #define FLUX_ADAPT_SET 0 #define FLUX_ADAPT_MULT 1 #define FLUX_ADAPT_ADD 2 FILE *hfile; /* id for data file */ char line[LINE_MAX_LENGTH]; long line_count_in_file = 0; long line_count_in_array = 0; long malloc_size = 100; char flag_exit_loop = 0; char flag_in_array = 0; char Type_Table = UNKNOWN_TABLE; double X,P; double *Weight_Table; double *KE_Table; long Length_Table=0; char Mode_Table = FLUX_ADAPT_SET; char verbose=0; int i; double v2,K,L,E,new_p,slope; double X1,X2,Y1,Y2; /* end of declare */ %} INITIALIZE %{ KE_Table = (double*)malloc(malloc_size*sizeof(double)); Weight_Table = (double*)malloc(malloc_size*sizeof(double)); hfile = fopen(file, "r"); if(!hfile) { fprintf(stderr, "Error: %s : could not open input file '%s'\n", mccompcurname, file); } else /* now look for the data */ { /* initialize data array */ if (strstr(options," k") || strstr(options," K ") || strstr(options,"wavevector")) Type_Table = WAVEVECTOR_TABLE; if (strstr(options,"omega") || strstr(options," e ") || strstr(options," E ") || strstr(options,"energy")) Type_Table = ENERGY_TABLE; if (strstr(options,"lambda") || strstr(options,"wavelength") || strstr(options," L ")) Type_Table = WAVELENGTH_TABLE; if (strstr(options,"set")) Mode_Table = FLUX_ADAPT_SET; if (strstr(options,"add")) Mode_Table = FLUX_ADAPT_ADD; if (strstr(options,"multiply")) Mode_Table = FLUX_ADAPT_MULT; if (strstr(options,"verbose")) verbose = 1; /* do main loop */ while (!flag_exit_loop) { if (fgets(line, LINE_MAX_LENGTH, hfile) != NULL) { /* tries to read some informations */ line_count_in_file++; for (i=0; (i < strlen(line)) && (i < LINE_MAX_LENGTH); i++) { line[i] = tolower(line[i]); } if (strstr(line," k ") || strstr(line,"wavevector")) /* overrides options */ Type_Table = WAVEVECTOR_TABLE; if (strstr(line," e ") || strstr(line,"omega") || strstr(line,"energy")) Type_Table = ENERGY_TABLE; if (strstr(line,"lambda") || strstr(line," l ") || strstr(line,"wavelength")) Type_Table = WAVELENGTH_TABLE; if (strstr(line,"set")) Mode_Table = FLUX_ADAPT_SET; if (strstr(line,"multiply")) Mode_Table = FLUX_ADAPT_MULT; if (strstr(line,"add")) Mode_Table = FLUX_ADAPT_ADD; if (strstr(line,"unactivate")) Type_Table = UNKNOWN_TABLE;; if (strstr(line,"verbose")) verbose = 1; /* tries to read 2 numbers */ if (sscanf(line,"%lg %lg",&X,&P) == 2) { /* if succeed and not in array : initialize array */ if (!flag_in_array) { flag_in_array = 1; line_count_in_array = 0; malloc_size = 0; } /* if succeed and in array : add (and realloc if necessary) */ if (line_count_in_array+100 > malloc_size) { malloc_size += 100; KE_Table = (double*)realloc(KE_Table,malloc_size*sizeof(double)); Weight_Table = (double*)realloc(Weight_Table,malloc_size*sizeof(double)); } KE_Table[line_count_in_array] = X; Weight_Table[line_count_in_array] = P; line_count_in_array++; } else /* if does not succeed : set 'not in array' flag */ { flag_in_array = 0; } } else flag_exit_loop = 1; /* else : end of file */ } Length_Table = line_count_in_array; if (Length_Table < 2) Type_Table = UNKNOWN_TABLE; /* not enough points */ if (verbose) { printf("Flux : %i points in %s\n",Length_Table, file); printf("Flux : data is [ "); if (Type_Table == ENERGY_TABLE) printf("Energy"); if (Type_Table == WAVEVECTOR_TABLE) printf("Wavevector"); if (Type_Table == WAVELENGTH_TABLE) printf("Wavelength"); if (Type_Table == UNKNOWN_TABLE) printf("UNKNOWN (not used)"); printf(", Flux ]"); if (Mode_Table == FLUX_ADAPT_MULT) printf(" in multiply mode"); printf("\n"); } fclose(hfile); } %} TRACE %{ PROP_Z0; if (Type_Table && (x>xmin && xymin && yxmin && xymin && y 2*Optim_Phase_Counts*Optim_step) && (Optim_Monitor_Counts >= Optim_bins*3)) || (Optim_Monitor_Counts >= Optim_bins*10)) { Optim_Phase_Counts_R = 0; /* enough counts on monitor */ if (Optim_Flag_Verbose) { printf(">> AUTO monitor has reached %i counts (non optimized",Optim_Monitor_Counts); if (Optim_Flag_Absorb) printf(", absorbed"); printf(")\n"); } Optim_step = (double)Optim_Reference_Counts/Optim_Phase_Counts; Optim_Phase_Counts = Optim_Reference_Counts; } } if ((Optim_Phase == OPTIM_PHASE_GET_REF) || ((Optim_Phase == OPTIM_PHASE_OPTIM) && (Optim_Flag_Continuous) )) /* build the Optimized Source distributions */ { if (Optim_Monitor_pmax == 0 & p > Optim_Monitor_pmax) Optim_Monitor_pmax = p; if (Optim_vx_max-Optim_vx_min) Optim_index = (int)rint(Optim_bins * (Optim_vx -Optim_vx_min)/(Optim_vx_max-Optim_vx_min)); else Optim_index = 0; if (Optim_index < 0) Optim_index = 0; if (Optim_index >= Optim_bins) Optim_index = Optim_bins - 1; Optim_New_Source_vx[Optim_index]++; if (Optim_vy_max-Optim_vy_min) Optim_index = (int)rint(Optim_bins * (Optim_vy -Optim_vy_min)/(Optim_vy_max-Optim_vy_min)); else Optim_index = 0; if (Optim_index < 0) Optim_index = 0; if (Optim_index >= Optim_bins) Optim_index = Optim_bins - 1; Optim_New_Source_vy[Optim_index]++; if (Optim_vz_max-Optim_vz_min) Optim_index = (int)rint(Optim_bins * (Optim_vz -Optim_vz_min)/(Optim_vz_max-Optim_vz_min)); else Optim_index = 0; if (Optim_index < 0) Optim_index = 0; if (Optim_index >= Optim_bins) Optim_index = Optim_bins - 1; Optim_New_Source_vz[Optim_index]++; if (Optim_x_max-Optim_x_min) Optim_index = (int)rint(Optim_bins * (Optim_x -Optim_x_min)/(Optim_x_max-Optim_x_min)); else Optim_index = 0; if (Optim_index < 0) Optim_index = 0; if (Optim_index >= Optim_bins) Optim_index = Optim_bins - 1; Optim_New_Source_x[Optim_index]++; if (Optim_y_max-Optim_y_min) Optim_index = (int)rint(Optim_bins * (Optim_y -Optim_y_min)/(Optim_y_max-Optim_y_min)); else Optim_index = 0; if (Optim_index < 0) Optim_index = 0; if (Optim_index >= Optim_bins) Optim_index = Optim_bins - 1; Optim_New_Source_y[Optim_index]++; if (Optim_s1_max-Optim_s1_min) Optim_index = (int)rint(Optim_bins * (Optim_s1 -Optim_s1_min)/(Optim_s1_max-Optim_s1_min)); else Optim_index = 0; if (Optim_index < 0) Optim_index = 0; if (Optim_index >= Optim_bins) Optim_index = Optim_bins - 1; Optim_New_Source_s1[Optim_index]++; if (Optim_s2_max-Optim_s2_min) Optim_index = (int)rint(Optim_bins * (Optim_s2 -Optim_s2_min)/(Optim_s2_max-Optim_s2_min)); else Optim_index = 0; if (Optim_index < 0) Optim_index = 0; if (Optim_index >= Optim_bins) Optim_index = Optim_bins - 1; Optim_New_Source_s2[Optim_index]++; if (Optim_p_max-Optim_p_min) Optim_index = (int)rint(Optim_bins * (Optim_p -Optim_p_min)/(Optim_p_max-Optim_p_min)); else Optim_index = 0; if (Optim_index < 0) Optim_index = 0; if (Optim_index >= Optim_bins) Optim_index = Optim_bins - 1; Optim_New_Source_p[Optim_index]++; } /* end if Optim_Phase */ if (Optim_Flag_Absorb && (Optim_Phase == OPTIM_PHASE_GET_REF)) ABSORB; } /* end if xy in optimizer */ /* end trace */ %} FINALLY %{ /* initial Reference distribution arrays (for weights) */ free(Optim_Reference_x); free(Optim_Reference_y); free(Optim_Reference_vx); free(Optim_Reference_vy); free(Optim_Reference_vz); free(Optim_Reference_s1); free(Optim_Reference_s2); free(Optim_Reference_p); /* optimized Source distribution arrays (to reach) */ free(Optim_Source_x); free(Optim_Source_y); free(Optim_Source_vx); free(Optim_Source_vy); free(Optim_Source_vz); free(Optim_Source_s1); free(Optim_Source_s2); free(Optim_Source_p); /* optimized New_Source distribution arrays (to reach in next step, passed to Source) */ free(Optim_New_Source_x); free(Optim_New_Source_y); free(Optim_New_Source_vx); free(Optim_New_Source_vy); free(Optim_New_Source_vz); free(Optim_New_Source_s1); free(Optim_New_Source_s2); free(Optim_New_Source_p); /* Passing distribution arrays (should grow to reach Source) */ free(Optim_Passing_x); free(Optim_Passing_y); free(Optim_Passing_vx); free(Optim_Passing_vy); free(Optim_Passing_vz); free(Optim_Passing_s1); free(Optim_Passing_s2); free(Optim_Passing_p); %} MCDISPLAY %{ magnify("xy"); multiline(5, (double)xmin, (double)ymin, 0.0, (double)xmax, (double)ymin, 0.0, (double)xmax, (double)ymax, 0.0, (double)xmin, (double)ymax, 0.0, (double)xmin, (double)ymin, 0.0); %} END -------------- next part -------------- /******************************************************************************* * * McStas, version 1.1, released * Maintained by Kristian Nielsen and Kim Lefmann, * Risoe National Laboratory, Roskilde, Denmark * * Component: Source_Optimizer * * Written by: EF, 17 Sept 1999 * * Usage: A component that optimizes the neutron flux passing through the * Source_optimizer in order to have the maximum flux at the * Monitor_Optimizer position. * * Principle: The optimizer first computes neutron state parameter limits * (step 1) passing in the Source_Optimizer, and then records a Reference source * (step 2) as well as the state (at Source_Optimizer position) of neutrons * reaching Monitor. The optimized source is defined as a fraction of the * Reference source plus the distribution of 'good' neutrons reaching the * Monitor. The optimization then starts (step 3), and focuses new neutrons on * the Monitor_Optimizer. In fact it changes 'bad' neutrons into 'good' ones * (that reach the Monitor). The overall flux is kept during process. * * Options: The optimized source can be computed regularly ('continuous' * option) or only once ('fixed'). The energy distribution can be kept during * optimization ('keepE') or released ('freeE'). The time spent in steps 1 and 2 * can be reduced for a better optimization ('auto'). The neutrons passing * during steps 1 and 2 can be absorbed for a better neutron weight distribution * ('absorb'). * * Source_optimizer can be placed just after the source (for instance). * Monitor_Optimizer should be placed at position to optimize. * * INPUT PARAMETERS: * * xmin: Lower x bound of optimizer opening (m) * xmax: Upper x bound of optimizer opening (m) * ymin: Lower y bound of optimizer opening (m) * ymax: Upper y bound of optimizer opening (m) * bins: Number of cells for sampling of neutron state distribution (10 is default) * step: Optimizer step (%, 10 is default). Overridden by 'auto' option. * The two first steps are not optimized. * keep: Percentage of initial source distribution kept (%, 10 is default) * file: Filename where to save optimized source distributions * options: string that can contain * 'continuous' for continuous source optimization (default) * 'fixed' same as 'not continuous' optimization * 'keepE' to keep energy and velocity if pos. (default) * 'freeE' same as 'no keepE' * 'verbose' displays optimization process * 'auto' uses the shortest possible 'step 1' and 'step 2' * and sets 'step' as required. * 'absorb' absorbs step 1 and 2 neutrons if possible. * * parameters bins, step, keep can be -1 for default values. * * OUTPUT PARAMETERS: * * distributions if filename is not empty ("") * * EXAMPLE: I use the following settings * (xmin = -0.03, xmax = 0.03, * ymin = -0.06, ymax = 0.06, * bins = -1, step = -1, keep = -1, * file="source.optim", * options="absorb+auto") * A good optimization needs to record enough non optimized neutrons on Monitor * during step 2. Typical enhancement in computation speed is by a factor 20. * *******************************************************************************/ /* History : Sep 17 1999 : v0.00 first release (not effective) Sep 26 1999 : v0.01 New_Source for continuous optimisation Sep 27 1999 : optimizer is ok, but not very efficient Sep 29 1999 : v0.02 re-direct 'bad' neutrons instead of ABSORB (rand generator for nothing) Oct 06 1999 : v0.03 installed options, corrected bugs, improved efficiency Oct 21 1999 : v0.04 optim can be choosen for xy,v,s,p */ /* NOTE : The 'Optim_' variables are reserved by those components. */ /* other options : setxy, setv, setp, sets to precise what paremeters should be optimized */ /* default is 'setxy'+setv+sets' */ DEFINE COMPONENT Source_Optimizer DEFINITION PARAMETERS (xmin, xmax, ymin, ymax, bins, step, keep,file,options) SETTING PARAMETERS () STATE PARAMETERS (x,y,z,vx,vy,vz,t,s1,s2,p) DECLARE %{ #ifndef MCSTAS_GEN_OPTIM /* McStas General optimizer ID */ #define MCSTAS_GEN_OPTIM #else #error McStas : Source_Optimizer should only be used once per instrument #endif #ifndef FLT_MAX #define FLT_MAX 1e37 #endif #define OPTIM_PHASE_SET_LIMITS 0 /* set array limits to 0, then ask for GET_LIMITS */ #define OPTIM_PHASE_GET_LIMITS 1 /* compute array limits, then ask for SET_REF */ #define OPTIM_PHASE_SET_REF 2 /* set Ref and New_Source to to 0, then ask for GET_REF */ #define OPTIM_PHASE_GET_REF 3 /* compute Ref (and New_Source in Monitor), then ask for SET_SOURCE */ #define OPTIM_PHASE_SET_SOURCE 4 /* set Source to Ref*x%+New_Source, normalize to Ref, Passing to 0, then ask for OPTIM */ #define OPTIM_PHASE_OPTIM 5 /* Optimize and get New_Source (continuous optimization), then reask SET_SOURCE when required */ #define OPTIM_MOD_X 1 /* what was modified in last optim */ #define OPTIM_MOD_Y 2 #define OPTIM_MOD_VX 4 #define OPTIM_MOD_VY 8 #define OPTIM_MOD_VZ 16 #define OPTIM_MOD_S1 32 #define OPTIM_MOD_S2 64 #define OPTIM_MOD_P 128 #define OPTIM_DO_XY 1 /* what to optimize */ #define OPTIM_DO_V 2 #define OPTIM_DO_S 4 #define OPTIM_DO_P 8 /* These are distribution arrays[bins] within limits * flux is kept during optimisation * NOT stored : z is the position of this component * t time (linked to z) */ /* initial Reference distribution arrays (for weights) */ long *Optim_Reference_x; long *Optim_Reference_y; long *Optim_Reference_vx; long *Optim_Reference_vy; long *Optim_Reference_vz; long *Optim_Reference_s1; long *Optim_Reference_s2; long *Optim_Reference_p; /* optimized Source distribution arrays (to reach) */ long *Optim_Source_x; long *Optim_Source_y; long *Optim_Source_vx; long *Optim_Source_vy; long *Optim_Source_vz; long *Optim_Source_s1; long *Optim_Source_s2; long *Optim_Source_p; /* optimized New_Source distribution arrays (to reach in next step, passed to Source) */ long *Optim_New_Source_x; long *Optim_New_Source_y; long *Optim_New_Source_vx; long *Optim_New_Source_vy; long *Optim_New_Source_vz; long *Optim_New_Source_s1; long *Optim_New_Source_s2; long *Optim_New_Source_p; /* Passing distribution arrays (should grow to reach Source) */ long *Optim_Passing_x; long *Optim_Passing_y; long *Optim_Passing_vx; long *Optim_Passing_vy; long *Optim_Passing_vz; long *Optim_Passing_s1; long *Optim_Passing_s2; long *Optim_Passing_p; /* limits for state parameters */ /* x and y are Optimizer dimensions (input parameters) */ double Optim_x_min, Optim_x_max; double Optim_y_min, Optim_y_max; double Optim_vx_min, Optim_vx_max; double Optim_vy_min, Optim_vy_max; double Optim_vz_min, Optim_vz_max; double Optim_s1_min, Optim_s1_max; double Optim_s2_min, Optim_s2_max; double Optim_p_min, Optim_p_max; int Optim_index=0; /* a running Optim_index */ int Optim_index_x=0; /* indexes for last neutron that passed through */ int Optim_index_y=0; int Optim_index_vx=0; int Optim_index_vy=0; int Optim_index_vz=0; int Optim_index_s1=0; int Optim_index_s2=0; int Optim_index_p=0; int Optim_good_x=0; /* indexes for last 'good' neutron that passed through */ int Optim_good_y=0; int Optim_good_vx=0; int Optim_good_vy=0; int Optim_good_vz=0; int Optim_good_s1=0; int Optim_good_s2=0; int Optim_good_p=0; int Optim_bins; long Optim_n_redirect; /* number of consecutive ABSORB */ int Optim_Phase; /* Optimizer function */ long Optim_Phase_Counts =0; /* neutron counts to achieve in each Phase */ long Optim_Phase_Counts_L =0; /* neutron counts to achieve in Limits Phase */ long Optim_Phase_Counts_R =0; /* neutron counts to achieve in Reference Phase */ char Optim_Flag_Continuous =1; /* 1 : continuous Source optimization */ char Optim_Flag_Recycle =0; /* record of neutron state changes by OPTIM_MOD_xx */ char Optim_Flag_KeepE =1; /* 1 : keep E as poss. when recycling */ /* i.e. keep E and |v| distribution */ char Optim_Flag_Verbose =0; /* displays optimization informations */ char Optim_Flag_Absorb =0; /* 1 means that first steps non optimized neutrons are absorbed */ char Optim_Flag_Auto =0; /* 1 is for minimum counts in 2 first steps */ char Optim_Flag_Type = OPTIM_DO_XY|OPTIM_DO_V|OPTIM_DO_S; long Optim_Limits_Counts =0; /* passing neutron counts in each Optim_Phase */ long Optim_Reference_Counts =0; long Optim_Passing_Counts =0; long Optim_Monitor_Counts =0; double Optim_Limits_Flux =0; /* passing neutron flux in each Optim_Phase */ double Optim_Reference_Flux=0; double Optim_Passing_Flux =0; double Optim_Monitor_Flux =0; double Optim_Monitor_pmax =0; float Optim_keep; float Optim_step; double Optim_vx; /* save neutron characteristics for Monitor and ABSORDed->Redirected neutrons */ double Optim_vy; double Optim_vz; double Optim_x; double Optim_y; double Optim_s1; double Optim_s2; double Optim_p; double Optim_v2; double Optim_t1; /* tempo vars */ double Optim_t2; double Optim_t3; double Optim_u1; /* tempo vars */ double Optim_u2; double Optim_u3; int Optim_i1; /* tempo vars */ int Optim_i2; int Optim_i3; long Optim_Normal_Monitor_Counts = 0; /* counts without optim */ long Optim_Total_Monitor_Counts = 0; /* final monitor counts */ FILE *hfile; /* end declare */ %} INITIALIZE %{ Optim_n_redirect = 0; Optim_Phase = OPTIM_PHASE_SET_LIMITS; Optim_x_min = xmin; Optim_x_max = xmax; Optim_y_min = ymin; Optim_y_max = ymax; Optim_bins = (int)bins; Optim_step = step; Optim_keep = keep; if (Optim_step < 0) Optim_step = .1; /* default values if -1 is given */ if (Optim_bins < 0) Optim_bins = 10; if (Optim_keep < 0) Optim_keep = .1; if (Optim_step >= 1) Optim_step = Optim_step/100; /* in case user gives % in 1-100 */ if (Optim_step < .01) Optim_step = .01; if (Optim_step > 1) Optim_step = 1; if (Optim_keep >= 1) Optim_keep = Optim_keep/100; /* in case user gives % in 1-100 */ if (Optim_keep < .01) Optim_keep = .01; if (Optim_keep > 1) Optim_keep = 1; Optim_Phase_Counts = mcget_ncount() * Optim_step; Optim_Phase_Counts_L = Optim_Phase_Counts; Optim_Phase_Counts_R = Optim_Phase_Counts; if (Optim_bins < 1) Optim_bins = 1; if (Optim_bins > 100) Optim_bins = 100; if (strstr(options,"continuous")) Optim_Flag_Continuous = 1; if (strstr(options,"fixed")) Optim_Flag_Continuous = 0; if (strstr(options,"keepE")) Optim_Flag_KeepE = 1; if (strstr(options,"freeE")) Optim_Flag_KeepE = 0; if (strstr(options,"verbose")) Optim_Flag_Verbose = 1; if (strstr(options,"set")) Optim_Flag_Type = 0; if (strstr(options,"setxy")) Optim_Flag_Type |= OPTIM_DO_XY; if (strstr(options,"setv")) Optim_Flag_Type |= OPTIM_DO_V; if (strstr(options,"sets")) Optim_Flag_Type |= OPTIM_DO_S; if (strstr(options,"setp")) Optim_Flag_Type |= OPTIM_DO_P; if (strstr(options,"auto")) { Optim_Flag_Auto = 1; if (Optim_bins*10 < Optim_Phase_Counts) Optim_Phase_Counts_L = Optim_bins*100; /* need at least 10 counts per bin for Limits */ Optim_Phase_Counts_R = mcget_ncount(); Optim_Phase_Counts = mcget_ncount(); } if (strstr(options,"absorb")) Optim_Flag_Absorb = 1; if ((Optim_Source_x = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_Source_y = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_Source_vx = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_Source_vy = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_Source_vz = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_Source_s1 = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_Source_s2 = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_Source_p = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_New_Source_x = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_New_Source_y = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_New_Source_vx = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_New_Source_vy = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_New_Source_vz = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_New_Source_s1 = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_New_Source_s2 = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_New_Source_p = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_Passing_x = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_Passing_y = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_Passing_vx = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_Passing_vy = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_Passing_vz = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_Passing_s1 = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_Passing_s2 = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_Passing_p = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_Reference_x = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_Reference_y = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_Reference_vx = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_Reference_vy = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_Reference_vz = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_Reference_s1 = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_Reference_s2 = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } if ((Optim_Reference_p = (long*)malloc(Optim_bins * sizeof(long*))) == NULL) { fprintf(stderr,"Optimizer : not enough memory\n"); exit(-1); } /* end initialize */ %} TRACE %{ PROP_Z0; if (x>Optim_x_min && xOptim_y_min && y= Optim_Phase_Counts_L)) { Optim_Phase = OPTIM_PHASE_SET_REF; if (Optim_Flag_Verbose) printf(">> OPTIM_PHASE_SET_REF (%i neutrons)\n", Optim_Limits_Counts); } if ((Optim_Phase == OPTIM_PHASE_GET_REF) && (Optim_Reference_Counts >= Optim_Phase_Counts_R)) { Optim_Phase = OPTIM_PHASE_SET_SOURCE; Optim_Phase_Counts_R = Optim_Phase_Counts; if (Optim_Flag_Verbose) { printf(">> OPTIM_PHASE_SET_SOURCE (%i neutrons) from Ref\n", Optim_Reference_Counts); printf("Counts : reference = %i, passing = %i, monitor = %i\n", Optim_Reference_Counts, Optim_Reference_Counts, Optim_Monitor_Counts); printf("Flux : reference = %.2g, passing = %.2g, monitor = %.2g\n", Optim_Reference_Flux, Optim_Reference_Flux, Optim_Monitor_Flux); } } if ((Optim_Phase == OPTIM_PHASE_OPTIM) && (Optim_Passing_Counts >= Optim_Phase_Counts)) { Optim_Phase = OPTIM_PHASE_SET_SOURCE; if (Optim_Flag_Verbose) { printf(">> OPTIM_PHASE_SET_SOURCE (%i neutrons)\n", Optim_Passing_Counts); printf("Number of redirections : %i\n",Optim_n_redirect); printf("Counts : reference = %i, passing = %i, monitor = %i\n", Optim_Reference_Counts, Optim_Passing_Counts, Optim_Monitor_Counts); printf("Flux : reference = %.2g, passing = %.2g, monitor = %.2g\n", Optim_Reference_Flux, Optim_Passing_Flux, Optim_Monitor_Flux); } } /* handle Optim_Phase functions */ if (Optim_Phase == OPTIM_PHASE_SET_LIMITS) /* init : need to compute limits and flux */ { Optim_Limits_Counts = 0; Optim_Limits_Flux = 0; Optim_vx_min = FLT_MAX; Optim_vx_max = -FLT_MAX; Optim_vy_min = FLT_MAX; Optim_vy_max = -FLT_MAX; Optim_vz_min = FLT_MAX; Optim_vz_max = -FLT_MAX; Optim_s1_min = FLT_MAX; Optim_s1_max = -FLT_MAX; Optim_s2_min = FLT_MAX; Optim_s2_max = -FLT_MAX; Optim_p_min = FLT_MAX; Optim_p_max = -FLT_MAX; Optim_Phase = OPTIM_PHASE_GET_LIMITS; } /* end OPTIM_PHASE_SET_LIMITS */ if (Optim_Phase == OPTIM_PHASE_GET_LIMITS) /* init : need to compute limits and flux */ { Optim_Limits_Counts++; Optim_Limits_Flux += p; if (x < Optim_x_min) Optim_x_min = x; if (y < Optim_y_min) Optim_y_min = y; if (x > Optim_x_max) Optim_x_max = x; if (y > Optim_y_max) Optim_y_max = y; if (vx < Optim_vx_min) Optim_vx_min = vx; if (vx > Optim_vx_max) Optim_vx_max = vx; if (vy < Optim_vy_min) Optim_vy_min = vy; if (vy > Optim_vy_max) Optim_vy_max = vy; if (vz < Optim_vz_min) Optim_vz_min = vz; if (vz > Optim_vz_max) Optim_vz_max = vz; if (p < Optim_p_min) Optim_p_min = p; if (p > Optim_p_max) Optim_p_max = p; if (s1 < Optim_s1_min) Optim_s1_min = s1; if (s1 > Optim_s1_max) Optim_s1_max = s1; if (s2 < Optim_s2_min) Optim_s2_min = s2; if (s2 > Optim_s2_max) Optim_s2_max = s2; if (Optim_Flag_Absorb) ABSORB; } /* end if OPTIM_PHASE_GET_LIMITS */ if (Optim_Phase == OPTIM_PHASE_SET_REF) /* Set Ref and New_Source to 0 */ { Optim_Reference_Counts = 0; Optim_Reference_Flux = 0; Optim_Monitor_Counts = 0; /* also counted as New_Source */ Optim_Monitor_Flux = 0; for (Optim_index=0; Optim_index < Optim_bins; Optim_index++) { Optim_Reference_x[Optim_index] = 0; /* initial distribution will be recorded first */ Optim_Reference_y[Optim_index] = 0; Optim_Reference_vx[Optim_index] = 0; Optim_Reference_vy[Optim_index] = 0; Optim_Reference_vz[Optim_index] = 0; Optim_Reference_s1[Optim_index] = 0; Optim_Reference_s2[Optim_index] = 0; Optim_Reference_p[Optim_index] = 0; Optim_New_Source_x[Optim_index] = 0; /* Monitor_Optimizer will compute the */ Optim_New_Source_y[Optim_index] = 0; /* optimized New_Source distribution */ Optim_New_Source_vx[Optim_index] = 0; /* that will become Source for Optim Optim_step */ Optim_New_Source_vy[Optim_index] = 0; Optim_New_Source_vz[Optim_index] = 0; Optim_New_Source_s1[Optim_index] = 0; Optim_New_Source_s2[Optim_index] = 0; Optim_New_Source_p[Optim_index] = 0; } /* end for */ Optim_Phase = OPTIM_PHASE_GET_REF; } /* end OPTIM_PHASE_SET_REF */ if (Optim_Phase == OPTIM_PHASE_GET_REF) /* now build the Reference in limits */ { /* New_Source is set by Monitor_Optimizer */ Optim_Reference_Counts++; Optim_Reference_Flux += p; if (Optim_vx_max-Optim_vx_min) Optim_index = (int)rint(Optim_bins * (vx -Optim_vx_min)/(Optim_vx_max-Optim_vx_min)); else Optim_index = 0; if (Optim_index < 0) Optim_index = 0; if (Optim_index >= Optim_bins) Optim_index = Optim_bins - 1; Optim_Reference_vx[Optim_index]++; if (Optim_vy_max-Optim_vy_min) Optim_index = (int)rint(Optim_bins * (vy -Optim_vy_min)/(Optim_vy_max-Optim_vy_min)); else Optim_index = 0; if (Optim_index < 0) Optim_index = 0; if (Optim_index >= Optim_bins) Optim_index = Optim_bins - 1; Optim_Reference_vy[Optim_index]++; if (Optim_vz_max-Optim_vz_min) Optim_index = (int)rint(Optim_bins * (vz -Optim_vz_min)/(Optim_vz_max-Optim_vz_min)); else Optim_index = 0; if (Optim_index < 0) Optim_index = 0; if (Optim_index >= Optim_bins) Optim_index = Optim_bins - 1; Optim_Reference_vz[Optim_index]++; if (Optim_x_max-Optim_x_min) Optim_index = (int)rint(Optim_bins * (x -Optim_x_min)/(Optim_x_max-Optim_x_min)); else Optim_index = 0; if (Optim_index < 0) Optim_index = 0; if (Optim_index >= Optim_bins) Optim_index = Optim_bins - 1; Optim_Reference_x[Optim_index]++; if (Optim_y_max-Optim_y_min) Optim_index = (int)rint(Optim_bins * (y -Optim_y_min)/(Optim_y_max-Optim_y_min)); else Optim_index = 0; if (Optim_index < 0) Optim_index = 0; if (Optim_index >= Optim_bins) Optim_index = Optim_bins - 1; Optim_Reference_y[Optim_index]++; if (Optim_s1_max-Optim_s1_min) Optim_index = (int)rint(Optim_bins * (s1 -Optim_s1_min)/(Optim_s1_max-Optim_s1_min)); else Optim_index = 0; if (Optim_index < 0) Optim_index = 0; if (Optim_index >= Optim_bins) Optim_index = Optim_bins - 1; Optim_Reference_s1[Optim_index]++; if (Optim_s2_max-Optim_s2_min) Optim_index = (int)rint(Optim_bins * (s2 -Optim_s2_min)/(Optim_s2_max-Optim_s2_min)); else Optim_index = 0; if (Optim_index < 0) Optim_index = 0; if (Optim_index >= Optim_bins) Optim_index = Optim_bins - 1; Optim_Reference_s2[Optim_index]++; if (Optim_p_max-Optim_p_min) Optim_index = (int)rint(Optim_bins * (p -Optim_p_min)/(Optim_p_max-Optim_p_min)); else Optim_index = 0; if (Optim_index < 0) Optim_index = 0; if (Optim_index >= Optim_bins) Optim_index = Optim_bins - 1; Optim_Reference_p[Optim_index]++; } /* end if OPTIM_PHASE_GET_REF */ if (Optim_Phase == OPTIM_PHASE_SET_SOURCE) /* Define optimized Source (normalized to Reference) */ { if (Optim_Monitor_Counts) Optim_t1 = (1 - Optim_keep) * Optim_Reference_Counts/Optim_Monitor_Counts; else Optim_t1 = 0; Optim_Passing_Counts = 0; Optim_Passing_Flux = 0; if (Optim_Normal_Monitor_Counts == 0) Optim_Normal_Monitor_Counts = Optim_Total_Monitor_Counts; /* 2 first un-optimized steps */ Optim_Monitor_Counts = 0; /* also counted as New_Source */ Optim_Monitor_Flux = 0; for (Optim_index = 0; Optim_index < Optim_bins; Optim_index++) { /* get Optim_keep % of Reference, and 1-Optim_keep% of New_Source normalized to Reference Counts */ if (Optim_Flag_Continuous | (Optim_n_redirect == 0)) { Optim_Source_x[Optim_index] = (long)(rint(Optim_keep * Optim_Reference_x[Optim_index]) + Optim_t1 * Optim_New_Source_x[Optim_index] ); Optim_Source_y[Optim_index] = (long)(rint(Optim_keep * Optim_Reference_y[Optim_index]) + Optim_t1 * Optim_New_Source_y[Optim_index] ); Optim_Source_vx[Optim_index] = (long)(rint(Optim_keep * Optim_Reference_vx[Optim_index]) + Optim_t1 * Optim_New_Source_vx[Optim_index] ); Optim_Source_vy[Optim_index] = (long)(rint(Optim_keep * Optim_Reference_vy[Optim_index]) + Optim_t1 * Optim_New_Source_vy[Optim_index] ); Optim_Source_vz[Optim_index] = (long)(rint(Optim_keep * Optim_Reference_vz[Optim_index]) + Optim_t1 * Optim_New_Source_vz[Optim_index] ); Optim_Source_s1[Optim_index] = (long)(rint(Optim_keep * Optim_Reference_s1[Optim_index]) + Optim_t1 * Optim_New_Source_s1[Optim_index] ); Optim_Source_s2[Optim_index] = (long)(rint(Optim_keep * Optim_Reference_s2[Optim_index]) + Optim_t1 * Optim_New_Source_s2[Optim_index] ); Optim_Source_p[Optim_index] = (long)(rint(Optim_keep * Optim_Reference_p[Optim_index]) + Optim_t1 * Optim_New_Source_p[Optim_index] ); if (Optim_New_Source_x[Optim_index] > Optim_New_Source_x[Optim_good_x]) Optim_good_x = Optim_index; if (Optim_New_Source_y[Optim_index] > Optim_New_Source_y[Optim_good_y]) Optim_good_y = Optim_index; if (Optim_New_Source_vx[Optim_index] > Optim_New_Source_vx[Optim_good_vx]) Optim_good_vx = Optim_index; if (Optim_New_Source_vy[Optim_index] > Optim_New_Source_vy[Optim_good_vy]) Optim_good_vy = Optim_index; if (Optim_New_Source_vz[Optim_index] > Optim_New_Source_vz[Optim_good_vz]) Optim_good_vz = Optim_index; if (Optim_New_Source_s1[Optim_index] > Optim_New_Source_s1[Optim_good_s1]) Optim_good_s1 = Optim_index; if (Optim_New_Source_s2[Optim_index] > Optim_New_Source_s2[Optim_good_s2]) Optim_good_s2 = Optim_index; if (Optim_New_Source_p[Optim_index] > Optim_New_Source_p[Optim_good_p]) Optim_good_p = Optim_index; } Optim_Passing_x[Optim_index] = 0; /* Passing neutrons will then reach Source */ Optim_Passing_y[Optim_index] = 0; /* weights will be adapted to match Reference */ Optim_Passing_vx[Optim_index] = 0; Optim_Passing_vy[Optim_index] = 0; Optim_Passing_vz[Optim_index] = 0; Optim_Passing_s1[Optim_index] = 0; Optim_Passing_s2[Optim_index] = 0; Optim_Passing_p[Optim_index] = 0; Optim_New_Source_x[Optim_index] = 0; /* Init of next Source */ Optim_New_Source_y[Optim_index] = 0; Optim_New_Source_vx[Optim_index] = 0; Optim_New_Source_vy[Optim_index] = 0; Optim_New_Source_vz[Optim_index] = 0; Optim_New_Source_s1[Optim_index] = 0; Optim_New_Source_s2[Optim_index] = 0; Optim_New_Source_p[Optim_index] = 0; } /* end for */ Optim_Phase = OPTIM_PHASE_OPTIM; } /* end OPTIM_PHASE_SET_SOURCE */ if (Optim_Phase == OPTIM_PHASE_OPTIM) /* Use optimized Source */ { Optim_Flag_Recycle = 0; Optim_index_x = Optim_good_x; Optim_index_y = Optim_good_y; Optim_index_vx= Optim_good_vx; Optim_index_vy= Optim_good_vy; Optim_index_vz= Optim_good_vz; Optim_index_s1= Optim_good_s1; Optim_index_s2= Optim_good_s2; Optim_index_p = Optim_good_p; if (Optim_vz_max-Optim_vz_min) Optim_index = (int)rint(Optim_bins * (vz -Optim_vz_min)/(Optim_vz_max-Optim_vz_min)); else Optim_index = 0; if (Optim_index < 0) Optim_index = 0; if (Optim_index >= Optim_bins) Optim_index = Optim_bins - 1; if ((Optim_Flag_Type & OPTIM_DO_V) && (Optim_Passing_vz[Optim_index] >= Optim_Source_vz[Optim_index])) { /* distribution achieved : redirect neutron near last neutron characteristic */ Optim_Flag_Recycle |= OPTIM_MOD_VX; Optim_vz += (Optim_index_vz-Optim_index)*(Optim_vz_max - Optim_vz_min)/Optim_bins; } else Optim_index_vz = Optim_index; if (Optim_vx_max-Optim_vx_min) Optim_index = (int)rint(Optim_bins * (vx -Optim_vx_min)/(Optim_vx_max-Optim_vx_min)); else Optim_index = 0; if (Optim_index < 0) Optim_index = 0; if (Optim_index >= Optim_bins) Optim_index = Optim_bins - 1; if ((Optim_Flag_Type & OPTIM_DO_V) && (Optim_Passing_vx[Optim_index] >= Optim_Source_vx[Optim_index])) { Optim_Flag_Recycle |= OPTIM_MOD_VY; Optim_vx += (Optim_index_vx-Optim_index)*(Optim_vx_max - Optim_vx_min)/Optim_bins; } else Optim_index_vx = Optim_index; if (Optim_vy_max-Optim_vy_min) Optim_index = (int)rint(Optim_bins * (vy -Optim_vy_min)/(Optim_vy_max-Optim_vy_min)); else Optim_index = 0; if (Optim_index < 0) Optim_index = 0; if (Optim_index >= Optim_bins) Optim_index = Optim_bins - 1; if ((Optim_Flag_Type & OPTIM_DO_V) && (Optim_Passing_vy[Optim_index] >= Optim_Source_vy[Optim_index])) { Optim_Flag_Recycle |= OPTIM_MOD_VZ; Optim_vy += (Optim_index_vy-Optim_index)*(Optim_vy_max - Optim_vy_min)/Optim_bins; } else Optim_index_vy = Optim_index; if ((Optim_Flag_Recycle & (OPTIM_MOD_VX|OPTIM_MOD_VY|OPTIM_MOD_VZ)) && Optim_Flag_KeepE) { /* now try to keep E distribution */ Optim_t1 = Optim_v2 - Optim_vz*Optim_vz - Optim_vy*Optim_vy; Optim_t2 = Optim_v2 - Optim_vz*Optim_vz - Optim_vx*Optim_vx; Optim_t3 = Optim_v2 - Optim_vx*Optim_vx - Optim_vy*Optim_vy; /* we affect the component wich is the most optimized (largest Source/Ref) */ if ((Optim_vx_max-Optim_vx_min) && (Optim_t1 > 0)) { Optim_t1 = sqrt(Optim_t1); if (vx < 0) Optim_t1 = -Optim_t1; Optim_i1 = (int)rint(Optim_bins * (Optim_t1 -Optim_vx_min)/(Optim_vx_max-Optim_vx_min)); if (Optim_i1 < 0) Optim_i1 = 0; if (Optim_i1 >= Optim_bins) Optim_i1 = Optim_bins - 1; Optim_u1 = (double)Optim_Source_vx[Optim_i1]/(Optim_Reference_vx[Optim_i1]+1); } else Optim_u1 = 0; if ((Optim_vy_max-Optim_vy_min) && (Optim_t2 > 0)) { Optim_t2 = sqrt(Optim_t2); if (vy < 0) Optim_t2 = -Optim_t2; Optim_i2 = (int)rint(Optim_bins * (Optim_t2 -Optim_vy_min)/(Optim_vy_max-Optim_vy_min)); if (Optim_i2 < 0) Optim_i2 = 0; if (Optim_i2 >= Optim_bins) Optim_i2 = Optim_bins - 1; Optim_u2 = (double)Optim_Source_vy[Optim_i2]/(Optim_Reference_vy[Optim_i2]+1); } else Optim_u2 = 0; if ((Optim_vz_max-Optim_vz_min) && (Optim_t3 > 0)) { Optim_t3 = sqrt(Optim_t3); if (vz < 0) Optim_t3 = -Optim_t3; Optim_i3 = (int)rint(Optim_bins * (Optim_t3 -Optim_vz_min)/(Optim_vz_max-Optim_vz_min)); if (Optim_i3 < 0) Optim_i3 = 0; if (Optim_i3 >= Optim_bins) Optim_i3 = Optim_bins - 1; Optim_u3 = (double)Optim_Source_vz[Optim_i3]/(Optim_Reference_vz[Optim_i3]+1); } else Optim_u3 = 0; if ((Optim_u1 > Optim_u2) && (Optim_u1 > Optim_u3)) { Optim_vx = Optim_t1; Optim_index_vx = Optim_i1; Optim_Flag_Recycle |= OPTIM_MOD_VX; Optim_index = -1; } if ((Optim_u2 > Optim_u1) && (Optim_u2 > Optim_u3) ) { Optim_vy = Optim_t2; Optim_index_vy = Optim_i2; Optim_Flag_Recycle |= OPTIM_MOD_VY; Optim_index = -1; } if ((Optim_u3 > Optim_u1) && (Optim_u3 > Optim_u1)) { Optim_vz = Optim_t3; Optim_index_vz = Optim_i3; Optim_Flag_Recycle |= OPTIM_MOD_VZ; Optim_index = -1; } } vx = Optim_vx; vy = Optim_vy; vz = Optim_vz; if (Optim_x_max-Optim_x_min) Optim_index = (int)rint(Optim_bins * (x -Optim_x_min)/(Optim_x_max-Optim_x_min)); else Optim_index = 0; if (Optim_index < 0) Optim_index = 0; if (Optim_index >= Optim_bins) Optim_index = Optim_bins - 1; if ((Optim_Flag_Type & OPTIM_DO_XY) && (Optim_Passing_x[Optim_index] >= Optim_Source_x[Optim_index])) { Optim_Flag_Recycle |= OPTIM_MOD_X; Optim_x += (Optim_index_x-Optim_index)*(Optim_x_max - Optim_x_min)/Optim_bins; x = Optim_x; } else Optim_index_x = Optim_index; if (Optim_y_max-Optim_y_min) Optim_index = (int)rint(Optim_bins * (y -Optim_y_min)/(Optim_y_max-Optim_y_min)); else Optim_index = 0; if (Optim_index < 0) Optim_index = 0; if (Optim_index >= Optim_bins) Optim_index = Optim_bins - 1; if ((Optim_Flag_Type & OPTIM_DO_XY) && (Optim_Passing_y[Optim_index] >= Optim_Source_y[Optim_index])) { Optim_Flag_Recycle |= OPTIM_MOD_Y; Optim_y += (Optim_index_y-Optim_index)*(Optim_y_max - Optim_y_min)/Optim_bins; y = Optim_y; } else Optim_index_y = Optim_index; if (Optim_s1_max-Optim_s1_min) Optim_index = (int)rint(Optim_bins * (s1 -Optim_s1_min)/(Optim_s1_max-Optim_s1_min)); else Optim_index = 0; if (Optim_index < 0) Optim_index = 0; if (Optim_index >= Optim_bins) Optim_index = Optim_bins - 1; if ((Optim_Flag_Type & OPTIM_DO_S) && (Optim_Passing_s1[Optim_index] >= Optim_Source_s1[Optim_index])) { Optim_Flag_Recycle |= OPTIM_MOD_S1; Optim_s1 += (Optim_index_s1-Optim_index)*(Optim_s1_max - Optim_s1_min)/Optim_bins; s1 = Optim_s1; } else Optim_index_s1 = Optim_index; if (Optim_s2_max-Optim_s2_min) Optim_index = (int)rint(Optim_bins * (s2 -Optim_s2_min)/(Optim_s2_max-Optim_s2_min)); else Optim_index = 0; if (Optim_index < 0) Optim_index = 0; if (Optim_index >= Optim_bins) Optim_index = Optim_bins - 1; if ((Optim_Flag_Type & OPTIM_DO_S) && (Optim_Passing_s2[Optim_index] >= Optim_Source_s2[Optim_index])) { Optim_Flag_Recycle |= OPTIM_MOD_S2; Optim_s2 += (Optim_index_s2-Optim_index)*(Optim_s2_max - Optim_s2_min)/Optim_bins; s2 = Optim_s2; } else Optim_index_s2 = Optim_index; if (Optim_p_max-Optim_p_min) Optim_index = (int)rint(Optim_bins * (p -Optim_p_min)/(Optim_p_max-Optim_p_min)); else Optim_index = 0; if (Optim_index < 0) Optim_index = 0; if (Optim_index >= Optim_bins) Optim_index = Optim_bins - 1; if ((Optim_Flag_Type & OPTIM_DO_P) && (Optim_Passing_p[Optim_index] >= Optim_Source_p[Optim_index])) { Optim_Flag_Recycle |= OPTIM_MOD_P; Optim_p += (Optim_index_p-Optim_index)*(Optim_p_max - Optim_p_min)/Optim_bins; p = Optim_p; } else Optim_index_p = Optim_index; /* neutron is passed ! */ if (Optim_Source_vx[Optim_index_vx] && Optim_Source_vy[Optim_index_vy] && Optim_Source_vz[Optim_index_vz] && Optim_Source_x[Optim_index_x] && Optim_Source_y[Optim_index_y] && Optim_Source_s1[Optim_index_s1] && Optim_Source_s2[Optim_index_s2] && Optim_Source_p[Optim_index_p] && Optim_Reference_vx[Optim_index_vx] && Optim_Reference_vy[Optim_index_vy] && Optim_Reference_vz[Optim_index_vz] && Optim_Reference_x[Optim_index_x] && Optim_Reference_y[Optim_index_y] && Optim_Reference_s1[Optim_index_s1] && Optim_Reference_s2[Optim_index_s2] && Optim_Reference_p[Optim_index_p]) { Optim_t1 = 1; /* good neutrons have an improved distribution, so Ref/Source < 1 */ /* unmodified (form Ref kept fraction) neutrons have Passing < Ref*Optim_keep. their weight should be kept */ /* at the end there will be of those : 2*Optim_step*Optim_keep + (1-2*Optim_step)*Optim_keep = Optim_keep % of unmodified neutrons */ /* the remining part (1-Optim_keep neutrons) should have an integrated flux of (1-Optim_keep) */ if (Optim_Flag_Type & OPTIM_DO_V) { Optim_t2 = (double)Optim_Reference_vx[Optim_index_vx]/Optim_Source_vx[Optim_index_vx]; if (Optim_t2 < 1) Optim_good_vx = Optim_index_vx; Optim_t1 *= Optim_t2; Optim_t2 = (double)Optim_Reference_vy[Optim_index_vy]/Optim_Source_vy[Optim_index_vy]; if (Optim_t2 < 1) Optim_good_vy = Optim_index_vy; Optim_t1 *= Optim_t2; Optim_t2 = (double)Optim_Reference_vz[Optim_index_vz]/Optim_Source_vz[Optim_index_vz]; if (Optim_t2 < 1) Optim_good_vz = Optim_index_vz; Optim_t1 *= Optim_t2; } if (Optim_Flag_Type & OPTIM_DO_XY) { Optim_t2 = (double)Optim_Reference_x[Optim_index_x]/Optim_Source_x[Optim_index_x]; if (Optim_t2 < 1) Optim_good_x = Optim_index_x; Optim_t1 *= Optim_t2; Optim_t2 = (double)Optim_Reference_y[Optim_index_y]/Optim_Source_y[Optim_index_y]; if (Optim_t2 < 1) Optim_good_y = Optim_index_y; Optim_t1 *= Optim_t2; } if (Optim_Flag_Type & OPTIM_DO_S) { Optim_t2 = (double)Optim_Reference_s1[Optim_index_s1]/Optim_Source_s1[Optim_index_s1]; if (Optim_t2 < 1) Optim_good_s1= Optim_index_s1; Optim_t1 *= Optim_t2; Optim_t2 = (double)Optim_Reference_s2[Optim_index_s2]/Optim_Source_s2[Optim_index_s2]; if (Optim_t2 < 1) Optim_good_s2= Optim_index_s2; Optim_t1 *= Optim_t2; } if (Optim_Flag_Type & OPTIM_DO_P) { Optim_t2 = (double)Optim_Reference_p[Optim_index_p]/Optim_Source_p[Optim_index_p]; if (Optim_t2 < 1) Optim_good_p = Optim_index_p; Optim_t1 *= Optim_t2; } /* now normalize to intial distribution */ Optim_p *= Optim_t1; if (Optim_Flag_Recycle) { Optim_n_redirect++; } /* Optim_p /= Optim_Flag_Recycle; */ p = Optim_p; } else ABSORB; /* can't modify neutron weight -> eject */ Optim_Passing_vx[Optim_index_vx]++; Optim_Passing_vy[Optim_index_vy]++; Optim_Passing_vz[Optim_index_vz]++; Optim_Passing_x[Optim_index_x]++; Optim_Passing_y[Optim_index_y]++; Optim_Passing_s1[Optim_index_s1]++; Optim_Passing_s2[Optim_index_s2]++; Optim_Passing_p[Optim_index_p]++; Optim_Passing_Counts++; Optim_Passing_Flux += p; } /* end if OPTIM_PHASE_OPTIM */ } /* end if xy in optimizer */ /* end trace */ %} FINALLY %{ if (strlen(file) > 0) { hfile = fopen(file, "w"); if(!hfile) { fprintf(stderr, "Error: %s : could not open output file '%s'\n", mccompcurname, file); } else { fprintf(hfile,"# Instrument-source: %s\n", mcinstrument_source); mcruninfo_out("# ", hfile); fprintf(hfile,"# type: array_2d(%i,6) \n",Optim_bins); fprintf(hfile,"# component: %s\n", mccompcurname); fprintf(hfile,"# title: General Optimizer distributions\n"); fprintf(hfile,"# filename: '%s'\n",file); fprintf(hfile,"# variables: x dx y dy vx dvx vy dvy vz dvz s1 ds1 s2 ds2 p dp\n"); fprintf(hfile,"# xvar: (x y vx vy vz s1 s2 p)\n"); fprintf(hfile,"# yvar: (dx dy dvx dvy dvz ds1 ds2 dp)\n"); fprintf(hfile,"# xlabel: 'Distributions'\n"); fprintf(hfile,"# ylabel: 'Counts'\n"); if (Optim_Normal_Monitor_Counts != 0) fprintf(hfile,"# Optimizer speedup estimate: %.3g [Monitor Normal counts %i (extrapolated), Optimized %i ]\n", (double)(Optim_Total_Monitor_Counts)/Optim_Normal_Monitor_Counts*2*Optim_step,(int)ceil(Optim_Normal_Monitor_Counts/2/Optim_step), Optim_Total_Monitor_Counts); fprintf(hfile,"# Optimizer options: "); if (Optim_Flag_Continuous) fprintf(hfile,"continuous "); else fprintf(hfile,"fixed "); if (Optim_Flag_Auto) fprintf(hfile,"auto "); if (Optim_Flag_Absorb) fprintf(hfile,"absorb "); if (Optim_Flag_KeepE) fprintf(hfile,"keepE "); else fprintf(hfile,"freeE "); if (Optim_Flag_Verbose) fprintf(hfile,"verbose "); if (Optim_Flag_Type & OPTIM_DO_XY) fprintf(hfile,"setxy "); if (Optim_Flag_Type & OPTIM_DO_V) fprintf(hfile,"setv "); if (Optim_Flag_Type & OPTIM_DO_S) fprintf(hfile,"sets "); if (Optim_Flag_Type & OPTIM_DO_P) fprintf(hfile,"setp "); fprintf(hfile,"\n"); fprintf(hfile,"# Redirected neutrons: %i (%.2f \%)\n",Optim_n_redirect,(double)(100*Optim_n_redirect/mcget_ncount())); fprintf(hfile,"# data: Optimzed Source\n"); for (Optim_index = 0; Optim_index < Optim_bins; Optim_index++) { fprintf(hfile,"%10.4g ",(Optim_x_min+((Optim_index+0.5)/Optim_bins)*(Optim_x_max - Optim_x_min))); fprintf(hfile,"%10i\t",Optim_Source_x[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_y_min+((Optim_index+0.5)/Optim_bins)*(Optim_y_max - Optim_y_min))); fprintf(hfile,"%10i\t",Optim_Source_y[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_vx_min+((Optim_index+0.5)/Optim_bins)*(Optim_vx_max - Optim_vx_min))); fprintf(hfile,"%10i\t",Optim_Source_vx[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_vy_min+((Optim_index+0.5)/Optim_bins)*(Optim_vy_max - Optim_vy_min))); fprintf(hfile,"%10i\t",Optim_Source_vy[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_vz_min+((Optim_index+0.5)/Optim_bins)*(Optim_vz_max - Optim_vz_min))); fprintf(hfile,"%10i\t",Optim_Source_vz[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_s1_min+((Optim_index+0.5)/Optim_bins)*(Optim_s1_max - Optim_s1_min))); fprintf(hfile,"%10i\t",Optim_Source_s1[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_s2_min+((Optim_index+0.5)/Optim_bins)*(Optim_s2_max - Optim_s2_min))); fprintf(hfile,"%10i\t",Optim_Source_s2[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_p_min+((Optim_index+0.5)/Optim_bins)*(Optim_p_max - Optim_p_min))); fprintf(hfile,"%10i\t",Optim_Source_p[Optim_index]); fprintf(hfile,"\n"); } fprintf(hfile,"# data: Reference Source\n"); for (Optim_index = 0; Optim_index < Optim_bins; Optim_index++) { fprintf(hfile,"%10.4g ",(Optim_x_min+((Optim_index+0.5)/Optim_bins)*(Optim_x_max - Optim_x_min))); fprintf(hfile,"%10i\t",Optim_Reference_x[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_y_min+((Optim_index+0.5)/Optim_bins)*(Optim_y_max - Optim_y_min))); fprintf(hfile,"%10i\t",Optim_Reference_y[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_vx_min+((Optim_index+0.5)/Optim_bins)*(Optim_vx_max - Optim_vx_min))); fprintf(hfile,"%10i\t",Optim_Reference_vx[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_vy_min+((Optim_index+0.5)/Optim_bins)*(Optim_vy_max - Optim_vy_min))); fprintf(hfile,"%10i\t",Optim_Reference_vy[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_vz_min+((Optim_index+0.5)/Optim_bins)*(Optim_vz_max - Optim_vz_min))); fprintf(hfile,"%10i\t",Optim_Reference_vz[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_s1_min+((Optim_index+0.5)/Optim_bins)*(Optim_s1_max - Optim_s1_min))); fprintf(hfile,"%10i\t",Optim_Reference_s1[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_s2_min+((Optim_index+0.5)/Optim_bins)*(Optim_s2_max - Optim_s2_min))); fprintf(hfile,"%10i\t",Optim_Reference_s2[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_p_min+((Optim_index+0.5)/Optim_bins)*(Optim_p_max - Optim_p_min))); fprintf(hfile,"%10i\t",Optim_Reference_p[Optim_index]); fprintf(hfile,"\n"); } fprintf(hfile,"# data: Passing\n"); for (Optim_index = 0; Optim_index < Optim_bins; Optim_index++) { fprintf(hfile,"%10.4g ",(Optim_x_min+((Optim_index+0.5)/Optim_bins)*(Optim_x_max - Optim_x_min))); fprintf(hfile,"%10i\t",Optim_Passing_x[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_y_min+((Optim_index+0.5)/Optim_bins)*(Optim_y_max - Optim_y_min))); fprintf(hfile,"%10i\t",Optim_Passing_y[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_vx_min+((Optim_index+0.5)/Optim_bins)*(Optim_vx_max - Optim_vx_min))); fprintf(hfile,"%10i\t",Optim_Passing_vx[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_vy_min+((Optim_index+0.5)/Optim_bins)*(Optim_vy_max - Optim_vy_min))); fprintf(hfile,"%10i\t",Optim_Passing_vy[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_vz_min+((Optim_index+0.5)/Optim_bins)*(Optim_vz_max - Optim_vz_min))); fprintf(hfile,"%10i\t",Optim_Passing_vz[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_s1_min+((Optim_index+0.5)/Optim_bins)*(Optim_s1_max - Optim_s1_min))); fprintf(hfile,"%10i\t",Optim_Passing_s1[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_s2_min+((Optim_index+0.5)/Optim_bins)*(Optim_s2_max - Optim_s2_min))); fprintf(hfile,"%10i\t",Optim_Passing_s2[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_p_min+((Optim_index+0.5)/Optim_bins)*(Optim_p_max - Optim_p_min))); fprintf(hfile,"%10i\t",Optim_Passing_p[Optim_index]); fprintf(hfile,"\n"); } fprintf(hfile,"# data: New_Source\n"); for (Optim_index = 0; Optim_index < Optim_bins; Optim_index++) { fprintf(hfile,"%10.4g ",(Optim_x_min+((Optim_index+0.5)/Optim_bins)*(Optim_x_max - Optim_x_min))); fprintf(hfile,"%10i\t",Optim_New_Source_x[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_y_min+((Optim_index+0.5)/Optim_bins)*(Optim_y_max - Optim_y_min))); fprintf(hfile,"%10i\t",Optim_New_Source_y[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_vx_min+((Optim_index+0.5)/Optim_bins)*(Optim_vx_max - Optim_vx_min))); fprintf(hfile,"%10i\t",Optim_New_Source_vx[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_vy_min+((Optim_index+0.5)/Optim_bins)*(Optim_vy_max - Optim_vy_min))); fprintf(hfile,"%10i\t",Optim_New_Source_vy[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_vz_min+((Optim_index+0.5)/Optim_bins)*(Optim_vz_max - Optim_vz_min))); fprintf(hfile,"%10i\t",Optim_New_Source_vz[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_s1_min+((Optim_index+0.5)/Optim_bins)*(Optim_s1_max - Optim_s1_min))); fprintf(hfile,"%10i\t",Optim_New_Source_s1[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_s2_min+((Optim_index+0.5)/Optim_bins)*(Optim_s2_max - Optim_s2_min))); fprintf(hfile,"%10i\t",Optim_New_Source_s2[Optim_index]); fprintf(hfile,"%10.4g ",(Optim_p_min+((Optim_index+0.5)/Optim_bins)*(Optim_p_max - Optim_p_min))); fprintf(hfile,"%10i\t",Optim_New_Source_p[Optim_index]); fprintf(hfile,"\n"); } fclose(hfile); } if (Optim_Flag_Verbose) { printf("End of optimization\n"); printf("Optim_Normal_Monitor_Counts = %i (2 steps), Optim_Total_Monitor_Counts = %i \n",Optim_Normal_Monitor_Counts, Optim_Total_Monitor_Counts); if (Optim_Normal_Monitor_Counts != 0) printf("Optimizer speedup : %.3g \n", (double)(Optim_Total_Monitor_Counts)/Optim_Normal_Monitor_Counts*2*Optim_step); printf("Number of redirections : %i\n",Optim_n_redirect); printf("Counts : reference = %i, passing = %i, monitor = %i\n", Optim_Reference_Counts, Optim_Passing_Counts, Optim_Monitor_Counts); printf("Flux : reference = %.2g, passing = %.2g, monitor = %.2g\n", Optim_Reference_Flux, Optim_Passing_Flux, Optim_Monitor_Flux); } } %} MCDISPLAY %{ magnify("xy"); multiline(5, (double)xmin, (double)ymin, 0.0, (double)xmax, (double)ymin, 0.0, (double)xmax, (double)ymax, 0.0, (double)xmin, (double)ymax, 0.0, (double)xmin, (double)ymin, 0.0); %} END From mja at ansto.gov.au Tue Oct 12 01:19:49 1999 From: mja at ansto.gov.au (JAMES, Michael) Date: Tue, 12 Oct 1999 09:19:49 +1000 Subject: McStas and monochromators Message-ID: <40BF49FB0D7DD311922000A0C966E30E0E4CEA@pdnt53.anp.ansto.gov.au> > -----Original Message----- > From: Kristian Nielsen [SMTP:kristian.nielsen at risoe.dk] > Sent: Monday, 11 October 1999 22:45 > To: JAMES, Michael > Subject: Re: McStas and monochromators > > > Date: Mon, 11 Oct 1999 09:49:29 +1000 > > From: "JAMES, Michael" > > > A colleague mentioned that he thought that a new flat monochromator component had been developed > to > > account for secondary extinction. I have searched for this component and have turned-up a > blank. > > Also have you heard of any similar components that account for variations in reflectivity with > > wavelength ? > > We do have a new monochromator in development, and it is close to > finished, but not completely finished yet unfortunately. I could send > you some code, but given that there are still unresolved issues and no > documentation yet I am not sure that it would be useful, unfortunately. > > The component is designed to handle multiple scattering events inside > the crystal, and should correctly handle secondary extinction as well as > wavelength dependency. I think the main error compared to a real > monochromator is in the modelling of the mosaicity. A gaussian mosaicity > is assumed with a large number of small microcrystals. This assumption > may not be valid in real mosaic crystals. > > - Kristian. [JAMES, Michael] Dear Kristian It sounds like you are making some good progress on the new monochromator. I would be very interested in testing a version of it as soon as you think it is in a reasonable state. Regards Michael James From farhi at ill.fr Fri Nov 5 17:13:02 1999 From: farhi at ill.fr (Farhi) Date: Fri, 05 Nov 1999 17:13:02 +0100 Subject: What's new ? Message-ID: <3823020E.4BD6AB2D@ill.fr> Hy Kristian, I've been extensively testing my flux adapter and optimizer. They both seem to work ok. the Flux_adapter do changes the beam distribution, whereas the flux optimizer doeas keep the overall flux at the Monitor_Optimizer position but the total number of targeting neutrons is increased. I don't know if you had time to look at that but it could be usefull to McStas users. I hope the usage of thoses components is simple enough... I'm now looking for some efficient phonon model in crystals (not so easy...), and also, we plan, with Tref Roberts, to think again to magnetic components that would affect the neutron spin. The ILL McStas users should meet next week (I hope) to organize our forces and requirements. We could also create a McStas Web site mirror... What about it ? Cheers. EF. -- Emmanuel FARHI, http://www.ill.fr/tas/people/Farhi.html \|/ ____ \|/ TAS-Group, Institut Laue-Langevin (ILL) Grenoble ~@-/ oO \-@~ Avenue des Martyrs, BP 156, 38042 Grenoble Cedex 9,France /_( \__/ )_\ Work :Tel (33/0) 4 76 20 71 83. Fax (33/0) 4 76 48 39 06 \__U_/ La Grande Arche, Chateau d'Uriage, 38410 Saint Martin d'Uriage 04 76 59 73 94 -------------- next part -------------- An HTML attachment was scrubbed... URL: From kristian.nielsen at risoe.dk Mon Nov 8 10:15:48 1999 From: kristian.nielsen at risoe.dk (Kristian Nielsen) Date: 8 Nov 1999 10:15:48 +0100 Subject: What's new ? In-Reply-To: <3823020E.4BD6AB2D@ill.fr> (message from Farhi on Fri, 05 Nov 1999 17:13:02 +0100) Message-ID: > Date: Fri, 05 Nov 1999 17:13:02 +0100 > From: Farhi Hi Emmanuel, I am sorry that I haven't been in touch. You new components are still sitting in my mailbox, I have been intending to put them up on the web page but just haven't found the time yet. I promise I will put them up this week. They will certainly be useful for other McStas users. Recently I finished the first stable version of a graphical user interface for McStas. It automatically compiles and runs simulations, and is particularly useful for re-running old simulations with slightly different parameters. If you are interested in testing it, I could send you a new version of McStas? I am of course looking forward to learning more about your phonon work. Currently we are starting to investigate single crystals in detail here at Ris?. I am of course very happy to see that there is a great deal of activity on Monte Carlo at the ILL (I also saw the Monte Carlo proposal in the Millennium Program, good luck on that!). I is quite unfortunate that I have been so busy recently, hopefully this will improve soon -- I do not want you to loose steem in your very active work on McStas! So keep on sending we your ideas and nagging me when I am slow to respond! About the web mirror: I am not quite sure what you had in mind. I suppose just a passive mirror would be of limited use (unless the intent is to speed up access from within the ILL?). It seems to me that what is really needed is some setup where selected people at the ILL could add to the web pages (eg. the component download page) so that things can appear quickly without the need to wait for action on my part. Maybe a two-way mirror, where changes at both the ILL and Ris? servers are mirrored back and forth. What do you think? I should certainly be able to handle any technical aspects at Ris? in whatever way is most convenient for you. - Kirstian. -- Kristian Nielsen kristian.nielsen at risoe.dk Ris? National Laboratory Condensed Matter Physics and Chemistry Department Tel. +45 4677 5515 Fax +45 4677 4790 From farhi at ill.fr Mon Nov 8 10:55:14 1999 From: farhi at ill.fr (Farhi) Date: Mon, 08 Nov 1999 10:55:14 +0100 Subject: What's new ? References: <01JI3AOJDG388X98DC@risoe.dk> Message-ID: <38269E01.DA976AB4@ill.fr> Hy Kristian, This all sounds great. Please send me your 'clic and run' version of McStas.I'll be glad to test it. What interface did you use : Tcl/Tk ? Java ? ... We have a pre-meeting next week, Ian Anderson, Mark Johnson and I, to organize tasks and fields of action. A 'real' meeting should follow, with all interested users. Concerning the Web mirror, you're right, just having a shared 'download' page in order to be able to add stuff on the fly would be great, and reduce your work load ! I will talk about this next week (I'm in vacation tomorrow night, till the 16th morning) Cheers and have fun ! EF. Kristian Nielsen wrote: > > Date: Fri, 05 Nov 1999 17:13:02 +0100 > > From: Farhi > > Hi Emmanuel, > > I am sorry that I haven't been in touch. You new components are still > sitting in my mailbox, I have been intending to put them up on the web > page but just haven't found the time yet. I promise I will put them up > this week. They will certainly be useful for other McStas users. > > Recently I finished the first stable version of a graphical user > interface for McStas. It automatically compiles and runs simulations, > and is particularly useful for re-running old simulations with slightly > different parameters. If you are interested in testing it, I could send > you a new version of McStas? > > I am of course looking forward to learning more about your phonon > work. Currently we are starting to investigate single crystals in detail > here at Ris?. > > I am of course very happy to see that there is a great deal of activity > on Monte Carlo at the ILL (I also saw the Monte Carlo proposal in the > Millennium Program, good luck on that!). I is quite unfortunate that I > have been so busy recently, hopefully this will improve soon -- I do not > want you to loose steem in your very active work on McStas! So keep on > sending we your ideas and nagging me when I am slow to respond! > > About the web mirror: I am not quite sure what you had in mind. I > suppose just a passive mirror would be of limited use (unless the intent > is to speed up access from within the ILL?). It seems to me that what is > really needed is some setup where selected people at the ILL could add > to the web pages (eg. the component download page) so that things can > appear quickly without the need to wait for action on my part. Maybe a > two-way mirror, where changes at both the ILL and Ris? servers are > mirrored back and forth. What do you think? I should certainly be able > to handle any technical aspects at Ris? in whatever way is most > convenient for you. > > - Kirstian. > > -- > Kristian Nielsen kristian.nielsen at risoe.dk > Ris? National Laboratory > Condensed Matter Physics and Chemistry Department > Tel. +45 4677 5515 Fax +45 4677 4790 -- Emmanuel FARHI, http://www.ill.fr/tas/people/Farhi.html \|/ ____ \|/ TAS-Group, Institut Laue-Langevin (ILL) Grenoble ~@-/ oO \-@~ Avenue des Martyrs, BP 156, 38042 Grenoble Cedex 9,France /_( \__/ )_\ Work :Tel (33/0) 4 76 20 71 83. Fax (33/0) 4 76 48 39 06 \__U_/ La Grande Arche, Chateau d'Uriage, 38410 Saint Martin d'Uriage 04 76 59 73 94 -------------- next part -------------- An HTML attachment was scrubbed... URL: From kristian.nielsen at risoe.dk Fri Nov 12 17:38:36 1999 From: kristian.nielsen at risoe.dk (Kristian Nielsen) Date: 12 Nov 1999 17:38:36 +0100 Subject: What's new ? In-Reply-To: <38269E01.DA976AB4@ill.fr> (message from Farhi on Mon, 08 Nov 1999 10:55:14 +0100) Message-ID: > Date: Mon, 08 Nov 1999 10:55:14 +0100 > From: Farhi > This all sounds great. > Please send me your 'clic and run' version of McStas.I'll be glad to = > test > it. What interface did you use : Tcl/Tk ? Java ? ... Ok, I put it on the web server at http://neutron.risoe.dk/mcstas/support/farhi/mcstas-1.17A.tar.gz It installs as usual. After installation, two new front-ends should be available, "mcgui" and "mcrun". The "mcrun" one is a command-line interface that automatically recompiles simulations if necessary, ie. mcrun in14_6.instr -n 1e5 KI=2.66 WN=0.03 ORDER=1 MHV=3 will run your in14 simulation, automatically running mcstas and the C compiler when the definition is changed. The "mcgui" front-end is the point-and-click interface. It allows you to load an instrument definition and modify it in a simple editor. You then select "run simulation", and a dialog will pop up allowing you to enter the values for instrument parameters etc, and then run the simulation. Optionally, the results will be plottet using mcplot. It is also possible to read in the "mcstas.sim" file from a previous simulation ("Read old simulation") to either plot the data or to re-run the simulation with the same parameters. Please let me know if you have any problems, I have tried to make it as simple and intuitive to use as possible. I used the Perl/Tk library, which is the same graphics library used in Tcl/Tk, but using Perl instead of Tcl. You can download it from the download page on the McStas web server, hopefully it will be easier to install than the PgPerl library. I also now put your new components on the "unofficial downloads" page. Once again, many thanks for your work! I hope I got everything right with file versions and so on. I think your components will be very useful. Have you considered sending a message to the mailing list (neutron-mc at risoe.dk) to announce your work and offer it to the other McStas users? - Kristian. From farhi at ill.fr Tue Nov 16 18:43:23 1999 From: farhi at ill.fr (Farhi) Date: Tue, 16 Nov 1999 18:43:23 +0100 Subject: v1.17A Message-ID: <383197BA.EF454F53@ill.fr> Hy, I've installed the version 1.17A of McStas. Problems : 1-Definition of components change sometimes (for instance Guide2). The version of in14_6 that I posted you uses the old Guide2.comp definition (from unofficial page). The new one which is included in the McStas distribution uses different parameters... 2- Some help sections in components have disappeared since previous versions Undocumented : Channeled_guide.comp DivPos_monitor.comp Divenergymon.comp Guide2.comp Mosaic_multi.comp Res_monitor.comp Res_sample.comp Source_div.comp Source_flat.comp Source_flux.comp 3- The MCGui seems to work ok My comments are : would it be possible to make a-Highlight syntaxing, such as in nedit or vim, with C based template and MCSTAS macros added By the way, it is possible for instance to customize the 'Shell' menu of NEdit in order to execute some mcstas operations. Perhaps a good option would be to optionally use the EDITOR variable, and use the mcgui one as default. mcgui could then check for changes in file and warn if unsaved before compiling. b- I guess you intend to add some copy/paste and search/replace features sometimes... (with Unix mouse text mode right now). Ctrl-C, X and V seem to work ok. 4- I've tried to obtain the HMI Vitess program. No way to compile it on my Mac PPC G3. And it appears quite monolythic (no way to create/modify components or instrument structure) 5- We've planed a Monte-Carlo unofficial workshop on January 21th 2000. You're invited of course. The aim is to gather efforts concerning MC simulations (i.e. Shadow, Vitess, McStas, Restrax, ...) even if I think that some dev team won't be keen on cooperating. Concerning McStas, it means presenting some instrument templates for each kind of instrument here at ILL : TAS, Diffractometers, TOF, backscattering, etc... For reflectometers, handling neutron interferences is not straight forward yet (need to propagate the neutron phase also) For SpinEcho, we should get further in designing magnetic components... Also we need to create some efficient samples for testing instruments. Powder is ok, need crystals... In order to achieve those points, we are now gathering McStas users at ILL. 6- After discussion, the 'chiefs' think it's better to have a specific ILL page for instruments, components, and documentation. Links would reach the Risoe site. Does all this sounds ok for you ? Cheers. EF. -- Emmanuel FARHI, http://www.ill.fr/tas/people/Farhi.html \|/ ____ \|/ TAS-Group, Institut Laue-Langevin (ILL) Grenoble ~@-/ oO \-@~ Avenue des Martyrs, BP 156, 38042 Grenoble Cedex 9,France /_( \__/ )_\ Work :Tel (33/0) 4 76 20 71 83. Fax (33/0) 4 76 48 39 06 \__U_/ La Grande Arche, Chateau d'Uriage, 38410 Saint Martin d'Uriage 04 76 59 73 94 -------------- next part -------------- An HTML attachment was scrubbed... URL: From kristian.nielsen at risoe.dk Wed Nov 17 11:03:04 1999 From: kristian.nielsen at risoe.dk (Kristian Nielsen) Date: 17 Nov 1999 11:03:04 +0100 Subject: v1.17A In-Reply-To: <383197BA.EF454F53@ill.fr> (message from Farhi on Tue, 16 Nov 1999 18:43:23 +0100) Message-ID: > Date: Tue, 16 Nov 1999 18:43:23 +0100 > From: Farhi > I've installed the version 1.17A of McStas. Great! I realize that I may have forgotten to warn you that this is again an ALPHA version, meaning that it may be unstable, etc. Your comments on problems are very useful, I will fix the problems you mention in the upcoming v1.2 proper release. > Problems : > 1-Definition of components change sometimes (for instance Guide2). The Yes, I was aware of this but it is good to be reminded! I will fix this, probably by renaming the new Guide component to something else. For now, just delete it or copy the one from the unofficial download page on top. I actually try very hard to be 100% backward compatible in new versions, so if you saw any more problems than the Guide2 component you mentioned, please let me know. Anyway, my plan is to implement optional parameters in components, ie. parameters that have default values if the user does not specify them. This would make it easier to extend components while maintaining backwards compatibility. > 2- Some help sections in components have disappeared since previous > versions > > Undocumented : > Channeled_guide.comp > DivPos_monitor.comp [...] Yes, the missing documentation is the main thing that I need to finish before I can release the next version. > 3- The MCGui seems to work ok My comments are : would it be possible to > make a-Highlight syntaxing, such as in nedit or vim, with C based > template and MCSTAS macros added By the way, it is possible for Of course, but it would probably be a lot of work. > instance to customize the 'Shell' menu of NEdit in order to execute some > mcstas operations. Yes, I think this is a better way to proceed. Anyway, there should be no problem using another editor instead of the really stupid one in mcgui. Mcgui will automatically recompile if the instrument has changed on disk, independent of what is in the internal editor. > Perhaps a good option would be to optionally use the EDITOR variable, > and use the mcgui one as default. mcgui could then check for changes in Yes, this is a good idea. The mcgui editor was only added because it could be done in two lines of code with Perl/Tk, I am not sure it is really a good idea. For serious use one would definitely use a better editor. > file and warn if unsaved before compiling. > b- I guess you intend to add some copy/paste and search/replace features > sometimes... (with Unix mouse text mode right now). Ctrl-C, X and V seem > to work ok. Yes, maybe. > 4- I've tried to obtain the HMI Vitess program. No way to compile it on > my Mac PPC G3. And it appears quite monolythic (no way to create/modify > components or instrument structure) Ah! I also tried it, and I agree with your impression. Apparently they are not willing to let anyone have their source code, which is in my opinion a very serious limitation. And also a great pity, since some of their components seem to have received a lot of effort. Overall, VITESS appears to be still a bit behind programs like McStas, MCLIB, and SHADOW. > 5- We've planed a Monte-Carlo unofficial workshop on > > January 21th 2000. > > You're invited of course. The aim is to gather efforts concerning MC > simulations (i.e. Shadow, Vitess, McStas, Restrax, ...) even if I think > that some dev team won't be keen on cooperating. Ok, thanks for the notice, I will make a note in my calendar. Hopefully I can participate, it sounds quite interesting. Also, I think (=hope) that McStas v1.2 will have been released by then. > For reflectometers, handling neutron interferences is not straight > forward yet (need to propagate the neutron phase also) > For SpinEcho, we should get further in designing magnetic components... Yes, this is an interesting direction of development, with entirely new challenges. It is very good that effort is being spent on this at the ILL, I am not aware of any previous major effort on spin in Monte Carlo. > Also we need to create some efficient samples for testing instruments. > Powder is ok, need crystals... I am currently working with some other people at Risoe on very realistic single-crystal samples (many reflections with individual structure factors, multiple scattering, mosaic, ...). And similarly for powder. Expect something good in a few months, maybe even at the ILL Workshop (no promises though!). > 6- After discussion, the 'chiefs' think it's better to have a specific > ILL page for instruments, components, and documentation. Links would > reach the Risoe site. Ok. In any case, in the future I will be more quick to put contributed components on the web page, especially if it just involves a link to the ILL pages. Thanks for the comments on the new McStas version, I will fix things before the official release. - Kristian. From kristian.nielsen at risoe.dk Wed Nov 17 14:20:32 1999 From: kristian.nielsen at risoe.dk (Kristian Nielsen) Date: 17 Nov 1999 14:20:32 +0100 Subject: Updates... In-Reply-To: <38327DDC.40C7E613@ill.fr> (message from Farhi on Wed, 17 Nov 1999 11:05:16 +0100) Message-ID: > Date: Wed, 17 Nov 1999 11:05:16 +0100 > From: Farhi > I've been updating the flux-adapter for a faster interpolation. Also, > the in14_6.instr simulation now uses the Guide2.comp from the McStas > distribution. Ok, I put the new version of the flux-adapter on the web page. I did not upload the new in14_6 simulation since, as I wrote in the previous mail, in the next release I will rename the official Guide2 component so that it does not conflict with the unofficial one. > You know, already as an Alpha it's great, so ... > for instance it is now possible to install transparently instrument > simulations easy to use (for visitors) on real instruments. Ah yes, that could be a good adea. I definitely need to provide an option to hide the editor in mcgui for when it is not wanted. I will think about it. > Concerning the crystal samples, Thomas and I are now thinking about some > components describing inelastic, incoherent, elastic scattering (for phonons, > magnons, Bragg...). > How far are you now on this way ? I am quite far on elastic powder, single crystal, and mosaic crystal, and at least the single crystal will be finished early next January since we need it for a Ph.D school. For inelastic, we have hardly begun yet. - Kristian. From farhi at ill.fr Wed Nov 17 13:13:11 1999 From: farhi at ill.fr (Farhi) Date: Wed, 17 Nov 1999 13:13:11 +0100 Subject: v1.17A References: <01JIFWYC6NKQ8XD4WX@risoe.dk> Message-ID: <38329BD7.6FDB953B@ill.fr> You know, already as an Alpha it's great, so ... for instance it is now possible to install transparently instrument simulations easy to use (for visitors) on real instruments. Concerning the crystal samples, Thomas and I are now thinking about some components describing inelastic, incoherent, elastic scattering (for phonons, magnons, Bragg...). How far are you now on this way ? Cheers. EF. Kristian Nielsen wrote: > > Date: Tue, 16 Nov 1999 18:43:23 +0100 > > From: Farhi > > > I've installed the version 1.17A of McStas. > > Great! I realize that I may have forgotten to warn you that this is > again an ALPHA version, meaning that it may be unstable, etc. Your > comments on problems are very useful, I will fix the problems you > mention in the upcoming v1.2 proper release. > > > Problems : > > 1-Definition of components change sometimes (for instance Guide2). The > > Yes, I was aware of this but it is good to be reminded! I will fix this, > probably by renaming the new Guide component to something else. For now, > just delete it or copy the one from the unofficial download page on top. > > I actually try very hard to be 100% backward compatible in new versions, > so if you saw any more problems than the Guide2 component you mentioned, > please let me know. > > Anyway, my plan is to implement optional parameters in components, > ie. parameters that have default values if the user does not specify > them. This would make it easier to extend components while maintaining > backwards compatibility. > > > 2- Some help sections in components have disappeared since previous > > versions > > > > Undocumented : > > Channeled_guide.comp > > DivPos_monitor.comp > [...] > > Yes, the missing documentation is the main thing that I need to finish > before I can release the next version. > > > 3- The MCGui seems to work ok My comments are : would it be possible to > > make a-Highlight syntaxing, such as in nedit or vim, with C based > > template and MCSTAS macros added By the way, it is possible for > > Of course, but it would probably be a lot of work. > > > instance to customize the 'Shell' menu of NEdit in order to execute some > > mcstas operations. > > Yes, I think this is a better way to proceed. Anyway, there should be no > problem using another editor instead of the really stupid one in > mcgui. Mcgui will automatically recompile if the instrument has changed > on disk, independent of what is in the internal editor. > > > Perhaps a good option would be to optionally use the EDITOR variable, > > and use the mcgui one as default. mcgui could then check for changes in > > Yes, this is a good idea. The mcgui editor was only added because it > could be done in two lines of code with Perl/Tk, I am not sure it is > really a good idea. For serious use one would definitely use a better > editor. > > > file and warn if unsaved before compiling. > > > b- I guess you intend to add some copy/paste and search/replace features > > sometimes... (with Unix mouse text mode right now). Ctrl-C, X and V seem > > to work ok. > > Yes, maybe. > > > 4- I've tried to obtain the HMI Vitess program. No way to compile it on > > my Mac PPC G3. And it appears quite monolythic (no way to create/modify > > components or instrument structure) > > Ah! I also tried it, and I agree with your impression. Apparently they > are not willing to let anyone have their source code, which is in my > opinion a very serious limitation. And also a great pity, since some of > their components seem to have received a lot of effort. Overall, VITESS > appears to be still a bit behind programs like McStas, MCLIB, and SHADOW. > > > 5- We've planed a Monte-Carlo unofficial workshop on > > > > January 21th 2000. > > > > You're invited of course. The aim is to gather efforts concerning MC > > simulations (i.e. Shadow, Vitess, McStas, Restrax, ...) even if I think > > that some dev team won't be keen on cooperating. > > Ok, thanks for the notice, I will make a note in my calendar. Hopefully > I can participate, it sounds quite interesting. Also, I think (=hope) > that McStas v1.2 will have been released by then. > > > For reflectometers, handling neutron interferences is not straight > > forward yet (need to propagate the neutron phase also) > > For SpinEcho, we should get further in designing magnetic components... > > Yes, this is an interesting direction of development, with entirely new > challenges. It is very good that effort is being spent on this at the > ILL, I am not aware of any previous major effort on spin in Monte Carlo. > > > Also we need to create some efficient samples for testing instruments. > > Powder is ok, need crystals... > > I am currently working with some other people at Risoe on very realistic > single-crystal samples (many reflections with individual structure > factors, multiple scattering, mosaic, ...). And similarly for > powder. Expect something good in a few months, maybe even at the ILL > Workshop (no promises though!). > > > 6- After discussion, the 'chiefs' think it's better to have a specific > > ILL page for instruments, components, and documentation. Links would > > reach the Risoe site. > > Ok. In any case, in the future I will be more quick to put contributed > components on the web page, especially if it just involves a link to the > ILL pages. > > Thanks for the comments on the new McStas version, I will fix things > before the official release. > > - Kristian. -- Emmanuel FARHI, http://www.ill.fr/tas/people/Farhi.html \|/ ____ \|/ TAS-Group, Institut Laue-Langevin (ILL) Grenoble ~@-/ oO \-@~ Avenue des Martyrs, BP 156, 38042 Grenoble Cedex 9,France /_( \__/ )_\ Work :Tel (33/0) 4 76 20 71 83. Fax (33/0) 4 76 48 39 06 \__U_/ La Grande Arche, Chateau d'Uriage, 38410 Saint Martin d'Uriage 04 76 59 73 94 -------------- next part -------------- An HTML attachment was scrubbed... URL: From farhi at ill.fr Wed Nov 17 11:05:16 1999 From: farhi at ill.fr (Farhi) Date: Wed, 17 Nov 1999 11:05:16 +0100 Subject: Updates... Message-ID: <38327DDC.40C7E613@ill.fr> Hy Kristian, I've been updating the flux-adapter for a faster interpolation. Also, the in14_6.instr simulation now uses the Guide2.comp from the McStas distribution. Cheers. EF. -- Emmanuel FARHI, http://www.ill.fr/tas/people/Farhi.html \|/ ____ \|/ TAS-Group, Institut Laue-Langevin (ILL) Grenoble ~@-/ oO \-@~ Avenue des Martyrs, BP 156, 38042 Grenoble Cedex 9,France /_( \__/ )_\ Work :Tel (33/0) 4 76 20 71 83. Fax (33/0) 4 76 48 39 06 \__U_/ La Grande Arche, Chateau d'Uriage, 38410 Saint Martin d'Uriage 04 76 59 73 94 -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- DEFINE INSTRUMENT IN14(KI,WN,ORDER,MHV) /* preprocess with : mcstas in14_6.instr */ /* compile on mica with : cc -Ofast -64 -o in14_3 in14_3.c -lm */ /* on LinuxPPC gcc -O2 -o in14_6 in14_6.c -lm */ /* Test with : */ /* in14_6 -n 1e6 KI=2.66 WN=0.03 ORDER=1 MHV=3 */ /* This simulation for McStas is IN14 from source to sample, with a curved monochromator, and a supermirror focalizing guide before sample */ DECLARE %{ #define VERSION "60a" double L1 = 16.68; /* source-mono */ double L2 = 2.12; /* mono-sample */ double L3 = 1.35; /* sample-ana */ double L4 = 0.70; /* ana-det */ int SM,SS,SA; double A1,A3,A5; double LM1, LM1b; /* distances to monitors M1 and M2 */ double LM2, LM2b; double A2,A4,A6,RM,RH; char *pfile; char *efile; char *dfile; char *kfile; /* ==================== Source description ==================== */ double EN; double D_EN; double EMIN, EMAX; double FLUX = 1e13; /* n/cm^2/s on guide entry */ /* ==================== Monochromator desciption ==================== */ double ETAM = 30; /* Mosaicity used on monochromator 30 */ double DM = 3.355; /* Monochromator d-spacing in Angs */ /* PG002 Orders : 1st 3.355 2e 1.6775, 3e 1.1183 */ double mono_r0 = 0.9; /* mean reflectivity */ double mono_width = 0.15; double mono_heigh = .122; double mono_gap = 0; /* slates are adjacent */ int mono_segment_number_vert = 7; int mono_segment_number_horz = 1; double mono_curv_vert; /* Vertical Rotation between adjacent slabs. */ double mono_curv_horz; /* Horizontal Rotation between adjacent slabs. */ double mono_slate_heigh; /* size (height) of slates */ double mono_slate_width; /* size (width) of slates */ double mono_q; /* Q vector for bragg scattering with monochromator and analysator */ double Ki, Ei; double TM, GM; /* ==================== Sample desciption ==================== */ double TU, TL; double GU, GL; /* ==================== Analyser desciption ==================== */ double ETAA = 30; /* Mosaicity used on analyser 30 */ double DA = 3.355; /* analyser d-spacing in Angs */ /* PG002 Orders : 1st 3.355 2e 1.6775, 3e 1.1183 */ double ana_r0 = 0.9; /* mean reflectivity */ double ana_width = 0.10; double ana_heigh = .14; double ana_gap = 0; /* slates are adjacent */ int ana_segment_number_vert = 7; int ana_segment_number_horz = 1; double ana_curv_vert; /* Vertical Rotation between adjacent slabs. */ double ana_curv_horz; /* Horizontal Rotation between adjacent slabs. */ double ana_slate_heigh; /* size (height) of slates */ double ana_slate_width; /* size (width) of slates */ double ana_q; /* Q vector for bragg scattering with monochromator and analysator */ double Kf, Ef; double TA, GA; %} INITIALIZE %{ double vi,vf,sample_q; mono_q = 2*PI*ORDER/DM; /* Q mono in Angs-1 */ A4 = 0; A2 = asin(mono_q/2/KI)*RAD2DEG*2; A6 = A2; printf("Instrument : IN14, v%s (21/09/99) on %s.\n",VERSION,getenv("HOSTNAME")); /* SM : scattering at mono to the right (-1)/left(+1) */ /* SS : scattering at sample to the right (-1)/left(+1) */ /* SA : scattering at analyser to the right (-1)/left(+1) */ SM = 1; SS = 1; SA = 1; A2 *= SM; /* A1 : mono theta (crystal) */ A1 = A2/2; /* A2 : mono 2 theta (arm to sample) */ A4 *= SS; /* A3 : sample theta */ A3 = A4/2; /* A4 : sample 2 theta (arm to analyser) */ A6 *= SA; /* A5 : analyser theta (crystal) */ A5 = A6/2; /* A6 : analyser 2 theta (arm to detector) */ TM = 0; /* TM : translation mono */ GM = 0; /* GM : tilt mono */ GU = 0; /* GU : tilt sample Up */ GL = 0; /* GL : tilt sample Low */ TU = 0; /* TU : translation sample Up */ TL = 0; /* TL : translation sample Low */ TA = 0; /* TA : translation analyser */ GA = 0; /* GA : tilt analyser */ /* RA : horizontal curvature analyser */ if ((fabs(mono_q/2/KI) < 1) && (sin(DEG2RAD*A1) != 0)) Ki = mono_q/2/sin(DEG2RAD*A1); else { printf("Warn : Can't define incident wave vector Ki\n"); Ki = 0; printf("Skipping simulation\n"); exit(-1); } vi = K2V*fabs(Ki); Ei = VS2E*vi*vi; EN = Ei; D_EN = .5; /* optimize source on Ki */ ana_q = 2*PI/DA; /* Q ana in Angs-1 */ if (sin(DEG2RAD*A5) != 0) Kf = ana_q/2/sin(DEG2RAD*A5); else { printf("Warn : Can't define outgoing wave vector Kf\n"); Kf = 0; } vf = K2V*fabs(Kf); Ef = VS2E*vf*vf; sample_q = sqrt(Ki*Ki + Kf*Kf -2*fabs(Ki*Kf)*cos(DEG2RAD*A4)); mono_slate_heigh = mono_heigh/mono_segment_number_vert; /* slates are adjacent */ mono_curv_vert = fabs(mono_slate_heigh*RAD2DEG/(2*L2*sin(DEG2RAD*A1))); /* RM : vertical mono curvature */ mono_slate_width = mono_width/mono_segment_number_horz; /* slates are adjacent */ mono_curv_horz = fabs(mono_slate_width*RAD2DEG*sin(DEG2RAD*A1)/(2*L2)); /* RH : horizontal mono curvature */ ana_slate_heigh = ana_heigh/ana_segment_number_vert; /* slates are adjacent */ ana_curv_vert = fabs(ana_slate_heigh*RAD2DEG/(2*L3*sin(DEG2RAD*A5))); /* RA : vertical ana curvature */ ana_slate_width = ana_width/ana_segment_number_horz; /* slates are adjacent */ ana_curv_horz = fabs(ana_slate_width*RAD2DEG*sin(DEG2RAD*A5)/(2*L3)); /* RHA : horizontal ana curvature */ /* print instrument config */ printf("Flat source, m=%.2f noze, width %.2f\n",MHV,WN); printf("Monochromator : (DM = %g)\n",DM); printf("A1 = %.2f, A2 = %.2f (deg)\n",A1,A2); printf("Ki = %.3g Angs-1 (Energy = %.3g meV, Velocity = %.3g m/s) \n", Ki, Ei,vi); printf("RM = %.3g Deg, RH = %.3g Deg\n",mono_curv_vert,mono_curv_horz); printf("\n"); printf("Sample :\n"); printf("A3 = %.2f, A4 = %.2f (deg)\n",A3,A4); printf("Energy transfert %.3g meV, Moment transfert %.3g Angs-1\n",Ef-Ei,sample_q); printf("\n"); printf("Analyser : (DA = %g)\n",DA); printf("A5 = %.2f, A6 = %.2f (deg)\n",A5,A6); printf("Kf = %.3g Angs-1 (Energy = %.3g meV, Velocity = %.3g m/s) \n", Kf, Ef,vf); printf("RA = %.3g Deg\n",ana_curv_vert); printf("\n"); printf("Detectors :\n"); /* local variables ------------------------------------ */ LM1 = L2*.9; LM1b = LM1+0.001; LM2 = L3/2; LM2b = LM2+0.001; EMIN = EN - D_EN; EMAX = EN + D_EN; pfile = (char *)malloc(256); efile = (char *)malloc(256); dfile = (char *)malloc(256); kfile = (char *)malloc(256); sprintf(pfile,"sim/i%s_k%iw%id%im%i.psd",VERSION,(int)floor(10*Ki+0.5),(int)floor(1000*WN),(int)floor(ORDER),(int)floor(MHV+0.5)); sprintf(efile,"sim/i%s_k%iw%id%im%i.nrj",VERSION,(int)floor(10*Ki+0.5),(int)floor(1000*WN),(int)floor(ORDER),(int)floor(MHV+0.5)); sprintf(dfile,"sim/i%s_k%iw%id%im%i.div",VERSION,(int)floor(10*Ki+0.5),(int)floor(1000*WN),(int)floor(ORDER),(int)floor(MHV+0.5)); sprintf(kfile,"sim/i%s_k%iw%id%im%i.kw",VERSION,(int)floor(10*Ki+0.5),(int)floor(1000*WN),(int)floor(ORDER),(int)floor(MHV+0.5)); %} TRACE COMPONENT origin = Arm() AT (0,0,0) ABSOLUTE COMPONENT source = Source_flux( radius = 0.20, dist = 2.16, xw = 0.06, yh = 0.12, E0 = EN, dE = D_EN, flux=FLUX) AT (0,0,0) RELATIVE origin ROTATED (0,0,0) RELATIVE origin COMPONENT ESourceOut = E_monitor( xmin = -0.1, xmax = 0.1, ymin = -0.1, ymax = 0.1, Emin = EMIN, Emax = EMAX, nchan = 21, filename = "beforeflux.nrj") AT(0, 0, 0.004) RELATIVE origin ROTATED (0,0,0) RELATIVE origin COMPONENT fa = Flux_adapter( xmin = -0.1, xmax = 0.1, ymin = -0.1, ymax = 0.1, file="source.flux", options="") AT (0,0,0.1) RELATIVE origin ROTATED (0,0,0) RELATIVE origin COMPONENT EAfterFlux = E_monitor( xmin = -0.1, xmax = 0.1, ymin = -0.1, ymax = 0.1, Emin = EMIN, Emax = EMAX, nchan = 21, filename = "outflux.nrj") AT(0, 0, 0.101) RELATIVE origin ROTATED (0,0,0) RELATIVE origin COMPONENT optim_s = Source_Optimizer( xmin = -0.1, xmax = 0.1, ymin = -0.1, ymax = 0.1, bins = -1, step = 10, keep = 10, file="source.optim", options="absorb") AT (0,0,2.145) RELATIVE origin ROTATED (0,0,0) RELATIVE origin COMPONENT EAfterOptim = E_monitor( xmin = -0.1, xmax = 0.1, ymin = -0.1, ymax = 0.1, Emin = EMIN, Emax = EMAX, nchan = 21, filename = "outoptim.nrj") AT(0, 0, 2.146) RELATIVE origin ROTATED (0,0,0) RELATIVE origin COMPONENT doigt_de_gant = Guide( w1 = 0.06, h1 = 0.12, w2 = 0.06, h2 = 0.12, l = 2.75, /* guide into the doigt de gant */ R0 = 1, m=1.2, /* Ni 58 */ Qc = 0.021, alpha = 2.33, W = 2e-3) AT (0,0,2.15) RELATIVE origin ROTATED (0,0,0) RELATIVE origin COMPONENT external_guide = Guide2( w1 = 0.06, h1 = 0.12, w2 = 0.06, h2 = 0.12, l = 13.67, /* external guide between doigt de gant and mono */ R0 = 1, Qcx = 0.021, Qcy = 0.021, alphax = 2.33, alphay = 2.33, mx=1.2, /* 1.2 Ni 58, 3 Super mirror */ my=1.2, W = 2e-3) AT (0,0,4.91) RELATIVE origin ROTATED (0,0,0) RELATIVE origin /* -------------- Start of monochromator building -------------- */ /* support of mono */ COMPONENT focus_mono = Arm() AT (0, 0, L1) RELATIVE origin ROTATED (0, A1, 0) RELATIVE origin COMPONENT m0 = Mon_2foc( zwidth=mono_slate_width, ywidth=mono_slate_heigh, gap=mono_gap, NH=mono_segment_number_vert, NV=mono_segment_number_horz, mosaich=ETAM, mosaicv=ETAM, r0=mono_r0, Q=mono_q, RH=mono_curv_vert, RV=mono_curv_horz) AT (TM, 0, 0) RELATIVE focus_mono ROTATED (0, 0, GM) RELATIVE focus_mono /* on mono, pointing towards sample */ COMPONENT out_mono = Arm() AT (0,0,0) RELATIVE focus_mono ROTATED (0, A2, 0) RELATIVE origin /* -------------- End of monochromator building -------------- */ COMPONENT noze = Guide2( w1 = 0.05, h1 = 0.05, w2 = WN, h2 = 0.05, l = .825, R0 = 1, Qcx = 0.021, Qcy = 0.021, alphax = 2.33, alphay = 2.33, mx = MHV, my =1e-5, /* Ni 58 */ W = 2e-3) AT (0, 0, .9) RELATIVE out_mono ROTATED (0,0,0) RELATIVE out_mono /* -------------- Start of sample building -------------- */ /* support of sample */ COMPONENT focus_sample = Arm() AT (0, 0, L2) RELATIVE out_mono ROTATED (0,A3,0) RELATIVE out_mono /* COMPONENT sample = Powder1( radius = 0.007, h = 0.015, q = 1.8049, d_phi0 = 4, pack = 1, j = 6, DW = 1, F2 = 56.8, Vc = 85.0054, sigma_a = 0.463, target_x = alu_focus_x, target_y = 0, target_z = 1000) AT (GU, 0, GL) RELATIVE focus_sample ROTATED (TU,0,TL) RELATIVE focus_sample */ COMPONENT optim_m = Monitor_Optimizer( xmin = -0.05, xmax = 0.05, ymin = -0.05, ymax = 0.05) AT(0, 0, 0) RELATIVE focus_sample ROTATED (0,0,0) RELATIVE focus_sample COMPONENT PSDSample = PSD_monitor( xmin = -0.05, xmax = 0.05, ymin = -0.05, ymax = 0.05, nx = 50, ny = 50, filename = pfile) AT(0, 0, 0.001) RELATIVE focus_sample ROTATED (0,0,0) RELATIVE focus_sample COMPONENT ESample = E_monitor( xmin = -0.005, xmax = 0.005, ymin = -0.005, ymax = 0.005, Emin = EMIN, Emax = EMAX, nchan = 21, filename = efile) AT(0, 0, 0.004) RELATIVE focus_sample ROTATED (0,0,0) RELATIVE focus_sample COMPONENT DivSample = Divergence_monitor( xmin = -0.005, xmax = 0.005, ymin = -0.005, ymax = 0.005, nv = 10, nh= 10, v_maxdiv = 0.5, h_maxdiv = 0.5, filename = dfile) AT(0, 0, 0.005) RELATIVE focus_sample ROTATED (0,0,0) RELATIVE focus_sample COMPONENT kw = kw_monitor( xmin = -0.005, xmax = 0.005, ymin = -0.005, ymax = 0.005, filename = kfile) AT(0, 0, 0.006) RELATIVE focus_sample ROTATED (0,0,0) RELATIVE focus_sample /* on sample, pointing towards ana */ COMPONENT out_sample = Arm() AT (0,0,0) RELATIVE focus_sample ROTATED (0, A4, 0) RELATIVE out_mono /* -------------- End of sample building -------------- */ /* COMPONENT M2 = Monitor( xmin = -0.1, xmax = 0.1, ymin = -0.1, ymax = 0.1) AT (0, 0, LM2) RELATIVE out_sample ROTATED (0,0,0) RELATIVE out_sample */ /* -------------- Start of analyzer building -------------- */ /* support of analyzer */ /* COMPONENT focus_ana = Arm() AT (0, 0, L3) RELATIVE out_sample ROTATED (0,A5,0) RELATIVE out_sample COMPONENT a0 = Mon_2foc( zwidth = ana_half_width, ywidth = ana_half_heigh, gap = 0, NH = 1, NV = 1, mosaich = ETAA, mosaicv = ETAA, r0 = ana_r0, Q = ana_q, RH=ana_curv_vert, RV=ana_curv_horz) AT (TA, 0, 0) RELATIVE focus_ana ROTATED (0, 0, GA) RELATIVE focus_ana COMPONENT out_ana = Arm() AT (0, 0, 0) RELATIVE focus_ana ROTATED (0, A6, 0) RELATIVE out_sample */ /* -------------- End of analyzer building -------------- */ /* COMPONENT focus_det = Arm() AT (0, 0, L4) RELATIVE out_ana ROTATED (0,0,0) RELATIVE out_ana COMPONENT Detector = Monitor( xmin = -0.02, xmax = 0.02, ymin = -0.05, ymax = 0.05) AT(0, 0, 0) RELATIVE focus_det ROTATED (0,0,0) RELATIVE focus_det COMPONENT emon2 = E_monitor( xmin = -0.02, xmax = 0.02, ymin = -0.05, ymax = 0.05, Emin = 10, Emax = 20, nchan = 35, filename = "sim/in14_EM2.vmon") AT(0, 0, 0.01) RELATIVE focus_det ROTATED (0,0,0) RELATIVE focus_det */ FINALLY %{ printf("Output files : %s %s %s %s\n",pfile,efile,dfile,kfile); free(pfile); free(dfile); free(efile); free(kfile); %} END -------------- next part -------------- /*********************************************************************** * * McStas, version 1.1, released ?? * Maintained by Kristian Nielsen and Kim Lefmann, * Risoe National Laboratory, Roskilde, Denmark * * Component: Flux_adapter * * Written by: EF, Oct 14, 1999, Rev Nov 17, 1999 * * The routine changes the neutron flux (weight) in order to match * a reference source table on disk. This file can be on format * (k[Angs-1],p), (omega[meV],p), (lambda[Angs],p) where p is the weight * A linear interpolation is performed during simulation. * This component should be placed after a source, in order to * simulate a real source. * * file : name of the file to look at (two columns data) * data should be sorted (ascending order) and monotonic * file can contain options (see below) as comment * options : string that can contain * "[ k p ]" or "wavector" for file type * "[ omega p]" or "energy" * "[ lambda p ]" or "wavelength" * "set" to set the weight according to the table * "multiply" to multiply (instead of set) the weight by factor * "add" to add to current flux * "unactivate" to unactivate flux_adapter (in flux file for test) * "verbose" to display additional informations * * EXAMPLE : * (xmin = -0.1, xmax = 0.1, * ymin = -0.1, ymax = 0.1, * file="source.flux", * options="") * With file "source.flux" beeing something like * # energy multiply * # [ meV flux_factor ] * 0 1 * 2 1.2 * 10 1.5 * 100 1 * ***********************************************************************/ DEFINE COMPONENT Flux_adapter DEFINITION PARAMETERS (xmin, xmax, ymin, ymax, file, options) SETTING PARAMETERS () OUTPUT PARAMETERS (KE_Table,Weight_Table,Type_table,Mode_Table,Length_Table,Step_Table) STATE PARAMETERS (x,y,z,vx,vy,vz,t,s1,s2,p) DECLARE %{ #define LINE_MAX_LENGTH 1024 #define UNKNOWN_TABLE 0 #define ENERGY_TABLE 1 #define WAVEVECTOR_TABLE 2 #define WAVELENGTH_TABLE 3 #define FLUX_ADAPT_SET 0 #define FLUX_ADAPT_MULT 1 #define FLUX_ADAPT_ADD 2 FILE *hfile; /* id for data file */ char line[LINE_MAX_LENGTH]; long line_count_in_file = 0; long line_count_in_array = 0; long malloc_size = 100; char flag_exit_loop = 0; char flag_in_array = 0; char Type_Table = UNKNOWN_TABLE; double X,P; double *Weight_Table, *tmp_weight; double *KE_Table, *tmp_ke; long Length_Table=0; double Step_Table=0; long tmp_length =0; long tmp; char Mode_Table = FLUX_ADAPT_SET; char verbose=0; int i; double v2,K,L,E,new_p,slope; double X1,X2,Y1,Y2,step; /* end of declare */ %} INITIALIZE %{ tmp_ke = (double*)malloc(malloc_size*sizeof(double)); tmp_weight = (double*)malloc(malloc_size*sizeof(double)); hfile = fopen(file, "r"); if(!hfile) { fprintf(stderr, "Error: %s : could not open input file '%s'\n", mccompcurname, file); } else /* now look for the data */ { /* initialize data array */ if (strstr(options," k") || strstr(options," K ") || strstr(options,"wavevector")) Type_Table = WAVEVECTOR_TABLE; if (strstr(options,"omega") || strstr(options," e ") || strstr(options," E ") || strstr(options,"energy")) Type_Table = ENERGY_TABLE; if (strstr(options,"lambda") || strstr(options,"wavelength") || strstr(options," L ")) Type_Table = WAVELENGTH_TABLE; if (strstr(options,"set")) Mode_Table = FLUX_ADAPT_SET; if (strstr(options,"add")) Mode_Table = FLUX_ADAPT_ADD; if (strstr(options,"multiply")) Mode_Table = FLUX_ADAPT_MULT; if (strstr(options,"verbose")) verbose = 1; /* do main loop */ while (!flag_exit_loop) { if (fgets(line, LINE_MAX_LENGTH, hfile) != NULL) { /* tries to read some informations */ line_count_in_file++; for (i=0; (i < strlen(line)) && (i < LINE_MAX_LENGTH); i++) { line[i] = tolower(line[i]); } if (strstr(line," k ") || strstr(line,"wavevector")) /* overrides options */ Type_Table = WAVEVECTOR_TABLE; if (strstr(line," e ") || strstr(line,"omega") || strstr(line,"energy")) Type_Table = ENERGY_TABLE; if (strstr(line,"lambda") || strstr(line," l ") || strstr(line,"wavelength")) Type_Table = WAVELENGTH_TABLE; if (strstr(line,"set")) Mode_Table = FLUX_ADAPT_SET; if (strstr(line,"multiply")) Mode_Table = FLUX_ADAPT_MULT; if (strstr(line,"add")) Mode_Table = FLUX_ADAPT_ADD; if (strstr(line,"unactivate")) Type_Table = UNKNOWN_TABLE;; if (strstr(line,"verbose")) verbose = 1; /* tries to read 2 numbers */ if (sscanf(line,"%lg %lg",&X,&P) == 2) { /* if succeed and not in array : initialize array */ if (!flag_in_array) { flag_in_array = 1; line_count_in_array = 0; malloc_size = 0; } /* if succeed and in array : add (and realloc if necessary) */ if (line_count_in_array+100 > malloc_size) { malloc_size += 100; tmp_ke = (double*)realloc(KE_Table,malloc_size*sizeof(double)); tmp_weight = (double*)realloc(Weight_Table,malloc_size*sizeof(double)); } tmp_ke[line_count_in_array] = X; tmp_weight[line_count_in_array] = P; line_count_in_array++; } else /* if does not succeed : set 'not in array' flag */ { flag_in_array = 0; } } else flag_exit_loop = 1; /* else : end of file */ } Length_Table = line_count_in_array; if (Length_Table < 2) Type_Table = UNKNOWN_TABLE; /* not enough points */ if (verbose) { printf("Flux : %i points in %s\n",Length_Table, file); printf("Flux : data is [ "); if (Type_Table == ENERGY_TABLE) printf("Energy"); if (Type_Table == WAVEVECTOR_TABLE) printf("Wavevector"); if (Type_Table == WAVELENGTH_TABLE) printf("Wavelength"); if (Type_Table == UNKNOWN_TABLE) printf("UNKNOWN (not used)"); printf(", Flux ]"); if (Mode_Table == FLUX_ADAPT_MULT) printf(" in multiply mode"); printf("\n"); } fclose(hfile); tmp_length = line_count_in_array; /* now re-sample with minimal step found in file */ step = fabs(tmp_ke[1] - tmp_ke[0]); /* minimal step in KE */ tmp = tmp_length; for (i=0; i < tmp_length - 1; i++) { X2 = fabs(tmp_ke[i+1] - tmp_ke[i]); if (X2 < step) step = X2; else tmp--; } /* for */ Step_Table = step; if (tmp > 0) /* table was not already evenly sampled */ { Length_Table = ceil(fabs(tmp_ke[tmp_length-1] - tmp_ke[0])/step); KE_Table = (double*)malloc(Length_Table*sizeof(double)); Weight_Table = (double*)malloc(Length_Table*sizeof(double)); for (i=0; i < Length_Table; i++) { X = tmp_ke[0] + i*step; KE_Table[i] = X; /* look for number just after X in table tmp_ke */ line_count_in_array=1; while ((line_count_in_array < tmp_length-1) && (tmp_ke[line_count_in_array] < X)) line_count_in_array++; X2 = tmp_ke[line_count_in_array]; X1 = tmp_ke[line_count_in_array-1]; Y2 = tmp_weight[line_count_in_array]; Y1 = tmp_weight[line_count_in_array-1]; if (X2-X1) { /* linear interpolation */ slope = (Y2-Y1)/(X2-X1); new_p = Y1+slope*(X-X1); Weight_Table[i] = new_p; } else Weight_Table[i] = tmp_weight[line_count_in_array]; } /* for */ if (verbose) { printf("Flux : resampled as %i points\n",Length_Table); } } /* if tmp */ else { Length_Table = tmp_length; KE_Table = (double*)malloc(Length_Table*sizeof(double)); Weight_Table = (double*)malloc(Length_Table*sizeof(double)); for (i=0; i < tmp_length; i++) { KE_Table[i] = tmp_ke[i]; Weight_Table[i] = tmp_weight[i]; } } } /* if hfile */ free(tmp_ke); free(tmp_weight); %} TRACE %{ PROP_Z0; if (Type_Table && (x>xmin && xymin && y= Length_Table -1) line_count_in_array = Length_Table-1; X2 = KE_Table[line_count_in_array]; X1 = KE_Table[line_count_in_array-1]; Y2 = Weight_Table[line_count_in_array]; Y1 = Weight_Table[line_count_in_array-1]; if (X2-X1) { /* linear interpolation */ slope = (Y2-Y1)/(X2-X1); new_p = Y1+slope*(X-X1); if (Mode_Table == FLUX_ADAPT_MULT) p *= new_p; else p = new_p; } else ABSORB; } else if (Type_Table) ABSORB; %} FINALLY %{ free(KE_Table); free(Weight_Table); %} MCDISPLAY %{ magnify("xy"); multiline(5, (double)xmin, (double)ymin, 0.0, (double)xmax, (double)ymin, 0.0, (double)xmax, (double)ymax, 0.0, (double)xmin, (double)ymax, 0.0, (double)xmin, (double)ymin, 0.0); %} END From hansen at ill.fr Tue Nov 30 18:40:16 1999 From: hansen at ill.fr (Thomas C Hansen) Date: Tue, 30 Nov 1999 18:40:16 +0100 Subject: problem mcstas configure or gcc on d20sgi Message-ID: <38440BF7.DAB3818@ill.fr> I downloaded the last version of McSTAS again from http://neutron.risoe.dk/mcstas/download.html, and what worked before does not work anymore, the configure script fails. I do not know if the error with the gcc compiler happens due to some problems with the McSTAS distribution and IRIX 6.5 on Silicon Graphics, or if it is related to the recent installation of Irix 6.5 on that Silicon Graphics Workstation. In the first case I would be happy, if Kristian could give me a hint, in the second one, if Martine Espitallier could tell me what to do! d20sgi 3# ./configure loading cache ./config.cache checking for gcc... gcc checking whether the C compiler (gcc ) works... no configure: error: installation or configuration problem: C compiler cannot create executables. d20sgi 4# pwd /hosts/d20sgi/users/dif/hansen/mcstas-1.1 Thank you / Merci! Thomas Hansen -------------- next part -------------- A non-text attachment was scrubbed... Name: hansen.vcf Type: text/x-vcard Size: 495 bytes Desc: Card for Thomas C Hansen URL: From farhi at ill.fr Tue Nov 30 15:36:59 1999 From: farhi at ill.fr (Farhi) Date: Tue, 30 Nov 1999 15:36:59 +0100 Subject: mcgui Message-ID: <3843E10B.64C17576@ill.fr> Hy again Kristian, I've been now showing some McStas demo to J. Combet (IN10), with mcgui. It's really cute. I just here give you some ideas about mcgui. 1- mcgui main window could contain what is displayed in the 'compiling' or 'simulation' windows in a sort of 'control/log' window 2- Editing a simulation source could open a new window, either with the default (simple) mcgui editor, or with an external editor (nedit...) 3- In the 'Run' menu, you could add something like 'display instrument geometry' calling mcdisplay. The control window should display PGplot key actions (zoom, etc...) I've got now D20 simulation from Thomas Hansen. Seems quite complicated. He uses the Numerical Recipies in C as a part of the sample simulation. I will put this on the ILL McStas page soon. One of the ECNS99 publication is entirely available on the doc page as an HTML link, if you want to put it on your site. Cheers. EF. -- Emmanuel FARHI, http://www.ill.fr/tas/people/Farhi.html \|/ ____ \|/ TAS-Group, Institut Laue-Langevin (ILL) Grenoble ~@-/ oO \-@~ Avenue des Martyrs, BP 156, 38042 Grenoble Cedex 9,France /_( \__/ )_\ Work :Tel (33/0) 4 76 20 71 83. Fax (33/0) 4 76 48 39 06 \__U_/ La Grande Arche, Chateau d'Uriage, 38410 Saint Martin d'Uriage 04 76 59 73 94 -------------- next part -------------- An HTML attachment was scrubbed... URL: From farhi at ill.fr Wed Dec 22 10:39:03 1999 From: farhi at ill.fr (Farhi) Date: Wed, 22 Dec 1999 10:39:03 +0100 Subject: new IN14 tutorial example at ILL Message-ID: <38609C37.3512557F@ill.fr> Hello everybody, I've installed a complete tutorial web page < http://www.ill.fr/tas/mcstas/tutorial.html > showing how to design, compile and use McStas for the IN14 instrument at ILL. It is intended to show you 'with hands' how to use McStas step by step. If you begin with McStas and want to do some serious work, go there ! The McStas library page of ILL also gathers all current components for McStas.< http://www.ill.fr/tas/mcstas/ill_lib.html >. Cheers. EF. -- Emmanuel FARHI, http://www.ill.fr/tas/people/Farhi.html \|/ ____ \|/ TAS-Group, Institut Laue-Langevin (ILL) Grenoble ~@-/ oO \-@~ Avenue des Martyrs, BP 156, 38042 Grenoble Cedex 9,France /_( \__/ )_\ Work :Tel (33/0) 4 76 20 71 83. Fax (33/0) 4 76 48 39 06 \__U_/ La Grande Arche, Chateau d'Uriage, 38410 Saint Martin d'Uriage 04 76 59 73 94 -------------- next part -------------- An HTML attachment was scrubbed... URL: From kristian.nielsen at risoe.dk Wed Dec 1 15:19:14 1999 From: kristian.nielsen at risoe.dk (Kristian Nielsen) Date: 1 Dec 1999 15:19:14 +0100 Subject: problem mcstas configure or gcc on d20sgi In-Reply-To: <38440BF7.DAB3818@ill.fr> (message from Thomas C Hansen on Tue, 30 Nov 1999 18:40:16 +0100) Message-ID: > Date: Tue, 30 Nov 1999 18:40:16 +0100 > From: Thomas C Hansen > d20sgi 3# ./configure > loading cache ./config.cache > checking for gcc... gcc > checking whether the C compiler (gcc ) works... no > configure: error: installation or configuration problem: C compiler cannot > create executables. This looks very much like a problem with gcc on the Silicon Graphics Workstation. You can try to build McStas with the standard C compiler "cc" and see if it works any better: rm config.cache setenv CC cc ./configure make make install In any case, let me know what pops up, and I will try to help if needed. - Kristian. -- Kristian Nielsen kristian.nielsen at risoe.dk Ris? National Laboratory Condensed Matter Physics and Chemistry Department Tel. +45 4677 5515 Fax +45 4677 4790 From PASeeger at aol.com Wed Dec 1 15:30:43 1999 From: PASeeger at aol.com (PASeeger at aol.com) Date: Wed, 01 Dec 1999 09:30:43 -0500 (EST) Subject: Instrument simulations and neutron polarisation Message-ID: <0.bd5311da.25768b13@aol.com> Kristian, Thank you for sending the web-page information. In the meantime, here are some notes I made on the way home: << Polarization is represented by a 3-vector P, with magnitude P <= 1. The probability of the spin of the neutron being in direction P is (1 + P)/2, and the probability of the opposite spin is (1 - P)/2. The probabilities in an arbitrary direction given by a unit vector A usey the dot product AoP in place of P. Thus P = 0 is an unpolarized beam, with probability in any direction being 50%. This notation is completely equivalent to tracking separate spin-up and spin-down neutrons with appropriate statistical weights. For instance, consider a longitudinal polarizer from which 90% of the emerging neutrons have spin in the +Z direction. This may be represented either by two histories (wt, P) = (0.9, 0, 0, 1) + (0.1, 0, 0, -1) or by a single history (1.0, 0, 0, 0.80) that is simply the weighted average of the two. Any operation that is symmetric with respect to spin, such as precession or spin-flip, can be applied either to the combined or to the separated histories. For algorithms that act differently on the two spin states, the single history must be decomposed; after the interaction, the two histories may either be recombined by weighted average, or may remain separated. For instance, if the above history passes through a filter which transmits 90% of the + spin and 2% of the - spin, the result is either (0.810, 0, 0, 1) + (0.002, 0, 0, -1) or (only if both neutrons have the same trajectory!) (0.812, 0, 0, 0.995). If it is desired also to track the non-transmitted neutrons (perhaps reflected out of the beam, contributing to backgrounds), they would be represented by (0.090, 0, 0, 1) + (0.098, 0, 0, -1) or (again, only if the trajectories are identical) by (0.188, 0, 0, -0.04255). In practice, an interaction in NISP may only result in two histories, so the combined form is necessary if the background neutron is also to be tracked. No information is lost because the partially polarized history can always be reconstituted into two spin states with respect to any analyzer direction. >> For most cases of multiple scattering, I do it within the sample region so propagation between regions would not be an issue. The first scatter is forced, with adjustment of statistical weight. Further scatters are Russian roulette. If you look in my OPERATE subroutine, cases which include multiple scattering are 30, 34, and 36. It was nice talking with you at PSI. Cheers, Phil Seeger From farhi at ill.fr Wed Dec 1 16:01:35 1999 From: farhi at ill.fr (Farhi) Date: Wed, 01 Dec 1999 16:01:35 +0100 Subject: McStas ILL Web site trial References: <01JIZQ6TAX6490OE5U@risoe.dk> Message-ID: <3845384F.D7AD5933@ill.fr> Hy, I've corrected the bad link. Yes you can announce the site, but I'm not sure yet of its location (will this stay on the ill/tas group zone ?). Perhaps it's better to wait the Dec 10th meeting, where I will raise the question. The number of components is not growing quite fast. The main problem is that physicists are very bad programmers, and the source code is usually a black box, with no help, etc... I think you're right : we should maintain a unique set of components, shared on both web sites. You told me you know how to update those files (mirror). I never tried this before. The task might be complicated by the presence of the ILL firewall, and the fact that I can only FTP to the ill web server (no tty). I've added already the MCDISPLAY parts in all 'bold' components of the ill_lib page. The help sections are also updated. Get the components, and see if it suits you. Also, can McStas search for components inside sub-directories in it's lib path ? This would enable to sort components by class (sources, monitors, etc) Thomas Hansen has noticed a McStas limit concerning the number of instrument parameters. He uses in it's D20 simulation about 20 to 30 input params !! As mcstas did not work with this, he now uses an 'input' file containing the parameters, read from the C embeded part of the INITIALIZE section. Cheers. EF. Kristian Nielsen wrote: > > Date: Tue, 30 Nov 1999 12:06:39 +0100 > > From: Farhi > > > I've been installing a tentative 'McStas at ILL' web site at the URL : > > > > < http://www.ill.fr/tas/mcstas/mcstas_ill.html > > > I took a quick look and my first comment is WOW! I did not realise that > you very this active with McStas at the ILL. I added a link from the > Ris? McStas page. I will probably get back later with more in-depth > comments. > > I found a bad link, to Trefs PDF report on the page at > http://www.ill.fr/tas/mcstas/documentation.html#docs (the bad link is > "http://www.ill.fr/home/farhi/DIVERS/html/mcstas/instruments/Test3He/3HeMcStas.pdf"). > > I think this page should be announced on the mailing list. Would you > like to do it yourself, or shall I? > > Thanks for the comments on mcgui, I agree very much and I will > incorporate them as soon as possible. > > I will wait for the MCDISPLAY stuff. > > - Kristian. -- Emmanuel FARHI, http://www.ill.fr/tas/people/Farhi.html \|/ ____ \|/ TAS-Group, Institut Laue-Langevin (ILL) Grenoble ~@-/ oO \-@~ Avenue des Martyrs, BP 156, 38042 Grenoble Cedex 9,France /_( \__/ )_\ Work :Tel (33/0) 4 76 20 71 83. Fax (33/0) 4 76 48 39 06 \__U_/ La Grande Arche, Chateau d'Uriage, 38410 Saint Martin d'Uriage 04 76 59 73 94 -------------- next part -------------- An HTML attachment was scrubbed... URL: From kristian.nielsen at risoe.dk Thu Dec 2 09:36:44 1999 From: kristian.nielsen at risoe.dk (Kristian Nielsen) Date: 2 Dec 1999 09:36:44 +0100 Subject: McStas ILL Web site trial In-Reply-To: <3845384F.D7AD5933@ill.fr> (message from Farhi on Wed, 01 Dec 1999 16:01:35 +0100) Message-ID: > Date: Wed, 01 Dec 1999 16:01:35 +0100 > From: Farhi > I've corrected the bad link. Yes you can announce the site, but I'm not sure yet of its > location (will this stay on the ill/tas group zone ?). Perhaps it's better to wait the > Dec 10th meeting, where I will raise the question. Ok, I will wait then. > The number of components is not growing quite fast. The main problem is that physicists > are very bad programmers, and the source code is usually a black box, with no help, > etc... Yes, this is clearly a problem to be addressed. One idea that came up was to have some sort of journal for components, where you would submit a component with a paper describing the algorithm for peer review. If the component and paper was accepted, you would then get scientific credit, just as for an ordinary paper. But it may not be so easy to set up in practice. > I think you're right : we should maintain a unique set of components, shared on both web > sites. You told me you know how to update those files (mirror). I never tried this > before. Well, I think I would have no problem setting up a little program that would automatically copy pages from the remote to the local server. This could use a web proxy to get through the firewall (I assume this is what your Netscape does). The problem is that we really want both of us to be able to add entries to a component list in a single file mirrored on both servers (Ris? and ILL). I cannot think of any good solutions right now, maybe we can wait a month or two and then do something reasonable? > Also, can McStas search for components inside sub-directories in it's lib path ? This > would enable to sort components by class (sources, monitors, etc) Yes, I could add that to the next version. I think I would prefer not to search arbitrary subdirectories, since this is potentially very time consiming and is also not portable (to Windows/Mac). How about having a fixed set of subdirectories (for example "samples", "monitors", "sources", "optics", "misc") that are searched? > Thomas Hansen has noticed a McStas limit concerning the number of instrument parameters. > He uses in it's D20 simulation about 20 to 30 input params !! As mcstas did not work Hm, I do not understand this. There IS a limit, which I will remove when the need arises, but that is set to 1000 parameters. I just tried an instrument with 299 input parameters, and that worked fine. Do you think you or Thomas could give some more details (maybe an error message)? - Kristian. From farhi at ill.fr Wed Dec 8 09:18:28 1999 From: farhi at ill.fr (Farhi) Date: Wed, 08 Dec 1999 09:18:28 +0100 Subject: McStas ILL Web site trial References: <01JJ0SBNG9D290OILZ@risoe.dk> Message-ID: <384E1454.AA017E69@ill.fr> Hy Kristian, I've seen that you added the ILL web page. Great. I think it will stay here for a while anyway (I'm in charge of this, huh ?) About the problem of writting 'good' components, the best is to gather the components, and if we see that one is not really clear, contact the author to improve this. I'm defining some 'good programmer's tips' in the ILL web page. Tell me if it suits you. About sorting components in the directories you gave, it seems reasonable. McStas should also continue to search in it's component root directory (for compatibility and unsorted components). In fact, I think that the 'limitation' that Thomas encountered is just that he began to think it's too much. But his instrument can probably run with all informations passed through command line. He also wanted to use a string instrument parameter, but this does not seem to be handled by McStas. It could be useful when one single simulation would be used with various configuration (for instance precise in parameters the type on monochromator one wants to use, e.g. "Graphite" or "Si"). McStas could just look for symbols " or ' in command line. Afetr heavy dicussions with me, Tref has been trying a Runge Kutta integration inside a magnetic component, in order to describe the neutron spin swiming in B field. Seems to work... (only alpha of course) Cheers. EF. -- Emmanuel FARHI, http://www.ill.fr/tas/people/Farhi.html \|/ ____ \|/ TAS-Group, Institut Laue-Langevin (ILL) Grenoble ~@-/ oO \-@~ Avenue des Martyrs, BP 156, 38042 Grenoble Cedex 9,France /_( \__/ )_\ Work :Tel (33/0) 4 76 20 71 83. Fax (33/0) 4 76 48 39 06 \__U_/ La Grande Arche, Chateau d'Uriage, 38410 Saint Martin d'Uriage 04 76 59 73 94 -------------- next part -------------- An HTML attachment was scrubbed... URL: From kristian.nielsen at risoe.dk Thu Dec 9 08:18:03 1999 From: kristian.nielsen at risoe.dk (Kristian Nielsen) Date: 9 Dec 1999 08:18:03 +0100 Subject: McStas ILL Web site trial In-Reply-To: <384E1454.AA017E69@ill.fr> (message from Farhi on Wed, 08 Dec 1999 09:18:28 +0100) Message-ID: > Date: Wed, 08 Dec 1999 09:18:28 +0100 > From: Farhi > I've seen that you added the ILL web page. Great. I think it will stay here for a while > anyway (I'm in charge of this, huh ?) Ok. > About the problem of writting 'good' components, the best is to gather the components, and if > we see that one is not really clear, contact the author to improve this. I'm defining some > 'good programmer's tips' in the ILL web page. Tell me if it suits you. Looks good. I thought some more about how to maintain the unofficial component libraries across the two web sites. My suggestion is that you simply take over the library completely, so that the Ris? page simply has a link to the ILL library. What you have now on the ILL page in terms of components is already much better than what I ever had on the Ris? pages. There also seems to be much more activity currently at the ILL in terms of actually running simulations than we will ever be able to do at Ris?, so it makes sense to maintain the component library there. At Ris? we will then concentrate on developing the McStas core, and maintaining the official component library (those with full documentation in the manual). Of course, I will keep closely involved in the ILL component library, possibly using the accounts I have on the ILL Unix and Linux machines. What do you think? > About sorting components in the directories you gave, it seems reasonable. McStas should also > continue to search in it's component root directory (for compatibility and unsorted > components). Ok, I will implement this in the next version. > command line. He also wanted to use a string instrument parameter, but this does not seem to > be handled by McStas. It could be useful when one single simulation would be used with Yes, this is important, and I will include it in version 2, along with many other enhancements for parameters > Afetr heavy dicussions with me, Tref has been trying a Runge Kutta integration inside a > magnetic component, in order to describe the neutron spin swiming in B field. Seems to > work... (only alpha of course) Sounds very interesting! Keep those suggestions coming! I hope that I will see you in January at the ILL Monte Carlo workshop on the 21th. - Kristian. From kristian.nielsen at risoe.dk Thu Dec 9 08:37:02 1999 From: kristian.nielsen at risoe.dk (Kristian Nielsen) Date: 9 Dec 1999 08:37:02 +0100 Subject: McStas tutorial Message-ID: Hi Emmanuel, I forgot to mention one thing in the previous email. I noticed on your web page that you had started on a McStas tutorial. I just wanted to show you what I have done so far on another McStas tutorial, which will be used in a McStas course in a Winter School in January. It is not finished yet, but it may be useful to you to see what I am preparing. This tutorial will of course eventually be included in McStas. As you will also see from the tutorial, we are doing progress with our single crystal simulation! Find the postscript file at http://neutron.risoe.dk/mcstas/support/farhi/tutorial.ps The tutorial will build a Laue diffraction instrument, so maybe this will be of interest to the LADI people at the ILL? - Kristian. From farhi at ill.fr Mon Dec 13 10:37:01 1999 From: farhi at ill.fr (Farhi) Date: Mon, 13 Dec 1999 10:37:01 +0100 Subject: About component parameters Message-ID: <3854BE3C.9F2E0662@ill.fr> Hy Kristian, I've noticed that one can not use math expressions for parameters in component calls. For instace COMPONENT mycomp = comp(par1=myvariable/2) does not work. Do you plan to implement expression evaluation in parameter calls (such as in standard C function calls) ? Cheers. EF. -- Emmanuel FARHI, http://www.ill.fr/tas/people/Farhi.html \|/ ____ \|/ TAS-Group, Institut Laue-Langevin (ILL) Grenoble ~@-/ oO \-@~ Avenue des Martyrs, BP 156, 38042 Grenoble Cedex 9,France /_( \__/ )_\ Work :Tel (33/0) 4 76 20 71 83. Fax (33/0) 4 76 48 39 06 \__U_/ La Grande Arche, Chateau d'Uriage, 38410 Saint Martin d'Uriage 04 76 59 73 94 -------------- next part -------------- An HTML attachment was scrubbed... URL: From kristian.nielsen at risoe.dk Mon Dec 13 10:51:54 1999 From: kristian.nielsen at risoe.dk (Kristian Nielsen) Date: 13 Dec 1999 10:51:54 +0100 Subject: About component parameters In-Reply-To: <3854BE3C.9F2E0662@ill.fr> (message from Farhi on Mon, 13 Dec 1999 10:37:01 +0100) Message-ID: > Date: Mon, 13 Dec 1999 10:37:01 +0100 > From: Farhi > Do you plan to implement expression evaluation in parameter calls (such > as in standard C function calls) ? Yes. I have been planning this for a long time, but have put it off to do more important things first. But I have decided it can not be posponed for much longer, and I will do it this spring (even if I have to lock my office to get time to do it :-). I know how it must be done, but I want to do it properly. By the way, I have decided to release McStas version 1.2 on January 31, on the ILL workshop. I may send you another beta or two before then in case you are interested. - Kristian. From farhi at ill.fr Mon Dec 13 10:51:39 1999 From: farhi at ill.fr (Farhi) Date: Mon, 13 Dec 1999 10:51:39 +0100 Subject: About component parameters References: <01JJG85SCTW490S1BQ@risoe.dk> Message-ID: <3854C1AB.F690ACA6@ill.fr> Ok, I'll test this when you want ! Cheers. EF. Kristian Nielsen wrote: > > Date: Mon, 13 Dec 1999 10:37:01 +0100 > > From: Farhi > > > Do you plan to implement expression evaluation in parameter calls (such > > as in standard C function calls) ? > > Yes. I have been planning this for a long time, but have put it off to > do more important things first. But I have decided it can not be > posponed for much longer, and I will do it this spring (even if I have > to lock my office to get time to do it :-). I know how it must be done, > but I want to do it properly. > > By the way, I have decided to release McStas version 1.2 on January 31, > on the ILL workshop. I may send you another beta or two before then in > case you are interested. > > - Kristian. -- Emmanuel FARHI, http://www.ill.fr/tas/people/Farhi.html \|/ ____ \|/ TAS-Group, Institut Laue-Langevin (ILL) Grenoble ~@-/ oO \-@~ Avenue des Martyrs, BP 156, 38042 Grenoble Cedex 9,France /_( \__/ )_\ Work :Tel (33/0) 4 76 20 71 83. Fax (33/0) 4 76 48 39 06 \__U_/ La Grande Arche, Chateau d'Uriage, 38410 Saint Martin d'Uriage 04 76 59 73 94 -------------- next part -------------- An HTML attachment was scrubbed... URL: From farhi at ill.fr Fri Dec 17 18:41:29 1999 From: farhi at ill.fr (Farhi) Date: Fri, 17 Dec 1999 18:41:29 +0100 Subject: McStas tutorial Message-ID: <385A75C8.EC766628@ill.fr> Hy Kristian, I've nearly finished the ILL tutorial. It shows a much more complex instrument building, with some C embeded code. It's more complicated, but is really shows what ILL users need. The pb is that I just can not update the web pages now (pb with the server access). The tutorial describes a complete 3-axis, used if fixed Ki, and computes its geometry with Q and E given as parameters. Also, when a user creates its components in the same directory as the instrument, are these components used first, before looking at the McStas tas library ? I mean the order of priority for searching components could be : PWD MC_LIB_PATH MC_LIB_PATH subdirectories Cheers. EF. -- Emmanuel FARHI, http://www.ill.fr/tas/people/Farhi.html \|/ ____ \|/ TAS-Group, Institut Laue-Langevin (ILL) Grenoble ~@-/ oO \-@~ Avenue des Martyrs, BP 156, 38042 Grenoble Cedex 9,France /_( \__/ )_\ Work :Tel (33/0) 4 76 20 71 83. Fax (33/0) 4 76 48 39 06 \__U_/ La Grande Arche, Chateau d'Uriage, 38410 Saint Martin d'Uriage 04 76 59 73 94 -------------- next part -------------- An HTML attachment was scrubbed... URL: From kristian.nielsen at risoe.dk Tue Dec 21 08:18:09 1999 From: kristian.nielsen at risoe.dk (Kristian Nielsen) Date: 21 Dec 1999 08:18:09 +0100 Subject: McStas tutorial In-Reply-To: <385A75C8.EC766628@ill.fr> (message from Farhi on Fri, 17 Dec 1999 18:41:29 +0100) Message-ID: > Date: Fri, 17 Dec 1999 18:41:29 +0100 > From: Farhi > I've nearly finished the ILL tutorial. It shows a much more complex > instrument building, with some C embeded code. It's more complicated, > but is really shows what ILL users need. That is fine, I think, the two tutorials supplement each other nicely (mine is really simple, but will get users started quickly, yours will enable them to start serious work without having to study the manual in detail). Maybe we can also use your tutorial on the winter school in January. > Also, when a user creates its components in the same directory as the > instrument, are these components used first, before looking at the > McStas tas library ? > I mean the order of priority for searching components could be : > PWD > MC_LIB_PATH > MC_LIB_PATH subdirectories Yes, the current directory is searched first, followed by any directories specified using the "-I" option, followed by the system directory. About the workshop on January 31, I wanted to start booking my plane ticket. Which days do you think I should stay at the ILL (apart from the 31th, of course)? Maybe it would be useful if I were there for a few days after (say Tuesday and Wednesday), provided people have time to talk with me then? - Kristian.