diff --git a/InnerDetector/InDetDetDescr/InDetGeoModelUtils/InDetGeoModelUtils/GeoNodePtr.h b/InnerDetector/InDetDetDescr/InDetGeoModelUtils/InDetGeoModelUtils/GeoNodePtr.h
index 20ebfcff530c465d1465e032e19e6af9b40efe1b..73fb8f3fbe0343263c8936f9fc90c515f304aaa2 100644
--- a/InnerDetector/InDetDetDescr/InDetGeoModelUtils/InDetGeoModelUtils/GeoNodePtr.h
+++ b/InnerDetector/InDetDetDescr/InDetGeoModelUtils/InDetGeoModelUtils/GeoNodePtr.h
@@ -1,65 +1,13 @@
 /*
-  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
 */
 #ifndef _GeoNodePtr_H_
 #define _GeoNodePtr_H_
 
 #include <iostream>
 
-// Smart pointer for reference counted GeoModel objects
-template <class T>
-class GeoNodePtr {
-   static T *ref(T *obj)   { if (obj) obj->ref();   return obj;}
-   static T *unref(T *obj) { if (obj) obj->unref(); return obj;}
-public:
-   using T_Ptr=T*;
-   using T_ConstPtr=const T * ;
-
-   GeoNodePtr() = default;
-   GeoNodePtr(T *obj)
-      : m_obj(ref(obj))
-   { }
-
-   ~GeoNodePtr()
-   { unref(m_obj); }
-
-   // copy
-   GeoNodePtr(const GeoNodePtr<T> &node_ptr)
-      : m_obj( ref( node_ptr->m_obj() ) )
-      { }
-
-   GeoNodePtr<T> &operator=(const GeoNodePtr<T> &node_ptr) {
-      if (node_ptr->m_obj != m_obj) {
-         unref(m_obj);
-         m_obj=ref(node_ptr->m_obj);
-      }
-      return *this;
-   }
-   GeoNodePtr<T> &operator=(T *obj) {
-      if (obj != m_obj) {
-         unref(m_obj);
-         m_obj=ref(obj);
-      }
-      return *this;
-   }
-
-   // move
-   GeoNodePtr(GeoNodePtr<T> &&node_ptr) : m_obj(node_ptr->m_obj) { node_ptr->m_obj=nullptr; }
-   GeoNodePtr<T> &operator=(GeoNodePtr<T> &&node_ptr) {
-      m_obj           = node_ptr->m_obj;
-      node_ptr->m_obj = nullptr;
-      return *this;
-   }
-
-   operator bool()  const      { return m_obj != nullptr; }
-   operator T_Ptr()            { return m_obj; }
-   T_ConstPtr get() const      { return m_obj; }
-
-   T *operator->()             { assert(m_obj); return m_obj; }
-   const T *operator->() const { assert(m_obj); return m_obj; }
-
-private:
-   T *m_obj = nullptr;
-};
+#include "GeoModelKernel/GeoIntrusivePtr.h"
 
+template <class T>
+using GeoNodePtr = GeoIntrusivePtr<T>;
 #endif
diff --git a/InnerDetector/InDetDetDescr/InDetGeoModelUtils/InDetGeoModelUtils/InDetMaterialManager.h b/InnerDetector/InDetDetDescr/InDetGeoModelUtils/InDetGeoModelUtils/InDetMaterialManager.h
index c63f68ee445b4ab569ec97ccfd760247e9cf4a8b..9bfd2672a4b2a7b3d35d36191b6fb90961c671b6 100755
--- a/InnerDetector/InDetDetDescr/InDetGeoModelUtils/InDetGeoModelUtils/InDetMaterialManager.h
+++ b/InnerDetector/InDetDetDescr/InDetGeoModelUtils/InDetGeoModelUtils/InDetMaterialManager.h
@@ -7,8 +7,9 @@
 
 #include "AthenaBaseComps/AthMessaging.h"
 #include "RDBAccessSvc/IRDBAccessSvc.h"
