LCOV - code coverage report
Current view: top level - include/reduced_basis - rb_eim_evaluation.h (source / functions) Hit Total Coverage
Test: libMesh/libmesh: #4232 (290bfc) with base 82cc40 Lines: 0 2 0.0 %
Date: 2025-08-27 15:46:53 Functions: 0 2 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // rbOOmit: An implementation of the Certified Reduced Basis method.
       2             : // Copyright (C) 2009, 2010 David J. Knezevic
       3             : 
       4             : // This file is part of rbOOmit.
       5             : 
       6             : // rbOOmit is free software; you can redistribute it and/or
       7             : // modify it under the terms of the GNU Lesser General Public
       8             : // License as published by the Free Software Foundation; either
       9             : // version 2.1 of the License, or (at your option) any later version.
      10             : 
      11             : // rbOOmit is distributed in the hope that it will be useful,
      12             : // but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      14             : // Lesser General Public License for more details.
      15             : 
      16             : // You should have received a copy of the GNU Lesser General Public
      17             : // License along with this library; if not, write to the Free Software
      18             : // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
      19             : 
      20             : #ifndef LIBMESH_RB_EIM_EVALUATION_H
      21             : #define LIBMESH_RB_EIM_EVALUATION_H
      22             : 
      23             : // libMesh includes
      24             : #include "libmesh/point.h"
      25             : #include "libmesh/rb_theta_expansion.h"
      26             : #include "libmesh/rb_parametrized.h"
      27             : #include "libmesh/parallel_object.h"
      28             : #include "libmesh/dense_matrix.h"
      29             : #include "libmesh/dense_vector.h"
      30             : #include "libmesh/rb_parametrized_function.h"
      31             : #include "libmesh/fe_type.h"
      32             : 
      33             : // C++ includes
      34             : #include <memory>
      35             : #include <map>
      36             : #include <vector>
      37             : #include <string>
      38             : 
      39             : namespace libMesh
      40             : {
      41             : 
      42             : class RBParameters;
      43             : class RBParametrizedFunction;
      44             : class RBTheta;
      45             : class System;
      46             : class EquationSystems;
      47             : class Elem;
      48             : 
      49             : /**
      50             :  * This struct encapsulates data that specifies how we will
      51             :  * perform plotting for EIM variable groups.
      52             :  */
      53           0 : struct EIMVarGroupPlottingInfo
      54             : {
      55             : 
      56             :   /**
      57             :    * Default constructor. Initialize values that would otherwise
      58             :    * be uninitialized. We do not initialize the FEType or string
      59             :    * members since they already have default constructors.
      60             :    */
      61             :   EIMVarGroupPlottingInfo()
      62             :   :
      63             :   first_eim_var_index(0),
      64             :   n_eim_vars(0),
      65             :   enforce_min_value(false),
      66             :   enforce_max_value(false),
      67             :   min_value(0.),
      68             :   max_value(0.)
      69             :   {
      70             :   }
      71             : 
      72             :   /**
      73             :    * The index for the first EIM variable in this variable group.
      74             :    */
      75             :   unsigned int first_eim_var_index;
      76             : 
      77             :   /**
      78             :    * The number of EIM variables in the group. The variables
      79             :    * are assumed to be numbered contiguously.
      80             :    */
      81             :   unsigned int n_eim_vars;
      82             : 
      83             :   /**
      84             :    * The name of the System we use for plotting this EIM variable group.
      85             :    */
      86             :   std::string eim_sys_name;
      87             : 
      88             :   /**
      89             :    * These booleans indicate if we should clamp the resulting output
      90             :    * to be above a min value or below a max value. This can be relevant
      91             :    * if we want to satisfy some physical constraints on the outputs, for
      92             :    * example, since these constraints may not be exactly satisfied by
      93             :    * the EIM output.
      94             :    */
      95             :   bool enforce_min_value;
      96             :   bool enforce_max_value;
      97             : 
      98             :   /**
      99             :    * The min (resp. max) value that we enforce if enforce_min_value
     100             :    * (resp. enforce_max_value) is true.
     101             :    */
     102             :   Real min_value;
     103             :   Real max_value;
     104             : };
     105             : 
     106             : /**
     107             :  * This class enables evaluation of an Empirical Interpolation Method (EIM)
     108             :  * approximation. RBEvaluation plays an analogous role in the context of
     109             :  * the regular reduced basis method.
     110             :  */
     111           0 : class RBEIMEvaluation : public RBParametrized,
     112             :                         public ParallelObject
     113             : {
     114             : public:
     115             : 
     116             :   /**
     117             :    * Constructor.
     118             :    */
     119             :   RBEIMEvaluation(const Parallel::Communicator & comm);
     120             : 
     121             :   /**
     122             :    * Special functions.
     123             :    * - This class contains unique_ptrs, so it can't be default copy
     124             :        constructed/assigned.
     125             :    * - The destructor is defaulted out of line.
     126             :    */
     127             :   RBEIMEvaluation (RBEIMEvaluation &&) = default;
     128             :   RBEIMEvaluation (const RBEIMEvaluation &) = delete;
     129             :   RBEIMEvaluation & operator= (const RBEIMEvaluation &) = delete;
     130             :   RBEIMEvaluation & operator= (RBEIMEvaluation &&) = default;
     131             :   virtual ~RBEIMEvaluation ();
     132             : 
     133             :   /**
     134             :    * Type of the data structure used to map from (elem id) -> [n_vars][n_qp] data.
     135             :    */
     136             :   typedef std::map<dof_id_type, std::vector<std::vector<Number>>> QpDataMap;
     137             : 
     138             :   /**
     139             :    * Type of the data structure used to map from (elem id, side index) -> [n_vars][n_qp] data.
     140             :    */
     141             :   typedef std::map<std::pair<dof_id_type,unsigned int>, std::vector<std::vector<Number>>> SideQpDataMap;
     142             : 
     143             :   /**
     144             :    * Type of the data structure used to map from (node id) -> [n_vars] data.
     145             :    */
     146             :   typedef std::map<dof_id_type, std::vector<Number>> NodeDataMap;
     147             : 
     148             :   /**
     149             :    * Clear this object.
     150             :    */
     151             :   virtual void clear() override;
     152             : 
     153             :   /**
     154             :    * Resize the data structures for storing data associated
     155             :    * with this object.
     156             :    */
     157             :   void resize_data_structures(const unsigned int Nmax);
     158             : 
     159             :   /**
     160             :    * Set the parametrized function that we will approximate
     161             :    * using the Empirical Interpolation Method. This object
     162             :    * will take ownership of the unique pointer.
     163             :    */
     164             :   void set_parametrized_function(std::unique_ptr<RBParametrizedFunction> pf);
     165             : 
     166             :   /**
     167             :    * Get a reference to the parametrized function.
     168             :    */
     169             :   RBParametrizedFunction & get_parametrized_function();
     170             : 
     171             :   /**
     172             :    * Get a const reference to the parametrized function.
     173             :    */
     174             :   const RBParametrizedFunction & get_parametrized_function() const;
     175             : 
     176             :   /**
     177             :    * Calculate the EIM approximation for the given
     178             :    * right-hand side vector \p EIM_rhs. Store the
     179             :    * solution coefficients in the member _eim_solution.
     180             :    */
     181             :   DenseVector<Number> rb_eim_solve(DenseVector<Number> & EIM_rhs);
     182             : 
     183             :   /**
     184             :    * Perform rb_eim_solves at each mu in \p mus and store the results
     185             :    * in _rb_eim_solutions.
     186             :    */
     187             :   void rb_eim_solves(const std::vector<RBParameters> & mus, unsigned int N);
     188             : 
     189             :   /**
     190             :    * Initialize _interpolation_points_spatial_indices. Once this data is
     191             :    * initialized, we can store it in the training data, and read it back
     192             :    * in during the Online stage to be used in solves.
     193             :    */
     194             :   void initialize_interpolation_points_spatial_indices();
     195             : 
     196             :   /**
     197             :    * The Online counterpart of initialize_interpolation_points_spatial_indices().
     198             :    * This is used to initialize the spatial indices data in _parametrized_function
     199             :    * so that the _parametrized_function can be used in the Online stage without
     200             :    * reconstructing the spatial indices on every element or node in the mesh.
     201             :    */
     202             :   void initialize_param_fn_spatial_indices();
     203             : 
     204             :   /**
     205             :    * Return the current number of EIM basis functions.
     206             :    */
     207             :   unsigned int get_n_basis_functions() const;
     208             : 
     209             :   /**
     210             :    * Return the number of interpolation points. If we're not using the EIM error
     211             :    * indicator, then this matches get_n_basis_functions(), but if we are using
     212             :    * the EIM error indicator then we should have one extra interpolation point.
     213             :    */
     214             :   unsigned int get_n_interpolation_points() const;
     215             : 
     216             :   /**
     217             :    * Return the number of unique elements containing interpolation points
     218             :    */
     219             :   unsigned int get_n_elems() const;
     220             : 
     221             :   /**
     222             :    * Return the number of properties stored in the rb_property_map
     223             :    */
     224             :   unsigned int get_n_properties() const;
     225             : 
     226             :   /**
     227             :    * Set the number of basis functions. Useful when reading in
     228             :    * stored data.
     229             :    */
     230             :   void set_n_basis_functions(unsigned int n_bfs);
     231             : 
     232             :   /**
     233             :    * Subtract coeffs[i]*basis_function[i] from \p v.
     234             :    */
     235             :   void decrement_vector(QpDataMap & v,
     236             :                         const DenseVector<Number> & coeffs);
     237             : 
     238             :   /**
     239             :    * Same as decrement_vector() except for Side data.
     240             :    */
     241             :   void side_decrement_vector(SideQpDataMap & v,
     242             :                              const DenseVector<Number> & coeffs);
     243             : 
     244             :   /**
     245             :    * Same as decrement_vector() except for node data.
     246             :    */
     247             :   void node_decrement_vector(NodeDataMap & v,
     248             :                              const DenseVector<Number> & coeffs);
     249             : 
     250             :   /**
     251             :    * Build a vector of RBTheta objects that accesses the components
     252             :    * of the RB_solution member variable of this RBEvaluation.
     253             :    * Store these objects in the member vector rb_theta_objects.
     254             :    */
     255             :   void initialize_eim_theta_objects();
     256             : 
     257             :   /**
     258             :    * \returns The vector of theta objects that point to this RBEIMEvaluation.
     259             :    */
     260             :   std::vector<std::unique_ptr<RBTheta>> & get_eim_theta_objects();
     261             : 
     262             :   /**
     263             :    * Build a theta object corresponding to EIM index \p index.
     264             :    * The default implementation builds an RBEIMTheta object, possibly
     265             :    * override in subclasses if we need more specialized behavior.
     266             :    */
     267             :   virtual std::unique_ptr<RBTheta> build_eim_theta(unsigned int index);
     268             : 
     269             :   /**
     270             :    * Fill up values by evaluating the parametrized function \p pf for all quadrature
     271             :    * points on element \p elem_id and component \p comp.
     272             :    */
     273             :   static void get_parametrized_function_values_at_qps(
     274             :     const QpDataMap & pf,
     275             :     dof_id_type elem_id,
     276             :     unsigned int comp,
     277             :     std::vector<Number> & values);
     278             : 
     279             :   /**
     280             :    * Same as get_parametrized_function_values_at_qps() except for side data.
     281             :    */
     282             :   static void get_parametrized_function_side_values_at_qps(
     283             :     const SideQpDataMap & pf,
     284             :     dof_id_type elem_id,
     285             :     unsigned int side_index,
     286             :     unsigned int comp,
     287             :     std::vector<Number> & values);
     288             : 
     289             :   /**
     290             :    * Same as get_parametrized_function_values_at_qps() except for node data.
     291             :    * Note that this does not do any parallel communication, so it is only
     292             :    * applicable to looking up local values.
     293             :    */
     294             :   static Number get_parametrized_function_node_local_value(
     295             :     const NodeDataMap & pf,
     296             :     dof_id_type node_id,
     297             :     unsigned int comp);
     298             : 
     299             :   /**
     300             :    * Same as above, except that we just return the value at the qp^th
     301             :    * quadrature point.
     302             :    */
     303             :   static Number get_parametrized_function_value(
     304             :     const Parallel::Communicator & comm,
     305             :     const QpDataMap & pf,
     306             :     dof_id_type elem_id,
     307             :     unsigned int comp,
     308             :     unsigned int qp);
     309             : 
     310             :   /**
     311             :    * Same as get_parametrized_function_value() except for side data.
     312             :    */
     313             :   static Number get_parametrized_function_side_value(
     314             :     const Parallel::Communicator & comm,
     315             :     const SideQpDataMap & pf,
     316             :     dof_id_type elem_id,
     317             :     unsigned int side_index,
     318             :     unsigned int comp,
     319             :     unsigned int qp);
     320             : 
     321             :   /**
     322             :    * Same as get_parametrized_function_value() except for node data.
     323             :    * Unlike get_parametrized_function_node_local_value(), this does
     324             :    * parallel communication, and therefore if can be used to look up
     325             :    * values regardless of whether or not \p node_id is local.
     326             :    */
     327             :   static Number get_parametrized_function_node_value(
     328             :     const Parallel::Communicator & comm,
     329             :     const NodeDataMap & pf,
     330             :     dof_id_type node_id,
     331             :     unsigned int comp);
     332             : 
     333             :   /**
     334             :    * Fill up \p values with the basis function values for basis function
     335             :    * \p basis_function_index and variable \p var, at all quadrature points
     336             :    * on element \p elem_id. Each processor stores data for only the
     337             :    * elements local to that processor, so if elem_id is not on this processor
     338             :    * then \p values will be empty.
     339             :    */
     340             :   void get_eim_basis_function_values_at_qps(unsigned int basis_function_index,
     341             :                                             dof_id_type elem_id,
     342             :                                             unsigned int var,
     343             :                                             std::vector<Number> & values) const;
     344             : 
     345             :   /**
     346             :    * Same as get_eim_basis_function_values_at_qps() except for side data.
     347             :    */
     348             :   void get_eim_basis_function_side_values_at_qps(unsigned int basis_function_index,
     349             :                                                  dof_id_type elem_id,
     350             :                                                  unsigned int side_index,
     351             :                                                  unsigned int var,
     352             :                                                  std::vector<Number> & values) const;
     353             : 
     354             :   /**
     355             :    * Same as get_eim_basis_function_values_at_qps() except for node data.
     356             :    * Note that this does not do any parallel communication, it just looks
     357             :    * up the value from _local_node_eim_basis_functions.
     358             :    */
     359             :   Number get_eim_basis_function_node_local_value(unsigned int basis_function_index,
     360             :                                                  dof_id_type node_id,
     361             :                                                  unsigned int var) const;
     362             : 
     363             :   /**
     364             :    * Same as above, except that we just return the value at the qp^th
     365             :    * quadrature point.
     366             :    */
     367             :   Number get_eim_basis_function_value(unsigned int basis_function_index,
     368             :                                       dof_id_type elem_id,
     369             :                                       unsigned int comp,
     370             :                                       unsigned int qp) const;
     371             : 
     372             :   /**
     373             :    * Same as get_eim_basis_function_value() except for side data.
     374             :    */
     375             :   Number get_eim_basis_function_side_value(unsigned int basis_function_index,
     376             :                                           dof_id_type elem_id,
     377             :                                           unsigned int side_index,
     378             :                                           unsigned int comp,
     379             :                                           unsigned int qp) const;
     380             : 
     381             :   /**
     382             :    * Same as get_eim_basis_function_value() except for node data.
     383             :    * Note that unlike get_eim_basis_function_node_local_value(),
     384             :    * this does do parallel communication so that it can be called
     385             :    * on any processor regardless of whether \p node_id is local or not.
     386             :    */
     387             :   Number get_eim_basis_function_node_value(unsigned int basis_function_index,
     388             :                                            dof_id_type node_id,
     389             :                                            unsigned int var) const;
     390             : 
     391             :   /**
     392             :    * Get a reference to the i^th basis function.
     393             :    */
     394             :   const QpDataMap & get_basis_function(unsigned int i) const;
     395             : 
     396             :   /**
     397             :    * Get a reference to the i^th side basis function.
     398             :    */
     399             :   const SideQpDataMap & get_side_basis_function(unsigned int i) const;
     400             : 
     401             :   /**
     402             :    * Get a reference to the i^th node basis function.
     403             :    */
     404             :   const NodeDataMap & get_node_basis_function(unsigned int i) const;
     405             : 
     406             :   /**
     407             :    * Set _rb_eim_solutions. Normally we update _rb_eim_solutions by performing
     408             :    * and EIM solve, but in some cases we want to set the EIM solution coefficients
     409             :    * elsewhere, so this setter enables us to do that.
     410             :    */
     411             :   void set_rb_eim_solutions(const std::vector<DenseVector<Number>> & rb_eim_solutions);
     412             : 
     413             :   /**
     414             :    * Return the EIM solution coefficients from the most recent call to rb_eim_solves().
     415             :    */
     416             :   const std::vector<DenseVector<Number>> & get_rb_eim_solutions() const;
     417             : 
     418             :   /**
     419             :    * Return entry \p index for each solution in _rb_eim_solutions.
     420             :    */
     421             :   std::vector<Number> get_rb_eim_solutions_entries(unsigned int index) const;
     422             : 
     423             :   /**
     424             :    * Return a const reference to the EIM solutions for the parameters in the training set.
     425             :    */
     426             :   const std::vector<DenseVector<Number>> & get_eim_solutions_for_training_set() const;
     427             : 
     428             :   /**
     429             :    * Return a writeable reference to the EIM solutions for the parameters in the training set.
     430             :    */
     431             :   std::vector<DenseVector<Number>> & get_eim_solutions_for_training_set();
     432             : 
     433             :   /**
     434             :    * Return the EIM error indicator values from the most recent call to rb_eim_solves().
     435             :    * The first entry of each pair is the normalized error indicator, and the second
     436             :    * entry is the normalization factor.
     437             :    */
     438             :   const std::vector<std::pair<Real,Real>> & get_rb_eim_error_indicators() const;
     439             : 
     440             :   /**
     441             :    * Set the data associated with EIM interpolation points.
     442             :    */
     443             :   void add_interpolation_points_xyz(Point p);
     444             :   void add_interpolation_points_comp(unsigned int comp);
     445             :   void add_interpolation_points_subdomain_id(subdomain_id_type sbd_id);
     446             :   void add_interpolation_points_boundary_id(boundary_id_type b_id);
     447             :   void add_interpolation_points_xyz_perturbations(const std::vector<Point> & perturbs);
     448             :   void add_interpolation_points_elem_id(dof_id_type elem_id);
     449             :   void add_interpolation_points_side_index(unsigned int side_index);
     450             :   void add_interpolation_points_node_id(dof_id_type node_id);
     451             :   void add_interpolation_points_qp(unsigned int qp);
     452             :   void add_interpolation_points_elem_type(ElemType elem_type);
     453             :   void add_interpolation_points_phi_i_qp(const std::vector<Real> & phi_i_qp);
     454             :   void add_interpolation_points_JxW_all_qp(const std::vector<Real> & JxW_all_qp);
     455             :   void add_interpolation_points_phi_i_all_qp(const std::vector<std::vector<Real>> & phi_i_all_qp);
     456             :   void add_interpolation_points_qrule_order(Order qrule_order);
     457             :   void add_elem_center_dxyzdxi(const Point & dxyzdxi);
     458             :   void add_elem_center_dxyzdeta(const Point & dxyzdxi);
     459             :   void add_interpolation_points_spatial_indices(const std::vector<unsigned int> & spatial_indices);
     460             :   void add_elem_id_local_index_map_entry(dof_id_type elem_id, unsigned int local_index);
     461             :   void add_rb_property_map_entry(std::string & property_name, std::set<dof_id_type> & entity_ids);
     462             : 
     463             :   /**
     464             :    * Get the data associated with EIM interpolation points.
     465             :    */
     466             :   Point get_interpolation_points_xyz(unsigned int index) const;
     467             :   unsigned int get_interpolation_points_comp(unsigned int index) const;
     468             :   subdomain_id_type get_interpolation_points_subdomain_id(unsigned int index) const;
     469             :   boundary_id_type get_interpolation_points_boundary_id(unsigned int index) const;
     470             :   const std::vector<Point> & get_interpolation_points_xyz_perturbations(unsigned int index) const;
     471             :   dof_id_type get_interpolation_points_elem_id(unsigned int index) const;
     472             :   unsigned int get_interpolation_points_side_index(unsigned int index) const;
     473             :   dof_id_type get_interpolation_points_node_id(unsigned int index) const;
     474             :   unsigned int get_interpolation_points_qp(unsigned int index) const;
     475             :   ElemType get_interpolation_points_elem_type(unsigned int index) const;
     476             :   const std::vector<Real> & get_interpolation_points_phi_i_qp(unsigned int index) const;
     477             :   const std::vector<Real> & get_interpolation_points_JxW_all_qp(unsigned int index) const;
     478             :   const std::vector<std::vector<Real>> & get_interpolation_points_phi_i_all_qp(unsigned int index) const;
     479             :   Order get_interpolation_points_qrule_order(unsigned int index) const;
     480             :   const Point & get_elem_center_dxyzdxi(unsigned int index) const;
     481             :   const Point & get_elem_center_dxyzdeta(unsigned int index) const;
     482             :   const std::vector<unsigned int> & get_interpolation_points_spatial_indices(unsigned int index) const;
     483             :   const std::map<dof_id_type, unsigned int> & get_elem_id_to_local_index_map() const;
     484             :   const std::unordered_map<std::string, std::set<dof_id_type>> & get_rb_property_map() const;
     485             : 
     486             :   /**
     487             :    * _interpolation_points_spatial_indices is optional data, so we need to be able to
     488             :    * check how many _interpolation_points_spatial_indices values have actually been set
     489             :    * since it may not match the number of interpolation points.
     490             :    */
     491             :   unsigned int get_n_interpolation_points_spatial_indices() const;
     492             : 
     493             :   /**
     494             :    * Set entry of the EIM interpolation matrix.
     495             :    */
     496             :   void set_interpolation_matrix_entry(unsigned int i, unsigned int j, Number value);
     497             : 
     498             :   /**
     499             :    * Get the EIM interpolation matrix.
     500             :    */
     501             :   const DenseMatrix<Number> & get_interpolation_matrix() const;
     502             : 
     503             :   /**
     504             :    * Add \p bf to our EIM basis.
     505             :    */
     506             :   void add_basis_function(
     507             :     const QpDataMap & bf);
     508             : 
     509             :   /**
     510             :    * Add interpolation data associated with a new basis function.
     511             :    */
     512             :   void add_interpolation_data(
     513             :     Point p,
     514             :     unsigned int comp,
     515             :     dof_id_type elem_id,
     516             :     subdomain_id_type subdomain_id,
     517             :     unsigned int qp,
     518             :     const std::vector<Point> & perturbs,
     519             :     const std::vector<Real> & phi_i_qp,
     520             :     ElemType elem_type,
     521             :     const std::vector<Real> & JxW_all_qp,
     522             :     const std::vector<std::vector<Real>> & phi_i_all_qp,
     523             :     Order qrule_order,
     524             :     const Point & dxyz_dxi_elem_center,
     525             :     const Point & dxyz_deta_elem_center);
     526             : 
     527             :   /**
     528             :    * Add \p side_bf to our EIM basis.
     529             :    */
     530             :   void add_side_basis_function(
     531             :     const SideQpDataMap & side_bf);
     532             : 
     533             :   /**
     534             :    * Add interpolation data associated with a new basis function.
     535             :    */
     536             :   void add_side_interpolation_data(
     537             :     Point p,
     538             :     unsigned int comp,
     539             :     dof_id_type elem_id,
     540             :     unsigned int side_index,
     541             :     subdomain_id_type subdomain_id,
     542             :     boundary_id_type boundary_id,
     543             :     unsigned int qp,
     544             :     const std::vector<Point> & perturbs,
     545             :     const std::vector<Real> & phi_i_qp);
     546             : 
     547             :   /**
     548             :    * Add \p node_bf to our EIM basis.
     549             :    */
     550             :   void add_node_basis_function(
     551             :     const NodeDataMap & node_bf);
     552             : 
     553             :   /**
     554             :    * Add interpolation data associated with a new basis function.
     555             :    */
     556             :   void add_node_interpolation_data(
     557             :     Point p,
     558             :     unsigned int comp,
     559             :     dof_id_type node_id,
     560             :     boundary_id_type boundary_id);
     561             : 
     562             :   /**
     563             :    * Set _preserve_rb_eim_solutions.
     564             :    */
     565             :   void set_preserve_rb_eim_solutions(bool preserve_rb_eim_solutions);
     566             : 
     567             :   /**
     568             :    * Get _preserve_rb_eim_solutions.
     569             :    */
     570             :   bool get_preserve_rb_eim_solutions() const;
     571             : 
     572             :   /**
     573             :    * Write out all the basis functions to file.
     574             :    * \p sys is used for file IO
     575             :    * \p directory_name specifies which directory to write files to
     576             :    * \p read_binary_basis_functions indicates whether to write
     577             :    * binary or ASCII data
     578             :    *
     579             :    * Note: this is not currently a virtual function and is not related
     580             :    * to the RBEvaluation function of the same name.
     581             :    */
     582             :   void write_out_basis_functions(const std::string & directory_name = "offline_data",
     583             :                                  bool write_binary_basis_functions = true);
     584             : 
     585             :   /**
     586             :    * Read in all the basis functions from file.
     587             :    *
     588             :    * \param sys The Mesh in this System determines the parallel distribution of the basis functions.
     589             :    * \param directory_name Specifies which directory to write files to.
     590             :    * \param read_binary_basis_functions Indicates whether to expect binary or ASCII data.
     591             :    *
     592             :    * Note: this is not a virtual function and is not related to the
     593             :    * RBEvaluation function of the same name.
     594             :    */
     595             :   void read_in_basis_functions(const System & sys,
     596             :                                const std::string & directory_name = "offline_data",
     597             :                                bool read_binary_basis_functions = true);
     598             : 
     599             :   /**
     600             :    * Project the EIM basis function data stored in \p bf_data onto
     601             :    * sys.solution. The intent of this function is to work with the
     602             :    * data format provided by get_interior_basis_functions_as_vecs().
     603             :    * That format can be easily serialized, if needed, and hence can
     604             :    * be used to provide \p bf_data after reading in data from disk,
     605             :    * for example.
     606             :    *
     607             :    * \p extra_options can be used to pass extra information to this
     608             :    * method, e.g. options related to how to perform the projection.
     609             :    *
     610             :    * This is a no-op by default, implement in sub-classes if needed.
     611             :    */
     612             :   virtual void project_qp_data_vector_onto_system(System & sys,
     613             :                                                   const std::vector<Number> & bf_data,
     614             :                                                   const EIMVarGroupPlottingInfo & eim_vargroup,
     615             :                                                   const std::map<std::string,std::string> & extra_options);
     616             : 
     617             :   /**
     618             :    * Get _eim_vars_to_project_and_write.
     619             :    */
     620             :   const std::vector<EIMVarGroupPlottingInfo> & get_eim_vars_to_project_and_write() const;
     621             : 
     622             :   /**
     623             :    * Get _scale_components_in_enrichment.
     624             :    */
     625             :   const std::set<unsigned int> & scale_components_in_enrichment() const;
     626             : 
     627             :   /**
     628             :    * Virtual function to indicate if we use the EIM error indicator in this case.
     629             :    * This indicates if we will generate the data during the Offline training for
     630             :    * the EIM error indicator. In EIM solves, the error indicator will only
     631             :    * be used if set_eim_error_indicator_active() is set to true, since we want
     632             :    * to be able to enable or disable the error indicator depending on the type
     633             :    * of solve we are doing (e.g. EIM solves during training do not need the
     634             :    * error indicator).
     635             :    */
     636             :   virtual bool use_eim_error_indicator() const;
     637             : 
     638             :   /**
     639             :    * Activate/decative the error indicator in EIM solves. We need this option since
     640             :    * in some cases (e.g. during EIM training) we do not want to activate the EIM
     641             :    * error indicator, whereas in "online solves" we do want to activate it.
     642             :    */
     643             :   void set_eim_error_indicator_active(bool is_active);
     644             : 
     645             :   /**
     646             :    * Get/set _extra_points_interpolation_matrix.
     647             :    */
     648             :   const DenseVector<Number> & get_error_indicator_interpolation_row() const;
     649             :   void set_error_indicator_interpolation_row(const DenseVector<Number> & error_indicator_row);
     650             : 
     651             :   /**
     652             :    * Evaluates the EIM error indicator based on \p error_indicator_rhs, \p eim_solution,
     653             :    * and _error_indicator_interpolation_row. We also pass in \p eim_rhs since this is
     654             :    * used to normalize the error indicator.
     655             :    *
     656             :    * We return a pair that specifies the relative error indicator, and the normalization
     657             :    * that was used to compute the relative error indicator. We can then recover the
     658             :    * absolute error indicator via rel. indicator x normalization.
     659             :    */
     660             :   std::pair<Real,Real> get_eim_error_indicator(
     661             :     Number error_indicator_rhs,
     662             :     const DenseVector<Number> & eim_solution,
     663             :     const DenseVector<Number> & eim_rhs);
     664             : 
     665             :   /**
     666             :    * Get the VectorizedEvalInput data.
     667             :    */
     668             :   const VectorizedEvalInput & get_vec_eval_input() const;
     669             : 
     670             :   /**
     671             :    * Initialize the rb_property_map of RBEIMEvaluation (this) from the rb_property_map stored in
     672             :    * RBParametrizedFunction with empty entries but identical keys.
     673             :    */
     674             :   void initialize_rb_property_map();
     675             : 
     676             :   /**
     677             :    * Get all interior basis functions in the form of std::vectors.
     678             :    * This can provide a convenient format for processing the basis
     679             :    * function data, or writing it to disk.
     680             :    *
     681             :    * Indexing is as follows:
     682             :    *  basis function index --> variable index --> data at qps per elems
     683             :    *
     684             :    * In parallel we gather basis functions to processor 0 and hence
     685             :    * we only return non-empty data on processor 0.
     686             :    */
     687             :   std::vector<std::vector<std::vector<Number>>> get_interior_basis_functions_as_vecs();
     688             : 
     689             :   /**
     690             :    * Get data that defines the sizes of interior EIM basis functions.
     691             :    */
     692             :   std::map<std::string,std::size_t>
     693             :     get_interior_basis_function_sizes(std::vector<unsigned int> & n_qp_per_elem);
     694             : 
     695             :   /**
     696             :    * Here we store an enum that defines the type of EIM error indicator
     697             :    * normalization that we use in get_eim_error_indicator(). The enum
     698             :    * is public so that it can be set in user code.
     699             :    *
     700             :    * RESIDUAL_SUM: Use the sum of the terms in the EIM residual to determine
     701             :    * the error indicator normalization. This ensures that the error indicator
     702             :    * value will be at most 1.0, which may be a desirable property of the
     703             :    * indicator.
     704             :    *
     705             :    * RHS: Use only the right-hand side value for the EIM residual to
     706             :    * determine the error indicator normalization.
     707             :    *
     708             :    * MAX_RHS: Use the maximum value in the EIM RHS vector to determine
     709             :    * the error indicator normalization (default). This is helpful when
     710             :    * the values at some EIM points are much larger than others, since in
     711             :    * this scenario we typically want to normalize the error indicator
     712             :    * based on the largest values in order to avoid overestimating the
     713             :    * error.
     714             :    */
     715             :   enum EimErrorIndicatorNormalization { RESIDUAL_SUM, RESIDUAL_RHS, MAX_RHS };
     716             : 
     717             :   EimErrorIndicatorNormalization eim_error_indicator_normalization;
     718             : 
     719             :   /**
     720             :    * If this boolean is true then we clamp EIM error indicator values to
     721             :    * be at most 1. This is often desirable since we typically think of
     722             :    * the error indicator as a percentage, and a value of 1 means 100%
     723             :    * error. We set this to true by default.
     724             :    */
     725             :   bool limit_eim_error_indicator_to_one;
     726             : 
     727             : protected:
     728             : 
     729             :   /**
     730             :    * This vector specifies which EIM variables we want to write to disk and/or
     731             :    * project to nodes for plotting purposes. By default this is an empty
     732             :    * set, but can be updated in subclasses to specify the EIM variables that
     733             :    * are relevant for visualization.
     734             :    *
     735             :    * We identify groups of variables with one or more variables in a group.
     736             :    * The purpose of using a group is often we plot multiple components of
     737             :    * a tensor-valued or vector-valued quantity, so it makes sense to refer
     738             :    * to the entire group of variables together in those cases.
     739             :    */
     740             :   std::vector<EIMVarGroupPlottingInfo> _eim_vars_to_project_and_write;
     741             : 
     742             :   /**
     743             :    * This set that specifies which EIM variables will be scaled during EIM
     744             :    * enrichment so that their maximum value matches the maximum value across
     745             :    * all variables. This is helpful in cases where some components are much
     746             :    * smaller in magnitude than others, since in those cases if we do not apply
     747             :    * component scaling to the small components then the accuracy of the EIM
     748             :    * approximation for those components will not be controlled well by the
     749             :    * EIM enrichment process.
     750             :    */
     751             :   std::set<unsigned int> _scale_components_in_enrichment;
     752             : 
     753             : private:
     754             : 
     755             :   /**
     756             :    * Method that writes out element interior EIM basis functions. This may be called by
     757             :    * write_out_basis_functions().
     758             :    */
     759             :   void write_out_interior_basis_functions(const std::string & directory_name,
     760             :                                           bool write_binary_basis_functions);
     761             : 
     762             :   /**
     763             :    * Method that writes out element side EIM basis functions. This may be called by
     764             :    * write_out_basis_functions().
     765             :    */
     766             :   void write_out_side_basis_functions(const std::string & directory_name,
     767             :                                       bool write_binary_basis_functions);
     768             : 
     769             :   /**
     770             :    * Method that writes out element node EIM basis functions. This may be called by
     771             :    * write_out_basis_functions().
     772             :    */
     773             :   void write_out_node_basis_functions(const std::string & directory_name,
     774             :                                       bool write_binary_basis_functions);
     775             : 
     776             :   /**
     777             :    * Method that reads in element interior EIM basis functions. This may be called by
     778             :    * read_in_basis_functions().
     779             :    */
     780             :   void read_in_interior_basis_functions(const System & sys,
     781             :                                         const std::string & directory_name,
     782             :                                         bool read_binary_basis_functions);
     783             : 
     784             :   /**
     785             :    * Method that reads in element side EIM basis functions. This may be called by
     786             :    * read_in_basis_functions().
     787             :    */
     788             :   void read_in_side_basis_functions(const System & sys,
     789             :                                     const std::string & directory_name,
     790             :                                     bool read_binary_basis_functions);
     791             : 
     792             :   /**
     793             :    * Method that reads in element node EIM basis functions. This may be called by
     794             :    * read_in_basis_functions().
     795             :    */
     796             :   void read_in_node_basis_functions(const System & sys,
     797             :                                     const std::string & directory_name,
     798             :                                     bool read_binary_basis_functions);
     799             : 
     800             :   /**
     801             :    * Helper function called by write_out_interior_basis_functions() to
     802             :    * get basis function \p bf_index stored as a std::vector per variable.
     803             :    */
     804             :   std::vector<std::vector<Number>> get_interior_basis_function_as_vec_helper(
     805             :     unsigned int n_vars,
     806             :     unsigned int n_qp_data,
     807             :     unsigned int bf_index);
     808             : 
     809             :   /**
     810             :    * The EIM solution coefficients from the most recent call to rb_eim_solves().
     811             :    */
     812             :   std::vector<DenseVector<Number>> _rb_eim_solutions;
     813             : 
     814             :   /**
     815             :    * If we're using the EIM error indicator, then we store the error indicator
     816             :    * values corresponding to _rb_eim_solutions here.
     817             :    */
     818             :   std::vector<std::pair<Real,Real>> _rb_eim_error_indicators;
     819             : 
     820             :   /**
     821             :    * Storage for EIM solutions from the training set. This is typically used in
     822             :    * the case that we have is_lookup_table==true in our RBParametrizedFunction,
     823             :    * since in that case we need to store all the EIM solutions on the training
     824             :    * set so that we do not always need to refer to the lookup table itself
     825             :    * (since in some cases, like in the Online stage, the lookup table is not
     826             :    * available).
     827             :    */
     828             :   std::vector<DenseVector<Number>> _eim_solutions_for_training_set;
     829             : 
     830             :   /**
     831             :    * The parameters and the number of basis functions that were used in the
     832             :    * most recent call to rb_eim_solves(). We store this so that we can
     833             :    * check if we can skip calling rb_eim_solves() again if the inputs
     834             :    * haven't changed.
     835             :    */
     836             :   std::vector<RBParameters> _rb_eim_solves_mus;
     837             :   unsigned int _rb_eim_solves_N;
     838             : 
     839             :   /**
     840             :    * Dense matrix that stores the lower triangular
     841             :    * interpolation matrix that can be used
     842             :    */
     843             :   DenseMatrix<Number> _interpolation_matrix;
     844             : 
     845             :   /**
     846             :    * We store the EIM interpolation point data in this object.
     847             :    */
     848             :   VectorizedEvalInput _vec_eval_input;
     849             : 
     850             :   /**
     851             :    * In the case of a "vector-valued" EIM, this vector determines which
     852             :    * component of the parameterized function we sample at each EIM point.
     853             :    */
     854             :   std::vector<unsigned int> _interpolation_points_comp;
     855             : 
     856             :   /**
     857             :    * Here we store the spatial indices that were initialized by
     858             :    * initialize_spatial_indices_at_interp_pts(). These are relevant
     859             :    * in the case that _parametrized_function is defined by indexing
     860             :    * into separate data based on the mesh-based data.
     861             :    */
     862             :   std::vector<std::vector<unsigned int>> _interpolation_points_spatial_indices;
     863             : 
     864             :   /**
     865             :    * Store the parametrized function that will be approximated
     866             :    * by this EIM system. Note that the parametrized function
     867             :    * may have more than one component, and each component is
     868             :    * approximated by a separate variable in the EIM system.
     869             :    */
     870             :   std::unique_ptr<RBParametrizedFunction> _parametrized_function;
     871             : 
     872             :   /**
     873             :    * The vector of RBTheta objects that are created to point to
     874             :    * this RBEIMEvaluation.
     875             :    */
     876             :   std::vector<std::unique_ptr<RBTheta>> _rb_eim_theta_objects;
     877             : 
     878             :   /**
     879             :    * The EIM basis functions. We store values at quadrature points
     880             :    * on elements that are local to this processor. The indexing
     881             :    * is as follows:
     882             :    *   basis function index --> element ID --> variable --> quadrature point --> value
     883             :    * We use a map to index the element ID, since the IDs on this processor in
     884             :    * general will not start at zero.
     885             :    */
     886             :   std::vector<QpDataMap> _local_eim_basis_functions;
     887             : 
     888             :   /**
     889             :    * The EIM basis functions on element sides. We store values at quadrature points
     890             :    * on elements that are local to this processor. The indexing
     891             :    * is as follows:
     892             :    *   basis function index --> (element ID,side index) --> variable --> quadrature point --> value
     893             :    * We use a map to index the element ID, since the IDs on this processor in
     894             :    * general will not start at zero.
     895             :    */
     896             :   std::vector<SideQpDataMap> _local_side_eim_basis_functions;
     897             : 
     898             :   /**
     899             :    * The EIM basis functions on element nodes (e.g. on a nodeset). We store values at nodes
     900             :    * that are local to this processor. The indexing
     901             :    * is as follows:
     902             :    *   basis function index --> node ID --> variable --> value
     903             :    * We use a map to index the node ID, since the IDs on this processor in
     904             :    * general will not start at zero.
     905             :    */
     906             :   std::vector<NodeDataMap> _local_node_eim_basis_functions;
     907             : 
     908             :   /**
     909             :    * Print the contents of _local_eim_basis_functions to libMesh::out.
     910             :    * Helper function mainly useful for debugging.
     911             :    */
     912             :   void print_local_eim_basis_functions() const;
     913             : 
     914             :   /**
     915             :    * Helper function that gathers the contents of
     916             :    * _local_eim_basis_functions to processor 0 in preparation for
     917             :    * printing to file.
     918             :    */
     919             :   void gather_bfs();
     920             : 
     921             :   /**
     922             :    * Same as gather_bfs() except for side data.
     923             :    */
     924             :   void side_gather_bfs();
     925             : 
     926             :   /**
     927             :    * Same as gather_bfs() except for node data.
     928             :    */
     929             :   void node_gather_bfs();
     930             : 
     931             :   /**
     932             :    * Helper function that distributes the entries of
     933             :    * _local_eim_basis_functions to their respective processors after
     934             :    * they are read in on processor 0.
     935             :    */
     936             :   void distribute_bfs(const System & sys);
     937             : 
     938             :   /**
     939             :    * Same as distribute_bfs() except for side data.
     940             :    */
     941             :   void side_distribute_bfs(const System & sys);
     942             : 
     943             :   /**
     944             :    * Same as distribute_bfs() except for node data.
     945             :    */
     946             :   void node_distribute_bfs(const System & sys);
     947             : 
     948             :   /**
     949             :    * Boolean to indicate if we skip updating _rb_eim_solutions in rb_eim_solves().
     950             :    * This is relevant for cases when we set up _rb_eim_solutions elsewhere and we
     951             :    * want to avoid changing it.
     952             :    */
     953             :   bool _preserve_rb_eim_solutions;
     954             : 
     955             :   /**
     956             :    * Indicate if the EIM error indicator is active in RB EIM solves. Note that
     957             :    * this is distinct from use_eim_error_indicator(), since use_eim_error_indicator()
     958             :    * indicates if this RBEIMEvaluation has an EIM error indicator defined,
     959             :    * whereas _is_eim_error_indicator_active is used to turn on or off the
     960             :    * error indicator. This primary purpose of _is_eim_error_indicator_active
     961             :    * is to turn the error indicator off during EIM training (when it is not relevant)
     962             :    * and to turn it on during "online solves".
     963             :    */
     964             :   bool _is_eim_error_indicator_active;
     965             : 
     966             :   /**
     967             :    * Here we store an extra row of the interpolation matrix which is used to
     968             :    * compute the EIM error indicator. This stores the EIM basis function
     969             :    * values at the extra point associated with the error indicator.
     970             :    */
     971             :   DenseVector<Number> _error_indicator_interpolation_row;
     972             : 
     973             : };
     974             : 
     975             : }
     976             : 
     977             : #endif // LIBMESH_RB_EIM_EVALUATION_H

Generated by: LCOV version 1.14