/***************************************************************************
*         McStas instrument definition URL=http://www.mcstas.org
*
* Instrument: Test_Magnetic_Userdefined
*
* %Identification
* Written by: Peter Christiansen and Peter Willendrup
* Date: August 2006
* Origin: RISOE
* %INSTRUMENT_SITE: Tests_polarization
*
* This instrument demonstrates how to use the Pol_Bfield
* component with a user-specified fieldFunction.
*
* %Description
* This instrument demonstrates how to use the component
* Pol_Bfield with a user-specified fieldFunction.
*
* The fieldFunction is specified in the DECLARE section and defined active
* using the fieldFunction parameter of the component. The example fieldFunction
* is timedependent (velocity-dependent), setting a B-field that will rotatate
* the neutron spins by PI.
*
* %Example: Test_Magnetic_Userdefined Detector: pollambdaMonitor2x_I=0.181511
*
* %Parameters
*
* %Link
*
* %End
****************************************************************************/

/* Change name of instrument and input parameters with default values */
DEFINE INSTRUMENT Test_Magnetic_Userdefined()

/* The DECLARE section allows us to declare variables or  small      */
/* functions in C syntax. These may be used in the whole instrument. */
DECLARE
%{
  double omegaL = -2 * PI * 29.16e6;
  double MagnetLength = 0.2;
  double SrcMagnetDist = 1;

  double user_parameters[3];

  int magnetic_field_t(double x, double y, double z, double t,
          double *bx, double *by, double *bz, void *data_Ptr) {
      double *d=data_Ptr;
      // Example of time-dependent field. Note parameters t0 and rho defined
    // just above, initialized below
    *by =  (PI * (d[2] + d[1]/2))/(d[0]*d[1]*t);
    *bx =  0;
    *bz =  0;
    return 1;
  }
%}

/* The INITIALIZE section is executed when the simulation starts     */
/* (C code). You may use them as component parameter values.         */
INITIALIZE
%{
    user_parameters[0]=omegaL;
    user_parameters[1]=MagnetLength;
    user_parameters[2]=SrcMagnetDist;
%}

/* Here comes the TRACE section, where the actual      */
/* instrument is defined as a sequence of components.  */
TRACE

/* The Arm() class component defines reference points and orientations  */
/* in 3D space. Every component instance must have a unique name. Here, */
/* Origin is used. This Arm() component is set to define the origin of  */
/* our global coordinate system (AT (0,0,0) ABSOLUTE). It may be used   */
/* for further RELATIVE reference, Other useful keywords are : ROTATED  */
/* EXTEND GROUP PREVIOUS. Also think about adding a neutron source !    */
/* Progress_bar is an Arm displaying simulation progress.               */
COMPONENT Origin = Progress_bar()
  AT (0,0,0) ABSOLUTE

COMPONENT source =
Source_simple(radius = 0.01, dist = 1.0, focus_xw = 0.1, focus_yh = 0.1, lambda0 = 5,
	      dlambda = 4.9, flux = 1)
     AT (0, 0, 0) RELATIVE Origin

COMPONENT polSetter =
Set_pol(px=1)
     AT (0, 0, 0.5) RELATIVE Origin

COMPONENT pollambdaMonitor1x =
PolLambda_monitor(xwidth=0.1, yheight=0.1,
		  nL=100, Lmin = 0.0, Lmax = 10.0, npol=21,
		  mx=1, my=0, mz=0, filename="pollambdaMon1x.data")
     AT (0, 0, 0.7) RELATIVE Origin

COMPONENT pollambdaMonitor1y =
PolLambda_monitor(xwidth=0.1, yheight=0.1,
		  nL=100, Lmin = 0.0, Lmax = 10.0, npol=21,
		  mx=0, my=1, mz=0, filename="pollambdaMon1y.data")
     AT (0, 0, 0.75) RELATIVE Origin

COMPONENT pollambdaMonitor1z =
PolLambda_monitor(xwidth=0.1, yheight=0.1,
		  nL=100, Lmin = 0.0, Lmax = 10.0, npol=21,
		  mx=0, my=0, mz=1, filename="pollambdaMon1z.data")
     AT (0, 0, 0.8) RELATIVE Origin

COMPONENT armMSF = Arm()
     AT (0,0,1) RELATIVE Origin

// The By field is set to rotate the spin 180 degrees for neutrons of wavelenth
// 5 AA
COMPONENT msf =
Pol_Bfield(xwidth=0.08, yheight=0.08,  Bx=0, By=-0.678332e-4, Bz=0,
        fieldFunction=magnetic_field_t, field_prms=user_parameters)
AT (0, 0, 0) RELATIVE armMSF

COMPONENT msf_stop =
Pol_Bfield_stop()
AT(0,0,MagnetLength) RELATIVE armMSF


COMPONENT pollambdaMonitor2x =
PolLambda_monitor(xwidth=0.1, yheight=0.1,
		  nL=100, Lmin = 0.0, Lmax = 10.0, npol=21,
		  mx=1, my=0, mz=0, filename="pollambdaMon2x.data")
     AT (0, 0, 0.1) RELATIVE PREVIOUS

COMPONENT pollambdaMonitor2y =
PolLambda_monitor(xwidth=0.1, yheight=0.1,
		  nL=100, Lmin = 0.0, Lmax = 10.0, npol=21,
		  mx=0, my=1, mz=0, filename="pollambdaMon2y.data")
     AT (0, 0, 0.1) RELATIVE PREVIOUS

COMPONENT pollambdaMonitor2z =
PolLambda_monitor(xwidth=0.1, yheight=0.1,
		  nL=100, Lmin = 0.0, Lmax = 10.0, npol=21,
		  mx=0, my=0, mz=1, filename="pollambdaMon2z.data")
     AT (0, 0, 0.1) RELATIVE PREVIOUS

COMPONENT mpollambdaMonitor2x =
MeanPolLambda_monitor(xwidth=0.1, yheight=0.1,
		      nL=100, Lmin = 0.0, Lmax = 10.0,
		      mx=1, my=0, mz=0, filename="mpollambdaMon2x.data")
     AT (0, 0, 0.1) RELATIVE PREVIOUS

COMPONENT mpollambdaMonitor2y =
MeanPolLambda_monitor(xwidth=0.1, yheight=0.1,
		      nL=100, Lmin = 0.0, Lmax = 10.0,
		      mx=0, my=1, mz=0, filename="mpollambdaMon2y.data")
     AT (0, 0, 0.1) RELATIVE PREVIOUS

COMPONENT mpollambdaMonitor2z =
MeanPolLambda_monitor(xwidth=0.1, yheight=0.1,
		      nL=100, Lmin = 0.0, Lmax = 10.0,
		      mx=0, my=0, mz=1, filename="mpollambdaMon2z.data")
     AT (0, 0, 0.1) RELATIVE PREVIOUS

/* This section is executed when the simulation ends (C code). Other    */
/* optional sections are : SAVE                                         */
FINALLY
%{
  %}
/* The END token marks the instrument definition end */
END
