diff --git a/GeoModelCore/GeoModelHelpers/GeoModelHelpers/cloneVolume.h b/GeoModelCore/GeoModelHelpers/GeoModelHelpers/cloneVolume.h
new file mode 100644
index 0000000000000000000000000000000000000000..944e1a0c4238eb4250e84c897278885906791234
--- /dev/null
+++ b/GeoModelCore/GeoModelHelpers/GeoModelHelpers/cloneVolume.h
@@ -0,0 +1,18 @@
+/*
+  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
+*/
+#ifndef GEOMODELUTILS_CLONEVOLUME_H
+#define GEOMODELUTILS_CLONEVOLUME_H
+#include "GeoModelKernel/GeoVPhysVol.h"
+
+
+/** @brief Creates a deep copy of the physical volume if the volume hosts full physical volumes in its subtrees
+ *         or if the allowShared flag is disabled. GeoNameTags, GeoTransforms etc. are appended to the new 
+ *         physical volume
+ * @param volume: Link to the Volume to clone
+ * @param allowShared: Switch to allow that GeoPhysVols that don't host GeoFullPhysVols are simply moved to the copied 
+ *                     volume and hence become shared objects.
+*/
+PVLink cloneVolume(PVLink volume,  bool allowShared = true);
+
+#endif
diff --git a/GeoModelCore/GeoModelHelpers/GeoModelHelpers/getChildNodesWithTrf.h b/GeoModelCore/GeoModelHelpers/GeoModelHelpers/getChildNodesWithTrf.h
index 78e79a6b8e599fbcc2ba08eaaeb1312ac84af443..f8818abcf9398a608f7a2e93e45e954a2ddad447 100644
--- a/GeoModelCore/GeoModelHelpers/GeoModelHelpers/getChildNodesWithTrf.h
+++ b/GeoModelCore/GeoModelHelpers/GeoModelHelpers/getChildNodesWithTrf.h
@@ -32,8 +32,15 @@ struct GeoChildNodeWithTrf {
         GeoChildNodeWithTrf(GeoVolumeCursor& curs);
 };
 
