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 #include <cstdlib>
10 #include <iostream>
11 #include <fstream>
12 #include <string>
13 #include <vector>
14 #include <map>
15 #include <algorithm>
16 #include <cctype>
17 #include <boost/algorithm/string.hpp>
18 
19 enum var_t { FT1,  FT2 };
20 
21 #define HIERARCH_TAG
22 
23 
main(int argc,char ** argv)24 int main(int argc, char** argv)
25 {
26   // This application program reads and writes parameter and response data
27   // directly so no input/output filters are needed.
28   std::ifstream fin(argv[1]);
29   if (!fin) {
30     std::cerr << "\nError: failure opening " << argv[1] << std::endl;
31     exit(-1);
32   }
33   size_t i, j, num_vars, num_fns, num_deriv_vars, num_ac;
34   std::string text, hier_tag;
35 
36   // define the std::string to enumeration map
37   std::map<std::string, var_t> var_t_map;
38   var_t_map["failthresh1"] = FT1; var_t_map["failthresh2"] = FT2;
39 
40   // Get the parameter std::vector and ignore the labels
41   fin >> num_vars >> text;
42   if (num_vars != 2 && num_vars != 10) {
43     std::cerr << "Error: wrong number of variables for trajectory_post().\n";
44     exit(-1);
45   }
46   std::map<var_t, double> vars;
47   //std::vector<var_t> labels(num_vars);
48   double value_i; std::string label_i; //var_t v_i;
49   std::map<std::string, var_t>::iterator v_iter;
50   for (i=0; i<num_vars; i++) {
51     fin >> value_i >> label_i;
52     transform(label_i.begin(), label_i.end(), label_i.begin(),
53 	      (int(*)(int))tolower);
54     v_iter = var_t_map.find(label_i);
55     // if (v_iter == var_t_map.end()) {
56     //   std::cerr << "Error: label \"" << label_i << "\" not supported in analysis "
57     // 	   << "driver." << std::endl;
58     //   exit(-1);
59     // }
60     // else
61     //   v_i = v_iter->second;
62     // vars[v_i] = value_i;
63     // labels[i] = v_i;
64 
65     // ignore any epistemic variables; only need the failure thresholds
66     if (v_iter != var_t_map.end())
67       vars[v_iter->second] = value_i;
68   }
69 
70   // Get the ASV std::vector and ignore the labels
71   fin >> num_fns >> text;
72   if (num_fns != 1) {
73     std::cerr << "Error: wrong number of functions in trajectory_post.\n";
74     exit(-1);
75   }
76   std::vector<short> ASV(num_fns);
77   for (i=0; i<num_fns; i++) {
78     fin >> ASV[i];
79     fin.ignore(256, '\n');
80   }
81 
82   // Get the DVV std::vector and ignore the labels
83   fin >> num_deriv_vars >> text;
84   //std::vector<var_t> DVV(num_deriv_vars);
85   unsigned int dvv_i;
86   for (i=0; i<num_deriv_vars; i++) {
87     fin >> dvv_i;
88     fin.ignore(256, '\n');
89     //DVV[i] = labels[dvv_i-1];
90   }
91 
92   // Extract the AC std::vector and ignore the labels
93   fin >> num_ac >> text;
94   std::vector<std::string> AC(num_ac);
95   for (i=0; i<num_ac; i++) {
96     fin >> AC[i];
97     fin.ignore(256, '\n');
98   }
99 
100 #ifdef HIERARCH_TAG
101   // Extract the hierarchical fn eval tags (required to link to opt interface)
102   fin >> hier_tag; fin.ignore(256, '\n');
103   std::vector<std::string> tags;
104   boost::split(tags, hier_tag, boost::is_any_of(".: "));
105   size_t num_tags = tags.size();
106   if (num_tags < 2) {
107     std::cerr << "Error: insufficient hierarchical tag depth." << std::endl;
108     exit(-1);
109   }
110   std::string e_tag   = tags[0];                 // if file_tag is on
111   //std::string e_tag = tags[0] + '.' + tags[0]; // if file_tag is off (hack)
112   for (i=1; i<num_tags-1; ++i)
113     e_tag += '.' + tags[i]; // up one level from last tag
114 
115   // Compute and output responses
116   std::string history = "../epistemic_simulation." + e_tag + "/time_history.dat";
117 #else
118   std::string history = "time_history.dat";
119 #endif
120 
121   std::ifstream hist_in(history.c_str());
122   if (!fin) {
123     std::cerr << "\nError: failure opening " << history << std::endl;
124     exit(-1);
125   }
126   std::ofstream fout(argv[2]);
127   if (!fout) {
128     std::cerr << "\nError: failure creating " << argv[2] << std::endl;
129     exit(-1);
130   }
131   fout.precision(15); // 16 total digits
132   fout.setf(std::ios::scientific);
133   fout.setf(std::ios::right);
134 
135   size_t num_delta;
136   hist_in >> num_delta;
137   double delta_t, t, t_prev, time_fail1, time_fail2, f1, f2, f1_prev, f2_prev,
138     fail_thresh1 = vars[FT1], fail_thresh2 = vars[FT2];
139   bool failed1 = false, failed2 = false, last_step;
140 
141   hist_in >> t_prev >> f1_prev >> f2_prev; // initial time step
142   //cout << "Init: " << t_prev << ' ' << f1_prev << ' ' << f2_prev << std::endl;
143 
144   for (i=1; i<num_delta; ++i) {
145     hist_in >> t >> f1 >> f2;
146     //cout << "Step: " << t << ' ' << f1 << ' ' << f2 << std::endl;
147 
148     last_step = (i == num_delta-1);
149     if (!failed1) {
150       // Check if f1 has reached failure threshold 1;
151       // if yes, then linearly interpolate for failure time.
152       // Or if last time step, linearly extrapolate for failure time.
153       if (f1 >= fail_thresh1 || last_step) {
154 	time_fail1 = t_prev +
155 	  (fail_thresh1 - f1_prev) / (f1 - f1_prev) * (t - t_prev);
156 	failed1 = true;
157 	//cout << "Fail 1: " <<  time_fail1 << std::endl;
158       }
159       else
160 	f1_prev = f1;
161     }
162 
163     if (!failed2) {
164       // Check if f2 has reached failure threshold 2;
165       // if yes, then linearly interpolate for failure time.
166       // Or if last time step, linearly extrapolate for failure time.
167       if (f2 >= fail_thresh2 || last_step) {
168 	time_fail2 = t_prev +
169 	  (fail_thresh2 - f2_prev) / (f2 - f2_prev) * (t - t_prev);
170 	failed2 = true;
171 	//cout << "Fail 2: " <<  time_fail2 << std::endl;
172       }
173       else
174 	f2_prev = f2;
175     }
176 
177     // break out if done
178     if (failed1 && failed2)
179       break;
180     t_prev = t;
181   }
182 
183   fout << time_fail2 - time_fail1 << " deltafailtime\n";
184   fout.flush();
185   fout.close();
186   return 0;
187 }
188