void CWin32Renderer::draw(CRenderable* pRenderable) { if (pRenderable && pRenderable->canBeRendered()) { const GLuint vboId = (GLuint)pRenderable->get1DParam(VBO0_ID); const GLuint iboId = (GLuint)pRenderable->get1DParam(IBO0_ID); if (vboId && iboId) { glBindBuffer(GL_ARRAY_BUFFER, vboId); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, iboId); ///@todo: implement in renderable, add the argument that defines the environment pRenderable->setEnvironment(); // Renderable-specific changes of the OpenGL environment: switch depth on/off etc. CGeometry* pGeometry = pRenderable->getGeometry(); CShader* pShader = pRenderable->getShader(); if (pGeometry && pShader) { pShader->setup(*pRenderable); if (mIsDebugMode && pRenderable->getFlag(eShaderFlags::DRAW_LINES)) { glLineWidth(pRenderable->get1DParam(eShader1DParams::LINE_WIDTH)); glDrawElements(GL_LINES, pGeometry->getNumOfIndices(), GL_UNSIGNED_INT, 0); } else { glDrawElements(GL_TRIANGLE_STRIP, pGeometry->getNumOfIndices(), GL_UNSIGNED_INT, 0); } } // Return to the initial OpenGL state. pRenderable->resetEnvironment(); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glBindTexture(GL_TEXTURE_2D, 0); } } }
CGeometry* CGeometryManager::LoadObject(const char file[100],const int length) { //Hash the file path int hash = Hash(file, length); hash %= MAX_MESHES; //check to see if it exists. if( !meshes[hash].empty() ) //first check if the list is empty. { //create iterator std::list<CGeometry*>::iterator temp = meshes[hash].begin(); //scroll through the list while( temp != meshes[hash].end() ) { //check to see if item in list matches input if( (*temp)->CompareSource( file ) ) { //if so return the existing pointer return *temp; }// end if compare }//end while }//end if empty //Load mesh CGeometry* newGeometry = new CGeometry; //newGeometry->Load(file, length, NULL, false); newGeometry->Load(string(file), NULL, false); if( false /*newGeometry->Load(file, length, NULL, true)*/ ) { meshes[hash].push_back( newGeometry ); return newGeometry; } return nullptr; }//end CGeometryManager::LoadObject
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[]) { 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 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[]) { unsigned short nZone = 1; char buffer_su2[8], buffer_vtk[8], buffer_plt[8], file_name[200]; string MeshFile; int rank = MASTER_NODE; int size = 1; #ifndef NO_MPI /*--- MPI initialization, and buffer setting ---*/ static char buffer[MAX_MPI_BUFFER]; // buffer size in bytes void *ptr; MPI::Init(argc, argv); MPI::Attach_buffer(buffer, MAX_MPI_BUFFER); rank = MPI::COMM_WORLD.Get_rank(); size = MPI::COMM_WORLD.Get_size(); #endif /*--- Definition of some important class ---*/ CConfig *config = NULL; CGeometry *geometry = NULL; CSurfaceMovement *surface_mov = NULL; CFreeFormDefBox** FFDBox = NULL; /*--- Definition of the config problem ---*/ if (argc == 2) { config = new CConfig(argv[1], SU2_DDC, ZONE_0, nZone, VERB_HIGH); } else { strcpy (file_name, "default.cfg"); config = new CConfig(file_name, SU2_DDC, ZONE_0, nZone, VERB_HIGH); } if (rank == MASTER_NODE) { /*--- Definition of the Class for the geometry ---*/ geometry = new CPhysicalGeometry(config, ZONE_0, nZone); } #ifndef NO_MPI MPI::COMM_WORLD.Barrier(); #endif /*--- Set domains for parallel computation (if any) ---*/ if (size > 1) { /*--- Write the new subgrid, and remove the extension ---*/ MeshFile = config->GetMesh_FileName(); unsigned short lastindex = MeshFile.find_last_of("."); MeshFile = MeshFile.substr(0, lastindex); if (rank == MASTER_NODE) { cout << endl <<"------------------------ Divide the numerical grid ----------------------" << endl; /*--- Color the initial grid and set the send-receive domains ---*/ geometry->SetColorGrid(config); } #ifndef NO_MPI MPI::COMM_WORLD.Barrier(); #endif /*--- Allocate the memory of the current domain, and divide the grid between the nodes ---*/ CDomainGeometry *domain = new CDomainGeometry(geometry, config); /*--- Add the Send/Receive boundaries ---*/ domain->SetSendReceive(config); #ifndef NO_MPI MPI::COMM_WORLD.Barrier(); #endif if (rank == MASTER_NODE) cout << endl <<"----------------------------- Write mesh files --------------------------" << endl; #ifndef NO_MPI MPI::COMM_WORLD.Barrier(); #endif /*--- Write tecplot files ---*/ if (config->GetVisualize_Partition()) { sprintf (buffer_plt, "_%d.dat", int(rank+1)); string MeshFile_plt = MeshFile + buffer_plt; char *cstr_plt = strdup(MeshFile_plt.c_str()); domain->SetTecPlot(cstr_plt); } /*--- Write .su2 file ---*/ sprintf (buffer_su2, "_%d.su2", int(rank+1)); string MeshFile_su2 = MeshFile + buffer_su2; char *cstr_su2 = strdup(MeshFile_su2.c_str()); domain->SetMeshFile(config, cstr_su2); #ifndef NO_MPI MPI::COMM_WORLD.Barrier(); #endif cout << "Domain " << rank <<": Mesh writing done (" << MeshFile_su2 <<")." << endl; #ifndef NO_MPI MPI::COMM_WORLD.Barrier(); #endif /*--- Write the FFD information (3D problems)---*/ if (domain->GetnDim() == 3) { #ifndef NO_MPI MPI::COMM_WORLD.Barrier(); #endif if (rank == MASTER_NODE) cout << endl <<"---------------------- Read and write FFD information -------------------" << endl; #ifndef NO_MPI MPI::COMM_WORLD.Barrier(); #endif FFDBox = new CFreeFormDefBox*[MAX_NUMBER_FFD]; surface_mov = new CSurfaceMovement(); surface_mov->ReadFFDInfo(domain, config, FFDBox, config->GetMesh_FileName(), false); surface_mov->WriteFFDInfo(domain, config, FFDBox, cstr_su2); } #ifndef NO_MPI /*--- Finalize MPI parallelization ---*/ MPI::COMM_WORLD.Barrier(); MPI::Detach_buffer(ptr); MPI::Finalize(); #endif } /*--- End solver ---*/ if (rank == MASTER_NODE) cout << endl <<"------------------------- Exit Success (SU2_DDC) ------------------------" << 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; }
int main(int argc, char *argv[]) { /*--- Variable definitions ---*/ unsigned short iZone, nZone = SINGLE_ZONE; su2double StartTime = 0.0, StopTime = 0.0, UsedTime = 0.0; char config_file_name[MAX_STRING_SIZE]; char file_name[MAX_STRING_SIZE]; int rank, size; string str; bool periodic = false; /*--- MPI initialization ---*/ #ifdef HAVE_MPI SU2_MPI::Init(&argc,&argv); SU2_MPI::Comm MPICommunicator(MPI_COMM_WORLD); #else SU2_Comm MPICommunicator(0); #endif rank = SU2_MPI::GetRank(); size = SU2_MPI::GetSize(); /*--- Pointer to different structures that will be used throughout the entire code ---*/ CConfig **config_container = NULL; CGeometry **geometry_container = NULL; /*--- Load in the number of zones and spatial dimensions in the mesh file (if no config file is specified, default.cfg is used) ---*/ if (argc == 2) { strcpy(config_file_name,argv[1]); } else { strcpy(config_file_name, "default.cfg"); } /*--- Read the name and format of the input mesh file to get from the mesh file the number of zones and dimensions from the numerical grid (required for variables allocation) ---*/ CConfig *config = NULL; config = new CConfig(config_file_name, SU2_DEF); nZone = CConfig::GetnZone(config->GetMesh_FileName(), config->GetMesh_FileFormat(), config); periodic = CConfig::GetPeriodic(config->GetMesh_FileName(), config->GetMesh_FileFormat(), config); /*--- Definition of the containers per zones ---*/ config_container = new CConfig*[nZone]; geometry_container = new CGeometry*[nZone]; for (iZone = 0; iZone < nZone; iZone++) { config_container[iZone] = NULL; geometry_container[iZone] = NULL; } /*--- Loop over all zones to initialize the various classes. In most cases, nZone is equal to one. This represents the solution of a partial differential equation on a single block, unstructured mesh. ---*/ for (iZone = 0; iZone < nZone; iZone++) { /*--- Definition of the configuration option class for all zones. In this constructor, the input configuration file is parsed and all options are read and stored. ---*/ config_container[iZone] = new CConfig(config_file_name, SU2_MSH, iZone, nZone, 0, VERB_HIGH); config_container[iZone]->SetMPICommunicator(MPICommunicator); /*--- Definition of the geometry class to store the primal grid in the partitioning process. ---*/ CGeometry *geometry_aux = NULL; /*--- All ranks process the grid and call ParMETIS for partitioning ---*/ geometry_aux = new CPhysicalGeometry(config_container[iZone], iZone, nZone); /*--- Color the initial grid and set the send-receive domains (ParMETIS) ---*/ geometry_aux->SetColorGrid_Parallel(config_container[iZone]); /*--- Until we finish the new periodic BC implementation, use the old partitioning routines for cases with periodic BCs. The old routines will be entirely removed eventually in favor of the new methods. ---*/ if (periodic) { geometry_container[iZone] = new CPhysicalGeometry(geometry_aux, config_container[iZone]); } else { geometry_container[iZone] = new CPhysicalGeometry(geometry_aux, config_container[iZone], periodic); } /*--- Deallocate the memory of geometry_aux ---*/ delete geometry_aux; /*--- Add the Send/Receive boundaries ---*/ geometry_container[iZone]->SetSendReceive(config_container[iZone]); /*--- Add the Send/Receive boundaries ---*/ geometry_container[iZone]->SetBoundaries(config_container[iZone]); } /*--- Set up a timer for performance benchmarking (preprocessing time is included) ---*/ #ifdef HAVE_MPI StartTime = MPI_Wtime(); #else StartTime = su2double(clock())/su2double(CLOCKS_PER_SEC); #endif 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_container[ZONE_0]->SetPoint_Connectivity(); geometry_container[ZONE_0]->SetElement_Connectivity(); /*--- Check the orientation before computing geometrical quantities ---*/ geometry_container[ZONE_0]->SetBoundVolume(); if (config_container[ZONE_0]->GetReorientElements()) { cout << "Check numerical grid orientation." <<endl; geometry_container[ZONE_0]->Check_IntElem_Orientation(config_container[ZONE_0]); geometry_container[ZONE_0]->Check_BoundElem_Orientation(config_container[ZONE_0]); } /*--- Create the edge structure ---*/ cout << "Identify faces, edges and vertices." <<endl; geometry_container[ZONE_0]->SetFaces(); geometry_container[ZONE_0]->SetEdges(); geometry_container[ZONE_0]->SetVertex(config_container[ZONE_0]); geometry_container[ZONE_0]->SetCoord_CG(); /*--- Create the control volume structures ---*/ cout << "Set control volume structure." << endl; geometry_container[ZONE_0]->SetControlVolume(config_container[ZONE_0], ALLOCATE); geometry_container[ZONE_0]->SetBoundControlVolume(config_container[ZONE_0], ALLOCATE); if ((config_container[ZONE_0]->GetKind_Adaptation() != NONE) && (config_container[ZONE_0]->GetKind_Adaptation() != PERIODIC)) { cout << endl <<"--------------------- Start numerical grid adaptation -------------------" << endl; /*-- Definition of the Class for grid adaptation ---*/ CGridAdaptation *grid_adaptation; grid_adaptation = new CGridAdaptation(geometry_container[ZONE_0], config_container[ZONE_0]); /*--- Read the flow solution and/or the adjoint solution and choose the elements to adapt ---*/ if ((config_container[ZONE_0]->GetKind_Adaptation() != FULL) && (config_container[ZONE_0]->GetKind_Adaptation() != WAKE) && (config_container[ZONE_0]->GetKind_Adaptation() != SMOOTHING) && (config_container[ZONE_0]->GetKind_Adaptation() != SUPERSONIC_SHOCK)) grid_adaptation->GetFlowSolution(geometry_container[ZONE_0], config_container[ZONE_0]); switch (config_container[ZONE_0]->GetKind_Adaptation()) { case NONE: break; case SMOOTHING: config_container[ZONE_0]->SetSmoothNumGrid(true); grid_adaptation->SetNo_Refinement(geometry_container[ZONE_0], 1); break; case FULL: grid_adaptation->SetComplete_Refinement(geometry_container[ZONE_0], 1); break; case WAKE: grid_adaptation->SetWake_Refinement(geometry_container[ZONE_0], 1); break; case SUPERSONIC_SHOCK: grid_adaptation->SetSupShock_Refinement(geometry_container[ZONE_0], config_container[ZONE_0]); break; case FULL_FLOW: grid_adaptation->SetComplete_Refinement(geometry_container[ZONE_0], 1); break; case FULL_ADJOINT: grid_adaptation->GetAdjSolution(geometry_container[ZONE_0], config_container[ZONE_0]); grid_adaptation->SetComplete_Refinement(geometry_container[ZONE_0], 1); break; case GRAD_FLOW: grid_adaptation->SetIndicator_Flow(geometry_container[ZONE_0], config_container[ZONE_0], 1); break; case GRAD_ADJOINT: grid_adaptation->GetAdjSolution(geometry_container[ZONE_0], config_container[ZONE_0]); grid_adaptation->SetIndicator_Adj(geometry_container[ZONE_0], config_container[ZONE_0], 1); break; case GRAD_FLOW_ADJ: grid_adaptation->GetAdjSolution(geometry_container[ZONE_0], config_container[ZONE_0]); grid_adaptation->SetIndicator_FlowAdj(geometry_container[ZONE_0], config_container[ZONE_0]); break; case COMPUTABLE: grid_adaptation->GetAdjSolution(geometry_container[ZONE_0], config_container[ZONE_0]); grid_adaptation->GetFlowResidual(geometry_container[ZONE_0], config_container[ZONE_0]); grid_adaptation->SetIndicator_Computable(geometry_container[ZONE_0], config_container[ZONE_0]); break; case REMAINING: SU2_MPI::Error("Adaptation method not implemented.", CURRENT_FUNCTION); 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_container[ZONE_0]->GetnDim() == 2) grid_adaptation->SetHomothetic_Adaptation2D(geometry_container[ZONE_0], geo_adapt, config_container[ZONE_0]); if (geometry_container[ZONE_0]->GetnDim() == 3) grid_adaptation->SetHomothetic_Adaptation3D(geometry_container[ZONE_0], geo_adapt, config_container[ZONE_0]); /*--- Smooth the numerical grid coordinates ---*/ if (config_container[ZONE_0]->GetSmoothNumGrid()) { cout << "Preprocessing for doing the implicit smoothing." << endl; geo_adapt->SetPoint_Connectivity(); geo_adapt->SetElement_Connectivity(); geo_adapt->SetBoundVolume(); if (config_container[ZONE_0]->GetReorientElements()) { geo_adapt->Check_IntElem_Orientation(config_container[ZONE_0]); geo_adapt->Check_BoundElem_Orientation(config_container[ZONE_0]); } geo_adapt->SetEdges(); geo_adapt->SetVertex(config_container[ZONE_0]); cout << "Implicit smoothing of the numerical grid coordinates." << endl; geo_adapt->SetCoord_Smoothing(5, 1.5, config_container[ZONE_0]); } /*--- Original and adapted grid ---*/ strcpy (file_name, "original_grid.dat"); geometry_container[ZONE_0]->SetTecPlot(file_name, true); strcpy (file_name, "original_surface.dat"); geometry_container[ZONE_0]->SetBoundTecPlot(file_name, true, config_container[ZONE_0]); /*--- Write the adapted grid sensor ---*/ strcpy (file_name, "adapted_grid.dat"); geo_adapt->SetTecPlot(file_name, true); strcpy (file_name, "adapted_surface.dat"); geo_adapt->SetBoundTecPlot(file_name, true, config_container[ZONE_0]); /*--- Write the new adapted grid, including the modified boundaries surfaces ---*/ geo_adapt->SetMeshFile(config_container[ZONE_0], config_container[ZONE_0]->GetMesh_Out_FileName()); /*--- Write the restart file ---*/ if ((config_container[ZONE_0]->GetKind_Adaptation() != SMOOTHING) && (config_container[ZONE_0]->GetKind_Adaptation() != FULL) && (config_container[ZONE_0]->GetKind_Adaptation() != WAKE) && (config_container[ZONE_0]->GetKind_Adaptation() != SUPERSONIC_SHOCK)) grid_adaptation->SetRestart_FlowSolution(config_container[ZONE_0], geo_adapt, config_container[ZONE_0]->GetRestart_FlowFileName()); if ((config_container[ZONE_0]->GetKind_Adaptation() == GRAD_FLOW_ADJ) || (config_container[ZONE_0]->GetKind_Adaptation() == GRAD_ADJOINT) || (config_container[ZONE_0]->GetKind_Adaptation() == FULL_ADJOINT) || (config_container[ZONE_0]->GetKind_Adaptation() == COMPUTABLE) || (config_container[ZONE_0]->GetKind_Adaptation() == REMAINING)) grid_adaptation->SetRestart_AdjSolution(config_container[ZONE_0], geo_adapt, config_container[ZONE_0]->GetRestart_AdjFileName()); } else { if (config_container[ZONE_0]->GetKind_Adaptation() == PERIODIC) { cout << endl <<"-------------------- Setting the periodic boundaries --------------------" << endl; /*--- Set periodic boundary conditions ---*/ geometry_container[ZONE_0]->SetPeriodicBoundary(config_container[ZONE_0]); /*--- Original grid for debugging purposes ---*/ strcpy (file_name, "periodic_original.dat"); geometry_container[ZONE_0]->SetTecPlot(file_name, true); /*--- Create a new grid with the right periodic boundary ---*/ CGeometry *periodic; periodic = new CPeriodicGeometry(geometry_container[ZONE_0], config_container[ZONE_0]); periodic->SetPeriodicBoundary(geometry_container[ZONE_0], config_container[ZONE_0]); periodic->SetMeshFile(geometry_container[ZONE_0], config_container[ZONE_0], config_container[ZONE_0]->GetMesh_Out_FileName()); /*--- Output of the grid for debuging purposes ---*/ strcpy (file_name, "periodic_halo.dat"); periodic->SetTecPlot(file_name, true); } if (config_container[ZONE_0]->GetKind_Adaptation() == NONE) { strcpy (file_name, "original_grid.dat"); geometry_container[ZONE_0]->SetTecPlot(file_name, true); geometry_container[ZONE_0]->SetMeshFile(config_container[ZONE_0], config_container[ZONE_0]->GetMesh_Out_FileName()); } } if (rank == MASTER_NODE) cout << endl <<"------------------------- Solver Postprocessing -------------------------" << endl; if (geometry_container != NULL) { for (iZone = 0; iZone < nZone; iZone++) { if (geometry_container[iZone] != NULL) { delete geometry_container[iZone]; } } delete [] geometry_container; } if (rank == MASTER_NODE) cout << "Deleted CGeometry container." << endl; if (config_container != NULL) { for (iZone = 0; iZone < nZone; iZone++) { if (config_container[iZone] != NULL) { delete config_container[iZone]; } } delete [] config_container; } if (rank == MASTER_NODE) cout << "Deleted CConfig container." << endl; delete config; config = NULL; /*--- Synchronization point after a single solver iteration. Compute the wall clock time required. ---*/ #ifdef HAVE_MPI StopTime = MPI_Wtime(); #else StopTime = su2double(clock())/su2double(CLOCKS_PER_SEC); #endif /*--- Compute/print the total time for performance benchmarking. ---*/ UsedTime = StopTime-StartTime; if (rank == MASTER_NODE) { cout << "\nCompleted in " << fixed << UsedTime << " seconds on "<< size; if (size == 1) cout << " core." << endl; else cout << " cores." << endl; } /*--- Exit the solver cleanly ---*/ cout << endl <<"------------------------- Exit Success (SU2_MSH) ------------------------" << endl << endl; /*--- Finalize MPI parallelization ---*/ #ifdef HAVE_MPI SU2_MPI::Finalize(); #endif return EXIT_SUCCESS; }