diff --git a/Common/OpenFile.cpp b/Common/OpenFile.cpp index 3f2adb4ccb17d7054117caba82df48437d7328ff..59a50d34a152b6e43028921561cb1c42d3d21ceb 100644 --- a/Common/OpenFile.cpp +++ b/Common/OpenFile.cpp @@ -202,7 +202,7 @@ void ParseString(std::string str) std::string fileName = CTX::instance()->homeDir + CTX::instance()->tmpFileName; FILE *fp = fopen(fileName.c_str(), "w"); if(fp){ - fprintf(fp, (str + "\n").c_str()); + fprintf(fp, "%s", (str + "\n").c_str()); fclose(fp); ParseFile(fileName, true); GModel::current()->importGEOInternals(); diff --git a/Geo/STensor3.cpp b/Geo/STensor3.cpp index 216c95517c26149293dee16f8a2518eac0fab005..bafc15d0aa2991ee6096ec7dc547fdb8408733ec 100644 --- a/Geo/STensor3.cpp +++ b/Geo/STensor3.cpp @@ -11,12 +11,11 @@ void SMetric3::print (const char *s) const SMetric3 intersection (const SMetric3 &m1, const SMetric3 &m2) { - SMetric3 im1 = m1.invert(); gmshMatrix<double> V(3,3); gmshVector<double> S(3); im1 *= m2; - im1.eig(V,S); + im1.eig(V,S,true); SVector3 v0(V(0,0),V(1,0),V(2,0)); SVector3 v1(V(0,1),V(1,1),V(2,1)); SVector3 v2(V(0,2),V(1,2),V(2,2)); @@ -57,3 +56,25 @@ SMetric3 interpolation (const SMetric3 &m1, return im1.invert(); } +SMetric3 interpolation (const SMetric3 &m1, + const SMetric3 &m2, + const SMetric3 &m3, + const SMetric3 &m4, + const double u, + const double v, + const double w) +{ + SMetric3 im1 = m1.invert(); + SMetric3 im2 = m2.invert(); + SMetric3 im3 = m3.invert(); + SMetric3 im4 = m4.invert(); + im1 *= (1.-u-v-w); + im2 *= u; + im3 *= v; + im4 *= w; + im1 += im2; + im1 += im3; + im1 += im4; + return im1.invert(); +} + diff --git a/Geo/STensor3.h b/Geo/STensor3.h index 40b29c703026b4ff39d7effbf89f6b6f09f5eb8b..b7b406b0be5af42e7a4c2cede10760dd7426d9ad 100644 --- a/Geo/STensor3.h +++ b/Geo/STensor3.h @@ -32,29 +32,69 @@ class SMetric3 { for (int j=i;j<3;j++) _val[getIndex(i,j)] = mat(i,j); } + SMetric3(const SMetric3& m){ + for (int i=0; i<6; i++) _val[i]=m._val[i]; + } // default constructor, identity SMetric3(const double v = 1.0){ - _val[0] = _val[2] = _val[5] = 1./(v*v); + _val[0] = _val[2] = _val[5] = v; _val[1] = _val[3] = _val[4] = 0.0; } - SMetric3(const double l1, +/* SMetric3(const double l1, // (h_1)^-2 */ +/* const double l2, */ +/* const double l3, */ +/* const SVector3 &t1, */ +/* const SVector3 &t2, */ +/* const SVector3 &t3){ */ +/* SVector3 t1b = t1; */ +/* SVector3 t2b = t2; */ +/* SVector3 t3b = t3; */ +/* t1b[0] *= l1; t2b[0] *= l1; t3b[0] *= l1; */ +/* t1b[1] *= l2; t2b[1] *= l2; t3b[1] *= l2; */ +/* t1b[2] *= l3; t2b[2] *= l3; t3b[2] *= l3; */ +/* _val[0] = dot (t1b,t1); */ +/* _val[1] = dot (t2b,t1); */ +/* _val[2] = dot (t2b,t2); */ +/* _val[3] = dot (t3b,t1); */ +/* _val[4] = dot (t3b,t2); */ +/* _val[5] = dot (t3b,t3); */ +/* } */ + SMetric3(const double l1, // l1 = h1^-2 const double l2, const double l3, const SVector3 &t1, const SVector3 &t2, - const SVector3 &t3){ - SVector3 t1b = t1; - SVector3 t2b = t2; - SVector3 t3b = t3; - t1b[0] *= l1; t2b[0] *= l1; t3b[0] *= l1; - t1b[1] *= l2; t2b[1] *= l2; t3b[1] *= l2; - t1b[2] *= l3; t2b[2] *= l3; t3b[2] *= l3; - _val[0] = dot (t1b,t1); - _val[1] = dot (t2b,t1); - _val[2] = dot (t2b,t2); - _val[3] = dot (t3b,t1); - _val[4] = dot (t3b,t2); - _val[5] = dot (t3b,t3); + const SVector3 &t3) + { + // M = e^1 * diag * e^1^t + // where the elements of diag are l_i = h_i^-2 + // and the rows of e are the UNIT and ORTHOGONAL directions + + gmshMatrix<double> e(3,3); + e(0,0) = t1(0); e(0,1) = t1(1); e(0,2) = t1(2); + e(1,0) = t2(0); e(1,1) = t2(1); e(1,2) = t2(2); + e(2,0) = t3(0); e(2,1) = t3(1); e(2,2) = t3(2); + e.invertInPlace(); + + gmshMatrix<double> tmp(3,3); + tmp(0,0) = l1 * e(0,0); + tmp(0,1) = l2 * e(0,1); + tmp(0,2) = l3 * e(0,2); + tmp(1,0) = l1 * e(1,0); + tmp(1,1) = l2 * e(1,1); + tmp(1,2) = l3 * e(1,2); + tmp(2,0) = l1 * e(2,0); + tmp(2,1) = l2 * e(2,1); + tmp(2,2) = l3 * e(2,2); + + e.transposeInPlace(); + + _val[0] = tmp(0,0) * e(0,0) + tmp(0,1) * e(1,0) + tmp(0,2) * e(2,0); + _val[1] = tmp(1,0) * e(0,0) + tmp(1,1) * e(1,0) + tmp(1,2) * e(2,0); + _val[2] = tmp(1,0) * e(0,1) + tmp(1,1) * e(1,1) + tmp(1,2) * e(2,1); + _val[3] = tmp(2,0) * e(0,0) + tmp(2,1) * e(1,0) + tmp(2,2) * e(2,0); + _val[4] = tmp(2,0) * e(0,1) + tmp(2,1) * e(1,1) + tmp(2,2) * e(2,1); + _val[5] = tmp(2,0) * e(0,2) + tmp(2,1) * e(1,2) + tmp(2,2) * e(2,2); } inline double &operator()(int i, int j){ return _val[getIndex(i,j)]; @@ -100,11 +140,12 @@ class SMetric3 { SMetric3 a; a.setMat(result); return a; } - void eig (gmshMatrix<double> &V, gmshVector<double> &S) const { + // s: true if eigenvalues are sorted (from min to max of the REAL part) + void eig (gmshMatrix<double> &V, gmshVector<double> &S, bool s=false) const { gmshMatrix<double> me(3,3),right(3,3); gmshVector<double> im(3); getMat(me); - me.eig(V,S,im,right); + me.eig(V,S,im,right,s); } void print(const char *) const; }; @@ -112,9 +153,9 @@ class SMetric3 { // scalar product with respect to the metric inline double dot(const SVector3 &a, const SMetric3 &m, const SVector3 &b) { return - b.x() * ( m(0,0) * a.x() + m(0,1) * a.y() + m(0,2) * a.z() ) + - b.y() * ( m(1,0) * a.x() + m(1,1) * a.y() + m(1,2) * a.z() ) + - b.z() * ( m(2,0) * a.x() + m(2,1) * a.y() + m(2,2) * a.z() ) ;} + b.x() * ( m(0,0) * a.x() + m(1,0) * a.y() + m(2,0) * a.z() ) + + b.y() * ( m(0,1) * a.x() + m(1,1) * a.y() + m(2,1) * a.z() ) + + b.z() * ( m(0,2) * a.x() + m(1,2) * a.y() + m(2,2) * a.z() ) ;} // compute the largest inscribed ellipsoid... SMetric3 intersection (const SMetric3 &m1, @@ -127,5 +168,12 @@ SMetric3 interpolation (const SMetric3 &m1, const SMetric3 &m3, const double u, const double v); +SMetric3 interpolation (const SMetric3 &m1, + const SMetric3 &m2, + const SMetric3 &m3, + const SMetric3 &m4, + const double u, + const double v, + const double w); #endif diff --git a/Numeric/GmshMatrix.cpp b/Numeric/GmshMatrix.cpp index f8a21ad5ab50dbc9a40ff640198b7d416bf68d67..125933b37287302d7edc17dd1145aad81a6ab6c1 100644 --- a/Numeric/GmshMatrix.cpp +++ b/Numeric/GmshMatrix.cpp @@ -143,7 +143,8 @@ template<> bool gmshMatrix<double>::eig(gmshMatrix<double> &VL, // left eigenvectors gmshVector<double> &DR, // Real part of eigenvalues gmshVector<double> &DI, // Im part of eigenvalues - gmshMatrix<double> &VR ) + gmshMatrix<double> &VR, + bool sortRealPart) // if true: sorted from min '|DR|' to max '|DR|' { int N = size1(), info; int LWORK = 10*N; @@ -158,12 +159,35 @@ bool gmshMatrix<double>::eig(gmshMatrix<double> &VL, // left eigenvectors delete [] work; - if(info == 0) return true; if(info > 0) Msg::Error("QR Algorithm failed to compute all the eigenvalues", info, info); - else + else if(info < 0) Msg::Error("Wrong %d-th argument in eig", -info); - return false; + + if (sortRealPart) { + double tmp[8]; + // do permutations + for (int i=0; i<(size1()-1); i++) { + int minR = i; + for (int j=i+1; j<size1(); j++) if ( fabs(DR(j)) < fabs(DR(minR)) ) minR = j; + if ( minR != i ) + { + tmp[0] = DR(i); tmp[1] = DI(i); + tmp[2] = VL(0,i); tmp[3] = VL(1,i); tmp[4] = VL(2,i); + tmp[5] = VR(0,i); tmp[6] = VR(1,i); tmp[7] = VR(2,i); + + DR(i) = DR(minR); DI(i) = DI(minR); + VL(0,i) = VL(0,minR); VL(1,i) = VL(1,minR); VL(2,i) = VL(2,minR); + VR(0,i) = VR(0,minR); VR(1,i) = VR(1,minR); VR(2,i) = VR(2,minR); + + DR(minR) = tmp[0]; DI(minR) = tmp[1]; + VL(0,minR) = tmp[2]; VL(1,minR) = tmp[3]; VL(2,minR) = tmp[4]; + VR(0,minR) = tmp[5]; VR(1,minR) = tmp[6]; VR(2,minR) = tmp[7]; + } + } + } + + return true; } diff --git a/Numeric/GmshMatrix.h b/Numeric/GmshMatrix.h index 9e6da0f6ffd66e55f0ac2e3f8e721900706fb042..a2d9ca46b2c8f2c809ea6b647fbea41d85b7e293 100644 --- a/Numeric/GmshMatrix.h +++ b/Numeric/GmshMatrix.h @@ -60,6 +60,14 @@ class gmshVector for(int i = 0; i < _r; ++i) s += _data[i]*other._data[i]; return s; } + void print(const char * name="") const { + printf("Printing vector %s:\n",name); + printf(" "); + for(int I = 0; I < size(); I++){ + printf("%12.5E ",(*this)(I)); + } + printf("\n"); + } }; @@ -175,6 +183,19 @@ class gmshMatrix T(j, i) = (*this)(i, j); return T; } + inline void transposeInPlace() + { + if ( size1() != size2() ) { + Msg::Error("Not a square matrix (size1: %d, size2: %d)",size1(),size2()); + } + scalar t; + for(int i = 0; i < size1(); i++) + for(int j = 0; j < i; j++) { + t = _data[i + _r * j]; + _data[i + _r * j] = _data[j + _r * i]; + _data[j + _r * i] = t; + } + } bool lu_solve(const gmshVector<scalar> &rhs, gmshVector<scalar> &result) #if !defined(HAVE_LAPACK) { @@ -194,7 +215,8 @@ class gmshMatrix bool eig(gmshMatrix<scalar> &VL, // left eigenvectors gmshVector<double> &DR, // Real part of eigenvalues gmshVector<double> &DI, // Im part of eigen - gmshMatrix<scalar> &VR) + gmshMatrix<scalar> &VR, + bool sortRealPart=false) // if true: sorted from min 'DR' to max 'DR' #if !defined(HAVE_LAPACK) { Msg::Error("Eigenvalue computations requires LAPACK"); @@ -239,6 +261,18 @@ class gmshMatrix } #endif ; + void print(const char * name="") const { + printf("Printing matrix %s:\n",name); + int ni = size1(); + int nj = size2(); + for(int I = 0; I < ni; I++){ + printf(" "); + for(int J = 0; J < nj; J++){ + printf("%12.5E ",(*this)(I, J)); + } + printf("\n"); + } + } }; #endif