Amesos2 - Direct Sparse Solver Interfaces Version of the Day
Amesos2_Superlu_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 
00054 #ifndef AMESOS2_SUPERLU_TYPEMAP_HPP
00055 #define AMESOS2_SUPERLU_TYPEMAP_HPP
00056 
00057 #include <functional>
00058 #ifdef HAVE_TEUCHOS_COMPLEX
00059 #include <complex>
00060 #endif
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 
00070 /* The SuperLU comples headers file only need to be included if
00071    complex has been enabled in Teuchos.  In addition we only need to
00072    define the conversion and printing functions if complex has been
00073    enabled. */
00074 namespace SLU {
00075 
00076 typedef int int_t;
00077 
00078 extern "C" {
00079 
00080 #undef __SUPERLU_SUPERMATRIX
00081 #include "supermatrix.h"  // for Dtype_t declaration
00082 
00083 #ifdef HAVE_TEUCHOS_COMPLEX
00084 namespace C {
00085 #undef __SUPERLU_SCOMPLEX
00086 #undef SCOMPLEX_INCLUDE
00087 #include "slu_scomplex.h"     // single-precision complex data type definitions
00088 }
00089 
00090 namespace Z {
00091 #undef __SUPERLU_DCOMPLEX
00092 #undef DCOMPLEX_INCLUDE
00093 #include "slu_dcomplex.h"     // double-precision complex data type definitions
00094 }
00095 #endif  // HAVE_TEUCHOS_COMPLEX
00096 
00097 } // end extern "C"
00098 
00099   // Declare and specialize a std::binary_funtion class for
00100   // multiplication of SuperLU types
00101   template <typename slu_scalar_t, typename slu_mag_t>
00102   struct slu_mult {};
00103 
00104   // This specialization handles the generic case were the scalar and
00105   // magnitude types are double or float.
00106   template <typename T>
00107   struct slu_mult<T,T> : std::multiplies<T> {};
00108 
00109 #ifdef HAVE_TEUCHOS_COMPLEX
00110   
00111   // For namespace/macro reasons, we prefix our variables with amesos_*
00112   template <>
00113   struct slu_mult<C::complex,float>
00114     : std::binary_function<C::complex,float,C::complex> {
00115     C::complex operator()(C::complex amesos_c, float amesos_f) {
00116       C::complex amesos_cr;
00117       cs_mult(&amesos_cr, &amesos_c, amesos_f); // cs_mult is a macro, so no namespacing
00118       return( amesos_cr );
00119     }
00120   };
00121 
00122   template <>
00123   struct slu_mult<C::complex,C::complex>
00124     : std::binary_function<C::complex,C::complex,C::complex> {
00125     C::complex operator()(C::complex amesos_c1, C::complex amesos_c2) {
00126       C::complex amesos_cr;
00127       cc_mult(&amesos_cr, &amesos_c1, &amesos_c2); // cc_mult is a macro, so no namespacing
00128       return( amesos_cr );
00129     }
00130   };
00131     
00132   template <>
00133   struct slu_mult<Z::doublecomplex,double>
00134     : std::binary_function<Z::doublecomplex,double,Z::doublecomplex> {
00135     Z::doublecomplex operator()(Z::doublecomplex amesos_z, double amesos_d) {
00136       Z::doublecomplex amesos_zr;
00137       zd_mult(&amesos_zr, &amesos_z, amesos_d); // zd_mult is a macro, so no namespacing
00138       return( amesos_zr );
00139     }
00140   };
00141 
00142   template <>
00143   struct slu_mult<Z::doublecomplex,Z::doublecomplex>
00144     : std::binary_function<Z::doublecomplex,Z::doublecomplex,Z::doublecomplex> {
00145     Z::doublecomplex operator()(Z::doublecomplex amesos_z1, Z::doublecomplex amesos_z2) {
00146       Z::doublecomplex amesos_zr;
00147       zz_mult(&amesos_zr, &amesos_z1, &amesos_z2);    // zz_mult is a macro, so no namespacing
00148       return( amesos_zr );
00149     }
00150   };
00151 
00152 #endif  // HAVE_TEUCHOS_COMPLEX
00153 } // end namespace SLU
00154 #ifdef HAVE_TEUCHOS_COMPLEX
00155 
00156 /* ==================== Conversion ==================== */
00157 namespace Teuchos {
00158 
00169 template <typename TypeFrom>
00170 class ValueTypeConversionTraits<SLU::C::complex, TypeFrom>
00171 {
00172 public:
00173   static SLU::C::complex convert( const TypeFrom t )
00174     {
00175       SLU::C::complex ret;
00176       ret.r = Teuchos::as<float>(t.real());
00177       ret.i = Teuchos::as<float>(t.imag());
00178       return( ret );
00179     }
00180 
00181   static SLU::C::complex safeConvert( const TypeFrom t )
00182     {
00183       SLU::C::complex ret;
00184       ret.r = Teuchos::as<float>(t.real());
00185       ret.i = Teuchos::as<float>(t.imag());
00186       return( ret );
00187     }
00188 };
00189 
00190 
00191 template <typename TypeFrom>
00192 class ValueTypeConversionTraits<SLU::Z::doublecomplex, TypeFrom>
00193 {
00194 public:
00195   static SLU::Z::doublecomplex convert( const TypeFrom t )
00196     {
00197       SLU::Z::doublecomplex ret;
00198       ret.r = Teuchos::as<double>(t.real());
00199       ret.i = Teuchos::as<double>(t.imag());
00200       return( ret );
00201     }
00202 
00203   static SLU::Z::doublecomplex safeConvert( const TypeFrom t )
00204     {
00205       SLU::Z::doublecomplex ret;
00206       ret.r = Teuchos::as<double>(t.real());
00207       ret.i = Teuchos::as<double>(t.imag());
00208       return( ret );
00209     }
00210 };
00211 
00212 
00213 // Also convert from SLU types
00214 template <typename TypeTo>
00215 class ValueTypeConversionTraits<TypeTo, SLU::C::complex>
00216 {
00217 public:
00218   static TypeTo convert( const SLU::C::complex t )
00219     {
00220       typedef typename TypeTo::value_type value_type;
00221       value_type ret_r = Teuchos::as<value_type>( t.r );
00222       value_type ret_i = Teuchos::as<value_type>( t.i );
00223       return ( TypeTo( ret_r, ret_i ) );
00224     }
00225 
00226   // No special checks for safe Convert
00227   static TypeTo safeConvert( const SLU::C::complex t )
00228     {
00229       typedef typename TypeTo::value_type value_type;
00230       value_type ret_r = Teuchos::as<value_type>( t.r );
00231       value_type ret_i = Teuchos::as<value_type>( t.i );
00232       return ( TypeTo( ret_r, ret_i ) );
00233     }
00234 };
00235 
00236 
00237 template <typename TypeTo>
00238 class ValueTypeConversionTraits<TypeTo, SLU::Z::doublecomplex>
00239 {
00240 public:
00241   static TypeTo convert( const SLU::Z::doublecomplex t )
00242     {
00243       typedef typename TypeTo::value_type value_type;
00244       value_type ret_r = Teuchos::as<value_type>( t.r );
00245       value_type ret_i = Teuchos::as<value_type>( t.i );
00246       return ( TypeTo( ret_r, ret_i ) );
00247     }
00248 
00249   // No special checks for safe Convert
00250   static TypeTo safeConvert( const SLU::Z::doublecomplex t )
00251     {
00252       typedef typename TypeTo::value_type value_type;
00253       value_type ret_r = Teuchos::as<value_type>( t.r );
00254       value_type ret_i = Teuchos::as<value_type>( t.i );
00255       return ( TypeTo( ret_r, ret_i ) );
00256     }
00257 };
00258 
00259 template <typename Ordinal>
00260 class SerializationTraits<Ordinal,SLU::C::complex>
00261   : public DirectSerializationTraits<Ordinal,SLU::C::complex>
00262 {};
00263 
00264 template <typename Ordinal>
00265 class SerializationTraits<Ordinal,SLU::Z::doublecomplex>
00266   : public DirectSerializationTraits<Ordinal,SLU::Z::doublecomplex>
00267 {};
00268 
00270 
00271 } // end namespace Teuchos
00272 
00273 // C++-style output functions for Superlu complex types
00274 namespace std {
00275   ostream& operator<<(ostream& out, const SLU::Z::doublecomplex z);
00276 
00277   ostream& operator<<(ostream& out, const SLU::C::complex c);
00278 }
00279 
00280 #endif  // HAVE_TEUCHOS_COMPLEX
00281 
00282 
00283 namespace Amesos2 {
00284 
00285 template <class, class> class Superlu;
00286 
00287 /* Specialize the Amesos2::TypeMap struct for Superlu types
00288  *
00289  * \cond Superlu_type_specializations
00290  */
00291 template <>
00292 struct TypeMap<Superlu,float>
00293 {
00294   static SLU::Dtype_t dtype;
00295   typedef float type;
00296   typedef float magnitude_type;
00297 };
00298 
00299 
00300 template <>
00301 struct TypeMap<Superlu,double>
00302 {
00303   static SLU::Dtype_t dtype;
00304   typedef double type;
00305   typedef double magnitude_type;
00306 };
00307 
00308 
00309 #ifdef HAVE_TEUCHOS_COMPLEX
00310 
00311 template <>
00312 struct TypeMap<Superlu,std::complex<float> >
00313 {
00314   static SLU::Dtype_t dtype;
00315   typedef SLU::C::complex type;
00316   typedef float magnitude_type;
00317 };
00318 
00319 
00320 template <>
00321 struct TypeMap<Superlu,std::complex<double> >
00322 {
00323   static SLU::Dtype_t dtype;
00324   typedef SLU::Z::doublecomplex type;
00325   typedef double magnitude_type;
00326 };
00327 
00328 
00329 template <>
00330 struct TypeMap<Superlu,SLU::C::complex>
00331 {
00332   static SLU::Dtype_t dtype;
00333   typedef SLU::C::complex type;
00334   typedef float magnitude_type;
00335 };
00336 
00337 
00338 template <>
00339 struct TypeMap<Superlu,SLU::Z::doublecomplex>
00340 {
00341   static SLU::Dtype_t dtype;
00342   typedef SLU::Z::doublecomplex type;
00343   typedef double magnitude_type;
00344 };
00345 
00346 
00347 #endif  // HAVE_TEUCHOS_COMPLEX
00348 
00349 /* \endcond Superlu_type_specializations */
00350 
00351 
00352 } // end namespace Amesos2
00353 
00354 #endif  // AMESOS2_SUPERLU_TYPEMAP_HPP