Chaste Release::3.1
PetscVecTools.cpp
00001 /*
00002 
00003 Copyright (c) 2005-2012, University of Oxford.
00004 All rights reserved.
00005 
00006 University of Oxford means the Chancellor, Masters and Scholars of the
00007 University of Oxford, having an administrative office at Wellington
00008 Square, Oxford OX1 2JD, UK.
00009 
00010 This file is part of Chaste.
00011 
00012 Redistribution and use in source and binary forms, with or without
00013 modification, are permitted provided that the following conditions are met:
00014  * Redistributions of source code must retain the above copyright notice,
00015    this list of conditions and the following disclaimer.
00016  * Redistributions in binary form must reproduce the above copyright notice,
00017    this list of conditions and the following disclaimer in the documentation
00018    and/or other materials provided with the distribution.
00019  * Neither the name of the University of Oxford nor the names of its
00020    contributors may be used to endorse or promote products derived from this
00021    software without specific prior written permission.
00022 
00023 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00024 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00025 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00026 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
00027 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00028 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
00029 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00030 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00031 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
00032 OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00033 
00034 */
00035 
00036 #include "PetscVecTools.hpp"
00037 #include "PetscTools.hpp"
00038 #include <petscviewer.h>
00039 #include <cassert>
00040 #include "DistributedVectorFactory.hpp"
00041 #include "DistributedVector.hpp"
00042 #include "PetscException.hpp"
00043 
00045 // Implementation
00047 
00048 void PetscVecTools::Finalise(Vec vector)
00049 {
00050     VecAssemblyBegin(vector);
00051     VecAssemblyEnd(vector);
00052 }
00053 
00054 void PetscVecTools::SetElement(Vec vector, PetscInt row, double value)
00055 {
00056     PetscInt lo, hi;
00057     GetOwnershipRange(vector, lo, hi);
00058 
00059     if (row >= lo && row < hi)
00060     {
00061         VecSetValues(vector, 1, &row, &value, INSERT_VALUES);
00062     }
00063 }
00064 
00065 void PetscVecTools::AddToElement(Vec vector, PetscInt row, double value)
00066 {
00067     PetscInt lo, hi;
00068     GetOwnershipRange(vector, lo, hi);
00069 
00070     if (row >= lo && row < hi)
00071     {
00072         VecSetValues(vector, 1, &row, &value, ADD_VALUES);
00073     }
00074 }
00075 
00076 void PetscVecTools::Display(Vec vector)
00077 {
00078     VecView(vector, PETSC_VIEWER_STDOUT_WORLD);
00079 }
00080 
00081 void PetscVecTools::Zero(Vec vector)
00082 {
00083 #if (PETSC_VERSION_MAJOR == 2 && PETSC_VERSION_MINOR == 2) //PETSc 2.2
00084     PetscScalar zero = 0.0;
00085     VecSet(&zero, vector);
00086 #else
00087     VecZeroEntries(vector);
00088 #endif
00089 }
00090 
00091 unsigned PetscVecTools::GetSize(Vec vector)
00092 {
00093     PetscInt size;
00094     VecGetSize(vector, &size);
00095     return (unsigned) size;
00096 }
00097 
00098 void PetscVecTools::GetOwnershipRange(Vec vector, PetscInt& lo, PetscInt& hi)
00099 {
00100     VecGetOwnershipRange(vector, &lo, &hi);
00101 }
00102 
00103 double PetscVecTools::GetElement(Vec vector, PetscInt row)
00104 {
00105     PetscInt lo, hi;
00106     GetOwnershipRange(vector, lo, hi);
00107     assert(lo <= row && row < hi);
00108 
00109     double* p_vector;
00110     PetscInt local_index = row-lo;
00111     VecGetArray(vector, &p_vector);
00112     double answer = p_vector[local_index];
00113     VecRestoreArray(vector, &p_vector);
00114 
00115     return answer;
00116 }
00117 
00118 void PetscVecTools::AddScaledVector(Vec y, Vec x, double scaleFactor)
00119 {
00120 #if (PETSC_VERSION_MAJOR == 2 && PETSC_VERSION_MINOR == 2) //PETSc 2.2
00121     VecAXPY(&scaleFactor, x, y);
00122 #else
00123     VecAXPY(y, scaleFactor, x);
00124 #endif
00125 }
00126 
00127 void PetscVecTools::Scale(Vec vector, double scaleFactor)
00128 {
00129 #if (PETSC_VERSION_MAJOR == 2 && PETSC_VERSION_MINOR == 2) //PETSc 2.2
00130     PETSCEXCEPT( VecScale(&scaleFactor, vector) );
00131 #else
00132     PETSCEXCEPT( VecScale(vector, scaleFactor) );
00133 #endif
00134 }
00135 
00136 void PetscVecTools::WAXPY(Vec w, double a, Vec x, Vec y)
00137 {
00138 #if (PETSC_VERSION_MAJOR == 2 && PETSC_VERSION_MINOR == 2) //PETSc 2.2
00139     PETSCEXCEPT( VecWAXPY(&a, x, y, w) );
00140 #else
00141     PETSCEXCEPT( VecWAXPY(w, a, x, y) );
00142 #endif
00143 }
00144 
00145 void PetscVecTools::SetupInterleavedVectorScatterGather(Vec interleavedVec, VecScatter& rFirstVariableScatterContext, VecScatter& rSecondVariableScatterContext)
00146 {
00147     PetscInt num_rows, num_local_rows;
00148 
00149     VecGetSize(interleavedVec, &num_rows);
00150     VecGetLocalSize(interleavedVec, &num_local_rows);
00151 
00152     IS A11_rows, A22_rows;
00153     ISCreateStride(PETSC_COMM_WORLD, num_rows/2, 0, 2, &A11_rows);
00154     ISCreateStride(PETSC_COMM_WORLD, num_rows/2, 1, 2, &A22_rows);
00155 
00156     IS all_vector;
00157     ISCreateStride(PETSC_COMM_WORLD, num_rows/2, 0, 1, &all_vector);
00158 
00159     unsigned subvector_num_rows = num_rows/2;
00160     unsigned subvector_local_rows = num_local_rows/2;
00161     Vec x1_subvector = PetscTools::CreateVec(subvector_num_rows, subvector_local_rows);
00162     Vec x2_subvector = PetscTools::CreateVec(subvector_num_rows, subvector_local_rows);
00163 
00164     VecScatterCreate(interleavedVec, A11_rows, x1_subvector, all_vector, &rFirstVariableScatterContext);
00165     VecScatterCreate(interleavedVec, A22_rows, x2_subvector, all_vector, &rSecondVariableScatterContext);
00166 
00167     PetscTools::Destroy(x1_subvector);
00168     PetscTools::Destroy(x2_subvector);
00169 
00170     ISDestroy(PETSC_DESTROY_PARAM(A11_rows));
00171     ISDestroy(PETSC_DESTROY_PARAM(A22_rows));
00172     ISDestroy(PETSC_DESTROY_PARAM(all_vector));
00173 }
00174 
00175 void PetscVecTools::DoInterleavedVecScatter(Vec interleavedVec, VecScatter firstVariableScatterContext, Vec firstVariableVec, VecScatter secondVariableScatterContefirstVariableScatterContextt, Vec secondVariableVec)
00176 {
00177     PetscScalar *p_interleaved_vec;
00178     PetscScalar *p_1st_variable_vec;
00179     PetscScalar *p_2nd_variable_vec;
00180 
00181     VecGetArray(interleavedVec, &p_interleaved_vec);
00182     VecGetArray(firstVariableVec, &p_1st_variable_vec);
00183     VecGetArray(secondVariableVec, &p_2nd_variable_vec);
00184 
00185     PetscInt vec_local_size;
00186     VecGetLocalSize(interleavedVec, &vec_local_size);
00187     assert(vec_local_size%2 == 0);
00188 
00189     for (PetscInt local_index=0; local_index<vec_local_size/2; local_index++)
00190     {
00191         p_1st_variable_vec[local_index] = p_interleaved_vec[2*local_index];
00192         p_2nd_variable_vec[local_index] = p_interleaved_vec[2*local_index+1];
00193     }
00194 
00195     VecRestoreArray(interleavedVec, &p_interleaved_vec);
00196     VecRestoreArray(firstVariableVec, &p_1st_variable_vec);
00197     VecRestoreArray(secondVariableVec, &p_2nd_variable_vec);
00198 
00199 //    DistributedVectorFactory factory(vec_size/2);
00200 //
00201 //    DistributedVector dist_inter_vec = factory.CreateDistributedVector(interleavedVec);
00202 //    DistributedVector::Stripe dist_inter_vec_1st_var(dist_inter_vec, 0);
00203 //    DistributedVector::Stripe dist_inter_vec_2nd_var(dist_inter_vec, 1);
00204 //
00205 //    DistributedVector dist_1st_var_vec = factory.CreateDistributedVector(firstVariableVec);
00206 //    DistributedVector dist_2nd_var_vec = factory.CreateDistributedVector(secondVariableVec);
00207 //
00208 //    for (DistributedVector::Iterator index = dist_1st_var_vec.Begin();
00209 //         index!= dist_1st_var_vec.End();
00210 //         ++index)
00211 //    {
00212 //        dist_1st_var_vec[index] = dist_inter_vec_1st_var[index];
00213 //        dist_2nd_var_vec[index] = dist_inter_vec_2nd_var[index];
00214 //    }
00215 
00216 
00217 //    //PETSc-3.x.x or PETSc-2.3.3
00218 //#if ( (PETSC_VERSION_MAJOR == 3) || (PETSC_VERSION_MAJOR == 2 && PETSC_VERSION_MINOR == 3 && PETSC_VERSION_SUBMINOR == 3)) //2.3.3 or 3.x.x
00219 //    VecScatterBegin(firstVariableScatterContext, interleavedVec, firstVariableVec, INSERT_VALUES, SCATTER_FORWARD);
00220 //    VecScatterEnd(firstVariableScatterContext, interleavedVec, firstVariableVec, INSERT_VALUES, SCATTER_FORWARD);
00221 //#else
00222 //    VecScatterBegin(interleavedVec, firstVariableVec, INSERT_VALUES, SCATTER_FORWARD, firstVariableScatterContext);
00223 //    VecScatterEnd(interleavedVec, firstVariableVec, INSERT_VALUES, SCATTER_FORWARD, firstVariableScatterContext);
00224 //#endif
00225 //
00226 //    //PETSc-3.x.x or PETSc-2.3.3
00227 //#if ( (PETSC_VERSION_MAJOR == 3) || (PETSC_VERSION_MAJOR == 2 && PETSC_VERSION_MINOR == 3 && PETSC_VERSION_SUBMINOR == 3)) //2.3.3 or 3.x.x
00228 //    VecScatterBegin(secondVariableScatterContefirstVariableScatterContextt, interleavedVec, secondVariableVec, INSERT_VALUES, SCATTER_FORWARD);
00229 //    VecScatterEnd(secondVariableScatterContefirstVariableScatterContextt, interleavedVec, secondVariableVec, INSERT_VALUES, SCATTER_FORWARD);
00230 //#else
00231 //    VecScatterBegin(interleavedVec, secondVariableVec, INSERT_VALUES, SCATTER_FORWARD, secondVariableScatterContefirstVariableScatterContextt);
00232 //    VecScatterEnd(interleavedVec, secondVariableVec, INSERT_VALUES, SCATTER_FORWARD, secondVariableScatterContefirstVariableScatterContextt);
00233 //#endif
00234 }
00235 
00236 void PetscVecTools::DoInterleavedVecGather(Vec interleavedVec, VecScatter firstVariableScatterContext, Vec firstVariableVec, VecScatter secondVariableScatterContext, Vec secondVariableVec)
00237 {
00238     PetscScalar *p_interleaved_vec;
00239     PetscScalar *p_1st_variable_vec;
00240     PetscScalar *p_2nd_variable_vec;
00241 
00242     VecGetArray(interleavedVec, &p_interleaved_vec);
00243     VecGetArray(firstVariableVec, &p_1st_variable_vec);
00244     VecGetArray(secondVariableVec, &p_2nd_variable_vec);
00245 
00246     PetscInt vec_local_size;
00247     VecGetLocalSize(interleavedVec, &vec_local_size);
00248     assert(vec_local_size%2 == 0);
00249 
00250     for (PetscInt local_index=0; local_index<vec_local_size/2; local_index++)
00251     {
00252         p_interleaved_vec[2*local_index] = p_1st_variable_vec[local_index];
00253         p_interleaved_vec[2*local_index+1] = p_2nd_variable_vec[local_index];
00254     }
00255 
00256     VecRestoreArray(interleavedVec, &p_interleaved_vec);
00257     VecRestoreArray(firstVariableVec, &p_1st_variable_vec);
00258     VecRestoreArray(secondVariableVec, &p_2nd_variable_vec);
00259 
00260 //#if ( (PETSC_VERSION_MAJOR == 3) || (PETSC_VERSION_MAJOR == 2 && PETSC_VERSION_MINOR == 3 && PETSC_VERSION_SUBMINOR == 3)) //2.3.3 or 3.x.x
00261 //    VecScatterBegin(firstVariableScatterContext, firstVariableVec, interleavedVec, INSERT_VALUES, SCATTER_REVERSE);
00262 //    VecScatterEnd(firstVariableScatterContext, firstVariableVec, interleavedVec, INSERT_VALUES, SCATTER_REVERSE);
00263 //#else
00264 //    VecScatterBegin(firstVariableVec, interleavedVec, INSERT_VALUES, SCATTER_REVERSE, firstVariableScatterContext);
00265 //    VecScatterEnd(firstVariableVec, interleavedVec, INSERT_VALUES, SCATTER_REVERSE, firstVariableScatterContext);
00266 //#endif
00267 //
00269 //#if ( (PETSC_VERSION_MAJOR == 3) || (PETSC_VERSION_MAJOR == 2 && PETSC_VERSION_MINOR == 3 && PETSC_VERSION_SUBMINOR == 3)) //2.3.3 or 3.x.x
00270 //    VecScatterBegin(secondVariableScatterContext, secondVariableVec, interleavedVec, INSERT_VALUES, SCATTER_REVERSE);
00271 //    VecScatterEnd(secondVariableScatterContext, secondVariableVec, interleavedVec, INSERT_VALUES, SCATTER_REVERSE);
00272 //#else
00273 //    VecScatterBegin(secondVariableVec, interleavedVec, INSERT_VALUES, SCATTER_REVERSE, secondVariableScatterContext);
00274 //    VecScatterEnd(secondVariableVec, interleavedVec, INSERT_VALUES, SCATTER_REVERSE, secondVariableScatterContext);
00275 //#endif
00276 }