Example #1
0
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);
}