Files
Estia-McStas/simulation/Shielding_log_iterator_total.comp

166 lines
5.1 KiB
Plaintext

/*******************************************************************************
*
* McStas, neutron ray-tracing package
* Copyright 1997-2002, All rights reserved
* Risoe National Laboratory, Roskilde, Denmark
* Institut Laue Langevin, Grenoble, France
*
* Component: Scatter_log_iterator.comp
*
* %I
*
* Written by: Erik B Knudsen
* Date: November 2012
* Version: $Revision: 1.21 $
* Release: McStas 2.1
* Origin: DTU Physics
*
* Iteration element for a Scatter_log
*
* %D
*
* This component marks the beginning of the region in trace in which pseudo-neutrons
* are to be propagated. Pseudo-neutrons are neutrons which are generated by the function
* <i>compute_func</i> from before and after SCATTER neutron states which have been logged by
* a set of Scatter_logger/Scatter_logger_stop components.
* N.B. This component should be immediately preceeded by an Arm. Any components between this one
* and a subsequent Scatter_log_iterator_stop-component will be visited by the set of pseudo-neutrons
* as if they were regular neutrons in the classical McStas-manner.
*
* %P
* Input parameters:
*
* compute_func [ ] : Address of the function that computes a psuedo neutron from before and after scatter states.
*
* %E
*******************************************************************************/
DEFINE COMPONENT Shielding_log_iterator_total
DEFINITION PARAMETERS (compute_func=NULL)
SETTING PARAMETERS ()
OUTPUT PARAMETERS (nstate_initial,s0,s1)
/* Neutron parameters: (x,y,z,vx,vy,vz,t,sx,sy,sz,p) */
SHARE
%{
/*This is the specialized pseudo-neutron function that computes
an escaping neutron from logged before and after SCATTER neutron states*/
int exit_neutron(double *ns_tilde, struct Generalized_State_t *S0, struct Generalized_State_t *S1){
/*!!Note that the transformation into global coordinate system must be done while logging
as we do not have access to neither the component name nor can get the component rotation by index.*/
Coords c1,c2;
Rotation R1,R2;
/*so now compute the pseudo neutron state and possibly user variables*/
/*position comes from "new" state*/
ns_tilde[0]=S1->_x;ns_tilde[1]=S1->_y;ns_tilde[2]=S1->_z;
/*velocity is the "old" state*/
ns_tilde[3]=S0->_vx;ns_tilde[4]=S0->_vy;ns_tilde[5]=S0->_vz;
/*time from new*/
ns_tilde[6]=S1->_t;
/*spin comes from "new" state*/
ns_tilde[7]=S1->_sx;ns_tilde[8]=S1->_sy;ns_tilde[9]=S1->_sz;
/*weight is difference old-new to mean the neutrons "deposited" in the guide wall*/
ns_tilde[10]=S0->_p-S1->_p;
return 0;
}
#define NOABS \
do {/* Nothing*/} while(0)
%}
DECLARE
%{
int (*pseudo_neutron_state_function) (double *, struct Generalized_State_t *, struct Generalized_State_t *);
struct Generalized_State_t *s1,*s0;
double *nstate_initial;
int optics_not_hit;
/*need a pointer to the structure set up by the logger*/
%}
INITIALIZE
%{
if (compute_func) {
pseudo_neutron_state_function=compute_func;
}else{
pseudo_neutron_state_function=exit_neutron;
}
nstate_initial=NULL;
optics_not_hit=0;
%}
TRACE
%{
//printf("Entering Iterator_total\n");
/*I am the start of the pseudo neutron iterator*/
if (nstate_initial==NULL){
optics_not_hit=0; /* Fresh start, resetting variable */
double *ns=nstate_initial=calloc(11,sizeof(double));
ns[0]=x;ns[1]=y; ns[2]=z;
ns[3]=vx;ns[4]=vy;ns[5]=vz;
ns[6]=t;
ns[7]=sx;ns[8]=sy;ns[9]=sz;
ns[10]=p;
s0=Bounce_store;
s1=Bounce_store+1;
/* Remove std. ABSORB to avoid breaking analysis loop */
#undef mcabsorb
#define mcabsorb scatter_iterator_stop
}
//if (s1->_p!=-1){
if (s1->_p!=-1 && s1->_p!=-2){
/*a neutron weight of -1 is nonsensical. I.e. if s1->p>=0, it means there are two states in the log from which we can compute a pseudo-neutron*/
double nstate[11];
if ( pseudo_neutron_state_function(nstate,s0,s1) ){
printf("Warning: (%s): error reported when computing pseudo neutron\n",NAME_CURRENT_COMP);
}
/*set neutron state for subsequent components*/
x=nstate[0];y=nstate[1];z=nstate[2];
vx=nstate[3];vy=nstate[4];vz=nstate[5];
t=nstate[6];
sx=nstate[7];sy=nstate[8];sz=nstate[9];
p=nstate[10];
s0++;
s1++;
// printf("Tot: z=%g\tp=%g\n",z,p);
}else if (Bounce_store[1]._p==-1){
/*This can happen now only in the case optics was not hit, i.e. no reflection, no absorption*/
x=s0->_x;y=s0->_y;z=s0->_z;
vx=s0->_vx;vy=s0->_vy;vz=s0->_vz;
t=s0->_t;
sx=s0->_sx;sy=s0->_sy;sz=s0->_sz;
p=s0->_p;
optics_not_hit = 1;
// fprintf(stdout,"No interactions with optics. Use \"optics_not_hit\" variable to JUMP at scatter_logger_stop and avoid sending to ScatterLogIterator those neutrons which were actually not scattered.\n");
} else {
printf("Here happens what should not happen: s1->_p=%g, Bounce_store[1]._p=%g\n",s1->_p,Bounce_store[1]._p);
fprintf(stderr,"This should not happen. Period.\n");
exit(1);
}
%}
MCDISPLAY
%{
/* A bit ugly; hard-coded dimensions. */
magnify("");
line(0,0,0,0.2,0,0);
line(0,0,0,0,0.2,0);
line(0,0,0,0,0,0.2);
%}
END