MeshKit
1.0
|
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 }