diff --git a/docs/web/release-notes-5.0.md b/docs/web/release-notes-5.0.md index e440a1747..62f87d8e4 100644 --- a/docs/web/release-notes-5.0.md +++ b/docs/web/release-notes-5.0.md @@ -249,6 +249,16 @@ use the `TFEL` libraries in `C++` projects, using either the # Issues fixed +## Issue 535: [mfront-doc] add support for material properties + +Allows mfront-doc to be used with the `MaterialLaw` DSL. Example of use: + +~~~~{.bash} +$ mfront-doc T91MartensiticSteel_gamma1_ROUX2007.mfront +~~~~ + +For more details, see + ## Issue 582: [cast3m interface] add explicit names and 4-letter mapping of internal variables to the castem file Adds the correspondence between variable names and the 4-letter diff --git a/mfront-doc/include/CMakeLists.txt b/mfront-doc/include/CMakeLists.txt index 531552b0b..f7755837a 100644 --- a/mfront-doc/include/CMakeLists.txt +++ b/mfront-doc/include/CMakeLists.txt @@ -1 +1 @@ -install_mfront_header(MFront BehaviourDocumentationGenerator.hxx) +install_mfront_header(MFront DocumentationGeneratorBase.hxx BehaviourDocumentationGenerator.hxx MaterialPropertyDocumentationGenerator.hxx) diff --git a/mfront-doc/include/MFront/BehaviourDocumentationGenerator.hxx b/mfront-doc/include/MFront/BehaviourDocumentationGenerator.hxx index 7f3c4a4bc..9e1730177 100644 --- a/mfront-doc/include/MFront/BehaviourDocumentationGenerator.hxx +++ b/mfront-doc/include/MFront/BehaviourDocumentationGenerator.hxx @@ -20,29 +20,15 @@ #include #include -#include "TFEL/Utilities/ArgumentParserBase.hxx" -#include "TFEL/Material/ModellingHypothesis.hxx" -#include "MFront/MFrontBase.hxx" +#include "MFront/DocumentationGeneratorBase.hxx" namespace mfront { - // forward declaration - struct AbstractBehaviourDSL; - // forward declaration - struct BehaviourDescription; - // forward declaration - struct FileDescription; - /*! * Class used by the mfront-query tool to extract information from * behaviour implementation */ - struct BehaviourDocumentationGenerator - : public tfel::utilities::ArgumentParserBase< - BehaviourDocumentationGenerator>, - public MFrontBase { - //! \brief type of documentation to be generated - enum OutputType { FULL, WEB }; + struct BehaviourDocumentationGenerator : public DocumentationGeneratorBase { /*! * build a BehaviourDocumentationGenerator object based on command line * arguments @@ -56,48 +42,32 @@ namespace mfront { std::shared_ptr, const std::string &); //! treat the requests - void exe(); + void exe() const override; //! destructor ~BehaviourDocumentationGenerator() override; + struct VariableInformation + : DocumentationGeneratorBase::VariableInformationBase { + using Hypothesis = tfel::material::ModellingHypothesis::Hypothesis; + VariableInformation(); + VariableInformation(VariableInformation &&) noexcept; + VariableInformation(const VariableInformation &); + VariableInformation &operator=(VariableInformation &&); + VariableInformation &operator=(const VariableInformation &); + ~VariableInformation() noexcept; + std::map descriptions; + std::vector hypotheses; + }; + private: - //! ArgumentParserBase must be a friend - friend struct tfel::utilities::ArgumentParserBase< - BehaviourDocumentationGenerator>; - //! \brief register call-backs associated with command line arguments - virtual void registerCommandLineCallBacks(); - //! treat the web argument - virtual void treatWeb(); - virtual void writeWebOutput(std::ostream &, - const BehaviourDescription &, - const FileDescription &) const; - virtual void writeFullOutput(std::ostream &, - const BehaviourDescription &, - const FileDescription &) const; - //! return the current argument - const tfel::utilities::Argument &getCurrentCommandLineArgument() - const override final; - //! treat an unknown argument - void treatUnknownArgument() override final; - //! get the version description - std::string getVersionDescription() const override final; - //! get the usage description - std::string getUsageDescription() const override final; + void writeWebOutput(std::ostream &, + const BehaviourDescription &, + const FileDescription &) const; + void writeFullOutput(std::ostream &, + const BehaviourDescription &, + const FileDescription &) const; //! abstract behaviour dsl std::shared_ptr dsl; - //! input file name - std::string file; - //! type of ouput - OutputType otype; - //! \brief generate output on standard output - bool std_output = false; - /*! - * \brief boolean whose meaning is the following: - * - if true, the generated documentation is contained in a whole document. - * - if false, the generated documentation is contained in a section meant - * to be included in a bigger document. - */ - bool standalone = false; }; // end of struct BehaviourDocumentationGenerator } // end of namespace mfront diff --git a/mfront-doc/include/MFront/DocumentationGeneratorBase.hxx b/mfront-doc/include/MFront/DocumentationGeneratorBase.hxx new file mode 100644 index 000000000..effc95bd7 --- /dev/null +++ b/mfront-doc/include/MFront/DocumentationGeneratorBase.hxx @@ -0,0 +1,111 @@ +/*! + * \file DocumentationGeneratorBase.hxx + * \brief + * \author Maxence Wangermez + * \date 16 avril 2024 + * \copyright Copyright (C) 2006-2024 CEA/DEN, EDF R&D. All rights + * reserved. + * This project is publicly released under either the GNU GPL Licence + * or the CECILL-A licence. A copy of thoses licences are delivered + * with the sources of TFEL. CEA or EDF may also distribute this + * project under specific licensing conditions. + */ + +#ifndef LIB_MFRONT_DOCUMENTATIONGENERATORBASE_H +#define LIB_MFRONT_DOCUMENTATIONGENERATORBASE_H + +#include +#include +#include +#include +#include + +#include "TFEL/Utilities/ArgumentParserBase.hxx" +#include "MFront/MFrontBase.hxx" + +namespace mfront { + + // forward declaration + struct BehaviourDescription; + // forward declaration + struct FileDescription; + + /*! + * Class used by the mfront-query tool to extract information from + * behaviour implementation + */ + struct DocumentationGeneratorBase + : public tfel::utilities::ArgumentParserBase, + public MFrontBase { + //! \brief type of documentation to be generated + enum OutputType { FULL, WEB }; + /*! + * build a DocumentationGeneratorBase object based on command line + * arguments + * \param[in] argc : number of command line arguments + * \param[in] argv : command line arguments + * \param[in] f : filename + */ + DocumentationGeneratorBase(const int, + const char *const *const, + const std::string &); + virtual void exe() const = 0; + //! destructor + ~DocumentationGeneratorBase() override; + + // Private member data + //! input file name + std::string file; + /*! + * \brief boolean whose meaning is the following: + * - if true, the generated documentation is contained in a whole document. + * - if false, the generated documentation is contained in a section meant + * to be included in a bigger document. + */ + bool standalone = false; + + //! \brief generate output on standard output + bool std_output = false; + //! type of ouput + OutputType otype; + //! \brief generate latex macros for header of output file + static void writeStandardLatexMacros(std::ostream &); + + //! \brief data structure describing a variable + struct VariableInformationBase { + VariableInformationBase(); + VariableInformationBase(VariableInformationBase &&) noexcept; + VariableInformationBase(const VariableInformationBase &); + VariableInformationBase &operator=(VariableInformationBase &&); + VariableInformationBase &operator=(const VariableInformationBase &); + ~VariableInformationBase() noexcept; + std::string name; + std::string type; + std::string description; + std::string externalName; + unsigned short arraySize; + }; + + private: + //! ArgumentParserBase must be a friend + friend struct tfel::utilities::ArgumentParserBase< + DocumentationGeneratorBase>; + //! \brief register call-backs associated with command line arguments + virtual void registerCommandLineCallBacks(); + //! treat the web argument + virtual void treatWeb(); + //! return the current argument + const tfel::utilities::Argument &getCurrentCommandLineArgument() + const override final; + //! treat an unknown argument + void treatUnknownArgument() override final; + //! get the version description + std::string getVersionDescription() const override final; + //! get the usage description + std::string getUsageDescription() const override final; + + }; // end of struct DocumentationGeneratorBase + +} // end of namespace mfront + +#endif /* LIB_MFRONT_DOCUMENTATIONGENERATORBASE_H */ diff --git a/mfront-doc/include/MFront/MaterialPropertyDocumentationGenerator.hxx b/mfront-doc/include/MFront/MaterialPropertyDocumentationGenerator.hxx new file mode 100644 index 000000000..c6d034bac --- /dev/null +++ b/mfront-doc/include/MFront/MaterialPropertyDocumentationGenerator.hxx @@ -0,0 +1,73 @@ +/*! + * \file MaterialPropertyDocumentationGenerator.hxx + * \brief + * \author Maxence Wangermez + * \date 16 avril 2024 + * \copyright Copyright (C) 2006-2024 CEA/DEN, EDF R&D. All rights + * reserved. + * This project is publicly released under either the GNU GPL Licence + * or the CECILL-A licence. A copy of thoses licences are delivered + * with the sources of TFEL. CEA or EDF may also distribute this + * project under specific licensing conditions. + */ + +#ifndef LIB_MFRONT_MATERIALPROPERTYDOCUMENTATIONGENERATOR_H +#define LIB_MFRONT_MATERIALPROPERTYDOCUMENTATIONGENERATOR_H + +#include +#include +#include +#include +#include + +#include "MFront/MaterialPropertyDSL.hxx" +#include "MFront/DocumentationGeneratorBase.hxx" + +namespace mfront { + + /*! + * Class used by the mfront-query tool to extract information from + * behaviour implementation + */ + struct MaterialPropertyDocumentationGenerator + : public DocumentationGeneratorBase { + /*! + * build a MaterialPropertyDocumentationGenerator object based on command + * line arguments \param[in] argc : number of command line arguments + * \param[in] argv : command line arguments + * \param[in] d : behaviour domain specific language + * \param[in] f : behaviour domain specific language + */ + MaterialPropertyDocumentationGenerator(const int, + const char *const *const, + std::shared_ptr, + const std::string &); + //! treat the requests + void exe() const override; + //! destructor + ~MaterialPropertyDocumentationGenerator() override; + + struct VariableInformation + : DocumentationGeneratorBase::VariableInformationBase { + VariableInformation(); + VariableInformation(VariableInformation &&) noexcept; + VariableInformation(const VariableInformation &); + VariableInformation &operator=(VariableInformation &&); + VariableInformation &operator=(const VariableInformation &); + ~VariableInformation() noexcept; + }; + + private: + void writeWebOutput(std::ostream &, + const MaterialPropertyDescription &, + const FileDescription &) const; + void writeFullOutput(std::ostream &, + const MaterialPropertyDescription &, + const FileDescription &) const; + //! abstract behaviour dsl + std::shared_ptr dsl; + }; // end of struct MaterialPropertyDocumentationGenerator + +} // end of namespace mfront + +#endif /* LIB_MFRONT_MATERIALPROPERTYDOCUMENTATIONGENERATOR_H */ diff --git a/mfront-doc/src/BehaviourDocumentationGenerator.cxx b/mfront-doc/src/BehaviourDocumentationGenerator.cxx index 0043e1e31..3c39d3d9f 100644 --- a/mfront-doc/src/BehaviourDocumentationGenerator.cxx +++ b/mfront-doc/src/BehaviourDocumentationGenerator.cxx @@ -25,6 +25,7 @@ #include "MFront/VariableDescription.hxx" #include "MFront/FileDescription.hxx" #include "MFront/BehaviourDescription.hxx" +#include "MFront/DocumentationGeneratorBase.hxx" #include "MFront/BehaviourDocumentationGenerator.hxx" namespace mfront { @@ -100,71 +101,11 @@ namespace mfront { return out.str(); } - static void writeStandardLatexMacros(std::ostream& os) { - os << "\\newcommand{\\tensor}[1]{\\underline{#1}}\n" - << "\\newcommand{\\tensorq}[1]{\\underline{\\mathbf{#1}}}\n" - << "\\newcommand{\\ust}[1]{\\underset{\\tilde{}}{\\mathbf{#1}}}\n" - << "\\newcommand{\\transpose}[1]{#1^{\\mathop{T}}}\n" - << "\\newcommand{\\tsigma}{\\underline{\\sigma}}\n" - << "\\newcommand{\\sigmaeq}{\\sigma_{\\mathrm{eq}}}\n" - << "\\newcommand{\\epsilonth}{\\epsilon^{\\mathrm{th}}}\n" - << "\\newcommand{\\tepsilonto}{\\underline{\\epsilon}^{\\mathrm{to}}}\n" - << "\\newcommand{\\tepsilonel}{\\underline{\\epsilon}^{\\mathrm{el}}}\n" - << "\\newcommand{\\tepsilonth}{\\underline{\\epsilon}^{\\mathrm{th}}}\n" - << "\\newcommand{\\tepsilonvis}{\\underline{\\epsilon}^{\\mathrm{vis}}}" - "\n" - << "\\newcommand{\\tdepsilonvis}{\\underline{\\dot{\\epsilon}}^{" - "\\mathrm{vis}}}\n" - << "\\newcommand{\\tepsilonp}{\\underline{\\epsilon}^{\\mathrm{p}}}\n" - << "\\newcommand{\\tdepsilonp}{\\underline{\\dot{\\epsilon}}^{\\mathrm{" - "p}}}\n" - << "\\newcommand{\\trace}[1]{\\mathrm{tr}\\paren{#1}}\n" - << "\\newcommand{\\Frac}[2]{{\\displaystyle \\frac{\\displaystyle " - "#1}{\\displaystyle #2}}}\n" - << "\\newcommand{\\deriv}[2]{{\\displaystyle \\frac{\\displaystyle " - "\\partial #1}{\\displaystyle \\partial #2}}}\n" - << "\\newcommand{\\dtot}{\\mathrm{d}}\n" - << "\\newcommand{\\paren}[1]{\\left(#1\\right)}\n" - << "\\newcommand{\\bts}[1]{\\left.#1\\right|_{t}}\n" - << "\\newcommand{\\mts}[1]{\\left.#1\\right|_{t+\\theta\\,\\Delta\\,t}}" - "\n" - << "\\newcommand{\\ets}[1]{\\left.#1\\right|_{t+\\Delta\\,t}}\n\n"; - } // end of writeStandardLatexMacros - - /*! - * internal structure gathering data from mechanical behaviour - * description - */ - struct Data { - using Hypothesis = tfel::material::ModellingHypothesis::Hypothesis; - Data(); - Data(Data&&) noexcept; - Data(const Data&); - Data& operator=(Data&&); - Data& operator=(const Data&); - ~Data() noexcept; - std::string name; - std::string type; - std::string description; - //! specific description per modelling hypothesis - std::map descriptions; - std::string externalName; - std::vector hypotheses; - unsigned short arraySize; - }; - - Data::Data() = default; - Data::Data(Data&&) noexcept = default; - Data::Data(const Data&) = default; - Data& Data::operator=(Data&&) = default; - Data& Data::operator=(const Data&) = default; - Data::~Data() noexcept = default; - - static void getData(std::vector& data, - const BehaviourDescription& mb, - const VariableDescriptionContainer& (BehaviourData::*m)() - const, - const tfel::material::ModellingHypothesis::Hypothesis h) { + static void getData( + std::vector& data, + const BehaviourDescription& mb, + const VariableDescriptionContainer& (BehaviourData::*m)() const, + const tfel::material::ModellingHypothesis::Hypothesis h) { const auto& d = mb.getBehaviourData(h); const auto& mdata = (d.*m)(); for (auto pv = mdata.begin(); pv != mdata.end(); ++pv) { @@ -177,7 +118,7 @@ namespace mfront { } } if (pd == data.end()) { - data.push_back(Data()); + data.push_back(BehaviourDocumentationGenerator::VariableInformation()); pd = data.end(); --pd; pd->name = pv->name; @@ -226,13 +167,14 @@ namespace mfront { } } // end of - static std::vector getData( - const BehaviourDescription& mb, - const VariableDescriptionContainer& (BehaviourData::*m)() const) { + static std::vector + getData(const BehaviourDescription& mb, + const VariableDescriptionContainer& (BehaviourData::*m)() const) { using namespace tfel::material; using namespace tfel::glossary; const auto& glossary = Glossary::getGlossary(); - auto data = std::vector{}; + auto data = + std::vector{}; const auto& dh = mb.getDistinctModellingHypotheses(); for (const auto& h : dh) { getData(data, mb, m, h); @@ -294,12 +236,14 @@ namespace mfront { return data; } - static void printData(std::ostream& os, - const BehaviourDescription& mb, - const std::string& title, - const std::vector& data, - const bool standalone, - const std::string& language = "english") { + static void printData( + std::ostream& os, + const BehaviourDescription& mb, + const std::string& title, + const std::vector& + data, + const bool standalone, + const std::string& language = "english") { using namespace tfel::material; if (data.empty()) { return; @@ -471,138 +415,15 @@ namespace mfront { const char* const* const argv, std::shared_ptr d, const std::string& f) - : tfel::utilities::ArgumentParserBase( - argc, argv), - dsl(d), - file(f), - otype(BehaviourDocumentationGenerator::FULL) { - this->registerCommandLineCallBacks(); - this->parseArguments(); + + : DocumentationGeneratorBase(argc, argv, f), dsl(d) { // registring interfaces if (!this->interfaces.empty()) { dsl->setInterfaces(this->interfaces); } } // end of BehaviourDocumentationGenerator::BehaviourDocumentationGenerator - void BehaviourDocumentationGenerator::registerCommandLineCallBacks() { - using Parser = - tfel::utilities::ArgumentParserBase; - Parser::registerNewCallBack("--verbose", - &BehaviourDocumentationGenerator::treatVerbose, - "set verbose output", true); - this->registerNewCallBack( - "--dsl-option", &BehaviourDocumentationGenerator::treatDSLOption, - "allow to define options passed to domain specific languages", true); - this->registerNewCallBack( - "--material-property-dsl-option", - &BehaviourDocumentationGenerator::treatMaterialPropertyDSLOption, - "allow to define options passed to domain specific languages related " - "to material properties", - true); - this->registerNewCallBack( - "--behaviour-dsl-option", - &BehaviourDocumentationGenerator::treatBehaviourDSLOption, - "allow to define options passed to domain specific languages related " - "to behaviours", - true); - this->registerNewCallBack( - "--model-dsl-option", - &BehaviourDocumentationGenerator::treatModelDSLOption, - "allow to define options passed to domain specific languages related " - "to models", - true); - this->registerNewCallBack( - "--dsl-options-file", - &BehaviourDocumentationGenerator::treatDSLOptionsFile, - "allow to define options passed to domain specific languages thanks to " - "an external file in a JSON-like format", - true); - this->registerNewCallBack( - "--material-property-dsl-options-file", - &BehaviourDocumentationGenerator::treatMaterialPropertyDSLOptionsFile, - "allow to define options passed to domain specific languages related " - "to material properties thanks to an external file in a JSON-like " - "format", - true); - this->registerNewCallBack( - "--behaviour-dsl-options-file", - &BehaviourDocumentationGenerator::treatBehaviourDSLOptionsFile, - "allow to define options passed to domain specific languages related " - "to behaviours thanks to an external file in a JSON-like format", - true); - this->registerNewCallBack( - "--model-dsl-options-file", - &BehaviourDocumentationGenerator::treatModelDSLOptionsFile, - "allow to define options passed to domain specific languages related " - "to models thanks to an external file in a JSON-like format", - true); - Parser::registerNewCallBack( - "--unicode-output", - &BehaviourDocumentationGenerator::treatUnicodeOutput, - "allow/disallow unicode output", true); - Parser::registerNewCallBack( - "--include", "-I", &BehaviourDocumentationGenerator::treatSearchPath, - "add a new path at the beginning of the search paths", true); - Parser::registerNewCallBack( - "--search-path", &BehaviourDocumentationGenerator::treatSearchPath, - "add a new path at the beginning of the search paths", true); - this->registerNewCallBack( - "--madnex-search-path", - &BehaviourDocumentationGenerator::treatMadnexSearchPath, - "add a mandex file to the search paths", true); - Parser::registerCallBack( - "--standalone", - CallBack( - "generate a standalone document (false by default)", - [this]() noexcept { this->standalone = true; }, false)); - Parser::registerNewCallBack("--web", - &BehaviourDocumentationGenerator::treatWeb, - "output a web version of the file"); - Parser::registerCallBack( - "--std-output", "--", - CallBack( - "print the output ont the standard output stream", - [this]() noexcept { this->std_output = true; }, false)); - } // end of BehaviourDocumentationGenerator::registerCommandLineCallBacks - - void BehaviourDocumentationGenerator::treatUnknownArgument() { - if (!MFrontBase::treatUnknownArgumentBase()) { -#if !(defined _WIN32 || defined _WIN64 || defined __CYGWIN__) - ArgumentParserBase< - BehaviourDocumentationGenerator>::treatUnknownArgument(); -#else - auto a = static_cast( - this->getCurrentCommandLineArgument()); - std::cerr << "mfront : unsupported option '" << a << '\'' << std::endl; - exit(EXIT_FAILURE); -#endif /* __CYGWIN__ */ - } - } // end of BehaviourDocumentationGenerator::treatUnknownArgument - - const tfel::utilities::Argument& - BehaviourDocumentationGenerator::getCurrentCommandLineArgument() const { - return *(this->currentArgument); - } - - std::string BehaviourDocumentationGenerator::getVersionDescription() const { - return MFrontHeader::getHeader(); - } // end of BehaviourDocumentationGenerator::getVersionDescription - - std::string BehaviourDocumentationGenerator::getUsageDescription() const { - std::string usage("Usage : "); - usage += this->programName; - usage += " [options] [files]"; - return usage; - } // end of BehaviourDocumentationGenerator::getUsageDescription - - void BehaviourDocumentationGenerator::treatWeb() { - tfel::raise_if(this->otype != FULL, - "BehaviourDocumentationGenerator::treatWeb: " - "output type already specified"); - this->otype = WEB; - } // end of BehaviourDocumentationGenerator::treatWeb - - void BehaviourDocumentationGenerator::exe() { + void BehaviourDocumentationGenerator::exe() const { if (getVerboseMode() >= VERBOSE_LEVEL2) { getLogStream() << "Treating file '" << this->file << "'\n"; } @@ -630,7 +451,7 @@ namespace mfront { name + ".txt'"); return output_file; }(); - writeStandardLatexMacros(out); + DocumentationGeneratorBase::writeStandardLatexMacros(out); if (this->otype == FULL) { this->writeFullOutput(out, mb, fd); } else if (this->otype == WEB) { @@ -791,9 +612,24 @@ namespace mfront { out << basic_title_level // << "# Code documentation\n\n" << code << '\n'; - } - } // end of BehaviourDocumentationGenerator::writeFullOutput + } + } // end of BehaviourDocumentationGenerator::writeFullOutput BehaviourDocumentationGenerator::~BehaviourDocumentationGenerator() = default; + BehaviourDocumentationGenerator::VariableInformation::VariableInformation() = + default; + BehaviourDocumentationGenerator::VariableInformation::VariableInformation( + VariableInformation&&) noexcept = default; + BehaviourDocumentationGenerator::VariableInformation::VariableInformation( + const VariableInformation&) = default; + BehaviourDocumentationGenerator::VariableInformation& + BehaviourDocumentationGenerator::VariableInformation::operator=( + VariableInformation&&) = default; + BehaviourDocumentationGenerator::VariableInformation& + BehaviourDocumentationGenerator::VariableInformation::operator=( + const VariableInformation&) = default; + BehaviourDocumentationGenerator::VariableInformation:: + ~VariableInformation() noexcept = default; + } // end of namespace mfront diff --git a/mfront-doc/src/CMakeLists.txt b/mfront-doc/src/CMakeLists.txt index 8e25bd9d5..0c3ff7f71 100644 --- a/mfront-doc/src/CMakeLists.txt +++ b/mfront-doc/src/CMakeLists.txt @@ -1,6 +1,6 @@ # mfront-doc -add_executable(mfront-doc mfront-doc.cxx - BehaviourDocumentationGenerator.cxx) +add_executable(mfront-doc mfront-doc.cxx DocumentationGeneratorBase.cxx + BehaviourDocumentationGenerator.cxx MaterialPropertyDocumentationGenerator.cxx) set_property(TARGET mfront-doc PROPERTY POSITION_INDEPENDENT_CODE TRUE) target_include_directories(mfront-doc PRIVATE ${PROJECT_SOURCE_DIR}/mfront-doc/include) diff --git a/mfront-doc/src/DocumentationGeneratorBase.cxx b/mfront-doc/src/DocumentationGeneratorBase.cxx new file mode 100644 index 000000000..3bd6e008d --- /dev/null +++ b/mfront-doc/src/DocumentationGeneratorBase.cxx @@ -0,0 +1,212 @@ +/*! + * \file DocumentationGeneratorBase.cxx + * \brief + * \author Maxence Wangermez + * \date 16 avril 2024 + * \copyright Copyright (C) 2006-2024 CEA/DEN, EDF R&D. All rights + * reserved. + * This project is publicly released under either the GNU GPL Licence with + * linking exception or the CECILL-A licence. A copy of thoses licences are + * delivered with the sources of TFEL. CEA or EDF may also distribute this + * project under specific licensing conditions. + */ + +#include +#include +#include + +#include "TFEL/Raise.hxx" +#include "TFEL/Glossary/Glossary.hxx" +#include "TFEL/Glossary/GlossaryEntry.hxx" +#include "TFEL/Utilities/StringAlgorithms.hxx" +#include "MFront/MFrontLogStream.hxx" +#include "MFront/MFrontHeader.hxx" +#include "MFront/AbstractBehaviourDSL.hxx" +#include "MFront/VariableDescription.hxx" +#include "MFront/FileDescription.hxx" +#include "MFront/BehaviourDescription.hxx" +#include "MFront/DocumentationGeneratorBase.hxx" + +namespace mfront { + + // map::at() is missing in ekopath standard library + template + static typename Map::mapped_type map_at(const Map& m, + const typename Map::key_type& k) { + const auto p = m.find(k); + tfel::raise_if(p == m.end(), "map_at : unknown key '" + k + "'"); + return p->second; + } + + void DocumentationGeneratorBase::writeStandardLatexMacros(std::ostream& os) { + os << "\\newcommand{\\tensor}[1]{\\underline{#1}}\n" + << "\\newcommand{\\tensorq}[1]{\\underline{\\mathbf{#1}}}\n" + << "\\newcommand{\\ust}[1]{\\underset{\\tilde{}}{\\mathbf{#1}}}\n" + << "\\newcommand{\\transpose}[1]{#1^{\\mathop{T}}}\n" + << "\\newcommand{\\tsigma}{\\underline{\\sigma}}\n" + << "\\newcommand{\\sigmaeq}{\\sigma_{\\mathrm{eq}}}\n" + << "\\newcommand{\\epsilonth}{\\epsilon^{\\mathrm{th}}}\n" + << "\\newcommand{\\tepsilonto}{\\underline{\\epsilon}^{\\mathrm{to}}}\n" + << "\\newcommand{\\tepsilonel}{\\underline{\\epsilon}^{\\mathrm{el}}}\n" + << "\\newcommand{\\tepsilonth}{\\underline{\\epsilon}^{\\mathrm{th}}}\n" + << "\\newcommand{\\tepsilonvis}{\\underline{\\epsilon}^{\\mathrm{vis}}}" + "\n" + << "\\newcommand{\\tdepsilonvis}{\\underline{\\dot{\\epsilon}}^{" + "\\mathrm{vis}}}\n" + << "\\newcommand{\\tepsilonp}{\\underline{\\epsilon}^{\\mathrm{p}}}\n" + << "\\newcommand{\\tdepsilonp}{\\underline{\\dot{\\epsilon}}^{\\mathrm{" + "p}}}\n" + << "\\newcommand{\\trace}[1]{\\mathrm{tr}\\paren{#1}}\n" + << "\\newcommand{\\Frac}[2]{{\\displaystyle \\frac{\\displaystyle " + "#1}{\\displaystyle #2}}}\n" + << "\\newcommand{\\deriv}[2]{{\\displaystyle \\frac{\\displaystyle " + "\\partial #1}{\\displaystyle \\partial #2}}}\n" + << "\\newcommand{\\dtot}{\\mathrm{d}}\n" + << "\\newcommand{\\paren}[1]{\\left(#1\\right)}\n" + << "\\newcommand{\\bts}[1]{\\left.#1\\right|_{t}}\n" + << "\\newcommand{\\mts}[1]{\\left.#1\\right|_{t+\\theta\\,\\Delta\\,t}}" + "\n" + << "\\newcommand{\\ets}[1]{\\left.#1\\right|_{t+\\Delta\\,t}}\n\n"; + } // end of writeStandardLatexMacros + + DocumentationGeneratorBase::DocumentationGeneratorBase( + const int argc, const char* const* const argv, const std::string& f) + : tfel::utilities::ArgumentParserBase(argc, + argv), + file(f), + otype(DocumentationGeneratorBase::FULL) { + this->registerCommandLineCallBacks(); + this->parseArguments(); + + } // end of DocumentationGeneratorBase::DocumentationGeneratorBase + + void DocumentationGeneratorBase::registerCommandLineCallBacks() { + using Parser = + tfel::utilities::ArgumentParserBase; + Parser::registerNewCallBack("--verbose", + &DocumentationGeneratorBase::treatVerbose, + "set verbose output", true); + this->registerNewCallBack( + "--dsl-option", &DocumentationGeneratorBase::treatDSLOption, + "allow to define options passed to domain specific languages", true); + this->registerNewCallBack( + "--material-property-dsl-option", + &DocumentationGeneratorBase::treatMaterialPropertyDSLOption, + "allow to define options passed to domain specific languages related " + "to material properties", + true); + this->registerNewCallBack( + "--behaviour-dsl-option", + &DocumentationGeneratorBase::treatBehaviourDSLOption, + "allow to define options passed to domain specific languages related " + "to behaviours", + true); + this->registerNewCallBack( + "--model-dsl-option", &DocumentationGeneratorBase::treatModelDSLOption, + "allow to define options passed to domain specific languages related " + "to models", + true); + this->registerNewCallBack( + "--dsl-options-file", &DocumentationGeneratorBase::treatDSLOptionsFile, + "allow to define options passed to domain specific languages thanks to " + "an external file in a JSON-like format", + true); + this->registerNewCallBack( + "--material-property-dsl-options-file", + &DocumentationGeneratorBase::treatMaterialPropertyDSLOptionsFile, + "allow to define options passed to domain specific languages related " + "to material properties thanks to an external file in a JSON-like " + "format", + true); + this->registerNewCallBack( + "--behaviour-dsl-options-file", + &DocumentationGeneratorBase::treatBehaviourDSLOptionsFile, + "allow to define options passed to domain specific languages related " + "to behaviours thanks to an external file in a JSON-like format", + true); + this->registerNewCallBack( + "--model-dsl-options-file", + &DocumentationGeneratorBase::treatModelDSLOptionsFile, + "allow to define options passed to domain specific languages related " + "to models thanks to an external file in a JSON-like format", + true); + Parser::registerNewCallBack("--unicode-output", + &DocumentationGeneratorBase::treatUnicodeOutput, + "allow/disallow unicode output", true); + Parser::registerNewCallBack( + "--include", "-I", &DocumentationGeneratorBase::treatSearchPath, + "add a new path at the beginning of the search paths", true); + Parser::registerNewCallBack( + "--search-path", &DocumentationGeneratorBase::treatSearchPath, + "add a new path at the beginning of the search paths", true); + this->registerNewCallBack( + "--madnex-search-path", + &DocumentationGeneratorBase::treatMadnexSearchPath, + "add a mandex file to the search paths", true); + Parser::registerCallBack( + "--standalone", + CallBack( + "generate a standalone document (false by default)", + [this]() noexcept { this->standalone = true; }, false)); + Parser::registerNewCallBack("--web", &DocumentationGeneratorBase::treatWeb, + "output a web version of the file"); + Parser::registerCallBack( + "--std-output", "--", + CallBack( + "print the output ont the standard output stream", + [this]() noexcept { this->std_output = true; }, false)); + } // end of DocumentationGeneratorBase::registerCommandLineCallBacks + + void DocumentationGeneratorBase::treatUnknownArgument() { + if (!MFrontBase::treatUnknownArgumentBase()) { +#if !(defined _WIN32 || defined _WIN64 || defined __CYGWIN__) + ArgumentParserBase::treatUnknownArgument(); +#else + auto a = static_cast( + this->getCurrentCommandLineArgument()); + std::cerr << "mfront : unsupported option '" << a << '\'' << std::endl; + exit(EXIT_FAILURE); +#endif /* __CYGWIN__ */ + } + } // end of DocumentationGeneratorBase::treatUnknownArgument + + const tfel::utilities::Argument& + DocumentationGeneratorBase::getCurrentCommandLineArgument() const { + return *(this->currentArgument); + } + + std::string DocumentationGeneratorBase::getVersionDescription() const { + return MFrontHeader::getHeader(); + } // end of DocumentationGeneratorBase::getVersionDescription + + std::string DocumentationGeneratorBase::getUsageDescription() const { + std::string usage("Usage : "); + usage += this->programName; + usage += " [options] [files]"; + return usage; + } // end of DocumentationGeneratorBase::getUsageDescription + + void DocumentationGeneratorBase::treatWeb() { + tfel::raise_if(this->otype != FULL, + "DocumentationGeneratorBase::treatWeb: " + "output type already specified"); + this->otype = WEB; + } // end of DocumentationGeneratorBase::treatWeb + + DocumentationGeneratorBase::~DocumentationGeneratorBase() = default; + + DocumentationGeneratorBase::VariableInformationBase:: + VariableInformationBase() = default; + DocumentationGeneratorBase::VariableInformationBase::VariableInformationBase( + VariableInformationBase&&) noexcept = default; + DocumentationGeneratorBase::VariableInformationBase::VariableInformationBase( + const VariableInformationBase&) = default; + DocumentationGeneratorBase::VariableInformationBase& + DocumentationGeneratorBase::VariableInformationBase::operator=( + VariableInformationBase&&) = default; + DocumentationGeneratorBase::VariableInformationBase& + DocumentationGeneratorBase::VariableInformationBase::operator=( + const VariableInformationBase&) = default; + DocumentationGeneratorBase::VariableInformationBase:: + ~VariableInformationBase() noexcept = default; +} // end of namespace mfront diff --git a/mfront-doc/src/MaterialPropertyDocumentationGenerator.cxx b/mfront-doc/src/MaterialPropertyDocumentationGenerator.cxx new file mode 100644 index 000000000..f20ae279a --- /dev/null +++ b/mfront-doc/src/MaterialPropertyDocumentationGenerator.cxx @@ -0,0 +1,458 @@ +/*! + * \file MaterialPropertyDocumentationGenerator.cxx + * \brief + * \author Maxence Wangermez + * \date 16 avril 2024 + * \copyright Copyright (C) 2006-2024 CEA/DEN, EDF R&D. All rights + * reserved. + * This project is publicly released under either the GNU GPL Licence with + * linking exception or the CECILL-A licence. A copy of thoses licences are + * delivered with the sources of TFEL. CEA or EDF may also distribute this + * project under specific licensing conditions. + */ + +#include +#include +#include + +#include "TFEL/Raise.hxx" +#include "TFEL/Glossary/Glossary.hxx" +#include "TFEL/Glossary/GlossaryEntry.hxx" +#include "TFEL/Utilities/StringAlgorithms.hxx" +#include "MFront/DSLUtilities.hxx" +#include "MFront/MFrontLogStream.hxx" +#include "MFront/MFrontHeader.hxx" +#include "MFront/AbstractBehaviourDSL.hxx" +#include "MFront/VariableDescription.hxx" +#include "MFront/FileDescription.hxx" +#include "MFront/MaterialPropertyDescription.hxx" +#include "MFront/DocumentationGeneratorBase.hxx" +#include "MFront/MaterialPropertyDocumentationGenerator.hxx" + +namespace mfront { + + // map::at() is missing in ekopath standard library + template + static typename Map::mapped_type map_at(const Map& m, + const typename Map::key_type& k) { + const auto p = m.find(k); + tfel::raise_if(p == m.end(), "map_at : unknown key '" + k + "'"); + return p->second; + } + + static std::string getCodeBlocksDocumentation( + const MaterialPropertyDescription& mpd, + const FileDescription& fd, + const bool standalone) { + const auto* const basic_title_level = standalone ? "" : "#"; + std::ostringstream out; + const auto name = mfront::getMaterialLawLibraryNameBase(mpd); + const auto& c = mpd.f; + if (!fd.description.empty()) { + out << basic_title_level << "## " << name << " description\n" // + << fd.description << "\n\n"; + } + if (getVerboseMode() >= VERBOSE_DEBUG) { + out << basic_title_level << "## " << name << " listing\n" + << '\n' + << "~~~~~~~ {.cpp}\n" + << c.body << '\n' + << "~~~~~~~ \n"; + } + return out.str(); + } + + static void getData( + std::vector& + data, + const VariableDescription& v) { + auto ndata = MaterialPropertyDocumentationGenerator::VariableInformation{}; + ndata.name = v.name; + ndata.arraySize = v.arraySize; + ndata.type = v.type; + ndata.externalName = v.getExternalName(); + ndata.description = v.description; + + data.push_back(ndata); + } // end of getData + + static void getData( + std::vector& + data, + const StaticVariableDescription& v) { + auto ndata = MaterialPropertyDocumentationGenerator::VariableInformation{}; + ndata.name = v.name; + ndata.arraySize = v.arraySize; + ndata.type = v.type; + ndata.description = v.description; + data.push_back(ndata); + } // end of getData + + static std::vector< + MaterialPropertyDocumentationGenerator::VariableInformation> + getData(const VariableDescription& vd) { + using namespace tfel::material; + using namespace tfel::glossary; + auto data = std::vector< + MaterialPropertyDocumentationGenerator::VariableInformation>{}; + getData(data, vd); + // description deserves a specific treatment + return data; + } + + static std::vector< + MaterialPropertyDocumentationGenerator::VariableInformation> + getData(const VariableDescriptionContainer& vdc) { + using namespace tfel::material; + using namespace tfel::glossary; + const auto& glossary = Glossary::getGlossary(); + auto data = std::vector< + MaterialPropertyDocumentationGenerator::VariableInformation>{}; + for (const auto& vd : vdc) { + getData(data, vd); + } + // description deserves a specific treatment + for (auto& d : data) { + if (glossary.contains(d.externalName)) { + const auto& e = glossary.getGlossaryEntry(d.externalName); + std::ostringstream os; + os << e.getShortDescription(); + const auto& cd = e.getDescription(); + for (const auto& cd_pcd : cd) { + if (!cd_pcd.empty()) { + os << cd_pcd << '\n'; + } + } + d.description += os.str(); + } + } + return data; + } + + static std::vector< + MaterialPropertyDocumentationGenerator::VariableInformation> + getData(const StaticVariableDescriptionContainer& vdc) { + using namespace tfel::material; + using namespace tfel::glossary; + const auto& glossary = Glossary::getGlossary(); + auto data = std::vector< + MaterialPropertyDocumentationGenerator::VariableInformation>{}; + for (const auto& vd : vdc) { + getData(data, vd); + } + // description deserves a specific treatment + for (auto& d : data) { + if (glossary.contains(d.externalName)) { + const auto& e = glossary.getGlossaryEntry(d.externalName); + std::ostringstream os; + os << e.getShortDescription(); + const auto& cd = e.getDescription(); + for (const auto& cd_pcd : cd) { + if (!cd_pcd.empty()) { + os << cd_pcd << '\n'; + } + } + d.description += os.str(); + } + } + return data; + } + + static void printData( + std::ostream& os, + const std::string& title, + const std::vector< + MaterialPropertyDocumentationGenerator::VariableInformation>& data, + const bool standalone, + const std::string& language = "english") { + using namespace tfel::material; + if (data.empty()) { + return; + } + const auto* const basic_title_level = standalone ? "" : "#"; + auto translations = + std::map>{}; + auto& en = translations["english"]; + auto& fr = translations["french"]; + en["variable name"] = "variable name"; + fr["variable name"] = "nom"; + en["variable type"] = "variable type"; + fr["variable type"] = "type"; + en["array size"] = "array size"; + fr["array size"] = "taille"; + en["defined for"] = "defined for"; + fr["defined for"] = "définie pour"; + en["description"] = "description"; + fr["description"] = "description"; + en["default value"] = "default value"; + fr["default value"] = "valeur par défaut"; + en["default value for"] = "default value for"; + fr["default value for"] = + "valeur par défaut pour l'hypothèse de modélsation "; + const auto& l = translations[language]; + if (getVerboseMode() >= VERBOSE_DEBUG) { + auto& log = getLogStream(); + log << "printData : begin\n"; + } + os << basic_title_level // + << "## " << title << "\n\n"; + for (const auto& d : data) { + os << "* " << d.externalName << ":\n"; + if (d.externalName != d.name) { + os << "\t+ " << map_at(l, "variable name") << ": " << d.name << '\n'; + } + os << "\t+ " << map_at(l, "variable type") << ": " << d.type << '\n'; + if (d.arraySize != 1u) { + os << "\t+ " << map_at(l, "array size") << ": " << d.arraySize << '\n'; + } + if (!d.description.empty()) { + os << "\t+ " << map_at(l, "description") << ": " << d.description + << '\n'; + } + + // codes blocks referring to the current variable + auto vcb = + std::map>{}; + auto dvcb = + std::map>{}; + if (getVerboseMode() >= VERBOSE_DEBUG) { + if (!vcb.empty()) { + os << "\t+ used in "; + for (auto pc = vcb.begin(); pc != vcb.end();) { + os << pc->first; + if (++pc != vcb.end()) { + os << ", "; + } + } + os << '\n'; + } + if (!dvcb.empty()) { + os << "\t+ increment (or rate) used in "; + for (auto pc = dvcb.begin(); pc != dvcb.end();) { + os << pc->first; + if (++pc != dvcb.end()) { + os << ", "; + } + } + os << '\n'; + } + } + } + // bounds + if (getVerboseMode() >= VERBOSE_DEBUG) { + auto& log = getLogStream(); + log << "printData : end\n"; + } + } + + MaterialPropertyDocumentationGenerator:: + MaterialPropertyDocumentationGenerator( + const int argc, + const char* const* const argv, + std::shared_ptr d, + const std::string& f) + + : DocumentationGeneratorBase(argc, argv, f), dsl(d) { + // registring interfaces + if (!this->interfaces.empty()) { + dsl->setInterfaces(this->interfaces); + } + } // end of + // MaterialPropertyDocumentationGenerator::MaterialPropertyDocumentationGenerator + + void MaterialPropertyDocumentationGenerator::exe() const { + if (getVerboseMode() >= VERBOSE_LEVEL2) { + getLogStream() << "Treating file '" << this->file << "'\n"; + } + // analysing the file + this->dsl->analyseFile(this->file, this->ecmds, this->substitutions); + const auto& fd = this->dsl->getFileDescription(); + const auto& mpd = this->dsl->getMaterialPropertyDescription(); + if (getVerboseMode() >= VERBOSE_DEBUG) { + auto& log = getLogStream(); + log << "MaterialPropertyDocumentationGenerator::exe : begin\n"; + } + std::ofstream output_file; + auto& out = [&output_file, &mpd, this]() -> std::ostream& { + if (this->std_output) { + return std::cout; + } + const auto name = mpd.material.empty() + ? mpd.className + : mpd.material + "_" + mpd.className; + output_file.open(name + ".md"); + output_file.exceptions(std::ios::badbit | std::ios::failbit); + tfel::raise_if(!output_file, + "MaterialPropertyDocumentationGenerator::exe: " + "could not open file 'src/" + + name + ".txt'"); + return output_file; + }(); + DocumentationGeneratorBase::writeStandardLatexMacros(out); + if (this->otype == FULL) { + this->writeFullOutput(out, mpd, fd); + } else if (this->otype == WEB) { + this->writeWebOutput(out, mpd, fd); + } else { + tfel::raise( + "MaterialPropertyDocumentationGenerator::exe: " + "unsupported output type"); + } + if (!this->std_output) { + output_file.close(); + } + if (getVerboseMode() >= VERBOSE_DEBUG) { + getLogStream() << "MaterialPropertyDocumentationGenerator::exe : end\n"; + } + } // end of MaterialPropertyDocumentationGenerator::exe + + void MaterialPropertyDocumentationGenerator::writeWebOutput( + std::ostream& out, + const MaterialPropertyDescription& mpd, + const FileDescription& fd) const { + using namespace tfel::utilities; + out << "# " << mfront::getMaterialLawLibraryNameBase(mpd) << mpd.className + << " material property description\n\n" + << "* file : " << fd.fileName << '\n' + << "* author : "; + if (!fd.authorName.empty()) { + out << fd.authorName << '\n'; + } else { + out << "(unspecified)\n"; + } + out << "* date : "; + if (!fd.date.empty()) { + out << fd.date; + } else { + out << "(unspecified)\n"; + } + out << "\n\n"; + if (!fd.description.empty()) { + const auto d = tokenize(fd.description, '\n'); + for (const auto& l : d) { + if ((l.size() >= 2) && ((l)[0] == '*') && ((l)[1] == ' ')) { + out << l.substr(2) << '\n'; + } else { + out << l << '\n'; + } + } + } else { + out << "No description specified\n"; + } + // + std::ifstream f(this->file); + tfel::raise_if(!f, + "MaterialPropertyDocumentationGenerator::writeWebOutput: " + "can't open file '" + + this->file + "'"); + out << '\n' + << "## Source code\n" + << '\n' + << "~~~~{#" << mpd.className << " .cpp .numberLines}\n" + << f.rdbuf() << '\n' + << "~~~~\n" + << '\n'; + } // end of MaterialPropertyDocumentationGenerator::writeWebOutput + + void MaterialPropertyDocumentationGenerator::writeFullOutput( + std::ostream& out, + const MaterialPropertyDescription& mpd, + const FileDescription& fd) const { + using namespace tfel::utilities; + using namespace tfel::material; + const auto* const basic_title_level = this->standalone ? "" : "#"; + if (this->standalone) { + out << "---\n" + << "title: Description of material property " + << mfront::getMaterialLawLibraryNameBase(mpd) << mpd.className + << '\n'; + if (!fd.authorName.empty()) { + out << "author: " << fd.authorName << '\n'; + } + if (!fd.date.empty()) { + out << "date: " << fd.date << '\n'; + } + out << "lang: en-EN\n" + << "link-citations: true\n" + << "colorlinks: true\n" + << "figPrefixTemplate: $$i$$\n" + << "tblPrefixTemplate: $$i$$\n" + << "secPrefixTemplate: $$i$$\n" + << "eqnPrefixTemplate: ($$i$$)\n" + << "---"; + } else { + out << "# " << mfront::getMaterialLawLibraryNameBase(mpd) << '_' + << mpd.className << " material property description\n\n" + << "* file: " << fd.fileName << '\n' + << "* author: "; + if (!fd.authorName.empty()) { + out << fd.authorName << '\n'; + } else { + out << "(unspecified)\n"; + } + out << "* date: "; + if (!fd.date.empty()) { + out << fd.date; + } else { + out << "(unspecified)"; + } + } + out << "\n\n"; + if (!fd.description.empty()) { + const auto d = tokenize(fd.description, '\n'); + for (const auto& l : d) { + if ((l.size() >= 2) && ((l)[0] == '*') && ((l)[1] == ' ')) { + out << l.substr(2) << '\n'; + } else { + out << l << '\n'; + } + } + } else { + out << "No description specified\n"; + } + + out << '\n' << basic_title_level << "# Variables\n\n"; + + if (!mpd.inputs.empty()) { + printData(out, "Inputs", getData(mpd.inputs), this->standalone); + out << '\n'; + } + + printData(out, "Outputs", getData(mpd.output), this->standalone); + + if (!areParametersTreatedAsStaticVariables(mpd)) { + if (mpd.hasParameters()) { + out << '\n'; + printData(out, "Parameters", getData(mpd.parameters), this->standalone); + } + } + out << '\n'; + printData(out, "Constantes", getData(mpd.staticVars), this->standalone); + + const auto code = getCodeBlocksDocumentation(mpd, fd, this->standalone); + if (!code.empty() != 0) { + out << basic_title_level // + << "# Code documentation\n\n" + << code << '\n'; + } + } // end of MaterialPropertyDocumentationGenerator::writeFullOutput + + MaterialPropertyDocumentationGenerator:: + ~MaterialPropertyDocumentationGenerator() = default; + + MaterialPropertyDocumentationGenerator::VariableInformation:: + VariableInformation() = default; + MaterialPropertyDocumentationGenerator::VariableInformation:: + VariableInformation(VariableInformation&&) noexcept = default; + MaterialPropertyDocumentationGenerator::VariableInformation:: + VariableInformation(const VariableInformation&) = default; + MaterialPropertyDocumentationGenerator::VariableInformation& + MaterialPropertyDocumentationGenerator::VariableInformation::operator=( + VariableInformation&&) = default; + MaterialPropertyDocumentationGenerator::VariableInformation& + MaterialPropertyDocumentationGenerator::VariableInformation::operator=( + const VariableInformation&) = default; + MaterialPropertyDocumentationGenerator::VariableInformation:: + ~VariableInformation() noexcept = default; + +} // end of namespace mfront diff --git a/mfront-doc/src/mfront-doc.cxx b/mfront-doc/src/mfront-doc.cxx index 132e03e5e..09a009dd6 100644 --- a/mfront-doc/src/mfront-doc.cxx +++ b/mfront-doc/src/mfront-doc.cxx @@ -30,16 +30,18 @@ #include "MFront/InitInterfaces.hxx" #include "MFront/MFrontHeader.hxx" #include "MFront/MFrontBase.hxx" -#include "MFront/BehaviourDocumentationGenerator.hxx" #include "MFront/AbstractDSL.hxx" #include "MFront/AbstractBehaviourDSL.hxx" +#include "MFront/MaterialPropertyDSL.hxx" +#include "MFront/DocumentationGeneratorBase.hxx" +#include "MFront/BehaviourDocumentationGenerator.hxx" +#include "MFront/MaterialPropertyDocumentationGenerator.hxx" #include "MFront/PathSpecifier.hxx" #include "MFront/SearchPathsHandler.hxx" /* coverity [UNCAUGHT_EXCEPT]*/ int main(const int argc, const char* const* const argv) { using namespace mfront; - using BGen = BehaviourDocumentationGenerator; initDSLs(); initInterfaces(); auto current_path_specifier = mfront::PathSpecifier{}; @@ -74,14 +76,23 @@ int main(const int argc, const char* const* const argv) { mfront::getImplementationsPaths(path_specifiers); SearchPathsHandler::addSearchPathsFromImplementationPaths(implementations); // - auto bgens = std::vector>{}; + auto bgens = + std::vector>{}; + auto mpgens = + std::vector>{}; for (const auto& f : implementations) { auto dsl = MFrontBase::getDSL(f); if (dsl->getTargetType() == AbstractDSL::BEHAVIOURDSL) { auto b = std::dynamic_pointer_cast(dsl); tfel::raise_if(!b, "mfront-doc: invalid dsl implementation"); - bgens.push_back(std::make_shared( + bgens.push_back(std::make_shared( untreated_arguments.size(), untreated_arguments.data(), b, f)); + } else if (dsl->getTargetType() == AbstractDSL::MATERIALPROPERTYDSL) { + auto b = std::dynamic_pointer_cast(dsl); + tfel::raise_if(!b, "mfront-doc: invalid dsl implementation"); + mpgens.push_back( + std::make_shared( + untreated_arguments.size(), untreated_arguments.data(), b, f)); } else { tfel::raise("mfront-doc: unsupported dsl type"); } @@ -90,6 +101,9 @@ int main(const int argc, const char* const* const argv) { for (const auto& q : bgens) { q->exe(); } + for (const auto& q : mpgens) { + q->exe(); + } #if defined _WIN32 || defined _WIN64 || defined __CYGWIN__ } catch (std::exception& e) { MessageBox(nullptr, e.what(), "mfront", 0); diff --git a/mfront/include/MFront/MaterialPropertyDescription.hxx b/mfront/include/MFront/MaterialPropertyDescription.hxx index 2e477cde0..ce4a1e0ef 100644 --- a/mfront/include/MFront/MaterialPropertyDescription.hxx +++ b/mfront/include/MFront/MaterialPropertyDescription.hxx @@ -106,6 +106,15 @@ namespace mfront { * \brief append the given code to the sources */ void appendToSources(const std::string&); + /*! + * \return true a parameter with the given name has been declared + * \param[in] n: name + */ + bool hasParameter(const std::string&) const; + /*! + * \return true if at least one parameter has been declared + */ + bool hasParameters() const; /*! * \brief register a name. * \param[in] n : name diff --git a/mfront/src/MaterialPropertyDescription.cxx b/mfront/src/MaterialPropertyDescription.cxx index 22e367e82..e449eb487 100644 --- a/mfront/src/MaterialPropertyDescription.cxx +++ b/mfront/src/MaterialPropertyDescription.cxx @@ -62,9 +62,9 @@ namespace mfront { const auto use_qt = (areQuantitiesSupported && useQuantities(mpd)) ? "true" : "false"; for (const auto& a : getScalarTypeAliases()) { - os << "using " << a << " [[maybe_unused]] = " - << "typename tfel::config::ScalarTypes<" << numeric_type << ", " - << use_qt << ">::" << a << ";\n"; + os << "using " << a + << " [[maybe_unused]] = " << "typename tfel::config::ScalarTypes<" + << numeric_type << ", " << use_qt << ">::" << a << ";\n"; } } // end of writeScalarStandardTypedefs @@ -306,6 +306,17 @@ namespace mfront { } } // end of addMaterialLaw + bool MaterialPropertyDescription::hasParameter(const std::string& v) const { + return this->parameters.contains(v); + } // end of hasParameter + + bool MaterialPropertyDescription::hasParameters() const { + if (!this->parameters.empty()) { + return true; + } + return false; + } // end of hasParameters + void MaterialPropertyDescription::reserveName(const std::string& n) { tfel::raise_if(!this->reservedNames.insert(n).second, "MaterialPropertyDescription::reserveName: "