+#include "GeoModelKernel/GeoIntrusivePtr.h"
+#include "GeoModelKernel/GeoMaterial.h"
 
-class GeoMaterial;
 class GeoElement;
 class StoredMaterialManager;
 class StoreGateSvc;
@@ -211,7 +212,7 @@ private:
   StoredMaterialManager *m_materialManager;
   std::string m_managerName;
 
-  typedef std::map<std::string, const GeoMaterial *> MaterialStore;
+  using MaterialStore = std::map<std::string, GeoIntrusivePtr<const GeoMaterial>>;
   MaterialStore m_store;
 
   typedef std::map<std::string, MaterialByWeight > MaterialWeightMap;
diff --git a/InnerDetector/InDetDetDescr/InDetGeoModelUtils/InDetGeoModelUtils/ServiceVolume.h b/InnerDetector/InDetDetDescr/InDetGeoModelUtils/InDetGeoModelUtils/ServiceVolume.h
index 60fbd00e60697049b740783bcc02840feaab0596..0afacbc0779a7de42f3abc35b3e3e89c7a405993 100755
--- a/InnerDetector/InDetDetDescr/InDetGeoModelUtils/InDetGeoModelUtils/ServiceVolume.h
+++ b/InnerDetector/InDetDetDescr/InDetGeoModelUtils/InDetGeoModelUtils/ServiceVolume.h
@@ -6,7 +6,8 @@
 #define InDetDD_ServiceVolume_H
 
 #include "CxxUtils/checker_macros.h"
-
+#include "GeoModelKernel/GeoShape.h"
+#include "GeoModelKernel/GeoIntrusivePtr.h"
 #include <cmath>
 #include <mutex>
 #include <string>
