• Main Page
  • Related Pages
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

QCAD_CoupledPSPreconditioner.cpp

Go to the documentation of this file.
00001 //*****************************************************************//
00002 //    Albany 2.0:  Copyright 2012 Sandia Corporation               //
00003 //    This Software is released under the BSD license detailed     //
00004 //    in the file "license.txt" in the top-level Albany directory  //
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   // Set member variables
00035   poissonPreconditioner = poissonPrecond;
00036   schrodingerPreconditioner = schrodingerPrecond;
00037 
00038   // Prepare the distributed and local eigenvalue maps
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   //local_evalMap = Teuchos::rcp(new Epetra_LocalMap(nEigenvalues, 0, *myComm));
00043   //eval_importer = Teuchos::rcp(new Epetra_Import(*local_evalMap, *dist_evalMap));
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   //int disc_nGlobalElements = discMap->NumGlobalElements();
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     // Split X(i) and Y(i) into vector views for Poisson and Schrodinger parts
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     // Communicate all the x_evals to every processor, since all parts of the mesh need them
00082     //x_neg_evals_local->Import(*x_neg_evals, *eval_importer, Insert);
00083 
00084 
00085     // Preconditioner Matrix is:
00086     //
00087     //                   Phi                    Psi[i]                            -Eval[i]
00088     //          | ---------------------------------------------------------------------------------|
00089     //          |                      |                             |                             |
00090     // Poisson  |    Precond_poisson   |           0                 |               0             |
00091     //          |                      |                             |                             |
00092     //          | ---------------------------------------------------------------------------------|
00093     //          |                      |                             |                             |
00094     // Schro[j] |          0           |     Precond_schrodinger     |               0             |    
00095     //          |                      |                             |                             |
00096     //          | ---------------------------------------------------------------------------------|
00097     //          |                      |                             |                             |
00098     // Norm[j]  |          0           |            0                |           Identity          |
00099     //          |                      |                             |                             |
00100     //          | ---------------------------------------------------------------------------------|
00101     //
00102     //
00103 
00104     // Do multiplication block-wise
00105 
00106     // y_poisson =     
00107     //poissonPreconditioner->Apply(*x_poisson, *y_poisson);
00108     poissonPreconditioner->ApplyInverse(*x_poisson, *y_poisson); //Ifpack operators: call ApplyInverse to apply preconditioner
00109 
00110     // y_schrodinger =
00111     for(int j=0; j<nEigenvalues; j++) {
00112       //schrodingerPreconditioner->Apply( *((*x_schrodinger)(j)), *((*y_schrodinger)(j)) ); // y_schrodinger[j] = H * x_schrodinger[j]
00113       schrodingerPreconditioner->ApplyInverse( *((*x_schrodinger)(j)), *((*y_schrodinger)(j)) ); // y_schrodinger[j] = H * x_schrodinger[j]
00114     }
00115       
00116     // y_neg_evals =
00117     y_neg_evals->Scale(1.0, *x_neg_evals);
00118   }
00119   return 0;
00120 }

Generated on Wed Mar 26 2014 18:36:43 for Albany: a Trilinos-based PDE code by  doxygen 1.7.1