BLFieldMap.hh

Go to the documentation of this file.
00001 //      BLFieldMap.hh
00002 /*
00003 This source file is part of G4beamline, http://g4beamline.muonsinc.com
00004 Copyright (C) 2003,2004,2005,2006 by Tom Roberts, all rights reserved.
00005 
00006 This program is free software; you can redistribute it and/or
00007 modify it under the terms of the GNU General Public License
00008 as published by the Free Software Foundation; either version 2
00009 of the License, or (at your option) any later version.
00010 
00011 This program is distributed in the hope that it will be useful,
00012 but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 GNU General Public License for more details.
00015 
00016 http://www.gnu.org/copyleft/gpl.html
00017 */
00018 #ifndef BLFIELDMAP_HH
00019 #define BLFIELDMAP_HH
00020 
00021 #include "globals.hh"
00022 #include "BLCommand.hh"
00023 
00024 
00025 /**     class BLFieldMap implements a general field map, both B and E.
00026  *
00027  *      Initially this class simply reads an input file to define the map.
00028  *      Eventually it will also generate a map automatically from a BLCoil,
00029  *      and from an arbitrary collection of magnets (to improve tracking 
00030  *      efficiency for a large number of overlapping solenoids).
00031  *
00032  *      Field components are interpolated in the map; the values used are:
00033  *        Bx = (interpolated value)*normB*(element_current/current_param)
00034  *        Ex = (interpolated value)*normE*(element_gradient/gradient_param)
00035  *        [other components are similar]
00036  *      where element_current and element_gradient are from the element 
00037  *      definition command in the input file, and normB, normE, curren_param,
00038  *      and gradient_param come from the input file. The presence of both norm
00039  *      and current/gradient in the input file is to accommodate diverse
00040  *      sources of input files and units.
00041  *
00042  *      Outside the map the fields are zero, so if the map is truncated you
00043  *      should ensure that no particles are tracked outside the map in that
00044  *      region. This happens, for instance, for a beam solenoid truncated
00045  *      in radius to the inside of the coil -- particles which enter the
00046  *      coil will see a zero field, so the coil should be set to kill them;
00047  *      particles outside the map along z but inside the bore will also see
00048  *      a zero field, but that is usually OK as long as the map extends far
00049  *      enough along Z to include the nonzero field region.
00050  *
00051  *
00052  *      Input File format:
00053  *      Blank lines, and lines beginning with # or * are comments. Lines
00054  *      beginning with * are printed to stdout. Units are mm for coordinates,
00055  *      Tesla for B, and MegaVolts/meter for E; use normB and normE if the
00056  *      data points use different units.
00057  *
00058  *      The input file starts with a set of commands to define the parameters
00059  *      of the map, followed by blocks of lines containing the values of the
00060  *      field components. The field component names depend on the type of map
00061  *      (grid: Bx,By,Bz,Ex,Ey,Ez; cylinder: Br,Bz,Er,Ez).
00062  *      Each command has a specific list of arguments to define parameters
00063  *      of the map.
00064  *
00065  *      BEWARE: the parsing is not exhaustive. For instance, invalid arguments
00066  *      are silently ignored (which means you must verify the spelling and 
00067  *      capitalization of argument names). Correct inputs will yield correct
00068  *      results, but invalid inputs may not be detected and may yield
00069  *      seemingly-correct but unintended results.
00070  *
00071  *      The first command is usually a param command, which has the following
00072  *      arguments:
00073  *              maxline The maximum number of characters per line (default=1023)
00074  *              current The current corresponding to this map (default=1.0)
00075  *              gradient The gradient corresponding to the map (default=1.0)
00076  *              normE   A normalization factor for E components (default=1.0)
00077  *              normB   A normalization factor for B components (default=1.0)
00078  *
00079  *      Two types of maps are implemented: grid and cylinder.
00080  *
00081  *      grid maps are a 3-D grid, with each block of data being a single
00082  *      X-Y plane; within a block the lines are Y and the columns of each line
00083  *      are values along X.
00084  *      The grid command has the following arguments:
00085  *              X0      The X value for the first value in each line
00086  *              Y0      The Y value for the first line in each block
00087  *              Z0      The Z value for the first block of each field component
00088  *              nX      The number of columns per line
00089  *              nY      The number of lines per block
00090  *              nZ      The number of blocks per field component
00091  *              dX      The X increment between values in each line
00092  *              dY      The Y increment between lines
00093  *              dZ      The Z increment between blocks
00094  *           tolerance  The tolerance for pointwise data (default=0.01 mm)
00095  *      After the grid command, the following optional commands can be given:
00096  *              extendX flip=...
00097  *              extendY flip=...
00098  *              extendZ flip=...
00099  *      These commands permit a half-map to be extended to the full map
00100  *      around X=0, Y=0, or Z=0 respectively. The optional flip argument is a 
00101  *      comma-separated list of field components whose signs will be inverted
00102  *      for negative values of the coordinate. For example, "extendZ flip=Bx,Ex"
00103  *      means the map from Z=0 to Z=(nZ-1)*dZ is extended symmetrically around
00104  *      Z=0 to negative Z values, flipping the signs of Bx and Ex when Z<0.
00105  *      This could be followed by "extendX flip=Bx,Ex", and the field flips
00106  *      will be the products of both commands.
00107  *
00108  *      cylinder maps are a 2-D map with rotational symmetry around the Z axis.
00109  *      Each field component has a single block with lines being Z and the
00110  *      columns being R.
00111  *      The cylinder command has the following arguments:
00112  *              Z0      The Z value for the first line in each block
00113  *              nR      The number of columns per line
00114  *              nZ      The number of lines per block
00115  *              dR      The R increment between colums
00116  *              dZ      The Z increment between lines
00117  *           tolerance  The tolerance for pointwise data (default=0.01 mm)
00118  *      After the cylinder command, the following optional commands can be 
00119  *      given:
00120  *              extendZ flip=...
00121  *      This command behaves the same as for the grid map.
00122  *
00123  *      After the commands, each block consists of a line containing the
00124  *      name of the field component, followed by the lines of the block.
00125  *      The values within a line can be separated by whitespace or a ','
00126  *      followed by optional whitespace.
00127  *      Field components that are not given are set to 0.0 everywhere.
00128  *      Missing values will be considered to be 0.0.
00129  *      For grid maps the first block is for Z=Z0, and successive blocks 
00130  *      increment Z by dZ; the first line in a block is for Y=Y0 and the
00131  *      first column in each line is for X=X0.
00132  *      For cylinder maps, the first line in each block is for Z=Z0 and the
00133  *      first column in each line is for R=0.
00134  *
00135  *      Instead of the blocked input format, a pointwise data format can be
00136  *      used. This is introduced by a line containing the command "data",
00137  *      followed by the individual points of the map, one per line. 
00138  *      for a grid field, each line contains values for
00139  *      X,Y,Z,Bx,By,Bz,Ex,Ey,Ez separated by either a comma and optional
00140  *      whitespece or by whitespace. for a cylinder field each line contains
00141  *      values for R,Z,Br,Bz,Er,Ez. The order of the points does not matter;
00142  *      omitted grid points will be 0.0, and for duplicates the last entry
00143  *      wins. If there is no E field, the Ex,Ey,Ez or Er,Ez entries should
00144  *      be omitted on every line. NOTE: every line's X,Y,Z or R,Z must be
00145  *      on a grid point as specified by the arguments to the grid or cylinder
00146  *      commands, to within the tolerance specified; if not, an error message
00147  *      is printed and the input line is ignored.
00148  *
00149  *      For time=dependent fields, the "time" command is used:
00150  *              time [period=12]
00151  *      period, if given, is in nanoseconds, and causes the interval [0,period)
00152  *      to be extended forever (before and after the values given). Because of
00153  *      the interpolation used, at least two points beyond the interval
00154  *      boundaries should be provided; there need not be a point at either 
00155  *      boundary (but usually there are).
00156  *      Following the time command are lines containing 2 or 3 doubles:
00157  *              t B E
00158  *      where t is the time (nanoseconds), and B and E are factors for the
00159  *      fields. If E is omitted, the value for B is used. These values will
00160  *      be interpolated in time with a cubic spline that can handle either
00161  *      uniform or non-uniform spacing of points along t.
00162  *      The time command can come either before or after the cylinder or grid
00163  *      commands, but not within either of their sequences.
00164  *      Note a cubic spline is used to interpolate between points, and that
00165  *      can cause over/under-shoot near an abrupt change. Combined with period=
00166  *      this gives an excellent representation of sinewave/cosinewave.
00167  *
00168  *      Note that time dependence can currently only be specified via the
00169  *      time command in an input file (i.e. not programmable method exists).
00170  *
00171  *
00172  *      Example block input file:
00173  *      * this is an example BLFieldMap input file, suitable for a solenoid
00174  *      # grid interval is 1 cm.
00175  *      # The region of validity is -390<=Z<=390 and 0<=R<=90
00176  *      param normB=1.0 current=1.0
00177  *      cylinder Z0=0.0 nR=10 nZ=40 dR=10.0 dZ=10.0
00178  *      extendZ flip=Br
00179  *      Bz
00180  *      ... 40 lines of 10 values, Z=0 thru Z=390
00181  *      Br
00182  *      ... 40 lines of 10 values, Z=0 thru Z=390
00183  *      --EOF--
00184  *
00185  *      Example pointwise input file:
00186  *      * this is an example BLFieldMap input file, suitable for a solenoid
00187  *      # grid interval is 1 cm.
00188  *      # The region of validity is -390<=Z<=390 and 0<=R<=90
00189  *      param normB=1.0 current=1.0
00190  *      cylinder Z0=0.0 nR=10 nZ=40 dR=10.0 dZ=10.0
00191  *      extendZ flip=Br
00192  *      data
00193  *      ... 400 lines of 4 values, giving R,Z,Br,Bz
00194  *      --EOF--
00195  *
00196  **/
00197 class BLFieldMap {
00198 public:
00199         /// default constructor.
00200         BLFieldMap();
00201 
00202         /// destructor.
00203         virtual ~BLFieldMap();
00204 
00205         /// readFile() reads a file to initialize the map.
00206         /// Returns true if OK, false on error.
00207         bool readFile(G4String filename);
00208 
00209         /// writeFile() writes the map to a file.
00210         /// Returns true if OK, false on error.
00211         bool writeFile(G4String filename, G4String comment="");
00212 
00213         /// getFieldValue() gets the map's field to the field[] array.
00214         /// local[] must be LOCAL coordinates; local[3] (time) is ignored
00215         /// unless there is a time dependence specified.
00216         /// (elements using BLFieldMap perform the global->local conversion)
00217         void getFieldValue(const G4double local[4], G4double field[6],
00218                         G4double current=1.0, G4double gradient=1.0);
00219 
00220         /// getFieldValueNoTimeNoScale() as above, except no time dependence
00221         /// is applies, and no scaling is performed.
00222         void getFieldValueNoTimeNoScale(const G4double local[4], 
00223                         G4double field[6]);
00224 
00225         /// getBoundingPoint() returns the i-th bounding point of the map.
00226         void getBoundingPoint(int i, G4double point[4]);
00227 
00228         /// hasB() returns true if this map has a nonzero B field.
00229         bool hasB();
00230 
00231         /// hasE() returns true if this map has a nonzero E field.
00232         bool hasE();
00233 
00234         /// createGridMap() will create a 3-d map from a pre-defined field.
00235         /// returns false if error.
00236         bool createGridMap(G4double X0, G4double Y0, G4double Z0, G4double dX,
00237                 G4double dY, G4double dZ, int nX, int nY, int nZ,
00238                 class G4ElectroMagneticField *field);
00239 
00240         /// createCylinderMap() will create a 2-d map from a pre-defined 
00241         /// cylindrically-symmetric field. NOTE: cylindrical symmetry is
00242         /// ASSUMED; the field in the Y=0,X>=0 half-plane is used (Bx->Br...).
00243         /// returns false if error.
00244         bool createCylinderMap(G4double Z0, G4double dR,  G4double dZ, int nR,
00245                 int nZ, class G4ElectroMagneticField *field);
00246         
00247         /// createTimeDependence() will apply the time dependence given.
00248         /// n is the # elements in the arrays; t[] is the time value for
00249         /// each point, b[] is the factor for B, and e[] is the factor for E.
00250         /// returns false if error.
00251         bool createTimeDependence(int n, G4double t[], G4double b[],
00252                                         G4double e[]=0, G4double period=-1.0);
00253 
00254         /// getTimeFactor() returns the time factors for B and E at time t.
00255         /// returns false if error.
00256         bool getTimeFactor(G4double t, G4double *b, G4double *e);
00257 private:
00258         G4int maxline;
00259         G4double current;
00260         G4double gradient;
00261         G4double normB;
00262         G4double normE;
00263         class FieldMapImpl *impl;
00264         class TimeImpl *time;
00265         friend class FieldMapPlacement;
00266 };
00267 
00268 #endif // BLFIELDMAP_HH
g4beamline