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 <cmath>
11 #include <iostream>
12 #include <fstream>
13 #include <string>
14 #include <vector>
15 #include <map>
16 #include <algorithm>
17 #include <cctype>
18
19 enum var_t { W, T, R, E, X, Y };
20
21
main(int argc,char ** argv)22 int main(int argc, char** argv)
23 {
24
25 // This test problem is an OUU example from Applied Research Associates
26 // (42nd AIAA SDM conference, April 2001).
27
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;
34 std::string vars_text, fns_text, dvv_text;
35
36 // define the std::string to enumeration map
37 std::map<std::string, var_t> var_t_map;
38 var_t_map["w"] = W; var_t_map["t"] = T;
39 var_t_map["r"] = R; var_t_map["e"] = E;
40 var_t_map["x"] = X; var_t_map["y"] = Y;
41
42 // Get the parameter std::vector and ignore the labels
43 fin >> num_vars >> vars_text;
44 std::map<var_t, double> vars;
45 std::vector<var_t> labels(num_vars);
46 double var_i; std::string label_i; var_t v_i;
47 std::map<std::string, var_t>::iterator v_iter;
48 for (i=0; i<num_vars; i++) {
49 fin >> var_i >> label_i;
50 transform(label_i.begin(), label_i.end(), label_i.begin(),
51 (int(*)(int))tolower);
52 v_iter = var_t_map.find(label_i);
53 if (v_iter == var_t_map.end()) {
54 std::cerr << "Error: label \"" << label_i << "\" not supported in analysis "
55 << "driver." << std::endl;
56 exit(-1);
57 }
58 else
59 v_i = v_iter->second;
60 vars[v_i] = var_i;
61 labels[i] = v_i;
62 }
63
64 // Get the ASV std::vector and ignore the labels
65 fin >> num_fns >> fns_text;
66 std::vector<short> ASV(num_fns);
67 for (i=0; i<num_fns; i++) {
68 fin >> ASV[i];
69 fin.ignore(256, '\n');
70 }
71
72 // Get the DVV std::vector and ignore the labels
73 fin >> num_deriv_vars >> dvv_text;
74 std::vector<var_t> DVV(num_deriv_vars);
75 unsigned int dvv_i;
76 for (i=0; i<num_deriv_vars; i++) {
77 fin >> dvv_i;
78 fin.ignore(256, '\n');
79 DVV[i] = labels[dvv_i-1];
80 }
81
82 if (num_vars != 4 && num_vars != 6) {
83 std::cerr << "Error: Wrong number of variables in mod_cantilever test fn."
84 << std::endl;
85 exit(-1);
86 }
87 if (num_fns < 2 || num_fns > 3) {
88 std::cerr << "Error: wrong number of response functions in mod_cantilever test "
89 << "fn." << std::endl;
90 exit(-1);
91 }
92
93 // Compute the cross-sectional area, stress, and displacement of the
94 // cantilever beam. This simulator is unusual in that it supports both
95 // the case of design variable insertion and the case of design variable
96 // augmentation. It does not support mixed insertion/augmentation. In
97 // the 6 variable case, w,t,R,E,X,Y are all passed in; in the 4 variable
98 // case, w,t assume local values.
99 std::map<var_t, double>::iterator m_iter = vars.find(W);
100 double w = (m_iter == vars.end()) ? 2.5 : m_iter->second; // beam width
101 m_iter = vars.find(T);
102 double t = (m_iter == vars.end()) ? 2.5 : m_iter->second; // beam thickness
103 double r = vars[R]; // yield strength
104 double e = vars[E]; // Young's modulus
105 double x = vars[X]; // horizontal load
106 double y = vars[Y]; // vertical load
107
108 // allow f,c1,c2 (optimization) or just c1,c2 (calibration)
109 bool objective; size_t c1i, c2i;
110 if (num_fns == 2) { objective = false; c1i = 0; c2i = 1; }
111 else { objective = true; c1i = 1; c2i = 2; }
112
113 // UQ limit state <= 0: don't scale stress by random variable r
114 //double g_stress = stress - r;
115 //double g_disp = displ - D0;
116
117 // Compute the results and output them directly to argv[2] (the NO_FILTER
118 // option is used). Response tags are optional; output them for ease of
119 // results readability.
120 double D0 = 2.2535, L = 100., area = w*t, w_sq = w*w, t_sq = t*t,
121 r_sq = r*r, x_sq = x*x, y_sq = y*y;
122 double stress = 600.*y/w/t_sq + 600.*x/w_sq/t;
123 double D1 = 4.*pow(L,3)/e/area, D2 = pow(y/t_sq, 2)+pow(x/w_sq, 2);
124 double D3 = D1/sqrt(D2), displ = D1*sqrt(D2);
125
126 std::ofstream fout(argv[2]); // do not instantiate until ready to write results
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 // **** f:
136 if (objective && (ASV[0] & 1))
137 fout << " " << area << '\n';
138
139 // **** c1:
140 if (ASV[c1i] & 1)
141 fout << " " << stress - r << '\n';
142
143 // **** c2:
144 if (ASV[c2i] & 1)
145 fout << " " << displ - D0 << '\n';
146
147 // **** df/dx:
148 if (objective && (ASV[0] & 2)) {
149 fout << "[ ";
150 for (i=0; i<num_deriv_vars; i++)
151 switch (DVV[i]) {
152 case W: fout << t << ' '; break; // design var derivative
153 case T: fout << w << ' '; break; // design var derivative
154 default: fout << "0. "; break; // uncertain var derivative
155 }
156 fout << "]\n";
157 }
158
159 // **** dc1/dx:
160 if (ASV[c1i] & 2) {
161 fout << "[ ";
162 for (i=0; i<num_deriv_vars; i++)
163 switch (DVV[i]) {
164 case W: fout << -600.*(y/t + 2.*x/w)/w_sq/t << ' '; break; // des var
165 case T: fout << -600.*(2.*y/t + x/w)/w/t_sq << ' '; break; // des var
166 case R: fout << "-1. "; break; // uncertain var deriv
167 case E: fout << "0. "; break; // uncertain var deriv
168 case X: fout << 600./w_sq/t << ' '; break; // uncertain var deriv
169 case Y: fout << 600./w/t_sq << ' '; break; // uncertain var deriv
170 }
171 fout << "]\n";
172 }
173
174 // **** dc2/dx:
175 if (ASV[c2i] & 2) {
176 fout << "[ ";
177 for (i=0; i<num_deriv_vars; i++)
178 switch (DVV[i]) {
179 case W: fout << -D3*2.*x_sq/w_sq/w_sq/w - displ/w << ' '; break; // dv
180 case T: fout << -D3*2.*y_sq/t_sq/t_sq/t - displ/t << ' '; break; // dv
181 case R: fout << "0. "; break; // unc var deriv
182 case E: fout << -displ/E << ' '; break; // unc var deriv
183 case X: fout << D3*x/w_sq/w_sq << ' '; break; // unc var deriv
184 case Y: fout << D3*y/t_sq/t_sq << ' '; break; // unc var deriv
185 }
186 fout << "]\n";
187 }
188
189 /* Alternative modification: take E out of displ denominator to remove
190 singularity in tail (at 20 std deviations). In PCE/SC testing, this
191 had minimal impact and did not justify the nonstandard form.
192
193 double D0 = 2.2535, L = 100., area = w*t, w_sq = w*w, t_sq = t*t,
194 r_sq = r*r, x_sq = x*x, y_sq = y*y;
195 double stress = 600.*y/w/t_sq + 600.*x/w_sq/t;
196 double D1 = 4.*pow(L,3)/area, D2 = pow(y/t_sq, 2)+pow(x/w_sq, 2);
197 double D3 = D1/sqrt(D2), D4 = D1*sqrt(D2);
198
199 // **** c2:
200 if (ASV[c2i] & 1)
201 fout << " " << D4 - D0*e << '\n';
202
203 // **** dc2/dx:
204 if (ASV[c2i] & 2) {
205 fout << "[ ";
206 for (i=0; i<num_deriv_vars; i++)
207 switch (DVV[i]) {
208 case W: fout << -D3*2.*x_sq/w_sq/w_sq/w - D4/w << ' '; break; // des var
209 case T: fout << -D3*2.*y_sq/t_sq/t_sq/t - D4/t << ' '; break; // des var
210 case R: fout << "0. "; break; // unc var deriv
211 case E: fout << -D0 << ' '; break; // unc var deriv
212 case X: fout << D3*x/w_sq/w_sq << ' '; break; // unc var deriv
213 case Y: fout << D3*y/t_sq/t_sq << ' '; break; // unc var deriv
214 }
215 fout << "]\n";
216 }
217 */
218
219 fout.flush();
220 fout.close();
221 return 0;
222 }
223