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; }
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[MAX_STRING_SIZE], buffer_char[50], out_file[MAX_STRING_SIZE]; char *cstr; ofstream Gradient_file, ObjFunc_file; int rank = MASTER_NODE; int size = SINGLE_NODE; /*--- MPI initialization ---*/ #ifdef HAVE_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_GEO, ZONE_0, nZone, 0, VERB_HIGH); else { strcpy (grid_file, "default.cfg"); config = new CConfig(grid_file, SU2_GEO, ZONE_0, nZone, 0, VERB_HIGH); } /*--- Change the name of the input-output files for the parallel computation ---*/ #ifdef HAVE_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->SetPoint_Connectivity(); 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_GEO 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], iDV, true); break; case FFD_CAMBER_2D : surface_mov->SetFFDCamber_2D(boundary, config, FFDBox[iFFDBox], iDV, true); break; case FFD_THICKNESS_2D : surface_mov->SetFFDThickness_2D(boundary, config, FFDBox[iFFDBox], iDV, true); break; case FFD_CONTROL_POINT : surface_mov->SetFFDCPChange(boundary, config, FFDBox[iFFDBox], iDV, true); break; case FFD_DIHEDRAL_ANGLE : surface_mov->SetFFDDihedralAngle(boundary, config, FFDBox[iFFDBox], iDV, true); break; case FFD_TWIST_ANGLE : surface_mov->SetFFDTwistAngle(boundary, config, FFDBox[iFFDBox], iDV, true); break; case FFD_ROTATION : surface_mov->SetFFDRotation(boundary, config, FFDBox[iFFDBox], iDV, true); break; case FFD_CAMBER : surface_mov->SetFFDCamber(boundary, config, FFDBox[iFFDBox], iDV, true); break; case FFD_THICKNESS : surface_mov->SetFFDThickness(boundary, config, FFDBox[iFFDBox], iDV, true); break; case FFD_CONTROL_SURFACE : surface_mov->SetFFDControl_Surface(boundary, config, FFDBox[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 HAVE_MPI MPI_Abort(MPI_COMM_WORLD,1); MPI_Finalize(); #else exit(1); #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_GEO 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 ---*/ #ifdef HAVE_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_GEO) ------------------------" << endl << endl; return EXIT_SUCCESS; }
int main(int argc, char *argv[]) { /*--- Local variables ---*/ unsigned short iMarker, iDim, iDV, iFFDBox, nZone = 1; unsigned long iVertex, iPoint; double delta_eps, my_Gradient, Gradient, *Normal, dS; double *VarCoord, Sensitivity; double dalpha[3], deps[3], dalpha_deps; char *cstr; ofstream Gradient_file, Jacobian_file; bool *UpdatePoint, Comma; int rank = MASTER_NODE; int size = SINGLE_NODE; #ifndef NO_MPI /*--- MPI initialization, and buffer setting ---*/ MPI::Init(argc,argv); rank = MPI::COMM_WORLD.Get_rank(); size = MPI::COMM_WORLD.Get_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_GPC, ZONE_0, nZone, VERB_HIGH); else { char grid_file[200]; strcpy (grid_file, "default.cfg"); config = new CConfig(grid_file, SU2_GPC, ZONE_0, nZone, VERB_HIGH); } #ifndef NO_MPI /*--- Change the name of the input-output files for the parallel computation ---*/ config->SetFileNameDomain(rank+1); #endif /*--- Definition of the Class for the boundary of the geometry, note that the orientation of the elements is not checked ---*/ boundary = new CBoundaryGeometry(config, config->GetMesh_FileName(), config->GetMesh_FileFormat()); /*--- Perform the non-dimensionalization, in case any values are needed ---*/ config->SetNondimensionalization(boundary->GetnDim(), ZONE_0); if (rank == MASTER_NODE) cout << endl <<"----------------------- Preprocessing computations ----------------------" << endl; /*--- Boundary geometry preprocessing ---*/ if (rank == MASTER_NODE) cout << "Identify vertices." <<endl; boundary->SetVertex(); /*--- Create the control volume structures ---*/ if (rank == MASTER_NODE) cout << "Set boundary control volume structure." << endl; boundary->SetBoundControlVolume(config, ALLOCATE); /*--- Load the surface sensitivities from file. This is done only once: if this is an unsteady problem, a time-average of the surface sensitivities at each node is taken within this routine. ---*/ if (rank == MASTER_NODE) cout << "Reading surface sensitivities at each node from file." << endl; boundary->SetBoundSensitivity(config); /*--- Boolean controlling points to be updated ---*/ UpdatePoint = new bool[boundary->GetnPoint()]; /*--- Definition of the Class for surface deformation ---*/ surface_mov = new CSurfaceMovement(); /*--- Definition of the FFD deformation class ---*/ unsigned short nFFDBox = MAX_NUMBER_FFD; FFDBox = new CFreeFormDefBox*[nFFDBox]; if (rank == MASTER_NODE) cout << endl <<"---------- Start gradient evaluation using surface sensitivity ----------" << 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); /*--- Write an additional file with the geometric Jacobian ---*/ /*--- WARNING: This is only for serial calculations!!! ---*/ if (size == SINGLE_NODE) { Jacobian_file.open("geo_jacobian.csv", ios::out); Jacobian_file.precision(15); /*--- Write the CSV file header ---*/ Comma = false; for (iMarker = 0; iMarker < config->GetnMarker_All(); iMarker++) { if (config->GetMarker_All_DV(iMarker) == YES) { for (iVertex = 0; iVertex < boundary->nVertex[iMarker]; iVertex++) { iPoint = boundary->vertex[iMarker][iVertex]->GetNode(); if (!Comma) { Jacobian_file << "\t\"DesignVariable\""; Comma = true;} Jacobian_file << ", " << "\t\"" << iPoint << "\""; } } } Jacobian_file << endl; } } for (iDV = 0; iDV < config->GetnDV(); iDV++) { if (size == SINGLE_NODE) { Jacobian_file << iDV; } /*--- Bump deformation for 2D problems ---*/ if (boundary->GetnDim() == 2) { if (rank == MASTER_NODE) cout << "Perform 2D deformation of the surface." << endl; switch ( config->GetDesign_Variable(iDV) ) { case COSINE_BUMP : surface_mov->SetCosBump(boundary, config, iDV, true); break; case FOURIER : surface_mov->SetFourier(boundary, config, iDV, true); break; case HICKS_HENNE : surface_mov->SetHicksHenne(boundary, config, iDV, true); break; case DISPLACEMENT : surface_mov->SetDisplacement(boundary, config, iDV, true); break; case ROTATION : surface_mov->SetRotation(boundary, config, iDV, true); break; case NACA_4DIGITS : surface_mov->SetNACA_4Digits(boundary, config); break; case PARABOLIC : surface_mov->SetParabolic(boundary, config); break; } } /*--- Free Form deformation for 3D problems ---*/ if (boundary->GetnDim() == 3) { if (config->GetDesign_Variable(0) == SPHERICAL) { if (rank == MASTER_NODE) { cout << endl << "Design variable number "<< iDV <<"." << endl; cout << "Spherical DV: Perform 3D deformation of the surface." << endl; } surface_mov->SetSpherical(boundary, config, iDV, true); } else { /*--- 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 : 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; case FFD_VOLUME : surface_mov->SetFFDVolume(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); } } } /*--- Continuous adjoint gradient computation ---*/ if (rank == MASTER_NODE) cout << "Evaluate functional gradient using the continuous adjoint strategy." << endl; /*--- Load the delta change in the design variable (finite difference step). ---*/ delta_eps = config->GetDV_Value(iDV); my_Gradient = 0.0; Gradient = 0.0; /*--- Reset update points ---*/ for (iPoint = 0; iPoint < boundary->GetnPoint(); iPoint++) UpdatePoint[iPoint] = true; for (iMarker = 0; iMarker < config->GetnMarker_All(); iMarker++) { if (config->GetMarker_All_DV(iMarker) == YES) { for (iVertex = 0; iVertex < boundary->nVertex[iMarker]; iVertex++) { iPoint = boundary->vertex[iMarker][iVertex]->GetNode(); if ((iPoint < boundary->GetnPointDomain()) && UpdatePoint[iPoint]) { Normal = boundary->vertex[iMarker][iVertex]->GetNormal(); VarCoord = boundary->vertex[iMarker][iVertex]->GetVarCoord(); Sensitivity = boundary->vertex[iMarker][iVertex]->GetAuxVar(); dS = 0.0; for (iDim = 0; iDim < boundary->GetnDim(); iDim++) { dS += Normal[iDim]*Normal[iDim]; deps[iDim] = VarCoord[iDim] / delta_eps; } dS = sqrt(dS); dalpha_deps = 0.0; for (iDim = 0; iDim < boundary->GetnDim(); iDim++) { dalpha[iDim] = Normal[iDim] / dS; dalpha_deps -= dalpha[iDim]*deps[iDim]; } /*--- Store the geometric sensitivity for this DV (rows) & this node (column) ---*/ if (size == SINGLE_NODE) { Jacobian_file << ", " << dalpha_deps; } my_Gradient += Sensitivity*dalpha_deps; UpdatePoint[iPoint] = false; } } } } #ifndef NO_MPI MPI::COMM_WORLD.Allreduce(&my_Gradient, &Gradient, 1, MPI::DOUBLE, MPI::SUM); #else Gradient = my_Gradient; #endif if (rank == MASTER_NODE) { switch (config->GetKind_ObjFunc()) { case LIFT_COEFFICIENT : if (iDV == 0) Gradient_file << "Lift coeff. grad. using cont. adj." << endl; cout << "Lift coefficient gradient: "<< Gradient << "." << endl; break; case DRAG_COEFFICIENT : if (iDV == 0) Gradient_file << "Drag coeff. grad. using cont. adj." << endl; cout << "Drag coefficient gradient: "<< Gradient << "." << endl; break; case SIDEFORCE_COEFFICIENT : if (iDV == 0) Gradient_file << "Sideforce coeff. grad. using cont. adj." << endl; cout << "Sideforce coefficient gradient: "<< Gradient << "." << endl; break; case MOMENT_X_COEFFICIENT : if (iDV == 0) Gradient_file << "Moment x coeff. grad. using cont. adj." << endl; cout << "Moment x coefficient gradient: "<< Gradient << "." << endl; break; case MOMENT_Y_COEFFICIENT : if (iDV == 0) Gradient_file << "Moment y coeff. grad. using cont. adj." << endl; cout << "Moment y coefficient gradient: "<< Gradient << "." << endl; break; case MOMENT_Z_COEFFICIENT : if (iDV == 0) Gradient_file << "Moment z coeff. grad. using cont. adj." << endl; cout << "Moment z coefficient gradient: "<< Gradient << "." << endl; break; case EFFICIENCY : if (iDV == 0) Gradient_file << "Efficiency coeff. grad. using cont. adj." << endl; cout << "Efficiency coefficient gradient: "<< Gradient << "." << endl; break; case EQUIVALENT_AREA : if (iDV == 0) Gradient_file << "Equivalent area coeff. grad. using cont. adj." << endl; cout << "Equivalent Area coefficient gradient: "<< Gradient << "." << endl; break; case NEARFIELD_PRESSURE : if (iDV == 0) Gradient_file << "Near-field pressure coeff. grad. using cont. adj." << endl; cout << "Near-field pressure coefficient gradient: "<< Gradient << "." << endl; break; case FORCE_X_COEFFICIENT : if (iDV == 0) Gradient_file << "Force x coeff. grad. using cont. adj." << endl; cout << "Force x coefficient gradient: "<< Gradient << "." << endl; break; case FORCE_Y_COEFFICIENT : if (iDV == 0) Gradient_file << "Force y coeff. grad. using cont. adj." << endl; cout << "Force y coefficient gradient: "<< Gradient << "." << endl; break; case FORCE_Z_COEFFICIENT : if (iDV == 0) Gradient_file << "Force z coeff. grad. using cont. adj." << endl; cout << "Force z coefficient gradient: "<< Gradient << "." << endl; break; case THRUST_COEFFICIENT : if (iDV == 0) Gradient_file << "Thrust coeff. grad. using cont. adj."<< endl; cout << "Thrust coefficient gradient: "<< Gradient << "." << endl; break; case TORQUE_COEFFICIENT : if (iDV == 0) Gradient_file << "Torque coeff. grad. using cont. adj."<< endl; cout << "Torque coefficient gradient: "<< Gradient << "." << endl; break; case FIGURE_OF_MERIT : if (iDV == 0) Gradient_file << "Rotor Figure of Merit grad. using cont. adj."<< endl; cout << "Rotor Figure of Merit gradient: "<< Gradient << "." << endl; break; case FREE_SURFACE : if (iDV == 0) Gradient_file << "Free-Surface grad. using cont. adj."<< endl; cout << "Free-surface gradient: "<< Gradient << "." << endl; break; case HEAT_LOAD : if (iDV == 0) Gradient_file << "Integrated surface heat flux. using cont. adj."<< endl; cout << "Heat load gradient: "<< Gradient << "." << endl; break; } Gradient_file << Gradient << endl; cout <<"-------------------------------------------------------------------------" << endl; } /*--- End the line for the current DV in the geometric Jacobian file ---*/ if (size == SINGLE_NODE) Jacobian_file << endl; } if (rank == MASTER_NODE) Gradient_file.close(); if (size == SINGLE_NODE) Jacobian_file.close(); delete [] UpdatePoint; #ifndef NO_MPI /*--- Finalize MPI parallelization ---*/ MPI::Finalize(); #endif /*--- End solver ---*/ if (rank == MASTER_NODE) cout << endl <<"------------------------- Exit Success (SU2_GPC) ------------------------" << endl << endl; return EXIT_SUCCESS; }
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; }
int main(int argc, char *argv[]) { /*--- Local variables ---*/ unsigned short iDV, nZone = 1, iFFDBox, iPlane, nPlane = 5, iVar; double ObjectiveFunc[100], ObjectiveFunc_New[100], Gradient[100], delta_eps, MinPlane, MaxPlane, Plane_P0[5][3], Plane_Normal[5][3]; vector<double> Xcoord_Airfoil[5], Ycoord_Airfoil[5], Zcoord_Airfoil[5]; char *cstr; ofstream Gradient_file, ObjFunc_file; int rank = MASTER_NODE; /*--- Initialization ---*/ for (iVar = 0; iVar < 100; iVar++) { ObjectiveFunc[iVar] = 0.0; ObjectiveFunc_New[iVar] = 0.0; Gradient[iVar] = 0.0; } #ifndef NO_MPI /*--- MPI initialization, and buffer setting ---*/ MPI::Init(argc,argv); rank = MPI::COMM_WORLD.Get_rank(); #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, VERB_HIGH); else { char grid_file[200]; strcpy (grid_file, "default.cfg"); config = new CConfig(grid_file, SU2_GDC, ZONE_0, nZone, VERB_HIGH); } #ifndef NO_MPI /*--- Change the name of the input-output files for the parallel computation ---*/ 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()); if (rank == MASTER_NODE) cout << endl <<"----------------------- Preprocessing computations ----------------------" << endl; /*--- Boundary geometry preprocessing ---*/ if (rank == MASTER_NODE) cout << "Identify vertices." <<endl; boundary->SetVertex(); /*--- Create the control volume structures ---*/ if (rank == MASTER_NODE) cout << "Set boundary control volume structure." << endl; boundary->SetBoundControlVolume(config, ALLOCATE); /*--- Create plane structure ---*/ if (rank == MASTER_NODE) cout << "Set plane structure." << endl; if (boundary->GetnDim() == 2) { nPlane = 1; 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) { nPlane = 5; MinPlane = config->GetSection_Limit(0); MaxPlane = config->GetSection_Limit(1); for (iPlane = 0; iPlane < nPlane; iPlane++) { Plane_Normal[iPlane][0] = 0.0; Plane_P0[iPlane][0] = 0.0; Plane_Normal[iPlane][1] = 1.0; Plane_P0[iPlane][1] = MinPlane + iPlane*(MaxPlane - MinPlane)/double(nPlane-1); Plane_Normal[iPlane][2] = 0.0; Plane_P0[iPlane][2] = 0.0; } } /*--- 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, config, Xcoord_Airfoil[iPlane], Ycoord_Airfoil[iPlane], Zcoord_Airfoil[iPlane], 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, 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, 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, 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, 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, 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, Xcoord_Airfoil[iPlane], Ycoord_Airfoil[iPlane], Zcoord_Airfoil[iPlane], true); ObjectiveFunc[6*nPlane+iPlane] = boundary->Compute_Area(Plane_P0[iPlane], Plane_Normal[iPlane], iPlane, 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; } } /*--- 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\"" << 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-1; iPlane++) ObjFunc_file << "\"CHORD_SEC"<< (iPlane+1) << "\", "; ObjFunc_file << "\"CHORD_SEC"<< (nPlane) << "\"" << endl; } ObjFunc_file << "ZONE T= \"Geometrical variables (value)\"" << endl; for (iPlane = 0; iPlane < nPlane*9-1; iPlane++) ObjFunc_file << ObjectiveFunc[iPlane] <<", "; ObjFunc_file << ObjectiveFunc[nPlane*9-1] << 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++) { /*--- Bump deformation for 2D problems ---*/ if (boundary->GetnDim() == 2) { if (rank == MASTER_NODE) cout << "Perform 2D deformation of the surface." << endl; switch ( config->GetDesign_Variable(iDV) ) { case HICKS_HENNE : surface_mov->SetHicksHenne(boundary, config, iDV, true); break; case DISPLACEMENT : surface_mov->SetDisplacement(boundary, config, iDV, true); break; case ROTATION : surface_mov->SetRotation(boundary, config, iDV, true); break; case NACA_4DIGITS : surface_mov->SetNACA_4Digits(boundary, config); break; case PARABOLIC : surface_mov->SetParabolic(boundary, config); break; } } /*--- Free Form deformation for 3D problems ---*/ else if (boundary->GetnDim() == 3) { /*--- 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 : 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; case FFD_VOLUME : surface_mov->SetFFDVolume(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); } } /*--- Create airfoil structure ---*/ for (iPlane = 0; iPlane < nPlane; iPlane++) { boundary->ComputeAirfoil_Section(Plane_P0[iPlane], Plane_Normal[iPlane], iPlane, config, Xcoord_Airfoil[iPlane], Ycoord_Airfoil[iPlane], Zcoord_Airfoil[iPlane], 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::COMM_WORLD.Abort(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, 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, 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, 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, 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, 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, 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, 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; } } 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\"" << 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-1; iPlane++) Gradient_file << "\"CHORD_SEC"<< (iPlane+1) << "\", "; Gradient_file << "\"CHORD_SEC"<< (nPlane) << "\"" << endl; } Gradient_file << "ZONE T= \"Geometrical variables (gradient)\"" << endl; } Gradient_file << (iDV) <<", "; for (iPlane = 0; iPlane < nPlane*9-1; iPlane++) Gradient_file << Gradient[iPlane] <<", "; Gradient_file << Gradient[nPlane*9-1] << endl; if (iDV != (config->GetnDV()-1)) cout <<"-------------------------------------------------------------------------" << endl; } } if (rank == MASTER_NODE) Gradient_file.close(); } #ifndef NO_MPI /*--- Finalize MPI parallelization ---*/ MPI::Finalize(); #endif /*--- End solver ---*/ if (rank == MASTER_NODE) cout << endl <<"------------------------- Exit Success (SU2_GDC) ------------------------" << endl << endl; return EXIT_SUCCESS; }