Commit in lcdd on MAIN
include/G4RZFieldMap.hh+21-71.2 -> 1.3
       /RZFieldMapType.hh+50-21.1 -> 1.2
       /rz_field_map.hh+3-31.1 -> 1.2
schemas/lcdd/1.0/lcdd_fields.xsd+41.2 -> 1.3
src/G4RZFieldMap.cc+199-391.2 -> 1.3
   /rz_field_mapProcess.cc+7-11.1 -> 1.2
   /rz_field_mapSubscriber.cc+20-21.2 -> 1.3
+304-54
7 modified files
Working copy of RZ field map.

lcdd/include
G4RZFieldMap.hh 1.2 -> 1.3
diff -u -r1.2 -r1.3
--- G4RZFieldMap.hh	30 Aug 2005 21:22:07 -0000	1.2
+++ G4RZFieldMap.hh	31 Aug 2005 01:21:25 -0000	1.3
@@ -1,4 +1,4 @@
-// $Header: /cvs/lcd/lcdd/include/G4RZFieldMap.hh,v 1.2 2005/08/30 21:22:07 jeremy Exp $
+// $Header: /cvs/lcd/lcdd/include/G4RZFieldMap.hh,v 1.3 2005/08/31 01:21:25 jeremy Exp $
 
 #ifndef G4RZFieldMap_hh
 #define G4RZFieldMap_hh 1
@@ -21,7 +21,7 @@
   typedef std::vector<G4RZB> RowsType;
 
 public:
-  G4RZFieldMap();
+  G4RZFieldMap(double spanR, double gridSizeR, double spanZ, double gridSizeZ);
   virtual ~G4RZFieldMap();
 
 public:
@@ -30,7 +30,7 @@
   void addRZB(double r, double z, double Br, double Bz);
 
   /*
-   * Call once all RZB rows are added to make an array of r, z, Br, Bz.
+   * Call once all RZB rows are added to make two arrays of [r][z] containg values for Br or Bz.
    * This should be much more performant than the vector of G4RZB objects.
    * @param clearRows Set to true in order to clear the G4RZB object vector. (Default is true.)
    */
@@ -38,11 +38,25 @@
 
 private:
 
-  RowsType rows;
+  void computeNumBins();
 
-  size_t arraySize;
-  double** array;
-  bool madeArray;
+private:
+
+  size_t m_numBinsR;
+  size_t m_numBinsZ;
+
+  double m_spanR;
+  double m_gridSizeR;
+
+  double m_spanZ;
+  double m_halfSpanZ;
+  double m_gridSizeZ;
+
+  RowsType m_rows;
+
+  double** m_BrArray;
+  double** m_BzArray;
+  bool m_madeArray;
 };
 
 #endif

lcdd/include
RZFieldMapType.hh 1.1 -> 1.2
diff -u -r1.1 -r1.2
--- RZFieldMapType.hh	29 Aug 2005 23:23:18 -0000	1.1
+++ RZFieldMapType.hh	31 Aug 2005 01:21:25 -0000	1.2
@@ -1,8 +1,10 @@
-// $Header: /cvs/lcd/lcdd/include/RZFieldMapType.hh,v 1.1 2005/08/29 23:23:18 jeremy Exp $
+// $Header: /cvs/lcd/lcdd/include/RZFieldMapType.hh,v 1.2 2005/08/31 01:21:25 jeremy Exp $
 #ifndef RZFieldMapType_hh
 #define RZFieldMapType_hh 1
 
-class RZFieldMapType : FieldMapType
+#include "FieldMapType.hh"
+
+class RZFieldMapType : public FieldMapType
 {
 
 public:
@@ -12,6 +14,52 @@
 
   virtual ~RZFieldMapType()
   {}
+
+  void set_span_r(const std::string& span_r)
+  {
+    m_span_r = span_r;
+  }
+
+  const std::string& get_span_r() const
+  {
+    return m_span_r;
+  }
+
+  void set_grid_size_r(const std::string& grid_size_r)
+  {
+    m_grid_size_r = grid_size_r;
+  }
+
+  const std::string& get_grid_size_r() const
+  {
+    return m_grid_size_r;
+  }
+
+  void set_span_z(const std::string& span_z)
+  {
+    m_span_z = span_z;
+  }
+
+  const std::string& get_span_z() const
+  {
+    return m_span_z;
+  }
+
+  void set_grid_size_z(const std::string& grid_size_z)
+  {
+    m_grid_size_z = grid_size_z;
+  }
+
+  const std::string& get_grid_size_z() const
+  {
+    return m_grid_size_z;
+  }
+
+private:
+  std::string m_span_r;
+  std::string m_grid_size_r;
+  std::string m_span_z;
+  std::string m_grid_size_z;
 };
 
 #endif

