diff --git a/GeoModelCore/GeoModelFuncSnippets/GeoModelFuncSnippets/MaterialManager.h b/GeoModelCore/GeoModelFuncSnippets/GeoModelFuncSnippets/MaterialManager.h new file mode 100755 index 0000000000000000000000000000000000000000..3110306f5251c736ff1620293b82049f4bb31b98 --- /dev/null +++ b/GeoModelCore/GeoModelFuncSnippets/GeoModelFuncSnippets/MaterialManager.h @@ -0,0 +1,128 @@ +/* + Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef GEO_MODEL_XML_MATERIAL_MANAGER_H +#define GEO_MODEL_XML_MATERIAL_MANAGER_H + +#include "GeoModelKernel/GeoMaterial.h" +#include "GeoModelKernel/GeoElement.h" +#include "GeoModelKernel/GeoIntrusivePtr.h" + +#include <memory> +#include <string> +#include <map> + + + +class MaterialManager { + + friend class Gmx2Geo; + + public: + + /// @brief Retrieve a GeoElement by name + const GeoElement* getElement(const std::string & name) const; + /// @brief Retrieve a GeoElement by number from the periodic table + const GeoElement* getElement(unsigned int atomicNumber) const; + /// @brief Creates a new GeoElement + /// @param name Name inside the GeoElement map + /// @param symbol Chemical symbol + /// @param z Number in the periodic table + /// @param a Atomic weight + void addElement(const std::string &name, + const std::string &symbol, + double z, + double a); + /// @brief Add a GeoElement* to the managed objects. If an element with the same name + /// has already been registered, then an exception is thrown + void addElement(GeoElement* elePtr); + /// @brief Returns whether the element is already registered + bool isElementDefined(const std::string& eleName) const; + + + /// @brief Returns the GeoMaterial by name. The name is expected to start with + /// a namespace. If the Material couldn't be found in the registry, the + /// current namespace is attempted to find the Material + /// @param name + /// @return + const GeoMaterial* getMaterial(const std::string & name) const; + + /// @brief Checks whether the matieral already exists in the database + bool isMaterialDefined(const std::string& matName) const; + + /// @brief Sets the name space underwich the following material are going to be added + void setMaterialNamespace(const std::string &name); + /// @brief Returns the current Material namespace + const std::string& materialNameSpace() const; + + /// @brief Dumps the complete content of the Material database + void printAll() const; + /// @brief Creates a new material called <name> with density + /// If the name contains ::, it's assumed that the prestring + /// Is part of another namespace as the current one. + void addMaterial(const std::string &name, double density); + + /// @brief Registers a new material to the database + void addMaterial(GeoMaterial* matPtr); + + /// @brief: Adds a new Material component to the current factory by name. + /// It's first checked whether the name corresponds to an element + /// in the Material database otherwise, the Element database is queried. + void addMatComponent(const std::string &name, double fraction); + + /// @brief Finalizes the Material definition in the current Material factory. + void lockMaterial(); + /// @brief Returns the singelton to this instance of the Material Manager + static MaterialManager* getManager(); + + virtual ~MaterialManager(); + + using ElementPtr = GeoIntrusivePtr<GeoElement>; + using ConstElementPtr = GeoIntrusivePtr<const GeoElement>; + using MaterialPtr = GeoIntrusivePtr<GeoMaterial>; + using ConstMaterialPtr = GeoIntrusivePtr<const GeoMaterial>; + + /// @brief Small helper struct to build complex materials + struct MaterialFactory { + + + ~MaterialFactory(); + MaterialFactory(MaterialPtr mat); + + void addComponent(ConstMaterialPtr mat, double fraction); + void addComponent(ConstElementPtr ele, double fraction); + + const GeoMaterial* get() const; + private: + using ElementComponent = std::pair<ConstElementPtr, double>; + std::vector<ElementComponent> m_components{}; + double m_totFraction{0.}; + MaterialPtr m_material{}; + }; + + protected: + MaterialManager(); + static MaterialManager* s_instance; + private: + // Map of elements indexed by Name + using ElementMap = std::map<std::string, ElementPtr>; + ElementMap m_elements{}; + + /// Map of materials indexed by fully qualified name Namespace::MaterialName + using MaterialMap = std::map<std::string, MaterialPtr>; + MaterialMap m_materials{}; + + /// @brief The namespace under which all materials are being added + /// to the Manager. The namespace is as well used if the + /// Material cannot be found in the MaterialMap. Then + /// it's prepended to the material name + std::string m_currentNameSpace{}; + + // Build special materials + void buildSpecialMaterials(); + + std::unique_ptr<MaterialFactory> m_factory{}; +}; + +#endif diff --git a/GeoModelCore/GeoModelFuncSnippets/src/MaterialManager.cxx b/GeoModelCore/GeoModelFuncSnippets/src/MaterialManager.cxx new file mode 100644 index 0000000000000000000000000000000000000000..e3179074e3501ffe7de019d1cc0c69bb4ef07d49 --- /dev/null +++ b/GeoModelCore/GeoModelFuncSnippets/src/MaterialManager.cxx @@ -0,0 +1,213 @@ +/* + Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration +*/ + +#include "GeoModelFuncSnippets/MaterialManager.h" + + +#include "GeoModelKernel/GeoIntrusivePtr.h" +#include "GeoModelKernel/GeoElement.h" +#include "GeoModelKernel/GeoMaterial.h" +#include "GeoModelKernel/Units.h" + +#include "GeoModelFuncSnippets/throwExcept.h" +#include "GeoModelFuncSnippets/StringUtils.h" + +#include <cstdlib> +#include <iomanip> +#include <stdio.h> +#include <iostream> + +namespace { + std::string replaceDColon(const std::string& name) { + return GeoStrUtils::replaceExpInString(name, "__dColon__", "::"); + } + constexpr double atomicDensity = GeoModelKernelUnits::gram / GeoModelKernelUnits::mole; + constexpr double volDensity = GeoModelKernelUnits::gram / GeoModelKernelUnits::cm3; + constexpr double invAtomicDensity = 1. / atomicDensity; + constexpr double invVolDensity = 1. / volDensity; +} + + +const GeoMaterial* MaterialManager::MaterialFactory::get() const { return m_material; } +MaterialManager::MaterialFactory::~MaterialFactory() { + if (!m_material) return; + // std::cout<<"MaterialFactory() -- finalize " <<m_material->getName()<<std::endl; + if (m_components.empty()) { + m_material->lock(); + return; + } + const double inv_totalFraction = 1. / m_totFraction; + for(const auto& [element, fraction] : m_components) { + m_material->add(element, + fraction * element->getA() * inv_totalFraction); + } + m_material->lock(); +} + +MaterialManager::MaterialFactory::MaterialFactory(MaterialPtr mat): + m_material{mat} { +} + +void MaterialManager::MaterialFactory::addComponent(ConstMaterialPtr mat, double fraction) { + for (unsigned int ele = 0 ; ele < mat->getNumElements(); ++ele) { + ConstElementPtr elePtr{mat->getElement(ele)}; + addComponent(elePtr, mat->getFraction(ele) * fraction); + } +} +void MaterialManager::MaterialFactory::addComponent(ConstElementPtr ele, + double fraction) { + m_components.emplace_back(std::make_pair(ele, fraction)); + m_totFraction += fraction; +} + +MaterialManager* MaterialManager::s_instance{nullptr}; + + +MaterialManager::MaterialManager() { + buildSpecialMaterials(); +} + +MaterialManager::~MaterialManager() { + s_instance = nullptr; +}; + +MaterialManager* MaterialManager::getManager() { + if(!s_instance) { + s_instance = new MaterialManager(); + } + return s_instance; +} + +bool MaterialManager::isMaterialDefined(const std::string& matName) const { + return m_materials.find(replaceDColon(matName))!= m_materials.end(); +} + +const GeoMaterial* MaterialManager::getMaterial(const std::string & name) const { + //std::cout << "Material Manager: attempt at retrieving material : "<<name<<std::endl; + // step 1 - check for simple name + const std::string matName = replaceDColon(name); + MaterialMap::const_iterator matItr = m_materials.find(matName); + if (matItr != m_materials.end()) { + return matItr->second; + } + // step 2 - check for material in namespace + std::string nameNS= m_currentNameSpace+"::"+matName; + matItr = m_materials.find(nameNS); + if (matItr != m_materials.end()) { + return matItr->second; + } + printAll(); + THROW_EXCEPTION("Could not find the material "<<matName); + return nullptr; +} + +const GeoElement* MaterialManager::getElement(const std::string & name) const { + ElementMap::const_iterator elementIt = m_elements.find(name); + return elementIt== m_elements.end() ? nullptr : elementIt->second; +} + +const GeoElement* MaterialManager::getElement(unsigned int atomicNumber) const { + for(const auto& [name, element]: m_elements) { + if((unsigned)(element->getZ())==atomicNumber) { + return element; + } + } + return nullptr; +} + +void MaterialManager::printAll() const { + std::cout << "============Material Manager Element List========================" << std::endl; + + for (const auto&[ name, el] : m_elements) { + std::cout << el->getSymbol() << '\t' << el->getZ() << '\t' + << el->getA() * invAtomicDensity << '\t' <<name << std::endl; + } + for (const auto&[material, mat]: m_materials) { + std::cout << "Material: " << material << " Density " << mat->getDensity() * invVolDensity << std::endl; + for (size_t i = 0; i< mat->getNumElements(); ++i) { + std::cout << " ***** ***** " + << int (mat->getFraction(i)*100) << "% \t" + << mat->getElement(i)->getName() << std::endl; + } + } +} + +void MaterialManager::addElement(const std::string &name, const std::string &symbol, double z, double a) { + GeoIntrusivePtr<GeoElement> newElement{new GeoElement(name,symbol,z,a*atomicDensity)}; + addElement(newElement); +} + +void MaterialManager::addElement(GeoElement* el) { + GeoIntrusivePtr<GeoElement> newElement{el}; + auto result = m_elements.insert(std::make_pair(newElement->getName(), newElement)); + if(!result.second) { + THROW_EXCEPTION("Attempted to redefine element " << newElement->getName()); + } +} + + +const std::string& MaterialManager::materialNameSpace() const { + return m_currentNameSpace; +} +void MaterialManager::setMaterialNamespace(const std::string &name) { + m_currentNameSpace = name; + lockMaterial(); +} +void MaterialManager::lockMaterial() { m_factory.reset(); } + +void MaterialManager::addMaterial(const std::string &name, double density) { + MaterialPtr newMat{new GeoMaterial(name, density * volDensity)}; + addMaterial(newMat); +} + +void MaterialManager::addMaterial(GeoMaterial* mat) { + + std::string matName = replaceDColon(mat->getName()); + if (matName.find("::") == std::string::npos) { + if (materialNameSpace().empty()) { + THROW_EXCEPTION("Material " << matName << " has not beed defined within a namespace"); + } else { + matName = materialNameSpace() + "::" + matName; + } + } + MaterialPtr matPtr{mat}; + auto result = m_materials.insert(std::make_pair(matName, matPtr)); + if(!result.second) { + THROW_EXCEPTION("Attempted to redefine material " << matName); + } + m_factory = std::make_unique<MaterialFactory>(matPtr); +} +bool MaterialManager::isElementDefined(const std::string& eleName) const { + return m_elements.find(eleName)!=m_elements.end(); +} + +void MaterialManager::addMatComponent(const std::string &name, double fraction) { + if (!m_factory){ + THROW_EXCEPTION("No Material factory defiend at the moment"); + } + std::string cmpName{replaceDColon(name)}; + if(!isMaterialDefined(name) || cmpName.find("::") == std::string::npos) { + // New components is an element + const GeoElement* element = getElement(name); + m_factory->addComponent(element, fraction); + } else { + const GeoMaterial* material = getMaterial(name); + m_factory->addComponent(material, fraction); + + } +} +void MaterialManager::buildSpecialMaterials() { + // Ether + GeoIntrusivePtr<GeoElement> ethElement{new GeoElement("Ether","ET",500.0,0.0)}; + m_elements.insert(std::make_pair("Ether",ethElement)); + GeoIntrusivePtr<GeoMaterial> ether{new GeoMaterial("Ether",0.0)}; + ether->add(ethElement,1.); + ether->lock(); + m_materials.insert(std::make_pair("special::Ether", ether)); + // HyperUranium + GeoIntrusivePtr<GeoMaterial> hu{new GeoMaterial("HyperUranium",0.0)}; + hu->add(ethElement,1.); + hu->lock(); + m_materials.insert(std::make_pair("special::HyperUranium", hu)); +} diff --git a/GeoModelCore/GeoModelKernel/GeoModelKernel/GeoMaterialManager.h b/GeoModelCore/GeoModelKernel/GeoModelKernel/GeoMaterialManager.h deleted file mode 100755 index 2fb78a99978a8d108a1b965ae5152b1359560210..0000000000000000000000000000000000000000 --- a/GeoModelCore/GeoModelKernel/GeoModelKernel/GeoMaterialManager.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration -*/ - -#ifndef GEOMATMANAGER_GEOMATMANAGER_H -#define GEOMATMANAGER_GEOMATMANAGER_H - -#include "GeoModelKernel/IGeoMaterialManager.h" - -#include <iostream> - -class GeoElement; -class GeoMaterial; -class Impl; - -class GeoMaterialManager: public IGeoMaterialManager { - - friend class Impl; - - public: - static const GeoMaterialManager* getManager(); - - const GeoMaterial *getMaterial(const std::string & name) const; - const GeoElement *getElement(const std::string & name) const; - const GeoElement *getElement(unsigned int atomicNumber) const; - - std::ostream & printAll(std::ostream & o=std::cout) const; - - void addElement(const std::string &name - , const std::string &symbol - , double z - , double a); - - void addNamespace(const std::string &name); - - void addMaterial(const std::string &name - , double density); - - void addMatComponent(const std::string &name - , double fraction); - - void lockMaterial(); - - void dump(); - - private: - Impl* m_pImpl; - static GeoMaterialManager* s_instance; - - GeoMaterialManager(); - ~GeoMaterialManager(); - - // Build special materials - // void buildSpecialMaterials(); -}; - -#endif diff --git a/GeoModelCore/GeoModelKernel/GeoModelKernel/IGeoMaterialManager.h b/GeoModelCore/GeoModelKernel/GeoModelKernel/IGeoMaterialManager.h deleted file mode 100755 index 64dad733d3539364cb4fd0f176eb19ddfdb3b4e9..0000000000000000000000000000000000000000 --- a/GeoModelCore/GeoModelKernel/GeoModelKernel/IGeoMaterialManager.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration -*/ - -#ifndef IGEOMATMANAGER_IGEOMATMANAGER_H -#define IGEOMATMANAGER_IGEOMATMANAGER_H - -#include <iostream> - -class GeoElement; -class GeoMaterial; - -class IGeoMaterialManager { - - public: - - virtual const GeoMaterial *getMaterial(const std::string & name) const =0; - virtual const GeoElement *getElement(const std::string & name) const =0; - virtual const GeoElement *getElement(unsigned int atomicNumber) const=0; - - virtual void addElement(const std::string &name - , const std::string &symbol - , double z - , double a) =0; - - virtual void addNamespace(const std::string &name) =0; - - virtual void addMaterial(const std::string &name - , double density) =0; - - virtual void addMatComponent(const std::string &name - , double fraction) =0; - - IGeoMaterialManager() {;} - virtual ~IGeoMaterialManager() {;} - -}; - -#endif diff --git a/GeoModelCore/GeoModelKernel/src/GeoMaterialManager.cxx b/GeoModelCore/GeoModelKernel/src/GeoMaterialManager.cxx deleted file mode 100644 index 93492a1c69a41097fc502f729f5e687042685322..0000000000000000000000000000000000000000 --- a/GeoModelCore/GeoModelKernel/src/GeoMaterialManager.cxx +++ /dev/null @@ -1,245 +0,0 @@ -/* - Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration -*/ - -#include "GeoModelKernel/GeoMaterialManager.h" - -#include "GeoModelKernel/GeoElement.h" -#include "GeoModelKernel/GeoMaterial.h" -#include "GeoModelKernel/Units.h" - -#include <cstdlib> -#include <iomanip> -#include <stdio.h> -#include <map> -#include <vector> - -GeoMaterialManager* GeoMaterialManager::s_instance{nullptr}; - -class Impl { -public: - Impl(GeoMaterialManager* /*man*/) - {} - ~Impl(){} - - // Map of elements indexed by Name - typedef std::map<std::string, GeoElement*> ElementMap; - ElementMap m_elements; - - // Map of materials indexed by fully qualified name Namespace::MaterialName - typedef std::map<std::string, GeoMaterial*> MaterialMap; - MaterialMap m_materials; - - //______________________________________________________ - // Auxiliary variables for building new material - std::string m_currentNamespace{""}; - GeoMaterial* m_currentMaterial{nullptr}; - bool m_firstComponent{true}; - bool m_hasSubMaterial{false}; - bool m_calculateFraction{false}; - double m_totalFraction{0.}; - std::vector<GeoElement*> m_elementComponents; - std::vector<double> m_elementFractions; - -}; - - -GeoMaterialManager::GeoMaterialManager() - : m_pImpl(new Impl(this)) -{ - -} - -GeoMaterialManager::~GeoMaterialManager() -{ - delete m_pImpl; -} - -const GeoMaterialManager* GeoMaterialManager::getManager() -{ - if(!s_instance) { - try { - s_instance = new GeoMaterialManager(); - } - catch(std::runtime_error& ex) { - std::cerr << ex.what() << std::endl; - return nullptr; - } - } - return s_instance; -} - -const GeoMaterial* GeoMaterialManager::getMaterial(const std::string & name) const -{ - auto materialIt = m_pImpl->m_materials.find(name); - return materialIt==m_pImpl->m_materials.end() ? nullptr : materialIt->second; -} - -const GeoElement* GeoMaterialManager::getElement(const std::string & name) const -{ - auto elementIt = m_pImpl->m_elements.find(name); - return elementIt==m_pImpl->m_elements.end() ? nullptr : elementIt->second; -} - -const GeoElement* GeoMaterialManager::getElement(unsigned int atomicNumber) const -{ - for(auto element : m_pImpl->m_elements) { - if((unsigned)(element.second->getZ())==atomicNumber) { - return element.second; - } - } - return nullptr; -} - -std::ostream& GeoMaterialManager::printAll(std::ostream& o) const -{ - o << "============Material Manager Element List========================" << std::endl; - - for (auto element : m_pImpl->m_elements) { - GeoElement* el = element.second; - o << el->getSymbol() << '\t' - << el->getZ() << '\t' - << el->getA() * (GeoModelKernelUnits::mole / GeoModelKernelUnits::gram) << '\t' - << el->getName() << std::endl; - } - - for (auto material : m_pImpl->m_materials) { - GeoMaterial* mat = material.second; - o << "Material: " << material.first - << " Density " << mat->getDensity() * (GeoModelKernelUnits::cm3 / GeoModelKernelUnits::gram) - << std::endl; - for (size_t i = 0; i< mat->getNumElements(); ++i) { - o << " ***** ***** " - << int (mat->getFraction(i)*100) << "% \t" - << mat->getElement(i)->getName() << std::endl; - } - } - return o; -} - -void GeoMaterialManager::addElement(const std::string &name - , const std::string &symbol - , double z - , double a) -{ - GeoElement* newElement = new GeoElement(name,symbol,z,a*(GeoModelKernelUnits::gram/GeoModelKernelUnits::mole)); - newElement->ref(); - auto result = m_pImpl->m_elements.insert(std::pair<std::string,GeoElement*>(name,newElement)); - if(!result.second) { - std::string errorMessage("Attempted to redefine element" + name); - throw std::runtime_error(errorMessage.c_str()); - } -} - -void GeoMaterialManager::addNamespace(const std::string &name) -{ - lockMaterial(); - m_pImpl->m_currentNamespace = name; -} - -void GeoMaterialManager::addMaterial(const std::string &name - , double density) -{ - if(m_pImpl->m_currentNamespace.empty()) { - std::string errorMessage("Material " + name + " has not beed defined within a namespace"); - throw std::runtime_error(errorMessage.c_str()); - } - lockMaterial(); - m_pImpl->m_currentMaterial = new GeoMaterial(name, density * (GeoModelKernelUnits::gram / GeoModelKernelUnits::cm3)); - auto result = m_pImpl->m_materials.insert(std::pair<std::string,GeoMaterial*>(m_pImpl->m_currentNamespace+"::"+name, m_pImpl->m_currentMaterial)); - if(!result.second) { - std::string errorMessage("Attempted to redefine material " + name); - throw std::runtime_error(errorMessage.c_str()); - } -} - -void GeoMaterialManager::addMatComponent(const std::string &name - , double fraction) -{ - if(m_pImpl->m_firstComponent) { - m_pImpl->m_firstComponent = false; - if(fraction>=1.) { - m_pImpl->m_calculateFraction = true; - } - } - - size_t separatorPos = name.find("::"); - if(separatorPos==std::string::npos) { - // New components is an element - auto elementIt = m_pImpl->m_elements.find(name); - if(elementIt==m_pImpl->m_elements.end()) { - std::string errorMessage("Unknown element " + name + " used in the definition of material " + m_pImpl->m_currentMaterial->getName()); - throw std::runtime_error(errorMessage.c_str()); - } - GeoElement* element = elementIt->second; - - if(m_pImpl->m_calculateFraction) { - m_pImpl->m_totalFraction += fraction*element->getA(); - m_pImpl->m_elementComponents.push_back(element); - m_pImpl->m_elementFractions.push_back(fraction); - } - else { - m_pImpl->m_currentMaterial->add(element,fraction); - } - } - else { - // New component is a material - auto materialIt = m_pImpl->m_materials.find(name); - if(materialIt==m_pImpl->m_materials.end()) { - std::string errorMessage("Unknown material " + name + " used in the components name " + name); - throw std::runtime_error(errorMessage.c_str()); - } - GeoMaterial* material = materialIt->second; - m_pImpl->m_hasSubMaterial = true; - m_pImpl->m_currentMaterial->add(material, fraction); - } -} - -void GeoMaterialManager::lockMaterial() -{ - if(!m_pImpl->m_currentMaterial) return; - - if(m_pImpl->m_calculateFraction && m_pImpl->m_hasSubMaterial && m_pImpl->m_elementComponents.size()>0) { - std::string errorMessage("Wrong definition of the material " + m_pImpl->m_currentMaterial->getName() + ". The exact fraction for elements must be indicated"); - throw std::runtime_error(errorMessage.c_str()); - } - - if(m_pImpl->m_calculateFraction && !m_pImpl->m_elementComponents.empty()) { - const double inv_totalFraction = 1. / m_pImpl->m_totalFraction; - for(unsigned i=0; i<m_pImpl->m_elementComponents.size(); i++) { - m_pImpl->m_currentMaterial->add(m_pImpl->m_elementComponents[i],m_pImpl->m_elementFractions[i]*m_pImpl->m_elementComponents[i]->getA() * inv_totalFraction); - } - } - m_pImpl->m_currentMaterial->lock(); - m_pImpl->m_currentMaterial->ref(); - - // Get ready for building next material - m_pImpl->m_currentMaterial = nullptr; - m_pImpl->m_firstComponent = true; - m_pImpl->m_hasSubMaterial = false; - m_pImpl->m_calculateFraction = false; - m_pImpl->m_totalFraction = 0.; - m_pImpl->m_elementComponents.clear(); - m_pImpl->m_elementFractions.clear(); -} - -void GeoMaterialManager::dump() -{ - const char separator(' '); - std::cout << "*******************************************************" << std::endl; - std::cout << "*** GeoXmlMaterialManager ***" << std::endl; - std::cout << "*******************************************************" << std::endl; - std::cout << "*** Elements:" << std::endl; - - for(const auto& item : m_pImpl->m_elements) { - GeoElement* element = item.second; - std::cout << "* "<< std::left << std::setw(15) << std::setfill(separator) << element->getName() - << " " << std::left << std::setw(5) << std::setfill(separator) << element->getSymbol() - << " " << std::left << std::setw(15) << std::setfill(separator) << element->getZ() - << " " << std::left << std::setw(5) << std::setfill(separator) << element->getA() - << std::endl; - } - std::cout << "*******************************************************" << std::endl; - -} - diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/GmxUtil.h b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/GmxUtil.h index b27cc1619d7e54c576dbba6e6e73b935e9d3b9c0..ff53275924f839043d10077f0c9bcdeb39fda2ce 100644 --- a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/GmxUtil.h +++ b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/GmxUtil.h @@ -10,7 +10,7 @@ // #include <string> #include "ExpressionEvaluator/Evaluator.h" -#include "GeoModelXml/MaterialManager.h" +#include "GeoModelFuncSnippets/MaterialManager.h" #include "GeoModelXml/ProcessorRegistry.h" #include "GeoModelXml/Element2GeoItemRegistry.h" diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/MaterialManager.h b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/MaterialManager.h deleted file mode 100755 index 87a1963cb9a5b76379ca848dbe43cfa339b0d7cd..0000000000000000000000000000000000000000 --- a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/MaterialManager.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration -*/ - -#ifndef GEO_MODEL_XML_MATERIAL_MANAGER_H -#define GEO_MODEL_XML_MATERIAL_MANAGER_H - -#include "GeoModelKernel/IGeoMaterialManager.h" - -#include <iostream> - -class GeoElement; -class GeoMaterial; -class Impl; - -class MaterialManager: public IGeoMaterialManager { - - friend class Impl; - friend class Gmx2Geo; - - public: - - const GeoMaterial *getMaterial(const std::string & name) const; - const GeoElement *getElement(const std::string & name) const; - const GeoElement *getElement(unsigned int atomicNumber) const; - - void printAll() const; - - void addElement(const std::string &name - , const std::string &symbol - , double z - , double a); - - void addElement(GeoElement*); - - void addNamespace(const std::string &name); - - void addMaterial(const std::string &name - , double density); - - void addMaterial(GeoMaterial*); - - void addMatComponent(const std::string &name - , double fraction); - - void lockMaterial(); - - void dump(); - - bool isMaterialDefined(const std::string s) const; - - bool isElementDefined(const std::string s) const; - - static MaterialManager* getManager(); - private: - Impl* m_pImpl; - static MaterialManager* s_instance; - - - MaterialManager(); - ~MaterialManager(); - - // Build special materials - void buildSpecialMaterials(); -}; - -#endif diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/src/AddPlane.cxx b/GeoModelTools/GeoModelXML/GeoModelXml/src/AddPlane.cxx index 4ae47791de96cd745c976561802dd0e350198828..036b17fd0b1f4d7fd380395618ebaab85d83a4dd 100644 --- a/GeoModelTools/GeoModelXML/GeoModelXml/src/AddPlane.cxx +++ b/GeoModelTools/GeoModelXML/GeoModelXml/src/AddPlane.cxx @@ -6,6 +6,7 @@ #include "GeoModelXml/GmxUtil.h" #include <string> #include <sstream> +#include <iostream> #include <xercesc/dom/DOM.hpp> #include "xercesc/util/XMLString.hpp" diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/src/Gmx2Geo.cxx b/GeoModelTools/GeoModelXML/GeoModelXml/src/Gmx2Geo.cxx index 5de2274ad1f524e817b0d1519d0ded6775421ea1..31fd4ebd824e7ed34b91025dd42341c3c0bb5c66 100644 --- a/GeoModelTools/GeoModelXML/GeoModelXml/src/Gmx2Geo.cxx +++ b/GeoModelTools/GeoModelXML/GeoModelXml/src/Gmx2Geo.cxx @@ -28,7 +28,7 @@ #include "GeoModelXml/GmxUtil.h" #include "GeoModelXml/GmxInterface.h" #include "GeoModelXml/createdomdocument.h" -#include "GeoModelXml/MaterialManager.h" +#include "GeoModelFuncSnippets/MaterialManager.h" using namespace std; using namespace xercesc; @@ -81,7 +81,7 @@ Gmx2Geo::Gmx2Geo(const string& xmlFile, GeoVPhysVol *addHere, GmxInterface &gmxI // if the material manager is set, create a namespace // - if (gmxUtil.matManager) gmxUtil.matManager->addNamespace(XMLString::transcode(attribute)); + if (gmxUtil.matManager) gmxUtil.matManager->setMaterialNamespace(XMLString::transcode(attribute)); // // Add all constant definitions to the evaluator, so they are ready if needed. diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/src/MaterialManager.cxx b/GeoModelTools/GeoModelXML/GeoModelXml/src/MaterialManager.cxx deleted file mode 100644 index cd2ba784658ead844926606096824bdcaa1bb04c..0000000000000000000000000000000000000000 --- a/GeoModelTools/GeoModelXML/GeoModelXml/src/MaterialManager.cxx +++ /dev/null @@ -1,330 +0,0 @@ -/* - Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration -*/ - -#include "GeoModelXml/MaterialManager.h" - -#include "GeoModelKernel/GeoElement.h" -#include "GeoModelKernel/GeoMaterial.h" -#include "GeoModelKernel/Units.h" - -#include <cstdlib> -#include <iomanip> -#include <stdio.h> -#include <map> -#include <vector> - -MaterialManager* MaterialManager::s_instance{nullptr}; - -class Impl { -public: - Impl(MaterialManager* man) - {} - ~Impl(){} - - // Map of elements indexed by Name - typedef std::map<std::string, GeoElement*> ElementMap; - ElementMap m_elements; - - // Map of materials indexed by fully qualified name Namespace::MaterialName - typedef std::map<std::string, GeoMaterial*> MaterialMap; - MaterialMap m_materials; - - //______________________________________________________ - // Auxiliary variables for building new material - std::string m_currentNamespace{""}; - GeoMaterial* m_currentMaterial{nullptr}; - bool m_firstComponent{true}; - bool m_hasSubMaterial{false}; - bool m_calculateFraction{false}; - double m_totalFraction{0.}; - std::vector<GeoElement*> m_elementComponents; - std::vector<double> m_elementFractions; - -}; - - -MaterialManager::MaterialManager() - : m_pImpl(new Impl(this)) -{ - // std::cout<<" this is the GMX MaterialManager being instantiated!"<<std::endl; - // std::cout<<" building special materials "<<std::endl; - buildSpecialMaterials(); -} - -MaterialManager::~MaterialManager() -{ - delete m_pImpl; -} - -MaterialManager* MaterialManager::getManager() -{ - if(!s_instance) { - try { - s_instance = new MaterialManager(); - } - catch(std::runtime_error& ex) { - std::cerr << ex.what() << std::endl; - return nullptr; - } - } - return s_instance; -} - -const GeoMaterial* MaterialManager::getMaterial(const std::string & name) const -{ - //std::cout << "Material Manager: attempt at retrieving material : "<<name<<std::endl; - // step 1 - check for simple name - auto materialIt = m_pImpl->m_materials.find(name); - if (materialIt!=m_pImpl->m_materials.end()) - { - //std::cout<<" material "<<name<<" found!"<<std::endl; - return materialIt->second; - } - // step 2 - check for material in namespace - std::string nameNS=m_pImpl->m_currentNamespace+"::"+name; - auto materialNSIt = m_pImpl->m_materials.find(nameNS); - if (materialNSIt!=m_pImpl->m_materials.end()) - { - //std::cout<<" material "<<nameNS<<" found!"<<std::endl; - return materialNSIt->second; - } - - // well, something is wrong... - //std::cout<<"MaterialManager::getMaterial() Warning! could not find material "<<name<<std::endl; - return nullptr; -} - -const GeoElement* MaterialManager::getElement(const std::string & name) const -{ - //std::cout << "Material Manager: attempt at retrieving element : "<<name<<std::endl; - auto elementIt = m_pImpl->m_elements.find(name); - return elementIt==m_pImpl->m_elements.end() ? nullptr : elementIt->second; -} - -const GeoElement* MaterialManager::getElement(unsigned int atomicNumber) const -{ - //std::cout << "Material Manager: attempt at retrieving material : "<<atomicNumber<<std::endl; - for(auto element : m_pImpl->m_elements) { - if((unsigned)(element.second->getZ())==atomicNumber) { - return element.second; - } - } - return nullptr; -} - -void MaterialManager::printAll() const -{ - std::cout << "============Material Manager Element List========================" << std::endl; - - for (auto element : m_pImpl->m_elements) { - GeoElement* el = element.second; - std::cout << el->getSymbol() << '\t' - << el->getZ() << '\t' - << el->getA() * (GeoModelKernelUnits::mole / GeoModelKernelUnits::gram) << '\t' - << el->getName() << std::endl; - } - - for (auto material : m_pImpl->m_materials) { - GeoMaterial* mat = material.second; - std::cout << "Material: " << material.first - << " Density " << mat->getDensity() * (GeoModelKernelUnits::cm3 / GeoModelKernelUnits::gram) - << std::endl; - for (size_t i = 0; i< mat->getNumElements(); ++i) { - std::cout << " ***** ***** " - << int (mat->getFraction(i)*100) << "% \t" - << mat->getElement(i)->getName() << std::endl; - } - } -} - -void MaterialManager::addElement(const std::string &name - , const std::string &symbol - , double z - , double a) -{ - //std::cout << "Material Manager: adding element : "<<name<<" "<<symbol<<" "<<z<<" "<<a<<std::endl; - GeoElement* newElement = new GeoElement(name,symbol,z,a*(GeoModelKernelUnits::gram/GeoModelKernelUnits::mole)); - newElement->ref(); - auto result = m_pImpl->m_elements.insert(std::pair<std::string,GeoElement*>(name,newElement)); - if(!result.second) { - std::string errorMessage("Attempted to redefine element" + name); - throw std::runtime_error(errorMessage.c_str()); - } -} - -void MaterialManager::addElement(GeoElement* el) -{ - std::string name=el->getName(); - //std::cout << "Material Manager: adding element : "<<name<<std::endl; - GeoElement* newElement = el; - newElement->ref(); - auto result = m_pImpl->m_elements.insert(std::pair<std::string,GeoElement*>(name,newElement)); - if(!result.second) { - std::string errorMessage("Attempted to redefine element" + name); - throw std::runtime_error(errorMessage.c_str()); - } -} - -void MaterialManager::addNamespace(const std::string &name) -{ - //std::cout << "Material Manager: adding namespace : "<<name<<std::endl; - lockMaterial(); - m_pImpl->m_currentNamespace = name; -} - -void MaterialManager::addMaterial(const std::string &name - , double density) -{ - //std::cout << "Material Manager: adding material : "<<name<<" "<<density<<std::endl; - if(m_pImpl->m_currentNamespace.empty()) { - std::string errorMessage("Material " + name + " has not beed defined within a namespace"); - throw std::runtime_error(errorMessage.c_str()); - } - lockMaterial(); - m_pImpl->m_currentMaterial = new GeoMaterial(name, density * (GeoModelKernelUnits::gram / GeoModelKernelUnits::cm3)); - auto result = m_pImpl->m_materials.insert(std::pair<std::string,GeoMaterial*>(m_pImpl->m_currentNamespace+"::"+name, m_pImpl->m_currentMaterial)); - if(!result.second) { - std::string errorMessage("Attempted to redefine material " + name); - throw std::runtime_error(errorMessage.c_str()); - } -} - -void MaterialManager::addMaterial(GeoMaterial* mat) -{ - const std::string name=mat->getName(); - //std::cout << "Material Manager: adding material : "<<name<<std::endl; - if(m_pImpl->m_currentNamespace.empty()) { - std::string errorMessage("Material " + name + " has not beed defined within a namespace"); - throw std::runtime_error(errorMessage.c_str()); - } - lockMaterial(); - m_pImpl->m_currentMaterial = mat; - auto result = m_pImpl->m_materials.insert(std::pair<std::string,GeoMaterial*>(m_pImpl->m_currentNamespace+"::"+name, m_pImpl->m_currentMaterial)); - if(!result.second) { - std::string errorMessage("Attempted to redefine material " + name); - throw std::runtime_error(errorMessage.c_str()); - } -} - -bool MaterialManager::isMaterialDefined(const std::string s) const -{ - if(m_pImpl->m_currentNamespace.empty()) { - std::string errorMessage("Material " + s + " has not beed defined within a namespace"); - throw std::runtime_error(errorMessage.c_str()); - } - return (m_pImpl->m_materials.find(s)!=m_pImpl->m_materials.end()); -} - -bool MaterialManager::isElementDefined(const std::string s) const -{ - return (m_pImpl->m_elements.find(s)!=m_pImpl->m_elements.end()); -} - -void MaterialManager::addMatComponent(const std::string &name - , double fraction) -{ - //std::cout << "Material Manager: adding material component : "<<name<<" "<<fraction<<std::endl; - if(m_pImpl->m_firstComponent) { - m_pImpl->m_firstComponent = false; - if(fraction>=1.) { - m_pImpl->m_calculateFraction = true; - } - } - - size_t separatorPos = name.find("::"); - if(separatorPos==std::string::npos) { - // New components is an element - auto elementIt = m_pImpl->m_elements.find(name); - if(elementIt==m_pImpl->m_elements.end()) { - std::string errorMessage("Unknown element " + name + " used in the definition of material " + m_pImpl->m_currentMaterial->getName()); - throw std::runtime_error(errorMessage.c_str()); - } - GeoElement* element = elementIt->second; - - if(m_pImpl->m_calculateFraction) { - m_pImpl->m_totalFraction += fraction*element->getA(); - m_pImpl->m_elementComponents.push_back(element); - m_pImpl->m_elementFractions.push_back(fraction); - } - else { - m_pImpl->m_currentMaterial->add(element,fraction); - } - } - else { - // New component is a material - auto materialIt = m_pImpl->m_materials.find(name); - if(materialIt==m_pImpl->m_materials.end()) { - std::string errorMessage("Unknown material " + name + " used in the components name " + name); - throw std::runtime_error(errorMessage.c_str()); - } - GeoMaterial* material = materialIt->second; - m_pImpl->m_hasSubMaterial = true; - m_pImpl->m_currentMaterial->add(material, fraction); - } -} - -void MaterialManager::lockMaterial() -{ - if(!m_pImpl->m_currentMaterial) return; - - if(m_pImpl->m_calculateFraction && m_pImpl->m_hasSubMaterial && m_pImpl->m_elementComponents.size()>0) { - std::string errorMessage("Wrong definition of the material " + m_pImpl->m_currentMaterial->getName() + ". The exact fraction for elements must be indicated"); - throw std::runtime_error(errorMessage.c_str()); - } - - if(m_pImpl->m_calculateFraction && !m_pImpl->m_elementComponents.empty()) { - const double inv_totalFraction = 1. / m_pImpl->m_totalFraction; - for(unsigned i=0; i<m_pImpl->m_elementComponents.size(); i++) { - m_pImpl->m_currentMaterial->add(m_pImpl->m_elementComponents[i],m_pImpl->m_elementFractions[i]*m_pImpl->m_elementComponents[i]->getA() * inv_totalFraction); - } - } - m_pImpl->m_currentMaterial->lock(); - m_pImpl->m_currentMaterial->ref(); - - // Get ready for building next material - m_pImpl->m_currentMaterial = nullptr; - m_pImpl->m_firstComponent = true; - m_pImpl->m_hasSubMaterial = false; - m_pImpl->m_calculateFraction = false; - m_pImpl->m_totalFraction = 0.; - m_pImpl->m_elementComponents.clear(); - m_pImpl->m_elementFractions.clear(); -} - -void MaterialManager::dump() -{ - const char separator(' '); - std::cout << "*******************************************************" << std::endl; - std::cout << "*** GeoXmlMaterialManager ***" << std::endl; - std::cout << "*******************************************************" << std::endl; - std::cout << "*** Elements:" << std::endl; - - for(const auto& item : m_pImpl->m_elements) { - GeoElement* element = item.second; - std::cout << "* "<< std::left << std::setw(15) << std::setfill(separator) << element->getName() - << " " << std::left << std::setw(5) << std::setfill(separator) << element->getSymbol() - << " " << std::left << std::setw(15) << std::setfill(separator) << element->getZ() - << " " << std::left << std::setw(5) << std::setfill(separator) << element->getA() - << std::endl; - } - std::cout << "*******************************************************" << std::endl; - -} - -void MaterialManager::buildSpecialMaterials() -{ - // Ether - GeoElement* ethElement = new GeoElement("Ether","ET",500.0,0.0); - ethElement->ref(); - m_pImpl->m_elements.insert(std::pair<std::string,GeoElement*>("Ether",ethElement)); - GeoMaterial* ether = new GeoMaterial("Ether",0.0); - ether->add(ethElement,1.); - ether->lock(); - m_pImpl->m_materials.insert(std::pair<std::string,GeoMaterial*>("special::Ether", ether)); - // HyperUranium - GeoMaterial* hu = new GeoMaterial("HyperUranium",0.0); - hu->add(ethElement,1.); - hu->lock(); - m_pImpl->m_materials.insert(std::pair<std::string,GeoMaterial*>("special::HyperUranium", hu)); -} diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/src/TransformProcessor.cxx b/GeoModelTools/GeoModelXML/GeoModelXml/src/TransformProcessor.cxx index 72d42b3c61577eb5cb2ee8215c68c46dffbfe923..1c31e8b3c6cc310cc1bc8c4dcaa7c8d8cbc7dc63 100644 --- a/GeoModelTools/GeoModelXML/GeoModelXml/src/TransformProcessor.cxx +++ b/GeoModelTools/GeoModelXML/GeoModelXml/src/TransformProcessor.cxx @@ -17,6 +17,7 @@ #include <string> #include <sstream> +#include <iostream> #include <vector> #include <xercesc/dom/DOM.hpp> #include "GeoModelKernel/GeoNameTag.h"