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: Interface
10 //- Description: Class implementation for abstract interface base class
11 //- Owner: Michael Eldred
12
13 #include "DakotaInterface.hpp"
14 #include "ProblemDescDB.hpp"
15 #include "DakotaVariables.hpp"
16
17 #include "SysCallApplicInterface.hpp"
18
19 #if defined(HAVE_SYS_WAIT_H) && defined(HAVE_UNISTD_H)
20 #include "ForkApplicInterface.hpp"
21 #elif defined(_WIN32) // or _MSC_VER (native MSVS compilers)
22 #include "SpawnApplicInterface.hpp"
23 #endif // HAVE_SYS_WAIT_H, HAVE_UNISTD_H
24
25 // Direct interfaces
26 #ifdef DAKOTA_GRID
27 #include "GridApplicInterface.hpp"
28 #endif // DAKOTA_GRID
29 #ifdef DAKOTA_MATLAB
30 #include "MatlabInterface.hpp"
31 #endif // DAKOTA_MATLAB
32 #ifdef DAKOTA_PYTHON
33 #include "PythonInterface.hpp"
34 #endif // DAKOTA_PYTHON
35 #ifdef DAKOTA_SCILAB
36 #include "ScilabInterface.hpp"
37 #endif // DAKOTA_SCILAB
38 #include "TestDriverInterface.hpp"
39
40 #include "ApproximationInterface.hpp"
41
42 #ifdef HAVE_AMPL
43 #undef NO // avoid name collision from UTILIB
44 #include "external/ampl/asl.h"
45 #endif // HAVE_AMPL
46
47 //#define DEBUG
48
49 namespace Dakota {
50
51 // Initialization of static interface ID counters
52 size_t Interface::noSpecIdNum = 0;
53
54
55 /** This constructor is the one which must build the base class data for all
56 inherited interfaces. get_interface() instantiates a derived class letter
57 and the derived constructor selects this base class constructor in its
58 initialization list (to avoid the recursion of the base class constructor
59 calling get_interface() again). Since this is the letter and the letter
60 IS the representation, interfaceRep is set to NULL. */
Interface(BaseConstructor,const ProblemDescDB & problem_db)61 Interface::Interface(BaseConstructor, const ProblemDescDB& problem_db):
62 interfaceType(problem_db.get_ushort("interface.type")),
63 interfaceId(problem_db.get_string("interface.id")),
64 analysisComponents(
65 problem_db.get_s2a("interface.application.analysis_components")),
66 algebraicMappings(false),
67 coreMappings(true), outputLevel(problem_db.get_short("method.output")),
68 currEvalId(0), fineGrainEvalCounters(outputLevel > NORMAL_OUTPUT),
69 evalIdCntr(0), newEvalIdCntr(0), evalIdRefPt(0), newEvalIdRefPt(0),
70 multiProcEvalFlag(false), ieDedMasterFlag(false),
71 // See base constructor in DakotaIterator.cpp for full discussion of output
72 // verbosity. Interfaces support the full granularity in verbosity.
73 appendIfaceId(true), asl(NULL)
74 {
75 #ifdef DEBUG
76 outputLevel = DEBUG_OUTPUT;
77 #endif // DEBUG
78 if(interfaceId.empty())
79 interfaceId = user_auto_id();
80 // Process the algebraic_mappings file (an AMPL .nl file) to get the number
81 // of variables/responses (currently, the tags are converted to index arrays
82 // at evaluation time, using the passed vars and response).
83 // TO DO: parallel bcast of data or very proc reads file?
84 const String& ampl_file_name
85 = problem_db.get_string("interface.algebraic_mappings");
86 if (!ampl_file_name.empty()) {
87 #ifdef HAVE_AMPL
88 algebraicMappings = true;
89 bool hess_flag
90 = (problem_db.get_string("responses.hessian_type") == "analytic");
91 asl = (hess_flag) ? ASL_alloc(ASL_read_pfgh) : ASL_alloc(ASL_read_fg);
92 // allow user input of either stub or stub.nl
93 String stub = (strends(ampl_file_name, ".nl")) ?
94 String(ampl_file_name, 0, ampl_file_name.size() - 3) : ampl_file_name;
95 //std::ifstream ampl_nl(ampl_file_name);
96 fint stub_str_len = stub.size();
97 // BMA NOTE: casting away the constness as done historically in DakotaString
98 char* nonconst_stub = (char*) stub.c_str();
99 FILE* ampl_nl = jac0dim(nonconst_stub, stub_str_len);
100 if (!ampl_nl) {
101 Cerr << "\nError: failure opening " << ampl_file_name << std::endl;
102 abort_handler(IO_ERROR);
103 }
104 int rtn = (hess_flag) ? pfgh_read(ampl_nl, ASL_return_read_err)
105 : fg_read(ampl_nl, ASL_return_read_err);
106 if (rtn) {
107 Cerr << "\nError: AMPL processing problem with " << ampl_file_name
108 << std::endl;
109 abort_handler(IO_ERROR);
110 }
111
112 // extract input/output tag lists
113 String row = stub + ".row", col = stub + ".col", ampl_tag;
114
115 std::ifstream ampl_col(col.c_str());
116 if (!ampl_col) {
117 Cerr << "\nError: failure opening " << col << std::endl;
118 abort_handler(IO_ERROR);
119 }
120 algebraicVarTags.resize(n_var);
121 for (size_t i=0; i<n_var; i++) {
122 std::getline(ampl_col, ampl_tag);
123 if (ampl_col.good())
124 algebraicVarTags[i] = ampl_tag;
125 else {
126 Cerr << "\nError: failure reading AMPL col file " << col
127 << std::endl;
128 abort_handler(IO_ERROR);
129 }
130 }
131
132 std::ifstream ampl_row(row.c_str());
133 if (!ampl_row) {
134 Cerr << "\nError: failure opening " << row << std::endl;
135 abort_handler(IO_ERROR);
136 }
137 algebraicFnTags.resize(n_obj+n_con);
138 algebraicFnTypes.resize(n_obj+n_con);
139 algebraicConstraintWeights.resize(n_con);
140 for (size_t i=0; i<n_obj+n_con; i++) {
141 getline(ampl_row, ampl_tag);
142 if (ampl_row.good()) {
143 algebraicFnTags[i] = ampl_tag;
144 algebraicFnTypes[i] = algebraic_function_type(ampl_tag);
145 }
146 else {
147 Cerr << "\nError: failure reading AMPL row file " << row
148 << std::endl;
149 abort_handler(IO_ERROR);
150 }
151 }
152
153 #ifdef DEBUG
154 Cout << ">>>>> algebraicVarTags =\n" << algebraicVarTags
155 << "\n>>>>> algebraicFnTags =\n" << algebraicFnTags
156 << "\n>>>>> algebraicFnTypes =\n" << algebraicFnTypes << std::endl;
157 #endif
158
159 #else
160 Cerr << "\nError: algebraic_mappings not supported without the AMPL solver "
161 << "library provided with the Acro package." << std::endl;
162 abort_handler(-1);
163 #endif // HAVE_AMPL
164 }
165 }
166
167
Interface(NoDBBaseConstructor,size_t num_fns,short output_level)168 Interface::Interface(NoDBBaseConstructor, size_t num_fns, short output_level):
169 interfaceId(no_spec_id()), algebraicMappings(false), coreMappings(true),
170 outputLevel(output_level), currEvalId(0),
171 fineGrainEvalCounters(outputLevel > NORMAL_OUTPUT), evalIdCntr(0),
172 newEvalIdCntr(0), evalIdRefPt(0), newEvalIdRefPt(0), multiProcEvalFlag(false),
173 ieDedMasterFlag(false), appendIfaceId(true)
174 {
175 #ifdef DEBUG
176 outputLevel = DEBUG_OUTPUT;
177 #endif // DEBUG
178 }
179
180
181 /** used in Model envelope class instantiations */
Interface()182 Interface::Interface()
183 { }
184
185
186 /** Used in Model instantiation to build the envelope. This constructor
187 only needs to extract enough data to properly execute get_interface, since
188 Interface::Interface(BaseConstructor, problem_db) builds the
189 actual base class data inherited by the derived interfaces. */
Interface(ProblemDescDB & problem_db)190 Interface::Interface(ProblemDescDB& problem_db):
191 // Set the rep pointer to the appropriate interface type
192 interfaceRep(get_interface(problem_db))
193 {
194 if (!interfaceRep) // bad type or insufficient memory
195 abort_handler(-1);
196 }
197
198
199 /** used only by the envelope constructor to initialize interfaceRep
200 to the appropriate derived type. */
get_interface(ProblemDescDB & problem_db)201 std::shared_ptr<Interface> Interface::get_interface(ProblemDescDB& problem_db)
202 {
203 const unsigned short interface_type = problem_db.get_ushort("interface.type");
204
205 // In the case where a derived interface type has been selected for managing
206 // analysis_drivers, then this determines the letter instantiation and any
207 // algebraic mappings are overlayed by ApplicationInterface.
208 const String& algebraic_map_file
209 = problem_db.get_string("interface.algebraic_mappings");
210 if (interface_type == SYSTEM_INTERFACE)
211 return std::make_shared<SysCallApplicInterface>(problem_db);
212 else if (interface_type == FORK_INTERFACE) {
213 #if defined(HAVE_SYS_WAIT_H) && defined(HAVE_UNISTD_H) // includes CYGWIN/MINGW
214 return std::make_shared<ForkApplicInterface>(problem_db);
215 #elif defined(_WIN32) // or _MSC_VER (native MSVS compilers)
216 return std::make_shared<SpawnApplicInterface>(problem_db);
217 #else
218 Cerr << "Fork interface requested, but not enabled in this DAKOTA "
219 << "executable." << std::endl;
220 return std::shared_ptr<Interface>();
221 #endif
222 }
223
224 else if (interface_type == TEST_INTERFACE)
225 return std::make_shared<TestDriverInterface>(problem_db);
226 // Note: in the case of a plug-in direct interface, this object gets replaced
227 // using Interface::assign_rep(). Error checking in DirectApplicInterface::
228 // derived_map_ac() should catch if this replacement fails to occur properly.
229
230 #ifdef DAKOTA_GRID
231 else if (interface_type == GRID_INTERFACE)
232 return std::make_shared<GridApplicInterface>(problem_db);
233 #endif
234
235 else if (interface_type == MATLAB_INTERFACE) {
236 #ifdef DAKOTA_MATLAB
237 return std::make_shared<MatlabInterface>(problem_db);
238 #else
239 Cerr << "Direct Matlab interface requested, but not enabled in this "
240 << "DAKOTA executable." << std::endl;
241 return std::shared_ptr<Interface>();
242 #endif
243 }
244
245 else if (interface_type == PYTHON_INTERFACE) {
246 #ifdef DAKOTA_PYTHON
247 return std::make_shared<PythonInterface>(problem_db);
248 #else
249 Cerr << "Direct Python interface requested, but not enabled in this "
250 << "DAKOTA executable." << std::endl;
251 return std::shared_ptr<Interface>();
252 #endif
253 }
254
255 else if (interface_type == SCILAB_INTERFACE) {
256 #ifdef DAKOTA_SCILAB
257 return std::make_shared<ScilabInterface>(problem_db);
258 #else
259 Cerr << "Direct Scilab interface requested, but not enabled in this "
260 << "DAKOTA executable." << std::endl;
261 return std::shared_ptr<Interface>();
262 #endif
263 }
264
265 // Should not be needed since ApproximationInterface is plugged-in from
266 // DataFitSurrModel using Interface::assign_rep().
267 //else if (interface_type == APPROX_INTERFACE)
268 // return std::make_shared<ApproximationInterface>(problem_db, num_acv, num_fns);
269
270 // In the case where only algebraic mappings are used, then no derived map
271 // functionality is needed and ApplicationInterface is used for the letter.
272 else if (!algebraic_map_file.empty()) {
273 #ifdef DEBUG
274 Cout << ">>>>> new ApplicationInterface: " << algebraic_map_file
275 << std::endl;
276 #endif // DEBUG
277 return std::make_shared<ApplicationInterface>(problem_db);
278 }
279
280 // If the interface type is empty (e.g., from default DataInterface creation
281 // in ProblemDescDB::check_input()), then ApplicationInterface is the letter.
282 else if (interface_type == DEFAULT_INTERFACE) {
283 Cerr << "Warning: empty interface type in Interface::get_interface()."
284 << std::endl;
285 return std::make_shared<ApplicationInterface>(problem_db);
286 }
287
288 else {
289 Cerr << "Invalid interface: " << interface_enum_to_string(interface_type)
290 << std::endl;
291 }
292
293 return std::shared_ptr<Interface>();
294 }
295
296
297 /** Copy constructor manages sharing of interfaceRep */
Interface(const Interface & interface_in)298 Interface::Interface(const Interface& interface_in):
299 interfaceRep(interface_in.interfaceRep)
300 { /* empty ctor */ }
301
302
operator =(const Interface & interface_in)303 Interface Interface::operator=(const Interface& interface_in)
304 {
305 interfaceRep = interface_in.interfaceRep;
306 return *this; // calls copy constructor since returned by value
307 }
308
309
~Interface()310 Interface::~Interface()
311 { /* empty dtor */ }
312
313
314 /** DEPRECATED but temporarily left for library mode clients needing to
315 MIGRATE TO shared_ptr API
316
317 Similar to the assignment operator, the assign_rep() function
318 decrements referenceCount for the old interfaceRep and assigns the
319 new interfaceRep. It is different in that it is used for
320 publishing derived class letters to existing envelopes, as opposed
321 to sharing representations among multiple envelopes (in
322 particular, assign_rep is passed a letter object and operator= is
323 passed an envelope object). Letter assignment historically
324 supported two models as governed by ref_count_incr:
325
326 \li ref_count_incr = true (removed): the incoming letter belongs
327 to another envelope. In this case, increment the reference count
328 in the normal manner so that deallocation of the letter is handled
329 properly.
330
331 \li ref_count_incr = false (always): the incoming letter is
332 instantiated on the fly and has no envelope. This case is modeled
333 after get_interface(): a letter is dynamically allocated using new
334 and passed into assign_rep, the letter's reference count is not
335 incremented, and the letter is not remotely deleted (its memory
336 management is passed over to the envelope). */
assign_rep(Interface * interface_rep,bool ref_count_incr)337 void Interface::assign_rep(Interface* interface_rep, bool ref_count_incr)
338 {
339 interfaceRep.reset(interface_rep);
340 }
341
342
343 /** The assign_rep() function is used for publishing derived class
344 letters to existing envelopes, as opposed to sharing
345 representations among multiple envelopes (in particular,
346 assign_rep is passed a letter object and operator= is passed an
347 envelope object).
348
349 Use case assumes the incoming letter is instantiated on the fly
350 and has no envelope. This case is modeled after get_interface(): a
351 letter is dynamically allocated and passed into assign_rep (its
352 memory management is passed over to the envelope).
353
354 If the letter happens to be managed by another envelope, it will
355 persist as long as the last envelope referencing it. */
assign_rep(std::shared_ptr<Interface> interface_rep)356 void Interface::assign_rep(std::shared_ptr<Interface> interface_rep)
357 {
358 interfaceRep = interface_rep;
359 }
360
361
fine_grained_evaluation_counters(size_t num_fns)362 void Interface::fine_grained_evaluation_counters(size_t num_fns)
363 {
364 if (interfaceRep) // envelope fwd to letter
365 interfaceRep->fine_grained_evaluation_counters(num_fns);
366 else if (!fineGrainEvalCounters) { // letter (not virtual)
367 init_evaluation_counters(num_fns);
368 fineGrainEvalCounters = true;
369 }
370 }
371
372
init_evaluation_counters(size_t num_fns)373 void Interface::init_evaluation_counters(size_t num_fns)
374 {
375 if (interfaceRep) // envelope fwd to letter
376 interfaceRep->init_evaluation_counters(num_fns);
377 else { // letter (not virtual)
378 //if (fnLabels.empty()) {
379 // fnLabels.resize(num_fns);
380 // build_labels(fnLabels, "response_fn_"); // generic resp fn labels
381 //}
382 if (fnValCounter.size() != num_fns) {
383 fnValCounter.assign(num_fns, 0); fnGradCounter.assign(num_fns, 0);
384 fnHessCounter.assign(num_fns, 0); newFnValCounter.assign(num_fns, 0);
385 newFnGradCounter.assign(num_fns, 0); newFnHessCounter.assign(num_fns, 0);
386 fnValRefPt.assign(num_fns, 0); fnGradRefPt.assign(num_fns, 0);
387 fnHessRefPt.assign(num_fns, 0); newFnValRefPt.assign(num_fns, 0);
388 newFnGradRefPt.assign(num_fns, 0); newFnHessRefPt.assign(num_fns, 0);
389 }
390 }
391 }
392
393
set_evaluation_reference()394 void Interface::set_evaluation_reference()
395 {
396 if (interfaceRep) // envelope fwd to letter
397 interfaceRep->set_evaluation_reference();
398 else { // letter (not virtual)
399
400 evalIdRefPt = evalIdCntr;
401 newEvalIdRefPt = newEvalIdCntr;
402
403 if (fineGrainEvalCounters) {
404 size_t i, num_fns = fnValCounter.size();
405 for (i=0; i<num_fns; i++) {
406 fnValRefPt[i] = fnValCounter[i];
407 newFnValRefPt[i] = newFnValCounter[i];
408 fnGradRefPt[i] = fnGradCounter[i];
409 newFnGradRefPt[i] = newFnGradCounter[i];
410 fnHessRefPt[i] = fnHessCounter[i];
411 newFnHessRefPt[i] = newFnHessCounter[i];
412 }
413 }
414 }
415 }
416
417
418 void Interface::
print_evaluation_summary(std::ostream & s,bool minimal_header,bool relative_count) const419 print_evaluation_summary(std::ostream& s, bool minimal_header,
420 bool relative_count) const
421 {
422 if (interfaceRep) // envelope fwd to letter
423 interfaceRep->print_evaluation_summary(s, minimal_header, relative_count);
424 else { // letter (not virtual)
425
426 // standard evaluation summary
427 if (minimal_header) {
428 if (interfaceId.empty() || interfaceId == "NO_ID")
429 s << " Interface evaluations";
430 else
431 s << " " << interfaceId << " evaluations";
432 }
433 else {
434 s << "<<<<< Function evaluation summary";
435 if (!(interfaceId.empty() || interfaceId == "NO_ID"))
436 s << " (" << interfaceId << ')';
437 }
438 int fn_evals = (relative_count) ? evalIdCntr - evalIdRefPt
439 : evalIdCntr;
440 int new_fn_evals = (relative_count) ? newEvalIdCntr - newEvalIdRefPt
441 : newEvalIdCntr;
442 s << ": " << fn_evals << " total (" << new_fn_evals << " new, "
443 << fn_evals - new_fn_evals << " duplicate)\n";
444
445 // detailed evaluation summary
446 if (fineGrainEvalCounters) {
447 size_t i, num_fns = std::min(fnValCounter.size(), fnLabels.size());
448 for (i=0; i<num_fns; i++) {
449 int t_v = (relative_count) ? fnValCounter[i] - fnValRefPt[i]
450 : fnValCounter[i];
451 int n_v = (relative_count) ? newFnValCounter[i] - newFnValRefPt[i]
452 : newFnValCounter[i];
453 int t_g = (relative_count) ? fnGradCounter[i] - fnGradRefPt[i]
454 : fnGradCounter[i];
455 int n_g = (relative_count) ? newFnGradCounter[i] - newFnGradRefPt[i]
456 : newFnGradCounter[i];
457 int t_h = (relative_count) ? fnHessCounter[i] - fnHessRefPt[i]
458 : fnHessCounter[i];
459 int n_h = (relative_count) ? newFnHessCounter[i] - newFnHessRefPt[i]
460 : newFnHessCounter[i];
461 s << std::setw(15) << fnLabels[i] << ": "
462 << t_v << " val (" << n_v << " n, " << t_v - n_v << " d), "
463 << t_g << " grad (" << n_g << " n, " << t_g - n_g << " d), "
464 << t_h << " Hess (" << n_h << " n, " << t_h - n_h << " d)\n";
465 }
466 }
467 }
468 }
469
470
471 /// default implementation just sets the list of eval ID tags;
472 /// derived classes containing additional models or interfaces should
473 /// override (currently no use cases)
474 void Interface::
eval_tag_prefix(const String & eval_id_str,bool append_iface_id)475 eval_tag_prefix(const String& eval_id_str, bool append_iface_id)
476 {
477 if (interfaceRep)
478 interfaceRep->eval_tag_prefix(eval_id_str, append_iface_id);
479 else {
480 evalTagPrefix = eval_id_str;
481 appendIfaceId = append_iface_id;
482 }
483 }
484
485
map(const Variables & vars,const ActiveSet & set,Response & response,bool asynch_flag)486 void Interface::map(const Variables& vars, const ActiveSet& set,
487 Response& response, bool asynch_flag)
488 {
489 if (interfaceRep) // envelope fwd to letter
490 interfaceRep->map(vars, set, response, asynch_flag);
491 else { // letter lacking redefinition of virtual fn.
492 Cerr << "Error: Letter lacking redefinition of virtual map function.\n"
493 << "No default map defined at Interface base class." << std::endl;
494 abort_handler(-1);
495 }
496 }
497
498
499 void Interface::
init_algebraic_mappings(const Variables & vars,const Response & response)500 init_algebraic_mappings(const Variables& vars, const Response& response)
501 {
502 size_t i, num_alg_vars = algebraicVarTags.size(),
503 num_alg_fns = algebraicFnTags.size();
504
505 algebraicACVIndices.resize(num_alg_vars);
506 algebraicACVIds.resize(num_alg_vars);
507 StringMultiArrayConstView acv_labels = vars.all_continuous_variable_labels();
508 SizetMultiArrayConstView acv_ids = vars.all_continuous_variable_ids();
509 for (i=0; i<num_alg_vars; ++i) {
510 // Note: variable mappings only support continuous variables.
511 // discrete variables are not directly supported by ASL interface.
512 size_t acv_index = find_index(acv_labels, algebraicVarTags[i]);
513 //size_t adv_index = find_index(adv_labels, algebraicVarTags[i]);
514 if (acv_index == _NPOS) { // && adv_index == _NPOS) {
515 Cerr << "\nError: AMPL column label " << algebraicVarTags[i] << " does "
516 <<"not exist in DAKOTA continuous variable descriptors.\n"
517 << std::endl;
518 abort_handler(INTERFACE_ERROR);
519 }
520 else {
521 algebraicACVIndices[i] = acv_index;
522 //algebraicADVIndices[i] = adv_index;
523 algebraicACVIds[i] = acv_ids[acv_index];
524 }
525 }
526
527 algebraicFnIndices.resize(num_alg_fns);
528 const StringArray& fn_labels = response.function_labels();
529 for (size_t i=0; i<num_alg_fns; ++i) {
530 size_t fn_index = Pecos::find_index(fn_labels, algebraicFnTags[i]);
531 if (fn_index == _NPOS) {
532 Cerr << "\nError: AMPL row label " << algebraicFnTags[i] << " does not "
533 <<"exist in DAKOTA response descriptors.\n" << std::endl;
534 abort_handler(INTERFACE_ERROR);
535 }
536 else
537 algebraicFnIndices[i] = fn_index;
538 }
539 }
540
541
542 void Interface::
asv_mapping(const ActiveSet & total_set,ActiveSet & algebraic_set,ActiveSet & core_set)543 asv_mapping(const ActiveSet& total_set, ActiveSet& algebraic_set,
544 ActiveSet& core_set)
545 {
546 const ShortArray& total_asv = total_set.request_vector();
547 const SizetArray& total_dvv = total_set.derivative_vector();
548
549 // algebraic_asv/dvv:
550
551 // the algebraic active set is defined over reduced algebraic function
552 // and variable spaces, rather than the original spaces. This simplifies
553 // algebraic_mappings() and allows direct copies of data from AMPL.
554 size_t i, num_alg_fns = algebraicFnTags.size(),
555 num_alg_vars = algebraicVarTags.size();
556 ShortArray algebraic_asv(num_alg_fns);
557 SizetArray algebraic_dvv(num_alg_vars);
558 for (i=0; i<num_alg_fns; i++) // map total_asv to algebraic_asv
559 algebraic_asv[i] = total_asv[algebraicFnIndices[i]];
560
561 algebraic_set.request_vector(algebraic_asv);
562 algebraic_set.derivative_vector(algebraic_dvv);
563 algebraic_set.derivative_start_value(1);
564
565 // core_asv/dvv:
566
567 // for now, core_asv is the same as total_asv, since there is no mechanism
568 // yet to determine if the algebraic_mapping portion is the complete
569 // definition (for which core_asv requests could be turned off).
570 core_set.request_vector(total_asv);
571 core_set.derivative_vector(total_dvv);
572 }
573
574
575 void Interface::
asv_mapping(const ActiveSet & algebraic_set,ActiveSet & total_set)576 asv_mapping(const ActiveSet& algebraic_set, ActiveSet& total_set)
577 {
578 const ShortArray& algebraic_asv = algebraic_set.request_vector();
579 size_t i, num_alg_fns = algebraicFnTags.size();
580 for (i=0; i<num_alg_fns; i++) // map algebraic_asv to total_asv
581 total_set.request_value(algebraic_asv[i], algebraicFnIndices[i]);
582 }
583
584
585 void Interface::
algebraic_mappings(const Variables & vars,const ActiveSet & algebraic_set,Response & algebraic_response)586 algebraic_mappings(const Variables& vars, const ActiveSet& algebraic_set,
587 Response& algebraic_response)
588 {
589 #ifdef HAVE_AMPL
590 // make sure cur_ASL is pointing to the ASL of this interface
591 // this is important for problems with multiple interfaces
592 set_cur_ASL(asl);
593 const ShortArray& algebraic_asv = algebraic_set.request_vector();
594 const SizetArray& algebraic_dvv = algebraic_set.derivative_vector();
595 size_t i, num_alg_fns = algebraic_asv.size(),
596 num_alg_vars = algebraic_dvv.size();
597 bool grad_flag = false, hess_flag = false;
598 for (i=0; i<num_alg_fns; ++i) {
599 if (algebraic_asv[i] & 2)
600 grad_flag = true;
601 if (algebraic_asv[i] & 4)
602 hess_flag = true;
603 }
604
605 // dak_a_c_vars (DAKOTA space) -> nl_vars (reduced AMPL space)
606 const RealVector& dak_a_c_vars = vars.all_continuous_variables();
607 //IntVector dak_a_d_vars = vars.all_discrete_variables();
608 Real* nl_vars = new Real [num_alg_vars];
609 for (i=0; i<num_alg_vars; i++)
610 nl_vars[i] = dak_a_c_vars[algebraicACVIndices[i]];
611
612 // nl_vars -> algebraic_response
613 algebraic_response.reset_inactive(); // zero inactive data
614 Real fn_val; RealVector fn_grad; RealSymMatrix fn_hess;
615 fint err = 0;
616 for (i=0; i<num_alg_fns; i++) {
617 // nl_vars -> response fns via AMPL
618 if (algebraic_asv[i] & 1) {
619 if (algebraicFnTypes[i] > 0)
620 fn_val = objval(algebraicFnTypes[i]-1, nl_vars, &err);
621 else
622 fn_val = conival(-1-algebraicFnTypes[i], nl_vars, &err);
623 if (err) {
624 Cerr << "\nError: AMPL processing failure in objval().\n" << std::endl;
625 abort_handler(INTERFACE_ERROR);
626 }
627 algebraic_response.function_value(fn_val, i);
628 }
629 // nl_vars -> response grads via AMPL
630 if (algebraic_asv[i] & 6) { // need grad for Hessian
631 fn_grad = algebraic_response.function_gradient_view(i);
632 if (algebraicFnTypes[i] > 0)
633 objgrd(algebraicFnTypes[i]-1, nl_vars, fn_grad.values(), &err);
634 else
635 congrd(-1-algebraicFnTypes[i], nl_vars, fn_grad.values(), &err);
636 if (err) {
637 Cerr << "\nError: AMPL processing failure in objgrad().\n" << std::endl;
638 abort_handler(INTERFACE_ERROR);
639 }
640 }
641 // nl_vars -> response Hessians via AMPL
642 if (algebraic_asv[i] & 4) {
643 fn_hess = algebraic_response.function_hessian_view(i);
644 // the fullhess calls must follow corresp call to objgrad/congrad
645 if (algebraicFnTypes[i] > 0)
646 fullhes(fn_hess.values(), num_alg_vars, algebraicFnTypes[i]-1,
647 NULL, NULL);
648 else {
649 algebraicConstraintWeights.assign(algebraicConstraintWeights.size(), 0);
650 algebraicConstraintWeights[-1-algebraicFnTypes[i]] = 1;
651 fullhes(fn_hess.values(), num_alg_vars, num_alg_vars, NULL,
652 &algebraicConstraintWeights[0]);
653 }
654 }
655 }
656 delete [] nl_vars;
657 algebraic_response.function_labels(algebraicFnTags);
658 #ifdef DEBUG
659 Cout << ">>>>> algebraic_response.fn_labels\n"
660 << algebraic_response.function_labels() << std::endl;
661 #endif // DEBUG
662
663 if (outputLevel > NORMAL_OUTPUT)
664 Cout << "Algebraic mapping applied.\n";
665 #endif // HAVE_AMPL
666 }
667
668
669 /** This function will get invoked even when only algebraic mappings are
670 active (no core mappings from derived_map), since the AMPL
671 algebraic_response may be ordered differently from the total_response.
672 In this case, the core_response object is unused. */
673 void Interface::
response_mapping(const Response & algebraic_response,const Response & core_response,Response & total_response)674 response_mapping(const Response& algebraic_response,
675 const Response& core_response, Response& total_response)
676 {
677 const ShortArray& total_asv = total_response.active_set_request_vector();
678 const SizetArray& total_dvv = total_response.active_set_derivative_vector();
679 size_t i, j, k, num_total_fns = total_asv.size(),
680 num_total_vars = total_dvv.size();
681 bool grad_flag = false, hess_flag = false;
682 for (i=0; i<num_total_fns; ++i) {
683 if (total_asv[i] & 2)
684 grad_flag = true;
685 if (total_asv[i] & 4)
686 hess_flag = true;
687 }
688
689 // core_response contributions to total_response:
690
691 if (coreMappings) {
692 total_response.reset_inactive();
693 const ShortArray& core_asv = core_response.active_set_request_vector();
694 size_t num_core_fns = core_asv.size();
695 for (i=0; i<num_core_fns; ++i) {
696 if (core_asv[i] & 1)
697 total_response.function_value(core_response.function_value(i), i);
698 if (core_asv[i] & 2)
699 total_response.function_gradient(
700 core_response.function_gradient_view(i), i);
701 if (core_asv[i] & 4)
702 total_response.function_hessian(core_response.function_hessian(i), i);
703 }
704 }
705 else {
706 // zero all response data before adding algebraic data to it
707 total_response.reset();
708 }
709
710 // algebraic_response contributions to total_response:
711
712 const ShortArray& algebraic_asv
713 = algebraic_response.active_set_request_vector();
714 size_t num_alg_fns = algebraic_asv.size(),
715 num_alg_vars = algebraic_response.active_set_derivative_vector().size();
716 if (num_alg_fns > num_total_fns) {
717 Cerr << "Error: response size mismatch in Interface::response_mapping()."
718 << std::endl;
719 abort_handler(-1);
720 }
721 if ( (grad_flag || hess_flag) && num_alg_vars > num_total_vars) {
722 Cerr << "Error: derivative variables size mismatch in Interface::"
723 << "response_mapping()." << std::endl;
724 abort_handler(-1);
725 }
726 SizetArray algebraic_dvv_indices;
727 if (grad_flag || hess_flag) {
728 algebraic_dvv_indices.resize(num_alg_vars);
729 using Pecos::find_index;
730 for (i=0; i<num_alg_vars; ++i)
731 algebraic_dvv_indices[i] = find_index(total_dvv, algebraicACVIds[i]);
732 // Note: _NPOS return is handled below
733 }
734 // augment total_response
735 const RealVector& algebraic_fn_vals = algebraic_response.function_values();
736 const RealMatrix& algebraic_fn_grads
737 = algebraic_response.function_gradients();
738 const RealSymMatrixArray& algebraic_fn_hessians
739 = algebraic_response.function_hessians();
740 RealVector total_fn_vals = total_response.function_values_view();
741 for (i=0; i<num_alg_fns; ++i) {
742 size_t fn_index = algebraicFnIndices[i];
743 if (algebraic_asv[i] & 1)
744 total_fn_vals[fn_index] += algebraic_fn_vals[i];
745 if (algebraic_asv[i] & 2) {
746 const Real* algebraic_fn_grad = algebraic_fn_grads[i];
747 RealVector total_fn_grad
748 = total_response.function_gradient_view(fn_index);
749 for (j=0; j<num_alg_vars; j++) {
750 size_t dvv_index = algebraic_dvv_indices[j];
751 if (dvv_index != _NPOS)
752 total_fn_grad[dvv_index] += algebraic_fn_grad[j];
753 }
754 }
755 if (algebraic_asv[i] & 4) {
756 const RealSymMatrix& algebraic_fn_hess = algebraic_fn_hessians[i];
757 RealSymMatrix total_fn_hess
758 = total_response.function_hessian_view(fn_index);
759 for (j=0; j<num_alg_vars; ++j) {
760 size_t dvv_index_j = algebraic_dvv_indices[j];
761 if (dvv_index_j != _NPOS) {
762 for (k=0; k<=j; ++k) {
763 size_t dvv_index_k = algebraic_dvv_indices[k];
764 if (dvv_index_k != _NPOS)
765 total_fn_hess(dvv_index_j,dvv_index_k) += algebraic_fn_hess(j,k);
766 }
767 }
768 }
769 }
770 }
771
772 // output response sets:
773
774 if (outputLevel == DEBUG_OUTPUT) {
775 if (coreMappings) Cout << "core_response:\n" << core_response;
776 Cout << "algebraic_response:\n" << algebraic_response
777 << "total_response:\n" << total_response << '\n';
778 }
779 }
780
781
final_eval_id_tag(int iface_eval_id)782 String Interface::final_eval_id_tag(int iface_eval_id)
783 {
784 if (interfaceRep)
785 return interfaceRep->final_eval_id_tag(iface_eval_id);
786
787 if (appendIfaceId)
788 return evalTagPrefix + "." + std::to_string(iface_eval_id);
789 return evalTagPrefix;
790 }
791
792
algebraic_function_type(String functionTag)793 int Interface::algebraic_function_type(String functionTag)
794 {
795 #ifdef HAVE_AMPL
796 int i;
797 for (i=0; i<n_obj; i++)
798 if (strcontains(functionTag, obj_name(i)))
799 return i+1;
800 for (i=0; i<n_con; i++)
801 if (strcontains(functionTag, con_name(i)))
802 return -(i+1);
803
804 Cerr << "Error: No function type available for \'" << functionTag << "\' "
805 << "via algebraic_mappings interface." << std::endl;
806 abort_handler(INTERFACE_ERROR);
807 #else
808 return 0;
809 #endif // HAVE_AMPL
810 }
811
synchronize()812 const IntResponseMap& Interface::synchronize()
813 {
814 if (!interfaceRep) { // letter lacking redefinition of virtual fn.
815 Cerr << "Error: Letter lacking redefinition of virtual synchronize() "
816 << "function.\nNo default defined at Interface base class."
817 << std::endl;
818 abort_handler(-1);
819 }
820
821 return interfaceRep->synchronize();
822 }
823
824
synchronize_nowait()825 const IntResponseMap& Interface::synchronize_nowait()
826 {
827 if (!interfaceRep) { // letter lacking redefinition of virtual fn.
828 Cerr << "Error: Letter lacking redefinition of virtual synchronize_nowait"
829 << "() function.\nNo default defined at Interface base class."
830 << std::endl;
831 abort_handler(-1);
832 }
833
834 return interfaceRep->synchronize_nowait();
835 }
836
837
cache_unmatched_response(int raw_id)838 void Interface::cache_unmatched_response(int raw_id)
839 {
840 if (interfaceRep) // envelope fwd to letter
841 interfaceRep->cache_unmatched_response(raw_id);
842 else { // base definition; not virtual
843 IntRespMIter rr_it = rawResponseMap.find(raw_id);
844 if (rr_it != rawResponseMap.end()) {
845 cachedResponseMap.insert(*rr_it);
846 rawResponseMap.erase(rr_it);
847 }
848 }
849 }
850
851
serve_evaluations()852 void Interface::serve_evaluations()
853 {
854 if (interfaceRep) // envelope fwd to letter
855 interfaceRep->serve_evaluations();
856 else { // letter lacking redefinition of virtual fn.
857 Cerr << "Error: Letter lacking redefinition of virtual serve_evaluations "
858 << "function.\nNo default serve_evaluations defined at Interface"
859 << " base class." << std::endl;
860 abort_handler(-1);
861 }
862 }
863
864
stop_evaluation_servers()865 void Interface::stop_evaluation_servers()
866 {
867 if (interfaceRep) // envelope fwd to letter
868 interfaceRep->stop_evaluation_servers();
869 else { // letter lacking redefinition of virtual fn.
870 Cerr << "Error: Letter lacking redefinition of virtual stop_evaluation_"
871 << "servers fn.\nNo default stop_evaluation_servers defined at "
872 << "Interface base class." << std::endl;
873 abort_handler(-1);
874 }
875 }
876
877
init_communicators(const IntArray & message_lengths,int max_eval_concurrency)878 void Interface::init_communicators(const IntArray& message_lengths,
879 int max_eval_concurrency)
880 {
881 if (interfaceRep) // envelope fwd to letter
882 interfaceRep->init_communicators(message_lengths, max_eval_concurrency);
883 else { // letter lacking redefinition of virtual fn.
884 // ApproximationInterfaces: do nothing
885 }
886 }
887
888
set_communicators(const IntArray & message_lengths,int max_eval_concurrency)889 void Interface::set_communicators(const IntArray& message_lengths,
890 int max_eval_concurrency)
891 {
892 if (interfaceRep) // envelope fwd to letter
893 interfaceRep->set_communicators(message_lengths, max_eval_concurrency);
894 else { // letter lacking redefinition of virtual fn.
895 // ApproximationInterfaces: do nothing
896 }
897 }
898
899
900 /*
901 void Interface::free_communicators()
902 {
903 if (interfaceRep) // envelope fwd to letter
904 interfaceRep->free_communicators();
905 else { // letter lacking redefinition of virtual fn.
906 // default is no-op
907 }
908 }
909 */
910
911
init_serial()912 void Interface::init_serial()
913 {
914 if (interfaceRep) // envelope fwd to letter
915 interfaceRep->init_serial();
916 else { // letter lacking redefinition of virtual fn.
917 // ApproximationInterfaces: do nothing
918 }
919 }
920
921
asynch_local_evaluation_concurrency() const922 int Interface::asynch_local_evaluation_concurrency() const
923 {
924 if (interfaceRep) // envelope fwd to letter
925 return interfaceRep->asynch_local_evaluation_concurrency();
926 else // letter lacking redefinition of virtual fn.
927 return 0; // default (redefined only for ApplicationInterfaces)
928 }
929
930
interface_synchronization() const931 short Interface::interface_synchronization() const
932 {
933 if (interfaceRep) // envelope fwd to letter
934 return interfaceRep->interface_synchronization(); // ApplicationInterfaces
935 else // letter lacking redefinition of virtual fn.
936 return SYNCHRONOUS_INTERFACE; // default (ApproximationInterfaces)
937 }
938
939
minimum_points(bool constraint_flag) const940 int Interface::minimum_points(bool constraint_flag) const
941 {
942 if (interfaceRep) // envelope fwd to letter
943 return interfaceRep->minimum_points(constraint_flag);
944 else // letter lacking redefinition of virtual fn.
945 return 0; // default (currently redefined only for ApproximationInterfaces)
946 }
947
948
recommended_points(bool constraint_flag) const949 int Interface::recommended_points(bool constraint_flag) const
950 {
951 if (interfaceRep) // envelope fwd to letter
952 return interfaceRep->recommended_points(constraint_flag);
953 else // letter lacking redefinition of virtual fn.
954 return 0; // default (currently redefined only for ApproximationInterfaces)
955 }
956
957
active_model_key(const UShortArray & mi_key)958 void Interface::active_model_key(const UShortArray& mi_key)
959 {
960 if (interfaceRep) // envelope fwd to letter
961 interfaceRep->active_model_key(mi_key);
962 // else: default implementation is no-op
963 }
964
965
clear_model_keys()966 void Interface::clear_model_keys()
967 {
968 if (interfaceRep) // envelope fwd to letter
969 interfaceRep->clear_model_keys();
970 // else: default implementation is no-op
971 }
972
973
approximation_function_indices(const IntSet & approx_fn_indices)974 void Interface::approximation_function_indices(const IntSet& approx_fn_indices)
975 {
976 if (interfaceRep) // envelope fwd to letter
977 interfaceRep->approximation_function_indices(approx_fn_indices);
978 // else: default implementation is no-op
979 }
980
981
982 /*
983 void Interface::link_multilevel_approximation_data()
984 {
985 if (interfaceRep) // envelope fwd to letter
986 interfaceRep->link_multilevel_approximation_data();
987 else { // letter lacking redefinition of virtual fn.
988 Cerr << "Error: Letter lacking redefinition of virtual link_multilevel_"
989 << "approximation_data() function.\n This interface does not "
990 << "support multilevel data." << std::endl;
991 abort_handler(-1);
992 }
993 }
994 */
995
996
997 void Interface::
update_approximation(const Variables & vars,const IntResponsePair & response_pr)998 update_approximation(const Variables& vars, const IntResponsePair& response_pr)
999 {
1000 if (interfaceRep) // envelope fwd to letter
1001 interfaceRep->update_approximation(vars, response_pr);
1002 else { // letter lacking redefinition of virtual fn.
1003 Cerr << "Error: Letter lacking redefinition of virtual update_approximation"
1004 << "(Variables, IntResponsePair) function.\n This interface "
1005 << "does not support approximation updating." << std::endl;
1006 abort_handler(-1);
1007 }
1008 }
1009
1010
1011 void Interface::
update_approximation(const RealMatrix & samples,const IntResponseMap & resp_map)1012 update_approximation(const RealMatrix& samples, const IntResponseMap& resp_map)
1013 {
1014 if (interfaceRep) // envelope fwd to letter
1015 interfaceRep->update_approximation(samples, resp_map);
1016 else { // letter lacking redefinition of virtual fn.
1017 Cerr << "Error: Letter lacking redefinition of virtual update_approximation"
1018 << "(RealMatrix, IntResponseMap) function.\n This interface "
1019 << "does not support approximation updating." << std::endl;
1020 abort_handler(-1);
1021 }
1022 }
1023
1024
1025 void Interface::
update_approximation(const VariablesArray & vars_array,const IntResponseMap & resp_map)1026 update_approximation(const VariablesArray& vars_array,
1027 const IntResponseMap& resp_map)
1028 {
1029 if (interfaceRep) // envelope fwd to letter
1030 interfaceRep->update_approximation(vars_array, resp_map);
1031 else { // letter lacking redefinition of virtual fn.
1032 Cerr << "Error: Letter lacking redefinition of virtual update_approximation"
1033 << "(VariablesArray, IntResponseMap) function.\n This interface "
1034 << "does not support approximation updating." << std::endl;
1035 abort_handler(-1);
1036 }
1037 }
1038
1039
1040 void Interface::
append_approximation(const Variables & vars,const IntResponsePair & response_pr)1041 append_approximation(const Variables& vars, const IntResponsePair& response_pr)
1042 {
1043 if (interfaceRep) // envelope fwd to letter
1044 interfaceRep->append_approximation(vars, response_pr);
1045 else { // letter lacking redefinition of virtual fn.
1046 Cerr << "Error: Letter lacking redefinition of virtual append_approximation"
1047 << "(Variables, IntResponsePair) function.\n This interface "
1048 << "does not support approximation appending." << std::endl;
1049 abort_handler(-1);
1050 }
1051 }
1052
1053
1054 void Interface::
append_approximation(const RealMatrix & samples,const IntResponseMap & resp_map)1055 append_approximation(const RealMatrix& samples, const IntResponseMap& resp_map)
1056 {
1057 if (interfaceRep) // envelope fwd to letter
1058 interfaceRep->append_approximation(samples, resp_map);
1059 else { // letter lacking redefinition of virtual fn.
1060 Cerr << "Error: Letter lacking redefinition of virtual append_approximation"
1061 << "(RealMatrix, IntResponseMap) function.\n This interface "
1062 << "does not support approximation appending." << std::endl;
1063 abort_handler(-1);
1064 }
1065 }
1066
1067
1068 void Interface::
append_approximation(const VariablesArray & vars_array,const IntResponseMap & resp_map)1069 append_approximation(const VariablesArray& vars_array,
1070 const IntResponseMap& resp_map)
1071 {
1072 if (interfaceRep) // envelope fwd to letter
1073 interfaceRep->append_approximation(vars_array, resp_map);
1074 else { // letter lacking redefinition of virtual fn.
1075 Cerr << "Error: Letter lacking redefinition of virtual append_approximation"
1076 << "(VariablesArray, IntResponseMap) function.\n This interface "
1077 << "does not support approximation appending." << std::endl;
1078 abort_handler(-1);
1079 }
1080 }
1081
1082
1083 void Interface::
build_approximation(const RealVector & c_l_bnds,const RealVector & c_u_bnds,const IntVector & di_l_bnds,const IntVector & di_u_bnds,const RealVector & dr_l_bnds,const RealVector & dr_u_bnds)1084 build_approximation(const RealVector& c_l_bnds, const RealVector& c_u_bnds,
1085 const IntVector& di_l_bnds, const IntVector& di_u_bnds,
1086 const RealVector& dr_l_bnds, const RealVector& dr_u_bnds)
1087 {
1088 if (interfaceRep) // envelope fwd to letter
1089 interfaceRep->build_approximation(c_l_bnds, c_u_bnds, di_l_bnds, di_u_bnds,
1090 dr_l_bnds, dr_u_bnds);
1091 else { // letter lacking redefinition of virtual fn.
1092 Cerr << "Error: Letter lacking redefinition of virtual build_approximation"
1093 << "() function.\n This interface does not support "
1094 << "approximations." << std::endl;
1095 abort_handler(-1);
1096 }
1097 }
1098
1099
export_approximation()1100 void Interface::export_approximation()
1101 {
1102 if (interfaceRep) // envelope fwd to letter
1103 interfaceRep->export_approximation();
1104 else { // letter lacking redefinition of virtual fn.
1105 Cerr << "Error: Letter lacking redefinition of virtual export_approximation"
1106 << "() function.\n This interface does not support exporting "
1107 << "approximations." << std::endl;
1108 abort_handler(-1);
1109 }
1110 }
1111
1112
rebuild_approximation(const BitArray & rebuild_fns)1113 void Interface::rebuild_approximation(const BitArray& rebuild_fns)
1114 {
1115 if (interfaceRep) // envelope fwd to letter
1116 interfaceRep->rebuild_approximation(rebuild_fns);
1117 else { // letter lacking redefinition of virtual fn.
1118 Cerr << "Error: Letter lacking redefinition of virtual rebuild_"
1119 << "approximation() function.\n This interface does not "
1120 << "support approximations." << std::endl;
1121 abort_handler(-1);
1122 }
1123 }
1124
1125
pop_approximation(bool save_data)1126 void Interface::pop_approximation(bool save_data)
1127 {
1128 if (interfaceRep) // envelope fwd to letter
1129 interfaceRep->pop_approximation(save_data);
1130 else { // letter lacking redefinition of virtual fn.
1131 Cerr << "Error: Letter lacking redefinition of virtual pop_approximation"
1132 << "(bool)\n function. This interface does not support "
1133 << "approximation\n data removal." << std::endl;
1134 abort_handler(-1);
1135 }
1136 }
1137
1138
push_approximation()1139 void Interface::push_approximation()
1140 {
1141 if (interfaceRep) // envelope fwd to letter
1142 interfaceRep->push_approximation();
1143 else { // letter lacking redefinition of virtual fn.
1144 Cerr << "Error: Letter lacking redefinition of virtual push_"
1145 << "approximation() function.\n This interface does not "
1146 << "support approximation data retrieval." << std::endl;
1147 abort_handler(-1);
1148 }
1149 }
1150
1151
push_available()1152 bool Interface::push_available()
1153 {
1154 if (!interfaceRep) { // letter lacking redefinition of virtual fn.
1155 Cerr << "Error: Letter lacking redefinition of virtual push_"
1156 << "available() function.\n This interface does not "
1157 << "support approximation data retrieval." << std::endl;
1158 abort_handler(-1);
1159 }
1160
1161 return interfaceRep->push_available();
1162 }
1163
1164
finalize_approximation()1165 void Interface::finalize_approximation()
1166 {
1167 if (interfaceRep) // envelope fwd to letter
1168 interfaceRep->finalize_approximation();
1169 else { // letter lacking redefinition of virtual fn.
1170 Cerr << "Error: Letter lacking redefinition of virtual finalize_"
1171 << "approximation() function.\n This interface does not "
1172 << "support approximation finalization." << std::endl;
1173 abort_handler(-1);
1174 }
1175 }
1176
1177
clear_inactive()1178 void Interface::clear_inactive()
1179 {
1180 if (interfaceRep) // envelope fwd to letter
1181 interfaceRep->clear_inactive();
1182 //else // letter lacking redefinition of virtual fn.
1183 // default: no inactive data to clear
1184 }
1185
1186
combine_approximation()1187 void Interface::combine_approximation()
1188 {
1189 if (interfaceRep) // envelope fwd to letter
1190 interfaceRep->combine_approximation();
1191 else { // letter lacking redefinition of virtual fn.
1192 Cerr << "Error: Letter lacking redefinition of virtual combine_"
1193 << "approximation() function.\n This interface does not "
1194 << "support approximation combination." << std::endl;
1195 abort_handler(-1);
1196 }
1197 }
1198
1199
combined_to_active(bool clear_combined)1200 void Interface::combined_to_active(bool clear_combined)
1201 {
1202 if (interfaceRep) // envelope fwd to letter
1203 interfaceRep->combined_to_active(clear_combined);
1204 else { // letter lacking redefinition of virtual fn.
1205 Cerr << "Error: Letter lacking redefinition of virtual combined_to_active()"
1206 << " function.\n This interface does not support approximation"
1207 << " combination." << std::endl;
1208 abort_handler(-1);
1209 }
1210 }
1211
1212
advancement_available()1213 bool Interface::advancement_available()
1214 {
1215 if (interfaceRep) return interfaceRep->advancement_available();
1216 else return true; // only a few cases throttle advancements
1217 }
1218
1219
formulation_updated() const1220 bool Interface::formulation_updated() const
1221 {
1222 if (!interfaceRep) { // letter lacking redefinition of virtual fn.
1223 Cerr << "Error: Letter lacking redefinition of virtual formulation_updated"
1224 << "() function.\n This interface does not define approximation "
1225 << "formulations." << std::endl;
1226 abort_handler(-1);
1227 }
1228
1229 return interfaceRep->formulation_updated();
1230 }
1231
1232
formulation_updated(bool update)1233 void Interface::formulation_updated(bool update)
1234 {
1235 if (interfaceRep)
1236 interfaceRep->formulation_updated(update);
1237 else { // letter lacking redefinition of virtual fn.
1238 Cerr << "Error: Letter lacking redefinition of virtual formulation_updated"
1239 << "() function.\n This interface does not define approximation "
1240 << "formulations." << std::endl;
1241 abort_handler(-1);
1242 }
1243 }
1244
1245
1246 Real2DArray Interface::
cv_diagnostics(const StringArray & metric_types,unsigned num_folds)1247 cv_diagnostics(const StringArray& metric_types, unsigned num_folds)
1248 {
1249 if (!interfaceRep) { // letter lacking redefinition of virtual fn.
1250 Cerr << "Error: Letter lacking redefinition of virtual cv_diagnostics()"
1251 << "function.\n This interface does not "
1252 << "support cross-validation diagnostics." << std::endl;
1253 abort_handler(-1);
1254 }
1255
1256 return interfaceRep->cv_diagnostics(metric_types, num_folds);
1257 }
1258
1259
challenge_diagnostics(const String & metric_type,const RealMatrix & challenge_pts)1260 RealArray Interface::challenge_diagnostics(const String& metric_type,
1261 const RealMatrix& challenge_pts)
1262 {
1263 if (!interfaceRep) { // letter lacking redefinition of virtual fn.
1264 Cerr << "Error: Letter lacking redefinition of virtual challenge_"
1265 << "diagnostics() function.\n This interface does not "
1266 << "support challenge data diagnostics." << std::endl;
1267 abort_handler(-1);
1268 }
1269
1270 return interfaceRep->challenge_diagnostics(metric_type, challenge_pts);
1271 }
1272
1273
clear_current_active_data()1274 void Interface::clear_current_active_data()
1275 {
1276 if (interfaceRep) // envelope fwd to letter
1277 interfaceRep->clear_current_active_data();
1278 //else // letter lacking redefinition of virtual fn.
1279 // ApplicationInterfaces: do nothing
1280 }
1281
1282
clear_active_data()1283 void Interface::clear_active_data()
1284 {
1285 if (interfaceRep) // envelope fwd to letter
1286 interfaceRep->clear_active_data();
1287 //else // letter lacking redefinition of virtual fn.
1288 // ApplicationInterfaces: do nothing
1289 }
1290
1291
shared_approximation()1292 SharedApproxData& Interface::shared_approximation()
1293 {
1294 if (!interfaceRep) { // letter lacking redefinition of virtual fn.
1295 Cerr << "Error: Letter lacking redefinition of virtual shared_approximation"
1296 << "() function.\nThis interface does not support approximations."
1297 << std::endl;
1298 abort_handler(-1);
1299 }
1300
1301 // envelope fwd to letter
1302 return interfaceRep->shared_approximation();
1303 }
1304
1305
approximations()1306 std::vector<Approximation>& Interface::approximations()
1307 {
1308 if (!interfaceRep) { // letter lacking redefinition of virtual fn.
1309 Cerr << "Error: Letter lacking redefinition of virtual approximations() "
1310 << "function.\n This interface does not support approximations."
1311 << std::endl;
1312 abort_handler(-1);
1313 }
1314
1315 // envelope fwd to letter
1316 return interfaceRep->approximations();
1317 }
1318
1319
approximation_data(size_t fn_index)1320 const Pecos::SurrogateData& Interface::approximation_data(size_t fn_index)
1321 {
1322 if (!interfaceRep) { // letter lacking redefinition of virtual fn.
1323 Cerr << "Error: Letter lacking redefinition of virtual approximation_data "
1324 << "function.\n This interface does not support approximations."
1325 << std::endl;
1326 abort_handler(-1);
1327 }
1328
1329 // envelope fwd to letter
1330 return interfaceRep->approximation_data(fn_index);
1331 }
1332
1333
approximation_coefficients(bool normalized)1334 const RealVectorArray& Interface::approximation_coefficients(bool normalized)
1335 {
1336 if (!interfaceRep) { // letter lacking redefinition of virtual fn.
1337 Cerr << "Error: Letter lacking redefinition of virtual approximation_"
1338 << "coefficients function.\n This interface does not support "
1339 << "approximations." << std::endl;
1340 abort_handler(-1);
1341 }
1342
1343 // envelope fwd to letter
1344 return interfaceRep->approximation_coefficients(normalized);
1345 }
1346
1347
1348 void Interface::
approximation_coefficients(const RealVectorArray & approx_coeffs,bool normalized)1349 approximation_coefficients(const RealVectorArray& approx_coeffs,
1350 bool normalized)
1351 {
1352 if (interfaceRep) // envelope fwd to letter
1353 interfaceRep->approximation_coefficients(approx_coeffs, normalized);
1354 else { // letter lacking redefinition of virtual fn.
1355 Cerr << "Error: Letter lacking redefinition of virtual approximation_"
1356 << "coefficients function.\n This interface does not support "
1357 << "approximations." << std::endl;
1358 abort_handler(-1);
1359 }
1360 }
1361
1362
approximation_variances(const Variables & vars)1363 const RealVector& Interface::approximation_variances(const Variables& vars)
1364 {
1365 if (!interfaceRep) { // letter lacking redefinition of virtual fn.
1366 Cerr << "Error: Letter lacking redefinition of virtual approximation_"
1367 << "variances function.\n This interface does not support "
1368 << "approximations." << std::endl;
1369 abort_handler(-1);
1370 }
1371
1372 // envelope fwd to letter
1373 return interfaceRep->approximation_variances(vars);
1374 }
1375
1376
analysis_drivers() const1377 const StringArray& Interface::analysis_drivers() const
1378 {
1379 if (!interfaceRep) { // letter lacking redefinition of virtual fn.
1380 Cerr << "Error: Letter lacking redefinition of virtual analysis_drivers "
1381 << "function." << std::endl;
1382 abort_handler(-1);
1383 }
1384
1385 // envelope fwd to letter
1386 return interfaceRep->analysis_drivers();
1387 }
1388
analysis_components() const1389 const String2DArray & Interface::analysis_components() const
1390 {
1391 if(interfaceRep)
1392 return interfaceRep->analysis_components();
1393 return analysisComponents;
1394 }
1395
evaluation_cache() const1396 bool Interface::evaluation_cache() const
1397 {
1398 if (interfaceRep)
1399 return interfaceRep->evaluation_cache();
1400 else // letter lacking redefinition of virtual fn.
1401 return false; // default
1402 }
1403
1404
restart_file() const1405 bool Interface::restart_file() const
1406 {
1407 if (interfaceRep)
1408 return interfaceRep->restart_file();
1409 else // letter lacking redefinition of virtual fn.
1410 return false; // default
1411 }
1412
1413
file_cleanup() const1414 void Interface::file_cleanup() const
1415 {
1416 if (interfaceRep)
1417 interfaceRep->file_cleanup();
1418 // else no-op
1419 }
1420
1421 /** Rationale: The parser allows multiple user-specified interfaces with
1422 empty (unspecified) ID. However, only a single Interface with empty
1423 ID can be constructed (if it's the only one present, or the "last
1424 one parsed"). Therefore decided to prefer NO_ID over NO_ID_<num>
1425 for consistency with interface NO_ID convention. Additionally, NO_ID
1426 is preferred over NO_INTERFACE_ID (contrast with Iterator and Model)
1427 to preserve backward compatibility
1428 */
user_auto_id()1429 String Interface::user_auto_id()
1430 {
1431 // // increment and then use the current ID value
1432 // return String("NO_ID_") + std::to_string(++userAutoIdNum);
1433 return String("NO_ID");
1434 }
1435
1436 /** Rationale: For now NOSPEC_ID_ is chosen due to historical
1437 id="NO_SPECIFICATION" used for internally-constructed
1438 Iterators. Longer-term, consider auto-generating an ID that
1439 includes the context from which the method is constructed, e.g.,
1440 the parent method or model's ID, together with its name. */
no_spec_id()1441 String Interface::no_spec_id()
1442 {
1443 // increment and then use the current ID value
1444 return String("NOSPEC_INTERFACE_ID_") + std::to_string(++noSpecIdNum);
1445 }
1446 } // namespace Dakota
1447