// Fill area by Flow
void Area2D::FillArea2D(unsigned int X,
                        unsigned int Y,
                        ulong     bnt,
                        Flow*   pf,
                        FP* p_Y,
                        ulong     att,
                        int MaterialID) {
    Flow2D F2D(*pf);
    FillArea2D((unsigned int)X,(unsigned int)Y,
               bnt | CT_NODE_IS_SET_2D,&F2D,p_Y,att,MaterialID);
}
void Area2D::FillArea2D(FP  X,
                        FP  Y,
                        ulong   bnt,
                        Flow2D*  pf2d,
                        FP*  p_Y,
                        ulong    att,
                        int MaterialID) {

  FillArea2D((unsigned int)(X/pMFN->GetValue(0,0).dx),
             (unsigned int)(Y/pMFN->GetValue(0,0).dy),
             bnt,
             pf2d,
             p_Y,
             att,
             MaterialID);
}
// Fill area by custom type nodes
void Area2D::FillArea2D(FP X, FP Y, ulong bnt,ulong att,
                        int MaterialID) {
    FillArea2D((unsigned int)(X/pMFN->GetValue(0,0).dx),(unsigned int)(Y/pMFN->GetValue(0,0).dy),bnt | CT_NODE_IS_SET_2D,(Flow2D*)NULL,NULL,att,MaterialID);
}
// Fill area by custom type nodes
void Area2D::FillArea2D(unsigned int X,unsigned int Y, 
                        ulong bnt,ulong att,
                        int MaterialID) {
    FillArea2D((unsigned int)X,(unsigned int)Y,bnt | CT_NODE_IS_SET_2D,(Flow2D*)NULL,NULL,att,MaterialID);
}
SolidBoundAirfoil2D::SolidBoundAirfoil2D(char* name,
                                         UMatrix2D< FlowNode2D< FP, NUM_COMPONENTS> >* JM, // Computation area reference
                                         FP  x,                      // Start profile 
                                         FP  y,                      // coordinates (x,y)
                                         InputData* airfoil_input_data, //
                                         FP  dx,                     // dx - step
                                         FP  dy,                     // dy - step
                                         ulong   ct,                 // condition type
                                         Flow2D* pInFlow2D,          // init flow2d object on circle bound
                                         FP* Y,                      // component matrix
                                         ulong   bctt,               // Bound contour turbulence type
                                         FP  scale,                  // airfoil scale
                                         FP  attack_angle,           // Angle of attack
                                         ostream* dbg_output):BoundContour2D(name,JM,
                                                                             (int)(x/dx+0.4999),
                                                                             (int)(y/dy+0.4999)
                                                                             ),Area2D(name,JM) {
    int     k,i,ret;
    FP      xx1,yy1,xx2,yy2,r,fi;
    int     ix,iy;
    Table*  UpperSurface = airfoil_input_data->GetTable((char*)"UpperSurface");
    Table*  LowerSurface = airfoil_input_data->GetTable((char*)"LowerSurface");

    FP dcx,dcy;
    xx1=yy1=xx2=yy2=0.;
 
    airfoil_type = AFT_TsAGI;

    xx1 = x;
    yy1 = y;

    for (i=0;i<UpperSurface->GetNumNodes();i++) {  //    upper surface
        xx2=x+scale*UpperSurface->GetX(i);
        yy2=y+scale*UpperSurface->GetY(i);
        ix = (int)(xx2/dx+0.4999);
        iy = (int)(yy2/dy+0.4999);

        if (dbg_output)
            *dbg_output << "\ndebug: Add airfoil node ("<< xx1 <<","<< yy1 << ")->[" << ix <<","<< iy << "]" 
            << flush;
#ifdef _UNIFORM_MESH_
        AddBound2D(name, ix,iy,ct,NULL,pInFlow2D,Y,bctt);
#else
        AddBound2D(name, xx2,yy2,ct,NULL,pInFlow2D,Y,bctt);
#endif // _UNIFORM_MESH_
        xx1 = xx2;
        yy1 = yy2;
    }
    
    for (i=LowerSurface->GetNumNodes()-1;i>0;i--) {          //     lower surface
        xx2=x+scale*LowerSurface->GetX(i);
        yy2=y+scale*LowerSurface->GetY(i);

        ix = (int)(xx2/dx+0.4999);
        iy = (int)(yy2/dy+0.4999);
        if (dbg_output)
            *dbg_output << "\ndebug: Add airfoil node ("<< xx1 <<","<< yy1 << ")->[" << ix <<","<< iy << "]" 
            << flush;
#ifdef _UNIFORM_MESH_
        AddBound2D(name,ix,iy,ct,NULL,pInFlow2D,Y,bctt);
#else
        AddBound2D(name, xx2,yy2,ct,NULL,pInFlow2D,Y,bctt);
#endif // _UNIFORM_MESH_
        xx1 = xx2;
        yy1 = yy2;
    }
    CloseContour2D(name, ct, NULL, pInFlow2D,Y,bctt);

    xx1=x+scale*UpperSurface->GetX(UpperSurface->GetNumNodes()/2);
    yy1=y+scale*(UpperSurface->GetY(UpperSurface->GetNumNodes()/2) + 
                 LowerSurface->GetY(LowerSurface->GetNumNodes()/2))/2;
    
    if (attack_angle != 0.) {
        dcx=x-xx1;
        dcy=y-yy1;
        r  = sqrt(dcx*dcx+dcy*dcy+1.e-30);        
        fi = atan2(dcx,dcy);
        xx1 = x + (r*sin(fi+attack_angle)); 
        yy1 = y + (r*cos(fi+attack_angle));
        ret = RotateBoundContour2D(x,y,attack_angle);

        if (dbg_output) {
            if (ret)
                *dbg_output << "\ndebug: Rotate sucess !\n" << flush;
            else
                *dbg_output << "\n@C1debug: Rotate failed !\n" << flush;
        }

    } else {
        ret = 1;
    }

    ix = (int)(xx1/dx+0.4999);
    iy = (int)(yy1/dy+0.4999);

    if (dbg_output)
        *dbg_output << "\n \ndebug:Start point for fill airfoil ("<< xx1 <<","<< yy1 << ")->[" << ix <<","<< iy << "]\n" 
        << flush;
    if (ret) {
        SetBounds();
#ifdef _UNIFORM_MESH_
        FillArea2D((unsigned int)ix,(unsigned int)iy,NT_S_2D);
#else    
        FillArea2D(xx1,yy1,NT_S_2D);
#endif // _UNIFORM_MESH_
    }
}
SolidBoundAirfoil2D::SolidBoundAirfoil2D(char* name,                 // Object name  
                                         UMatrix2D< FlowNode2D< FP, NUM_COMPONENTS> >* JM, // Computation area reference
                                         FP  x,                      // Start profile 
                                         FP  y,                      // coordinates (x,y)
                                         FP  m_m,                    //
                                         FP  p_p,                    //
                                         FP  thick,                  // airfoil thick
                                         FP  dx,                     // dx - step
                                         FP  dy,                     // dy - step
                                         ulong   ct,                 // condition type
                                         Flow2D* pInFlow2D,          // init flow2d object on circle bound
                                         FP* Y,                      // component matrix
                                         ulong   bctt,               // Bound contour turbulence type
                                         FP  scale,                  // airfoil scale
                                         FP  attack_angle,           // Angle of attack
                                         ostream* dbg_output):BoundContour2D(name,JM,
                                                                             (int)(x/dx+0.4999),
                                                                             (int)(y/dy+0.4999)
                                                                             ),Area2D(name,JM) {
    int    k,i,ret;
    FP xx1,yy1,xx2,yy2,r,fi;
    int    ix,iy;
    k = (int)(scale/dx);

    FP dcx,dcy,dt=2./k;
    xx1=yy1=xx2=yy2=0.;
    pp =  p_p;
    mm =  m_m;
    
    airfoil_type = AFT_NACA;
    
    xx1 = x;
    yy1 = y;
    
    for (i=0;i<k/2;i++) {                             //    upper surface
        xx2=x+scale*airfoil_x((i+1)*dt);
        yy2=y+scale*airfoil_y1((i+1)*dt,thick);
        ix = (int)(xx2/dx+0.4999);
        iy = (int)(yy2/dy+0.4999);
        
        if (dbg_output)
            *dbg_output << "\ndebug: Add airfoil node ("<< xx1 <<","<< yy1 << ")->[" << ix <<","<< iy << "]" 
            << flush;
#ifdef _UNIFORM_MESH_
        AddBound2D(name, ix,iy,ct,NULL,pInFlow2D,Y,bctt);
#else
        AddBound2D(name, xx2,yy2,ct,NULL,pInFlow2D,Y,bctt);
#endif // _UNIFORM_MESH_
        xx1 = xx2;
        yy1 = yy2;
    }
    for (;i>0;i--) {          //     lower surface
        xx2=x+scale*airfoil_x((i-1)*dt);
        yy2=y+scale*airfoil_y2((i-1)*dt,thick);
        
        ix = (int)(xx2/dx+0.4999);
        iy = (int)(yy2/dy+0.4999);
        if (dbg_output)
            *dbg_output << "\ndebug: Add airfoil node ("<< xx1 <<","<< yy1 << ")->[" << ix <<","<< iy << "]" 
            << flush;
#ifdef _UNIFORM_MESH_
        AddBound2D(name,ix,iy,ct,NULL,pInFlow2D,Y,bctt);
#else
        AddBound2D(name, xx2,yy2,ct,NULL,pInFlow2D,Y,bctt);
#endif // _UNIFORM_MESH_
        xx1 = xx2;
        yy1 = yy2;
    }
    CloseContour2D(name, ct, NULL, pInFlow2D,Y,bctt);

    xx1=x+scale*airfoil_x(0.5);
    yy1=y+scale*airfoil_y(0.5);
    if (attack_angle != 0.) {
        dcx=x-xx1;
        dcy=y-yy1;
        r  = sqrt(dcx*dcx+dcy*dcy+1.e-30);        
        fi = atan2(dcx,dcy);
        xx1 = x + (r*sin(fi+attack_angle)); 
        yy1 = y + (r*cos(fi+attack_angle));
        ret = RotateBoundContour2D(x,y,attack_angle);
        
        if (dbg_output) {
            if (ret)
                *dbg_output << "\ndebug: Rotate sucess !\n" << flush;
            else
                *dbg_output << "\n@C1debug: Rotate failed !\n" << flush;
        }
    
    } else {
        ret = 1;
    }
    
    ix = (int)(xx1/dx+0.4999);
    iy = (int)(yy1/dy+0.4999);
    
    if (dbg_output)
        *dbg_output << "\n \ndebug:Start point for fill airfoil ("<< xx1 <<","<< yy1 << ")->[" << ix <<","<< iy << "]\n" 
        << flush;
    if (ret) {
        SetBounds();
#ifdef _UNIFORM_MESH_
        FillArea2D((unsigned int)ix,(unsigned int)iy,NT_S_2D);
#else    
        FillArea2D(xx1,yy1,NT_S_2D);
#endif // _UNIFORM_MESH_
    }
}