|
Teko Version of the Day
|
00001 /* 00002 // @HEADER 00003 // 00004 // *********************************************************************** 00005 // 00006 // Teko: A package for block and physics based preconditioning 00007 // Copyright 2010 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 // Redistribution and use in source and binary forms, with or without 00013 // modification, are permitted provided that the following conditions are 00014 // met: 00015 // 00016 // 1. Redistributions of source code must retain the above copyright 00017 // notice, this list of conditions and the following disclaimer. 00018 // 00019 // 2. Redistributions in binary form must reproduce the above copyright 00020 // notice, this list of conditions and the following disclaimer in the 00021 // documentation and/or other materials provided with the distribution. 00022 // 00023 // 3. Neither the name of the Corporation nor the names of the 00024 // contributors may be used to endorse or promote products derived from 00025 // this software without specific prior written permission. 00026 // 00027 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY 00028 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00029 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 00030 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE 00031 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00032 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00033 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00034 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00035 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00036 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00037 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00038 // 00039 // Questions? Contact Eric C. Cyr (eccyr@sandia.gov) 00040 // 00041 // *********************************************************************** 00042 // 00043 // @HEADER 00044 00045 */ 00046 00047 #include "Teko_LU2x2InverseOp.hpp" 00048 00049 #include "Thyra_DefaultProductVectorSpace.hpp" 00050 #include "Thyra_ProductMultiVectorBase.hpp" 00051 #include "Thyra_DefaultMultipliedLinearOp.hpp" 00052 #include "Thyra_MultiVectorStdOps.hpp" 00053 00054 using namespace Thyra; 00055 using Teuchos::RCP; 00056 using Teuchos::ArrayRCP; 00057 using Teuchos::dyn_cast; 00058 00059 namespace Teko { 00060 00061 // Thyra::LinearOpBase requirements 00063 LU2x2InverseOp::LU2x2InverseOp(const BlockedLinearOp & A, 00064 const LinearOp & invA00, 00065 const LinearOp & invS) 00066 : A_(A), hatInvA00_(invA00), tildeInvA00_(invA00), invS_(invS), 00067 A10_(A->getBlock(1,0)), A01_(A->getBlock(0,1)) 00068 { 00069 RCP<const VectorSpaceBase<double> > productArray[2]; 00070 00071 // create and store range space 00072 productArray[0] = hatInvA00_->range(); 00073 productArray[1] = invS_->range(); 00074 productRange_ = rcp(new DefaultProductVectorSpace<double>(2,&productArray[0])); 00075 00076 // create and store range space 00077 productArray[0] = hatInvA00_->domain(); 00078 productArray[1] = invS_->domain(); 00079 productDomain_ = rcp(new DefaultProductVectorSpace<double>(2,&productArray[0])); 00080 // "productVectorSpace" did not yield to me quick enough 00081 } 00082 00094 LU2x2InverseOp::LU2x2InverseOp(const BlockedLinearOp & A, 00095 const LinearOp & hatInvA00, 00096 const LinearOp & tildeInvA00, 00097 const LinearOp & invS) 00098 : A_(A), hatInvA00_(hatInvA00), tildeInvA00_(tildeInvA00), invS_(invS), 00099 A10_(A->getBlock(1,0)), A01_(A->getBlock(0,1)) 00100 { 00101 RCP<const VectorSpaceBase<double> > productArray[2]; 00102 00103 // create and store range space 00104 productArray[0] = hatInvA00_->range(); 00105 productArray[1] = invS_->range(); 00106 productRange_ = rcp(new DefaultProductVectorSpace<double>(2,&productArray[0])); 00107 00108 // create and store range space 00109 productArray[0] = hatInvA00_->domain(); 00110 productArray[1] = invS_->domain(); 00111 productDomain_ = rcp(new DefaultProductVectorSpace<double>(2,&productArray[0])); 00112 // "productVectorSpace" did not yield to me quick enough 00113 } 00114 00115 void LU2x2InverseOp::implicitApply(const BlockedMultiVector & x, BlockedMultiVector & y, 00116 const double alpha, const double beta) const 00117 { 00118 // get src blocks 00119 MultiVector f = getBlock(0,x); // f 00120 MultiVector g = getBlock(1,x); // g 00121 00122 // get extra storage 00123 MultiVector ps = deepcopy(g); // this is need b/c of p = -inv(S)*p 00124 00125 // get destination blocks 00126 MultiVector u = getBlock(0,y); // u (u^) 00127 MultiVector p = getBlock(1,y); // p (p^) 00128 00129 // for efficiency make copies of u and p 00130 MultiVector uc,pc; // copies of u and p 00131 if(beta!=0) { 00132 // perform a deep copy 00133 uc = deepcopy(u); 00134 pc = deepcopy(p); 00135 } else { 00136 // perform a shallow copy 00137 00138 // uc and pc point 00139 // to the data of u and p 00140 uc = u; 00141 pc = p; 00142 } 00143 00144 // set temporary operator for performing inv(A_00)*A_01 00145 LinearOp invA00_A01 = Thyra::multiply(tildeInvA00_,A01_); 00146 00147 // compute actual product 00148 applyOp(hatInvA00_, f, uc); // u = inv(A_00) * f 00149 applyOp(A10_, uc, ps, -1.0, 1.0); // ps += -A_10*u 00150 applyOp(invS_, ps, pc, -1.0); // p = -inv(S)*ps 00151 applyOp(invA00_A01, pc, uc, -1.0, 1.0); // u += -inv(A_00)*A_01*p 00152 00153 // scale result by alpha 00154 if(beta!=0) { 00155 update(alpha,uc,beta,u); // u = alpha * uc + beta * u 00156 update(alpha,pc,beta,p); // p = alpha * pc + beta * p 00157 } 00158 else if(alpha!=1.0) { 00159 scale(alpha,u); // u = alpha * u 00160 scale(alpha,p); // p = alpha * p 00161 } 00162 } 00163 00164 void LU2x2InverseOp::describe(Teuchos::FancyOStream & out_arg, 00165 const Teuchos::EVerbosityLevel verbLevel) const 00166 { 00167 using Teuchos::OSTab; 00168 00169 RCP<Teuchos::FancyOStream> out = rcp(&out_arg,false); 00170 OSTab tab(out); 00171 switch(verbLevel) { 00172 case Teuchos::VERB_DEFAULT: 00173 case Teuchos::VERB_LOW: 00174 *out << this->description() << std::endl; 00175 break; 00176 case Teuchos::VERB_MEDIUM: 00177 case Teuchos::VERB_HIGH: 00178 case Teuchos::VERB_EXTREME: 00179 { 00180 *out << Teuchos::Describable::description() << "{" 00181 << "rangeDim=" << this->range()->dim() 00182 << ",domainDim=" << this->domain()->dim() 00183 << "}\n"; 00184 { 00185 OSTab tab(out); 00186 *out << "[invS]:\n"; 00187 *out << Teuchos::describe(*invS_,verbLevel); 00188 00189 *out << "[hatInvA00]:\n"; 00190 *out << Teuchos::describe(*hatInvA00_,verbLevel); 00191 00192 *out << "[tildeInvA00]:\n"; 00193 *out << Teuchos::describe(*tildeInvA00_,verbLevel); 00194 00195 *out << "[A_10]:\n"; 00196 *out << Teuchos::describe(*A10_,verbLevel); 00197 00198 *out << "[A_01]:\n"; 00199 *out << Teuchos::describe(*A01_,verbLevel); 00200 } 00201 break; 00202 } 00203 default: 00204 TEST_FOR_EXCEPT(true); // Should never get here! 00205 } 00206 } 00207 00208 } // end namespace Teko
1.7.4