void Solver::QPSolve(ARRAY<2, double>& a, ARRAY<1, double>& b, ARRAY<1, double>& f) { int n = f.dim(1); f.Fill(0); ARRAY<1, double> c = b; ARRAY<1, double> delta_f(n), delta_a(n); set<int> C, NC; set<int> ad_minus; for (int i = 1; i <= n; ++i) { if (c(i) < -1e-4) { ad_minus.insert(i); } } while (!ad_minus.empty()) { set<int>::iterator it = ad_minus.begin(); int d = *it; NC.erase(d); while (true) { fdirection(d, a, C, delta_f, delta_a); pair<double, int> sj = maxstep(f,c,delta_f,delta_a,C,NC,d); if (sj.first > 1e20) { return; } for (set<int>::iterator it = C.begin(); it != C.end(); ++it) if (*it != d) f(*it) += sj.first * delta_f(*it); f(d) += sj.first * delta_f(d); for (int i = 1; i <= n; ++i) { c(i) += delta_a(i) * sj.first; if (c(i) < -1e-4) { ad_minus.insert(i); } else { if (i == d) { sj.second = d; NC.erase(d); } ad_minus.erase(i); } } it = C.find(sj.second); if (it != C.end()) { NC.insert(*it); C.erase(it); } else { it = NC.find(sj.second); if (it != NC.end()) { C.insert(*it); NC.erase(it); } else { C.insert(d); ad_minus.erase(d); break; } } } } }
//##################################################################### // Function Compute_Level_Set //##################################################################### template<class T> void LEVELSET_MAKER_UNIFORM_2D<T>:: Compute_Level_Set(SEGMENTED_CURVE_2D<T>& curve,GRID<TV>& grid,int ghost_cells,ARRAY<T,TV_INT>& phi) { phi.Fill(FLT_MAX); T dx=grid.dX.Max(); ARRAY<bool,TV_INT> done(grid.Domain_Indices(ghost_cells+1)); for(int i=1;i<=curve.mesh.elements.m;i++){ SEGMENT_2D<T> segment(curve.particles.X(curve.mesh.elements(i).x),curve.particles.X(curve.mesh.elements(i).y)); RANGE<TV_INT> box(grid.Cell(segment.x1,3)); box.Enlarge_To_Include_Point(grid.Cell(segment.x2,3)); box=box.Intersect(box,grid.Domain_Indices(ghost_cells-1)); if(box.Empty()) continue; for(UNIFORM_ARRAY_ITERATOR<TV::m> it(box.Thickened(1));it.Valid();it.Next()){ TV X=grid.X(it.index); T dist=segment.Distance_From_Point_To_Segment(X); if(dist<abs(phi(it.index))+dx*1e-4 && dist<dx){ bool new_sign=TV::Dot_Product(X-segment.x1,segment.Normal())<0; if(abs(dist-abs(phi(it.index)))<dx*1e-4 && new_sign != (phi(it.index)<0)) new_sign=curve.Inside(grid.X(it.index)); if(abs(dist)<abs(phi(it.index))) phi(it.index)=dist; phi(it.index)=abs(phi(it.index))*(new_sign?-1:1); done(it.index)=true;}}} ARRAY<TV_INT> todo,next_todo; for(UNIFORM_GRID_ITERATOR_CELL<TV> it(grid);it.Valid();it.Next()) if(phi(it.index)!=FLT_MAX) todo.Append(it.index); for(int layer=1;todo.m;layer++){ while(todo.m){ TV_INT index=todo.Pop(); T next=sign(phi(index))*layer*dx; Compute_Level_Set_Helper(index+TV_INT(1,0),next,next_todo,phi); Compute_Level_Set_Helper(index-TV_INT(1,0),next,next_todo,phi); Compute_Level_Set_Helper(index+TV_INT(0,1),next,next_todo,phi); Compute_Level_Set_Helper(index-TV_INT(0,1),next,next_todo,phi);} todo.Exchange(next_todo);} /* for(UNIFORM_GRID_ITERATOR_CELL<TV> it(grid);it.Valid();it.Next()){ VECTOR<T,3> color=phi(it.index)>0?VECTOR<T,3>(0,1,0):VECTOR<T,3>(1,0,0); if(done(it.index)) color/=(T)3; Add_Debug_Particle(grid.X(it.index),color);}*/ PHYSBAM_DEBUG_WRITE_SUBSTEP("Compute Level Set",0,1); LEVELSET_2D<GRID<TV> > levelset(grid,phi); FAST_MARCHING_METHOD_UNIFORM<GRID<TV> > fmm(levelset,ghost_cells); fmm.Fast_Marching_Method(phi,done); }