Example #1
0
void dump(double ****f1,double ***nu,double t_cur,long count)
{
FILE *fd;
char *message="dump";
int tag=1,v;

 boundary_conditions(f1);
 calculate_curl(&f1[4],B,NodeMagn);
 calculate_curl(B,J,NodeMagn);

 if(rank!=0) MPI_Recv(message,0,MPI_CHAR,rank-1,tag,MPI_COMM_WORLD,statuses);

 fd=fileopen(NameDumpFile,rank);

 Master nmessage("dump has been started",t_cur,count);
 Master fprintf(fd,"current time = %0.10f \ncurrent iteration = %ld\n",t_cur,count);
 Master fprintf(fd,"number of processors along axes={%d,%d,%d}\n",pp[0],pp[1],pp[2]);
 Master fprintf(fd,"Number of points along x = %d\n",N1);
 Master fprintf(fd,"Number of points along y = %d\n",N2);
 Master fprintf(fd,"Number of points along z = %d\n",N3);
 Master fprintf(fd,"Reynolds number = %lf\n",Re);

 for(v=0;v<nvar;v++)
    print_array3d(fd,f1[v],0,m1,0,m2,0,m3);
 print_array3d(fd,B[0],0,m1,0,m2,0,m3);
 print_array3d(fd,B[1],0,m1,0,m2,0,m3);
 print_array3d(fd,B[2],0,m1,0,m2,0,m3);
 print_array3d(fd,nu,0,m1,0,m2,0,m3);
 fclose(fd);

 if(rank!=size-1) MPI_Send(message,0,MPI_CHAR,rank+1,tag,MPI_COMM_WORLD);
             else {nmessage("dump is done",t_cur,count);
                   add_control_point(NameDumpFile);}
}
Example #2
0
void pde(double t, double ****f, double ****df)
{
   int i,j,k,l,m;
   double dv1[3][3],dv2[3][3],dp1[3],dp2[3],dn1[3];

   boundary_conditions(f);

   for(i=ghost;i<mm1;i++)
   for(j=ghost;j<mm2;j++)
   for(k=ghost;k<mm3;k++) {
      for(l=0;l<3;l++)
      for(m=0;m<3;m++) {
         dv1[l][m]=dr(f[l],i,j,k,m+1,0,dx[m],ghost, approx);
         dv2[l][m]=dr(f[l],i,j,k,m+1,1,dx[m]*dx[m],ghost, approx);
      }
      for(m=0;m<3;m++) {
         dp1[m]=dr(f[3],i,j,k,m+1,0,dx[m],ghost, approx);
         dn1[m]=dr(nut,i,j,k,m+1,0,dx[m],ghost, approx);
      }

      for(l=0;l<3;l++)
       df[l][i][j][k]= (dv2[l][0] + dv2[l][1] + dv2[l][2])*nut[i][j][k]
                     - dp1[l] + (dn1[0]-f[0][i][j][k])*dv1[l][0]
                              + (dn1[1]-f[1][i][j][k])*dv1[l][1]
                              + (dn1[2]-f[2][i][j][k])*dv1[l][2];
      df[3][i][j][k]= (-(dv1[0][0] + dv1[1][1] + dv1[2][2]))/Gamma;
   }

   return;
}
Example #3
0
void snapshot(double ***f1,double **nu,double t_cur,long count)
{
char str[256];
char message[10]="message";
long tag=count,v;
FILE *fd;

 sprintf(str,"%s_%d_%ld.snp",NameSnapFile,size,count);
 boundary_conditions(f1,nut);

 if(rank!=0) MPI_Recv(message,0,MPI_CHAR,rank-1,tag,MPI_COMM_WORLD,statuses);

 fd=fileopen(str,rank);
 Master nmessage("snap has been started",t_cur,count);
 Master fprintf(fd,"current time = %0.10f \ncurrent iteration = %ld\n",t_cur,count);
 Master fprintf(fd,"number of processors along axes={%d,%d}\n",pp[0],pp[2]);
 Master fprintf(fd,"Number of points along x = %d\n",N1);
 Master fprintf(fd,"Number of points along z = %d\n",N3);
 Master fprintf(fd,"Reynolds number = %lf\n",Re);

 for(v=0;v<nvar;v++)
    print_array2d(fd,f1[v],0,m1,0,m3);
 print_array2d(fd,nu,0,m1,0,m3);
 fileclose(fd);
                  
 if(rank!=size-1) MPI_Send(message,0,MPI_CHAR,rank+1,tag,MPI_COMM_WORLD);
 MPI_Barrier(MPI_COMM_WORLD);
 Master {nmessage("snap is done",t_cur,count);
                   add_control_point(str);}
}
Example #4
0
// Функция полного цикла расчетов на следующем временном слое
// 1. Расчет плотности жидкостей, давлений, энтальпий фаз и суммарной внутренней энергии на текущем слое
// 3. Расчет скоростей жидкостей
// 5. Расчет переменной roS на следующем временном слое
// 6. Расчет методом Ньютона давления воды P1 и насыщенности DNAPL S2
// 7. Применение граничных условий для P1 и S2
// 8. Обмен между процессорами пограничными значениями P1 и S2
// 9.Вычисление суммарной внутренней энергии на следующем временном слое
void time_step_function(double t)
{
	boundary_conditions(); // (7)
	prepare_all_vars(); // (1)
	u_calculation(); // (3)
	find_values_from_partial_equations(t); // (5)
	solve_nonlinear_system(); // (6)
	exchange_basic_vars(); // (8)
}
Example #5
0
void printing(double ****f1,double dtdid,double t_cur,long count,double en)
{
double temp, div=0;
int i,j,k,l;
double mf, mda, mdr;
double *avervx, *avernu;
AnsiString TempScreen;
FILE *fv,*fnu,*fen,*fkv;
//fnu = fileopen(NameNuFile,count);
if(MainWindow->CheckClear->Checked)
         MainWindow->Screen->Lines->Clear();
boundary_conditions(f1);

for(i=ghost;i<mm1;i++)
   for(j=ghost;j<mm2;j++)
      for(k=ghost;k<mm3;k++) {
           temp=0;
           for(l=0;l<3;l++)
            temp+=dr(f1[l],i,j,k,l+1,0,dx[l],ghost, approx);
           if (fabs(temp)>div) div=fabs(temp);
           }
time(&time_now);
if(MainWindow->CheckScreenOutput->Checked)  {
   TempScreen.printf("program is working %ld seconds",time_now-time_begin);
   MainWindow->Screen->Lines->Append(TempScreen);
   TempScreen.printf("t=%e \tdtdid=%e \tNIter=%d", t_cur, dtdid, count);
   MainWindow->Screen->Lines->Append(TempScreen);
   TempScreen.printf("divergention=%e", div);
   }
for(l=0;l<nvar;l++) {
       mf=mda=mdr=0;
       for(i=ghost;i<mm1;i++)
        for(j=ghost;j<mm2;j++)
         for(k=ghost;k<mm3;k++) {
            temp=fabs(f[l][i][j][k]-f1[l][i][j][k]);
            if (temp>mda) mda=temp;
            if(f1[l][i][j][k]!=0) temp/=f1[l][i][j][k];
            if (temp>mdr) mdr=temp;
            if (fabs(f1[l][i][j][k])>mf) mf=fabs(f1[l][i][j][k]);
          }
          if(MainWindow->CheckScreenOutput->Checked)  {
                TempScreen.printf("%d\t%e\t%e\t%e",l, mf, mda, mdr);
                MainWindow->Screen->Lines->Append(TempScreen);
                }
          }

         if(MainWindow->CheckScreenOutput->Checked)  {
            TempScreen.printf("Energy of pulsations=%g, total energy=%g",en,TotalEnergy);
            MainWindow->Screen->Lines->Append(TempScreen);
            }
         if(MainWindow->CheckFileOutput->Checked)  {
            fen = fileopen(NameEnergyFile,count);
            fprintf(fen,"%0.10f\n",en);
            fclose(fen);
            }
         if(MainWindow->CheckScreenOutput->Checked)  {
            TempScreen.printf("number of runge-kutt calculations=%d",enter);
            MainWindow->Screen->Lines->Append(TempScreen);
            }

if(MainWindow->CheckFileOutput->Checked)  {  //if fileoutput
/*avervx = alloc_mem_1f(m3);
if(avervx == NULL)  nrerror("\nAlloc_mem: insufficient memory!\n\a",t_cur);*/

avernu = alloc_mem_1f(m3);

for(k=ghost;k<mm3;k++)
	{
	/*  avervx[k] =*/ avernu[k] = 0;
          for(i=ghost;i<mm1;i++)
             for(j=ghost;j<mm2;j++)
		 {
	  //	   avervx[k] += f1[0][i][j][k];
                   avernu[k] += nut[i][j][k];
		  }
//	   avervx[k] /= n1*n2;
	   avernu[k] /= n1*n2;
	 }
  //putting velocities to file
        fv = fileopen(NameVFile,count);
        fprintf(fv,"{%-7.5lf}",t_cur);
        print_array1d(fv,f1[0][m1/2][0],ghost,n3);
        fclose(fv);
  //putting viscosities to file
      fnu = fileopen(NameNuFile,count);
        print_array1d(fnu,avernu,ghost,n3);
        fclose(fnu);
  //for(k=0;k<m3;k++) printf("%e\n",f1[0][5][5][k]);
  //putting kaskad variables(log energy combined from them) to file
if(MainWindow->CheckNut->Checked)
  {
  fkv=fileopen(NameKaskadVarFile,count);
  fprintf(fkv,"{");
  for(i=0;i<Ns;i++)
    {
    fprintf(fkv,"{");
    for(k=0;k<n3;k++)
        {
        mf=fabs(sha[k][i]*sha[k][i]+shb[k][i]*shb[k][i]);
        if(mf>1e-300) fprintf(fkv,"%0.10lf",log(mf));
                 else fprintf(fkv,"NAN");
        fprintf(fkv,k<n3-1 ? "," : "}");
        }
    fprintf(fkv,i<Ns-1 ? "," : "}\n");
    }
  fclose(fkv);
  }//if nu_kaskad is used
 free_mem_1f(avernu,m3);
  }//if fileoutput
}
int main (int nNumberofArgs,char *argv[])
{
  //Test for correct input arguments
  if (nNumberofArgs!=3)
  {
    cout << "FATAL ERROR: wrong number inputs. The program needs the path name and the file name" << endl;
    exit(EXIT_SUCCESS);
  }

  string path_name = argv[1];
  
  // make sure there is a slash on the end of the file
  string lchar = path_name.substr(path_name.length()-2,1);
  string slash = "/";      
  if (lchar != slash)
  {
    cout << "You forgot the frontslash at the end of the path. Appending." << endl; 
    path_name = path_name+slash;
  } 		
  
  string f_name = argv[2];

  cout << "\nYou are running the write junctions driver." << endl
       <<"IMPORTANT: this has been updated to load an ENVI DEM, whith extension .bil" << endl
       <<"You can convert your DEM to this file format using gdal_translate, with -of ENVI" << endl
       <<"See documentation at: http://www.geos.ed.ac.uk/~smudd/LSDTT_docs/html/gdal_notes.html" << endl << endl;
       
  cout << "The path is: " << path_name << " and the filename is: " << f_name << endl;

  string full_name = path_name+f_name;

  ifstream file_info_in;
  file_info_in.open(full_name.c_str());
  if( file_info_in.fail() )
  {
    cout << "\nFATAL ERROR: the header file \"" << full_name
         << "\" doesn't exist" << endl;
    exit(EXIT_FAILURE);
  }

  string DEM_name;
  string fill_ext = "_fill";
  file_info_in >> DEM_name;
  int junction_number;
  float pruning_threshold;
  int threshold;
  float A_0;
  int minimum_segment_length;
  float sigma;
  float start_movern;
  float d_movern;
  float Minimum_Slope;
  int n_movern;
  int target_nodes;
  int n_iterations;
  float fraction_dchi_for_variation;
  float vertical_interval;
  float horizontal_interval;
  float area_thin_frac;
  int target_skip;

  file_info_in >> Minimum_Slope >> threshold >> junction_number
        >> pruning_threshold >> A_0 >> minimum_segment_length >> sigma >> start_movern
        >> d_movern >> n_movern >> target_nodes >> n_iterations >> fraction_dchi_for_variation
        >> vertical_interval >> horizontal_interval >> area_thin_frac >> target_skip;


  cout << "Paramters of this run: " << endl
       << "junction number: " << junction_number << endl
       << "pruning_threshold: " << pruning_threshold << endl
       << "threshold: " << threshold << endl
       << "A_0: " << A_0 << endl
       << "minimum_segment_length: " << minimum_segment_length << endl
       << "sigma: " << sigma << endl
       << "start_movern " << start_movern << endl
       << "d_movern: " << d_movern << endl
       << "n_movern: " << n_movern << endl
       << "target_nodes: " << target_nodes << endl
       << "n_iterarions: " << n_iterations << endl
       << "fraction_dchi_for_variation: " << fraction_dchi_for_variation << endl
       << "vertical interval: " << vertical_interval << endl
       << "horizontal interval: " << horizontal_interval << endl
       << "area thinning fraction for SA analysis: " << area_thin_frac << endl
       << "target_skip is: " << target_skip << endl;


  string jn_name = itoa(junction_number);
  string uscore = "_";
  jn_name = uscore+jn_name;
  file_info_in.close();

  string DEM_f_name = path_name+DEM_name+fill_ext;
  string DEM_bil_extension = "bil";

  // set no flux boundary conditions
  vector<string> boundary_conditions(4);
  boundary_conditions[0] = "No";
  boundary_conditions[1] = "no flux";
  boundary_conditions[2] = "no flux";
  boundary_conditions[3] = "No flux";


  // load the filled DEM
  LSDRaster filled_topo_test((path_name+DEM_name+fill_ext), DEM_bil_extension);

  // get a flow info object
  LSDFlowInfo FlowInfo(boundary_conditions,filled_topo_test);

  // calcualte the distance from outlet
  LSDRaster DistanceFromOutlet = FlowInfo.distance_from_outlet();
  LSDIndexRaster ContributingPixels = FlowInfo.write_NContributingNodes_to_LSDIndexRaster();

  // get the sources
  vector<int> sources;
  sources = FlowInfo.get_sources_index_threshold(ContributingPixels, threshold);

  // now get the junction network
  LSDJunctionNetwork ChanNetwork(sources, FlowInfo);

  // now get a junction and look for the longest channel upstream
  cout << "creating main stem" << endl;
  LSDIndexChannel main_stem = ChanNetwork.generate_longest_index_channel_in_basin(junction_number, FlowInfo, DistanceFromOutlet);
        cout << "got main stem channel, with n_nodes " << main_stem.get_n_nodes_in_channel() <<  endl;

  string Basin_name = "_basin";
  LSDIndexRaster BasinArray = ChanNetwork.extract_basin_from_junction(junction_number,junction_number,FlowInfo);
  BasinArray.write_raster((path_name+DEM_name+Basin_name+jn_name),DEM_bil_extension);

  // now get the best fit m over n for all the tributaries
  int organization_switch = 1;
  int pruning_switch = 1;
  LSDIndexChannelTree ChannelTree(FlowInfo, ChanNetwork, junction_number, organization_switch,
                                        DistanceFromOutlet, pruning_switch, pruning_threshold);

  // print a file that can be ingested bt the chi fitting algorithm
  string Chan_fname = "_ChanNet";
  string Chan_ext = ".chan";
  string Chan_for_chi_ingestion_fname = path_name+DEM_name+Chan_fname+jn_name+Chan_ext;
  ChannelTree.print_LSDChannels_for_chi_network_ingestion(FlowInfo,
                             filled_topo_test, DistanceFromOutlet, Chan_for_chi_ingestion_fname);
  ChannelTree.convert_chan_file_for_ArcMap_ingestion(Chan_for_chi_ingestion_fname);

}
Example #7
0
void pde(double t, double ****f, double ****df)
{
   int i,j,k,l,m,n;
   double dv1[7][3],dv2[7][3],dA11[7][3][3],dp1[3],dn1[3],w,dw;

   boundary_conditions(f);

//   omega(t,&w,&dw);
   for(i=0;i<m1;i++)
   for(j=ghost;j<mm2;j++)
   for(k=0;k<m3;k++)
   {
     if(isType(node[i][k],NodeFluid) && !isType(node[i][k],NodeClued))
     {
/*      for(m=0;m<3;m++)
         dp1[m]=dr(f[0],i,j,k,m+1,0,dx[m],ghost, approx);
      for(l=1;l<=3;l++) {
       for(m=0;m<3;m++) {
         dv1[l][m]=dr(f[l],i,j,k,m+1,0,dx[m],ghost, approx);
         dv2[l][m]=dr(f[l],i,j,k,m+1,1,dx[m]*dx[m],ghost, approx);
         }
       dv1[l][1] *= r_1[i];     dv2[l][1] *= r_2[i];
       }
      df[1][i][j][k]=nut[i][j][k]*(dv2[1][0]+dv2[1][1]+dv2[1][2]+r_1[i]*dv1[1][0]
                                   -f[1][i][j][k]*r_2[i]+2*dv1[2][1]*r_1[i])
                     -dp1[0]+w*w/r_1[i]       +2*w*f[2][i][j][k]                   //forces of inertion
                     +(j+n[2]<=ghost+2 ? coordin(k,2)*f[2][i][j][k] : 0)                //helical force
                     -f[1][i][j][k]*dv1[1][0]-f[2][i][j][k]*dv1[1][1]
                     -f[3][i][j][k]*dv1[1][2]+r_2[i]*f[2][i][j][k]*f[2][i][j][k];
      df[2][i][j][k]=nut[i][j][k]*(dv2[2][0]+dv2[2][1]+dv2[2][2]+r_1[i]*dv1[2][0]
                                   -f[2][i][j][k]*r_2[i]+2*dv1[1][1]*r_1[i])
                     -dp1[1]*r_1[i]-dw/r_1[i] -2*w*f[1][i][j][k]                   //forces of inertion
                     -(j<=ghost+2 ? (coordin(i,2)-rc)*f[2][i][j][k] :0)            //helical force
                     -f[1][i][j][k]*dv1[2][0]-f[2][i][j][k]*dv1[2][1]
                     -f[3][i][j][k]*dv1[2][2]-r_1[i]*f[1][i][j][k]*f[2][i][j][k];
      df[3][i][j][k]=nut[i][j][k]*(dv2[3][0]+dv2[3][1]+dv2[3][2]+r_1[i]*dv1[3][0])
                     -dp1[2]
                     -f[1][i][j][k]*dv1[3][0]-f[2][i][j][k]*dv1[3][1]-f[3][i][j][k]*dv1[3][2];
      df[0][i][j][k]= -(dv1[1][0]+dv1[2][1]+dv1[3][2]+f[1][i][j][k]*r_1[i])/Gamma;*/
      df[0][i][j][k] = df[1][i][j][k] = df[2][i][j][k] = df[3][i][j][k] = 0;
      }
     if(isType(node[i][k],NodeMagn) && !isType(node[i][k],NodeClued))
      {
      for(l=4;l<=6;l++) {
       for(m=0;m<3;m++) {
         dv1[l][m]=dr(f[l],i,j,k,m+1,0,dx[m],ghost, approx);
         dv2[l][m]=dr(f[l],i,j,k,m+1,1,dx[m]*dx[m],ghost, approx);
         for(n=0;n<3;n++) if(n!=m)
              dA11[l][m][n]=d2cross(f[l],i,j,k,m+1,n+1,ghost,approx);
         }
        dv1[l][1] *= r_1[i];     dv2[l][1] *= r_2[i];
        for(n=0;n<3;n++) {dA11[l][1][n] *= r_1[i];
                          dA11[l][n][1] *= r_1[i];}
        }

       df[4][i][j][k]=f[2][i][j][k]*(dv1[5][0]-dv1[4][1]+f[5][i][j][k]*r_1[i])-f[3][i][j][k]*(dv1[4][2]-dv1[6][0])
                     +eta[i][j][k]*(dv2[4][0]+dv2[4][1]+dv2[4][2]+r_1[i]*dv1[4][0]-f[4][i][j][k]*r_2[i]-2*dv1[5][1]*r_1[i])
                     +(1./Rm-eta[i][j][k])*(dv2[4][0]+dv1[4][0]*r_1[i]-f[4][i][j][k]*r_2[i]-dv1[5][1]*r_1[i]+dA11[5][0][1]+dA11[6][0][2]);
       df[5][i][j][k]=f[3][i][j][k]*(dv1[6][1]-dv1[5][2])-f[1][i][j][k]*(dv1[5][0]-dv1[4][1]+f[5][i][j][k]*r_1[i])
                     +eta[i][j][k]*(dv2[5][0]+dv2[5][1]+dv2[5][2]+r_1[i]*dv1[5][0]-f[5][i][j][k]*r_2[i]+2*dv1[4][1]*r_1[i])
                     +(1./Rm-eta[i][j][k])*(dv1[4][1]*r_1[i]+dA11[4][0][1]+dv2[5][1]+dA11[6][1][2]);
       df[6][i][j][k]=f[1][i][j][k]*(dv1[4][2]-dv1[6][0])-f[2][i][j][k]*(dv1[6][1]-dv1[5][2])
                     +eta[i][j][k]*(dv2[6][0]+dv2[6][1]+dv2[6][2]+r_1[i]*dv1[6][0])
                     +(1./Rm-eta[i][j][k])*(dv1[4][2]*r_1[i]+dA11[4][0][2]+dA11[5][1][2]+dv2[6][2]);
/*       df[4][i][j][k]=eta[i][j][k]*(dv2[4][0]+dv2[4][1]+dv2[4][2]+r_1[i]*dv1[4][0]-f[4][i][j][k]*r_2[i]-2*dv1[5][1]*r_1[i]);
       df[5][i][j][k]=f[3][i][j][k]*(dv1[6][1]-dv1[5][2])-f[1][i][j][k]*(dv1[5][0]-dv1[4][1]+f[5][i][j][k]*r_1[i])
                     +eta[i][j][k]*(dv2[5][0]+dv2[5][1]+dv2[5][2]+r_1[i]*dv1[5][0]-f[5][i][j][k]*r_2[i]+2*dv1[4][1]*r_1[i])
                     +(1./Rm-eta[i][j][k])*(dv1[4][1]*r_1[i]+dA11[4][0][1]+dv2[5][1]+dA11[6][1][2]);
       df[6][i][j][k]=0;*/
      }
  } //global for
   return;
}
int main (int nNumberofArgs,char *argv[])
{
	//Test for correct input arguments
	if (nNumberofArgs!=3)
	{
		cout << "FATAL ERROR: wrong number inputs. The program needs the path name and the file name" << endl;
		exit(EXIT_SUCCESS);
	}

	string path_name = argv[1];
	string f_name = argv[2];

	cout << "The path is: " << path_name << " and the filename is: " << f_name << endl;

	string full_name = path_name+f_name;

	ifstream file_info_in;
	file_info_in.open(full_name.c_str());
	if( file_info_in.fail() )
	{
		cout << "\nFATAL ERROR: the header file \"" << full_name
		     << "\" doesn't exist" << endl;
		exit(EXIT_FAILURE);
	}

	string DEM_name;
	string fill_ext = "_fill";
	file_info_in >> DEM_name;
	int threshold;
	float Minimum_Slope;
	float curv_threshold;
	float minimum_catchment_area;

	file_info_in >> Minimum_Slope >> threshold >> curv_threshold >> minimum_catchment_area;

	// get some file names
	string DEM_f_name = path_name+DEM_name+fill_ext;
	string DEM_flt_extension = "bil";

	// load the DEM
	LSDRaster topo_test((path_name+DEM_name), DEM_flt_extension);
  LSDRasterSpectral SpectralRaster(topo_test);                        
//   int FilterType = 2;
//   float FLow = 0.01;
//   float FHigh = 0.1;
//   LSDRaster topo_test_filtered = SpectralRaster.fftw2D_filter(FilterType, FLow, FHigh);
  LSDRaster topo_test_wiener = SpectralRaster.fftw2D_wiener();
  int border_width = 100;	
//   topo_test_filtered = topo_test_filtered.border_with_nodata(border_width);
	topo_test_wiener = topo_test_wiener.border_with_nodata(border_width);       
	
	// Set the no flux boundary conditions
  vector<string> boundary_conditions(4);
	boundary_conditions[0] = "No";
	boundary_conditions[1] = "no flux";
	boundary_conditions[2] = "no flux";
	boundary_conditions[3] = "No flux";
	
		// get the filled file
	cout << "Filling the DEM" << endl;
// 	LSDRaster filled_topo_test = topo_test_filtered.fill(Minimum_Slope);
	LSDRaster filled_topo_test = topo_test_wiener.fill(Minimum_Slope);
	filled_topo_test.write_raster((DEM_f_name),DEM_flt_extension);
  
  //get a FlowInfo object
	LSDFlowInfo FlowInfo(boundary_conditions,filled_topo_test); 
	LSDIndexRaster ContributingPixels = FlowInfo.write_NContributingNodes_to_LSDIndexRaster();	
	vector<int> sources;
	sources = FlowInfo.get_sources_index_threshold(ContributingPixels, threshold); 

  // now get the junction network
	LSDJunctionNetwork ChanNetwork(sources, FlowInfo);
	
	// Get the valleys using the contour curvature
	
  int surface_fitting_window_radius = 7;
  int surface_fitting_window_radius_LW = 25;
  vector<LSDRaster> surface_fitting, surface_fitting_LW;
  LSDRaster tan_curvature;
  LSDRaster tan_curvature_LW;
  string curv_name = "_tan_curv";
  vector<int> raster_selection(8, 0);
  raster_selection[6] = 1;
  surface_fitting = topo_test_wiener.calculate_polyfit_surface_metrics(surface_fitting_window_radius, raster_selection);
  surface_fitting_LW = topo_test_wiener.calculate_polyfit_surface_metrics(surface_fitting_window_radius_LW, raster_selection);
  
  for(int i = 0; i<int(raster_selection.size()); ++i)
	{
		if(raster_selection[i]==1)
		{
      tan_curvature = surface_fitting[i];
      tan_curvature.write_raster((path_name+DEM_name+curv_name), DEM_flt_extension);
      tan_curvature_LW = surface_fitting[i];
      tan_curvature_LW.write_raster((path_name+DEM_name+curv_name+"_LW"), DEM_flt_extension);
    }
  }

	string CH_name = "_CH_Pelletier";
	Array2D<float> topography = filled_topo_test.get_RasterData();
	Array2D<float> curvature = tan_curvature.get_RasterData();
	Array2D<float> curvature_LW = tan_curvature_LW.get_RasterData();
	cout << "\tLocating channel heads..." << endl;
  vector<int> ChannelHeadNodes = ChanNetwork.calculate_pelletier_channel_heads_DTM(FlowInfo, topography, curv_threshold, curvature,curvature_LW);
  
  // Now filter out false positives along channel according to a threshold 
  // catchment area
  cout << "\tFiltering out false positives..." << endl;
  LSDJunctionNetwork ChanNetworkNew(ChannelHeadNodes, FlowInfo);
	vector<int> ChannelHeadNodesFilt;
  int count = 0;
  for(int i = 0; i<int(ChannelHeadNodes.size()); ++i)
	{
    int upstream_junc = ChanNetworkNew.get_Junction_of_Node(ChannelHeadNodes[i], FlowInfo);
    int test_node = ChanNetworkNew.get_penultimate_node_from_stream_link(upstream_junc, FlowInfo);
    float catchment_area = float(FlowInfo.retrieve_contributing_pixels_of_node(test_node)) * FlowInfo.get_DataResolution();
    if (catchment_area >= minimum_catchment_area) ChannelHeadNodesFilt.push_back(ChannelHeadNodes[i]);
    else ++count;
  }
  cout << "\t...removed " << count << " nodes out of " << ChannelHeadNodes.size() << endl;
  FlowInfo.print_vector_of_nodeindices_to_csv_file(ChannelHeadNodesFilt,(path_name+DEM_name+CH_name));
  //LSDIndexRaster Channel_heads_raster = FlowInfo.write_NodeIndexVector_to_LSDIndexRaster(ChannelHeadNodesFilt);
  //Channel_heads_raster.write_raster((path_name+DEM_name+CH_name),DEM_flt_extension);
	
	//create a channel network based on these channel heads
	LSDJunctionNetwork NewChanNetwork(ChannelHeadNodesFilt, FlowInfo);
  LSDIndexRaster SOArrayNew = NewChanNetwork.StreamOrderArray_to_LSDIndexRaster();
	string SO_name_new = "_SO_Pelletier";
	
	SOArrayNew.write_raster((path_name+DEM_name+SO_name_new),DEM_flt_extension);	
                              
}