@@ -18,20 +19,7 @@ namespace InDetDD {
 
   // class to hold GeoShape pointer. This takes care of the GeoShape ref counting and 
   // avoids needing to write a copy constructor for ServiceVolume
-  class GeoShapeHolder {
-  public:
-    GeoShapeHolder(); 
-    GeoShapeHolder(const GeoShape *); 
-    GeoShapeHolder(const GeoShapeHolder &);
-    GeoShapeHolder & operator=(const GeoShapeHolder &);
-    GeoShapeHolder & operator=(GeoShapeHolder &&) noexcept;
-    ~GeoShapeHolder(); 
-    const GeoShape * get() const {return m_geoShape;}
-    void set(const GeoShape *);
-    void reset();
-  private:
-    const GeoShape * m_geoShape;
-  };
+  using GeoShapeHolder = GeoIntrusivePtr<const GeoShape>;
   
   class ServiceVolume {
 
diff --git a/InnerDetector/InDetDetDescr/InDetGeoModelUtils/InDetGeoModelUtils/VolumeBuilder.h b/InnerDetector/InDetDetDescr/InDetGeoModelUtils/InDetGeoModelUtils/VolumeBuilder.h
index 9e08b77013199594d9266a9dc1755624d6eb8566..70ae0ead6bb513a095452557a9c7d9cbf46c6cb6 100644
--- a/InnerDetector/InDetDetDescr/InDetGeoModelUtils/InDetGeoModelUtils/VolumeBuilder.h
+++ b/InnerDetector/InDetDetDescr/InDetGeoModelUtils/InDetGeoModelUtils/VolumeBuilder.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef InDetGeoModelUtils_VolumeBuilder_H
@@ -9,13 +9,13 @@
 #include "InDetGeoModelUtils/VolumeSplitterUtils.h"
 #include "InDetGeoModelUtils/VolumeSplitter.h"
 
+#include "GeoModelKernel/GeoPhysVol.h"
+#include "GeoModelKernel/GeoFullPhysVol.h"
+
 #include <string>
 #include <vector>
 
 class InDetMaterialManager;
-class GeoPhysVol;
-class GeoFullPhysVol;
-class GeoVPhysVol;
 class GeoTransform;
 class GeoShape;
 
@@ -41,7 +41,8 @@ namespace InDetDD {
     void buildAndPlaceEnvelope(const std::string & region, GeoFullPhysVol * parent, int iParent, int iElement, double zcenter = 0);
     void buildAndPlaceEnvelope(const std::string & region, GeoPhysVol * parent, int iParent, int iElement, double zcenter = 0);
     void addServices(const Zone & zone, const std::vector<const ServiceVolume * > & services);
-    GeoVPhysVol* build(int iElement);
+    using PhysVolPtr = GeoIntrusivePtr<GeoPhysVol>; 
+    PhysVolPtr build(int iElement);
     int numCopies(int iElement);
     GeoTransform * getPlacement(int iElement, int iCopy);
     GeoTransform * getPlacementEnvelope(int iElement, int iCopy,  int iMothElement);
diff --git a/InnerDetector/InDetDetDescr/InDetGeoModelUtils/src/InDetMaterialManager.cxx b/InnerDetector/InDetDetDescr/InDetGeoModelUtils/src/InDetMaterialManager.cxx
index a48771b32c389fc4179fcaa5761d9dab49cfcdaf..981e767a0a5facf7b9582c4b585fe57c202a4ffd 100755
--- a/InnerDetector/InDetDetDescr/InDetGeoModelUtils/src/InDetMaterialManager.cxx
+++ b/InnerDetector/InDetDetDescr/InDetGeoModelUtils/src/InDetMaterialManager.cxx
@@ -5,6 +5,7 @@
 #include "InDetGeoModelUtils/InDetMaterialManager.h"
 #include "InDetGeoModelUtils/InDetDDAthenaComps.h"
 #include "GeoModelInterfaces/StoredMaterialManager.h"
+#include "GeoModelKernel/GeoIntrusivePtr.h"
 #include "GeoModelKernel/GeoMaterial.h"
 #include "GeoModelKernel/GeoElement.h"
 #include "GeoModelKernel/Units.h"
@@ -74,13 +75,7 @@ InDetMaterialManager::InDetMaterialManager(const std::string& managerName,
   addTextFileMaterials();
 }
 
-InDetMaterialManager::~InDetMaterialManager() {
-  // Dereference the materials.
-  MaterialStore::const_iterator iter;
-  for (iter = m_store.begin(); iter != m_store.end(); ++iter) {
-    iter->second->unref();
-  }
-}
+InDetMaterialManager::~InDetMaterialManager() = default;
 
 inline StoredMaterialManager*
 InDetMaterialManager::retrieveManager(const StoreGateSvc* detStore) {
@@ -302,17 +297,15 @@ InDetMaterialManager::getMaterialScaledInternal(const std::string& origMaterialN
 
 void
 InDetMaterialManager::addMaterial(GeoMaterial* material) {
+  GeoIntrusivePtr<const GeoMaterial> matPtr{material};
   std::string name(material->getName());
   if (m_store.find(name) != m_store.end()) {
     ATH_MSG_WARNING("Ignoring attempt to redefine an existing material: " << name);
     // Delete the material if it is not already ref counted.
-    material->ref();
-    material->unref();
     //std::cout << m_store[name] << std::endl;
   } else {
     material->lock();
-    material->ref();
-    m_store[name] = material;
+    m_store[name] = matPtr;
 
     ATH_MSG_DEBUG("Created new material: " << name << ", " << material->getDensity() /
                   (Gaudi::Units::g / Gaudi::Units::cm3) << " g/cm3");
@@ -883,7 +876,7 @@ InDetMaterialManager::createMaterial(const MaterialDef& material) {
     }
   }
   // Now build the material
-  GeoMaterial* newMaterial = new GeoMaterial(material.name(), material.density());
+  GeoIntrusivePtr<GeoMaterial> newMaterial{new GeoMaterial(material.name(), material.density())};
   ATH_MSG_DEBUG("Creating material: " << material.name() << " with density: "
                 << material.density() / (Gaudi::Units::g / Gaudi::Units::cm3));
   for (unsigned int i = 0; i < material.numComponents(); i++) {
@@ -893,8 +886,6 @@ InDetMaterialManager::createMaterial(const MaterialDef& material) {
       if (!element) {
         ATH_MSG_ERROR("Error making material " << material.name() << ". Element not found: " << material.compName(i));
         // delete the partially created material
-        newMaterial->ref();
-        newMaterial->unref();
         return;
       }
       if (byAtomicRatio) {
@@ -903,19 +894,17 @@ InDetMaterialManager::createMaterial(const MaterialDef& material) {
       newMaterial->add(const_cast<GeoElement*>(element), fracWeight);
       ATH_MSG_DEBUG(" Component: " << material.compName(i) << " " << fracWeight);
     } else {
-      const GeoMaterial* materialTmp = getMaterialInternal(material.compName(i));
+      GeoIntrusivePtr<const GeoMaterial> materialTmp{getMaterialInternal(material.compName(i))};
       if (!materialTmp) {
         ATH_MSG_ERROR("Error making material " << material.name() << ". Component not found: " << material.compName(i));
         // delete the partially created material
-        newMaterial->ref();
-        newMaterial->unref();
         return;
       }
       if (byAtomicRatio) {
         // Should not happen as already checked that all components were elements.
         ATH_MSG_ERROR("Unexpected Error");
       }
-      newMaterial->add(const_cast<GeoMaterial*>(materialTmp), fracWeight);
+      newMaterial->add(const_cast<GeoMaterial*>(materialTmp.get()), fracWeight);
       ATH_MSG_DEBUG(" Component: " << material.compName(i) << " " << fracWeight);
     }
   }
diff --git a/InnerDetector/InDetDetDescr/InDetGeoModelUtils/src/ServiceVolume.cxx b/InnerDetector/InDetDetDescr/InDetGeoModelUtils/src/ServiceVolume.cxx
index 13c975be9d110714c1cf207c7fc08aa46d9fe9bc..f42a6c9810ff81540ea17e24ea9c352989196d18 100755
--- a/InnerDetector/InDetDetDescr/InDetGeoModelUtils/src/ServiceVolume.cxx
+++ b/InnerDetector/InDetDetDescr/InDetGeoModelUtils/src/ServiceVolume.cxx
@@ -320,7 +320,7 @@ namespace InDetDD {
     if (!volume && serviceShape != nullptr) volume = serviceShape->volume();
 
     m_volume = volume;
-    m_geoShape.set(serviceShape);
+    m_geoShape = serviceShape;
     return serviceShape;
   }
 
@@ -340,7 +340,7 @@ namespace InDetDD {
       // We allow a volume to specified as the volume calculation for some shapes (ie boolean volumes) are unreliable.
       // If volume is not supplied, get it from the shape itself.
       if (!m_volume) m_volume = geoShape->volume();
-      m_geoShape.set(geoShape);
+      m_geoShape = geoShape;
       m_lockGeoShape = true; // This disables resetGeoShape().
       setShapeType("CUSTOM");
     } else {
@@ -366,56 +366,4 @@ namespace InDetDD {
     }
   }
 
-  GeoShapeHolder::GeoShapeHolder()
-    : m_geoShape(nullptr)
-  {}
-
-  GeoShapeHolder::GeoShapeHolder(const GeoShape* geoShape)
-    : m_geoShape(geoShape) {
-    if (m_geoShape) m_geoShape->ref();
-  }
-
-  GeoShapeHolder::~GeoShapeHolder() {
-    reset();
-  }
-
-  GeoShapeHolder::GeoShapeHolder(const GeoShapeHolder& rhs) {
-    m_geoShape = rhs.m_geoShape;
-    if (m_geoShape) m_geoShape->ref();
-  }
-
-  GeoShapeHolder&
-  GeoShapeHolder::operator = (const GeoShapeHolder& rhs) {
-    if (&rhs != this) {
-      reset();
-      m_geoShape = rhs.m_geoShape;
-      if (m_geoShape) m_geoShape->ref();
-    }
-    return *this;
-  }
-  
-  GeoShapeHolder&
-  GeoShapeHolder::operator = (GeoShapeHolder&& rhs)  noexcept {
-    if (&rhs != this) {
-      if (m_geoShape) m_geoShape->unref();//this geoshape will be overwritten, so decrement its reference
-      m_geoShape = rhs.m_geoShape; //simply equate the pointers
-      rhs.m_geoShape=nullptr;      //render the original unusable for safety
-      //if (m_geoShape) m_geoShape->ref(); << no need to increment the reference; the original is moved here
-      //                                      with its original refcount intact.
-    }
-    return *this;
-  }
-
-  void
-  GeoShapeHolder::set(const GeoShape* geoShape) {
-    reset();
-    m_geoShape = geoShape;
-    if (m_geoShape) m_geoShape->ref();
-  }
-
-  void
-  GeoShapeHolder::reset() {
-    if (m_geoShape) m_geoShape->unref();
-    m_geoShape = nullptr;
-  }
 } // end namespace
diff --git a/InnerDetector/InDetDetDescr/InDetGeoModelUtils/src/VolumeBuilder.cxx b/InnerDetector/InDetDetDescr/InDetGeoModelUtils/src/VolumeBuilder.cxx
index 8833482bcd20247f8fa1f252e0e440c768054902..9ba6cbf20ee42a093bfaf7798f6bcbaf68e0dbc6 100755
--- a/InnerDetector/InDetDetDescr/InDetGeoModelUtils/src/VolumeBuilder.cxx
+++ b/InnerDetector/InDetDetDescr/InDetGeoModelUtils/src/VolumeBuilder.cxx
@@ -14,7 +14,9 @@
 #include "GeoModelKernel/GeoDefinitions.h"
 #include "GaudiKernel/SystemOfUnits.h"
 
+
 namespace InDetDD {
+  using PhysVolPtr = VolumeBuilder::PhysVolPtr;
   VolumeBuilder::VolumeBuilder(const Zone& zone, const std::vector<const ServiceVolume* >& services)
     : AthMessaging("InDetDDVolumeBuilder"),
     m_region("None"), // Empty refers to a valid region. Set some default so we can check it is actually set.
@@ -83,14 +85,12 @@ namespace InDetDD {
     setRegion(region, zcenter);
     for (unsigned int iElement = 0; iElement < services().size(); ++iElement)
       if (!isEnvelopeOrChild(iElement)) {
-        GeoVPhysVol* physVol = build(iElement);
+        PhysVolPtr physVol{build(iElement)};
         if (physVol) {
-          physVol->ref();
           for (int iCopy = 0; iCopy < numCopies(iElement); ++iCopy) {
             parent->add(getPlacement(iElement, iCopy));
             parent->add(physVol);
           }
-          physVol->unref();//should delete if never added
         }
       }
   }
@@ -101,15 +101,12 @@ namespace InDetDD {
     setRegion(region, zcenter);
     for (unsigned int iElement = 0; iElement < services().size(); ++iElement) {
       if (!isEnvelopeOrChild(iElement)) {
-        //    GeoVPhysVol* physVol = build(iElement);
-        GeoVPhysVol* physVol = build(iElement);
+        PhysVolPtr physVol{build(iElement)};
         if (physVol) {
-          physVol->ref();
           for (int iCopy = 0; iCopy < numCopies(iElement); ++iCopy) {
             parent->add(getPlacement(iElement, iCopy));
             parent->add(physVol);
           }
-          physVol->unref();//should delete if never used
         }
       }
     }
@@ -126,9 +123,8 @@ namespace InDetDD {
   void
   VolumeBuilder::buildAndPlaceEnvelope(const std::string& region, GeoFullPhysVol* parent, int iParent, int iElement,
                                        double zcenter) {
-    GeoPhysVol* physVol = dynamic_cast<GeoPhysVol*>(build(iElement));
+    PhysVolPtr physVol{build(iElement)};
     if (physVol) {
-      physVol->ref();
       for (unsigned int iChild = 0; iChild < services().size(); ++iChild) {
         if (isChildService(iElement, iChild) && services()[iChild]->envelopeNum() > 0) {
           // if volume is a child volume : build and place it
@@ -138,14 +134,12 @@ namespace InDetDD {
       for (unsigned int iChild = 0; iChild < services().size(); ++iChild) {
         if (isChildService(iElement, iChild) && services()[iChild]->envelopeNum() == 0) {
           // if volume is not a child volume
-          GeoVPhysVol* physVol_child = build(iChild);
+          PhysVolPtr physVol_child{build(iChild)};
           if (physVol_child) {
-            physVol_child->ref();
             for (int iCopy2 = 0; iCopy2 < numCopies(iChild); ++iCopy2) {
               physVol->add(getPlacementEnvelope(iChild, iCopy2, iElement));
               physVol->add(physVol_child);
             }
-            physVol_child->unref();//should delete if was never added
           }
         }
       }
@@ -155,16 +149,14 @@ namespace InDetDD {
         else parent->add(getPlacementEnvelope(iElement, iCopy, iParent));
         parent->add(physVol);
       }
-      physVol->unref(); ///should delete even if it was never added
     }
   }
 
   void
   VolumeBuilder::buildAndPlaceEnvelope(const std::string& region, GeoPhysVol* parent, int iParent, int iElement,
                                        double zcenter) {
-    GeoPhysVol* physVol = dynamic_cast<GeoPhysVol*>(build(iElement));
+    PhysVolPtr physVol{build(iElement)};
     if (physVol) {
-      physVol->ref();
       for (unsigned int iChild = 0; iChild < services().size(); ++iChild) {
         if (isChildService(iElement, iChild) && services()[iChild]->envelopeNum() > 0) {
           // if volume is a child volume : build and place it
@@ -174,14 +166,12 @@ namespace InDetDD {
       for (unsigned int iChild = 0; iChild < services().size(); ++iChild) {
         if (isChildService(iElement, iChild) && services()[iChild]->envelopeNum() == 0) {
           // if volume is not a child volume
-          GeoVPhysVol* physVol_child = build(iChild);
+          PhysVolPtr physVol_child{build(iChild)};
           if (physVol_child) {
-            physVol_child->ref();
             for (int iCopy2 = 0; iCopy2 < numCopies(iChild); ++iCopy2) {
               physVol->add(getPlacementEnvelope(iChild, iCopy2, iElement));
               physVol->add(physVol_child);
             }
-            physVol_child->unref(); //will delete physVol_child if never used
           }
         }
       }
@@ -191,12 +181,10 @@ namespace InDetDD {
         else parent->add(getPlacementEnvelope(iElement, iCopy, iParent));
         parent->add(physVol);
       }
-      physVol->unref();//will delete physvol if it was never used
     }
   }
 
-  GeoVPhysVol*
-  VolumeBuilder::build(int iElement) {
+  PhysVolPtr VolumeBuilder::build(int iElement) {
     if (m_region == "None") {
       ATH_MSG_ERROR("No region set. Cannot build services");
       return nullptr;
@@ -236,7 +224,7 @@ namespace InDetDD {
     // Or use volume of original volume in param.
     //const GeoMaterial* serviceMat = mat_mgr->getMaterialForVolume(param.material(),param.origVolume());
     GeoLogVol* serviceLog = new GeoLogVol(logName, serviceShape, serviceMat);
-    GeoPhysVol* servicePhys = new GeoPhysVol(serviceLog);
+    PhysVolPtr servicePhys{new GeoPhysVol(serviceLog)};
     return servicePhys;
   }