![]() |
Mesh Oriented datABase
(version 5.4.1)
Array-based unstructured mesh datastructure
|
00001 // Copyright (c) 2010, Lawrence Livermore National Security, LLC. Produced at
00002 // the Lawrence Livermore National Laboratory. LLNL-CODE-443211. All Rights
00003 // reserved. See file COPYRIGHT for details.
00004 //
00005 // This file is part of the MFEM library. For more information and source code
00006 // availability see http://mfem.org.
00007 //
00008 // MFEM is free software; you can redistribute it and/or modify it under the
00009 // terms of the GNU Lesser General Public License (as published by the Free
00010 // Software Foundation) version 2.1 dated February 1999.
00011
00012 #include "HypreParVector.hpp"
00013 #include "HypreParMatrix.hpp"
00014
00015 #ifdef MOAB_HAVE_MPI
00016
00017 #include
00018 #include
00019 #include
00020 #include
00021 #include
00022
00023 using namespace std;
00024
00025 namespace moab
00026 {
00027 #define moab_hypre_assert( a, b ) \
00028 { \
00029 }
00030 #define moab_hypre_assert_t( a, b ) \
00031 { \
00032 if( !a ) \
00033 { \
00034 std::cout << "HYPRE Error: " << b << std::endl; \
00035 exit( -1 ); \
00036 }
00037
00038 HypreParVector::HypreParVector( moab::ParallelComm* p_comm ) : pcomm( p_comm )
00039 {
00040 x = NULL;
00041 initialized = size = gsize = rstart = rend = 0;
00042 }
00043
00044 HypreParVector::HypreParVector( moab::ParallelComm* p_comm,
00045 HYPRE_Int glob_size,
00046 HYPRE_Int p_irstart,
00047 HYPRE_Int p_irend )
00048 : rstart( p_irstart ), rend( p_irend ), pcomm( p_comm )
00049 {
00050 HYPRE_IJVectorCreate( pcomm->comm(), rstart, rend, &x );
00051 HYPRE_IJVectorSetObjectType( x, HYPRE_PARCSR );
00052 HYPRE_IJVectorInitialize( x );
00053 HYPRE_IJVectorAssemble( x );
00054 HYPRE_IJVectorGetObject( x, (void**)&x_par );
00055 size = rstart - rend;
00056 gsize = glob_size;
00057 own_ParVector = 1;
00058 initialized = 1;
00059 }
00060
00061 HypreParVector::HypreParVector( const HypreParVector& y )
00062 {
00063 pcomm = y.pcomm;
00064 rstart = y.rstart;
00065 rend = y.rend;
00066 size = y.size;
00067 gsize = y.gsize;
00068 HYPRE_IJVectorCreate( pcomm->comm(), y.rstart, y.rend, &x );
00069 HYPRE_IJVectorSetObjectType( x, HYPRE_PARCSR );
00070 HYPRE_IJVectorInitialize( x );
00071 HYPRE_IJVectorAssemble( x );
00072 HYPRE_IJVectorGetObject( x, (void**)&x_par );
00073 HYPRE_Complex* array = NULL;
00074 HYPRE_IJVectorGetValues( y.x, y.size, NULL, array );
00075 HYPRE_IJVectorSetValues( x, size, NULL, array );
00076 array = NULL;
00077 own_ParVector = 1;
00078 initialized = 1;
00079 }
00080
00081 HypreParVector::HypreParVector( HypreParMatrix& A, int tr )
00082 {
00083 pcomm = A.GetParallelCommunicator();
00084 int* part;
00085
00086 if( tr )
00087 {
00088 part = A.ColPart();
00089 }
00090 else
00091 part = A.RowPart();
00092
00093 HYPRE_IJVectorCreate( pcomm->comm(), part[0], part[1], &x );
00094 HYPRE_IJVectorSetObjectType( x, HYPRE_PARCSR );
00095 HYPRE_IJVectorInitialize( x );
00096 HYPRE_IJVectorAssemble( x );
00097 HYPRE_IJVectorGetObject( x, (void**)&x_par );
00098 // if (!tr)
00099 // {
00100 // x_par = hypre_ParVectorInDomainOf(static_cast(A.A_parcsr));
00101 // }
00102 // else
00103 // {
00104 // x_par = hypre_ParVectorInRangeOf(static_cast(A.A_parcsr));
00105 // }
00106 // comm = hypre_ParVectorComm(x);
00107 rstart = part[0];
00108 rend = part[1];
00109 size = rstart - rend;
00110 own_ParVector = 1;
00111 initialized = 1;
00112 }
00113
00114 HypreParVector::operator HYPRE_IJVector() const
00115 {
00116 return x;
00117 }
00118
00119 // #ifndef HYPRE_PAR_VECTOR_STRUCT
00120 HypreParVector::operator HYPRE_ParVector() const
00121 {
00122 return x_par;
00123 }
00124 // #endif
00125
00126 HypreParVector& HypreParVector::operator=( double d )
00127 {
00128 hypre_ParVectorSetConstantValues( x_par, d );
00129 return *this;
00130 }
00131
00132 HypreParVector& HypreParVector::operator=( const HypreParVector& y )
00133 {
00134 #ifndef NDEBUG
00135
00136 if( this->GlobalSize() != y.GlobalSize() )
00137 { // || local_size != y.local_size) {
00138 MB_SET_ERR_RET_VAL( "HypreParVector::operator failed. Incompatible vector sizes", *this );
00139 }
00140
00141 #endif
00142 pcomm = y.pcomm;
00143 rstart = y.rstart;
00144 rend = y.rend;
00145 size = y.size;
00146
00147 if( x )
00148 {
00149 HYPRE_IJVectorDestroy( x );
00150 }
00151
00152 x = y.x;
00153 x_par = y.x_par;
00154 own_ParVector = 0;
00155 initialized = y.initialized;
00156 return *this;
00157 }
00158
00159 HYPRE_Int HypreParVector::resize( HYPRE_Int /*glob_size*/, HYPRE_Int p_irstart, HYPRE_Int p_irend )
00160 {
00161 if( initialized || x != NULL ) MB_SET_ERR_RET_VAL( "Vector is already initialized and partitioned", -1 );
00162
00163 HYPRE_IJVectorCreate( this->pcomm->comm(), p_irstart, p_irend, &x );
00164 HYPRE_IJVectorSetObjectType( x, HYPRE_PARCSR );
00165 HYPRE_IJVectorInitialize( x );
00166 HYPRE_IJVectorAssemble( x );
00167 HYPRE_IJVectorGetObject( x, (void**)&x_par );
00168 rstart = p_irstart;
00169 rend = p_irend;
00170 size = rstart - rend;
00171 own_ParVector = 1;
00172 initialized = 1;
00173 return 0;
00174 }
00175
00176 HYPRE_Int HypreParVector::SetData( HYPRE_Complex* p_data, HYPRE_Int* p_col )
00177 {
00178 return HYPRE_IJVectorSetValues( x, size, p_col, p_data );
00179 }
00180
00181 HYPRE_Int HypreParVector::AddData( HYPRE_Complex* p_data, HYPRE_Int* p_col )
00182 {
00183 return HYPRE_IJVectorAddToValues( x, size, p_col, p_data );
00184 }
00185
00186 HYPRE_Int HypreParVector::GetValues( const int ndata, const HYPRE_Int* indices, HYPRE_Complex* const _data ) const
00187 {
00188 return HYPRE_IJVectorGetValues( x, ndata, indices, _data );
00189 }
00190
00191 HYPRE_Int HypreParVector::SetValues( const int ndata, const HYPRE_Int* indices, const HYPRE_Complex* const _data )
00192 {
00193 return HYPRE_IJVectorSetValues( x, ndata, indices, _data );
00194 }
00195
00196 HYPRE_Int HypreParVector::AddValues( const int ndata, const HYPRE_Int* indices, const HYPRE_Complex* const _data )
00197 {
00198 return HYPRE_IJVectorAddToValues( x, ndata, indices, _data );
00199 }
00200
00201 HYPRE_Int HypreParVector::GetValue( HYPRE_Int index, HYPRE_Complex* const _data ) const
00202 {
00203 return HYPRE_IJVectorGetValues( x, 1, &index, _data );
00204 }
00205
00206 HYPRE_Int HypreParVector::SetValue( const HYPRE_Int index, const HYPRE_Complex _data )
00207 {
00208 return HYPRE_IJVectorSetValues( x, 1, &index, &_data );
00209 }
00210
00211 HYPRE_Int HypreParVector::AddValue( const HYPRE_Int index, const HYPRE_Complex _data )
00212 {
00213 return HYPRE_IJVectorAddToValues( x, 1, &index, &_data );
00214 }
00215
00216 HYPRE_Int HypreParVector::FinalizeAssembly()
00217 {
00218 return HYPRE_IJVectorAssemble( x );
00219 }
00220
00221 HYPRE_Int HypreParVector::verbosity( const HYPRE_Int level )
00222 {
00223 return HYPRE_IJVectorSetPrintLevel( x, level );
00224 }
00225
00226 void HypreParVector::Print( const char* fname ) const
00227 {
00228 HYPRE_IJVectorPrint( x, fname );
00229 }
00230
00231 HypreParVector::~HypreParVector()
00232 {
00233 if( own_ParVector )
00234 {
00235 HYPRE_IJVectorDestroy( x );
00236 }
00237 }
00238
00239 double HypreParVector::InnerProduct( HypreParVector& x, HypreParVector& y )
00240 {
00241 return hypre_ParVectorInnerProd( x.x_par, y.x_par );
00242 }
00243
00244 } // namespace moab
00245
00246 #endif