MeshKit  1.0
TriharmonicRBF.cpp
Go to the documentation of this file.
00001 #include "TriharmonicRBF.hpp"
00002 #include <iostream>
00003 #include <math.h>
00004 #include <map>
00005 
00006 #ifdef HAVE_OPENBLAS
00007 extern "C" void openblas_set_num_threads(int);
00008 #endif
00009 
00010 
00011 namespace MeshKit {
00012 
00013 TriharmonicRBF::TriharmonicRBF(vector<vector<double> > undeformed_cage_vertices, vector<vector<double> > deformed_cage_vertices, vector<vector<int> > t_cage_faces)
00014 {
00015     num_vertices = undeformed_cage_vertices.size();
00016     //pass the data
00017     un_cage_vertices.resize(num_vertices);
00018     cage_vertices.resize(num_vertices);
00019     for (unsigned int i = 0; i < num_vertices; i++){
00020         un_cage_vertices[i].resize(3);
00021         cage_vertices[i].resize(3);
00022         for (int j = 0; j < 3; j++){
00023             un_cage_vertices[i][j] = undeformed_cage_vertices[i][j];
00024             cage_vertices[i][j] = deformed_cage_vertices[i][j];
00025         }
00026     }
00027     
00028 }
00029 
00030 void TriharmonicRBF::SetupInteriorNodes(vector<vector<double> > undeformed_in_nodes)
00031 {
00032     num_interior = undeformed_in_nodes.size();
00033     un_InnerNodes.resize(num_interior);
00034     InnerNodes.resize(num_interior);
00035     for (unsigned int i = 0; i < undeformed_in_nodes.size(); i++){
00036         un_InnerNodes[i].resize(3);
00037         InnerNodes[i].resize(3);
00038         for (int j = 0; j < 3; j++){
00039             un_InnerNodes[i][j]=undeformed_in_nodes[i][j];
00040         }
00041     }
00042     
00043 }
00044 void TriharmonicRBF::GetInteriorNodes(vector<vector<double> > &final_locations)
00045 {
00046    for (unsigned int i = 0; i < InnerNodes.size(); i++){
00047         for (unsigned int j = 0; j < InnerNodes[i].size(); j++){
00048             final_locations[i][j] = InnerNodes[i][j];
00049         }
00050    }
00051 }
00052 
00053 void TriharmonicRBF::Execute()
00054 {
00055     const unsigned int vertex_size = un_cage_vertices.size();
00056     const unsigned int tmp_var = vertex_size + 4;
00057     
00058     mat A = zeros<mat>(vertex_size+4,vertex_size+4);
00059     //mat::fixed<tmp_var,tmp_var> A;
00060     //A.zeros();
00061     /**************************/
00062     /*      |   G       H |      */
00063     /*  A = |             |      */                            
00064     /*      |   H'      0 |      */                            
00065     /*****************************/
00066     //Assign H and H'
00067     for (unsigned int j = 0; j < vertex_size; j++){
00068         A(j,vertex_size) = 1.0;
00069         A(j,vertex_size+1) = un_cage_vertices[j][0];
00070         A(j,vertex_size+2) = un_cage_vertices[j][1];
00071         A(j,vertex_size+3) = un_cage_vertices[j][2];
00072         A(vertex_size,j) = 1.0;
00073         A(vertex_size+1,j) = un_cage_vertices[j][0];
00074         A(vertex_size+2,j) = un_cage_vertices[j][1];
00075         A(vertex_size+3,j) = un_cage_vertices[j][2];
00076     }
00077         
00078     //assign G
00079     for (unsigned int i = 0; i < vertex_size; i++){
00080         for (unsigned int j = 0; j < vertex_size; j++){
00081             A(i,j) = TriHarmonicFun(un_cage_vertices[i], un_cage_vertices[j]);
00082         }
00083     }
00084     //done with the big matrix A
00085     //set up the displacement in x direction
00086     mat b=zeros<mat>(vertex_size+4,3);
00087     //mat::fixed<tmp_var,3> b;
00088     //b.zeros();
00089     for (unsigned int i = 0; i < vertex_size; i++)
00090         b(i,0) = cage_vertices[i][0] - un_cage_vertices[i][0];
00091     //solve the linear equations: least-squares solving with a SVD decomposition.
00092     //Eigen provides one as the JacobiSVD class and its solve() is doing least-square solving
00093     //MatrixXf coeffs_x = A.jacobiSvd(ComputeThinU | ComputeThinV).solve(b);
00094     for (unsigned int i = 0; i < vertex_size; i++)
00095         b(i,1) = cage_vertices[i][1] - un_cage_vertices[i][1];
00096     //solve the linear equations
00097     //MatrixXf coeffs_y = A.jacobiSvd(ComputeThinU | ComputeThinV).solve(b);
00098 
00099     //set up the displacement in z direction
00100     for (unsigned int i = 0; i < vertex_size; i++)
00101         b(i,2) = cage_vertices[i][2] - un_cage_vertices[i][2];
00102     //solve the linear equations
00103     //MatrixXf coeffs_z = A.jacobiSvd(ComputeThinU | ComputeThinV).solve(b);
00104     //MatrixXf coeffs_z = A.householderQr().solve(b);
00105     std::cout << "Matrix size is " << vertex_size+4 << "*" << vertex_size+4 << "\n";
00106 #ifdef HAVE_OPENBLAS
00107     openblas_set_num_threads(4);
00108 #endif
00109     mat coeffs = solve(A,b);
00110     //MatrixXf coeffs = A.jacobiSvd(ComputeThinU | ComputeThinV).solve(b);
00111     
00112 
00113     //compute the displacement in x direction for interior nodes
00114     for (unsigned int i = 0; i < num_interior; i++){
00115         InnerNodes[i][0] = un_InnerNodes[i][0] + InterpolatedFun(un_InnerNodes[i], coeffs.col(0));
00116         InnerNodes[i][1] = un_InnerNodes[i][1] + InterpolatedFun(un_InnerNodes[i], coeffs.col(1));
00117         InnerNodes[i][2] = un_InnerNodes[i][2] + InterpolatedFun(un_InnerNodes[i], coeffs.col(2));
00118     }
00119     
00120 }
00121 
00122 double TriharmonicRBF::InterpolatedFun(vector<double> x, vec coeffs)
00123 {
00124     double tmp = 0.0;
00125     double tmp_variable[4] = {1.0, x[0], x[1], x[2]};
00126     for (unsigned int i = 0; i < num_vertices; i++)
00127             tmp += coeffs(i,0)*TriHarmonicFun(x, un_cage_vertices[i]);
00128     for (int i = 0; i < 4; i++)
00129             tmp += coeffs(num_vertices+i,0)*tmp_variable[i];
00130 
00131     return tmp;
00132 }
00133 
00134 double TriharmonicRBF::TriHarmonicFun(vector<double> xi, vector<double> xj)
00135 {
00136     double value = 0.0;
00137     double delta = pow((xi[0] - xj[0]),2) + pow((xi[1] - xj[1]),2) + pow((xi[2] - xj[2]),2);
00138     //value = sqrt(log10(delta+1));
00139     //value = pow(delta, 0.5);
00140     //double a = 1.0e-3;
00141     //value = 1.0/sqrt(a*a+delta);
00142     // value = sqrt(a*a+delta);
00143     //value = exp(-1.0*delta);
00144     value = pow(delta, 1.5);
00145     return value;
00146 }
00147 
00148 TriharmonicRBF::~TriharmonicRBF()
00149 {
00150         cout << "It is over now in calculating the TriHarmonic" << endl;
00151 }
00152 
00153 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines