Chaste Release::3.1
|
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 "CompareHdf5ResultsFiles.hpp" 00037 00038 #include <iostream> 00039 #include <vector> 00040 #include "petscvec.h" 00041 #include "Hdf5DataReader.hpp" 00042 #include "DistributedVectorFactory.hpp" 00043 00044 bool CompareFilesViaHdf5DataReader(std::string pathname1, std::string filename1, bool makeAbsolute1, 00045 std::string pathname2, std::string filename2, bool makeAbsolute2, 00046 double tol) 00047 { 00048 Hdf5DataReader reader1(pathname1, filename1, makeAbsolute1); 00049 Hdf5DataReader reader2(pathname2, filename2, makeAbsolute2); 00050 00051 unsigned number_nodes1 = reader1.GetNumberOfRows(); 00052 unsigned number_nodes2 = reader2.GetNumberOfRows(); 00053 if (number_nodes1 != number_nodes2) 00054 { 00055 std::cout << "Number of nodes " << number_nodes1 << " and " << number_nodes2 << " don't match\n"; 00056 return false; 00057 } 00058 00059 // Check the variable names and units 00060 std::vector<std::string> variable_names1 = reader1.GetVariableNames(); 00061 std::vector<std::string> variable_names2 = reader2.GetVariableNames(); 00062 unsigned num_vars = variable_names1.size(); 00063 if (num_vars != variable_names2.size()) 00064 { 00065 std::cout << "Number of variables " << variable_names1.size() 00066 << " and " << variable_names2.size() << " don't match\n"; 00067 return false; 00068 } 00069 for (unsigned var=0; var<num_vars; var++) 00070 { 00071 std::string var_name = variable_names1[var]; 00072 if (var_name != variable_names2[var]) 00073 { 00074 std::cout << "Variable names " << var_name << " and " 00075 << variable_names2[var] << " don't match\n"; 00076 return false; 00077 } 00078 if (reader1.GetUnit(var_name) != reader2.GetUnit(var_name)) 00079 { 00080 std::cout << "Units names " << reader1.GetUnit(var_name) 00081 << " and " << reader2.GetUnit(var_name) << " don't match\n"; 00082 return false; 00083 } 00084 } 00085 00086 // Check the timestep vectors 00087 std::vector<double> times1 = reader1.GetUnlimitedDimensionValues(); 00088 std::vector<double> times2 = reader2.GetUnlimitedDimensionValues(); 00089 00090 if (times1.size() != times2.size()) 00091 { 00092 std::cout << "Number of time steps " << times1.size() 00093 << " and " << times2.size() << " don't match\n"; 00094 return false; 00095 } 00096 00097 for (unsigned timestep=0; timestep<times1.size(); timestep++) 00098 { 00100 if (fabs(times1[timestep]-times2[timestep]) > 1e-8) 00101 { 00102 std::cout << "Time steps " << times1[timestep] 00103 << " and " << times2[timestep] << " don't match\n"; 00104 return false; 00105 } 00106 } 00107 00108 bool is_complete1 = reader1.IsDataComplete(); 00109 bool is_complete2 = reader2.IsDataComplete(); 00110 00111 if (is_complete1 != is_complete2) 00112 { 00113 std::cout<<"One of the readers has incomplete data and the other doesn't\n"; 00114 return false; 00115 } 00116 00117 if (is_complete1) 00118 { 00119 DistributedVectorFactory factory(number_nodes1); 00120 00121 Vec data1 = factory.CreateVec(); 00122 Vec data2 = factory.CreateVec(); 00123 00124 for (unsigned timestep=0; timestep<times1.size(); timestep++) 00125 { 00126 for (unsigned var=0; var<num_vars; var++) 00127 { 00128 reader1.GetVariableOverNodes(data1, variable_names1[var], timestep); 00129 reader2.GetVariableOverNodes(data2, variable_names2[var], timestep); 00130 00131 #if (PETSC_VERSION_MAJOR == 2 && PETSC_VERSION_MINOR == 2) //PETSc 2.2 00132 double minus_one = -1.0; 00133 VecAXPY(&minus_one, data2, data1); 00134 #else 00135 //[note: VecAXPY(y,a,x) computes y = ax+y] 00136 VecAXPY(data1, -1.0, data2); 00137 #endif 00138 00139 PetscReal difference_norm; 00140 VecNorm(data1, NORM_2, &difference_norm); 00141 00142 if (difference_norm > tol) 00143 { 00144 std::cout << "Vectors differ in NORM_2 by " << difference_norm << std::endl; 00145 return false; 00146 } 00147 } 00148 } 00149 PetscTools::Destroy(data1); 00150 PetscTools::Destroy(data2); 00151 } 00152 else 00153 { 00154 // Incomplete data 00155 00156 // Check the index vectors 00157 std::vector<unsigned> indices1 = reader1.GetIncompleteNodeMap(); 00158 std::vector<unsigned> indices2 = reader2.GetIncompleteNodeMap(); 00159 00160 if (indices1.size() != indices2.size()) 00161 { 00162 std::cout << "Index map sizes " << indices1.size() << " and " << indices2.size() << " don't match\n"; 00163 return false; 00164 } 00165 00166 for (unsigned index=0; index<indices1.size(); index++) 00167 { 00168 if (indices1[index]!=indices2[index]) 00169 { 00170 std::cout << "Time steps " << indices1[index] << " and " << indices2[index] << " don't match\n"; 00171 return false; 00172 } 00173 } 00174 00175 // Check all the data 00176 for (unsigned index=0; index<indices1.size(); index++) 00177 { 00178 unsigned node_index = indices1[index]; 00179 for (unsigned var=0; var<num_vars; var++) 00180 { 00181 std::vector<double> var_over_time1 = reader1.GetVariableOverTime(variable_names1[var], node_index); 00182 std::vector<double> var_over_time2 = reader2.GetVariableOverTime(variable_names1[var], node_index); 00183 for (unsigned time_step=0;time_step< var_over_time1.size(); time_step++) 00184 { 00185 if (fabs(var_over_time1[time_step] - var_over_time2[time_step]) > tol) 00186 { 00187 std::cout<<"Node "<<node_index<<" at time step "<<time_step<<" variable "<<variable_names1[var]<< 00188 " differs ("<<var_over_time1[time_step]<<" != "<<var_over_time2[time_step]<<")\n"; 00189 return false; 00190 } 00191 } 00192 } 00193 } 00194 } 00195 return true; 00196 } 00197 00198 bool CompareFilesViaHdf5DataReaderGlobalNorm(std::string pathname1, std::string filename1, bool makeAbsolute1, 00199 std::string pathname2, std::string filename2, bool makeAbsolute2, 00200 double tol) 00201 { 00202 Hdf5DataReader reader1(pathname1, filename1, makeAbsolute1); 00203 Hdf5DataReader reader2(pathname2, filename2, makeAbsolute2); 00204 00205 unsigned number_nodes1 = reader1.GetNumberOfRows(); 00206 bool is_the_same = true; 00207 std::vector<std::string> variable_names1 = reader1.GetVariableNames(); 00208 std::vector<std::string> variable_names2 = reader2.GetVariableNames(); 00209 std::vector<double> times1 = reader1.GetUnlimitedDimensionValues(); 00210 unsigned num_vars = variable_names1.size(); 00211 DistributedVectorFactory factory(number_nodes1); 00212 00213 Vec data1 = factory.CreateVec(); 00214 Vec data2 = factory.CreateVec(); 00215 00216 for (unsigned timestep=0; timestep<times1.size(); timestep++) 00217 { 00218 for (unsigned var=0; var<num_vars; var++) 00219 { 00220 reader1.GetVariableOverNodes(data1, variable_names1[var], timestep); 00221 reader2.GetVariableOverNodes(data2, variable_names2[var], timestep); 00222 00223 PetscReal data1_norm; 00224 PetscReal data2_norm; 00225 VecNorm(data1, NORM_2, &data1_norm); 00226 VecNorm(data2, NORM_2, &data2_norm); 00227 PetscReal norm = fabs(data1_norm-data2_norm); 00228 if (norm > tol) 00229 { 00230 is_the_same = false; 00231 std::cout << "Vectors differ in global NORM_2 by " << norm << std::endl; 00232 } 00233 } 00234 } 00235 00236 PetscTools::Destroy(data1); 00237 PetscTools::Destroy(data2); 00238 00239 return is_the_same; 00240 }