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_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
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
00104
00105
00106
00107
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
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