00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include "Epetra_config.h"
00033 #include "Epetra_MultiVector.h"
00034
00035 #include "FEApp_SGMeanPrecOp.hpp"
00036
00037 #if SGFAD_ACTIVE
00038
00039 FEApp::SGMeanPrecOp::SGMeanPrecOp(
00040 const Teuchos::RCP<const Epetra_Map>& base_map_,
00041 const Teuchos::RCP<const Epetra_Map>& sg_map_,
00042 unsigned int num_blocks_,
00043 const Teuchos::RCP<Epetra_CrsMatrix>& mean_jac_,
00044 const Teuchos::RCP<Teuchos::ParameterList>& precParams_) :
00045 label("FEApp::SGMeanPrecOp"),
00046 base_map(base_map_),
00047 sg_map(sg_map_),
00048 mean_jac(mean_jac_),
00049 precParams(precParams_),
00050 useTranspose(false),
00051 num_blocks(num_blocks_),
00052 sg_input(),
00053 sg_result(),
00054 input_block(num_blocks),
00055 result_block(num_blocks)
00056 {
00057 reset();
00058 }
00059
00060 FEApp::SGMeanPrecOp::~SGMeanPrecOp()
00061 {
00062 }
00063
00064 int
00065 FEApp::SGMeanPrecOp::reset()
00066 {
00067
00068 Ifpack Factory;
00069 std::string prec = precParams->get("Ifpack Preconditioner", "ILU");
00070 int overlap = precParams->get("Overlap", 0);
00071 ifpackPrec = Teuchos::rcp(Factory.Create(prec, mean_jac.get(), overlap));
00072 ifpackPrec->SetParameters(*precParams);
00073 int err = ifpackPrec->Initialize();
00074 err = ifpackPrec->Compute();
00075
00076 return err;
00077 }
00078
00079 Teuchos::RCP<Epetra_CrsMatrix>
00080 FEApp::SGMeanPrecOp::getMeanJacobian()
00081 {
00082 return mean_jac;
00083 }
00084
00085 int
00086 FEApp::SGMeanPrecOp::SetUseTranspose(bool UseTranspose)
00087 {
00088 useTranspose = UseTranspose;
00089 mean_jac->SetUseTranspose(useTranspose);
00090
00091 return 0;
00092 }
00093
00094 int
00095 FEApp::SGMeanPrecOp::Apply(const Epetra_MultiVector& Input,
00096 Epetra_MultiVector& Result) const
00097 {
00098 int m = Input.NumVectors();
00099 if (sg_input == Teuchos::null || sg_input->NumVectors() != m) {
00100 sg_input =
00101 Teuchos::rcp(new EpetraExt::BlockMultiVector(*base_map, *sg_map, m));
00102 sg_result =
00103 Teuchos::rcp(new EpetraExt::BlockMultiVector(*base_map, *sg_map, m));
00104 for (unsigned int i=0; i<num_blocks; i++) {
00105 input_block[i] = Teuchos::rcp(new Epetra_MultiVector(*base_map, m));
00106 result_block[i] = Teuchos::rcp(new Epetra_MultiVector(*base_map, m));
00107 }
00108 }
00109
00110
00111 sg_input->Scale(1.0, Input);
00112 for (unsigned int i=0; i<num_blocks; i++) {
00113 sg_input->ExtractBlockValues(*input_block[i], i);
00114 result_block[i]->PutScalar(0.0);
00115 }
00116
00117
00118 for (unsigned int i=0; i<num_blocks; i++) {
00119 ifpackPrec->Apply(*input_block[i], *result_block[i]);
00120 }
00121
00122
00123 for (unsigned int i=0; i<num_blocks; i++)
00124 sg_result->LoadBlockValues(*result_block[i], i);
00125 Result.Scale(1.0, *sg_result);
00126
00127 return 0;
00128 }
00129
00130 int
00131 FEApp::SGMeanPrecOp::ApplyInverse(const Epetra_MultiVector& Input,
00132 Epetra_MultiVector& Result) const
00133 {
00134 int m = Input.NumVectors();
00135 if (sg_input == Teuchos::null || sg_input->NumVectors() != m) {
00136 sg_input =
00137 Teuchos::rcp(new EpetraExt::BlockMultiVector(*base_map, *sg_map, m));
00138 sg_result =
00139 Teuchos::rcp(new EpetraExt::BlockMultiVector(*base_map, *sg_map, m));
00140 for (unsigned int i=0; i<num_blocks; i++) {
00141 input_block[i] = Teuchos::rcp(new Epetra_MultiVector(*base_map, m));
00142 result_block[i] = Teuchos::rcp(new Epetra_MultiVector(*base_map, m));
00143 }
00144 }
00145
00146
00147 sg_input->Scale(1.0, Input);
00148 for (unsigned int i=0; i<num_blocks; i++) {
00149 sg_input->ExtractBlockValues(*input_block[i], i);
00150 result_block[i]->PutScalar(0.0);
00151 }
00152
00153
00154 for (unsigned int i=0; i<num_blocks; i++) {
00155 ifpackPrec->ApplyInverse(*input_block[i], *result_block[i]);
00156 }
00157
00158
00159 for (unsigned int i=0; i<num_blocks; i++)
00160 sg_result->LoadBlockValues(*result_block[i], i);
00161 Result.Scale(1.0, *sg_result);
00162
00163 return 0;
00164 }
00165
00166 double
00167 FEApp::SGMeanPrecOp::NormInf() const
00168 {
00169 return mean_jac->NormInf();
00170 }
00171
00172
00173 const char*
00174 FEApp::SGMeanPrecOp::Label () const
00175 {
00176 return const_cast<char*>(label.c_str());
00177 }
00178
00179 bool
00180 FEApp::SGMeanPrecOp::UseTranspose() const
00181 {
00182 return useTranspose;
00183 }
00184
00185 bool
00186 FEApp::SGMeanPrecOp::HasNormInf() const
00187 {
00188 return true;
00189 }
00190
00191 const Epetra_Comm &
00192 FEApp::SGMeanPrecOp::Comm() const
00193 {
00194 return base_map->Comm();
00195 }
00196 const Epetra_Map&
00197 FEApp::SGMeanPrecOp::OperatorDomainMap() const
00198 {
00199 return *sg_map;
00200 }
00201
00202 const Epetra_Map&
00203 FEApp::SGMeanPrecOp::OperatorRangeMap() const
00204 {
00205 return *sg_map;
00206 }
00207
00208 #endif