|
Amesos2 - Direct Sparse Solver Interfaces
Version of the Day
|
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
1.7.6.1