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: SimulationModel
10 //- Description: Implementation code for the SimulationModel class
11 //- Owner: Mike Eldred
12 //- Checked by:
13
14 #include "dakota_system_defs.hpp"
15 #include "SimulationModel.hpp"
16 #include "ProblemDescDB.hpp"
17 #include "MarginalsCorrDistribution.hpp"
18
19 static const char rcsId[]="@(#) $Id: SimulationModel.cpp 6492 2009-12-19 00:04:28Z briadam $";
20
21
22 using namespace std;
23
24 namespace Dakota {
25
26
SimulationModel(ProblemDescDB & problem_db)27 SimulationModel::SimulationModel(ProblemDescDB& problem_db):
28 Model(BaseConstructor(), problem_db),
29 userDefinedInterface(problem_db.get_interface()),
30 solnCntlVarType(EMPTY_TYPE), solnCntlADVIndex(0), solnCntlRVIndex(0),
31 simModelEvalCntr(0)
32 {
33 componentParallelMode = INTERFACE_MODE;
34 ignoreBounds = problem_db.get_bool("responses.ignore_bounds");
35 centralHess = problem_db.get_bool("responses.central_hess");
36
37 initialize_solution_control(
38 problem_db.get_string("model.simulation.solution_level_control"),
39 problem_db.get_rv("model.simulation.solution_level_cost"));
40
41 }
42
43
44 void SimulationModel::
initialize_solution_control(const String & control,const RealVector & cost)45 initialize_solution_control(const String& control, const RealVector& cost)
46 {
47 solnCntlCostMap.clear();
48
49 size_t cost_len = cost.length();
50 if (control.empty()) {
51 // cost_len of 0: empty map for no solution control
52 // cost_len of 1: nominal cost for model w/o any soln levels
53 // cost_len > 1: error
54 if (cost_len == 1) // nominal cost with no solution control
55 solnCntlCostMap.insert(std::pair<Real, size_t>(cost[0], _NPOS));
56 else if (cost_len) { // more than 1 cost requires associated control
57 Cerr << "Error: vector-valued solution cost requires an associated "
58 << "solution control." << std::endl;
59 abort_handler(MODEL_ERROR);
60 }
61 return;
62 }
63
64 // find the variable label used for solution control within the discrete
65 // variables (all view). It must be a discrete variable so that the number
66 // of levels is finite; however, the discrete values may be int, string, or
67 // real. It should not be an active variable, but may not be an inactive
68 // variable (inactive view assigned from a higher level context).
69 solnCntlADVIndex = find_index(
70 currentVariables.all_discrete_int_variable_labels(), control);
71 if (solnCntlADVIndex != _NPOS) {
72 solnCntlVarType = currentVariables.
73 all_discrete_int_variable_types()[solnCntlADVIndex];
74 if (find_index(currentVariables.discrete_int_variable_labels(), control)
75 != _NPOS) {
76 Cerr << "Error: solution_level_control cannot be an active variable."
77 << std::endl;
78 abort_handler(MODEL_ERROR);
79 }
80 }
81 else {
82 solnCntlADVIndex = find_index(
83 currentVariables.all_discrete_string_variable_labels(), control);
84 if (solnCntlADVIndex != _NPOS) {
85 solnCntlVarType = currentVariables.
86 all_discrete_string_variable_types()[solnCntlADVIndex];
87 if (find_index(currentVariables.discrete_string_variable_labels(),
88 control) != _NPOS) {
89 Cerr << "Error: solution_level_control cannot be an active variable."
90 << std::endl;
91 abort_handler(MODEL_ERROR);
92 }
93 }
94 else {
95 solnCntlADVIndex = find_index(
96 currentVariables.all_discrete_real_variable_labels(), control);
97 if (solnCntlADVIndex != _NPOS) {
98 solnCntlVarType = currentVariables.
99 all_discrete_real_variable_types()[solnCntlADVIndex];
100 if (find_index(currentVariables.discrete_real_variable_labels(),
101 control) != _NPOS) {
102 Cerr << "Error: solution_level_control cannot be an active variable."
103 << std::endl;
104 abort_handler(MODEL_ERROR);
105 }
106 }
107 else {
108 Cerr << "Error: solution_level_control string identifier not found "
109 << "within discrete variable labels." << std::endl;
110 abort_handler(MODEL_ERROR);
111 }
112 }
113 }
114
115 // get size of corresponding set values
116 size_t i, num_lev;
117 std::shared_ptr<Pecos::MarginalsCorrDistribution> mvd_rep =
118 std::static_pointer_cast<Pecos::MarginalsCorrDistribution>
119 (mvDist.multivar_dist_rep());
120 const SharedVariablesData& svd = currentVariables.shared_data();
121 switch (solnCntlVarType) {
122 case DISCRETE_DESIGN_RANGE: case DISCRETE_INTERVAL_UNCERTAIN:
123 case DISCRETE_STATE_RANGE:
124 //solnCntlRVIndex = svd.adiv_index_to_all_index(solnCntlADVIndex);
125 num_lev =
126 userDefinedConstraints.all_discrete_int_upper_bounds()[solnCntlADVIndex] -
127 userDefinedConstraints.all_discrete_int_lower_bounds()[solnCntlADVIndex];
128 break;
129 case DISCRETE_DESIGN_SET_INT: case DISCRETE_STATE_SET_INT:
130 solnCntlRVIndex = svd.adiv_index_to_all_index(solnCntlADVIndex);
131 num_lev = mvd_rep->
132 pull_parameter_size<IntSet>(solnCntlRVIndex, Pecos::DSI_VALUES);
133 break;
134 case DISCRETE_DESIGN_SET_STRING: case DISCRETE_STATE_SET_STRING:
135 solnCntlRVIndex = svd.adsv_index_to_all_index(solnCntlADVIndex);
136 num_lev = mvd_rep->
137 pull_parameter_size<StringSet>(solnCntlRVIndex, Pecos::DSS_VALUES);
138 break;
139 case DISCRETE_DESIGN_SET_REAL: case DISCRETE_STATE_SET_REAL:
140 solnCntlRVIndex = svd.adrv_index_to_all_index(solnCntlADVIndex);
141 num_lev = mvd_rep->
142 pull_parameter_size<RealSet>(solnCntlRVIndex, Pecos::DSR_VALUES);
143 break;
144 case DISCRETE_UNCERTAIN_SET_INT:
145 solnCntlRVIndex = svd.adiv_index_to_all_index(solnCntlADVIndex);
146 num_lev = mvd_rep->
147 pull_parameter_size<IntRealMap>(solnCntlRVIndex,Pecos::DUSI_VALUES_PROBS);
148 break;
149 case DISCRETE_UNCERTAIN_SET_STRING:
150 solnCntlRVIndex = svd.adsv_index_to_all_index(solnCntlADVIndex);
151 num_lev = mvd_rep->
152 pull_parameter_size<StringRealMap>(solnCntlRVIndex,
153 Pecos::DUSS_VALUES_PROBS);
154 break;
155 case DISCRETE_UNCERTAIN_SET_REAL:
156 solnCntlRVIndex = svd.adrv_index_to_all_index(solnCntlADVIndex);
157 num_lev = mvd_rep->
158 pull_parameter_size<RealRealMap>(solnCntlRVIndex,
159 Pecos::DUSR_VALUES_PROBS);
160 break;
161 default:
162 Cerr << "Error: unsupported variable type in SimulationModel::"
163 << "initialize_solution_control" << std::endl;
164 abort_handler(MODEL_ERROR); break;
165 }
166
167 // process cost array to create ordered map.
168 // Specified set values are sorted on input, but specified costs are not
169 // --> solnCntlCostMap sorts on cost key and maps to the unordered index
170 // of these sorted values.
171 // > Example 1:
172 // model simulation
173 // solution_level_control = 'dssiv1'
174 // solution_level_cost = 10. 2. 200.
175 // results in solnCntlCostMap = { {2., 1}, {10., 0}, {200., 2} }
176 // > Example 2:
177 // model simulation
178 // solution_level_control = 'dssiv1'
179 // solution_level_cost = 10. # scalar multiplier
180 // results in solnCntlCostMap = { {1., 0}, {10., 1}, {100., 2} }
181 if (cost.length() == num_lev)
182 for (i=0; i<num_lev; ++i)
183 solnCntlCostMap.insert(std::pair<Real, size_t>(cost[i], i));
184 else if (cost.length() == 1) {
185 Real multiplier = cost[0], prod = 1.;
186 for (i=0; i<num_lev; ++i) { // assume increasing cost
187 solnCntlCostMap.insert(std::pair<Real, size_t>(prod, i));
188 prod *= multiplier;
189 }
190 }
191 else {
192 Cerr << "Error: solution_level_cost specification of length "
193 << cost.length() << " provided;\n expected scalar or vector "
194 << "of length " << num_lev << "." << std::endl;
195 abort_handler(MODEL_ERROR);
196 }
197 }
198
199
solution_level_index(unsigned short lev_index)200 /* Real */void SimulationModel::solution_level_index(unsigned short lev_index)
201 {
202 // incoming soln level index is an index into the ordered solnCntlCostMap,
203 // not to be confused with the value in the key-value pair that corresponds
204 // to the discrete variable value index (val_index below).
205 if (lev_index == USHRT_MAX) { // just return quietly to simplify calling code
206 return; // (rather than always checking index validity)
207
208 //Cerr << "Error: USHRT_MAX passed to SimulationModel::"
209 // << "solution_level_index()." << std::endl;
210 //abort_handler(MODEL_ERROR);
211 }
212
213 std::map<Real, size_t>::const_iterator c_cit = solnCntlCostMap.begin();
214 std::advance(c_cit, lev_index);
215 size_t val_index = c_cit->second;
216
217 std::shared_ptr<Pecos::MarginalsCorrDistribution> mvd_rep =
218 std::static_pointer_cast<Pecos::MarginalsCorrDistribution>
219 (mvDist.multivar_dist_rep());
220 switch (solnCntlVarType) {
221 case DISCRETE_DESIGN_RANGE: case DISCRETE_INTERVAL_UNCERTAIN:
222 case DISCRETE_STATE_RANGE: {
223 int val = val_index + userDefinedConstraints.
224 all_discrete_int_lower_bounds()[solnCntlADVIndex];
225 currentVariables.all_discrete_int_variable(val, solnCntlADVIndex);
226 break;
227 }
228 //////////////////////////////
229 case DISCRETE_DESIGN_SET_INT: case DISCRETE_STATE_SET_INT: {
230 IntSet is;
231 mvd_rep->pull_parameter<IntSet>(solnCntlRVIndex, Pecos::DSI_VALUES, is);
232 ISIter is_it = is.begin(); std::advance(is_it, val_index);
233 currentVariables.all_discrete_int_variable(*is_it, solnCntlADVIndex);
234 break;
235 }
236 case DISCRETE_DESIGN_SET_STRING: case DISCRETE_STATE_SET_STRING: {
237 StringSet ss;
238 mvd_rep->pull_parameter<StringSet>(solnCntlRVIndex, Pecos::DSS_VALUES, ss);
239 SSCIter ss_it = ss.begin(); std::advance(ss_it, val_index);
240 currentVariables.all_discrete_string_variable(*ss_it, solnCntlADVIndex);
241 break;
242 }
243 case DISCRETE_DESIGN_SET_REAL: case DISCRETE_STATE_SET_REAL: {
244 RealSet rs;
245 mvd_rep->pull_parameter<RealSet>(solnCntlRVIndex, Pecos::DSR_VALUES, rs);
246 RSIter rs_it = rs.begin(); std::advance(rs_it, val_index);
247 currentVariables.all_discrete_real_variable(*rs_it, solnCntlADVIndex);
248 break;
249 }
250 //////////////////////////////
251 case DISCRETE_UNCERTAIN_SET_INT: {
252 IntRealMap irm;
253 mvd_rep->pull_parameter<IntRealMap>(solnCntlRVIndex,
254 Pecos::DUSI_VALUES_PROBS, irm);
255 IRMIter ir_it = irm.begin(); std::advance(ir_it, val_index);
256 currentVariables.all_discrete_int_variable(ir_it->first, solnCntlADVIndex);
257 break;
258 }
259 case DISCRETE_UNCERTAIN_SET_STRING: {
260 StringRealMap srm;
261 mvd_rep->pull_parameter<StringRealMap>(solnCntlRVIndex,
262 Pecos::DUSS_VALUES_PROBS, srm);
263 SRMIter sr_it = srm.begin(); std::advance(sr_it, val_index);
264 currentVariables.all_discrete_string_variable(sr_it->first,
265 solnCntlADVIndex);
266 break;
267 }
268 case DISCRETE_UNCERTAIN_SET_REAL: {
269 RealRealMap rrm;
270 mvd_rep->pull_parameter<RealRealMap>(solnCntlRVIndex,
271 Pecos::DUSR_VALUES_PROBS, rrm);
272 RRMIter rr_it = rrm.begin(); std::advance(rr_it, val_index);
273 currentVariables.all_discrete_real_variable(rr_it->first, solnCntlADVIndex);
274 break;
275 }
276 }
277
278 //return c_cit->first; // cost estimate for this solution level index
279 }
280
281
solution_level_index() const282 unsigned short SimulationModel::solution_level_index() const
283 {
284 size_t val_index;
285 std::shared_ptr<Pecos::MarginalsCorrDistribution> mvd_rep =
286 std::static_pointer_cast<Pecos::MarginalsCorrDistribution>
287 (mvDist.multivar_dist_rep());
288 switch (solnCntlVarType) {
289 case DISCRETE_DESIGN_RANGE: case DISCRETE_INTERVAL_UNCERTAIN:
290 case DISCRETE_STATE_RANGE: {
291 int val = currentVariables.all_discrete_int_variables()[solnCntlADVIndex],
292 l_bnd = userDefinedConstraints.all_discrete_int_lower_bounds()
293 [solnCntlADVIndex];
294 val_index = (size_t)(val - l_bnd);
295 break;
296 }
297 //////////////////////////////
298 case DISCRETE_DESIGN_SET_INT: case DISCRETE_STATE_SET_INT: {
299 IntSet is;
300 mvd_rep->pull_parameter<IntSet>(solnCntlRVIndex, Pecos::DSI_VALUES, is);
301 val_index = set_value_to_index(
302 currentVariables.all_discrete_int_variables()[solnCntlADVIndex], is);
303 break;
304 }
305 case DISCRETE_DESIGN_SET_STRING: case DISCRETE_STATE_SET_STRING: {
306 StringSet ss;
307 mvd_rep->pull_parameter<StringSet>(solnCntlRVIndex, Pecos::DSS_VALUES, ss);
308 val_index = set_value_to_index(
309 currentVariables.all_discrete_string_variables()[solnCntlADVIndex], ss);
310 break;
311 }
312 case DISCRETE_DESIGN_SET_REAL: case DISCRETE_STATE_SET_REAL: {
313 RealSet rs;
314 mvd_rep->pull_parameter<RealSet>(solnCntlRVIndex, Pecos::DSR_VALUES, rs);
315 val_index = set_value_to_index(
316 currentVariables.all_discrete_real_variables()[solnCntlADVIndex], rs);
317 break;
318 }
319 //////////////////////////////
320 case DISCRETE_UNCERTAIN_SET_INT: {
321 IntRealMap irm;
322 mvd_rep->pull_parameter<IntRealMap>(solnCntlRVIndex,
323 Pecos::DUSI_VALUES_PROBS, irm);
324 val_index = map_key_to_index(
325 currentVariables.all_discrete_int_variables()[solnCntlADVIndex], irm);
326 break;
327 }
328 case DISCRETE_UNCERTAIN_SET_STRING: {
329 StringRealMap srm;
330 mvd_rep->pull_parameter<StringRealMap>(solnCntlRVIndex,
331 Pecos::DUSS_VALUES_PROBS, srm);
332 val_index = map_key_to_index(
333 currentVariables.all_discrete_string_variables()[solnCntlADVIndex], srm);
334 break;
335 }
336 case DISCRETE_UNCERTAIN_SET_REAL: {
337 RealRealMap rrm;
338 mvd_rep->pull_parameter<RealRealMap>(solnCntlRVIndex,
339 Pecos::DUSR_VALUES_PROBS, rrm);
340 val_index = map_key_to_index(
341 currentVariables.all_discrete_real_variables()[solnCntlADVIndex], rrm);
342 break;
343 }
344 //////////////////////////////
345 default: // EMPTY_TYPE (no solution_level_control provided)
346 return USHRT_MAX; break;
347 }
348
349 // convert val_index to lev_index and return
350 size_t lev_index = map_value_to_index(val_index, solnCntlCostMap);
351 return (lev_index == _NPOS) ? USHRT_MAX : (unsigned short)lev_index;
352 }
353
354
solution_level_costs() const355 RealVector SimulationModel::solution_level_costs() const
356 {
357 RealVector cost_levels(solnCntlCostMap.size(), false);
358 std::map<Real, size_t>::const_iterator cit; size_t i;
359 for (cit=solnCntlCostMap.begin(), i=0; cit!=solnCntlCostMap.end(); ++cit, ++i)
360 cost_levels[i] = cit->first;
361 return cost_levels;
362 }
363
364
solution_level_cost() const365 Real SimulationModel::solution_level_cost() const
366 {
367 std::map<Real, size_t>::const_iterator cit = solnCntlCostMap.begin();
368 if (cit == solnCntlCostMap.end()) return 0.;
369 else {
370 unsigned short lev_index = solution_level_index();
371 if (lev_index != USHRT_MAX)
372 std::advance(cit, lev_index);
373 return cit->first;
374 }
375 }
376
377
378 /*
379 void SimulationModel::component_parallel_mode(short mode)
380 {
381 if (mode != INTERFACE_MODE) {
382 Cerr << "Error: SimulationModel only supports the INTERFACE_MODE component "
383 << "parallel mode." << std::endl;
384 abort_handler(MODEL_ERROR);
385 }
386 parallelLib.parallel_configuration_iterator(modelPCIter);
387 //componentParallelMode = mode;
388 }
389 */
390
391
392 /** SimulationModel doesn't need to change the tagging, so just forward to
393 Interface */
eval_tag_prefix(const String & eval_id_str)394 void SimulationModel::eval_tag_prefix(const String& eval_id_str)
395 {
396 // Simulation model uses the counter from the interface
397 bool append_iface_id = true;
398 userDefinedInterface.eval_tag_prefix(eval_id_str, append_iface_id);
399 }
400
401 /*ActiveSet SimulationModel::default_active_set() {
402 ActiveSet set(numFns, numDerivVars);
403 ShortArray asv(numFns, 1);
404
405 if(gradientType != "none" && (gradientType == "analytic" || supportsEstimDerivs))
406 for(auto &a : asv)
407 a |= 2;
408
409 if(hessianType != "none" && (hessianType == "analytic" || supportsEstimDerivs))
410 for(auto &a : asv)
411 a |= 4;
412
413 set.request_vector(asv);
414 return set;
415 }
416 */
default_interface_active_set()417 ActiveSet SimulationModel::default_interface_active_set() {
418 // compute the default active set for the user-defined interface
419 ActiveSet set;
420 set.derivative_vector(currentVariables.all_continuous_variable_ids());
421 bool has_deriv_vars = set.derivative_vector().size() != 0;
422 ShortArray asv(numFns, 1);
423 if(has_deriv_vars) {
424 if(gradientType == "analytic") {
425 for(auto &a : asv)
426 a |= 2;
427 } else if(gradientType == "mixed") {
428 for(const auto &gi : gradIdAnalytic)
429 asv[gi-1] |= 2;
430 }
431
432 if(hessianType == "analytic") {
433 for(auto &a : asv)
434 a |= 4;
435 } else if(hessianType == "mixed") {
436 for(const auto &hi : hessIdAnalytic)
437 asv[hi-1] |= 4;
438 }
439 }
440 set.request_vector(asv);
441 return set;
442 }
443
declare_sources()444 void SimulationModel::declare_sources() {
445 evaluationsDB.declare_source(modelId, modelType, interface_id(), "interface");
446 }
447 } // namespace Dakota
448