Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007 #include "QCAD_CoupledPSPreconditioner.hpp"
00008 #include "Teuchos_ParameterListExceptions.hpp"
00009 #include "Teuchos_TestForException.hpp"
00010 #include "Epetra_LocalMap.h"
00011
00012
00013 QCAD::CoupledPSPreconditioner::CoupledPSPreconditioner(int nEigenvals,
00014 const Teuchos::RCP<const Epetra_Map>& discretizationMap,
00015 const Teuchos::RCP<const Epetra_Map>& fullPSMap,
00016 const Teuchos::RCP<const Epetra_Comm>& comm)
00017 {
00018 discMap = discretizationMap;
00019 domainMap = rangeMap = fullPSMap;
00020 myComm = comm;
00021 bUseTranspose = false;
00022 bInitialized = false;
00023 nEigenvalues = nEigenvals;
00024 }
00025
00026 QCAD::CoupledPSPreconditioner::~CoupledPSPreconditioner()
00027 {
00028 }
00029
00030
00032 void QCAD::CoupledPSPreconditioner::initialize(const Teuchos::RCP<Epetra_Operator>& poissonPrecond, const Teuchos::RCP<Epetra_Operator>& schrodingerPrecond)
00033 {
00034
00035 poissonPreconditioner = poissonPrecond;
00036 schrodingerPreconditioner = schrodingerPrecond;
00037
00038
00039 int num_discMap_myEls = discMap->NumMyElements();
00040 int my_nEigenvals = domainMap->NumMyElements() - num_discMap_myEls * (1+nEigenvalues);
00041 dist_evalMap = Teuchos::rcp(new Epetra_Map(nEigenvalues, my_nEigenvals, 0, *myComm));
00042
00043
00044 }
00045
00046
00048 int QCAD::CoupledPSPreconditioner::Apply(const Epetra_MultiVector& X, Epetra_MultiVector& Y) const
00049 {
00050 TEUCHOS_TEST_FOR_EXCEPTION(true, Teuchos::Exceptions::InvalidParameter,
00051 std::endl << "QCAD::CoupledPSPreconditioner::Apply is not implemented." << std::endl);
00052 return 0;
00053 }
00054
00056 int QCAD::CoupledPSPreconditioner::ApplyInverse(const Epetra_MultiVector& X, Epetra_MultiVector& Y) const
00057 {
00058
00059 int disc_nMyElements = discMap->NumMyElements();
00060
00061 Teuchos::RCP<Epetra_Vector> x_poisson, y_poisson;
00062 Teuchos::RCP<Epetra_MultiVector> x_schrodinger, y_schrodinger;
00063 Teuchos::RCP<Epetra_Vector> x_neg_evals, y_neg_evals;
00064 double *x_data, *y_data;
00065
00066 for(int i=0; i < X.NumVectors(); i++) {
00067
00068
00069 if(X(i)->ExtractView(&x_data) != 0 || Y(i)->ExtractView(&y_data) != 0)
00070 TEUCHOS_TEST_FOR_EXCEPTION(true, Teuchos::Exceptions::InvalidParameter,
00071 "Error! QCAD::CoupledPSPreconditioner -- cannot extract vector views");
00072
00073 x_poisson = Teuchos::rcp(new Epetra_Vector(::View, *discMap, &x_data[0]));
00074 x_schrodinger = Teuchos::rcp(new Epetra_MultiVector(::View, *discMap, &x_data[disc_nMyElements], disc_nMyElements, nEigenvalues));
00075 x_neg_evals = Teuchos::rcp(new Epetra_Vector(::View, *dist_evalMap, &x_data[(1+nEigenvalues)*disc_nMyElements]));
00076
00077 y_poisson = Teuchos::rcp(new Epetra_Vector(::View, *discMap, &y_data[0]));
00078 y_schrodinger = Teuchos::rcp(new Epetra_MultiVector(::View, *discMap, &y_data[disc_nMyElements], disc_nMyElements, nEigenvalues));
00079 y_neg_evals = Teuchos::rcp(new Epetra_Vector(::View, *dist_evalMap, &y_data[(1+nEigenvalues)*disc_nMyElements]));
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108 poissonPreconditioner->ApplyInverse(*x_poisson, *y_poisson);
00109
00110
00111 for(int j=0; j<nEigenvalues; j++) {
00112
00113 schrodingerPreconditioner->ApplyInverse( *((*x_schrodinger)(j)), *((*y_schrodinger)(j)) );
00114 }
00115
00116
00117 y_neg_evals->Scale(1.0, *x_neg_evals);
00118 }
00119 return 0;
00120 }