00001
00002
00003
00004
00005
00006
00007 #include "Albany_SolutionFileResponseFunction.hpp"
00008
00009
00010 #include "Epetra_Map.h"
00011 #include "EpetraExt_BlockMapIn.h"
00012 #include "Epetra_SerialComm.h"
00013
00014 template<class Norm>
00015 Albany::SolutionFileResponseFunction<Norm>::
00016 SolutionFileResponseFunction(const Teuchos::RCP<const Epetra_Comm>& comm)
00017 : SamplingBasedScalarResponseFunction(comm),
00018 RefSoln(NULL), solutionLoaded(false)
00019 {
00020 }
00021
00022 template<class Norm>
00023 Albany::SolutionFileResponseFunction<Norm>::
00024 ~SolutionFileResponseFunction()
00025 {
00026 if (solutionLoaded) delete RefSoln;
00027 }
00028
00029 template<class Norm>
00030 unsigned int
00031 Albany::SolutionFileResponseFunction<Norm>::
00032 numResponses() const
00033 {
00034 return 1;
00035 }
00036
00037 template<class Norm>
00038 void
00039 Albany::SolutionFileResponseFunction<Norm>::
00040 evaluateResponse(const double current_time,
00041 const Epetra_Vector* xdot,
00042 const Epetra_Vector* xdotdot,
00043 const Epetra_Vector& x,
00044 const Teuchos::Array<ParamVec>& p,
00045 Epetra_Vector& g)
00046 {
00047
00048 int MMFileStatus = 0;
00049
00050
00051
00052
00053
00054 if (!solutionLoaded) {
00055
00056 MMFileStatus = MatrixMarketFileToVector("reference_solution.dat",x.Map(),RefSoln);
00057
00058 TEUCHOS_TEST_FOR_EXCEPTION(MMFileStatus, std::runtime_error,
00059 std::endl << "EpetraExt::MatrixMarketFileToVector, file " __FILE__
00060 " line " << __LINE__ << " returned " << MMFileStatus << std::endl);
00061
00062 solutionLoaded = true;
00063 }
00064
00065
00066
00067 Epetra_Vector diff(x.Map());
00068
00069 double normval;
00070 Norm vec_op;
00071
00072
00073 diff.Update(1.0,x,-1.0,*RefSoln,0.0);
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086 normval = vec_op.Norm(diff);
00087
00088 g[0]=normval;
00089 }
00090
00091 template<class Norm>
00092 void
00093 Albany::SolutionFileResponseFunction<Norm>::
00094 evaluateTangent(
00095 const double alpha,
00096 const double beta,
00097 const double omega,
00098 const double current_time,
00099 bool sum_derivs,
00100 const Epetra_Vector* xdot,
00101 const Epetra_Vector* xdotdot,
00102 const Epetra_Vector& x,
00103 const Teuchos::Array<ParamVec>& p,
00104 ParamVec* deriv_p,
00105 const Epetra_MultiVector* Vxdot,
00106 const Epetra_MultiVector* Vxdotdot,
00107 const Epetra_MultiVector* Vx,
00108 const Epetra_MultiVector* Vp,
00109 Epetra_Vector* g,
00110 Epetra_MultiVector* gx,
00111 Epetra_MultiVector* gp)
00112 {
00113 Teuchos::RCP<Epetra_MultiVector> dgdx;
00114 if (gx != NULL && Vx != NULL)
00115 dgdx = Teuchos::rcp(new Epetra_MultiVector(x.Map(), 1));
00116 else
00117 dgdx = Teuchos::rcp(gx,false);
00118 evaluateGradient(current_time, xdot, xdotdot, x, p, deriv_p, g, dgdx.get(), NULL, NULL, gp);
00119 if (gx != NULL && Vx != NULL)
00120 gx->Multiply('T', 'N', alpha, *dgdx, *Vx, 0.0);
00121 }
00122
00123 template<class Norm>
00124 void
00125 Albany::SolutionFileResponseFunction<Norm>::
00126 evaluateGradient(const double current_time,
00127 const Epetra_Vector* xdot,
00128 const Epetra_Vector* xdotdot,
00129 const Epetra_Vector& x,
00130 const Teuchos::Array<ParamVec>& p,
00131 ParamVec* deriv_p,
00132 Epetra_Vector* g,
00133 Epetra_MultiVector* dg_dx,
00134 Epetra_MultiVector* dg_dxdot,
00135 Epetra_MultiVector* dg_dxdotdot,
00136 Epetra_MultiVector* dg_dp)
00137 {
00138 int MMFileStatus = 0;
00139
00140 if (!solutionLoaded) {
00141
00142 MMFileStatus = MatrixMarketFileToVector("reference_solution.dat",x.Map(),RefSoln);
00143
00144 TEUCHOS_TEST_FOR_EXCEPTION(MMFileStatus, std::runtime_error,
00145 std::endl << "EpetraExt::MatrixMarketFileToVector, file " __FILE__
00146 " line " << __LINE__ << " returned " << MMFileStatus << std::endl);
00147
00148 solutionLoaded = true;
00149 }
00150
00151
00152
00153 Epetra_Vector diff(x.Map());
00154
00155 double normval;
00156 Norm vec_op;
00157
00158
00159 if (g != NULL) {
00160
00161
00162
00163 diff.Update(1.0,x,-1.0,*RefSoln,0.0);
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175 normval = vec_op.Norm(diff);
00176 (*g)[0]=normval;
00177 }
00178
00179
00180 if (dg_dx != NULL)
00181 dg_dx->Update(2.0,x,-2.0,*RefSoln,0.0);
00182
00183
00184 if (dg_dxdot != NULL)
00185 dg_dxdot->PutScalar(0.0);
00186 if (dg_dxdotdot != NULL)
00187 dg_dxdotdot->PutScalar(0.0);
00188
00189
00190 if (dg_dp != NULL)
00191 dg_dp->PutScalar(0.0);
00192 }
00193
00194
00195
00196
00197 template<class Norm>
00198 int
00199 Albany::SolutionFileResponseFunction<Norm>::
00200 MatrixMarketFileToVector( const char *filename, const Epetra_BlockMap & map, Epetra_Vector * & A) {
00201
00202 Epetra_MultiVector * A1;
00203 if (MatrixMarketFileToMultiVector(filename, map, A1)) return(-1);
00204 A = dynamic_cast<Epetra_Vector *>(A1);
00205 return(0);
00206 }
00207
00208 template<class Norm>
00209 int
00210 Albany::SolutionFileResponseFunction<Norm>::
00211 MatrixMarketFileToMultiVector( const char *filename, const Epetra_BlockMap & map, Epetra_MultiVector * & A) {
00212
00213 const int lineLength = 1025;
00214 const int tokenLength = 35;
00215 char line[lineLength];
00216 char token1[tokenLength];
00217 char token2[tokenLength];
00218 char token3[tokenLength];
00219 char token4[tokenLength];
00220 char token5[tokenLength];
00221 int M, N;
00222
00223 FILE * handle = 0;
00224
00225 handle = fopen(filename,"r");
00226 if (handle == 0)
00227
00228 TEUCHOS_TEST_FOR_EXCEPTION(true, std::runtime_error,
00229 std::endl << "Reference solution file \" " << filename << " \" not found"
00230 << std::endl);
00231
00232
00233 if(fgets(line, lineLength, handle)==0)
00234
00235 TEUCHOS_TEST_FOR_EXCEPTION(true, std::runtime_error,
00236 std::endl << "Reference solution: MatrixMarket file is not in the proper format."
00237 << std::endl);
00238
00239 if(sscanf(line, "%s %s %s %s %s", token1, token2, token3, token4, token5 )==0)
00240
00241 TEUCHOS_TEST_FOR_EXCEPTION(true, std::runtime_error,
00242 std::endl << "Incorrect number of arguments on first line of reference solution file."
00243 << std::endl);
00244
00245 if (strcmp(token1, "%%MatrixMarket") ||
00246 strcmp(token2, "matrix") ||
00247 strcmp(token3, "array") ||
00248 strcmp(token4, "real") ||
00249 strcmp(token5, "general"))
00250
00251 TEUCHOS_TEST_FOR_EXCEPTION(true, std::runtime_error,
00252 std::endl << "Incorrect type of arguments on first line of reference solution file."
00253 << std::endl);
00254
00255
00256 do {
00257 if(fgets(line, lineLength, handle)==0)
00258 TEUCHOS_TEST_FOR_EXCEPTION(true, std::runtime_error,
00259 std::endl << "Reference solution file: invalid comment line."
00260 << std::endl);
00261 } while (line[0] == '%');
00262
00263
00264 if(sscanf(line, "%d %d", &M, &N)==0)
00265
00266 TEUCHOS_TEST_FOR_EXCEPTION(true, std::runtime_error,
00267 std::endl << "Reference solution file: cannot compute problem dimensions"
00268 << std::endl);
00269
00270
00271 int numMyPoints = map.NumMyPoints();
00272 int offset;
00273
00274
00275
00276
00277
00278
00279 if(map.Comm().MyPID() == 0){
00280 std::cout << "Reading reference solution from file \"" << filename << "\"" << std::endl;
00281 std::cout << "Reference solution contains " << N << " vectors, each with " << M << " rows." << std::endl;
00282 std::cout << std::endl;
00283 }
00284
00285
00286 if (N==1)
00287 A = new Epetra_Vector(map);
00288 else
00289 A = new Epetra_MultiVector(map, N);
00290
00291 double ** Ap = A->Pointers();
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334 for (int j=0; j<N; j++) {
00335 double * v = Ap[j];
00336
00337
00338 double V;
00339 for (int i=0; i<M; i++) {
00340 if(fgets(line, lineLength, handle)==0)
00341
00342 TEUCHOS_TEST_FOR_EXCEPTION(true, std::runtime_error,
00343 std::endl << "Reference solution file: cannot read line number " << i + offset << " in file."
00344 << std::endl);
00345
00346 if(map.LID(i)>= 0){
00347 if(sscanf(line, "%lg\n", &V)==0)
00348
00349 TEUCHOS_TEST_FOR_EXCEPTION(true, std::runtime_error,
00350 std::endl << "Reference solution file: cannot parse line number " << i << " in file."
00351 << std::endl);
00352
00353 v[map.LID(i)] = V;
00354 }
00355 }
00356 }
00357
00358 if (fclose(handle))
00359
00360 TEUCHOS_TEST_FOR_EXCEPTION(true, std::runtime_error,
00361 std::endl << "Cannot close reference solution file."
00362 << std::endl);
00363
00364 return(0);
00365 }
00366