diff --git a/MagneticField/MagFieldElements/CMakeLists.txt b/MagneticField/MagFieldElements/CMakeLists.txt
index d24244fcfb5aba4d9e7d09679e0fc93b42d3acaf..f7929d3a6cda021157f6b392bb73e39e158fa708 100644
--- a/MagneticField/MagFieldElements/CMakeLists.txt
+++ b/MagneticField/MagFieldElements/CMakeLists.txt
@@ -13,3 +13,10 @@ atlas_add_library( MagFieldElements
                    INCLUDE_DIRS ${ROOT_INCLUDE_DIRS}
                    LINK_LIBRARIES CxxUtils EventPrimitives GaudiKernel
                    PRIVATE_LINK_LIBRARIES ${ROOT_LIBRARIES} PathResolver )
+
+		 
+atlas_add_test( BFieldExample
+                SOURCES  test/BFieldExample_test.cxx
+                INCLUDE_DIRS ${GTEST_INCLUDE_DIRS} #${GMOCK_INCLUDE_DIRS}
+                LINK_LIBRARIES TestTools  CxxUtils EventPrimitives ${GTEST_LIBRARIES} #${GMOCK_LIBRARIES}
+                ENVIRONMENT "JOBOPTSEARCHPATH=${CMAKE_CURRENT_SOURCE_DIR}/share" )		
diff --git a/MagneticField/MagFieldElements/MagFieldElements/BFieldCache.h b/MagneticField/MagFieldElements/MagFieldElements/BFieldCache.h
index e42b999ef3bebe16e2df4f9564f8d7de6a9fe526..8282eb91153ed3a7297593e6b7da13787a262b5d 100644
--- a/MagneticField/MagFieldElements/MagFieldElements/BFieldCache.h
+++ b/MagneticField/MagFieldElements/MagFieldElements/BFieldCache.h
@@ -55,28 +55,52 @@ public:
     m_invr = 1.0 / (rmax - rmin);
     m_invphi = 1.0 / (phimax - phimin);
   }
-  // set the field values at each corner (rescale for current scale factor)
-  void setField(const std::array<BFieldVector<double>, 8>& field,
-                double scaleFactor = 1.0)
-  {
-    // We pass array of 8 elements with 3 entries
-    // Which go to 3x8 matrix
-    for (int i = 0; i < 8; ++i) {
-      for (int j = 0; j < 3; ++j) {
-        m_field[j][i] = scaleFactor * field[i][j];
-      }
-    }
+
+    // **
+    // ** The following two methods are commented out, and replaced by the third setField as optimization test
+    // **
+  // // set the field values at each corner (rescale for current scale factor)
+  // void setField(const std::array<BFieldVector<double>, 8>& field,
+  //               double scaleFactor = 1.0)
+  // {
+  //   // We pass array of 8 elements with 3 entries
+  //   // Which go to 3x8 matrix
+  //   for (int i = 0; i < 8; ++i) {
+  //     for (int j = 0; j < 3; ++j) {
+  //       m_field[j][i] = scaleFactor * field[i][j];
+  //     }
+  //   }
+  // }
+
+  // void setField(const std::array<BFieldVector<short>, 8>& field,
+  //               double scaleFactor = 1.0)
+  // {
+  //   // We pass array of 8 elements with 3 entries
+  //   // Which go to 3x8 matrix
+  //   for (int i = 0; i < 8; ++i) {
+  //     for (int j = 0; j < 3; ++j) {
+  //       m_field[j][i] = scaleFactor * field[i][j];
+  //     }
+  //   }
+  // }
+
+  // set field array, filled externally
+  void setField(double field[][8]) {
+      std::copy( &field[0][0], &field[0][0] + 3*8, &m_field[0][0]);
   }
+    
 
-  void setField(const std::array<BFieldVector<short>, 8>& field,
-                double scaleFactor = 1.0)
+  // set the field values at each corner (rescale for current scale factor)
+  void printField() 
   {
-    // We pass array of 8 elements with 3 entries
-    // Which go to 3x8 matrix
+    // print out field values
+    std::cout << "Field at corner i, for each component j (Bz, Br, Bphi)" << std::endl;
+
     for (int i = 0; i < 8; ++i) {
       for (int j = 0; j < 3; ++j) {
-        m_field[j][i] = scaleFactor * field[i][j];
+          std::cout << i << "," << j << ": " << m_field[j][i] << ", ";
       }
+      std::cout << std::endl;
     }
   }
 
diff --git a/MagneticField/MagFieldElements/MagFieldElements/BFieldMesh.h b/MagneticField/MagFieldElements/MagFieldElements/BFieldMesh.h
index 9c85785a4af2c2a59ca69d5a3409b8986c81660d..7424d87ab3de46217aa4186211d851693c20b545 100644
--- a/MagneticField/MagFieldElements/MagFieldElements/BFieldMesh.h
+++ b/MagneticField/MagFieldElements/MagFieldElements/BFieldMesh.h
@@ -112,6 +112,7 @@ private:
   std::array<std::vector<int>,3> m_LUT;
   std::array<double,3> m_invUnit; // inverse unit size in the LUT
   int m_roff, m_zoff;
+
 };
 #include "MagFieldElements/BFieldMesh.icc"
 #endif