-std::vector <GeoChildNodeWithTrf> getChildrenWithRef (PVConstLink& physVol,
+std::vector <GeoChildNodeWithTrf> getChildrenWithRef (PVConstLink physVol,
                                                       bool summarizeEqualVol = true);
 
+/**
+ *  Returns whether a volume has fullPhysical volume nodes in 
+ *  it's children and grand children tree
+*/
+bool hasFullPhysVolInTree(PVConstLink physVol);
+
+
 
 #endif
\ No newline at end of file
diff --git a/GeoModelCore/GeoModelHelpers/src/cloneVolume.cxx b/GeoModelCore/GeoModelHelpers/src/cloneVolume.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..ef8fc56bb9fb835a3387e0e45ba5304744dcb759
--- /dev/null
+++ b/GeoModelCore/GeoModelHelpers/src/cloneVolume.cxx
@@ -0,0 +1,32 @@
+
+#include "GeoModelHelpers/cloneVolume.h"
+#include "GeoModelHelpers/getChildNodesWithTrf.h"
+
+#include "GeoModelKernel/GeoFullPhysVol.h"
+#include "GeoModelKernel/GeoPhysVol.h"
+
+PVLink cloneVolume(PVLink volume, 
+                   bool allowShared) {
+    PVLink newVolume{volume};
+    if (!allowShared || hasFullPhysVolInTree(volume)) {
+        if (typeid(*volume) == typeid(GeoPhysVol)) {
+            newVolume = new GeoPhysVol(volume->getLogVol());
+        } else if (typeid(*volume) == typeid(GeoFullPhysVol)) {
+            newVolume = new GeoFullPhysVol(volume->getLogVol());
+        }
+        for (unsigned int ch = 0; ch < volume->getNChildNodes(); ++ch){
+          const GeoGraphNode* node = (*volume->getChildNode(ch));
+          
+          if (typeid(*node) == typeid(GeoPhysVol) || typeid(*node) == typeid(GeoFullPhysVol)) {    
+            const GeoVPhysVol* childConstVol{static_cast<const GeoVPhysVol*>(node)};
+            GeoVPhysVol* childVol{const_cast<GeoVPhysVol*>(childConstVol)};
+            newVolume->add(cloneVolume(childVol, allowShared));
+          } else {
+            newVolume->add(const_cast<GeoGraphNode*>(node));
+          }
+        }
+        
+    }
+    return newVolume;
+    
+}
\ No newline at end of file
diff --git a/GeoModelCore/GeoModelHelpers/src/defineWorld.cxx b/GeoModelCore/GeoModelHelpers/src/defineWorld.cxx
index b28b918a7a3256e75c41ef2523d96fb4ec491319..ebf851eaffd7f0fc4e5229094280c474ee5c1e00 100644
--- a/GeoModelCore/GeoModelHelpers/src/defineWorld.cxx
+++ b/GeoModelCore/GeoModelHelpers/src/defineWorld.cxx
@@ -2,6 +2,7 @@
   Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
 */
 #include "GeoModelHelpers/defineWorld.h"
+#include "GeoModelHelpers/cloneVolume.h"
 #include "GeoModelKernel/GeoElement.h"
 #include "GeoModelKernel/GeoMaterial.h"
 #include "GeoModelKernel/GeoBox.h"
@@ -42,97 +43,52 @@ GeoIntrusivePtr<GeoPhysVol> createGeoWorld(const double worldBoxX,
     return world;    
 }
 
-GeoIntrusivePtr<GeoPhysVol> resizeGeoWorld(GeoIntrusivePtr<GeoPhysVol> world)
-{
-    if (world)
-    {
-        //resize the world volume to the real needed volume
-        
-        // get number of children volumes
-        unsigned int nChild=world->getNChildVols();
-        
-        //Dimensions of the bounding boxes
-        double xmin=0.,ymin=0.,zmin=0.,xmax=0.,ymax=0.,zmax=0.;
-        double xworld=0.,yworld=0.,zworld=0.;
+GeoIntrusivePtr<GeoPhysVol> resizeGeoWorld(GeoIntrusivePtr<GeoPhysVol> world) {
+    if (!world) return world;
+
+    //resize the world volume to the real needed volume
+    
+    // get number of children volumes
+    unsigned int nChild=world->getNChildVols();
+    
+    //Dimensions of the bounding boxes
+    double xmin=0.,ymin=0.,zmin=0.,xmax=0.,ymax=0.,zmax=0.;
+    double xworld=0.,yworld=0.,zworld=0.;
         
-        // loop over all children volumes
-        for (unsigned int i=0; i<nChild; i++)
+    // loop over all children volumes
+    for (unsigned int i=0; i<nChild; i++) {
+        PVConstLink nodeLink = world->getChildVol(i);
+        if ( dynamic_cast<const GeoVPhysVol*>( &(*( nodeLink ))) )
         {
-            PVConstLink nodeLink = world->getChildVol(i);
-            if ( dynamic_cast<const GeoVPhysVol*>( &(*( nodeLink ))) )
-            {
-                const GeoVPhysVol *childVolV = &(*( nodeLink ));
-                
-                if ( dynamic_cast<const GeoPhysVol*>(childVolV) ) {
-                    const GeoPhysVol* childVol = dynamic_cast<const GeoPhysVol*>(childVolV);
-                    childVol->getLogVol()->getShape()->extent(xmin, ymin, zmin, xmax, ymax, zmax);
-                }
-                else if ( dynamic_cast<const GeoFullPhysVol*>(childVolV) ) {
-                    const GeoFullPhysVol* childVol = dynamic_cast<const GeoFullPhysVol*>(childVolV);
-                    childVol->getLogVol()->getShape()->extent(xmin, ymin, zmin, xmax, ymax, zmax);
-                   
-                }
-                xworld=std::max({xworld,std::abs(xmin),std::abs(xmax)});
-                yworld=std::max({yworld,std::abs(ymin),std::abs(ymax)});
-                zworld=std::max({zworld,std::abs(zmin),std::abs(zmax)});
-            }
-        }
-
-        GeoIntrusivePtr<GeoPhysVol> resizedWorld{createGeoWorld(xworld, yworld, zworld)};
-       
-        for (unsigned int i=0; i< world->getNChildNodes(); i++){
-            const GeoGraphNode * node = *(world->getChildNode(i));
-            
-            
-            if (dynamic_cast<const GeoVPhysVol*>( node ))
-            {
-                if ( dynamic_cast<const GeoFullPhysVol*>(node) ){
-                    const GeoFullPhysVol* nodeFullPhysVol = dynamic_cast<const GeoFullPhysVol*>(node);
-                    resizedWorld->add((GeoGraphNode *)nodeFullPhysVol);
-                    
-                }
-                else  if ( dynamic_cast<const GeoPhysVol*>(node) ){
-                    const GeoPhysVol* nodePhysVol = dynamic_cast<const GeoPhysVol*>(node);
-                    resizedWorld->add((GeoGraphNode *)nodePhysVol);
-                    
-                }
-            }
-            else if (dynamic_cast<const GeoNameTag*>( node )){
-                const GeoNameTag* nodeTag = dynamic_cast<const GeoNameTag*>(node);
-                resizedWorld->add((GeoGraphNode *)nodeTag);
-                
-            }
+            const GeoVPhysVol *childVolV = &(*( nodeLink ));
             
-            else if (dynamic_cast<const GeoAlignableTransform*>( node )){
-                const GeoAlignableTransform* nodeAT = dynamic_cast<const GeoAlignableTransform*>(node);
-                resizedWorld->add((GeoGraphNode *)nodeAT);
-                
+            if ( dynamic_cast<const GeoPhysVol*>(childVolV) ) {
+                const GeoPhysVol* childVol = dynamic_cast<const GeoPhysVol*>(childVolV);
+                childVol->getLogVol()->getShape()->extent(xmin, ymin, zmin, xmax, ymax, zmax);
             }
-            
-            else if (dynamic_cast<const GeoSerialTransformer*>( node )){
-                const GeoSerialTransformer* nodeST = dynamic_cast<const GeoSerialTransformer*>(node);
-                resizedWorld->add((GeoGraphNode *)nodeST);
-                
-            }
-            
-            else if (dynamic_cast<const GeoSerialDenominator*>( node )){
-                const GeoSerialDenominator* nodeSD = dynamic_cast<const GeoSerialDenominator*>(node);
-                resizedWorld->add((GeoGraphNode *)nodeSD);
-                
-            }
-            else if (dynamic_cast<const GeoTransform*>( node )){
-                const GeoTransform* nodeTransform = dynamic_cast<const GeoTransform*>(node);
-                resizedWorld->add((GeoGraphNode *)nodeTransform);
-                
-            }else if (dynamic_cast<const GeoIdentifierTag*>( node )){
-                const GeoIdentifierTag* nodeIT = dynamic_cast<const GeoIdentifierTag*>(node);
-                resizedWorld->add((GeoGraphNode *)nodeIT);
+            else if ( dynamic_cast<const GeoFullPhysVol*>(childVolV) ) {
+                const GeoFullPhysVol* childVol = dynamic_cast<const GeoFullPhysVol*>(childVolV);
+                childVol->getLogVol()->getShape()->extent(xmin, ymin, zmin, xmax, ymax, zmax);
                 
             }
+            xworld=std::max({xworld,std::abs(xmin),std::abs(xmax)});
+            yworld=std::max({yworld,std::abs(ymin),std::abs(ymax)});
+            zworld=std::max({zworld,std::abs(zmin),std::abs(zmax)});
         }
-
-        return resizedWorld;
-        
     }
-    return world;
+
+    GeoIntrusivePtr<GeoPhysVol> resizedWorld{createGeoWorld(xworld, yworld, zworld)};
+    for (unsigned int ch = 0; ch < world->getNChildNodes(); ++ch) {
+        const GeoGraphNode * node = *(world->getChildNode(ch));
+        if (typeid(*node) == typeid(GeoFullPhysVol) ||
+            typeid(*node) == typeid(GeoPhysVol)) {
+            const GeoVPhysVol* subVol{dynamic_cast<const GeoVPhysVol*>(node)};
+            GeoVPhysVol* nonConstVol{const_cast<GeoVPhysVol*>(subVol)};
+            resizedWorld->add(cloneVolume(nonConstVol));
+        } else {
+            resizedWorld->add(const_cast<GeoGraphNode*>(node));
+        }
+    }  
+ 
+    return resizedWorld;
 }
diff --git a/GeoModelCore/GeoModelHelpers/src/getChildNodesWithTrf.cxx b/GeoModelCore/GeoModelHelpers/src/getChildNodesWithTrf.cxx
index cc16ee76af27c4f6934cefae40ab664a5fe2e2a1..91389b27acf0a9865133fd84f4108e25d4100f83 100644
--- a/GeoModelCore/GeoModelHelpers/src/getChildNodesWithTrf.cxx
+++ b/GeoModelCore/GeoModelHelpers/src/getChildNodesWithTrf.cxx
@@ -26,7 +26,7 @@ namespace {
     }
 }
 
-std::vector <GeoChildNodeWithTrf> getChildrenWithRef(PVConstLink& physVol,
+std::vector <GeoChildNodeWithTrf> getChildrenWithRef(PVConstLink physVol,
                                                      bool summarizeEqualVol) {
     std::vector<GeoChildNodeWithTrf> children{};
  
@@ -64,3 +64,14 @@ std::vector <GeoChildNodeWithTrf> getChildrenWithRef(PVConstLink& physVol,
     }
     return children;
 }
+bool hasFullPhysVolInTree(PVConstLink physVol) {
+    if (typeid(*physVol) == typeid(GeoFullPhysVol) ||
+        typeid(*physVol) == typeid(GeoVFullPhysVol)){
+        return true;
+    }
+    for (unsigned int ch = 0; ch < physVol->getNChildVols(); ++ch) {
+        if (hasFullPhysVolInTree(physVol->getChildVol(ch))) return true;
+    }
+
+    return false;
+}
\ No newline at end of file