$extrastylesheet
00001 // The libMesh Finite Element Library. 00002 // Copyright (C) 2002-2014 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner 00003 00004 // This library is free software; you can redistribute it and/or 00005 // modify it under the terms of the GNU Lesser General Public 00006 // License as published by the Free Software Foundation; either 00007 // version 2.1 of the License, or (at your option) any later version. 00008 00009 // This library is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 // Lesser General Public License for more details. 00013 00014 // You should have received a copy of the GNU Lesser General Public 00015 // License along with this library; if not, write to the Free Software 00016 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00017 00018 00019 00020 // C++ includes 00021 #include <algorithm> // for std::min 00022 #include <limits> 00023 00024 // Local Includes 00025 #include "libmesh/dense_subvector.h" 00026 #include "libmesh/dense_vector.h" 00027 #include "libmesh/laspack_vector.h" 00028 #include "libmesh/laspack_matrix.h" 00029 00030 00031 #ifdef LIBMESH_HAVE_LASPACK 00032 00033 namespace libMesh 00034 { 00035 00036 template <typename T> 00037 T LaspackVector<T>::sum () const 00038 { 00039 libmesh_assert (this->closed()); 00040 00041 T _sum = 0; 00042 00043 const numeric_index_type n = this->size(); 00044 00045 for (numeric_index_type i=0; i!=n; ++i) 00046 _sum += (*this)(i); 00047 00048 return _sum; 00049 } 00050 00051 00052 00053 template <typename T> 00054 Real LaspackVector<T>::l1_norm () const 00055 { 00056 libmesh_assert (this->closed()); 00057 00058 return static_cast<Real>(l1Norm_V(const_cast<QVector*>(&_vec))); 00059 } 00060 00061 00062 00063 template <typename T> 00064 Real LaspackVector<T>::l2_norm () const 00065 { 00066 libmesh_assert (this->closed()); 00067 00068 return static_cast<Real>(l2Norm_V(const_cast<QVector*>(&_vec))); 00069 } 00070 00071 00072 00073 template <typename T> 00074 Real LaspackVector<T>::linfty_norm () const 00075 { 00076 libmesh_assert (this->closed()); 00077 00078 return static_cast<Real>(MaxNorm_V(const_cast<QVector*>(&_vec))); 00079 } 00080 00081 00082 00083 template <typename T> 00084 NumericVector<T>& LaspackVector<T>::operator += (const NumericVector<T>& v) 00085 { 00086 libmesh_assert (this->closed()); 00087 00088 this->add(1., v); 00089 00090 return *this; 00091 } 00092 00093 00094 00095 00096 template <typename T> 00097 NumericVector<T>& LaspackVector<T>::operator -= (const NumericVector<T>& v) 00098 { 00099 libmesh_assert (this->closed()); 00100 00101 this->add(-1., v); 00102 00103 return *this; 00104 } 00105 00106 00107 00108 template <typename T> 00109 NumericVector<T> & LaspackVector<T>::operator /= (NumericVector<T> & v) 00110 { 00111 libmesh_assert_equal_to(size(), v.size()); 00112 00113 const numeric_index_type n = this->size(); 00114 00115 for (numeric_index_type i=0; i<n; i++) 00116 this->set(i, (*this)(i) / v(i)); 00117 00118 return *this; 00119 } 00120 00121 00122 00123 template <typename T> 00124 void LaspackVector<T>::reciprocal() 00125 { 00126 const numeric_index_type n = this->size(); 00127 00128 for (numeric_index_type i=0; i<n; i++) 00129 { 00130 T v = (*this)(i); 00131 00132 // Don't divide by zero! 00133 libmesh_assert_not_equal_to (v, T(0)); 00134 00135 this->set(i, 1. / v); 00136 } 00137 } 00138 00139 00140 00141 template <typename T> 00142 void LaspackVector<T>::conjugate() 00143 { 00144 const numeric_index_type n = this->size(); 00145 00146 for (numeric_index_type i=0; i<n; i++) 00147 { 00148 T v = (*this)(i); 00149 00150 this->set(i, libmesh_conj(v) ); 00151 } 00152 } 00153 00154 00155 template <typename T> 00156 void LaspackVector<T>::add (const T v) 00157 { 00158 const numeric_index_type n = this->size(); 00159 00160 for (numeric_index_type i=0; i<n; i++) 00161 this->add (i, v); 00162 00163 #ifndef NDEBUG 00164 this->_is_closed = false; 00165 #endif 00166 } 00167 00168 00169 00170 00171 template <typename T> 00172 void LaspackVector<T>::add (const NumericVector<T>& v) 00173 { 00174 this->add (1., v); 00175 } 00176 00177 00178 00179 template <typename T> 00180 void LaspackVector<T>::add (const T a, const NumericVector<T>& v_in) 00181 { 00182 // Make sure the vector passed in is really a LaspackVector 00183 const LaspackVector* v = cast_ptr<const LaspackVector*>(&v_in); 00184 00185 #ifndef NDEBUG 00186 const bool was_closed = this->_is_closed; 00187 #endif 00188 00189 libmesh_assert(v); 00190 libmesh_assert_equal_to (this->size(), v->size()); 00191 00192 for (numeric_index_type i=0; i<v->size(); i++) 00193 this->add (i, a*(*v)(i)); 00194 00195 #ifndef NDEBUG 00196 this->_is_closed = was_closed; 00197 #endif 00198 } 00199 00200 00201 00202 template <typename T> 00203 void LaspackVector<T>::add_vector (const NumericVector<T> &vec_in, 00204 const SparseMatrix<T> &mat_in) 00205 { 00206 // Make sure the data passed in are really in Laspack types 00207 const LaspackVector<T>* vec = cast_ptr<const LaspackVector<T>*>(&vec_in); 00208 const LaspackMatrix<T>* mat = cast_ptr<const LaspackMatrix<T>*>(&mat_in); 00209 00210 libmesh_assert(vec); 00211 libmesh_assert(mat); 00212 00213 // += mat*vec 00214 AddAsgn_VV (&_vec, Mul_QV(const_cast<QMatrix*>(&mat->_QMat), 00215 const_cast<QVector*>(&vec->_vec))); 00216 } 00217 00218 00219 template <typename T> 00220 void LaspackVector<T>::add_vector_transpose (const NumericVector<T> &, 00221 const SparseMatrix<T> &) 00222 { 00223 libmesh_not_implemented(); 00224 } 00225 00226 00227 00228 template <typename T> 00229 void LaspackVector<T>::scale (const T factor) 00230 { 00231 libmesh_assert (this->initialized()); 00232 00233 Asgn_VV(&_vec, Mul_SV (factor, &_vec)); 00234 } 00235 00236 template <typename T> 00237 void LaspackVector<T>::abs() 00238 { 00239 libmesh_assert (this->initialized()); 00240 00241 const numeric_index_type n = this->size(); 00242 00243 for (numeric_index_type i=0; i!=n; ++i) 00244 this->set(i,std::abs((*this)(i))); 00245 } 00246 00247 template <typename T> 00248 T LaspackVector<T>::dot (const NumericVector<T>& V) const 00249 { 00250 libmesh_assert (this->initialized()); 00251 00252 // Make sure the NumericVector passed in is really a LaspackVector 00253 const LaspackVector<T>* v = cast_ptr<const LaspackVector<T>*>(&V); 00254 libmesh_assert(v); 00255 00256 return Mul_VV (const_cast<QVector*>(&(this->_vec)), 00257 const_cast<QVector*>(&(v->_vec))); 00258 } 00259 00260 00261 00262 template <typename T> 00263 NumericVector<T>& 00264 LaspackVector<T>::operator = (const T s) 00265 { 00266 libmesh_assert (this->initialized()); 00267 libmesh_assert (this->closed()); 00268 00269 V_SetAllCmp (&_vec, s); 00270 00271 return *this; 00272 } 00273 00274 00275 00276 template <typename T> 00277 NumericVector<T>& 00278 LaspackVector<T>::operator = (const NumericVector<T>& v_in) 00279 { 00280 // Make sure the NumericVector passed in is really a LaspackVector 00281 const LaspackVector<T>* v = 00282 cast_ptr<const LaspackVector<T>*>(&v_in); 00283 00284 libmesh_assert(v); 00285 00286 *this = *v; 00287 00288 return *this; 00289 } 00290 00291 00292 00293 template <typename T> 00294 LaspackVector<T>& 00295 LaspackVector<T>::operator = (const LaspackVector<T>& v) 00296 { 00297 libmesh_assert (this->initialized()); 00298 libmesh_assert (v.closed()); 00299 libmesh_assert_equal_to (this->size(), v.size()); 00300 00301 if (v.size() != 0) 00302 Asgn_VV (const_cast<QVector*>(&_vec), 00303 const_cast<QVector*>(&v._vec) 00304 ); 00305 00306 #ifndef NDEBUG 00307 this->_is_closed = true; 00308 #endif 00309 00310 return *this; 00311 } 00312 00313 00314 00315 template <typename T> 00316 NumericVector<T>& 00317 LaspackVector<T>::operator = (const std::vector<T>& v) 00318 { 00323 if (this->size() == v.size()) 00324 for (numeric_index_type i=0; i<v.size(); i++) 00325 this->set (i, v[i]); 00326 00327 else 00328 libmesh_error_msg("this->size() = " << this->size() << " must be equal to v.size() = " << v.size()); 00329 00330 return *this; 00331 } 00332 00333 00334 template <typename T> 00335 void LaspackVector<T>::localize (NumericVector<T>& v_local_in) const 00336 { 00337 // Make sure the NumericVector passed in is really a LaspackVector 00338 LaspackVector<T>* v_local = 00339 cast_ptr<LaspackVector<T>*>(&v_local_in); 00340 00341 libmesh_assert(v_local); 00342 00343 *v_local = *this; 00344 } 00345 00346 00347 00348 template <typename T> 00349 void LaspackVector<T>::localize (NumericVector<T>& v_local_in, 00350 const std::vector<numeric_index_type>& libmesh_dbg_var(send_list)) const 00351 { 00352 // Make sure the NumericVector passed in is really a LaspackVector 00353 LaspackVector<T>* v_local = 00354 cast_ptr<LaspackVector<T>*>(&v_local_in); 00355 00356 libmesh_assert(v_local); 00357 libmesh_assert_less_equal (send_list.size(), v_local->size()); 00358 00359 *v_local = *this; 00360 } 00361 00362 00363 00364 template <typename T> 00365 void LaspackVector<T>::localize (const numeric_index_type libmesh_dbg_var(first_local_idx), 00366 const numeric_index_type libmesh_dbg_var(last_local_idx), 00367 const std::vector<numeric_index_type>& libmesh_dbg_var(send_list)) 00368 { 00369 libmesh_assert_equal_to (first_local_idx, 0); 00370 libmesh_assert_equal_to (last_local_idx+1, this->size()); 00371 00372 libmesh_assert_less_equal (send_list.size(), this->size()); 00373 00374 #ifndef NDEBUG 00375 this->_is_closed = true; 00376 #endif 00377 } 00378 00379 00380 00381 template <typename T> 00382 void LaspackVector<T>::localize (std::vector<T>& v_local) const 00383 00384 { 00385 v_local.resize(this->size()); 00386 00387 for (numeric_index_type i=0; i<v_local.size(); i++) 00388 v_local[i] = (*this)(i); 00389 } 00390 00391 00392 00393 template <typename T> 00394 void LaspackVector<T>::localize_to_one (std::vector<T>& v_local, 00395 const processor_id_type libmesh_dbg_var(pid)) const 00396 { 00397 libmesh_assert_equal_to (pid, 0); 00398 00399 this->localize (v_local); 00400 } 00401 00402 00403 00404 template <typename T> 00405 void LaspackVector<T>::pointwise_mult (const NumericVector<T>& /*vec1*/, 00406 const NumericVector<T>& /*vec2*/) 00407 { 00408 libmesh_not_implemented(); 00409 } 00410 00411 00412 00413 template <typename T> 00414 Real LaspackVector<T>::max() const 00415 { 00416 libmesh_assert (this->initialized()); 00417 if (!this->size()) 00418 return -std::numeric_limits<Real>::max(); 00419 00420 Real the_max = libmesh_real((*this)(0)); 00421 00422 const numeric_index_type n = this->size(); 00423 00424 for (numeric_index_type i=1; i<n; i++) 00425 the_max = std::max (the_max, libmesh_real((*this)(i))); 00426 00427 return the_max; 00428 } 00429 00430 00431 00432 template <typename T> 00433 Real LaspackVector<T>::min () const 00434 { 00435 libmesh_assert (this->initialized()); 00436 if (!this->size()) 00437 return std::numeric_limits<Real>::max(); 00438 00439 Real the_min = libmesh_real((*this)(0)); 00440 00441 const numeric_index_type n = this->size(); 00442 00443 for (numeric_index_type i=1; i<n; i++) 00444 the_min = std::min (the_min, libmesh_real((*this)(i))); 00445 00446 return the_min; 00447 } 00448 00449 00450 //------------------------------------------------------------------ 00451 // Explicit instantiations 00452 template class LaspackVector<Number>; 00453 00454 } // namespace libMesh 00455 00456 00457 #endif // #ifdef LIBMESH_HAVE_LASPACK