Amesos2 - Direct Sparse Solver Interfaces Version of the Day
Amesos2_Superludist_TypeMap.hpp
Go to the documentation of this file.
00001 // @HEADER
00002 //
00003 // ***********************************************************************
00004 //
00005 //           Amesos2: Templated Direct Sparse Solver Package 
00006 //                  Copyright 2011 Sandia Corporation
00007 //
00008 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
00009 // the U.S. Government retains certain rights in this software.
00010 //
00011 // Redistribution and use in source and binary forms, with or without
00012 // modification, are permitted provided that the following conditions are
00013 // met:
00014 //
00015 // 1. Redistributions of source code must retain the above copyright
00016 // notice, this list of conditions and the following disclaimer.
00017 //
00018 // 2. Redistributions in binary form must reproduce the above copyright
00019 // notice, this list of conditions and the following disclaimer in the
00020 // documentation and/or other materials provided with the distribution.
00021 //
00022 // 3. Neither the name of the Corporation nor the names of the
00023 // contributors may be used to endorse or promote products derived from
00024 // this software without specific prior written permission.
00025 //
00026 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00027 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00028 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00029 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00030 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00031 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00032 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00033 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00034 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00035 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00036 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00037 //
00038 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
00039 //
00040 // ***********************************************************************
00041 //
00042 // @HEADER
00043 
00057 #ifndef AMESOS2_SUPERLUDIST_TYPEMAP_HPP
00058 #define AMESOS2_SUPERLUDIST_TYPEMAP_HPP
00059 
00060 #include <functional>
00061 
00062 #include <Teuchos_as.hpp>
00063 #ifdef HAVE_TEUCHOS_COMPLEX
00064 #include <Teuchos_SerializationTraits.hpp>
00065 #endif
00066 
00067 #include "Amesos2_TypeMap.hpp"
00068 
00069 namespace SLUD {
00070 
00071 extern "C" {
00072 
00073   // undefine compiler guard in case we also have the sequential
00074   // SuperLU enabled
00075 #undef __SUPERLU_SUPERMATRIX
00076 #include "superlu_defs.h"
00077 
00078   namespace D {
00079 #include "superlu_ddefs.h"  // double-precision real definitions
00080   }
00081 
00082 #ifdef HAVE_TEUCHOS_COMPLEX
00083   namespace Z {
00084 #include "superlu_zdefs.h"     // double-precision complex definitions
00085   }
00086 #endif  // HAVE_TEUCHOS_COMPLEX
00087 
00088 } // end extern "C"
00089 #ifdef HAVE_TEUCHOS_COMPLEX
00090 
00091   // Declare and specialize a std::binary_funtion class for
00092   // multiplication of SLUD types
00093   template <typename slu_scalar_t, typename slu_mag_t>
00094   struct slu_mt_mult {};
00095 
00096   // This specialization handles the generic case were the scalar and
00097   // magnitude types are double or float.
00098   template <typename T>
00099   struct slu_mt_mult<T,T> : std::multiplies<T> {};
00100 
00101   // For namespace/macro reasons, we prefix our variables with amesos_*
00102   template <>
00103   struct slu_mt_mult<Z::doublecomplex,double>
00104     : std::binary_function<Z::doublecomplex,double,Z::doublecomplex> {
00105     Z::doublecomplex operator()(Z::doublecomplex amesos_z, double amesos_d) {
00106       Z::doublecomplex amesos_zr;
00107       zd_mult(&amesos_zr, &amesos_z, amesos_d); // zd_mult is a macro, so no namespacing
00108       return( amesos_zr );
00109     }
00110   };
00111 
00112   template <>
00113   struct slu_mt_mult<Z::doublecomplex,Z::doublecomplex>
00114     : std::binary_function<Z::doublecomplex,Z::doublecomplex,Z::doublecomplex> {
00115     Z::doublecomplex operator()(Z::doublecomplex amesos_z1, Z::doublecomplex amesos_z2) {
00116       Z::doublecomplex amesos_zr;
00117       zz_mult(&amesos_zr, &amesos_z1, &amesos_z2);    // zz_mult is a macro, so no namespacing
00118       return( amesos_zr );
00119     }
00120   };
00121 #endif  // HAVE_TEUCHOS_COMPLEX
00122 } // end namespace SLUD
00123 #ifdef HAVE_TEUCHOS_COMPLEX
00124 
00125 
00126 /* ==================== Conversion ==================== */
00127 namespace Teuchos {
00128 
00139 template <typename TypeFrom>
00140 class ValueTypeConversionTraits<SLUD::Z::doublecomplex, TypeFrom>
00141 {
00142 public:
00143   static SLUD::Z::doublecomplex convert( const TypeFrom t )
00144     {
00145       SLUD::Z::doublecomplex ret;
00146       ret.r = Teuchos::as<double>(t.real());
00147       ret.i = Teuchos::as<double>(t.imag());
00148       return( ret );
00149     }
00150 
00151   static SLUD::Z::doublecomplex safeConvert( const TypeFrom t )
00152     {
00153       SLUD::Z::doublecomplex ret;
00154       ret.r = Teuchos::as<double>(t.real());
00155       ret.i = Teuchos::as<double>(t.imag());
00156       return( ret );
00157     }
00158 };
00159 
00160 
00161 // Also convert from SLU types
00162 template <typename TypeTo>
00163 class ValueTypeConversionTraits<TypeTo, SLUD::Z::doublecomplex>
00164 {
00165 public:
00166   static TypeTo convert( const SLUD::Z::doublecomplex t )
00167     {
00168       typedef typename TypeTo::value_type value_type;
00169       value_type ret_r = Teuchos::as<value_type>( t.r );
00170       value_type ret_i = Teuchos::as<value_type>( t.i );
00171       return ( TypeTo( ret_r, ret_i ) );
00172     }
00173 
00174   // No special checks for safe Convert
00175   static TypeTo safeConvert( const SLUD::Z::doublecomplex t )
00176     {
00177       typedef typename TypeTo::value_type value_type;
00178       value_type ret_r = Teuchos::as<value_type>( t.r );
00179       value_type ret_i = Teuchos::as<value_type>( t.i );
00180       return ( TypeTo( ret_r, ret_i ) );
00181     }
00182 };
00183 
00184 template <typename Ordinal>
00185 class SerializationTraits<Ordinal,SLUD::Z::doublecomplex>
00186   : public DirectSerializationTraits<Ordinal,SLUD::Z::doublecomplex>
00187 {};
00188 
00190 
00191 } // end namespace Teuchos
00192 
00193 
00194 
00200 namespace std {
00201   // C++-style output functions for Superludist complex types
00202   ostream& operator<<(ostream& out, const SLUD::Z::doublecomplex z);
00203   
00205 }
00206 #endif  // HAVE_TEUCHOS_COMPLEX
00207 
00208 
00209 
00210 namespace Amesos2 {
00211 
00212 template <class, class> class Superludist;
00213 
00214 /* Specialize the Amesos2::TypeMap struct for SuperLU_DIST types
00215  *
00216  * \cond Superludist_type_specializations 
00217  */
00218 template <>
00219 struct TypeMap<Superludist,double>
00220 {
00221   static const SLUD::Dtype_t dtype = SLUD::SLU_D;
00222   typedef double type;
00223   typedef double magnitude_type;
00224   typedef SLUD::D::LUstruct_t LUstruct_t;
00225   typedef SLUD::D::SOLVEstruct_t SOLVEstruct_t;
00226 };
00227 
00228 #ifdef HAVE_TEUCHOS_COMPLEX
00229 template <>
00230 struct TypeMap<Superludist,std::complex<double> >
00231 {
00232   static const SLUD::Dtype_t dtype = SLUD::SLU_Z;
00233   typedef SLUD::Z::doublecomplex type;
00234   typedef double magnitude_type;
00235   typedef SLUD::Z::LUstruct_t LUstruct_t;
00236   typedef SLUD::Z::SOLVEstruct_t SOLVEstruct_t;
00237 };
00238 
00239   // It probably won't happen, but what if someone does create a
00240   // matrix or multivector with the SuperLU_DIST doublecomplex type
00241   // directly?
00242 template <>
00243 struct TypeMap<Superludist,SLUD::Z::doublecomplex>
00244 {
00245   static const SLUD::Dtype_t dtype = SLUD::SLU_Z;
00246   typedef SLUD::Z::doublecomplex type;
00247   typedef double magnitude_type;
00248   typedef SLUD::Z::LUstruct_t LUstruct_t;
00249   typedef SLUD::Z::SOLVEstruct_t SOLVEstruct_t;
00250 };
00251 
00252 #endif  // HAVE_TEUCHOS_COMPLEX
00253 
00254 /* \endcond Superludist_type_specializations */
00255 
00256 
00257 } // end namespace Amesos2
00258 
00259 #endif  // AMESOS2_SUPERLUDIST_TYPEMAP_HPP