1 /*  _______________________________________________________________________
2 
3     DAKOTA: Design Analysis Kit for Optimization and Terascale Applications
4     Copyright 2014-2020 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
5     This software is distributed under the GNU Lesser General Public License.
6     For more information, see the README file in the top Dakota directory.
7     _______________________________________________________________________ */
8 
9 //- Class:       RecastModel
10 //- Description: A model mapping variables into responses using
11 //-              primary/secondary function pointers.
12 //- Owner:       Mike Eldred
13 //- Checked by:
14 //- Version: $Id: RecastModel.hpp 7024 2010-10-16 01:24:42Z mseldre $
15 
16 #ifndef RECAST_MODEL_H
17 #define RECAST_MODEL_H
18 
19 #include "DakotaModel.hpp"
20 
21 namespace Dakota {
22 
23 class ProblemDescDB;
24 class Interface;
25 
26 /// Derived model class which provides a thin wrapper around a sub-model
27 /// in order to recast the form of its inputs and/or outputs.
28 
29 /** The RecastModel class uses function pointers to allow recasting of
30     the subModel input/output into new problem forms.  For example,
31     this is used to recast SBO approximate subproblems, multiobjective
32     and least-squares reductions, and variable/response.
33 
34     For now, making the assumption that variables mappings are ordered
35     by submodel active continous, discrete int, discrete string,
36     discrete real variables, even though all current use cases are
37     continuous only.
38 
39     When not using the standard (full) constructor, client code must
40     make sure to complete initialization before using the
41     RecastModel's mapping functions.  Initialization steps:
42       1. sub model (all ctors do this)
43       2. init_sizes: once known, size Variables, Response, Constraints
44          (full and intermediate ctor do this)
45       3. init_maps: set indices and callback pointers
46          (only full ctor does this)
47 */
48 class RecastModel: public Model
49 {
50 public:
51 
52   //
53   //- Heading: Constructor and destructor
54   //
55 
56   /// standard (full) constructor; assumes provided sizes and map
57   /// functions are final and constructs all member data
58   RecastModel(const Model& sub_model, const Sizet2DArray& vars_map_indices,
59 	      const SizetArray& vars_comps_total, const BitArray& all_relax_di,
60 	      const BitArray& all_relax_dr, bool nonlinear_vars_mapping,
61 	      void (*variables_map)      (const Variables& recast_vars,
62 					  Variables& sub_model_vars),
63 	      void (*set_map)            (const Variables& recast_vars,
64 					  const ActiveSet& recast_set,
65 					  ActiveSet& sub_model_set),
66 	      const Sizet2DArray& primary_resp_map_indices,
67 	      const Sizet2DArray& secondary_resp_map_indices,
68 	      size_t recast_secondary_offset, short recast_resp_order,
69 	      const BoolDequeArray& nonlinear_resp_mapping,
70 	      void (*primary_resp_map)   (const Variables& sub_model_vars,
71 					  const Variables& recast_vars,
72 					  const Response& sub_model_response,
73 					  Response& recast_response),
74 	      void (*secondary_resp_map) (const Variables& sub_model_vars,
75 					  const Variables& recast_vars,
76 					  const Response& sub_model_response,
77 					  Response& recast_response));
78 
79   /// alternate constructor; uses provided sizes to construct Variables,
80   /// Response and Constraints so Model can be passed to an Iterator;
81   /// requires subsequent init_maps() call.
82   RecastModel(const Model& sub_model, //size_t num_deriv_vars,
83 	      const SizetArray& vars_comps_totals, const BitArray& all_relax_di,
84 	      const BitArray& all_relax_dr,    size_t num_recast_primary_fns,
85 	      size_t num_recast_secondary_fns, size_t recast_secondary_offset,
86 	      short recast_resp_order);
87 
88   /// Problem DB-based ctor, e.g., for use in subspace model; assumes
89   /// mappings to be initialized later; only initializes based on sub-model
90   RecastModel(ProblemDescDB& problem_db, const Model& sub_model);
91 
92   /// lightest constructor used when transform sizes aren't known at
93   /// construct time; doesn't initialize variables and responses, so
94   /// this Model can't be used to construct an Iterator; requires
95   /// subsequent init_sizes() and init_maps() calls.
96   RecastModel(const Model& sub_model);
97 
98   /// destructor
99   ~RecastModel();
100 
101   //
102   //- Heading: Member functions
103   //
104 
105   /// update recast sizes and size Variables and Response members
106   /// after alternate construction
107   void init_sizes(const SizetArray& vars_comps_totals,
108 		  const BitArray& all_relax_di, const BitArray& all_relax_dr,
109 		  size_t num_recast_primary_fns,
110 		  size_t num_recast_secondary_fns,
111 		  size_t recast_secondary_offset, short recast_resp_order);
112 
113   /// initialize recast indices and map callbacks after alternate
114   /// construction
115   void init_maps(const Sizet2DArray& vars_map_indices,
116 		 bool nonlinear_vars_mapping,
117 		 void (*variables_map)     (const Variables& recast_vars,
118 					    Variables& sub_model_vars),
119 		 void (*set_map)           (const Variables& recast_vars,
120 					    const ActiveSet& recast_set,
121 					    ActiveSet& sub_model_set),
122 		 const Sizet2DArray& primary_resp_map_indices,
123 		 const Sizet2DArray& secondary_resp_map_indices,
124 		 const BoolDequeArray& nonlinear_resp_mapping,
125 		 void (*primary_resp_map)  (const Variables& sub_model_vars,
126 					    const Variables& recast_vars,
127 					    const Response& sub_model_response,
128 					    Response& recast_response),
129 		 void (*secondary_resp_map)(const Variables& sub_model_vars,
130 					    const Variables& recast_vars,
131 					    const Response& sub_model_response,
132 					    Response& recast_response));
133 
134   /// provide optional inverse mappings
135   void inverse_mappings(
136     void (*inv_vars_map)     (const Variables& sub_model_vars,
137 			      Variables& recast_vars),
138     void (*inv_set_map)      (const Variables& sub_model_vars,
139 			      const ActiveSet& sub_model_set,
140 			      ActiveSet& recast_set),
141     void (*inv_pri_resp_map) (const Variables& recast_vars,
142 			      const Variables& sub_model_vars,
143 			      const Response& recast_resp,
144 			      Response& sub_model_resp),
145     void (*inv_sec_resp_map) (const Variables& recast_vars,
146 			      const Variables& sub_model_vars,
147 			      const Response& recast_resp,
148 			      Response& sub_model_resp));
149 
150   /// perform transformation of Variables (recast --> sub-model)
151   void transform_variables(const Variables& recast_vars,
152 			   Variables& sub_model_vars);
153   /// into sub_model_set for use with subModel.
154   void transform_set(const Variables& recast_vars, const ActiveSet& recast_set,
155 		     ActiveSet& sub_model_set);
156   /// perform transformation of Response (sub-model --> recast)
157   void transform_response(const Variables& recast_vars,
158 			  const Variables& sub_model_vars,
159 			  const Response& sub_model_resp,
160 			  Response& recast_resp);
161   /// invoke transform_response() on each response within old_resp_map
162   /// to create new_resp_map
163   void transform_response_map(const IntResponseMap& old_resp_map,
164 			      IntResponseMap& new_resp_map);
165 
166   /// perform inverse transformation of Variables (sub-model --> recast)
167   void inverse_transform_variables(const Variables& sub_model_vars,
168 				   Variables& recast_vars);
169   /// into sub_model_set for use with subModel.
170   void inverse_transform_set(const Variables& sub_model_vars,
171 			     const ActiveSet& sub_model_set,
172 			     ActiveSet& recast_set);
173   /// perform inverse transformation of Response (recast --> sub-model)
174   void inverse_transform_response(const Variables& sub_model_vars,
175 				  const Variables& recast_vars,
176 				  const Response& recast_resp,
177 				  Response& sub_model_resp);
178 
179   /// override the submodel's derivative estimation behavior
180   void submodel_supports_derivative_estimation(bool sed_flag);
181 
182   String root_model_id();
183 
184   ActiveSet default_active_set();
185   void declare_sources();
186 
187   /// return nonlinearVarsMapping
188   bool nonlinear_variables_mapping() const;
189 
190 protected:
191 
192   //
193   //- Heading: Virtual function redefinitions
194   //
195 
196   Pecos::ProbabilityTransformation& probability_transformation();
197 
198   bool initialize_mapping(ParLevLIter pl_iter);
199   bool finalize_mapping();
200 
201   void nested_variable_mappings(const SizetArray& c_index1,
202 				const SizetArray& di_index1,
203 				const SizetArray& ds_index1,
204 				const SizetArray& dr_index1,
205 				const ShortArray& c_target2,
206 				const ShortArray& di_target2,
207 				const ShortArray& ds_target2,
208 				const ShortArray& dr_target2);
209   const SizetArray& nested_acv1_indices() const;
210   const ShortArray& nested_acv2_targets() const;
211   short query_distribution_parameter_derivatives() const;
212   void activate_distribution_parameter_derivatives();
213   void deactivate_distribution_parameter_derivatives();
214 
215   void trans_grad_X_to_U(const RealVector& fn_grad_x, RealVector& fn_grad_u,
216 			 const RealVector& x_vars);
217   void trans_grad_U_to_X(const RealVector& fn_grad_u, RealVector& fn_grad_x,
218 			 const RealVector& x_vars);
219   void trans_grad_X_to_S(const RealVector& fn_grad_x, RealVector& fn_grad_s,
220 			 const RealVector& x_vars);
221   void trans_hess_X_to_U(const RealSymMatrix& fn_hess_x,
222 			 RealSymMatrix& fn_hess_u, const RealVector& x_vars,
223 			 const RealVector& fn_grad_x);
224 
225   size_t qoi() const;
226 
227   /// portion of evaluate() specific to RecastModel
228   /// (forward to subModel.evaluate())
229   void derived_evaluate(const ActiveSet& set);
230   /// portion of evaluate_nowait() specific to RecastModel
231   /// (forward to subModel.evaluate_nowait())
232   void derived_evaluate_nowait(const ActiveSet& set);
233   /// portion of synchronize() specific to RecastModel
234   /// (forward to subModel.synchronize())
235   const IntResponseMap& derived_synchronize();
236   /// portion of synchronize_nowait() specific to RecastModel
237   /// (forward to subModel.synchronize_nowait())
238   const IntResponseMap& derived_synchronize_nowait();
239 
240   /// return sub-iterator, if present, within subModel
241   Iterator& subordinate_iterator();
242   /// return subModel
243   Model& subordinate_model();
244 
245   /// set key in subModel
246   void active_model_key(const UShortArray& mi_key);
247   /// remove keys in subModel
248   void clear_model_keys();
249 
250   /// return surrogate model, if present, within subModel
251   Model& surrogate_model();
252   /// return surrogate model, if present, within subModel
253   const Model& surrogate_model() const;
254 
255   /// return truth model, if present, within subModel
256   Model& truth_model();
257   /// return truth model, if present, within subModel
258   const Model& truth_model() const;
259 
260   /// add subModel to list and recurse into subModel
261   void derived_subordinate_models(ModelList& ml, bool recurse_flag);
262   /// pass request to subModel if recursing and then resize from its results
263   void resize_from_subordinate_model(size_t depth =
264 				     std::numeric_limits<size_t>::max());
265   /// pass request to subModel if recursing and then update from its results
266   void update_from_subordinate_model(size_t depth =
267 				     std::numeric_limits<size_t>::max());
268   /// return subModel interface
269   Interface& derived_interface();
270 
271   /// return size of subModel::solnControlCostMap
272   size_t solution_levels() const;
273   /// activate entry in subModel::solnControlCostMap
274   void solution_level_index(unsigned short lev_index);
275   /// return active entry in subModel::solnControlCostMap
276   unsigned short solution_level_index() const;
277   /// return cost estimates from subModel::solnControlCostMap
278   RealVector solution_level_costs() const;
279   /// return active cost estimate from subModel::solnControlCostMap
280   Real solution_level_cost() const;
281 
282   /// set the relative weightings for multiple objective functions or least
283   /// squares terms and optionally recurses into subModel
284   void primary_response_fn_weights(const RealVector& wts,
285 				   bool recurse_flag = true);
286 
287   /// update the subModel's surrogate response function indices
288   /// (DataFitSurrModel::surrogateFnIndices)
289   void surrogate_function_indices(const IntSet& surr_fn_indices);
290 
291   /// update the subModel's surrogate response mode
292   /// (SurrogateModel::responseMode)
293   void surrogate_response_mode(short mode);
294 
295   // link SurrogateData instances within the subModel
296   //void link_multilevel_approximation_data();
297 
298   /// retrieve subModel's correction type
299   short correction_type();
300   /// update subModel's correction type
301   void correction_type(short corr_type);
302 
303   /// retrieve error estimates corresponding to the subModel
304   const RealVector& error_estimates();
305 
306   /// builds the subModel approximation
307   void build_approximation();
308   /// builds the subModel approximation
309   bool build_approximation(const Variables& vars,
310 			   const IntResponsePair& response_pr);
311   /// updates a subModel approximation
312   void rebuild_approximation();
313 
314   /// replaces data in the subModel approximation
315   void update_approximation(bool rebuild_flag);
316   /// replaces data in the subModel approximation
317   void update_approximation(const Variables& vars,
318 			    const IntResponsePair& response_pr,
319 			    bool rebuild_flag);
320   /// replaces data in the subModel approximation
321   void update_approximation(const VariablesArray& vars_array,
322 			    const IntResponseMap& resp_map, bool rebuild_flag);
323 
324   /// appends data to the subModel approximation
325   void append_approximation(bool rebuild_flag);
326   /// appends data to the subModel approximation
327   void append_approximation(const Variables& vars,
328 			    const IntResponsePair& response_pr,
329 			    bool rebuild_flag);
330   /// appends data to the subModel approximation
331   void append_approximation(const VariablesArray& vars_array,
332 			    const IntResponseMap& resp_map, bool rebuild_flag);
333 
334   void pop_approximation(bool save_surr_data, bool rebuild_flag = false);
335   void push_approximation();
336   bool push_available();
337   void finalize_approximation();
338   void combine_approximation();
339   void combined_to_active(bool clear_combined = true);
340 
341   /*
342   void store_approximation(size_t index = _NPOS);
343   void restore_approximation(size_t index = _NPOS);
344   void remove_stored_approximation(size_t index = _NPOS);
345   */
346   void clear_inactive();
347 
348   /// retrieve the set of Approximations from the subModel
349   std::vector<Approximation>& approximations();
350   /// retrieve the approximation coefficients from the subModel
351   const RealVectorArray& approximation_coefficients(bool normalized = false);
352   /// set the approximation coefficients within the subModel
353   void approximation_coefficients(const RealVectorArray& approx_coeffs,
354 				  bool normalized = false);
355   /// retrieve the approximation variances from the subModel
356   const RealVector& approximation_variances(const Variables& vars);
357   /// retrieve the approximation data from the subModel
358   const Pecos::SurrogateData& approximation_data(size_t fn_index);
359 
360   /// RecastModel only supports parallelism in subModel, so this
361   /// virtual function redefinition is simply a sanity check.
362   void component_parallel_mode(short mode);
363 
364   /// return subModel's MI parallel level index
365   size_t mi_parallel_level_index() const;
366 
367   /// return subModel local synchronization setting
368   short local_eval_synchronization();
369   /// return subModel local evaluation concurrency
370   int local_eval_concurrency();
371   /// flag which prevents overloading the master with a multiprocessor
372   /// evaluation (request forwarded to subModel)
373   bool derived_master_overload() const;
374 
375   IntIntPair estimate_partition_bounds(int max_eval_concurrency);
376 
377   /// set up RecastModel for parallel operations (request forwarded to subModel)
378   void derived_init_communicators(ParLevLIter pl_iter, int max_eval_concurrency,
379 				  bool recurse_flag = true);
380   /// set up RecastModel for serial operations (request forwarded to subModel).
381   void derived_init_serial();
382   /// set active parallel configuration within subModel
383   void derived_set_communicators(ParLevLIter pl_iter, int max_eval_concurrency,
384 				 bool recurse_flag = true);
385   /// deallocate communicator partitions for the RecastModel (request forwarded
386   /// to subModel)
387   void derived_free_communicators(ParLevLIter pl_iter, int max_eval_concurrency,
388 				  bool recurse_flag = true);
389 
390   /// Service subModel job requests received from the master.
391   /// Completes when a termination message is received from stop_servers().
392   void serve_run(ParLevLIter pl_iter, int max_eval_concurrency);
393   /// executed by the master to terminate subModel server operations
394   /// when RecastModel iteration is complete.
395   void stop_servers();
396 
397   /// update the Model's inactive view based on higher level (nested)
398   /// context and optionally recurse into subModel
399   void inactive_view(short view, bool recurse_flag = true);
400 
401   /// return the subModel interface identifier
402   const String& interface_id() const;
403   /// if recurse_flag, return the subModel evaluation cache usage
404   bool evaluation_cache(bool recurse_flag = true) const;
405   /// if recurse_flag, return the subModel restart file usage
406   bool restart_file(bool recurse_flag = true) const;
407 
408   /// return the current evaluation id for the RecastModel
409   int derived_evaluation_id() const;
410   /// set the evaluation counter reference points for the RecastModel
411   /// (request forwarded to subModel)
412   void set_evaluation_reference();
413   /// request fine-grained evaluation reporting within subModel
414   void fine_grained_evaluation_counters();
415   /// print the evaluation summary for the RecastModel (request
416   /// forwarded to subModel)
417   void print_evaluation_summary(std::ostream& s, bool minimal_header = false,
418 				bool relative_count = true) const;
419 
420   /// set the warm start flag, including the orderedModels
421   void warm_start_flag(const bool flag);
422 
423   /// set the hierarchical eval ID tag prefix
424   void eval_tag_prefix(const String& eval_id_str);
425 
426   /// RecastModel may need to map variables, asv before DB lookup, or
427   /// responses after lookup
428   bool db_lookup(const Variables& search_vars,
429 		 const ActiveSet& search_set, Response& found_resp);
430 
431   //
432   //- Heading: New virtual functions
433   //
434 
435   /// assign static pointer instance to this for use in static
436   /// transformation functions
437   virtual void assign_instance();
438 
439   //
440   //- Heading: Member functions
441   //
442 
443   /// helper to compute the recast response order during member initialization
444   // TODO: Move to Response?
445   static short response_order(const Model& sub_model);
446 
447   /// Generate a model id for recast models
448   static String recast_model_id(const String &root_id, const String &type);
449 
450   /// initialize currentVariables and related info from the passed
451   /// size/type info
452   bool init_variables(const SizetArray& vars_comps_totals,
453 		      const BitArray& all_relax_di,
454 		      const BitArray& all_relax_dr);
455   /// initialize currentResponse from the passed size info
456   void init_response(size_t num_recast_primary_fns,
457 		     size_t num_recast_secondary_fns,
458 		     short recast_resp_order, bool reshape_vars);
459 
460   /// Reshape the RecastModel Response, assuming no change in variables
461   /// or derivative information
462   void reshape_response(size_t num_recast_primary_fns,
463 			size_t num_recast_secondary_fns);
464 
465   /// initialize userDefinedConstraints from the passed size info
466   void init_constraints(size_t num_recast_secondary_fns,
467 			size_t recast_secondary_offset, bool reshape_vars);
468 
469   /// update current variables/bounds/labels/constraints from subModel
470   void update_from_model(Model& model);
471   /// update active variables/bounds/labels from subModel
472   bool update_variables_from_model(Model& model);
473   /// update complement of active variables/bounds/labels from subModel
474   void update_variables_active_complement_from_model(Model& model);
475   /// update nonlinear constraint bounds/targets from subModel
476   void update_response_from_model(Model& model);
477 
478   //
479   //- Heading: Data members
480   //
481 
482   /// the sub-model underlying the transformations
483   Model subModel;
484 
485   /// local evaluation id counter used for id mapping
486   int recastModelEvalCntr;
487 
488   /// map of recast active set passed to derived_evaluate_nowait().
489   /// Needed for currentResponse update in synchronization routines.
490   IntActiveSetMap recastSetMap;
491   /// map of recast variables used by derived_evaluate_nowait().
492   /// Needed for primaryRespMapping() and secondaryRespMapping() in
493   /// synchronization routines.
494   IntVariablesMap recastVarsMap;
495   /// map of subModel variables used by derived_evaluate_nowait().
496   /// Needed for primaryRespMapping() and secondaryRespMapping() in
497   /// synchronization routines.
498   IntVariablesMap subModelVarsMap;
499   /// map of recast responses used by RecastModel::derived_synchronize()
500   /// and RecastModel::derived_synchronize_nowait()
501   IntResponseMap recastResponseMap;
502   /// mapping from subModel evaluation ids to RecastModel evaluation ids
503   IntIntMap recastIdMap;
504   /// Counters for naming RecastModels
505   static StringStringPairIntMap recastModelIdCounters;
506 
507   /// boolean set to true if the variables mapping involves a nonlinear
508   /// transformation.  Used in transform_set() to manage the requirement for
509   /// gradients within the Hessian transformations.  This does not require
510   /// a BoolDeque for each individual variable, since response gradients and
511   /// Hessians are managed per function, not per variable.
512   bool nonlinearVarsMapping;
513 
514 private:
515 
516   //
517   //- Heading: Convenience member functions
518   //
519 
520   /// code shared among constructors to initialize base class data from submodel
521   void initialize_data_from_submodel();
522 
523   /// resize {primary,secondary}MapIndices and nonlinearRespMapping to
524   /// synchronize with subModel sizes
525   void resize_response_mapping();
526 
527   //
528   //- Heading: Data members
529   //
530 
531   /// For each subModel variable, identifies the indices of the recast
532   /// variables used to define it (maps RecastModel variables to
533   /// subModel variables; data is packed with only the variable indices
534   /// employed rather than a sparsely filled N_sm x N_r matrix).
535   Sizet2DArray varsMapIndices;
536 
537   /// For each recast primary function, identifies the indices of the
538   /// subModel functions used to define it (maps subModel response
539   /// to RecastModel Response).
540   Sizet2DArray primaryRespMapIndices;
541   /// For each recast secondary function, identifies the indices of
542   /// the subModel functions used to define it (maps subModel response
543   /// to RecastModel response).
544   Sizet2DArray secondaryRespMapIndices;
545   /// array of BoolDeques, one for each recast response function.  Each
546   /// BoolDeque defines which subModel response functions contribute to the
547   /// recast function using a nonlinear mapping.  Used in transform_set() to
548   /// augment the subModel function value/gradient requirements.
549   BoolDequeArray nonlinearRespMapping;
550 
551   /// mapping of subModel.error_estimates() through response mappings
552   RealVector mappedErrorEstimates;
553 
554   /// holds pointer for variables mapping function passed in ctor/initialize
555   void (*variablesMapping)     (const Variables& recast_vars,
556 			        Variables& sub_model_vars);
557   /// holds pointer for set mapping function passed in ctor/initialize
558   void (*setMapping)           (const Variables& recast_vars,
559 				const ActiveSet& recast_set,
560 			        ActiveSet& sub_model_set);
561   /// holds pointer for primary response mapping function passed in
562   /// ctor/initialize
563   void (*primaryRespMapping)   (const Variables& sub_model_vars,
564 				const Variables& recast_vars,
565 				const Response& sub_model_response,
566 				Response& recast_response);
567   /// holds pointer for secondary response mapping function passed in
568   /// ctor/initialize
569   void (*secondaryRespMapping) (const Variables& sub_model_vars,
570 				const Variables& recast_vars,
571 				const Response& sub_model_response,
572 				Response& recast_response);
573 
574   /// holds pointer for optional inverse variables mapping function
575   /// passed in inverse_mappings()
576   void (*invVarsMapping)    (const Variables& sub_model_vars,
577 			     Variables& recast_vars);
578   /// holds pointer for optional inverse set mapping function passed
579   /// in inverse_mappings()
580   void (*invSetMapping)     (const Variables& sub_model_vars,
581 			     const ActiveSet& sub_model_set,
582 			     ActiveSet& recast_set);
583   /// holds pointer for optional inverse primary response mapping
584   /// function passed in inverse_mappings()
585   void (*invPriRespMapping) (const Variables& recast_vars,
586 			     const Variables& sub_model_vars,
587 			     const Response& recast_resp,
588 			     Response& sub_model_resp);
589   /// holds pointer for optional inverse secondary response mapping
590   /// function passed in inverse_mappings()
591   void (*invSecRespMapping) (const Variables& recast_vars,
592 			     const Variables& sub_model_vars,
593 			     const Response& recast_resp,
594 			     Response& sub_model_resp);
595 
596 };
597 
598 
~RecastModel()599 inline RecastModel::~RecastModel()
600 { }
601 
602 
nonlinear_variables_mapping() const603 inline bool RecastModel::nonlinear_variables_mapping() const
604 { return nonlinearVarsMapping; }
605 
606 
submodel_supports_derivative_estimation(bool sed_flag)607 inline void RecastModel::submodel_supports_derivative_estimation(bool sed_flag)
608 { subModel.supports_derivative_estimation(sed_flag); }
609 
610 
611 inline Pecos::ProbabilityTransformation& RecastModel::
probability_transformation()612 probability_transformation()
613 { return subModel.probability_transformation(); } // forward along
614 
615 
initialize_mapping(ParLevLIter pl_iter)616 inline bool RecastModel::initialize_mapping(ParLevLIter pl_iter)
617 {
618   Model::initialize_mapping(pl_iter);
619 
620   bool sub_model_resize = subModel.initialize_mapping(pl_iter);
621 
622   // update message lengths for send/receive of parallel jobs (normally
623   // performed once in Model::init_communicators() just after construct time)
624   if (sub_model_resize)
625     estimate_message_lengths();
626 
627   return sub_model_resize;
628 }
629 
630 
finalize_mapping()631 inline bool RecastModel::finalize_mapping()
632 {
633   bool sub_model_resize = subModel.finalize_mapping();
634   Model::finalize_mapping();
635   return sub_model_resize;
636 }
637 
638 
639 inline void RecastModel::
nested_variable_mappings(const SizetArray & c_index1,const SizetArray & di_index1,const SizetArray & ds_index1,const SizetArray & dr_index1,const ShortArray & c_target2,const ShortArray & di_target2,const ShortArray & ds_target2,const ShortArray & dr_target2)640 nested_variable_mappings(const SizetArray& c_index1,
641 			 const SizetArray& di_index1,
642 			 const SizetArray& ds_index1,
643 			 const SizetArray& dr_index1,
644 			 const ShortArray& c_target2,
645 			 const ShortArray& di_target2,
646 			 const ShortArray& ds_target2,
647 			 const ShortArray& dr_target2)
648 {
649   // forward along to subModel:
650   subModel.nested_variable_mappings(c_index1, di_index1, ds_index1,
651 				    dr_index1, c_target2, di_target2,
652 				    ds_target2, dr_target2);
653 }
654 
655 
nested_acv1_indices() const656 inline const SizetArray& RecastModel::nested_acv1_indices() const
657 { return subModel.nested_acv1_indices(); }
658 
659 
nested_acv2_targets() const660 inline const ShortArray& RecastModel::nested_acv2_targets() const
661 { return subModel.nested_acv2_targets(); }
662 
663 
query_distribution_parameter_derivatives() const664 inline short RecastModel::query_distribution_parameter_derivatives() const
665 { return subModel.query_distribution_parameter_derivatives(); }
666 
667 
activate_distribution_parameter_derivatives()668 inline void RecastModel::activate_distribution_parameter_derivatives()
669 { subModel.activate_distribution_parameter_derivatives(); }
670 
671 
deactivate_distribution_parameter_derivatives()672 inline void RecastModel::deactivate_distribution_parameter_derivatives()
673 { subModel.deactivate_distribution_parameter_derivatives(); }
674 
675 
676 inline void RecastModel::
trans_grad_X_to_U(const RealVector & fn_grad_x,RealVector & fn_grad_u,const RealVector & x_vars)677 trans_grad_X_to_U(const RealVector& fn_grad_x, RealVector& fn_grad_u,
678 		  const RealVector& x_vars)
679 { subModel.trans_grad_X_to_U(fn_grad_x, fn_grad_u, x_vars); }
680 
681 
682 inline void RecastModel::
trans_grad_U_to_X(const RealVector & fn_grad_u,RealVector & fn_grad_x,const RealVector & x_vars)683 trans_grad_U_to_X(const RealVector& fn_grad_u, RealVector& fn_grad_x,
684 		  const RealVector& x_vars)
685 { subModel.trans_grad_U_to_X(fn_grad_u, fn_grad_x, x_vars); }
686 
687 
688 inline void RecastModel::
trans_grad_X_to_S(const RealVector & fn_grad_x,RealVector & fn_grad_s,const RealVector & x_vars)689 trans_grad_X_to_S(const RealVector& fn_grad_x, RealVector& fn_grad_s,
690 		  const RealVector& x_vars)
691 { subModel.trans_grad_X_to_S(fn_grad_x, fn_grad_s, x_vars); }
692 
693 
694 inline void RecastModel::
trans_hess_X_to_U(const RealSymMatrix & fn_hess_x,RealSymMatrix & fn_hess_u,const RealVector & x_vars,const RealVector & fn_grad_x)695 trans_hess_X_to_U(const RealSymMatrix& fn_hess_x,
696 		  RealSymMatrix& fn_hess_u, const RealVector& x_vars,
697 		  const RealVector& fn_grad_x)
698 { subModel.trans_hess_X_to_U(fn_hess_x, fn_hess_u, x_vars, fn_grad_x); }
699 
700 
qoi() const701 inline size_t RecastModel::qoi() const
702 { return subModel.qoi(); } // TO DO: check for response mapping
703 
704 
subordinate_iterator()705 inline Iterator& RecastModel::subordinate_iterator()
706 { return subModel.subordinate_iterator(); }
707 
708 
subordinate_model()709 inline Model& RecastModel::subordinate_model()
710 { return subModel; }
711 
712 
active_model_key(const UShortArray & mi_key)713 inline void RecastModel::active_model_key(const UShortArray& mi_key)
714 { subModel.active_model_key(mi_key); }
715 
716 
clear_model_keys()717 inline void RecastModel::clear_model_keys()
718 { subModel.clear_model_keys(); }
719 
720 
surrogate_model()721 inline Model& RecastModel::surrogate_model()
722 { return subModel.surrogate_model(); }
723 
724 
surrogate_model() const725 inline const Model& RecastModel::surrogate_model() const
726 { return subModel.surrogate_model(); }
727 
728 
truth_model()729 inline Model& RecastModel::truth_model()
730 { return subModel.truth_model(); }
731 
732 
truth_model() const733 inline const Model& RecastModel::truth_model() const
734 { return subModel.truth_model(); }
735 
736 
737 inline void RecastModel::
derived_subordinate_models(ModelList & ml,bool recurse_flag)738 derived_subordinate_models(ModelList& ml, bool recurse_flag)
739 {
740   ml.push_back(subModel);
741   if (recurse_flag)
742     subModel.derived_subordinate_models(ml, true);
743 }
744 
745 
resize_from_subordinate_model(size_t depth)746 inline void RecastModel::resize_from_subordinate_model(size_t depth)
747 {
748   // data flows from the bottom-up, so recurse first
749   if (depth == std::numeric_limits<size_t>::max())
750     subModel.resize_from_subordinate_model(depth); // retain special value (inf)
751   else if (depth)
752     subModel.resize_from_subordinate_model(depth - 1); // decrement
753   //else depth exhausted --> resize this level only
754 
755   // pull sizing updates from subModel: reflect aggregated counts, if present,
756   // by accessing count from response rather than virtual count from Model
757   numFns = subModel.response_size();
758   if (currentResponse.num_functions() != numFns) {
759     resize_response_mapping(); // requires current sizes before reshape below
760     currentResponse.reshape(numFns, currentVariables.cv(),
761                             !currentResponse.function_gradients().empty(),
762                             !currentResponse.function_hessians().empty());
763   }
764 
765   //size_t num_sm_acv = subModel.acv(), ...;
766   //if (currentVariables.acv() != num_sm_acv || ...)
767   //  currentVariables.reshape(num_sm_acv,num_sm_adiv,num_sm_adsv,num_sm_adrv);
768 }
769 
770 
update_from_subordinate_model(size_t depth)771 inline void RecastModel::update_from_subordinate_model(size_t depth)
772 {
773   // data flows from the bottom-up, so recurse first
774   if (depth == std::numeric_limits<size_t>::max())
775     subModel.update_from_subordinate_model(depth); // retain special value (inf)
776   else if (depth)
777     subModel.update_from_subordinate_model(depth - 1); // decrement
778   //else depth exhausted --> update this level only
779 
780   // now pull the latest updates from subModel
781   update_from_model(subModel);
782 }
783 
784 
derived_interface()785 inline Interface& RecastModel::derived_interface()
786 { return subModel.derived_interface(); }
787 
788 
solution_levels() const789 inline size_t RecastModel::solution_levels() const
790 { return subModel.solution_levels(); }
791 
792 
solution_level_index(unsigned short lev_index)793 inline void RecastModel::solution_level_index(unsigned short lev_index)
794 { subModel.solution_level_index(lev_index); }
795 
796 
solution_level_index() const797 inline unsigned short RecastModel::solution_level_index() const
798 { return subModel.solution_level_index(); }
799 
800 
solution_level_costs() const801 inline RealVector RecastModel::solution_level_costs() const
802 { return subModel.solution_level_costs(); }
803 
804 
solution_level_cost() const805 inline Real RecastModel::solution_level_cost() const
806 { return subModel.solution_level_cost(); }
807 
808 
809 inline void RecastModel::
primary_response_fn_weights(const RealVector & wts,bool recurse_flag)810 primary_response_fn_weights(const RealVector& wts, bool recurse_flag)
811 {
812   primaryRespFnWts = wts;
813   if (recurse_flag && !primaryRespMapping)
814     subModel.primary_response_fn_weights(wts, recurse_flag);
815 }
816 
817 
818 inline void RecastModel::
surrogate_function_indices(const IntSet & surr_fn_indices)819 surrogate_function_indices(const IntSet& surr_fn_indices)
820 { subModel.surrogate_function_indices(surr_fn_indices); }
821 
822 
823 // For case of RecastModel, forward to subModel for all cases.  SurrogateModels
824 // and NestedModels only fwd if BYPASS_SURROGATE (to support recursive bypass),
825 // but Recast should allow mode set followed by reset for underlying surrogate.
surrogate_response_mode(short mode)826 inline void RecastModel::surrogate_response_mode(short mode)
827 { /* if (mode == BYPASS_SURROGATE) */ subModel.surrogate_response_mode(mode); }
828 
829 
830 //inline void RecastModel::link_multilevel_approximation_data()
831 //{ subModel.link_multilevel_approximation_data(); }
832 
833 
correction_type()834 inline short RecastModel::correction_type()
835 { return subModel.correction_type(); }
836 
837 
correction_type(short corr_type)838 inline void RecastModel::correction_type(short corr_type)
839 { subModel.correction_type(corr_type); }
840 
841 
build_approximation()842 inline void RecastModel::build_approximation()
843 { subModel.build_approximation(); }
844 
845 
846 inline bool RecastModel::
build_approximation(const Variables & vars,const IntResponsePair & response_pr)847 build_approximation(const Variables& vars, const IntResponsePair& response_pr)
848 { return subModel.build_approximation(vars, response_pr); }
849 
850 
rebuild_approximation()851 inline void RecastModel::rebuild_approximation()
852 { subModel.rebuild_approximation(); }
853 
854 
update_approximation(bool rebuild_flag)855 inline void RecastModel::update_approximation(bool rebuild_flag)
856 { subModel.update_approximation(rebuild_flag); }
857 
858 
859 inline void RecastModel::
update_approximation(const Variables & vars,const IntResponsePair & response_pr,bool rebuild_flag)860 update_approximation(const Variables& vars, const IntResponsePair& response_pr,
861 		     bool rebuild_flag)
862 { subModel.update_approximation(vars, response_pr, rebuild_flag); }
863 
864 
865 inline void RecastModel::
update_approximation(const VariablesArray & vars_array,const IntResponseMap & resp_map,bool rebuild_flag)866 update_approximation(const VariablesArray& vars_array,
867 		     const IntResponseMap& resp_map, bool rebuild_flag)
868 { subModel.update_approximation(vars_array, resp_map, rebuild_flag); }
869 
870 
append_approximation(bool rebuild_flag)871 inline void RecastModel::append_approximation(bool rebuild_flag)
872 { subModel.append_approximation(rebuild_flag); }
873 
874 
875 inline void RecastModel::
append_approximation(const Variables & vars,const IntResponsePair & response_pr,bool rebuild_flag)876 append_approximation(const Variables& vars, const IntResponsePair& response_pr,
877 		     bool rebuild_flag)
878 { subModel.append_approximation(vars, response_pr, rebuild_flag); }
879 
880 
881 inline void RecastModel::
append_approximation(const VariablesArray & vars_array,const IntResponseMap & resp_map,bool rebuild_flag)882 append_approximation(const VariablesArray& vars_array,
883 		     const IntResponseMap& resp_map, bool rebuild_flag)
884 { subModel.append_approximation(vars_array, resp_map, rebuild_flag); }
885 
886 
887 inline void RecastModel::
pop_approximation(bool save_surr_data,bool rebuild_flag)888 pop_approximation(bool save_surr_data, bool rebuild_flag)
889 { subModel.pop_approximation(save_surr_data, rebuild_flag); }
890 
891 
push_approximation()892 inline void RecastModel::push_approximation()
893 { subModel.push_approximation(); }
894 
895 
push_available()896 inline bool RecastModel::push_available()
897 { return subModel.push_available(); }
898 
899 
finalize_approximation()900 inline void RecastModel::finalize_approximation()
901 { subModel.finalize_approximation(); }
902 
903 
combine_approximation()904 inline void RecastModel::combine_approximation()
905 { subModel.combine_approximation(); }
906 
907 
combined_to_active(bool clear_combined)908 inline void RecastModel::combined_to_active(bool clear_combined)
909 { subModel.combined_to_active(clear_combined); }
910 
911 
912 /*
913 inline void RecastModel::store_approximation(size_t index)
914 { subModel.store_approximation(index); }
915 
916 
917 inline void RecastModel::restore_approximation(size_t index)
918 { subModel.restore_approximation(index); }
919 
920 
921 inline void RecastModel::remove_stored_approximation(size_t index)
922 { subModel.remove_stored_approximation(index); }
923 */
924 
925 
clear_inactive()926 inline void RecastModel::clear_inactive()
927 { subModel.clear_inactive(); }
928 
929 
approximations()930 inline std::vector<Approximation>& RecastModel::approximations()
931 { return subModel.approximations(); }
932 
933 
934 inline const RealVectorArray& RecastModel::
approximation_coefficients(bool normalized)935 approximation_coefficients(bool normalized)
936 { return subModel.approximation_coefficients(normalized); }
937 
938 
939 inline void RecastModel::
approximation_coefficients(const RealVectorArray & approx_coeffs,bool normalized)940 approximation_coefficients(const RealVectorArray& approx_coeffs,
941 			   bool normalized)
942 { subModel.approximation_coefficients(approx_coeffs, normalized); }
943 
944 
945 inline const RealVector& RecastModel::
approximation_variances(const Variables & vars)946 approximation_variances(const Variables& vars)
947 { return subModel.approximation_variances(vars); }
948 
949 
950 inline const Pecos::SurrogateData& RecastModel::
approximation_data(size_t fn_index)951 approximation_data(size_t fn_index)
952 { return subModel.approximation_data(fn_index); }
953 
954 
component_parallel_mode(short mode)955 inline void RecastModel::component_parallel_mode(short mode)
956 {
957   //if (mode != SUB_MODEL_MODE) {
958   //  Cerr << "Error: RecastModel only supports the SUB_MODEL_MODE component "
959   //       << "parallel mode." << std::endl;
960   //  abort_handler(-1);
961   //}
962 
963   // Since we don't want the thin recast wrapper interfering with subModel
964   // parallelism, we forward the parallel mode to the subModel.  This differs
965   // from all other derived Model implementations (which utilize the mode
966   // locally and do not forward it).
967   subModel.component_parallel_mode(mode);
968 }
969 
970 
mi_parallel_level_index() const971 inline size_t RecastModel::mi_parallel_level_index() const
972 { return subModel.mi_parallel_level_index(); }
973 
974 
local_eval_synchronization()975 inline short RecastModel::local_eval_synchronization()
976 { return subModel.local_eval_synchronization(); }
977 
978 
local_eval_concurrency()979 inline int RecastModel::local_eval_concurrency()
980 { return subModel.local_eval_concurrency(); }
981 
982 
derived_master_overload() const983 inline bool RecastModel::derived_master_overload() const
984 { return subModel.derived_master_overload(); }
985 
986 
987 inline IntIntPair RecastModel::
estimate_partition_bounds(int max_eval_concurrency)988 estimate_partition_bounds(int max_eval_concurrency)
989 { return subModel.estimate_partition_bounds(max_eval_concurrency); }
990 
991 
992 inline void RecastModel::
derived_init_communicators(ParLevLIter pl_iter,int max_eval_concurrency,bool recurse_flag)993 derived_init_communicators(ParLevLIter pl_iter, int max_eval_concurrency,
994 			   bool recurse_flag)
995 {
996   if (recurse_flag)
997     subModel.init_communicators(pl_iter, max_eval_concurrency);
998 }
999 
1000 
derived_init_serial()1001 inline void RecastModel::derived_init_serial()
1002 { subModel.init_serial(); }
1003 
1004 
1005 inline void RecastModel::
derived_set_communicators(ParLevLIter pl_iter,int max_eval_concurrency,bool recurse_flag)1006 derived_set_communicators(ParLevLIter pl_iter, int max_eval_concurrency,
1007 			  bool recurse_flag)
1008 {
1009   if (recurse_flag) {
1010     subModel.set_communicators(pl_iter, max_eval_concurrency);
1011 
1012     // RecastModels do not utilize default set_ie_asynchronous_mode() as
1013     // they do not define the ie_parallel_level
1014     asynchEvalFlag     = subModel.asynch_flag();
1015     evaluationCapacity = subModel.evaluation_capacity();
1016   }
1017 }
1018 
1019 
1020 inline void RecastModel::
derived_free_communicators(ParLevLIter pl_iter,int max_eval_concurrency,bool recurse_flag)1021 derived_free_communicators(ParLevLIter pl_iter, int max_eval_concurrency,
1022 			   bool recurse_flag)
1023 {
1024   if (recurse_flag)
1025     subModel.free_communicators(pl_iter, max_eval_concurrency);
1026 }
1027 
1028 
1029 inline void RecastModel::
serve_run(ParLevLIter pl_iter,int max_eval_concurrency)1030 serve_run(ParLevLIter pl_iter, int max_eval_concurrency)
1031 {
1032   // don't recurse, as subModel.serve() will set subModel comms
1033   set_communicators(pl_iter, max_eval_concurrency, false);
1034 
1035   subModel.serve_run(pl_iter, max_eval_concurrency); // sets subModel comms
1036 }
1037 
1038 
stop_servers()1039 inline void RecastModel::stop_servers()
1040 { subModel.stop_servers(); }
1041 
1042 
inactive_view(short view,bool recurse_flag)1043 inline void RecastModel::inactive_view(short view, bool recurse_flag)
1044 {
1045   currentVariables.inactive_view(view);
1046   userDefinedConstraints.inactive_view(view);
1047   if (recurse_flag)
1048     subModel.inactive_view(view, recurse_flag);
1049 }
1050 
1051 
interface_id() const1052 inline const String& RecastModel::interface_id() const
1053 { return subModel.interface_id(); }
1054 
1055 
evaluation_cache(bool recurse_flag) const1056 inline bool RecastModel::evaluation_cache(bool recurse_flag) const
1057 { return (recurse_flag) ? subModel.evaluation_cache(recurse_flag) : false; }
1058 
1059 
restart_file(bool recurse_flag) const1060 inline bool RecastModel::restart_file(bool recurse_flag) const
1061 { return (recurse_flag) ? subModel.restart_file(recurse_flag) : false; }
1062 
1063 
derived_evaluation_id() const1064 inline int RecastModel::derived_evaluation_id() const
1065 { return recastModelEvalCntr; }
1066 
1067 
set_evaluation_reference()1068 inline void RecastModel::set_evaluation_reference()
1069 { subModel.set_evaluation_reference(); }
1070 
1071 
fine_grained_evaluation_counters()1072 inline void RecastModel::fine_grained_evaluation_counters()
1073 { subModel.fine_grained_evaluation_counters(); }
1074 
1075 
1076 inline void RecastModel::
print_evaluation_summary(std::ostream & s,bool minimal_header,bool relative_count) const1077 print_evaluation_summary(std::ostream& s, bool minimal_header,
1078 			 bool relative_count) const
1079 { subModel.print_evaluation_summary(s, minimal_header, relative_count); }
1080 
1081 
warm_start_flag(const bool flag)1082 inline void RecastModel::warm_start_flag(const bool flag)
1083 {
1084   // Note: supportsEstimDerivs prevents quasi-Newton Hessian accumulations
1085   warmStartFlag = flag;
1086   subModel.warm_start_flag(flag);
1087 }
1088 
1089 
1090 /** RecastModel just forwards any tags to its subModel */
eval_tag_prefix(const String & eval_id_str)1091 inline void RecastModel::eval_tag_prefix(const String& eval_id_str)
1092 { subModel.eval_tag_prefix(eval_id_str); }
1093 
1094 } // namespace Dakota
1095 
1096 #endif
1097