PetscVecTools.cpp

00001 /*
00002 
00003 Copyright (C) University of Oxford, 2005-2011
00004 
00005 University of Oxford means the Chancellor, Masters and Scholars of the
00006 University of Oxford, having an administrative office at Wellington
00007 Square, Oxford OX1 2JD, UK.
00008 
00009 This file is part of Chaste.
00010 
00011 Chaste is free software: you can redistribute it and/or modify it
00012 under the terms of the GNU Lesser General Public License as published
00013 by the Free Software Foundation, either version 2.1 of the License, or
00014 (at your option) any later version.
00015 
00016 Chaste is distributed in the hope that it will be useful, but WITHOUT
00017 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00018 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
00019 License for more details. The offer of Chaste under the terms of the
00020 License is subject to the License being interpreted in accordance with
00021 English Law and subject to any action against the University of Oxford
00022 being under the jurisdiction of the English Courts.
00023 
00024 You should have received a copy of the GNU Lesser General Public License
00025 along with Chaste. If not, see <http://www.gnu.org/licenses/>.
00026 
00027 */
00028 
00029 #include "PetscVecTools.hpp"
00030 #include "PetscTools.hpp"
00031 #include <petscviewer.h>
00032 #include <cassert>
00033 #include "DistributedVectorFactory.hpp"
00034 #include "DistributedVector.hpp"
00035 #include "PetscException.hpp"
00036 
00038 // Implementation
00040 
00041 void PetscVecTools::Finalise(Vec vector)
00042 {
00043     VecAssemblyBegin(vector);
00044     VecAssemblyEnd(vector);
00045 }
00046 
00047 void PetscVecTools::SetElement(Vec vector, PetscInt row, double value)
00048 {
00049     PetscInt lo, hi;
00050     GetOwnershipRange(vector, lo, hi);
00051 
00052     if (row >= lo && row < hi)
00053     {
00054         VecSetValues(vector, 1, &row, &value, INSERT_VALUES);
00055     }
00056 }
00057 
00058 void PetscVecTools::AddToElement(Vec vector, PetscInt row, double value)
00059 {
00060     PetscInt lo, hi;
00061     GetOwnershipRange(vector, lo, hi);
00062 
00063     if (row >= lo && row < hi)
00064     {
00065         VecSetValues(vector, 1, &row, &value, ADD_VALUES);
00066     }
00067 }
00068 
00069 void PetscVecTools::Display(Vec vector)
00070 {
00071     VecView(vector, PETSC_VIEWER_STDOUT_WORLD);
00072 }
00073 
00074 void PetscVecTools::Zero(Vec vector)
00075 {
00076 #if (PETSC_VERSION_MAJOR == 2 && PETSC_VERSION_MINOR == 2) //PETSc 2.2
00077     PetscScalar zero = 0.0;
00078     VecSet(&zero, vector);
00079 #else
00080     VecZeroEntries(vector);
00081 #endif
00082 }
00083 
00084 unsigned PetscVecTools::GetSize(Vec vector)
00085 {
00086     PetscInt size;
00087     VecGetSize(vector, &size);
00088     return (unsigned) size;
00089 }
00090 
00091 void PetscVecTools::GetOwnershipRange(Vec vector, PetscInt& lo, PetscInt& hi)
00092 {
00093     VecGetOwnershipRange(vector, &lo, &hi);
00094 }
00095 
00096 double PetscVecTools::GetElement(Vec vector, PetscInt row)
00097 {
00098     PetscInt lo, hi;
00099     GetOwnershipRange(vector, lo, hi);
00100     assert(lo <= row && row < hi);
00101 
00102     double* p_vector;
00103     PetscInt local_index = row-lo;
00104     VecGetArray(vector, &p_vector);
00105     double answer = p_vector[local_index];
00106     VecRestoreArray(vector, &p_vector);
00107 
00108     return answer;
00109 }
00110 
00111 void PetscVecTools::AddScaledVector(Vec y, Vec x, double scaleFactor)
00112 {
00113 #if (PETSC_VERSION_MAJOR == 2 && PETSC_VERSION_MINOR == 2) //PETSc 2.2
00114     VecAXPY(&scaleFactor, x, y);
00115 #else
00116     VecAXPY(y, scaleFactor, x);
00117 #endif
00118 }
00119 
00120 void PetscVecTools::Scale(Vec vector, double scaleFactor)
00121 {
00122 #if (PETSC_VERSION_MAJOR == 2 && PETSC_VERSION_MINOR == 2) //PETSc 2.2
00123     PETSCEXCEPT( VecScale(&scaleFactor, vector) );
00124 #else
00125     PETSCEXCEPT( VecScale(vector, scaleFactor) );
00126 #endif
00127 }
00128 
00129 void PetscVecTools::WAXPY(Vec w, double a, Vec x, Vec y)
00130 {
00131 #if (PETSC_VERSION_MAJOR == 2 && PETSC_VERSION_MINOR == 2) //PETSc 2.2
00132     PETSCEXCEPT( VecWAXPY(&a, x, y, w) );
00133 #else
00134     PETSCEXCEPT( VecWAXPY(w, a, x, y) );
00135 #endif
00136 }
00137 
00138 void PetscVecTools::SetupInterleavedVectorScatterGather(Vec interleavedVec, VecScatter& rFirstVariableScatterContext, VecScatter& rSecondVariableScatterContext)
00139 {
00140     PetscInt num_rows, num_local_rows;
00141 
00142     VecGetSize(interleavedVec, &num_rows);
00143     VecGetLocalSize(interleavedVec, &num_local_rows);
00144 
00145     IS A11_rows, A22_rows;
00146     ISCreateStride(PETSC_COMM_WORLD, num_rows/2, 0, 2, &A11_rows);
00147     ISCreateStride(PETSC_COMM_WORLD, num_rows/2, 1, 2, &A22_rows);
00148 
00149     IS all_vector;
00150     ISCreateStride(PETSC_COMM_WORLD, num_rows/2, 0, 1, &all_vector);
00151 
00152     unsigned subvector_num_rows = num_rows/2;
00153     unsigned subvector_local_rows = num_local_rows/2;
00154     Vec x1_subvector = PetscTools::CreateVec(subvector_num_rows, subvector_local_rows);
00155     Vec x2_subvector = PetscTools::CreateVec(subvector_num_rows, subvector_local_rows);
00156 
00157     VecScatterCreate(interleavedVec, A11_rows, x1_subvector, all_vector, &rFirstVariableScatterContext);
00158     VecScatterCreate(interleavedVec, A22_rows, x2_subvector, all_vector, &rSecondVariableScatterContext);
00159 
00160     VecDestroy(x1_subvector);
00161     VecDestroy(x2_subvector);
00162 
00163     ISDestroy(A11_rows);
00164     ISDestroy(A22_rows);
00165     ISDestroy(all_vector);
00166 }
00167 
00168 void PetscVecTools::DoInterleavedVecScatter(Vec interleavedVec, VecScatter firstVariableScatterContext, Vec firstVariableVec, VecScatter secondVariableScatterContefirstVariableScatterContextt, Vec secondVariableVec)
00169 {
00170     PetscScalar *p_interleaved_vec;
00171     PetscScalar *p_1st_variable_vec;
00172     PetscScalar *p_2nd_variable_vec;
00173 
00174     VecGetArray(interleavedVec, &p_interleaved_vec);
00175     VecGetArray(firstVariableVec, &p_1st_variable_vec);
00176     VecGetArray(secondVariableVec, &p_2nd_variable_vec);
00177 
00178     PetscInt vec_local_size;
00179     VecGetLocalSize(interleavedVec, &vec_local_size);
00180     assert(vec_local_size%2 == 0);
00181 
00182     for (PetscInt local_index=0; local_index<vec_local_size/2; local_index++)
00183     {
00184         p_1st_variable_vec[local_index] = p_interleaved_vec[2*local_index];
00185         p_2nd_variable_vec[local_index] = p_interleaved_vec[2*local_index+1];
00186     }
00187 
00188     VecRestoreArray(interleavedVec, &p_interleaved_vec);
00189     VecRestoreArray(firstVariableVec, &p_1st_variable_vec);
00190     VecRestoreArray(secondVariableVec, &p_2nd_variable_vec);
00191 
00192 //    DistributedVectorFactory factory(vec_size/2);
00193 //
00194 //    DistributedVector dist_inter_vec = factory.CreateDistributedVector(interleavedVec);
00195 //    DistributedVector::Stripe dist_inter_vec_1st_var(dist_inter_vec, 0);
00196 //    DistributedVector::Stripe dist_inter_vec_2nd_var(dist_inter_vec, 1);
00197 //
00198 //    DistributedVector dist_1st_var_vec = factory.CreateDistributedVector(firstVariableVec);
00199 //    DistributedVector dist_2nd_var_vec = factory.CreateDistributedVector(secondVariableVec);
00200 //
00201 //    for (DistributedVector::Iterator index = dist_1st_var_vec.Begin();
00202 //         index!= dist_1st_var_vec.End();
00203 //         ++index)
00204 //    {
00205 //        dist_1st_var_vec[index] = dist_inter_vec_1st_var[index];
00206 //        dist_2nd_var_vec[index] = dist_inter_vec_2nd_var[index];
00207 //    }
00208 
00209 
00210 //    //PETSc-3.x.x or PETSc-2.3.3
00211 //    #if ( (PETSC_VERSION_MAJOR == 3) || (PETSC_VERSION_MAJOR == 2 && PETSC_VERSION_MINOR == 3 && PETSC_VERSION_SUBMINOR == 3)) //2.3.3 or 3.x.x
00212 //        VecScatterBegin(firstVariableScatterContext, interleavedVec, firstVariableVec, INSERT_VALUES, SCATTER_FORWARD);
00213 //        VecScatterEnd(firstVariableScatterContext, interleavedVec, firstVariableVec, INSERT_VALUES, SCATTER_FORWARD);
00214 //    #else
00215 //        VecScatterBegin(interleavedVec, firstVariableVec, INSERT_VALUES, SCATTER_FORWARD, firstVariableScatterContext);
00216 //        VecScatterEnd(interleavedVec, firstVariableVec, INSERT_VALUES, SCATTER_FORWARD, firstVariableScatterContext);
00217 //    #endif
00218 //
00219 //    //PETSc-3.x.x or PETSc-2.3.3
00220 //    #if ( (PETSC_VERSION_MAJOR == 3) || (PETSC_VERSION_MAJOR == 2 && PETSC_VERSION_MINOR == 3 && PETSC_VERSION_SUBMINOR == 3)) //2.3.3 or 3.x.x
00221 //        VecScatterBegin(secondVariableScatterContefirstVariableScatterContextt, interleavedVec, secondVariableVec, INSERT_VALUES, SCATTER_FORWARD);
00222 //        VecScatterEnd(secondVariableScatterContefirstVariableScatterContextt, interleavedVec, secondVariableVec, INSERT_VALUES, SCATTER_FORWARD);
00223 //    #else
00224 //        VecScatterBegin(interleavedVec, secondVariableVec, INSERT_VALUES, SCATTER_FORWARD, secondVariableScatterContefirstVariableScatterContextt);
00225 //        VecScatterEnd(interleavedVec, secondVariableVec, INSERT_VALUES, SCATTER_FORWARD, secondVariableScatterContefirstVariableScatterContextt);
00226 //   #endif
00227 }
00228 
00229 void PetscVecTools::DoInterleavedVecGather(Vec interleavedVec, VecScatter firstVariableScatterContext, Vec firstVariableVec, VecScatter secondVariableScatterContext, Vec secondVariableVec)
00230 {
00231     PetscScalar *p_interleaved_vec;
00232     PetscScalar *p_1st_variable_vec;
00233     PetscScalar *p_2nd_variable_vec;
00234 
00235     VecGetArray(interleavedVec, &p_interleaved_vec);
00236     VecGetArray(firstVariableVec, &p_1st_variable_vec);
00237     VecGetArray(secondVariableVec, &p_2nd_variable_vec);
00238 
00239     PetscInt vec_local_size;
00240     VecGetLocalSize(interleavedVec, &vec_local_size);
00241     assert(vec_local_size%2 == 0);
00242 
00243     for (PetscInt local_index=0; local_index<vec_local_size/2; local_index++)
00244     {
00245         p_interleaved_vec[2*local_index] = p_1st_variable_vec[local_index];
00246         p_interleaved_vec[2*local_index+1] = p_2nd_variable_vec[local_index];
00247     }
00248 
00249     VecRestoreArray(interleavedVec, &p_interleaved_vec);
00250     VecRestoreArray(firstVariableVec, &p_1st_variable_vec);
00251     VecRestoreArray(secondVariableVec, &p_2nd_variable_vec);
00252 
00253 //#if ( (PETSC_VERSION_MAJOR == 3) || (PETSC_VERSION_MAJOR == 2 && PETSC_VERSION_MINOR == 3 && PETSC_VERSION_SUBMINOR == 3)) //2.3.3 or 3.x.x
00254 //    VecScatterBegin(firstVariableScatterContext, firstVariableVec, interleavedVec, INSERT_VALUES, SCATTER_REVERSE);
00255 //    VecScatterEnd(firstVariableScatterContext, firstVariableVec, interleavedVec, INSERT_VALUES, SCATTER_REVERSE);
00256 //#else
00257 //    VecScatterBegin(firstVariableVec, interleavedVec, INSERT_VALUES, SCATTER_REVERSE, firstVariableScatterContext);
00258 //    VecScatterEnd(firstVariableVec, interleavedVec, INSERT_VALUES, SCATTER_REVERSE, firstVariableScatterContext);
00259 //#endif
00260 //
00262 //#if ( (PETSC_VERSION_MAJOR == 3) || (PETSC_VERSION_MAJOR == 2 && PETSC_VERSION_MINOR == 3 && PETSC_VERSION_SUBMINOR == 3)) //2.3.3 or 3.x.x
00263 //    VecScatterBegin(secondVariableScatterContext, secondVariableVec, interleavedVec, INSERT_VALUES, SCATTER_REVERSE);
00264 //    VecScatterEnd(secondVariableScatterContext, secondVariableVec, interleavedVec, INSERT_VALUES, SCATTER_REVERSE);
00265 //#else
00266 //    VecScatterBegin(secondVariableVec, interleavedVec, INSERT_VALUES, SCATTER_REVERSE, secondVariableScatterContext);
00267 //    VecScatterEnd(secondVariableVec, interleavedVec, INSERT_VALUES, SCATTER_REVERSE, secondVariableScatterContext);
00268 //#endif
00269 }
Generated on Thu Dec 22 13:00:07 2011 for Chaste by  doxygen 1.6.3