diff --git a/MagneticField/MagFieldElements/MagFieldElements/BFieldMesh.icc b/MagneticField/MagFieldElements/MagFieldElements/BFieldMesh.icc
index 810c9739fdc2588d80b5cf1a200d2b29049ca1a2..114bffa4fdcebe9052d81b1141c4203aea1d765b 100644
--- a/MagneticField/MagFieldElements/MagFieldElements/BFieldMesh.icc
+++ b/MagneticField/MagFieldElements/MagFieldElements/BFieldMesh.icc
@@ -70,21 +70,60 @@ BFieldMesh<T>::getCache(double z,
     ++iphi;
   }
   // store the bin edges
-  cache.setRange(
-    mz[iz], mz[iz + 1], mr[ir], mr[ir + 1], mphi[iphi], mphi[iphi + 1]);
+  cache.setRange(mz[iz], mz[iz + 1], mr[ir], mr[ir + 1], mphi[iphi], mphi[iphi + 1]);
+
+  
   // store the B field at the 8 corners
   const int im0 = iz * m_zoff + ir * m_roff + iphi; // index of the first corner
-  std::array<BFieldVector<T>, 8> field = {
-    m_field[im0],
-    m_field[im0 + 1],
-    m_field[im0 + m_roff],
-    m_field[im0 + m_roff + 1],
-    m_field[im0 + m_zoff],
-    m_field[im0 + m_zoff + 1],
-    m_field[im0 + m_zoff + m_roff],
-    m_field[im0 + m_zoff + m_roff + 1]
+
+  
+  // ** The following field initialization is commented out, and replaced by subsequent matrix
+  // ** initialization as optimization test
+  
+
+  // std::array<BFieldVector<T>, 8> field = {
+  //   m_field[im0],
+  //   m_field[im0 + 1],
+  //   m_field[im0 + m_roff],
+  //   m_field[im0 + m_roff + 1],
+  //   m_field[im0 + m_zoff],
+  //   m_field[im0 + m_zoff + 1],
+  //   m_field[im0 + m_zoff + m_roff],
+  //   m_field[im0 + m_zoff + m_roff + 1]
+  // };
+
+  // cache.setField(field, scaleFactor);
+
+  const double sf = scaleFactor;
+
+  double field1[3][8] = {
+      { sf * m_field[im0][0],                        
+        sf * m_field[im0 + 1][0],                    
+        sf * m_field[im0 + m_roff][0],               
+        sf * m_field[im0 + m_roff + 1][0],           
+        sf * m_field[im0 + m_zoff][0],               
+        sf * m_field[im0 + m_zoff + 1][0],           
+        sf * m_field[im0 + m_zoff + m_roff][0],      
+        sf * m_field[im0 + m_zoff + m_roff + 1][0] },
+      { sf * m_field[im0][1],                      
+        sf * m_field[im0 + 1][1],                  
+        sf * m_field[im0 + m_roff][1],             
+        sf * m_field[im0 + m_roff + 1][1],         
+        sf * m_field[im0 + m_zoff][1],             
+        sf * m_field[im0 + m_zoff + 1][1],         
+        sf * m_field[im0 + m_zoff + m_roff][1],    
+        sf * m_field[im0 + m_zoff + m_roff + 1][1] },
+      { sf * m_field[im0][2],                     
+        sf * m_field[im0 + 1][2],                 
+        sf * m_field[im0 + m_roff][2],            
+        sf * m_field[im0 + m_roff + 1][2],        
+        sf * m_field[im0 + m_zoff][2],            
+        sf * m_field[im0 + m_zoff + 1][2],        
+        sf * m_field[im0 + m_zoff + m_roff][2],   
+        sf * m_field[im0 + m_zoff + m_roff + 1][2] }
   };
-  cache.setField(field, scaleFactor);
+  cache.setField(field1);
+  
   // store the B scale
   cache.setBscale(m_scale);
 }
