MeshKit  1.0
IsoLaplace.cpp
Go to the documentation of this file.
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 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines