LCOV - code coverage report
Current view: top level - src/base - Capabilities.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: #33390 (250e9c) with base 846a5c Lines: 229 234 97.9 %
Date: 2026-07-31 18:15:22 Functions: 18 18 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //* This file is part of the MOOSE framework
       2             : //* https://mooseframework.inl.gov
       3             : //*
       4             : //* All rights reserved, see COPYRIGHT for full restrictions
       5             : //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
       6             : //*
       7             : //* Licensed under LGPL 2.1, please see LICENSE for details
       8             : //* https://www.gnu.org/licenses/lgpl-2.1.html
       9             : 
      10             : // Needs to be included before Capabilities.h, which
      11             : // includes nlohmann/json_fwd.h
      12             : #include "nlohmann/json.h"
      13             : 
      14             : #include "Capabilities.h"
      15             : #include "CapabilityException.h"
      16             : #include "MooseUtils.h"
      17             : #include "Conversion.h"
      18             : 
      19             : #include <vector>
      20             : 
      21             : #include "libmesh/libmesh_config.h"
      22             : #include "petscconf.h"
      23             : #include "petscpkg_version.h"
      24             : 
      25             : #ifdef MOOSE_LIBTORCH_ENABLED
      26             : #include <torch/version.h>
      27             : #endif
      28             : 
      29             : #if __has_include(<torch/xpu.h>)
      30             : #include <torch/xpu.h>
      31             : #define MOOSE_HAVE_XPU 1
      32             : #endif
      33             : 
      34             : #ifdef MOOSE_MFEM_ENABLED
      35             : #include "mfem/config/config.hpp"
      36             : #endif
      37             : 
      38             : #ifdef LIBMESH_HAVE_NETGEN
      39             : #include "netgen/netgen_version.hpp"
      40             : #endif
      41             : 
      42             : namespace Moose::internal
      43             : {
      44             : 
      45       55395 : Capabilities::Capabilities() : CapabilityRegistry()
      46             : {
      47             :   // Register the moose capabilities, just once
      48       55395 :   registerMooseCapabilities();
      49       55395 : }
      50             : 
      51             : Capabilities &
      52      647820 : Capabilities::getCapabilities(const Capabilities::GetCapabilitiesPassKey)
      53             : {
      54             :   // We need a naked new here (_not_ a smart pointer or object instance) due to what seems like a
      55             :   // bug in clang's static object destruction when using dynamic library loading.
      56             :   static Capabilities * capability_registry = nullptr;
      57      647820 :   if (!capability_registry)
      58       55395 :     capability_registry = new Capabilities();
      59      647820 :   return *capability_registry;
      60             : }
      61             : 
      62             : std::string
      63          21 : Capabilities::dump() const
      64             : {
      65          21 :   nlohmann::json root;
      66        1151 :   for (const auto & [name, capability] : _registry)
      67             :   {
      68        1130 :     auto & entry = root[name];
      69        2260 :     std::visit([&entry](const auto & v) { entry["value"] = v; }, capability.getValue());
      70        1130 :     entry["doc"] = capability.getDoc();
      71        1130 :     if (const auto enumeration_ptr = capability.queryEnumeration())
      72        1130 :       entry["enumeration"] = *enumeration_ptr;
      73        1130 :     if (!capability.hasBoolValue())
      74         560 :       entry["explicit"] = capability.getExplicit();
      75             :   }
      76          42 :   return root.dump(2);
      77          21 : }
      78             : 
      79             : void
      80         389 : Capabilities::augment(const nlohmann::json & input, const Capabilities::AugmentPassKey)
      81             : {
      82         828 :   for (const auto & [name_json, entry] : input.items())
      83             :   {
      84         445 :     const std::string name = name_json;
      85             : 
      86           6 :     const auto error = [&name](const std::string & message)
      87           6 :     { throw CapabilityException("Capabilities::augment: Capability '" + name + "' " + message); };
      88             : 
      89         445 :     std::string doc;
      90         445 :     if (const auto it = entry.find("doc"); it != entry.end())
      91         441 :       doc = *it;
      92             :     else
      93           8 :       error("missing 'doc' entry");
      94             : 
      95         441 :     Moose::Capability::Value value;
      96         441 :     if (const auto it = entry.find("value"); it != entry.end())
      97             :     {
      98         439 :       if (it->is_boolean())
      99         124 :         value = it->get<bool>();
     100         315 :       else if (it->is_number_integer())
     101          16 :         value = it->get<int>();
     102             :       else
     103         299 :         value = it->get<std::string>();
     104             :     }
     105             :     else
     106           4 :       error("missing 'value' entry");
     107             : 
     108         439 :     auto & capability = add(name, value, doc);
     109             : 
     110         439 :     if (const auto it = entry.find("explicit"); it != entry.end() && it->get<bool>())
     111         291 :       capability.setExplicit();
     112             : 
     113         439 :     if (const auto it = entry.find("enumeration"); it != entry.end())
     114         283 :       capability.setEnumeration(it->get<std::set<std::string>>());
     115         848 :   }
     116         383 : }
     117             : 
     118             : bool
     119          24 : Capabilities::isInstallationType(const std::string & installation_type) const
     120             : {
     121          48 :   const auto & capability = get("installation_type");
     122             :   mooseAssert(capability.getEnumeration().count(installation_type), "Not a valid enumeration");
     123          24 :   return capability.getStringValue() == installation_type;
     124             : }
     125             : 
     126             : void
     127       55401 : Capabilities::registerMooseCapabilities()
     128             : {
     129             :   // helper lambdas for explicitly adding typed capabilities
     130     1465351 :   const auto add_bool = [&](const std::string_view capability,
     131             :                             const bool value,
     132             :                             const std::string_view doc) -> Capability &
     133     1465351 :   { return add(capability, value, doc); };
     134      110802 :   const auto add_int = [&](const std::string_view capability,
     135             :                            const int value,
     136             :                            const std::string_view doc) -> Capability &
     137      110802 :   { return add(capability, value, doc); };
     138     1138496 :   const auto add_string = [&](const std::string_view capability,
     139             :                               const std::string_view value,
     140             :                               const std::string_view doc) -> Capability &
     141     3415488 :   { return add(capability, std::string(value), doc); };
     142             : 
     143             :   // helper lambdas for adding capabilities
     144      448457 :   const auto have = [&](const std::string & capability, const std::string & doc) -> Capability &
     145      448457 :   { return add_bool(capability, true, doc + " is available."); };
     146      410959 :   const auto missing = [&](const std::string & capability,
     147             :                            const std::string & doc,
     148             :                            const std::string & help = "") -> Capability &
     149      410959 :   { return add_bool(capability, false, doc + " is not available. " + help); };
     150             : 
     151      166203 :   const auto have_version = [&](const std::string & capability,
     152             :                                 const std::string & doc,
     153             :                                 const std::string & version) -> Capability &
     154      166203 :   { return add_string(capability, version, doc + " version " + version + " is available."); };
     155      110802 :   const auto petsc_missing = [&](const std::string & capability,
     156             :                                  const std::string & doc) -> Capability &
     157             :   {
     158      110802 :     return add_bool(
     159      221604 :         capability, false, doc + " is not available. Check your PETSc configure options.");
     160       55401 :   };
     161      384331 :   const auto libmesh_missing = [&](const std::string & capability,
     162             :                                    const std::string & doc,
     163             :                                    const std::string & config_option) -> Capability &
     164             :   {
     165      384331 :     return add_bool(capability,
     166             :                     false,
     167      768662 :                     doc + " is not available. It is controlled by the `" + config_option +
     168      768662 :                         "` libMesh configure option.");
     169       55401 :   };
     170             : 
     171             :   {
     172       55401 :     const auto doc = "LibTorch machine learning and parallel tensor algebra library";
     173             : #ifdef MOOSE_LIBTORCH_ENABLED
     174        1773 :     add_string("libtorch", TORCH_VERSION, doc);
     175             : #else
     176      268140 :     missing("libtorch",
     177             :             doc,
     178             :             "Check "
     179             :             "https://mooseframework.inl.gov/moose/getting_started/installation/"
     180             :             "install_libtorch.html for "
     181             :             "instructions on how to configure and build moose with libTorch.");
     182             : #endif
     183             :   }
     184             : 
     185             :   {
     186       55401 :     const auto doc = "MFEM finite element library";
     187             : #ifdef MOOSE_MFEM_ENABLED
     188       41183 :     add_string("mfem", MFEM_VERSION_STRING, doc);
     189             : #else
     190       71090 :     missing("mfem",
     191             :             doc,
     192             :             "Install mfem using the scripts/update_and_rebuild_mfem.sh script after "
     193             :             "first running scripts/update_and_rebuild_conduit.sh. Finally, configure "
     194             :             "moose with ./configure --with-mfem");
     195             : #endif
     196             :   }
     197             : 
     198             :   {
     199       55401 :     const auto doc = "New Engineering Material model Library, version 2";
     200             : #ifdef NEML2_ENABLED
     201        5319 :     have("neml2", doc);
     202             : #else
     203      268140 :     missing("neml2",
     204             :             doc,
     205             :             "Install neml2 using the scripts/update_and_rebuild_neml2.sh script, then "
     206             :             "configure moose with ./configure --with-neml2 --with-libtorch");
     207             : #endif
     208             :   }
     209             : 
     210             :   {
     211       55401 :     const auto doc = "gperftools code performance analysis and profiling library";
     212             : #ifdef HAVE_GPERFTOOLS
     213             :     have("gperftools", doc);
     214             : #else
     215      277005 :     missing("gperftools",
     216             :             doc,
     217             :             "Check https://mooseframework.inl.gov/application_development/profiling.html "
     218             :             "for instructions on profiling MOOSE based applications.");
     219             : #endif
     220             :   }
     221             : 
     222             :   {
     223       55401 :     const auto doc = "libPNG portable network graphics format library";
     224             : #ifdef MOOSE_HAVE_LIBPNG
     225      166203 :     have("libpng", doc);
     226             : #else
     227             :     missing("libpng",
     228             :             doc,
     229             :             "Install libpng through conda or your distribution and check that it gets "
     230             :             "detected through pkg-config, then reconfigure and rebuild MOOSE.");
     231             : #endif
     232             :   }
     233             : 
     234             :   {
     235       55401 :     const auto doc = "NVIDIA GPU parallel computing platform";
     236             : #ifdef PETSC_HAVE_CUDA
     237             :     const std::string version = QUOTE(PETSC_PKG_CUDA_VERSION_MAJOR) "." QUOTE(
     238        1738 :         PETSC_PKG_CUDA_VERSION_MINOR) "." QUOTE(PETSC_PKG_CUDA_VERSION_SUBMINOR);
     239        1738 :     add_string("cuda", version, doc);
     240             : #else
     241      268315 :     missing("cuda", doc, "Add the CUDA bin directory to your path and rebuild PETSc.");
     242             : #endif
     243        1738 :   }
     244             : 
     245             :   {
     246       55401 :     const auto doc = "AMD GPU parallel computing platform";
     247             : #ifdef PETSC_HAVE_HIPROCM
     248             :     const std::string version = QUOTE(PETSC_PKG_HIP_VERSION_MAJOR) "." QUOTE(
     249             :         PETSC_PKG_HIP_VERSION_MINOR) "." QUOTE(PETSC_PKG_HIP_VERSION_SUBMINOR);
     250             :     add_string("hip", version, doc);
     251             : #else
     252      277005 :     missing("hip", doc, "Add the HIP bin directory to your path and rebuild PETSc.");
     253             : #endif
     254             :   }
     255             : 
     256             :   {
     257       55401 :     const auto doc = "Intel GPU parallel computing platform";
     258             : #ifdef PETSC_HAVE_SYCL
     259             :     const std::string version = QUOTE(PETSC_PKG_SYCL_VERSION_MAJOR) "." QUOTE(
     260             :         PETSC_PKG_SYCL_VERSION_MINOR) "." QUOTE(PETSC_PKG_SYCL_VERSION_SUBMINOR);
     261             :     add_string("sycl", version, doc);
     262             : #else
     263      277005 :     missing("sycl", doc, "Add the SYCL bin directory to your path and rebuild PETSc.");
     264             : #endif
     265             :   }
     266             : 
     267             :   {
     268       55401 :     const auto doc = "Kokkos performance portability programming ecosystem";
     269             : #ifdef MOOSE_KOKKOS_ENABLED
     270             :     const std::string version = QUOTE(PETSC_PKG_KOKKOS_VERSION_MAJOR) "." QUOTE(
     271       41183 :         PETSC_PKG_KOKKOS_VERSION_MINOR) "." QUOTE(PETSC_PKG_KOKKOS_VERSION_SUBMINOR);
     272       41183 :     add_string("kokkos", version, doc);
     273             : #else
     274       71090 :     missing("kokkos",
     275             :             doc,
     276             :             "Rebuild PETSc with Kokkos support and libMesh. Then, reconfigure MOOSE with "
     277             :             "--with-kokkos.");
     278             : #endif
     279       41183 :   }
     280             : 
     281             :   {
     282       55401 :     const auto doc = "Kokkos support for PETSc";
     283             : #ifdef PETSC_HAVE_KOKKOS
     284             :     const std::string version = QUOTE(PETSC_PKG_KOKKOS_VERSION_MAJOR) "." QUOTE(
     285       55401 :         PETSC_PKG_KOKKOS_VERSION_MINOR) "." QUOTE(PETSC_PKG_KOKKOS_VERSION_SUBMINOR);
     286       55401 :     add_string("petsc_kokkos", version, doc);
     287             : #else
     288             :     missing(
     289             :         "petsc_kokkos", doc, "Rebuild PETSc with Kokkos support, then rebuild libMesh and MOOSE.");
     290             : #endif
     291       55401 :   }
     292             : 
     293             :   {
     294       55401 :     const auto doc = "Intel OneAPI XPU accelerator support";
     295             : #ifdef MOOSE_HAVE_XPU
     296        1773 :     if (torch::xpu::is_available())
     297           0 :       have("xpu", doc);
     298             :     else
     299       10638 :       missing("xpu", doc, "No usable XPU devices have been found.");
     300             : #else
     301      268140 :     missing("xpu", doc, "The torch version used to build this app has no XPU support.");
     302             : #endif
     303             :   }
     304             : 
     305       55401 :   add_int(
     306             :       "ad_size",
     307             :       MOOSE_AD_MAX_DOFS_PER_ELEM,
     308      110802 :       "MOOSE was configured and built with a dual number backing store size of " +
     309      221604 :           Moose::stringify(MOOSE_AD_MAX_DOFS_PER_ELEM) +
     310             :           ". Complex simulations with many variables or contact problems may require larger "
     311             :           "values. Reconfigure MOOSE with the --with-derivative-size=<n> option in the root of the "
     312             :           "repository.")
     313       55401 :       .setExplicit();
     314             : 
     315             :   {
     316       55401 :     const std::string method = QUOTE(METHOD);
     317      110802 :     add_string("method", method, "The executable was built with METHOD=\"" + method + "\"")
     318       55401 :         .setExplicit()
     319       55401 :         .setEnumeration({"dbg", "devel", "oprof", "opt"});
     320       55401 :   }
     321             : 
     322             :   {
     323             :     const std::string version = QUOTE(LIBMESH_DETECTED_PETSC_VERSION_MAJOR) "." QUOTE(
     324       55401 :         LIBMESH_DETECTED_PETSC_VERSION_MINOR) "." QUOTE(LIBMESH_DETECTED_PETSC_VERSION_SUBMINOR);
     325       55401 :     add_string("petsc", version, "Using PETSc version " + version + ".");
     326       55401 :   }
     327             : 
     328             : #ifdef LIBMESH_PETSC_USE_DEBUG
     329       55401 :   add_bool("petsc_debug", true, "PETSc was built with debugging options.");
     330             : #else
     331             :   add_bool("petsc_debug", false, "PETSc was built without debugging options.");
     332             : #endif
     333             : 
     334             :   {
     335       55401 :     const auto doc = "SuperLU direct solver";
     336             : #ifdef LIBMESH_PETSC_HAVE_SUPERLU_DIST
     337             :     const std::string version = QUOTE(PETSC_PKG_SUPERLU_DIST_VERSION_MAJOR) "." QUOTE(
     338       55401 :         PETSC_PKG_SUPERLU_DIST_VERSION_MINOR) "." QUOTE(PETSC_PKG_SUPERLU_DIST_VERSION_SUBMINOR);
     339       55401 :     add_string("superlu", version, doc);
     340             : #else
     341             :     petsc_missing("superlu", doc);
     342             : #endif
     343       55401 :   }
     344             : 
     345             :   {
     346       55401 :     const auto doc = "MUltifrontal Massively Parallel sparse direct Solver (MUMPS)";
     347             : #ifdef LIBMESH_PETSC_HAVE_MUMPS
     348             :     const std::string version = QUOTE(PETSC_PKG_MUMPS_VERSION_MAJOR) "." QUOTE(
     349       55401 :         PETSC_PKG_MUMPS_VERSION_MINOR) "." QUOTE(PETSC_PKG_MUMPS_VERSION_SUBMINOR);
     350       55401 :     add_string("mumps", version, doc);
     351             : #else
     352             :     petsc_missing("mumps", doc);
     353             : #endif
     354       55401 :   }
     355             : 
     356             :   {
     357       55401 :     const auto doc = "STRUMPACK - STRUctured Matrix PACKage solver library";
     358             : #ifdef LIBMESH_PETSC_HAVE_STRUMPACK
     359             :     const std::string version = QUOTE(PETSC_PKG_STRUMPACK_VERSION_MAJOR) "." QUOTE(
     360       55401 :         PETSC_PKG_STRUMPACK_VERSION_MINOR) "." QUOTE(PETSC_PKG_STRUMPACK_VERSION_SUBMINOR);
     361       55401 :     add_string("strumpack", version, doc);
     362             : #else
     363             :     petsc_missing("strumpack", doc);
     364             : #endif
     365       55401 :   }
     366             : 
     367             :   {
     368       55401 :     const auto doc = "Parmetis partitioning library";
     369             : #if defined(LIBMESH_PETSC_HAVE_PARMETIS)
     370             :     const std::string version = QUOTE(PETSC_PKG_PARMETIS_VERSION_MAJOR) "." QUOTE(
     371       55401 :         PETSC_PKG_PARMETIS_VERSION_MINOR) "." QUOTE(PETSC_PKG_PARMETIS_VERSION_SUBMINOR);
     372       55401 :     add_string("parmetis", version, doc);
     373             : #elif defined(LIBMESH_HAVE_PARMETIS)
     374             :     have("parmetis", doc);
     375             : #else
     376             :     petsc_missing("parmetis", doc);
     377             : #endif
     378       55401 :   }
     379             : 
     380             :   {
     381       55401 :     const auto doc = "Chaco graph partitioning library";
     382             : #ifdef LIBMESH_PETSC_HAVE_CHACO
     383             :     have("chaco", doc);
     384             : #else
     385      166203 :     petsc_missing("chaco", doc);
     386             : #endif
     387             :   }
     388             : 
     389             :   {
     390       55401 :     const auto doc = "Party matrix or graph partitioning library";
     391             : #ifdef LIBMESH_PETSC_HAVE_PARTY
     392             :     have("party", doc);
     393             : #else
     394      166203 :     petsc_missing("party", doc);
     395             : #endif
     396             :   }
     397             : 
     398             :   {
     399       55401 :     const auto doc = "PT-Scotch graph partitioning library";
     400             : #ifdef LIBMESH_PETSC_HAVE_PTSCOTCH
     401             :     const std::string version = QUOTE(PETSC_PKG_PTSCOTCH_VERSION_MAJOR) "." QUOTE(
     402       55401 :         PETSC_PKG_PTSCOTCH_VERSION_MINOR) "." QUOTE(PETSC_PKG_PTSCOTCH_VERSION_SUBMINOR);
     403       55401 :     add_string("ptscotch", version, doc);
     404             : #else
     405             :     petsc_missing("ptscotch", doc);
     406             : #endif
     407       55401 :   }
     408             : 
     409             :   {
     410       55401 :     const auto doc = "Optimized BLAS library";
     411             : #ifdef PETSC_HAVE_OPENBLAS
     412             :     const std::string version = QUOTE(PETSC_PKG_OPENBLAS_VERSION_MAJOR) "." QUOTE(
     413       55401 :         PETSC_PKG_OPENBLAS_VERSION_MINOR) "." QUOTE(PETSC_PKG_OPENBLAS_VERSION_SUBMINOR);
     414       55401 :     add_string("openblas", version, doc);
     415             : #else
     416             :     petsc_missing("openblas", doc);
     417             : #endif
     418       55401 :   }
     419             : 
     420             :   {
     421       55401 :     const auto doc = "Umpire resource management library";
     422             : #ifdef PETSC_HAVE_UMPIRE
     423      166203 :     have("umpire", doc);
     424             : #else
     425             :     petsc_missing("umpire", doc);
     426             : #endif
     427             :   }
     428             : 
     429             :   {
     430       55401 :     const auto doc = "Scalable Library for Eigenvalue Problem Computations (SLEPc)";
     431             : #ifdef LIBMESH_HAVE_SLEPC
     432       55401 :     const auto version = QUOTE(LIBMESH_DETECTED_SLEPC_VERSION_MAJOR) "." QUOTE(
     433             :         LIBMESH_DETECTED_SLEPC_VERSION_MINOR) "." QUOTE(LIBMESH_DETECTED_SLEPC_VERSION_SUBMINOR);
     434      277005 :     have_version("slepc", doc, version);
     435             : #else
     436             :     petsc_missing("slepc", doc);
     437             : #endif
     438             :   }
     439             : 
     440             :   {
     441       55401 :     const auto doc = "Exodus mesh file format library";
     442             : #ifdef LIBMESH_HAVE_EXODUS_API
     443      110802 :     const std::string version = QUOTE(LIBMESH_DETECTED_EXODUS_VERSION_MAJOR) "." QUOTE(
     444             :         LIBMESH_DETECTED_EXODUS_VERSION_MINOR);
     445      166203 :     have_version("exodus", doc, version);
     446             : #else
     447             :     libmesh_missing("exodus", doc, "--enable-exodus");
     448             : #endif
     449       55401 :   }
     450             : 
     451             :   {
     452       55401 :     const auto doc = "Netgen meshing library";
     453             : #ifdef LIBMESH_HAVE_NETGEN
     454             :     const std::string version =
     455       55401 :         QUOTE(NETGEN_VERSION_MAJOR) "." QUOTE(NETGEN_VERSION_MINOR) "." QUOTE(NETGEN_VERSION_PATCH);
     456       55401 :     add_string("netgen", version, doc);
     457             : #else
     458             :     libmesh_missing("netgen", doc, "--enable-netgen");
     459             : #endif
     460       55401 :   }
     461             : 
     462             :   {
     463       55401 :     const auto doc = "Visualization Toolkit (VTK)";
     464             : #ifdef LIBMESH_HAVE_VTK
     465             :     const std::string version = QUOTE(LIBMESH_DETECTED_VTK_VERSION_MAJOR) "." QUOTE(
     466      110802 :         LIBMESH_DETECTED_VTK_VERSION_MINOR) "." QUOTE(LIBMESH_DETECTED_VTK_VERSION_SUBMINOR);
     467      166203 :     have_version("vtk", doc, version);
     468             : #else
     469             :     libmesh_missing("vtk", doc, "--disable-vtk and --enable-vtk-required");
     470             : #endif
     471       55401 :   }
     472             : 
     473             :   {
     474       55401 :     const auto doc = "libcurl - the multiprotocol file transfer library";
     475             : #ifdef LIBMESH_HAVE_CURL
     476             :     have("curl", doc);
     477             : #else
     478      277005 :     libmesh_missing("curl", doc, "--enable-curl");
     479             : #endif
     480             :   }
     481             : 
     482             :   {
     483       55401 :     const auto doc = "Tecplot post-processing tools API";
     484             : #ifdef LIBMESH_HAVE_TECPLOT_API
     485             :     have("tecplot", doc);
     486             : #else
     487      277005 :     libmesh_missing("tecplot", doc, "--enable-tecplot");
     488             : #endif
     489             :   }
     490             : 
     491             :   {
     492       55401 :     const auto doc = "NVIDIA Tools Extension Library API";
     493             : #ifdef LIBMESH_HAVE_NVTX_API
     494        5214 :     have("nvtx_api", doc);
     495             : #else
     496      268315 :     libmesh_missing("nvtx_api", doc, "--with-nvtx");
     497             : #endif
     498             :   }
     499             : 
     500             :   {
     501       55401 :     const auto doc = "libMesh performance logging";
     502             : #ifdef LIBMESH_ENABLE_PERFORMANCE_LOGGING
     503        5214 :     have("libmesh_perflog", doc);
     504             : #else
     505      268315 :     libmesh_missing("libmesh_perflog", doc, "--enable-perflog");
     506             : #endif
     507             :   }
     508             : 
     509             :   {
     510       55401 :     const auto doc = "Boost C++ library";
     511             : #ifdef LIBMESH_HAVE_EXTERNAL_BOOST
     512             :     have("boost", doc);
     513             : #else
     514      277005 :     libmesh_missing("boost", doc, "--with-boost");
     515             : #endif
     516             :   }
     517             : 
     518             :   // libmesh stuff
     519             :   {
     520       55401 :     const auto doc = "Adaptive mesh refinement";
     521             : #ifdef LIBMESH_ENABLE_AMR
     522      166203 :     have("amr", doc);
     523             : #else
     524             :     libmesh_missing("amr", doc, "--disable-amr");
     525             : #endif
     526             :   }
     527             : 
     528             :   {
     529       55401 :     const auto doc = "nanoflann library for Nearest Neighbor (NN) search with KD-trees";
     530             : #ifdef LIBMESH_HAVE_NANOFLANN
     531      166203 :     have("nanoflann", doc);
     532             : #else
     533             :     libmesh_missing("nanoflann", doc, "--disable-nanoflann");
     534             : #endif
     535             :   }
     536             : 
     537             :   {
     538       55401 :     const auto doc = "sfcurves library for space filling curves (required by geometric "
     539             :                      "partitioners such as SFCurves, Hilbert and Morton -  not LGPL compatible)";
     540             : #ifdef LIBMESH_HAVE_SFCURVES
     541             :     have("sfcurves", doc);
     542             : #else
     543      277005 :     libmesh_missing("sfcurves", doc, "--disable-sfc");
     544             : #endif
     545             :   }
     546             : 
     547             :   {
     548             : #ifdef LIBMESH_HAVE_FPARSER
     549             : #ifdef LIBMESH_HAVE_FPARSER_JIT
     550       55401 :     const auto value = "jit";
     551       55401 :     const auto doc = "FParser enabled with just in time compilation support.";
     552             : #else
     553             :     const auto value = "byte_code";
     554             :     const auto doc = "FParser enabled.";
     555             : #endif
     556       55401 :     add_string("fparser", value, doc);
     557             : #else
     558             :     add_bool("fparser",
     559             :              false,
     560             :              "FParser is disabled, libMesh was likely configured with --disable-fparser.");
     561             : #endif
     562             :   }
     563             : 
     564             : #ifdef LIBMESH_HAVE_DLOPEN
     565       55401 :   add_bool("dlopen", true, "The dlopen() system call is available to dynamically load libraries.");
     566             : #else
     567             :   add_bool("dlopen",
     568             :            false,
     569             :            "The dlopen() system call is not available. Dynamic library loading is "
     570             :            "not supported on this system.");
     571             : #endif
     572             : 
     573             :   {
     574       55401 :     const auto doc = "LibMesh support for threaded execution";
     575             : #ifdef LIBMESH_USING_THREADS
     576      166203 :     have("threads", doc);
     577             : #else
     578             :     libmesh_missing("threads", doc, "--with-thread-model=tbb,pthread,openmp,auto,none");
     579             : #endif
     580             :   }
     581             : 
     582             :   {
     583       55401 :     const auto doc = "OpenMP multi-platform shared-memory parallel programming API";
     584             : #ifdef LIBMESH_HAVE_OPENMP
     585      166203 :     have("openmp", doc);
     586             : #else
     587             :     libmesh_missing("openmp", doc, "--with-thread-model=tbb,pthread,openmp,auto,none");
     588             : #endif
     589             :   }
     590             :   {
     591       55401 :     const auto doc = "POSIX Threads API";
     592             : #ifdef LIBMESH_HAVE_PTHREAD
     593      166203 :     have("pthread", doc);
     594             : #else
     595             :     libmesh_missing("pthread", doc, "--with-thread-model=tbb,pthread,openmp,auto,none");
     596             : #endif
     597             :   }
     598             :   {
     599       55401 :     const auto doc = "oneAPI Threading Building Blocks (TBB) API";
     600             : #ifdef LIBMESH_HAVE_TBB_API
     601             :     have("tbb", doc);
     602             : #else
     603      277005 :     libmesh_missing("tbb", doc, "--with-thread-model=tbb,pthread,openmp,auto,none");
     604             : #endif
     605             :   }
     606             : 
     607             :   {
     608       55401 :     const auto doc = "libMesh unique ID support";
     609             : #ifdef LIBMESH_ENABLE_UNIQUE_ID
     610      166203 :     have("unique_id", doc);
     611             : #else
     612             :     libmesh_missing("unique_id", doc, "--enable-unique-id");
     613             : #endif
     614             :   }
     615             : 
     616             :   {
     617             : #ifdef LIBMESH_ENABLE_PARMESH
     618             :     const auto value = "distributed";
     619             : #else
     620       55401 :     const auto value = "replicated";
     621             : #endif
     622       55401 :     add_string("mesh_mode", value, "libMesh default mesh mode")
     623       55401 :         .setExplicit()
     624       55401 :         .setEnumeration({"distributed", "replicated"});
     625             :   }
     626             : 
     627       55401 :   add_int("dof_id_bytes",
     628             :           static_cast<int>(sizeof(dof_id_type)),
     629      110802 :           "Degree of freedom (DOF) identifiers use " + Moose::stringify(sizeof(dof_id_type)) +
     630             :               " bytes for storage. This is controlled by the "
     631             :               "--with-dof-id-bytes=<1|2|4|8> libMesh configure option.")
     632       55401 :       .setExplicit();
     633             : 
     634             :   {
     635             : #ifdef LIBMESH_HAVE_STATIC_LIBS
     636             :     const auto value = "static";
     637             : #else
     638       55401 :     const auto value = "dynamic";
     639             : #endif
     640       55401 :     add_string("library_mode",
     641             :                value,
     642             :                "The libMesh library mode. This is controlled by the --enable-static libMesh "
     643             :                "configure option.")
     644       55401 :         .setExplicit()
     645       55401 :         .setEnumeration({"dynamic", "static"});
     646             :   }
     647             : 
     648             :   // compiler
     649             :   {
     650       55401 :     const auto doc = "Compiler used to build the MOOSE framework.";
     651             : #if defined(__INTEL_LLVM_COMPILER)
     652             :     const auto value = "intel";
     653             : #elif defined(__clang__)
     654             :     const auto value = "clang";
     655             : #elif defined(__GNUC__) || defined(__GNUG__)
     656       55401 :     const auto value = "gcc";
     657             : #elif defined(_MSC_VER)
     658             :     const auto value = "msvc";
     659             : #else
     660             :     mooseDoOnce(mooseWarning("Failed to determine compiler; setting capability compiler=unknown"));
     661             :     const auto value = "unknown";
     662             : #endif
     663       55401 :     add_string("compiler", value, doc)
     664       55401 :         .setExplicit()
     665       55401 :         .setEnumeration({"clang", "gcc", "intel", "msvc", "unknown"});
     666             :   }
     667             : 
     668             :   // OS related
     669             :   {
     670             : #ifdef __APPLE__
     671             :     const auto value = "darwin";
     672             : #elif __WIN32__
     673             :     const auto value = "win32";
     674             : #elif __linux__
     675       55401 :     const auto value = "linux";
     676             : #elif __unix__
     677             :     const auto value = "unix";
     678             : #else
     679             :     mooseDoOnce(mooseWarning("Failed to determine platform; setting capability platform=unknown"));
     680             :     const auto value = "unknown";
     681             : #endif
     682       55401 :     add_string("platform", value, "Operating system this executable is running on.")
     683       55401 :         .setExplicit()
     684       55401 :         .setEnumeration({"darwin", "linux", "unix", "unknown", "win32"});
     685             :   }
     686             : 
     687             :   // Installation type (in tree or installed)
     688             :   {
     689             :     // Try to find the path to the running executable
     690       55401 :     std::optional<std::string> executable_path;
     691             :     {
     692       55401 :       Moose::ScopedThrowOnError scoped_throw_on_error;
     693             :       try
     694             :       {
     695       55401 :         executable_path = Moose::getExec();
     696             :       }
     697           0 :       catch (const MooseException &)
     698             :       {
     699           0 :       }
     700       55401 :     }
     701             : 
     702       55401 :     std::string value = "unknown";
     703             : 
     704       55401 :     if (executable_path)
     705             :     {
     706             :       // Try to follow all symlinks to get the real path
     707       55401 :       std::error_code ec;
     708             :       const auto resolved_path =
     709       55401 :           std::filesystem::weakly_canonical(std::filesystem::path(*executable_path), ec);
     710       55401 :       if (ec)
     711           0 :         mooseDoOnce(mooseWarning("Failed to resolve executable path '",
     712             :                                  *executable_path,
     713             :                                  "':\n",
     714             :                                  ec.message(),
     715             :                                  "\n\nSetting capability installation_type=unknown"));
     716             :       else
     717             :       {
     718             :         // If the binary is in a folder "bin", we'll consider it installed.
     719             :         // This isn't the best check, but it works with how we currently
     720             :         // install applications in app.mk
     721       55401 :         value = resolved_path.parent_path().filename() == "bin" ? "relocated" : "in_tree";
     722             :       }
     723       55401 :     }
     724             :     else
     725           0 :       mooseDoOnce(mooseWarning(
     726             :           "Failed to determine executable path; setting capability installation_type=unknown"));
     727             : 
     728       55401 :     add_string("installation_type", value, "The installation type of the application.")
     729       55401 :         .setExplicit()
     730       55401 :         .setEnumeration({"in_tree", "relocated", "unknown"});
     731             : 
     732             :     mooseAssert(isInstallationType(value), "Value mismatch");
     733       55401 :   }
     734       55401 : }
     735             : 
     736             : } // namespace Moose

Generated by: LCOV version 1.14