FEApp_SGMatrixFreeOp.cpp

Go to the documentation of this file.
00001 // $Id: FEApp_SGMatrixFreeOp.cpp,v 1.1 2008/08/01 22:57:12 etphipp Exp $ 
00002 // $Source: /space/CVS/Trilinos/packages/sacado/example/FEApp/FEApp_SGMatrixFreeOp.cpp,v $ 
00003 // @HEADER
00004 // ***********************************************************************
00005 // 
00006 //                           Sacado Package
00007 //                 Copyright (2006) Sandia Corporation
00008 // 
00009 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
00010 // the U.S. Government retains certain rights in this software.
00011 // 
00012 // This library is free software; you can redistribute it and/or modify
00013 // it under the terms of the GNU Lesser General Public License as
00014 // published by the Free Software Foundation; either version 2.1 of the
00015 // License, or (at your option) any later version.
00016 //  
00017 // This library is distributed in the hope that it will be useful, but
00018 // WITHOUT ANY WARRANTY; without even the implied warranty of
00019 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00020 // Lesser General Public License for more details.
00021 //  
00022 // You should have received a copy of the GNU Lesser General Public
00023 // License along with this library; if not, write to the Free Software
00024 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00025 // USA
00026 // Questions? Contact David M. Gay (dmgay@sandia.gov) or Eric T. Phipps
00027 // (etphipp@sandia.gov).
00028 // 
00029 // ***********************************************************************
00030 // @HEADER
00031 
00032 #include "Epetra_config.h"
00033 #include "Epetra_MultiVector.h"
00034 
00035 #include "FEApp_SGMatrixFreeOp.hpp"
00036 
00037 #if SGFAD_ACTIVE
00038 
00039 FEApp::SGMatrixFreeOp::SGMatrixFreeOp(
00040    const Teuchos::RCP<const Epetra_Map>& base_map_,
00041    const Teuchos::RCP<const Epetra_Map>& sg_map_,
00042    const Teuchos::RCP<const tp_type >& Cijk_,
00043    const Teuchos::RCP<std::vector< Teuchos::RCP<Epetra_CrsMatrix> > >& jacs_) :
00044   label("FEApp::SGMatrixFreeOp"),
00045   base_map(base_map_),
00046   sg_map(sg_map_),
00047   Cijk(Cijk_),
00048   jacs(jacs_),
00049   useTranspose(false),
00050   num_blocks(jacs->size()),
00051   sg_input(),
00052   sg_result(),
00053   input_block(num_blocks),
00054   result_block(num_blocks),
00055   tmp()
00056 {
00057 }
00058 
00059 FEApp::SGMatrixFreeOp::~SGMatrixFreeOp()
00060 {
00061 }
00062 
00063 std::vector< Teuchos::RCP<Epetra_CrsMatrix> >&
00064 FEApp::SGMatrixFreeOp::getJacobianBlocks()
00065 {
00066   return *jacs;
00067 }
00068 
00069 int 
00070 FEApp::SGMatrixFreeOp::SetUseTranspose(bool UseTranspose) 
00071 {
00072   useTranspose = UseTranspose;
00073   for (unsigned int i=0; i<num_blocks; i++)
00074     (*jacs)[i]->SetUseTranspose(useTranspose);
00075 
00076   return 0;
00077 }
00078 
00079 int 
00080 FEApp::SGMatrixFreeOp::Apply(const Epetra_MultiVector& Input, 
00081            Epetra_MultiVector& Result) const
00082 {
00083   int m = Input.NumVectors();
00084   if (sg_input == Teuchos::null || sg_input->NumVectors() != m) {
00085     sg_input = 
00086       Teuchos::rcp(new EpetraExt::BlockMultiVector(*base_map, *sg_map, m));
00087     sg_result = 
00088       Teuchos::rcp(new EpetraExt::BlockMultiVector(*base_map, *sg_map, m));
00089     for (unsigned int i=0; i<num_blocks; i++) {
00090       input_block[i] = Teuchos::rcp(new Epetra_MultiVector(*base_map, m));
00091       result_block[i] = Teuchos::rcp(new Epetra_MultiVector(*base_map, m));
00092     }
00093     tmp = Teuchos::rcp(new Epetra_MultiVector(*base_map, m));
00094   }
00095 
00096   // Fill input blocks
00097   sg_input->Scale(1.0, Input);
00098   for (unsigned int i=0; i<num_blocks; i++) {
00099     sg_input->ExtractBlockValues(*input_block[i], i);
00100     result_block[i]->PutScalar(0.0);
00101   }
00102 
00103   // Apply block SG Jacobian via
00104   // w_i = 
00105   //    \sum_{j=0}^P \sum_{k=0}^P J_k v_j < \psi_i \psi_j \psi_k > / <\psi_i^2>
00106   // for i=0,...,P where P = num_blocks w_j is the jth input block, w_i
00107   // is the ith result block, and J_k is the kth block Jacobian
00108   double cijk;
00109   unsigned int i, j;
00110   for (unsigned int k=0; k<num_blocks; k++) {
00111     unsigned int nl = Cijk->num_values(k);
00112     for (unsigned int l=0; l<nl; l++) {
00113       Cijk->triple_value(k, l, i, j, cijk);
00114       cijk /= Cijk->norm_squared(i);
00115       (*jacs)[k]->Apply(*input_block[j], *tmp);
00116       result_block[i]->Update(cijk, *tmp, 1.0);
00117     }
00118   }
00119 
00120   // Get result from blocks
00121   for (unsigned int i=0; i<num_blocks; i++)
00122     sg_result->LoadBlockValues(*result_block[i], i);
00123   Result.Scale(1.0, *sg_result);
00124 
00125   return 0;
00126 }
00127 
00128 int 
00129 FEApp::SGMatrixFreeOp::ApplyInverse(const Epetra_MultiVector& Input, 
00130             Epetra_MultiVector& Result) const
00131 {
00132   throw "SGMatrixFreeOp::ApplyInverse not defined!";
00133   return -1;
00134 }
00135 
00136 double 
00137 FEApp::SGMatrixFreeOp::NormInf() const
00138 {
00139   return 1.0;
00140 }
00141 
00142 
00143 const char* 
00144 FEApp::SGMatrixFreeOp::Label () const
00145 {
00146   return const_cast<char*>(label.c_str());
00147 }
00148   
00149 bool 
00150 FEApp::SGMatrixFreeOp::UseTranspose() const
00151 {
00152   return useTranspose;
00153 }
00154 
00155 bool 
00156 FEApp::SGMatrixFreeOp::HasNormInf() const
00157 {
00158   return false;
00159 }
00160 
00161 const Epetra_Comm & 
00162 FEApp::SGMatrixFreeOp::Comm() const
00163 {
00164   return base_map->Comm();
00165 }
00166 const Epetra_Map& 
00167 FEApp::SGMatrixFreeOp::OperatorDomainMap() const
00168 {
00169   return *sg_map;
00170 }
00171 
00172 const Epetra_Map& 
00173 FEApp::SGMatrixFreeOp::OperatorRangeMap() const
00174 {
00175   return *sg_map;
00176 }
00177 
00178 #endif

Generated on Wed May 12 21:59:04 2010 for Sacado Package Browser (Single Doxygen Collection) by  doxygen 1.4.7