MeshKit
1.0
|
00001 #include "IsoLaplace.hpp" 00002 #include <algorithm> 00003 00004 00005 //---------------------------------------------------------------------------// 00006 // construction function for IsoLaplace class 00007 IsoLaplace::IsoLaplace() 00008 { 00009 00010 00011 } 00012 00013 00014 00015 //---------------------------------------------------------------------------// 00016 // deconstruction function for IsoLaplace class 00017 IsoLaplace::~IsoLaplace() 00018 { 00019 00020 } 00021 00022 //setup the data for IsoLaplace 00023 void IsoLaplace::SetupData(std::vector<std::set<int> > AdjElements, std::vector<std::vector<int> > Quads, std::vector<std::vector<double> > coords, std::vector<bool> isBnd, std::vector<double> w) 00024 { 00025 //pass the node coordinates to the local variables 00026 coordinates.resize(coords.size()); 00027 for (unsigned int i = 0; i < coords.size(); i++){ 00028 coordinates[i].resize(coords[i].size()); 00029 for (unsigned int j = 0; j < coords[i].size(); j++) 00030 coordinates[i][j] = coords[i][j]; 00031 } 00032 00033 //pass the connectivity information to the local variables 00034 adjElements.resize(AdjElements.size()); 00035 for (unsigned int i = 0; i < AdjElements.size(); i++){ 00036 for (std::set<int>::iterator it = AdjElements[i].begin(); it != AdjElements[i].end(); it++) 00037 adjElements[i].insert(*it); 00038 } 00039 00040 quads.resize(Quads.size()); 00041 for (unsigned int i = 0; i < Quads.size(); i++){ 00042 quads[i].resize(Quads[i].size()); 00043 for (unsigned int j = 0; j < Quads[i].size(); j++) 00044 quads[i][j] = Quads[i][j]; 00045 } 00046 00047 //pass the boundary info to the local variables 00048 isBoundary.resize(isBnd.size()); 00049 for (unsigned int i = 0; i < isBnd.size(); i++) 00050 isBoundary[i] = isBnd[i]; 00051 00052 //pass the element's weight to the local variables 00053 weight.resize(w.size()); 00054 for (unsigned int i = 0; i < w.size(); i++) 00055 weight[i] = w[i]; 00056 //done 00057 } 00058 00059 //return the results 00060 void IsoLaplace::GetCoords(std::vector<std::vector<double> > &coords) 00061 { 00062 //return the results to the user 00063 coords.resize(coordinates.size()); 00064 for (unsigned int i = 0; i < coords.size(); i++){ 00065 if (!isBoundary[i]){ 00066 coords[i].resize(coordinates[i].size()); 00067 for (unsigned int j = 0; j < coordinates[i].size(); j++) 00068 coords[i][j] = coordinates[i][j]; 00069 } 00070 } 00071 } 00072 00073 //Execute function 00074 void IsoLaplace::Execute() 00075 { 00076 00077 //test the input 00078 for (unsigned int i = 0; i < coordinates.size(); i++){ 00079 if (!isBoundary[i]){ 00080 std::cout << "IsoLaplace index = " << i << "\t[" << coordinates[i][0] << ", " << coordinates[i][1] << ", " << coordinates[i][2] << "]\n"; 00081 std::cout << "\n\n"; 00082 } 00083 } 00084 std::cout << "test the adjacent element info\n"; 00085 for (unsigned int i = 0; i < adjElements.size(); i++){ 00086 std::set<int>::iterator it = adjElements[i].begin(); 00087 std::cout << "node index = " << i << "\t"; 00088 for (; it != adjElements[i].end(); it++) 00089 std::cout << *it << "\t"; 00090 std::cout << "\n"; 00091 } 00092 00093 std::cout << "test the quad info\n"; 00094 for (unsigned int i = 0; i < quads.size(); i++){ 00095 std::cout << "quad index = " << i << "\nthe adjacent nodes are "; 00096 for (unsigned int j = 0; j < quads[i].size(); j++){ 00097 std::cout << quads[i][j] << "\t"; 00098 } 00099 std::cout << std::endl; 00100 } 00101 std::cout << "test the weights\n"; 00102 for (unsigned int i = 0; i < weight.size(); i++){ 00103 std::cout << "index = " << i << "\tweight is " << weight[i] << std::endl; 00104 } 00105 00106 00107 00108 00109 double epilson = 0.01; 00110 double error = 0.0; 00111 int step = 0; 00112 double r = 0.1; 00113 while(true){ 00114 error = 0.0; 00115 //loop over all the nodes 00116 for (unsigned int i = 0; i < coordinates.size(); i++){ 00117 if (!(isBoundary[i])){ 00118 double sum_neighbors[3] = {0.0, 0.0, 0.0}; 00119 double sum_opposite[3] = {0.0, 0.0, 0.0}; 00120 double sum_weight = 0.0; 00121 //loop over the adjacent quads 00122 for (std::set<int>::iterator it = adjElements[i].begin(); it != adjElements[i].end(); it++){ 00123 int stNodeIndex = -1; 00124 if (int(i) == quads[*it][0]) 00125 stNodeIndex = 0; 00126 else if (int(i) == quads[*it][1]) 00127 stNodeIndex = 1; 00128 else if (int(i) == quads[*it][2]) 00129 stNodeIndex = 2; 00130 else 00131 stNodeIndex = 3; 00132 //sum up the neighbor nodes and opposite nodes 00133 for (int k = 0; k < 3; k++){ 00134 sum_neighbors[k] += weight[*it]*coordinates[quads[*it][(stNodeIndex+1)%4]][k]; 00135 sum_neighbors[k] += weight[*it]*coordinates[quads[*it][(stNodeIndex+3)%4]][k]; 00136 sum_opposite[k] += weight[*it]*r*coordinates[quads[*it][(stNodeIndex+2)%4]][k]; 00137 } 00138 sum_weight += weight[*it]; 00139 } 00140 double tmp[3]; 00141 double e = 0.0; 00142 //average the sum_neighbors and sum_opposite 00143 for (int k = 0; k < 3; k++){ 00144 sum_neighbors[k] = sum_neighbors[k]/sum_weight; 00145 sum_opposite[k] = sum_opposite[k]/sum_weight; 00146 } 00147 //update the node position and calculate the error 00148 for (int j = 0; j < 3; j++){ 00149 tmp[j] = (sum_neighbors[j] - sum_opposite[j])/(2-r); 00150 e += fabs(tmp[j] - coordinates[i][j]); 00151 coordinates[i][j] = tmp[j]; 00152 } 00153 if(e > error) 00154 error = e; 00155 } 00156 } 00157 step++; 00158 //UpdateWeight(); 00159 00160 std::cout << "IsoLaplace smoothing step = " << step << "\tError = " << error << std::endl; 00161 if (error < epilson) break; 00162 } 00163 00164 00165 for (unsigned int i = 0; i < coordinates.size(); i++){ 00166 if (!isBoundary[i]){ 00167 std::cout << "IsoLaplace index = " << i << "\t[" << coordinates[i][0] << ", " << coordinates[i][1] << ", " << coordinates[i][2] << "]\n"; 00168 std::cout << "\n\n"; 00169 } 00170 } 00171 00172 std::cout << std::endl; 00173 00174 } 00175 00176 void IsoLaplace::UpdateWeight(){ 00177 for (unsigned int i = 0; i < quads.size(); i++){ 00178 //calculate the area 00179 double a, b, c, s; 00180 weight[i] = 0.0; 00181 //calculate one half triangle 00182 a = sqrt(pow(coordinates[quads[i][0]][0] - coordinates[quads[i][1]][0], 2) + pow(coordinates[quads[i][0]][1] - coordinates[quads[i][1]][1],2) + pow(coordinates[quads[i][0]][2] - coordinates[quads[i][1]][2], 2)); 00183 b = sqrt(pow(coordinates[quads[i][0]][0] - coordinates[quads[i][2]][0], 2) + pow(coordinates[quads[i][0]][1] - coordinates[quads[i][2]][1],2) + pow(coordinates[quads[i][0]][2] - coordinates[quads[i][2]][2], 2)); 00184 c = sqrt(pow(coordinates[quads[i][1]][0] - coordinates[quads[i][2]][0], 2) + pow(coordinates[quads[i][1]][1] - coordinates[quads[i][2]][1],2) + pow(coordinates[quads[i][1]][2] - coordinates[quads[i][2]][2], 2)); 00185 s = 0.5*(a + b + c); 00186 weight[i] += sqrt(fabs(s*(s-a)*(s-b)*(s-c))); 00187 00188 //calculate the other half triangle 00189 a = sqrt(pow(coordinates[quads[i][0]][0] - coordinates[quads[i][3]][0], 2) + pow(coordinates[quads[i][0]][1] - coordinates[quads[i][3]][1],2) + pow(coordinates[quads[i][0]][2] - coordinates[quads[i][3]][2], 2)); 00190 b = sqrt(pow(coordinates[quads[i][3]][0] - coordinates[quads[i][2]][0], 2) + pow(coordinates[quads[i][3]][1] - coordinates[quads[i][2]][1],2) + pow(coordinates[quads[i][3]][2] - coordinates[quads[i][2]][2], 2)); 00191 c = sqrt(pow(coordinates[quads[i][1]][0] - coordinates[quads[i][2]][0], 2) + pow(coordinates[quads[i][1]][1] - coordinates[quads[i][2]][1],2) + pow(coordinates[quads[i][1]][2] - coordinates[quads[i][2]][2], 2)); 00192 s = 0.5*(a + b + c); 00193 weight[i] += sqrt(fabs(s*(s-a)*(s-b)*(s-c))); 00194 } 00195 } 00196