Commit 14c0517e by Kirill Terekhov

### Fix for mesh modification algorithm

parent 0e99faa2
 ... @@ -298,10 +298,11 @@ namespace INMOST ... @@ -298,10 +298,11 @@ namespace INMOST flag = 0; flag = 0; break; break; } } if( l == 0 ) break; if (fabs(get_value(Sigma(nm,nm))) + anorm == anorm) if (fabs(get_value(Sigma(nm,nm))) + anorm == anorm) break; break; } } if (flag) if (flag && l != 0) { { c = 0.0; c = 0.0; s = 1.0; s = 1.0; ... @@ -377,7 +378,7 @@ namespace INMOST ... @@ -377,7 +378,7 @@ namespace INMOST } } z = pythag(f, h); z = pythag(f, h); Sigma(j,j) = z; Sigma(j,j) = z; if (z) if (get_value(z)) { { z = 1.0 / z; z = 1.0 / z; c = f * z; c = f * z; ... @@ -1115,6 +1116,19 @@ namespace INMOST ... @@ -1115,6 +1116,19 @@ namespace INMOST n = _n; n = _n; m = _m; m = _m; } } Matrix PseudoInvert(INMOST_DATA_REAL_TYPE tol = 0) { Matrix U,S,V; SVD(U,S,V); for(int k = 0; k < S.Cols(); ++k) { if( S(k,k) > tol ) S(k,k) = 1.0/S(k,k); else S(k,k) = 0.0; } return V*S*U.Transpose(); } }; }; typedef Matrix rMatrix; //shortcut for real matrix typedef Matrix rMatrix; //shortcut for real matrix ... ...
 ... @@ -1503,16 +1503,19 @@ namespace INMOST ... @@ -1503,16 +1503,19 @@ namespace INMOST class pow_const_expression : public shell_expression > class pow_const_expression : public shell_expression > { { const A & left; const A & left; INMOST_DATA_REAL_TYPE value, ldmult; INMOST_DATA_REAL_TYPE value, ldmult, ldmult2; public: public: pow_const_expression(const shell_expression & pleft, INMOST_DATA_REAL_TYPE pright) : left(pleft) pow_const_expression(const shell_expression & pleft, INMOST_DATA_REAL_TYPE pright) : left(pleft) { { INMOST_DATA_REAL_TYPE lval = left.GetValue(); INMOST_DATA_REAL_TYPE lval = left.GetValue(); value = ::pow(lval,pright); value = ::pow(lval,pright); if( lval != 0 ) if( lval != 0 ) { ldmult = value * pright / lval; ldmult = value * pright / lval; ldmult2 = ldmult * (pright-1) / lval; } else else ldmult = 0; ldmult = ldmult2 = 0; } } pow_const_expression(const pow_const_expression & other) pow_const_expression(const pow_const_expression & other) :left(other.left), value(other.value), ldmult(other.ldmult) {} :left(other.left), value(other.value), ldmult(other.ldmult) {} ... @@ -1527,7 +1530,13 @@ namespace INMOST ... @@ -1527,7 +1530,13 @@ namespace INMOST } } __INLINE void GetHessian(INMOST_DATA_REAL_TYPE multJ, Sparse::Row & J, INMOST_DATA_REAL_TYPE multH, Sparse::HessianRow & H) const __INLINE void GetHessian(INMOST_DATA_REAL_TYPE multJ, Sparse::Row & J, INMOST_DATA_REAL_TYPE multH, Sparse::HessianRow & H) const { { throw NotImplemented; //(F(G))'' = (F'(G)G')' = (F''(G)G'+F'(G)G'') //(g(x)^n)'' = n g(x)^(n - 2) (g(x) g''(x) + (n - 1) g'(x)^2) Sparse::Row JL; Sparse::HessianRow HL; left.GetHessian(1,JL,1,HL); //retrive jacobian row and hessian matrix of the left expression Sparse::HessianRow::MergeJacobianHessian(multH*ldmult2,JL,JL,multH*ldmult,HL,H); for(Sparse::Row::iterator it = JL.Begin(); it != JL.End(); ++it) it->second *= ldmult*multJ; } } }; }; ... ...
 ... @@ -99,7 +99,7 @@ namespace INMOST ... @@ -99,7 +99,7 @@ namespace INMOST dynarray< char , 256 > hide_column; dynarray< char , 256 > hide_column; dynarray< char , 256 > hide_row; dynarray< char , 256 > hide_row; dynarray< char , 256 > stub_row; dynarray< char , 256 > stub_row; //std::vector< std::pair,double> > remember; std::vector< std::pair,double> > remember; double min_loop_measure; double min_loop_measure; bool print; bool print; AbstractCoords * coords; AbstractCoords * coords; ... @@ -293,37 +293,61 @@ namespace INMOST ... @@ -293,37 +293,61 @@ namespace INMOST } } } while(true); } while(true); data.RemPrivateMarker(mrk); data.RemPrivateMarker(mrk); mesh->ReleasePrivateMarker(mrk); Storage::real fnrm[3], fcnt[3], ccnt[3] = {0,0,0}, nnodes = 0; Storage::real nrm[3], cnt[3]; Storage::real_array x0,a,b; Storage::real_array v0,v1,v2; //find cell centroid for(typename ElementArray::size_type j = 0; j < data.size(); j++) { ElementArray nodes = data[j]->getAsFace()->getNodes(mrk,true); nodes.SetPrivateMarker(mrk); for(ElementArray::iterator qt = nodes.begin(); qt != nodes.end(); ++qt) { x0 = coords->Get(qt->self()); ccnt[0] += x0[0]; ccnt[1] += x0[1]; ccnt[2] += x0[2]; nnodes += 1; } } ccnt[0] /= nnodes; ccnt[1] /= nnodes; ccnt[2] /= nnodes; for(typename ElementArray::size_type j = 0; j < data.size(); j++) for(typename ElementArray::size_type j = 0; j < data.size(); j++) { { //compute normal to face //compute normal to face ElementArray nodes = data[j]->getAsFace()->getNodes(); ElementArray nodes = data[j]->getAsFace()->getNodes(); nrm[0] = nrm[1] = nrm[2] = 0; nodes.RemPrivateMarker(mrk); v0 = v1 = coords->Get(nodes[0]); fnrm[0] = fnrm[1] = fnrm[2] = 0; cnt[0] = v1[0]; fcnt[0] = fcnt[1] = fcnt[2] = 0; cnt[1] = v1[1]; nnodes = 0; cnt[2] = v1[2]; x0 = coords->Get(nodes[0]); a = x0; for(unsigned i = 0; i < nodes.size(); i++) for(unsigned i = 0; i < nodes.size(); i++) { { v2 = coords->Get(nodes[(i+1)%nodes.size()]); b = coords->Get(nodes[(i+1)%nodes.size()]); cnt[0] += v2[0]; fnrm[0] += (a[1]-x0[1])*(b[2]-x0[2]) - (a[2]-x0[2])*(b[1]-x0[1]); cnt[1] += v2[1]; fnrm[1] += (a[2]-x0[2])*(b[0]-x0[0]) - (a[0]-x0[0])*(b[2]-x0[2]); cnt[2] += v2[2]; fnrm[2] += (a[0]-x0[0])*(b[1]-x0[1]) - (a[1]-x0[1])*(b[0]-x0[0]); nrm[0] += (v1[1]-v0[1])*(v2[2]-v0[2]) - (v1[2]-v0[2])*(v2[1]-v0[1]); nrm[1] += (v1[2]-v0[2])*(v2[0]-v0[0]) - (v1[0]-v0[0])*(v2[2]-v0[2]); fcnt[0] += a[0]; nrm[2] += (v1[0]-v0[0])*(v2[1]-v0[1]) - (v1[1]-v0[1])*(v2[0]-v0[0]); fcnt[1] += a[1]; v1.swap(v2); fcnt[2] += a[2]; } nrm[0] *= 0.5; a.swap(b); nrm[1] *= 0.5; nrm[2] *= 0.5; nnodes += 1; cnt[0] /= (Storage::real)nodes.size(); } cnt[1] /= (Storage::real)nodes.size(); fnrm[0] *= 0.5; cnt[2] /= (Storage::real)nodes.size(); fnrm[1] *= 0.5; measure += (data[j]->GetPrivateMarker(rev) ? -1.0 : 1.0)*dot_prod(cnt,nrm); fnrm[2] *= 0.5; fcnt[0] /= nnodes; fcnt[1] /= nnodes; fcnt[2] /= nnodes; for(int r = 0; r < 3; ++r) fcnt[r] = fcnt[r]-ccnt[r]; measure += (data[j]->GetPrivateMarker(rev) ? -1.0 : 1.0)*dot_prod(fcnt,fnrm); } } mesh->ReleasePrivateMarker(mrk); data.RemPrivateMarker(rev); data.RemPrivateMarker(rev); mesh->ReleasePrivateMarker(rev); mesh->ReleasePrivateMarker(rev); measure /= 3.0; measure /= 3.0; ... @@ -447,7 +471,7 @@ namespace INMOST ... @@ -447,7 +471,7 @@ namespace INMOST std::cout << " " << cnt[0] << " " << cnt[1] << " " << cnt[2]; std::cout << " " << cnt[0] << " " << cnt[1] << " " << cnt[2]; std::cout << std::endl; std::cout << std::endl; } } /* std::cout << "loops [" << remember.size() << "]:" << std::endl; std::cout << "loops [" << remember.size() << "]:" << std::endl; for(size_t k = 0; k < remember.size(); ++k) for(size_t k = 0; k < remember.size(); ++k) { { ... @@ -456,7 +480,7 @@ namespace INMOST ... @@ -456,7 +480,7 @@ namespace INMOST std::cout << remember[k].first[l] << ", "; std::cout << remember[k].first[l] << ", "; std::cout << remember[k].first.back() << " measure " << remember[k].second << std::endl; std::cout << remember[k].first.back() << " measure " << remember[k].second << std::endl; } } */ if( GetHandleElementType(head_column[0]) == EDGE ) if( GetHandleElementType(head_column[0]) == EDGE ) { { std::cout << "edges [" << head_column.size() << "]" << std::endl; std::cout << "edges [" << head_column.size() << "]" << std::endl; ... @@ -582,7 +606,7 @@ namespace INMOST ... @@ -582,7 +606,7 @@ namespace INMOST if( min_loop.empty() ) if( min_loop.empty() ) { { if( print ) std::cout << "abandon " << first << std::endl; if( print ) std::cout << "abandon " << first << std::endl; //remember.push_back(std::make_pair(std::vector(1,first),-1.0)); remember.push_back(std::make_pair(std::vector(1,first),-1.0)); visits[first]--; //don't start again from this element visits[first]--; //don't start again from this element } } } } ... @@ -595,8 +619,8 @@ namespace INMOST ... @@ -595,8 +619,8 @@ namespace INMOST if( !ret.empty() ) if( !ret.empty() ) { { //std::vector add_remember; std::vector add_remember; //add_remember.reserve(min_loop.size()); add_remember.reserve(min_loop.size()); MarkerType hide_marker = mesh->CreatePrivateMarker(); MarkerType hide_marker = mesh->CreatePrivateMarker(); for(typename ElementArray::size_type k = 0; k < ret.size(); k++) mesh->SetPrivateMarker(ret.at(k),hide_marker); for(typename ElementArray::size_type k = 0; k < ret.size(); k++) mesh->SetPrivateMarker(ret.at(k),hide_marker); if( print ) std::cout << "return loop [" << ret.size() << "]:"; if( print ) std::cout << "return loop [" << ret.size() << "]:"; ... @@ -604,13 +628,13 @@ namespace INMOST ... @@ -604,13 +628,13 @@ namespace INMOST if( mesh->GetPrivateMarker(head_column[k],hide_marker) ) if( mesh->GetPrivateMarker(head_column[k],hide_marker) ) { { visits[k]--; visits[k]--; //add_remember.push_back((int)k); add_remember.push_back((int)k); if( print ) std::cout << k << " "; if( print ) std::cout << k << " "; } } if( print ) std::cout << std::endl; if( print ) std::cout << std::endl; for(typename ElementArray::size_type k = 0; k < ret.size(); k++) mesh->RemPrivateMarker(ret.at(k),hide_marker); for(typename ElementArray::size_type k = 0; k < ret.size(); k++) mesh->RemPrivateMarker(ret.at(k),hide_marker); mesh->ReleasePrivateMarker(hide_marker); mesh->ReleasePrivateMarker(hide_marker); //remember.push_back(std::make_pair(add_remember,min_loop_measure)); remember.push_back(std::make_pair(add_remember,min_loop_measure)); return true; return true; } } return false; return false; ... ...
 ... @@ -1252,6 +1252,20 @@ namespace INMOST ... @@ -1252,6 +1252,20 @@ namespace INMOST else break; else break; } while( true ); } while( true ); /* //debug if(!mat.all_visited()) { mat.print_matrix(); incident_matrix mat(m,temp.begin(),temp.end(),ninner,GridCoords(),true); do { mat.find_shortest_loop(loop); if (!loop.empty()) ret.push_back(m->CreateCell(loop).first); else break; } while( true ); } */ return ret; return ret; } } bool Cell::TestSplitCell(Cell cell, const ElementArray & faces, MarkerType del_protect) bool Cell::TestSplitCell(Cell cell, const ElementArray & faces, MarkerType del_protect) ... ...
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!