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