Example #1
0
int main(int argc, char *argv[]) {
	
	char buffer_vtk[100], buffer_plt[100]; 
	string MeshFile;
	unsigned short nZone = 1;
    
#ifndef NO_MPI
#ifdef WINDOWS
	MPI_Init(&argc,&argv);
#else
    MPI::Init(argc, argv);
#endif
#endif
  
	/*--- Definition of the class for the definition of the problem ---*/
	CConfig *config;
	if (argc == 2) config = new CConfig(argv[1], SU2_PBC, ZONE_0, nZone, 0, VERB_HIGH);
	else {
		char grid_file[200];
		strcpy (grid_file, "default.cfg");
		config = new CConfig(grid_file, SU2_PBC, ZONE_0, nZone, 0, VERB_HIGH);
	}

	/*--- Definition of the class for the geometry ---*/
	CGeometry *geometry; geometry = new CGeometry;
	geometry = new CPhysicalGeometry(config, ZONE_0, nZone);
  
  /*--- Perform the non-dimensionalization, in case any values are needed ---*/
  config->SetNondimensionalization(geometry->GetnDim(), ZONE_0);
  
	cout << endl <<"----------------------- Preprocessing computations ----------------------" << endl;
	
	/*--- Compute elements surrounding points, points surrounding points, and elements surrounding elements ---*/
	cout << "Setting local point and element connectivity." <<endl; 
	geometry->SetEsuP(); geometry->SetPsuP(); geometry->SetEsuE();
	
	/*--- Check the orientation before computing geometrical quantities ---*/
	cout << "Checking the numerical grid orientation." <<endl;
	geometry->SetBoundVolume(); geometry->Check_Orientation(config);
	
	/*--- Create the edge structure ---*/
	cout << "Identifying edges and vertices." <<endl; 
	geometry->SetEdges(); geometry->SetVertex(config); 
	
	/*--- Compute center of gravity ---*/
	cout << "Computing centers of gravity." << endl;
	geometry->SetCG();
  
	/*--- Create the control volume structures ---*/
	cout << "Setting the control volume structure." << endl; 
	geometry->SetControlVolume(config, ALLOCATE);
	geometry->SetBoundControlVolume(config, ALLOCATE);
	
	cout << endl <<"-------------------- Setting the periodic boundaries --------------------" << endl;

	/*--- Set periodic boundary conditions ---*/
	geometry->SetPeriodicBoundary(config);
	
  /*--- Original grid for debugging purposes ---*/
  strcpy (buffer_plt, "periodic_original.plt"); geometry->SetTecPlot(buffer_plt);
 
	/*--- Create a new grid with the right periodic boundary ---*/
	CGeometry *periodic; periodic = new CPeriodicGeometry(geometry, config);
	periodic->SetPeriodicBoundary(geometry, config);
	periodic->SetMeshFile(geometry, config, config->GetMesh_Out_FileName());
	
	/*--- Output of the grid for debuging purposes ---*/
  strcpy (buffer_plt, "periodic_halo.plt"); periodic->SetTecPlot(buffer_plt);
	
#ifndef NO_MPI
#ifdef WINDOWS
	MPI_Finalize();
#else
	MPI::Finalize();
#endif
#endif
    
	/*--- End solver ---*/
	cout << endl <<"------------------------- Exit Success (SU2_PBC) ------------------------" << endl << endl;
	
	return EXIT_SUCCESS;
}
Example #2
0
int main(int argc, char *argv[]) {
	
	/*--- Variable definitions ---*/
	char file_name[200];
  unsigned short nZone = 1;
  
#ifndef NO_MPI
#ifdef WINDOWS
	MPI_Init(&argc,&argv);
#else
	MPI::Init(argc, argv);
#endif
#endif
	
	/*--- Definition of the config problem ---*/
	CConfig *config;
	if (argc == 2) config = new CConfig(argv[1], SU2_MAC, ZONE_0, nZone, VERB_HIGH);
	else { strcpy (file_name, "default.cfg"); config = new CConfig(file_name, SU2_MAC, ZONE_0, nZone, VERB_HIGH); }
	
	/*--- Definition of the Class for the geometry ---*/
	CGeometry *geometry; geometry = new CGeometry;
	geometry = new CPhysicalGeometry(config, ZONE_0, nZone);
	
  /*--- Perform the non-dimensionalization, in case any values are needed ---*/
  config->SetNondimensionalization(geometry->GetnDim(), ZONE_0);
  
	cout << endl <<"----------------------- Preprocessing computations ----------------------" << endl;
	
	/*--- Compute elements surrounding points, points surrounding points, and elements surronding elements ---*/
	cout << "Setting local point and element connectivity." <<endl;
	geometry->SetEsuP(); geometry->SetPsuP(); geometry->SetEsuE();
	
	/*--- Check the orientation before computing geometrical quantities ---*/
	cout << "Check numerical grid orientation." <<endl;
	geometry->SetBoundVolume(); geometry->Check_Orientation(config);
	
	/*--- Create the edge structure ---*/
	cout << "Identify faces, edges and vertices." <<endl;
	geometry->SetFaces(); geometry->SetEdges(); geometry->SetVertex(config); geometry->SetCG();
	
	/*--- Create the control volume structures ---*/
	cout << "Set control volume structure." << endl;
	geometry->SetControlVolume(config, ALLOCATE); geometry->SetBoundControlVolume(config, ALLOCATE);
	
	/*--- Set the near-field and interface boundary conditions  ---*/
	geometry->MatchNearField(config);
	
	if (config->GetKind_Adaptation() != NONE) {
		
		cout << endl <<"--------------------- Start numerical grid adaptation -------------------" << endl;
		
		/*-- Definition of the Class for grid adaptation ---*/
		CGridAdaptation *grid_adaptation;
		grid_adaptation = new CGridAdaptation(geometry, config);
		
		/*--- Read the flow solution and/or the adjoint solution
		 and choose the elements to adapt ---*/
		if ((config->GetKind_Adaptation() != NONE) && (config->GetKind_Adaptation() != FULL)
				&& (config->GetKind_Adaptation() != WAKE) && (config->GetKind_Adaptation() != TWOPHASE)
				&& (config->GetKind_Adaptation() != SMOOTHING) && (config->GetKind_Adaptation() != SUPERSONIC_SHOCK))
			grid_adaptation->GetFlowSolution(geometry, config);
		
		switch (config->GetKind_Adaptation()) {
			case NONE:
				break;
			case SMOOTHING:
				config->SetSmoothNumGrid(true);
				grid_adaptation->SetNo_Refinement(geometry, 1);
				break;
			case FULL:
				grid_adaptation->SetComplete_Refinement(geometry, 1);
				break;
			case WAKE:
				grid_adaptation->SetWake_Refinement(geometry, 1);
				break;
			case TWOPHASE:
				grid_adaptation->SetTwoPhase_Refinement(geometry, 1);
				break;
			case SUPERSONIC_SHOCK:
				grid_adaptation->SetSupShock_Refinement(geometry, config);
				break;
			case FULL_FLOW:
				grid_adaptation->SetComplete_Refinement(geometry, 1);
				break;
			case FULL_ADJOINT:
				grid_adaptation->GetAdjSolution(geometry, config);
				grid_adaptation->SetComplete_Refinement(geometry, 1);
				break;
			case FULL_LINEAR:
				grid_adaptation->GetLinSolution(geometry, config);
				grid_adaptation->SetComplete_Refinement(geometry, 1);
				break;
			case GRAD_FLOW:
				grid_adaptation->SetIndicator_Flow(geometry, config, 1);
				break;
			case GRAD_ADJOINT:
				grid_adaptation->GetAdjSolution(geometry, config);
				grid_adaptation->SetIndicator_Adj(geometry, config, 1);
				break;
			case GRAD_FLOW_ADJ:
				grid_adaptation->GetAdjSolution(geometry, config);
				grid_adaptation->SetIndicator_FlowAdj(geometry, config);
				break;
			case COMPUTABLE:
				grid_adaptation->GetAdjSolution(geometry, config);
				grid_adaptation->GetFlowResidual(geometry, config);
				grid_adaptation->SetIndicator_Computable(geometry, config);
				break;
			case REMAINING:
				cout << "Adaptation method not implemented."<< endl;
				cout << "Press any key to exit..." << endl;
				cin.get();
				exit(1);
				break;
			case ROBUST:
				grid_adaptation->GetFlowResidual(geometry, config);
				grid_adaptation->GetAdjResidual(geometry, config);
				grid_adaptation->SetIndicator_Robust(geometry, config);
				break;
			case COMPUTABLE_ROBUST:
				grid_adaptation->GetAdjSolution(geometry, config);
				grid_adaptation->GetLinResidual(geometry, config);
				grid_adaptation->SetIndicator_Computable_Robust(geometry, config);
				break;
			default :
				cout << "The adaptation is not defined" << endl;
		}
		
		/*--- Perform an homothetic adaptation of the grid ---*/
		CPhysicalGeometry *geo_adapt; geo_adapt = new CPhysicalGeometry;
		
		cout << "Homothetic grid adaptation" << endl;
		if (geometry->GetnDim() == 2) grid_adaptation->SetHomothetic_Adaptation2D(geometry, geo_adapt, config);
		if (geometry->GetnDim() == 3) grid_adaptation->SetHomothetic_Adaptation3D(geometry, geo_adapt, config);
    
		/*--- Smooth the numerical grid coordinates ---*/
		if (config->GetSmoothNumGrid()) {
			cout << "Preprocessing for doing the implicit smoothing." << endl;
			geo_adapt->SetEsuP(); geo_adapt->SetPsuP(); geo_adapt->SetEsuE();
			geo_adapt->SetBoundVolume(); geo_adapt->Check_Orientation(config);
			geo_adapt->SetEdges(); geo_adapt->SetVertex(config);
			cout << "Implicit smoothing of the numerical grid coordinates." << endl;
			geo_adapt->SetCoord_Smoothing(5, 1.5, config);
		}
		
		/*--- Original and adapted grid ---*/
    strcpy (file_name, "original_grid.plt");
    geometry->SetTecPlot(file_name);
    
		/*--- Write the adaptation sensor ---*/
		grid_adaptation->WriteAdaptSensor(geometry, file_name);
		
    strcpy (file_name, "adapted_grid.plt");
    geo_adapt->SetTecPlot(file_name);
    strcpy (file_name, "adapted_surface.plt");
    geo_adapt->SetBoundTecPlot(config,file_name);
		
		/*--- Write the new adapted grid, including the modified boundaries surfaces ---*/
		geo_adapt->SetMeshFile(config, config->GetMesh_Out_FileName());
    
    
		/*--- Write the restart file ---*/
		if ((config->GetKind_Adaptation() != SMOOTHING) && (config->GetKind_Adaptation() != FULL) &&
				(config->GetKind_Adaptation() != WAKE) && (config->GetKind_Adaptation() != TWOPHASE) &&
				(config->GetKind_Adaptation() != SUPERSONIC_SHOCK))
			grid_adaptation->SetRestart_FlowSolution(config, geo_adapt, config->GetRestart_FlowFileName());
		
		if ((config->GetKind_Adaptation() == GRAD_FLOW_ADJ) || (config->GetKind_Adaptation() == GRAD_ADJOINT)
				|| (config->GetKind_Adaptation() == FULL_ADJOINT) || (config->GetKind_Adaptation() == ROBUST)
				|| (config->GetKind_Adaptation() == COMPUTABLE) || (config->GetKind_Adaptation() == COMPUTABLE_ROBUST) ||
				(config->GetKind_Adaptation() == REMAINING))
			grid_adaptation->SetRestart_AdjSolution(config, geo_adapt, config->GetRestart_AdjFileName());
		
		if ((config->GetKind_Adaptation() == FULL_LINEAR) || (config->GetKind_Adaptation() == COMPUTABLE_ROBUST)) {
			grid_adaptation->SetRestart_LinSolution(config, geo_adapt, config->GetRestart_LinFileName());
		}
	}
	else {
    strcpy (file_name, "original_grid.plt");
    geometry->SetTecPlot(file_name);
		geometry->SetMeshFile (config, config->GetMesh_Out_FileName());
	}
  
#ifndef NO_MPI
#ifdef WINDOWS
	MPI_Finalize();
#else
	MPI::Finalize();
#endif
#endif
	
	/*--- End solver ---*/
	cout << endl <<"------------------------- Exit Success (SU2_MAC) ------------------------" << endl << endl;
  
	return EXIT_SUCCESS;
}
Example #3
0
int main(int argc, char *argv[]) {
  
  /*--- Local variables ---*/
  
	unsigned short iDV, nZone = 1, iFFDBox, iPlane, nPlane, iVar;
	double *ObjectiveFunc, *ObjectiveFunc_New, *Gradient, delta_eps, MinPlane, MaxPlane, MinXCoord, MaxXCoord,
  **Plane_P0, **Plane_Normal, Volume, Volume_New, Volume_Grad;
  vector<double> *Xcoord_Airfoil, *Ycoord_Airfoil, *Zcoord_Airfoil, *Variable_Airfoil;
  char grid_file[200], buffer_char[50], out_file[200];

 	char *cstr;
	ofstream Gradient_file, ObjFunc_file;
	int rank = MASTER_NODE;
  int size = SINGLE_NODE;
  
  /*--- MPI initialization ---*/

#ifndef NO_MPI
	MPI_Init(&argc,&argv);
	MPI_Comm_rank(MPI_COMM_WORLD,&rank);
  MPI_Comm_size(MPI_COMM_WORLD,&size);
#endif
	
	/*--- Pointer to different structures that will be used throughout the entire code ---*/
  
	CFreeFormDefBox** FFDBox = NULL;
	CConfig *config = NULL;
	CGeometry *boundary = NULL;
	CSurfaceMovement *surface_mov = NULL;
	
	/*--- Definition of the class for the definition of the problem ---*/
  
	if (argc == 2) config = new CConfig(argv[1], SU2_GDC, ZONE_0, nZone, 0, VERB_HIGH);
	else {
		strcpy (grid_file, "default.cfg");
		config = new CConfig(grid_file, SU2_GDC, ZONE_0, nZone, 0, VERB_HIGH);
	}
	
  /*--- Change the name of the input-output files for the parallel computation ---*/
  
#ifndef NO_MPI
	config->SetFileNameDomain(rank+1);
#endif
	
	/*--- Definition of the class for the boundary of the geometry ---*/
  
	boundary = new CBoundaryGeometry(config, config->GetMesh_FileName(), config->GetMesh_FileFormat());
  
  /*--- Set the number of sections, and allocate the memory ---*/
  
  if (boundary->GetnDim() == 2) nPlane = 1;
  else nPlane = config->GetnSections();

  Xcoord_Airfoil = new vector<double>[nPlane];
  Ycoord_Airfoil = new vector<double>[nPlane];
  Zcoord_Airfoil = new vector<double>[nPlane];
  Variable_Airfoil = new vector<double>[nPlane];

  Plane_P0 = new double*[nPlane];
  Plane_Normal = new double*[nPlane];
  for(iPlane = 0; iPlane < nPlane; iPlane++ ) {
    Plane_P0[iPlane] = new double[3];
    Plane_Normal[iPlane] = new double[3];
  }
  
  ObjectiveFunc = new double[nPlane*20];
  ObjectiveFunc_New = new double[nPlane*20];
  Gradient = new double[nPlane*20];

  for (iVar = 0; iVar < nPlane*20; iVar++) {
    ObjectiveFunc[iVar] = 0.0;
    ObjectiveFunc_New[iVar] = 0.0;
    Gradient[iVar] = 0.0;
  }
  
  /*--- Evaluation of the objective function ---*/
  
	if (rank == MASTER_NODE)
		cout << endl <<"----------------------- Preprocessing computations ----------------------" << endl;

  
  /*--- Boundary geometry preprocessing ---*/
  
	if (rank == MASTER_NODE) cout << "Identify vertices." <<endl;
	boundary->SetVertex();
  
  /*--- Compute elements surrounding points & points surrounding points ---*/
  
  if (rank == MASTER_NODE) cout << "Setting local point and element connectivity." << endl;
  boundary->SetEsuP();
	boundary->SetPsuP();
  boundary->SetEdges();

	/*--- Create the control volume structures ---*/
  
	if (rank == MASTER_NODE) cout << "Set boundary control volume structure." << endl;
	boundary->SetBoundControlVolume(config, ALLOCATE);
	
  /*--- Compute the surface curvature ---*/
  
  if (rank == MASTER_NODE) cout << "Compute the surface curvature." << endl;
  boundary->ComputeSurf_Curvature(config);
  
  if (rank == MASTER_NODE) cout << "Writing a Tecplot file of the surface curvature." << endl;
  if (size > 1) sprintf (buffer_char, "_%d.plt", rank+1); else sprintf (buffer_char, ".plt");
  strcpy (out_file, "Surface_Curvature"); strcat(out_file, buffer_char); boundary->SetBoundTecPlot(out_file, true, config);
  
	/*--- Create plane structure ---*/
  
  if (rank == MASTER_NODE) cout << "Set plane structure." << endl;
  if (boundary->GetnDim() == 2) {
    MinXCoord = -1E6; MaxXCoord = 1E6;
    Plane_Normal[0][0] = 0.0;   Plane_P0[0][0] = 0.0;
    Plane_Normal[0][1] = 1.0;   Plane_P0[0][1] = 0.0;
    Plane_Normal[0][2] = 0.0;   Plane_P0[0][2] = 0.0;
  }
  else if (boundary->GetnDim() == 3) {
    MinPlane = config->GetSection_Location(0); MaxPlane = config->GetSection_Location(1);
    MinXCoord = -1E6; MaxXCoord = 1E6;
    for (iPlane = 0; iPlane < nPlane; iPlane++) {
      Plane_Normal[iPlane][0] = 0.0;    Plane_P0[iPlane][0] = 0.0;
      Plane_Normal[iPlane][1] = 0.0;    Plane_P0[iPlane][1] = 0.0;
      Plane_Normal[iPlane][2] = 0.0;    Plane_P0[iPlane][2] = 0.0;
      Plane_Normal[iPlane][config->GetAxis_Orientation()] = 1.0;
      Plane_P0[iPlane][config->GetAxis_Orientation()] = MinPlane + iPlane*(MaxPlane - MinPlane)/double(nPlane-1);
    }
  }

  /*--- Create airfoil section structure ---*/
  
  if (rank == MASTER_NODE) cout << "Set airfoil section structure." << endl;
  for (iPlane = 0; iPlane < nPlane; iPlane++) {
    boundary->ComputeAirfoil_Section(Plane_P0[iPlane], Plane_Normal[iPlane], iPlane, MinXCoord, MaxXCoord, NULL,
                                     Xcoord_Airfoil[iPlane], Ycoord_Airfoil[iPlane], Zcoord_Airfoil[iPlane], Variable_Airfoil[iPlane], true, config);
  }
  
  /*--- Compute the internal volume of a 3D body. ---*/
  
  if (rank == MASTER_NODE)  cout << "Computing the internal volume." << endl;
  if (boundary->GetnDim() == 3) Volume = boundary->Compute_Volume(config, true);
  
  if (rank == MASTER_NODE)
    cout << endl <<"-------------------- Objective function evaluation ----------------------" << endl;

  if (rank == MASTER_NODE) {
    
    /*--- Evaluate objective function ---*/
    for (iPlane = 0; iPlane < nPlane; iPlane++) {

      if (Xcoord_Airfoil[iPlane].size() != 0) {
        
        cout << "\nSection " << (iPlane+1) << ". Plane (yCoord): " << Plane_P0[iPlane][1] << "." << endl;
        
        ObjectiveFunc[iPlane]           = boundary->Compute_MaxThickness(Plane_P0[iPlane], Plane_Normal[iPlane], iPlane, config, Xcoord_Airfoil[iPlane], Ycoord_Airfoil[iPlane], Zcoord_Airfoil[iPlane], true);
        ObjectiveFunc[1*nPlane+iPlane]  = boundary->Compute_Thickness(Plane_P0[iPlane], Plane_Normal[iPlane], iPlane, 0.250000, config, Xcoord_Airfoil[iPlane], Ycoord_Airfoil[iPlane], Zcoord_Airfoil[iPlane], true);
        ObjectiveFunc[2*nPlane+iPlane]  = boundary->Compute_Thickness(Plane_P0[iPlane], Plane_Normal[iPlane], iPlane, 0.333333, config, Xcoord_Airfoil[iPlane], Ycoord_Airfoil[iPlane], Zcoord_Airfoil[iPlane], true);
        ObjectiveFunc[3*nPlane+iPlane]  = boundary->Compute_Thickness(Plane_P0[iPlane], Plane_Normal[iPlane], iPlane, 0.500000, config, Xcoord_Airfoil[iPlane], Ycoord_Airfoil[iPlane], Zcoord_Airfoil[iPlane], true);
        ObjectiveFunc[4*nPlane+iPlane]  = boundary->Compute_Thickness(Plane_P0[iPlane], Plane_Normal[iPlane], iPlane, 0.666666, config, Xcoord_Airfoil[iPlane], Ycoord_Airfoil[iPlane], Zcoord_Airfoil[iPlane], true);
        ObjectiveFunc[5*nPlane+iPlane]  = boundary->Compute_Thickness(Plane_P0[iPlane], Plane_Normal[iPlane], iPlane, 0.750000, config, Xcoord_Airfoil[iPlane], Ycoord_Airfoil[iPlane], Zcoord_Airfoil[iPlane], true);
        ObjectiveFunc[6*nPlane+iPlane]  = boundary->Compute_Area(Plane_P0[iPlane], Plane_Normal[iPlane], iPlane, config, Xcoord_Airfoil[iPlane], Ycoord_Airfoil[iPlane], Zcoord_Airfoil[iPlane], true);
        ObjectiveFunc[7*nPlane+iPlane]  = boundary->Compute_AoA(Plane_P0[iPlane], Plane_Normal[iPlane], iPlane, Xcoord_Airfoil[iPlane], Ycoord_Airfoil[iPlane], Zcoord_Airfoil[iPlane], true);
        ObjectiveFunc[8*nPlane+iPlane]  = boundary->Compute_Chord(Plane_P0[iPlane], Plane_Normal[iPlane], iPlane, Xcoord_Airfoil[iPlane], Ycoord_Airfoil[iPlane], Zcoord_Airfoil[iPlane], true);
        
        cout << "Maximum thickness: "   << ObjectiveFunc[iPlane] << "." << endl;
        cout << "1/4 chord thickness: " << ObjectiveFunc[1*nPlane+iPlane] << "." << endl;
        cout << "1/3 chord thickness: " << ObjectiveFunc[2*nPlane+iPlane] << "." << endl;
        cout << "1/2 chord thickness: " << ObjectiveFunc[3*nPlane+iPlane] << "." << endl;
        cout << "2/3 chord thickness: " << ObjectiveFunc[4*nPlane+iPlane] << "." << endl;
        cout << "3/4 chord thickness: " << ObjectiveFunc[5*nPlane+iPlane] << "." << endl;
        cout << "Area: "                << ObjectiveFunc[6*nPlane+iPlane] << "." << endl;
        cout << "Angle of attack: "     << ObjectiveFunc[7*nPlane+iPlane] << "." << endl;
        cout << "Chord: "               << ObjectiveFunc[8*nPlane+iPlane] << "." << endl;
        
      }
      
    }
    
    /*--- The value for Volume to the area of the first section
     in case this is a 2D calculation ---*/
    
    if (boundary->GetnDim() == 2) Volume = ObjectiveFunc[6];
    cout << "\nInternal volume: " << Volume << "." << endl;
    
    /*--- Write the objective function in a external file ---*/
		cstr = new char [config->GetObjFunc_Value_FileName().size()+1];
		strcpy (cstr, config->GetObjFunc_Value_FileName().c_str());
		ObjFunc_file.open(cstr, ios::out);
    ObjFunc_file << "TITLE = \"SU2_GDC Simulation\"" << endl;
    
    if (boundary->GetnDim() == 2) {
      ObjFunc_file << "VARIABLES = \"MAX_THICKNESS\",\"1/4_THICKNESS\",\"1/3_THICKNESS\",\"1/2_THICKNESS\",\"2/3_THICKNESS\",\"3/4_THICKNESS\",\"AREA\",\"AOA\",\"CHORD\",\"VOLUME\"" << endl;
    }
    else if (boundary->GetnDim() == 3) {
      ObjFunc_file << "VARIABLES = ";
      for (iPlane = 0; iPlane < nPlane; iPlane++) ObjFunc_file << "\"MAX_THICKNESS_SEC"<< (iPlane+1) << "\", ";
      for (iPlane = 0; iPlane < nPlane; iPlane++) ObjFunc_file << "\"1/4_THICKNESS_SEC"<< (iPlane+1) << "\", ";
      for (iPlane = 0; iPlane < nPlane; iPlane++) ObjFunc_file << "\"1/3_THICKNESS_SEC"<< (iPlane+1) << "\", ";
      for (iPlane = 0; iPlane < nPlane; iPlane++) ObjFunc_file << "\"1/2_THICKNESS_SEC"<< (iPlane+1) << "\", ";
      for (iPlane = 0; iPlane < nPlane; iPlane++) ObjFunc_file << "\"2/3_THICKNESS_SEC"<< (iPlane+1) << "\", ";
      for (iPlane = 0; iPlane < nPlane; iPlane++) ObjFunc_file << "\"3/4_THICKNESS_SEC"<< (iPlane+1) << "\", ";
      for (iPlane = 0; iPlane < nPlane; iPlane++) ObjFunc_file << "\"AREA_SEC"<< (iPlane+1) << "\", ";
      for (iPlane = 0; iPlane < nPlane; iPlane++) ObjFunc_file << "\"AOA_SEC"<< (iPlane+1) << "\", ";
      for (iPlane = 0; iPlane < nPlane; iPlane++) ObjFunc_file << "\"CHORD_SEC"<< (iPlane+1) << "\", ";
      ObjFunc_file << "\"VOLUME\"" << endl;
    }
    
    ObjFunc_file << "ZONE T= \"Geometrical variables (value)\"" << endl;
    
    for (iPlane = 0; iPlane < nPlane*9; iPlane++)
      ObjFunc_file << ObjectiveFunc[iPlane] <<", ";
    ObjFunc_file << Volume << endl;

    ObjFunc_file.close();
    
	}
	
	if (config->GetGeometryMode() == GRADIENT) {
		
		/*--- Definition of the Class for surface deformation ---*/
		surface_mov = new CSurfaceMovement();
		
		/*--- Definition of the FFD deformation class ---*/
		FFDBox = new CFreeFormDefBox*[MAX_NUMBER_FFD];
		
		if (rank == MASTER_NODE)
			cout << endl <<"------------- Gradient evaluation using finite differences --------------" << endl;

		/*--- Write the gradient in a external file ---*/
		if (rank == MASTER_NODE) {
			cstr = new char [config->GetObjFunc_Grad_FileName().size()+1];
			strcpy (cstr, config->GetObjFunc_Grad_FileName().c_str());
			Gradient_file.open(cstr, ios::out);
		}
		
		for (iDV = 0; iDV < config->GetnDV(); iDV++) {
			   
      /*--- Free Form deformation based ---*/
      
      if ((config->GetDesign_Variable(iDV) == FFD_CONTROL_POINT_2D) ||
          (config->GetDesign_Variable(iDV) == FFD_CAMBER_2D) ||
          (config->GetDesign_Variable(iDV) == FFD_THICKNESS_2D) ||
          (config->GetDesign_Variable(iDV) == FFD_CONTROL_POINT) ||
          (config->GetDesign_Variable(iDV) == FFD_DIHEDRAL_ANGLE) ||
          (config->GetDesign_Variable(iDV) == FFD_TWIST_ANGLE) ||
          (config->GetDesign_Variable(iDV) == FFD_ROTATION) ||
          (config->GetDesign_Variable(iDV) == FFD_CAMBER) ||
          (config->GetDesign_Variable(iDV) == FFD_THICKNESS) ) {
        
        /*--- Read the FFD information in the first iteration ---*/
        
        if (iDV == 0) {
          
          if (rank == MASTER_NODE) cout << "Read the FFD information from mesh file." << endl;
          
          /*--- Read the FFD information from the grid file ---*/
          
          surface_mov->ReadFFDInfo(boundary, config, FFDBox, config->GetMesh_FileName(), true);
          
          /*--- If the FFDBox was not defined in the input file ---*/
          
          if (!surface_mov->GetFFDBoxDefinition() && (rank == MASTER_NODE)) {
            cout << "The input grid doesn't have the entire FFD information!" << endl;
            cout << "Press any key to exit..." << endl;
            cin.get();
          }
          
          if (rank == MASTER_NODE)
            cout <<"-------------------------------------------------------------------------" << endl;
          
        }
        
        if (rank == MASTER_NODE) {
          cout << endl << "Design variable number "<< iDV <<"." << endl;
          cout << "Perform 3D deformation of the surface." << endl;
        }
        
        /*--- Apply the control point change ---*/
        
        for (iFFDBox = 0; iFFDBox < surface_mov->GetnFFDBox(); iFFDBox++) {
          
          switch ( config->GetDesign_Variable(iDV) ) {
            case FFD_CONTROL_POINT_2D : surface_mov->SetFFDCPChange_2D(boundary, config, FFDBox[iFFDBox], iFFDBox, iDV, true); break;
            case FFD_CAMBER_2D : surface_mov->SetFFDCamber_2D(boundary, config, FFDBox[iFFDBox], iFFDBox, iDV, true); break;
            case FFD_THICKNESS_2D : surface_mov->SetFFDThickness_2D(boundary, config, FFDBox[iFFDBox], iFFDBox, iDV, true); break;
            case FFD_CONTROL_POINT : surface_mov->SetFFDCPChange(boundary, config, FFDBox[iFFDBox], iFFDBox, iDV, true); break;
            case FFD_DIHEDRAL_ANGLE : surface_mov->SetFFDDihedralAngle(boundary, config, FFDBox[iFFDBox], iFFDBox, iDV, true); break;
            case FFD_TWIST_ANGLE : surface_mov->SetFFDTwistAngle(boundary, config, FFDBox[iFFDBox], iFFDBox, iDV, true); break;
            case FFD_ROTATION : surface_mov->SetFFDRotation(boundary, config, FFDBox[iFFDBox], iFFDBox, iDV, true); break;
            case FFD_CAMBER : surface_mov->SetFFDCamber(boundary, config, FFDBox[iFFDBox], iFFDBox, iDV, true); break;
            case FFD_THICKNESS : surface_mov->SetFFDThickness(boundary, config, FFDBox[iFFDBox], iFFDBox, iDV, true); break;
          }
          
          /*--- Recompute cartesian coordinates using the new control points position ---*/
          
          surface_mov->SetCartesianCoord(boundary, config, FFDBox[iFFDBox], iFFDBox);
          
        }
        
      }
      
      /*--- Hicks Henne design variable ---*/
      
      else if (config->GetDesign_Variable(iDV) == HICKS_HENNE) {
        if (rank == MASTER_NODE) {
          cout << endl << "Design variable number "<< iDV <<"." << endl;
          cout << "Perform 2D deformation of the surface." << endl;
        }
        surface_mov->SetHicksHenne(boundary, config, iDV, true);
      }
      
      /*--- Displacement design variable ---*/
      
      else if (config->GetDesign_Variable(iDV) == DISPLACEMENT) {
        if (rank == MASTER_NODE) {
          cout << endl << "Design variable number "<< iDV <<"." << endl;
          cout << "Perform 2D deformation of the surface." << endl;
        }
        surface_mov->SetDisplacement(boundary, config, iDV, true);
      }
      
      /*--- Rotation design variable ---*/
      
      else if (config->GetDesign_Variable(iDV) == ROTATION) {
        if (rank == MASTER_NODE) {
          cout << endl << "Design variable number "<< iDV <<"." << endl;
          cout << "Perform 2D deformation of the surface." << endl;
        }
        surface_mov->SetRotation(boundary, config, iDV, true);
      }
      
      /*--- CosBump design variable ---*/
      
      else if (config->GetDesign_Variable(iDV) == COSINE_BUMP) {
        if (rank == MASTER_NODE) {
          cout << endl << "Design variable number "<< iDV <<"." << endl;
          cout << "Perform 2D deformation of the surface." << endl;
        }
        surface_mov->SetCosBump(boundary, config, iDV, true);
      }
      
      /*--- Fourier design variable ---*/
      
      else if (config->GetDesign_Variable(iDV) == FOURIER) {
        if (rank == MASTER_NODE) {
          cout << endl << "Design variable number "<< iDV <<"." << endl;
          cout << "Perform 2D deformation of the surface." << endl;
        }
        surface_mov->SetFourier(boundary, config, iDV, true);
      }
      
      /*--- NACA_4Digits design variable ---*/
      
      else if (config->GetDesign_Variable(iDV) == NACA_4DIGITS) {
        if (rank == MASTER_NODE) {
          cout << endl << "Design variable number "<< iDV <<"." << endl;
          cout << "Perform 2D deformation of the surface." << endl;
        }
        surface_mov->SetNACA_4Digits(boundary, config);
      }
      
      /*--- Parabolic design variable ---*/
      
      else if (config->GetDesign_Variable(iDV) == PARABOLIC) {
        if (rank == MASTER_NODE) {
          cout << endl << "Design variable number "<< iDV <<"." << endl;
          cout << "Perform 2D deformation of the surface." << endl;
        }
        surface_mov->SetParabolic(boundary, config);
      }
      
      /*--- Spherical design variable ---*/
      
      else if (config->GetDesign_Variable(iDV) == SPHERICAL) {
        if (rank == MASTER_NODE) {
          cout << endl << "Design variable number "<< iDV <<"." << endl;
          cout << "Perform 3D deformation of the surface." << endl;
        }
        surface_mov->SetSpherical(boundary, config, iDV, true);
      }
      
      /*--- Design variable not implement ---*/
      
      else { cout << "Design Variable not implement yet" << endl; }
      
      /*--- Create airfoil structure ---*/
      for (iPlane = 0; iPlane < nPlane; iPlane++) {
        boundary->ComputeAirfoil_Section(Plane_P0[iPlane], Plane_Normal[iPlane], iPlane, MinXCoord, MaxXCoord, NULL,
                                         Xcoord_Airfoil[iPlane], Ycoord_Airfoil[iPlane], Zcoord_Airfoil[iPlane], Variable_Airfoil[iPlane], false, config);
      }
      
      /*--- Compute the gradient for the volume. In 2D this is just
       the gradient of the area. ---*/
      
      if (boundary->GetnDim() == 3) Volume_New = boundary->Compute_Volume(config, false);
      
			/*--- Compute gradient ---*/
			if (rank == MASTER_NODE) {
        
        delta_eps = config->GetDV_Value(iDV);
        
        if (delta_eps == 0) {
          cout << "The finite difference steps is zero!!" << endl;
          cout << "Press any key to exit..." << endl;
          cin.get();
#ifdef NO_MPI
          exit(1);
#else
		  MPI_Abort(MPI_COMM_WORLD,1);
		  MPI_Finalize();
#endif
        }

        for (iPlane = 0; iPlane < nPlane; iPlane++) {
          
          if (Xcoord_Airfoil[iPlane].size() != 0) {
            
            cout << "\nSection " << (iPlane+1) << ". Plane (yCoord): " << Plane_P0[iPlane][1] << "." << endl;
            
            ObjectiveFunc_New[iPlane] = boundary->Compute_MaxThickness(Plane_P0[iPlane], Plane_Normal[iPlane], iPlane, config, Xcoord_Airfoil[iPlane], Ycoord_Airfoil[iPlane], Zcoord_Airfoil[iPlane], false);
            Gradient[iPlane] = (ObjectiveFunc_New[iPlane] - ObjectiveFunc[iPlane]) / delta_eps;
            
            ObjectiveFunc_New[1*nPlane + iPlane] = boundary->Compute_Thickness(Plane_P0[iPlane], Plane_Normal[iPlane], iPlane, 0.250000, config, Xcoord_Airfoil[iPlane], Ycoord_Airfoil[iPlane], Zcoord_Airfoil[iPlane], false);
            Gradient[1*nPlane + iPlane] = (ObjectiveFunc_New[1*nPlane + iPlane] - ObjectiveFunc[1*nPlane + iPlane]) / delta_eps;
            
            ObjectiveFunc_New[2*nPlane + iPlane] = boundary->Compute_Thickness(Plane_P0[iPlane], Plane_Normal[iPlane], iPlane, 0.333333, config, Xcoord_Airfoil[iPlane], Ycoord_Airfoil[iPlane], Zcoord_Airfoil[iPlane], false);
            Gradient[2*nPlane + iPlane] = (ObjectiveFunc_New[2*nPlane + iPlane] - ObjectiveFunc[2*nPlane + iPlane]) / delta_eps;
            
            ObjectiveFunc_New[3*nPlane + iPlane] = boundary->Compute_Thickness(Plane_P0[iPlane], Plane_Normal[iPlane], iPlane, 0.500000, config, Xcoord_Airfoil[iPlane], Ycoord_Airfoil[iPlane], Zcoord_Airfoil[iPlane], false);
            Gradient[3*nPlane + iPlane] = (ObjectiveFunc_New[3*nPlane + iPlane] - ObjectiveFunc[3*nPlane + iPlane]) / delta_eps;
            
            ObjectiveFunc_New[4*nPlane + iPlane] = boundary->Compute_Thickness(Plane_P0[iPlane], Plane_Normal[iPlane], iPlane, 0.666666, config, Xcoord_Airfoil[iPlane], Ycoord_Airfoil[iPlane], Zcoord_Airfoil[iPlane], false);
            Gradient[4*nPlane + iPlane] = (ObjectiveFunc_New[4*nPlane + iPlane] - ObjectiveFunc[4*nPlane + iPlane]) / delta_eps;
            
            ObjectiveFunc_New[5*nPlane + iPlane] = boundary->Compute_Thickness(Plane_P0[iPlane], Plane_Normal[iPlane], iPlane, 0.750000, config, Xcoord_Airfoil[iPlane], Ycoord_Airfoil[iPlane], Zcoord_Airfoil[iPlane], false);
            Gradient[5*nPlane + iPlane] = (ObjectiveFunc_New[5*nPlane + iPlane] - ObjectiveFunc[5*nPlane + iPlane]) / delta_eps;
            
            ObjectiveFunc_New[6*nPlane + iPlane] = boundary->Compute_Area(Plane_P0[iPlane], Plane_Normal[iPlane], iPlane, config, Xcoord_Airfoil[iPlane], Ycoord_Airfoil[iPlane], Zcoord_Airfoil[iPlane], false);
            Gradient[6*nPlane + iPlane] = (ObjectiveFunc_New[6*nPlane + iPlane] - ObjectiveFunc[6*nPlane + iPlane]) / delta_eps;
            
            ObjectiveFunc_New[7*nPlane + iPlane] = boundary->Compute_AoA(Plane_P0[iPlane], Plane_Normal[iPlane], iPlane, Xcoord_Airfoil[iPlane], Ycoord_Airfoil[iPlane], Zcoord_Airfoil[iPlane], false);
            Gradient[7*nPlane + iPlane] = (ObjectiveFunc_New[7*nPlane + iPlane] - ObjectiveFunc[7*nPlane + iPlane]) / delta_eps;
            
            ObjectiveFunc_New[8*nPlane + iPlane] = boundary->Compute_Chord(Plane_P0[iPlane], Plane_Normal[iPlane], iPlane, Xcoord_Airfoil[iPlane], Ycoord_Airfoil[iPlane], Zcoord_Airfoil[iPlane], false);
            Gradient[8*nPlane + iPlane] = (ObjectiveFunc_New[8*nPlane + iPlane] - ObjectiveFunc[8*nPlane + iPlane]) / delta_eps;
            
            cout << "Maximum thickness gradient: "    << Gradient[iPlane] << "." << endl;
            cout << "1/4 chord thickness gradient: "  << Gradient[1*nPlane + iPlane] << "." << endl;
            cout << "1/3 chord thickness gradient: "  << Gradient[2*nPlane + iPlane] << "." << endl;
            cout << "1/2 chord thickness gradient: "  << Gradient[3*nPlane + iPlane] << "." << endl;
            cout << "2/3 chord thickness gradient: "  << Gradient[4*nPlane + iPlane] << "." << endl;
            cout << "3/4 chord thickness gradient: "  << Gradient[5*nPlane + iPlane] << "." << endl;
            cout << "Area gradient: "                 << Gradient[6*nPlane + iPlane] << "." << endl;
            cout << "Angle of attack gradient: "      << Gradient[7*nPlane + iPlane] << "." << endl;
            cout << "Chord gradient: "                << Gradient[8*nPlane + iPlane] << "." << endl;
            
          }
          
        }
        
        /*--- Compute the gradient for the volume. In 2D this is just
         the gradient of the area. ---*/
        
        if (boundary->GetnDim() == 2) Volume_New = ObjectiveFunc_New[6];
        Volume_Grad = (Volume_New - Volume)/ delta_eps;
        cout << "\nInternal volume gradient: " << Volume_Grad << "." << endl;
 				
        if (iDV == 0) {
          Gradient_file << "TITLE = \"SU2_GDC Simulation\"" << endl;

          if (boundary->GetnDim() == 2) {
            Gradient_file << "VARIABLES = \"DESIGN_VARIABLE\",\"MAX_THICKNESS\",\"1/4_THICKNESS\",\"1/3_THICKNESS\",\"1/2_THICKNESS\",\"2/3_THICKNESS\",\"3/4_THICKNESS\",\"AREA\",\"AOA\",\"CHORD\",\"VOLUME\"" << endl;
          }
          else if (boundary->GetnDim() == 3) {
            Gradient_file << "VARIABLES = \"DESIGN_VARIABLE\",";
            for (iPlane = 0; iPlane < nPlane; iPlane++) Gradient_file << "\"MAX_THICKNESS_SEC"<< (iPlane+1) << "\", ";
            for (iPlane = 0; iPlane < nPlane; iPlane++) Gradient_file << "\"1/4_THICKNESS_SEC"<< (iPlane+1) << "\", ";
            for (iPlane = 0; iPlane < nPlane; iPlane++) Gradient_file << "\"1/3_THICKNESS_SEC"<< (iPlane+1) << "\", ";
            for (iPlane = 0; iPlane < nPlane; iPlane++) Gradient_file << "\"1/2_THICKNESS_SEC"<< (iPlane+1) << "\", ";
            for (iPlane = 0; iPlane < nPlane; iPlane++) Gradient_file << "\"2/3_THICKNESS_SEC"<< (iPlane+1) << "\", ";
            for (iPlane = 0; iPlane < nPlane; iPlane++) Gradient_file << "\"3/4_THICKNESS_SEC"<< (iPlane+1) << "\", ";
            for (iPlane = 0; iPlane < nPlane; iPlane++) Gradient_file << "\"AREA_SEC"<< (iPlane+1) << "\", ";
            for (iPlane = 0; iPlane < nPlane; iPlane++) Gradient_file << "\"AOA_SEC"<< (iPlane+1) << "\", ";
            for (iPlane = 0; iPlane < nPlane; iPlane++) Gradient_file << "\"CHORD_SEC"<< (iPlane+1) << "\", ";
            Gradient_file << "\"VOLUME\"" << endl;
          }
          
          Gradient_file << "ZONE T= \"Geometrical variables (gradient)\"" << endl;
          
        }
        
        Gradient_file << (iDV) <<", ";
        for (iPlane = 0; iPlane < nPlane*9; iPlane++)
          Gradient_file << Gradient[iPlane] <<", ";
        Gradient_file << Volume_Grad << endl;
        
				if (iDV != (config->GetnDV()-1)) cout <<"-------------------------------------------------------------------------" << endl;
				
			}

		}
		
		if (rank == MASTER_NODE)
			Gradient_file.close();
    
	}
	
  /*--- Finalize MPI parallelization ---*/
	
#ifndef NO_MPI
	MPI_Finalize();
#endif
	
  /*--- Deallocate memory ---*/
  
  delete [] Xcoord_Airfoil;
  delete [] Ycoord_Airfoil;
  delete [] Zcoord_Airfoil;
  
  delete [] ObjectiveFunc;
  delete [] ObjectiveFunc_New;
  delete [] Gradient;
  
  for(iPlane = 0; iPlane < nPlane; iPlane++ ) {
    delete Plane_P0[iPlane];
    delete Plane_Normal[iPlane];
  }
  delete [] Plane_P0;
  delete [] Plane_Normal;
  
  /*--- End solver ---*/
  
	if (rank == MASTER_NODE)
		cout << endl <<"------------------------- Exit Success (SU2_GDC) ------------------------" << endl << endl;

  
	return EXIT_SUCCESS;
	
}