lcdd/include
rz_field_map.hh 1.1 -> 1.2
diff -u -r1.1 -r1.2
--- rz_field_map.hh	29 Aug 2005 23:23:19 -0000	1.1
+++ rz_field_map.hh	31 Aug 2005 01:21:25 -0000	1.2
@@ -1,14 +1,14 @@
-// $Header: /cvs/lcd/lcdd/include/rz_field_map.hh,v 1.1 2005/08/29 23:23:19 jeremy Exp $
+// $Header: /cvs/lcd/lcdd/include/rz_field_map.hh,v 1.2 2005/08/31 01:21:25 jeremy Exp $
 #ifndef rz_field_map_hh
 #define rz_field_map_hh 1
 
-#include "FieldMapType.hh"
+#include "RZFieldMapType.hh"
 
 /**
  * @class rz_field_map
  * @brief The rz_field_map element from lcdd_fields.xsd subschema.
  */
-class rz_field_map : public SAXObject, public FieldMapType
+class rz_field_map : public SAXObject, public RZFieldMapType
 {
 public:
   rz_field_map()

lcdd/schemas/lcdd/1.0
lcdd_fields.xsd 1.2 -> 1.3
diff -u -r1.2 -r1.3
--- lcdd_fields.xsd	29 Aug 2005 23:22:35 -0000	1.2
+++ lcdd_fields.xsd	31 Aug 2005 01:21:26 -0000	1.3
@@ -101,6 +101,10 @@
 	<xs:sequence>
 	  <xs:element name="rzB" type="RZBType" minOccurs="2" maxOccurs="unbounded" />
 	</xs:sequence>
+	<xs:attribute name="span_r" type="xs:double" />
+	<xs:attribute name="grid_size_r" type="xs:double" />
+	<xs:attribute name="span_z" type="xs:double" />
+	<xs:attribute name="grid_size_z" type="xs:double" />
       </xs:extension>
     </xs:complexContent>
   </xs:complexType>

lcdd/src
G4RZFieldMap.cc 1.2 -> 1.3
diff -u -r1.2 -r1.3
--- G4RZFieldMap.cc	30 Aug 2005 21:22:07 -0000	1.2
+++ G4RZFieldMap.cc	31 Aug 2005 01:21:26 -0000	1.3
@@ -1,77 +1,237 @@
-// $Header: /cvs/lcd/lcdd/src/G4RZFieldMap.cc,v 1.2 2005/08/30 21:22:07 jeremy Exp $
+// $Header: /cvs/lcd/lcdd/src/G4RZFieldMap.cc,v 1.3 2005/08/31 01:21:26 jeremy Exp $
 #include "G4RZFieldMap.hh"
 
-G4RZFieldMap::G4RZFieldMap()
-  : arraySize(0),
-    array(0),
-    madeArray(false)
-{}
+#include "globals.hh"
+
+#include <cmath>
+
+G4RZFieldMap::G4RZFieldMap(double spanR, double gridSizeR, double spanZ, double gridSizeZ)
+  : m_numBinsR(0),
+    m_numBinsZ(0),
+    m_spanR(spanR),
+    m_gridSizeR(gridSizeR),
+    m_spanZ(spanZ),
+    m_gridSizeZ(gridSizeZ),
+    m_BrArray(0),
+    m_BzArray(0),
+    m_madeArray(false)
+{
+  computeNumBins();
+}
 
 G4RZFieldMap::~G4RZFieldMap()
 {
   /* delete the array */
-  if ( madeArray ) {
-    for (size_t i=0; i<arraySize; i++) {
-      delete[] array[i];
+  if ( m_madeArray ) {
+    for (size_t i=0; i<m_numBinsR; i++) {
+      delete[] m_BrArray[i];
+      delete[] m_BzArray[i];
     }
-    delete[] array;
+    delete[] m_BrArray;
+    delete[] m_BzArray;
+  }
+}
+
+void G4RZFieldMap::computeNumBins()
+{
+  /* r bins */
+  double rem = fmod( (float)m_spanR, (float)m_gridSizeR);
+
+  if ( rem != 0 ) {
+    G4Exception("spanR is not evenly divisible by gridSizeR.");
+  }
+
+  m_numBinsR = (size_t)(m_spanR / m_gridSizeR);
+
+  if ( m_numBinsR == 0 ) {
+    G4Exception("numBinsR == 0");
+  }
+
+  /* z bins */
+  rem = fmod( (float)m_spanZ, (float)m_gridSizeZ);
+
+  if ( rem != 0 ) {
+    G4Exception("spanZ is not evenly disible by gridSizeZ.");
+  }
+
+  m_numBinsZ = (size_t)(m_spanZ / m_gridSizeZ);
+
+  if ( m_numBinsZ == 0 ) {
+    G4Exception("numBinsZ == 0");
   }
 }
 
 /*
- *  FIXME: Needs implementation!
- *  See Takashi's FORTRAN code at /afs/slac/www/accel/nlc/local/systems/beamdelivery/geant/SDNEW/solenoid.f
+ * Compute B field at given point using the arrays of Br and Bz field strengths.
+ *
+ * This function is based on Takashi's FORTRAN code at
+ *
+ * /afs/slac/www/accel/nlc/local/systems/beamdelivery/geant/SDNEW/solenoid.f
+ *
  */
 void G4RZFieldMap::GetFieldValue( const double Point[3], double *Bfield ) const
 {
-  /* make compiler happy */
-  if ( Point[0] );
-  if ( Bfield );
+  std::cout << std::endl << "G4RZFieldMap::GetFieldValue" << std::endl;
+  std::cout << "Point = " << Point[0] << ", " << Point[1] << ", " << Point[2] << std::endl;
+
+  double rcyl = sqrt( ( Point[0] * Point[0] ) + ( Point[1] * Point[1] ) );
+  double z = Point[2];
+
+  size_t binR = (int)floor( rcyl / m_gridSizeR );
+  binR += 1;
+
+  std::cout << "binR = " << binR << std::endl;
+
+  if ( binR >= m_numBinsR ) {
+    std::cerr << "OVERFLOW: binR > m_numBinsR - 1 ... RETURNING" << std::endl;
+    return;
+  }
+
+  size_t binZ = (size_t) floor( ( fabs(z) / m_gridSizeZ ) );
+  binZ += 1;
+
+  std::cout << "binZ = " << binZ << std::endl;
+
+  if ( binZ >= m_numBinsZ ) {
+    std::cerr << "OVERFLOW: binZ > m_numBinsZ - 1 ... SETTING binZ = m_numBinZ" << std::endl;
+    binZ = m_numBinsZ;
+  }
+
+  double brmin = m_BrArray[binR][binZ];
+  double bzmin = m_BzArray[binR][binZ];
+
+  double remR = (double) ( rcyl - ( (binR - 1) * m_gridSizeR ) );
+  double brdz = (m_BrArray[binZ+1][binR] - brmin) / m_gridSizeZ;
+  double brdr = (m_BrArray[binZ][binR+1] - brmin) / m_gridSizeR;
+
+  double remZ = (double) fabs(z) - ( (binZ - 1) * m_gridSizeZ );
+  double bzdz = (m_BzArray[binZ+1][binR] - bzmin) / m_gridSizeZ;
+  double bzdr = (m_BzArray[binZ][binR+1] - bzmin) / m_gridSizeR;
+
+  double bz = bzmin + bzdz * remZ + bzdr * remR;
+  double br = brmin + brdz * remZ + brdr * remR;
+
+  double theta = atan2(Point[1], Point[0]);
+  double bx = br * cos(theta);
+  double by = br * sin(theta);
+
+  Bfield[0] = bx;
+  Bfield[1] = by;
+  Bfield[2] = bz;
+
+  // DEBUG: prints
+  std::cout << "brmin = " << brmin << std::endl;
+  std::cout << "bzmin = " << bzmin << std::endl;
+  std::cout << "remR = " << remR << std::endl;
+  std::cout << "brdz = " << brdz << std::endl;
+  std::cout << "brdr = " << brdr << std::endl;
+  std::cout << "bzdz = " << bzdz << std::endl;
+  std::cout << "bzdr = " << bzdr << std::endl;
+  std::cout << "bz = " << bz << std::endl;
+  std::cout << "br = " << br << std::endl;
+  std::cout << "Bfield = " << Bfield[0] << ", " << Bfield[1] << ", " << Bfield[2] << std::endl;
 }
 
 void G4RZFieldMap::addRZB(double r, double z, double Br, double Bz)
 {
   //  std::cout << "adding --> r z Br Bz = " << r << " " << z << " " << Br << " " << Bz << std::endl;
-  if ( !madeArray ) {
-    rows.push_back(G4RZB(r, z, Br, Bz));
+  if ( !m_madeArray ) {
+    m_rows.push_back(G4RZB(r, z, Br, Bz));
   }
   else {
-    std::cerr << "ERROR: Additional rows not allowed once G4RZFieldMap::makeArray() has been called." << std::endl;
+    std::cerr << "ERROR: Additional m_rows not allowed once G4RZFieldMap::makeArray() has been called." << std::endl;
   }
 }
 
-void G4RZFieldMap::makeArray(bool clearRows)
+void G4RZFieldMap::makeArray(bool clearM_Rows)
 {
-  if ( !madeArray ) {
+  if ( !m_madeArray ) {
 
-    /* allocate array of [arraySize][4] */
-    arraySize = rows.size();
-    array = new double*[arraySize];
+    /* Make two 2D arrays of numBinsR x numBinsZ */
+    m_BrArray = new double*[m_numBinsR];
+    m_BzArray = new double*[m_numBinsR];
+
+    for (size_t i=0; i<m_numBinsR; i++) {
+      m_BrArray[i] = new double[m_numBinsZ];
+      m_BzArray[i] = new double[m_numBinsZ];
+    }
 
-    for (size_t i=0; i<arraySize; i++) {
-      array[i] = new double[4];
+    /* Init arrays to all 0's */
+    for ( size_t i=0; i<m_numBinsR; i++) {
+      for ( size_t j=0; j<m_numBinsZ; j++) {
+	m_BrArray[i][j]=0;
+	m_BzArray[i][j]=0;
+      }
     }
 
-    /* fill array with values from object vector */
-    int cntr = 0;
-    for ( RowsType::const_iterator iter = rows.begin();
-	  iter != rows.end();
+    /* Fill arrays with values from object vector. */
+    size_t binR = 0;
+    size_t binZ = 0;
+    for ( RowsType::const_iterator iter = m_rows.begin();
+	  iter != m_rows.end();
 	  iter++ ) {
-      array[cntr][0] = (*iter).r();
-      array[cntr][1] = (*iter).z();
-      array[cntr][2] = (*iter).Br();
-      array[cntr][3] = (*iter).Bz();
-      ++cntr;
+
+      /* Compute the r bin. */
+      binR = (size_t) floor( (*iter).r() / m_gridSizeR );
+
+      double r = (*iter).r();
+      if ( r == m_spanR ) {
+	binR -= 1;
+      }
+      else if ( r > m_spanR ) {
+	G4Exception("r value is > spanR");
+      }
+
+      std::cout << std::endl;
+      std::cout << "r = " << (*iter).r() << std::endl;
+      std::cout << "binR = " << binR << std::endl;
+
+      /* r overflow? */
+      if ( binR > ( m_numBinsR - 1 ) ) {
+	G4Exception("OVERFLOW: R bin > numBinsR - 1");
+      }
+
+      /*
+       * Compute z bin, normalized to positive value.
+       * Forces z symmetry w.r.t. the +/- z halves.
+      */
+      double z = fabs((*iter).z());
+      binZ = (size_t) floor( z / m_gridSizeZ );
+
+      /* If Z value is equal to spanZ, set to last z bin. */
+      if (z == m_spanZ) {
+	binZ -= 1;
+      }
+      else if ( z > m_spanZ ) {
+	G4Exception("z value is > spanZ");
+      }
+
+      std::cout << "z = " << z << std::endl;
+      std::cout << "binZ = " << binZ << std::endl;
+
+      /* z overflow? */
+      if ( binZ > ( m_numBinsZ - 1) ) {
+	G4Exception("OVERFLOW: Z bin > numBinsZ - 1");
+      }
+
+      /* Assign Bz and Br array values. */
+      std::cout << "setting r,z bins = " << binR << ", " << binZ << std::endl;
+
+      m_BrArray[binR][binZ] = (*iter).Bz();
+      m_BzArray[binR][binZ] = (*iter).Br();
+
+      std::cout << "br[r][z] = " << m_BrArray[binR][binZ] << std::endl;
+      std::cout << "br[r][z] = " << m_BzArray[binR][binZ] << std::endl;
     }
 
-    /* clear object vector rows */
-    if ( clearRows ) {
-      rows.clear();
+    /* clear object vector m_rows */
+    if ( clearM_Rows ) {
+      m_rows.clear();
     }
 
-    madeArray = true;
+    m_madeArray = true;
   }
-  else {
+    else {
     std::cerr << "WARNING: Ignoring additional call to G4RZFieldMap::makeArray()." << std::endl;
   }
 }

lcdd/src
rz_field_mapProcess.cc 1.1 -> 1.2
diff -u -r1.1 -r1.2
--- rz_field_mapProcess.cc	29 Aug 2005 23:23:19 -0000	1.1
+++ rz_field_mapProcess.cc	31 Aug 2005 01:21:26 -0000	1.2
@@ -1,4 +1,4 @@
-// $Header: /cvs/lcd/lcdd/src/rz_field_mapProcess.cc,v 1.1 2005/08/29 23:23:19 jeremy Exp $
+// $Header: /cvs/lcd/lcdd/src/rz_field_mapProcess.cc,v 1.2 2005/08/31 01:21:26 jeremy Exp $
 #include "FieldMapTypeProcess.hh"
 #include "rz_field_map.hh"
 #include <iostream>
@@ -26,6 +26,12 @@
 
     rz_field_map* rzmap = new rz_field_map;
 
+    /* set attributes */
+    rzmap->set_span_r(attrs.getValue("span_r"));
+    rzmap->set_grid_size_r(attrs.getValue("grid_size_r"));
+    rzmap->set_span_z(attrs.getValue("span_z"));
+    rzmap->set_grid_size_z(attrs.getValue("grid_size_z"));
+
     /* Top-level caller needs to setup the SAXObject references. */
     m_obj = rzmap;
     *obj = rzmap;

lcdd/src
rz_field_mapSubscriber.cc 1.2 -> 1.3
diff -u -r1.2 -r1.3
--- rz_field_mapSubscriber.cc	30 Aug 2005 21:22:07 -0000	1.2
+++ rz_field_mapSubscriber.cc	31 Aug 2005 01:21:26 -0000	1.3
@@ -1,4 +1,4 @@
-// $Header: /cvs/lcd/lcdd/src/rz_field_mapSubscriber.cc,v 1.2 2005/08/30 21:22:07 jeremy Exp $
+// $Header: /cvs/lcd/lcdd/src/rz_field_mapSubscriber.cc,v 1.3 2005/08/31 01:21:26 jeremy Exp $
 
 #include "Saxana/SAXSubscriber.h"
 #include "Saxana/SAXComponentFactory.h"
@@ -48,7 +48,25 @@
 	std::string funit = obj->get_funit();
 	std::string name = obj->get_name();
 
-	G4RZFieldMap* fmap = new G4RZFieldMap();
+	double spanR, gridSizeR, spanZ, gridSizeZ;
+
+	std::string sval = obj->get_span_r();
+	sval += "*" + lunit;
+	spanR = calc->Eval(sval);
+
+	sval = obj->get_grid_size_r();
+	sval += "*" + lunit;
+	gridSizeR = calc->Eval(sval);
+
+	sval = obj->get_span_z();
+	sval += "*" + lunit;
+	spanZ = calc->Eval(sval);
+
+	sval = obj->get_grid_size_z();
+	sval += "*" + lunit;
+	gridSizeZ = calc->Eval(sval);
+
+	G4RZFieldMap* fmap = new G4RZFieldMap(spanR, gridSizeR, spanZ, gridSizeZ);
 	LCDDProcessor::instance()->addMagneticField(name, fmap);
 
 	/* add RZB rows */
CVSspam 0.2.8