• Main Page
  • Related Pages
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

Albany_SolutionFileResponseFunction_Def.hpp

Go to the documentation of this file.
00001 //*****************************************************************//
00002 //    Albany 2.0:  Copyright 2012 Sandia Corporation               //
00003 //    This Software is released under the BSD license detailed     //
00004 //    in the file "license.txt" in the top-level Albany directory  //
00005 //*****************************************************************//
00006 
00007 #include "Albany_SolutionFileResponseFunction.hpp"
00008 //#include "EpetraExt_VectorIn.h"
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   // Read the reference solution for comparison from "reference_solution.dat"
00051 
00052   // Note that this is of MatrixMarket array real general format
00053 
00054   if (!solutionLoaded) {
00055 //    MMFileStatus = EpetraExt::MatrixMarketFileToVector("reference_solution.dat",x.Map(),RefSoln);
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   // Build a vector to hold the difference between the actual and reference solutions
00067   Epetra_Vector diff(x.Map());
00068 
00069   double normval;
00070   Norm vec_op;
00071 
00072   // The diff vector equals 1.0 * soln + -1.0 * reference
00073   diff.Update(1.0,x,-1.0,*RefSoln,0.0); 
00074 
00075   // Print vectors for debugging
00076 /*
00077   std::cout << "Difference from evaluate response" << std::endl;
00078   diff.Print(std::cout);
00079   std::cout << "Solution from evaluate response" << std::endl;
00080   x.Print(std::cout);
00081   std::cout << "Ref solution from evaluate response" << std::endl;
00082   RefSoln->Print(std::cout);
00083 */
00084 
00085   // Get the norm
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 //    MMFileStatus = EpetraExt::MatrixMarketFileToVector("reference_solution.dat",x.Map(),RefSoln);
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   // Build a vector to hold the difference between the actual and reference solutions
00153   Epetra_Vector diff(x.Map());
00154 
00155   double normval;
00156   Norm vec_op;
00157 
00158   // Evaluate response g
00159   if (g != NULL) {
00160 
00161   // The diff vector equals 1.0 * soln + -1.0 * reference
00162 
00163     diff.Update(1.0,x,-1.0,*RefSoln,0.0);
00164 
00165     // Print vectors for debugging
00166 /*
00167     std::cout << "Difference from evaluate gradient" << std::endl;
00168     diff.Print(std::cout);
00169     std::cout << "Solution from evaluate gradient" << std::endl;
00170     x.Print(std::cout);
00171     std::cout << "Ref solution from evaluate gradient" << std::endl;
00172     RefSoln->Print(std::cout);
00173 */
00174 
00175     normval = vec_op.Norm(diff);
00176     (*g)[0]=normval;
00177   }
00178 
00179   // Evaluate dg/dx
00180   if (dg_dx != NULL)
00181     dg_dx->Update(2.0,x,-2.0,*RefSoln,0.0);
00182 
00183   // Evaluate dg/dxdot
00184   if (dg_dxdot != NULL)
00185     dg_dxdot->PutScalar(0.0);
00186   if (dg_dxdotdot != NULL)
00187     dg_dxdotdot->PutScalar(0.0);
00188 
00189   // Evaluate dg/dp
00190   if (dg_dp != NULL)
00191     dg_dp->PutScalar(0.0);
00192 }
00193 
00194 // This is "borrowed" from EpetraExt because more explicit debugging information is needed than
00195 //  is present in the EpetraExt version. TO DO: Move this back there
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");  // Open file
00226   if (handle == 0)
00227     // file not found
00228     TEUCHOS_TEST_FOR_EXCEPTION(true, std::runtime_error,
00229       std::endl << "Reference solution file \" " << filename << " \" not found"
00230       << std::endl);
00231 
00232   // Check first line, which should be "%%MatrixMarket matrix coordinate real general" (without quotes)
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   // Next, strip off header lines (which start with "%")
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   // Next get problem dimensions: M, N
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   // Compute the offset for each processor for when it should start storing values
00271   int numMyPoints = map.NumMyPoints();
00272   int offset;
00273   //map.Comm().ScanSum(&numMyPoints, &offset, 1); // ScanSum will compute offsets for us
00274   //offset -= numMyPoints; // readjust for my PE
00275 
00276   // Line to start reading in reference file
00277 //  offset = map.MinMyGID();
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   // Now construct vector/multivector
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   for (int j=0; j<N; j++) {
00295     double * v = Ap[j];
00296 
00297     // Now read in lines that we will discard
00298     for (int i=0; i<offset; i++)
00299       if(fgets(line, lineLength, handle)==0)
00300 
00301         TEUCHOS_TEST_FOR_EXCEPTION(true, std::runtime_error,
00302           std::endl << "Reference solution file: invalid line number " << i << " found while reading file lead data."
00303           << std::endl);
00304     
00305     // Now read in each value and store to the local portion of the the  if the row is owned.
00306     double V;
00307     for (int i=0; i<numMyPoints; i++) {
00308       if(fgets(line, lineLength, handle)==0) 
00309 
00310         TEUCHOS_TEST_FOR_EXCEPTION(true, std::runtime_error,
00311           std::endl << "Reference solution file: cannot read line number " << i + offset << " in file."
00312           << std::endl);
00313 
00314       if(sscanf(line, "%lg\n", &V)==0)
00315 
00316         TEUCHOS_TEST_FOR_EXCEPTION(true, std::runtime_error,
00317           std::endl << "Reference solution file: cannot parse line number " << i << " in file."
00318           << std::endl);
00319 
00320       v[i] = V;
00321     }
00322     // Now read in the rest of the lines to discard
00323     for (int i=0; i < M-numMyPoints-offset; i++) {
00324       if(fgets(line, lineLength, handle)==0)
00325 
00326         TEUCHOS_TEST_FOR_EXCEPTION(true, std::runtime_error,
00327           std::endl << "Reference solution file: invalid line number " << i + offset + numMyPoints
00328           << " found parsing toward end of file."
00329           << std::endl);
00330     }
00331   }
00332 */
00333 
00334   for (int j=0; j<N; j++) {
00335     double * v = Ap[j];
00336 
00337     // Now read in each value and store to the local portion of the array if the row is owned.
00338     double V;
00339     for (int i=0; i<M; i++) { // i is rownumber in file, or the GID 
00340       if(fgets(line, lineLength, handle)==0)  // Can't read the line
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){ // we own this data value
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 

Generated on Wed Mar 26 2014 18:36:36 for Albany: a Trilinos-based PDE code by  doxygen 1.7.1