diff --git a/MagneticField/MagFieldElements/test/BFieldExample_test.cxx b/MagneticField/MagFieldElements/test/BFieldExample_test.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..34ca83c9e083321c520689ea9a72d2aeb8aab821
--- /dev/null
+++ b/MagneticField/MagFieldElements/test/BFieldExample_test.cxx
@@ -0,0 +1,205 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include <iostream>
+#include "MagFieldElements/BFieldCache.h"
+#include "MagFieldElements/BFieldZone.h"
+#include <unistd.h>
+
+/**
+ * @brief Specimen of service caching expensive calculations.
+ * It uses internally std::map which is not thread-safely expandable.
+ **/
+class BFieldTest {
+public:
+    int runTest(bool doDebug = false  ) {
+
+
+        // Create a field zone
+
+
+        double fieldz[] = { 19487, 19487, 19488, 19488, 19487, 19487, 19531, 19531, 19532, 19532, 19531, 19531,  6399,  6400,  6400,  6400,  6399, -1561, -1561, -1560, -1560, -1560, -1561, -1516, -1516, -1515, -1515, -1516, -1516, 20310, 20310, 20311, 20311, 20311, 20310, 20329, 20329, 20329, 20330, 20329, 20329,  7172,  7173,  7173,  7172,  7172,  -814,  -814,  -813,  -812,  -813,  -814,  -795,  -795,  -794,  -793,  -794,  -795, 20310, 20310, 20311, 20312, 20311, 20310, 20329, 20329, 20330, 20330, 20330, 20329,  7172,  7172,  7173,  7173,  7173,  7172,  -813,  -813,  -812,  -812,  -813,  -813,  -794,  -794,  -793,  -793,  -793,  -794, 19487, 19487, 19488, 19488, 19488, 19487, 19531, 19531, 19532, 19532, 19532, 19531,  6400,  6399,  6400,  6401,  6400,  6400, -1561, -1561, -1560, -1559, -1560, -1561, -1516, -1516, -1515, -1515, -1515, -1516, -1516, -1516 };
+
+        double  fieldr[]  = { -1357, -1356, -1353, -1354, -1354, -1357, -1366, -1366, -1362, -1363, -1363, -1366, -1378, -1374, -1375, -1375, -1378, -1388, -1388, -1385, -1386, -1386, -1388, -1394, -1394, -1390, -1391, -1391, -1394,  -318,  -318,  -314,  -315,  -316,  -318,  -321,  -321,  -317,  -318,  -319,  -321,  -325,  -321,  -322,  -322,  -325,  -328,  -328,  -324,  -325,  -326,  -328,  -330,  -331,  -326,  -327,  -328,  -330,   312,   312,   316,   315,   315,   312,   315,   315,   319,   318,   318,   315,   319,   318,   323,   322,   321,   319,   322,   322,   326,   325,   325,   322,   324,   324,   328,   327,   327,   324,  1351,  1351,  1356,  1354,  1354,  1351,  1360,  1360,  1365,  1363,  1363,  1360,  1372,  1372,  1377,  1375,  1375,  1372,  1383,  1383,  1387,  1386,  1386,  1383,  1388,  1388,  1393,  1391,  1391,  1388,  1388,  1388 };
+
+        double fieldphi[] = { -2,  7,  3,  1,  6,  -2,  -2,  7,  3,  1,  6,  -2,  -2        ,  3,  1,  6,  -2,  -2,  7,  3,  1,  6,  -2,  -2,  7,  3,  1,  6,  -2,  -1,  7,  3,  1,  6,  -1,  -1,  7,  3,  1,  6,  -1,  -1,  3,  1,  6,  -1,  -1,  7,  3,  1,  6,  -1,  -1,  8,  3,  1,  6,  -1,  1,  7,  3,  2,  6,  1,  1,  7,  3,  2,  6,  1,  1,  7,  3,  2,  6,  1,  1,  7,  3,  2,  6,  1,  0,  8,  3,  2,  6,  0,  2,  7,  3,  2,  6,  2,  2,  7,  3,  2,  6,  2,  2,  7,  3,  2,  6,  2,  2,  7,  3,  2,  6,  2,  2,  8,  3,  2,  6,  2,  2,  2 };
+            
+
+        int id{5};
+        double zmin{-1400}, zmax{1400}, rmin{1200}, rmax{1300}, phimin{0}, phimax{6.28319}, bscale{1e-07};
+        BFieldZone zone(id, zmin, zmax, rmin, rmax, phimin, phimax, bscale);
+        // add in field
+        int nmeshz{4}, nmeshr{5}, nmeshphi{6};
+        int nfield = nmeshz * nmeshr * nmeshphi;
+
+        zone.reserve(nmeshz, nmeshr, nmeshphi);
+
+        double meshz[] = { -1400, -466.93, 466.14, 1400 };
+        
+        for (int j = 0; j < nmeshz; j++) {
+            zone.appendMesh(0, meshz[j]);
+
+            if (doDebug) std::cout << "j, meshz " << j << ", " << meshz[j] << std::endl;
+            
+        }
+
+        if (doDebug) std::cout << "did  meshz " << std::endl;
+        
+        double meshr[] = { 1200, 1225, 1250, 1275, 1300 };
+        
+        for (int j = 0; j < nmeshr; j++) {
+            zone.appendMesh(1, meshr[j]);
+        }
+
+        if (doDebug) std::cout << "did  meshr " << std::endl;
+
+        double meshphi[] = { 0, 1.25664, 2.51327, 3.76991, 5.02655, 6.28318 };
+
+        for (int j = 0; j < nmeshphi; j++) {
+            zone.appendMesh(2, meshphi[j]);
+        }
+
+        if (doDebug) std::cout << "did  meshphi " << std::endl;
+
+        for (int j = 0; j < nfield; j++) {
+            BFieldVector<short> field(fieldz[j], fieldr[j], fieldphi[j]);
+            zone.appendField(field);
+        }
+        
+        if (doDebug) std::cout << "did  field " << std::endl;
+
+        // build (trivial) look up table for zone
+        zone.buildLUT();
+        
+        if (doDebug) std::cout << "did  buildLUT " << std::endl;
+
+        
+        // fill the cache, pass in current scale factor
+        BFieldCache cache3d;
+        double z{0}, r{1250}, phi{1.6};
+
+        // if (doDebug) std::cout << "do getCache old " << std::endl;
+
+        // zone.m_doNew = false;
+        
+        // zone.getCache(z, r, phi, cache3d, 1);
+
+        // cache3d.printField();
+
+        // if (doDebug) std::cout << "do getCache new " << std::endl;
+        
+        // zone.m_doNew = true;
+        
+        // zone.getCache(z, r, phi, cache3d, 1);
+
+        // cache3d.printField();
+
+
+        // get field at steps of 10 mm from 1200 to 1300
+
+        int status{0};
+
+        double z0      = z;
+        double r0      = 1200;
+        double phi0    = phi;
+        double xyz[3]  = {0, 0, 0};
+        double bxyz[3] = {0, 0, 0};
+        double bxyz_std[3][10] = { 
+            { -2.83727e-07, -2.81403e-07, -2.79079e-07, -2.76755e-07, -2.74431e-07,
+              -2.72107e-07, -2.69782e-07, -2.67458e-07, -2.65134e-07, -2.6281e-07 },
+            {  9.47007e-08,  7.49033e-08,  5.51058e-08,  3.53084e-08,  1.5511e-08,
+              -4.28645e-09, -2.40839e-08, -4.38813e-08, -6.36787e-08, -8.34762e-08 },
+            {  0.00308551,   0.00255923,   0.00203296,   0.00150669,   0.000980422,
+               0.000454151, -7.21201e-05, -0.000598391, -0.00112466,  -0.00165093 }
+        };
+        
+// get field std: i, bxyz_std 0 -2.83727e-07, 9.47007e-08, 0.00308551
+// get field new: i, bxyz_new 0 -2.83727e-07, 9.47007e-08, 0.00308551
+// get field std: i, bxyz_std 1 -2.81403e-07, 7.49033e-08, 0.00255923
+// get field new: i, bxyz_new 1 -2.81403e-07, 7.49033e-08, 0.00255923
+// get field std: i, bxyz_std 2 -2.79079e-07, 5.51058e-08, 0.00203296
+// get field new: i, bxyz_new 2 -2.79079e-07, 5.51058e-08, 0.00203296
+// get field std: i, bxyz_std 3 -2.76755e-07, 3.53084e-08, 0.00150669
+// get field new: i, bxyz_new 3 -2.76755e-07, 3.53084e-08, 0.00150669
+// get field std: i, bxyz_std 4 -2.74431e-07, 1.5511e-08, 0.000980422
+// get field new: i, bxyz_new 4 -2.74431e-07, 1.5511e-08, 0.000980422
+// get field std: i, bxyz_std 5 -2.72107e-07, -4.28645e-09, 0.000454151
+// get field new: i, bxyz_new 5 -2.72107e-07, -4.28645e-09, 0.000454151
+// get field std: i, bxyz_std 6 -2.69782e-07, -2.40839e-08, -7.21201e-05
+// get field new: i, bxyz_new 6 -2.69782e-07, -2.40839e-08, -7.21201e-05
+// get field std: i, bxyz_std 7 -2.67458e-07, -4.38813e-08, -0.000598391
+// get field new: i, bxyz_new 7 -2.67458e-07, -4.38813e-08, -0.000598391
+// get field std: i, bxyz_std 8 -2.65134e-07, -6.36787e-08, -0.00112466
+// get field new: i, bxyz_new 8 -2.65134e-07, -6.36787e-08, -0.00112466
+// get field std: i, bxyz_std 9 -2.6281e-07, -8.34762e-08, -0.00165093
+// get field new: i, bxyz_new 9 -2.6281e-07, -8.34762e-08, -0.00165093
+
+        
+        for (unsigned int i = 0; i < 10; ++i) {
+            double r1 = r0 + 5 + i*10.;
+
+            xyz[0] = r1 * cos(phi0);
+            xyz[1] = r1 * sin(phi0);
+            xyz[2] = z0;
+            
+            // do interpolation (cache3d has correct scale factor)
+            zone.getCache(z, r, phi, cache3d, 1);
+            cache3d.getB(xyz, r1, phi, bxyz, 0);
+
+            std::cout << "get field std: i, bxyz " << i << " "
+                      << bxyz[0] << ", " << bxyz[1] << ", "
+                      << bxyz[2]
+                      << " fractional diff gt 10^-5: "
+                      << int(fabs(bxyz[0] - bxyz_std[0][i])/bxyz[0] > 0.00001) << ", "
+                      << int(fabs(bxyz[1] - bxyz_std[1][i])/bxyz[1] > 0.00001) << ", "
+                      << int(fabs(bxyz[2] - bxyz_std[2][i])/bxyz[2] > 0.00001) 
+                      << std::endl;
+
+            if (fabs(bxyz[0] - bxyz_std[0][i]) > 0.00001) {
+                std::cout << "failed bz comparison - bz, bz std " << bxyz[0] << ", " << bxyz_std[0][i] << std::endl;
+                status = 1;
+            }
+            if (fabs(bxyz[1] - bxyz_std[1][i]) > 0.00001) {
+                std::cout << "failed br comparison" << std::endl;
+                std::cout << "failed br comparison - br, br std " << bxyz[1] << ", " << bxyz_std[1][i] << std::endl;
+                status = 1;
+            }
+            if (fabs(bxyz[2] - bxyz_std[2][i]) > 0.00001) {
+                std::cout << "failed bphi comparison" << std::endl;
+                std::cout << "failed bphi comparison - bphi, bphi std " << bxyz[2] << ", " << bxyz_std[2][i] << std::endl;
+                status = 1;
+            }
+            
+        }
+        
+        std::cout << "runTest: status " << status << std::endl;
+
+        return status;
+        
+    }
+
+private:
+};
+
+
+
+
+int main() {
+
+    std::cout << "start BFieldExample test" << std::endl;
+
+
+    BFieldTest bftest;
+    int status = bftest.runTest(true);
+
+    if (status == 0) {
+        std::cout << "Test passed OK" << std::endl;
+        return 0;
+    }
+    else {
+        std::cout << "Test failed" << std::endl;
+        return 1;
+    }
+    
+}